Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(607)

Unified Diff: chrome/browser/resources/google_now/utility_unittest.gtestjs

Issue 23623010: Unit tests for task manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: skare@ comments Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/google_now/utility_unittest.gtestjs
diff --git a/chrome/browser/resources/google_now/utility_unittest.gtestjs b/chrome/browser/resources/google_now/utility_unittest.gtestjs
index 419864d193172dcd9e281e38e5e0fc4d8532d6c1..423f0878195a674c5c7ae0f26130b6329c4e4b34 100644
--- a/chrome/browser/resources/google_now/utility_unittest.gtestjs
+++ b/chrome/browser/resources/google_now/utility_unittest.gtestjs
@@ -149,12 +149,12 @@ TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackEvent', function() {
this.makeMockLocalFunctions(['callback']);
- // Step 1. Wrapping callback.
+ // Step 1. Wrap a callback.
var wrappedCallback =
wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true);
Mock4JS.verifyAllMocks();
- // Step 2. Invoking wrapped callback.
+ // Step 2. Invoke wrapped callback.
// Expectations.
this.mockLocalFunctions.expects(once()).
callback('test string', 239).
@@ -166,7 +166,7 @@ TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackEvent', function() {
wrappedCallback('test string', 239);
Mock4JS.verifyAllMocks();
- // Step 3. Checking that after the callback we are again in non-instrumented
+ // Step 3. Check that after the callback we are again in non-instrumented
// code.
// Expectations.
this.mockGlobals.expects(once()).
@@ -195,12 +195,12 @@ TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackPlugin', function() {
'epilogue'
]);
- // Step 1. Registering plugin factory.
+ // Step 1. Register plugin factory.
wrapper.registerWrapperPluginFactory(
this.mockLocalFunctions.functions().pluginFactory);
Mock4JS.verifyAllMocks();
- // Step 2. Wrapping callback.
+ // Step 2. Wrap a callback.
// Expectations.
this.mockLocalFunctions.expects(once()).
pluginFactory().
@@ -214,7 +214,7 @@ TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackPlugin', function() {
wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true);
Mock4JS.verifyAllMocks();
- // Step 3. Calling the wrapped callback.
+ // Step 3. Call the wrapped callback.
// Expectations.
this.mockLocalFunctions.expects(once()).prologue();
this.mockLocalFunctions.expects(once()).callback();
@@ -233,12 +233,12 @@ TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackCatchError', function() {
]);
this.makeMockLocalFunctions(['callback']);
- // Step 1. Wrapping callback.
+ // Step 1. Wrap a callback.
var wrappedCallback =
wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true);
Mock4JS.verifyAllMocks();
- // Step 2. Invoking wrapped callback.
+ // Step 2. Invoke wrapped callback.
// Expectations.
this.mockLocalFunctions.expects(once()).
callback().
@@ -272,11 +272,11 @@ TEST_F('GoogleNowUtilityUnitTest',
addListener: this.mockLocalFunctions.functions().apiFunction1
};
- // Step 1. Instrumenting the listener.
+ // Step 1. Instrument the listener.
wrapper.instrumentChromeApiFunction('testApi.addListener', 1);
Mock4JS.verifyAllMocks();
- // Step 2. Invoking the instrumented API call.
+ // Step 2. Invoke the instrumented API call.
// Expectations.
var function1SavedArgs = new SaveMockArguments();
this.mockLocalFunctions.expects(once()).
@@ -289,7 +289,7 @@ TEST_F('GoogleNowUtilityUnitTest',
239, this.mockLocalFunctions.functions().callback1);
Mock4JS.verifyAllMocks();
- // Step 3. Invoking the callback that was passed by the instrumented function
+ // Step 3. Invoke the callback that was passed by the instrumented function
// to the original one.
// Expectations.
this.mockLocalFunctions.expects(once()).callback1(237);
@@ -303,10 +303,10 @@ TEST_F('GoogleNowUtilityUnitTest',
this.mockLocalFunctions.functions().pluginFactory);
Mock4JS.verifyAllMocks();
- // Step 5. Binding the API to another function.
+ // Step 5. Bind the API to another function.
chrome.testApi.addListener = this.mockLocalFunctions.functions().apiFunction2;
- // Step 6. Invoking the API with another callback.
+ // Step 6. Invoke the API with another callback.
// Expectations.
this.mockLocalFunctions.expects(once()).
pluginFactory().
@@ -325,7 +325,7 @@ TEST_F('GoogleNowUtilityUnitTest',
239, this.mockLocalFunctions.functions().callback2);
Mock4JS.verifyAllMocks();
- // Step 7. Invoking the callback that was passed by the instrumented function
+ // Step 7. Invoke the callback that was passed by the instrumented function
// to the original one.
// Expectations.
this.mockLocalFunctions.expects(once()).prologue();
@@ -351,12 +351,12 @@ TEST_F('GoogleNowUtilityUnitTest', 'WrapperOnSuspendListenerFail', function() {
this.makeMockLocalFunctions(['listener', 'callback']);
var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend');
- // Step 1. Wrapping event listener.
+ // Step 1. Wrap event listener.
var wrappedListener =
wrapper.wrapCallback(this.mockLocalFunctions.functions().listener, true);
Mock4JS.verifyAllMocks();
- // Step 2. Invoking event listener, which will wrap a required callback.
+ // Step 2. Invoke event listener, which will wrap a required callback.
// Setup and expectations.
var wrappedCallback;
var testFixture = this;
@@ -371,7 +371,7 @@ TEST_F('GoogleNowUtilityUnitTest', 'WrapperOnSuspendListenerFail', function() {
wrappedListener();
Mock4JS.verifyAllMocks();
- // Step 3. Firing runtime.onSuspend event.
+ // Step 3. Fire runtime.onSuspend event.
// Expectations.
this.mockGlobals.expects(once()).
buildErrorWithMessageForServer(stringContains(
@@ -396,12 +396,12 @@ TEST_F('GoogleNowUtilityUnitTest',
this.makeMockLocalFunctions(['listener', 'callback']);
var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend');
- // Step 1. Wrapping event listener.
+ // Step 1. Wrap event listener.
var wrappedListener =
wrapper.wrapCallback(this.mockLocalFunctions.functions().listener, true);
Mock4JS.verifyAllMocks();
- // Step 2. Invoking event listener, which will wrap a required callback.
+ // Step 2. Invoke event listener, which will wrap a required callback.
// Setup and expectations.
var wrappedCallback;
var testFixture = this;
@@ -416,15 +416,313 @@ TEST_F('GoogleNowUtilityUnitTest',
wrappedListener();
Mock4JS.verifyAllMocks();
- // Step 3. Calling wrapped callback.
+ // Step 3. Call wrapped callback.
// Expectations.
this.mockLocalFunctions.expects(once()).callback();
// Invocation.
wrappedCallback();
- // Step 4. Firing runtime.onSuspend event.
+ // Step 4. Fire runtime.onSuspend event.
assertTrue(onSuspendHandlerContainer.length == 1,
'onSuspendHandlerContainer.length must be 1');
onSuspendHandlerContainer[0]();
});
+
+var taskNameA = 'TASK A';
+var taskNameB = 'TASK B';
+var taskNameC = 'TASK C';
+
+function areTasksConflicting(newTaskName, scheduledTaskName) {
+ // Task B is conflicting with Task A. This means that if Task B is added when
+ // Task A is running, Task B will be ignored (but not vice versa). No other
+ // pair is conflicting.
+ return newTaskName == taskNameB && scheduledTaskName == taskNameA;
+}
+
+function setUpTaskManagerTest(fixture) {
+ // We want to mock wrapper using makeAndRegisterMockApis(), which requires
+ // the mocked functions to not exist as a precondition. Resetting 'wrapper' to
+ // 'undefined'.
+ wrapper = undefined;
+
+ fixture.makeAndRegisterMockApis([
+ 'wrapper.checkInWrappedCallback',
+ 'wrapper.registerWrapperPluginFactory',
+ 'wrapper.debugGetStateString'
+ ]);
+ fixture.makeMockLocalFunctions(['task1', 'task2', 'task3']);
+ fixture.makeAndRegisterMockGlobals(['reportError']);
+
+ fixture.mockApis.stubs().wrapper_checkInWrappedCallback();
+ fixture.mockApis.stubs().wrapper_debugGetStateString().
+ will(returnValue('testWrapperDebugState'));
+
+ var registerWrapperPluginFactorySavedArgs = new SaveMockArguments();
+ fixture.mockApis.expects(once()).wrapper_registerWrapperPluginFactory(
+ registerWrapperPluginFactorySavedArgs.match(ANYTHING));
+ var tasks = buildTaskManager(areTasksConflicting);
+ Mock4JS.verifyAllMocks();
+
+ return {
+ tasks: tasks,
+ pluginFactory: registerWrapperPluginFactorySavedArgs.arguments[0]
+ };
+}
+
+TEST_F('GoogleNowUtilityUnitTest', 'TaskManager2Sequential', function() {
+ // Tests that 2 tasks get successfully executed consecutively, even if the
+ // second one conflicts with the first.
+
+ // Setup.
+ var test = setUpTaskManagerTest(this);
+
+ // Step 1. Add 1st task that doesn't create pending callbacks.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task1(ANYTHING);
+ // Invocation.
+ test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1);
+ Mock4JS.verifyAllMocks();
+
+ // Step 2. Add 2nd task.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task2(ANYTHING);
+ // Invocation.
+ test.tasks.add(taskNameB, this.mockLocalFunctions.functions().task2);
+});
+
+TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerConflicting', function() {
+ // Tests that adding a task while a conflicting task is being executed causes
+ // the second one to be ignored.
+
+ // Setup.
+ var test = setUpTaskManagerTest(this);
+ var task1PluginInstance;
+
+ // Step 1. Add 1st task that creates a pending callback.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task1(ANYTHING).
+ will(callFunction(function() {
+ task1PluginInstance = test.pluginFactory();
+ }));
+ // Invocation.
+ test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1);
+ Mock4JS.verifyAllMocks();
+
+ // Step 2. Add 2nd task. Since it conflicts with currently running task1
+ // (see areTasksConflicting), it should be ignored.
+ test.tasks.add(taskNameB, this.mockLocalFunctions.functions().task2);
+ Mock4JS.verifyAllMocks();
+
+ // Step 3. Enter the callback of task1.
+ task1PluginInstance.prologue();
+ Mock4JS.verifyAllMocks();
+
+ // Step 4. Leave the callback of task1.
+ task1PluginInstance.epilogue();
+});
+
+TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerNestedTaskEnqueue', function() {
+ // Tests that adding a task while a non-conflicting task is being executed
+ // causes the second one to be executed after the first one completes.
+
+ // Setup.
+ var test = setUpTaskManagerTest(this);
+ var task1PluginInstance;
+
+ // Step 1. Add 1st task that creates a pending callback.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task1(ANYTHING).
+ will(callFunction(function() {
+ task1PluginInstance = test.pluginFactory();
+ }));
+ // Invocation.
+ test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1);
+ Mock4JS.verifyAllMocks();
+
+ // Step 2. Add 2nd task. Since it doesn't conflict with currently running
+ // task1 (see areTasksConflicting), it should not be ignored.
+ test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2);
+ Mock4JS.verifyAllMocks();
+
+ // Step 3. Enter the callback of task1.
+ task1PluginInstance.prologue();
+ Mock4JS.verifyAllMocks();
+
+ // Step 4. Leave the callback of task1.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task2(ANYTHING);
+ // Invocation.
+ task1PluginInstance.epilogue();
+});
+
+TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerBranching', function() {
+ // Tests that task manager correctly detects completion of tasks that create
+ // branching chains of callbacks (in this test, task1 creates pending
+ // callbacks 1 and 2, and callback 1 creates pending callback 3).
+
+ // Setup.
+ var test = setUpTaskManagerTest(this);
+ var task1PluginInstance1, task1PluginInstance2, task1PluginInstance3;
+
+ // Step 1. Add 1st task that creates a 2 pending callbacks.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task1(ANYTHING).
+ will(callFunction(function() {
+ task1PluginInstance1 = test.pluginFactory();
+ task1PluginInstance2 = test.pluginFactory();
+ }));
+ // Invocation.
+ test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1);
+ Mock4JS.verifyAllMocks();
+
+ // Step 2. Add 2nd task, which is not conflicting (see areTasksConflicting)
+ // with task1.
+ test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2);
+ Mock4JS.verifyAllMocks();
+
+ // Step 3. Enter callback 1, create pending callback 3, exit callback 1.
+ // Enter/exit callback 2. Enter callback 3.
+ task1PluginInstance1.prologue();
+ task1PluginInstance3 = test.pluginFactory();
+ task1PluginInstance1.epilogue();
+ task1PluginInstance2.prologue();
+ task1PluginInstance2.epilogue();
+ task1PluginInstance3.prologue();
+ Mock4JS.verifyAllMocks();
+
+ // Step 4. Leave 3rd callback of task1. Now task1 is complete, and task2
+ // should start.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task2(ANYTHING);
+ // Invocation.
+ task1PluginInstance3.epilogue();
+});
+
+TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerSuspendError', function() {
+ // Tests that task manager's onSuspend method reports an error if there are
+ // pending tasks.
+
+ // Setup.
+ var test = setUpTaskManagerTest(this);
+ var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend');
+
+ // Step 1. Add a task that creates a pending callback.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task1(ANYTHING).
+ will(callFunction(function() {
+ test.pluginFactory();
+ }));
+ // Invocation.
+ test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1);
+ Mock4JS.verifyAllMocks();
+
+ // Step 2. Invoke onSuspend event of the task manager.
+ // Setup and expectations. The 2 callbacks in onSuspendHandlerContainer are
+ // from the wrapper and the task manager.
+ assertTrue(onSuspendHandlerContainer.length == 2,
+ 'onSuspendHandlerContainer.length must be 2');
+ this.mockGlobals.expects(once()).reportError(eqToString(
+ 'Error: ASSERT: Incomplete task when unloading event page,' +
+ ' queue = [{"name":"TASK A"}], testWrapperDebugState'));
+ // Invocation.
+ onSuspendHandlerContainer[1]();
+});
+
+TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerSuspendSuccess', function() {
+ // Tests that task manager's onSuspend method does not report an error if all
+ // tasks completed.
+
+ // Setup.
+ var test = setUpTaskManagerTest(this);
+ var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend');
+ var task1PluginInstance;
+
+ // Step 1. Add a task that creates a pending callback.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task1(ANYTHING).
+ will(callFunction(function() {
+ task1PluginInstance = test.pluginFactory();
+ }));
+ // Invocation.
+ test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1);
+ Mock4JS.verifyAllMocks();
+
+ // Step 2. Invoke task's callback and the onSuspend event of the task manager.
+ // The 2 callbacks in onSuspendHandlerContainer are from the wrapper and the
+ // task manager.
+ task1PluginInstance.prologue();
+ task1PluginInstance.epilogue();
+ onSuspendHandlerContainer[1]();
+});
+
+TEST_F('GoogleNowUtilityUnitTest', 'TaskManager3Tasks', function() {
+ // Tests that 3 tasks can be executed too. In particular, that if the second
+ // task is a single-step task which execution was originally blocked by task1,
+ // unblocking it causes immediate synchronous execution of both tasks 2 and 3.
+
+ // Setup.
+ var test = setUpTaskManagerTest(this);
+ var task1PluginInstance;
+
+ // Step 1. Add 1st task that creates a pending callback.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task1(ANYTHING).
+ will(callFunction(function() {
+ task1PluginInstance = test.pluginFactory();
+ }));
+ // Invocation.
+ test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1);
+ Mock4JS.verifyAllMocks();
+
+ // Step 2. Add 2nd and 3rd tasks, both non-conflicting (see
+ // areTasksConflicting) with task1.
+ test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2);
+ test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task3);
+ Mock4JS.verifyAllMocks();
+
+ // Step 3. Enter the callback of task1.
+ task1PluginInstance.prologue();
+ Mock4JS.verifyAllMocks();
+
+ // Step 4. Leave the callback of task1.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task2(ANYTHING);
+ this.mockLocalFunctions.expects(once()).task3(ANYTHING);
+ // Invocation.
+ task1PluginInstance.epilogue();
+});
+
+TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerNestedNonTask', function() {
+ // Tests callbacks requested while a task is running, but not from a callback
+ // belonging to a task, are not counted as a part of the task.
+
+ // Setup.
+ var test = setUpTaskManagerTest(this);
+ var task1PluginInstance;
+
+ // Step 1. Add 1st task that creates a pending callback.
+ // Expectations.
+ this.mockLocalFunctions.expects(once()).task1(ANYTHING).
+ will(callFunction(function() {
+ task1PluginInstance = test.pluginFactory();
+ }));
+ // Invocation.
+ test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1);
+ Mock4JS.verifyAllMocks();
+
+ // Step 2. Create a pending callback from code that is not a part of the task.
+ test.pluginFactory();
+ Mock4JS.verifyAllMocks();
+
+ // Step 3. Enter the callback of task1. After this, task1 should be
+ // finished despite the pending non-task callback.
+ task1PluginInstance.prologue();
+ task1PluginInstance.epilogue();
+ Mock4JS.verifyAllMocks();
+
+ // Step 4. Check that task1 is finished by submitting task2, which should
+ // be executed immediately.
+ this.mockLocalFunctions.expects(once()).task2(ANYTHING);
+ test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2);
+});
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698