Commit 018e1a60 authored by mmenke@chromium.org's avatar mmenke@chromium.org

Fix reentrancy bug in NetInternalsTest.NetInternalsDnsViewIncognitoClears.

InProcessBrowserTest::CreateIncognitoBrowser() runs its own message loop
as it waits for navigation to complete, which resulted in a race between
the navigation to about:blank completing and trying to close the
Incognito browser.

BUG=106707

Review URL: http://codereview.chromium.org/8892006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113898 0039d316-1c4b-4281-b951-d872f2087c98
parent 25b0a587
......@@ -121,7 +121,8 @@ class NetInternalsTest : public WebUIBrowserTest {
// there, and that the background tab exists at slot 1.
void NavigateToPrerender(const ListValue* list_value);
// Creates an incognito browser.
// Creates an incognito browser. Once creation is complete, passes a
// message to the Javascript test harness.
void CreateIncognitoBrowser(const ListValue* list_value);
// Closes an incognito browser created with CreateIncognitoBrowser.
......@@ -264,6 +265,10 @@ void NetInternalsTest::MessageHandler::CreateIncognitoBrowser(
const ListValue* list_value) {
ASSERT_FALSE(incognito_browser_);
incognito_browser_ = net_internals_test_->CreateIncognitoBrowser();
// Tell the test harness that creation is complete.
StringValue command_value("onIncognitoBrowserCreatedForTest");
web_ui()->CallJavascriptFunction("g_browser.receive", command_value);
}
void NetInternalsTest::MessageHandler::CloseIncognitoBrowser(
......@@ -403,11 +408,6 @@ IN_PROC_BROWSER_TEST_F(NetInternalsTest, NetInternalsDnsViewAddTwoTwice) {
// Makes sure that openning and then closing an incognito window clears the
// DNS cache. To keep things simple, we add a fake cache entry ourselves,
// rather than having the incognito browser create one.
#if defined(OS_CHROMEOS)
// http://crbug.com/106707
#define NetInternalsDnsViewIncognitoClears \
FLAKY_NetInternalsDnsViewIncognitoClears
#endif
IN_PROC_BROWSER_TEST_F(NetInternalsTest, NetInternalsDnsViewIncognitoClears) {
EXPECT_TRUE(RunJavascriptAsyncTest("netInternalsDnsViewIncognitoClears"));
}
......
......@@ -258,7 +258,7 @@ netInternalsTest.test('netInternalsDnsViewAddTwoTwice', function() {
netInternalsTest.test('netInternalsDnsViewIncognitoClears', function() {
netInternalsTest.switchToView('dns');
var taskQueue = new netInternalsTest.TaskQueue(true);
taskQueue.addTask(netInternalsTest.getCreateIncognitoBrowserTask());
taskQueue.addTask(new netInternalsTest.CreateIncognitoBrowserTask());
taskQueue.addTask(new AddCacheEntryTask(
'somewhere.com', '1.2.3.4', 0, true));
taskQueue.addTask(netInternalsTest.getCloseIncognitoBrowserTask());
......
......@@ -424,18 +424,51 @@ var netInternalsTest = (function() {
}
};
// Creates an incognito window. May not be called if there already is an
// incognito in exitence. Returns immediately.
function getCreateIncognitoBrowserTask() {
return new CallFunctionTask(
function() {
chrome.send('createIncognitoBrowser');
});
/**
* A Task that creates an incognito window and only completes once it has
* navigated to about:blank. The waiting is required to avoid reentrancy
* issues, since the function to create the incognito browser also waits
* for the navigation to complete. May not be called if there's already an
* incognito browser in existence.
* @constructor
*/
function CreateIncognitoBrowserTask() {
Task.call(this);
}
CreateIncognitoBrowserTask.prototype = {
__proto__: Task.prototype,
/**
* Tells the browser process to create an incognito browser, and sets
* up a callback to be called on completion.
*/
start: function() {
// Reuse the BrowserBridge's callback mechanism, since it's already
// wrapped in our test harness.
assertEquals('undefined',
typeof g_browser.onIncognitoBrowserCreatedForTest);
g_browser.onIncognitoBrowserCreatedForTest =
this.onIncognitoBrowserCreatedForTest.bind(this);
chrome.send('createIncognitoBrowser');
},
/**
* Deletes the callback function, and completes the task.
*/
onIncognitoBrowserCreatedForTest: function() {
delete g_browser.onIncognitoBrowserCreatedForTest;
this.onTaskDone();
}
};
// Closes an incognito window created with the task above. May only be
// called if there's an incognito window created by the above function
// that has yet to be closed. Returns immediately.
/**
* Returns a task that closes an incognito window created with the task
* above. May only be called if there's an incognito window created by
* the above function that has yet to be closed. Returns immediately.
* @return {Task} Task that closes incognito browser window.
*/
function getCloseIncognitoBrowserTask() {
return new CallFunctionTask(
function() {
......@@ -530,7 +563,7 @@ var netInternalsTest = (function() {
TaskQueue: TaskQueue,
Task: Task,
CallFunctionTask: CallFunctionTask,
getCreateIncognitoBrowserTask: getCreateIncognitoBrowserTask,
CreateIncognitoBrowserTask: CreateIncognitoBrowserTask,
getCloseIncognitoBrowserTask: getCloseIncognitoBrowserTask,
Source: Source,
Event: Event,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment