New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 827231 link

Starred by 3 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Mixing document.cookie and cookieStore produces flaky behavior

Project Member Reported by jsb...@chromium.org, Mar 29 2018

Issue description

With the following as the core of a testharness.js test:

promise_test(async t => {
  await cookieStore.delete('c');
  document.cookie = 'c=v; path=/';
  assert_not_equals(await cookieStore.get('c'), null);
}, 'this is flaky');

... the results are flaky; with --repeat-each=25 I get about 50% pass/fail on my linux box, but it's really timing sensitive.

 

Comment 1 by jsb...@chromium.org, Mar 29 2018

Hrm, this looks like it could be the cause:

https://cs.chromium.org/chromium/src/content/browser/frame_host/render_frame_message_filter.cc?sq=package:chromium&l=460

https://cs.chromium.org/chromium/src/content/browser/frame_host/render_frame_message_filter.cc?sq=package:chromium&l=492

"Pass a null callback since we don't care about when the 'set' completes."

------

A couple runs, with some key methods DLOGing, where 'A' is the cookieStore.delete(), 'B' is the set via document.cookie, and 'C' is the cookieStore.get()

We're dealing with two processes (renderer, browser) and the browser has two threads, so logging can be confusing.



Succeeded:

A blink::ScriptPromise blink::CookieStore::DoWrite()
A - void net::CookieMonster::SetCanonicalCookie()
A static void blink::CookieStore::OnSetCanonicalCookieResult()

B void blink::Document::setCookie()
B void blink::SetCookies()

C blink::ScriptPromise blink::CookieStore::DoRead() (**1)
B - virtual void content::RenderFrameMessageFilter::SetCookie() - invoking callback (**2)
B - virtual void content::RenderFrameMessageFilter::SetCookie() - issuing async set
B - void net::CookieMonster::SetCanonicalCookie() (**3)
C - virtual void net::CookieMonster::GetCookieListWithOptionsAsync()
C - void net::CookieMonster::GetCookieListWithOptions() (**4)
C static void blink::CookieStore::GetAllForUrlToGetResult()

Note that log ordering of **1 and **2 is presumably due to multi-thread/process logging; the DoRead call (**1) should not happen until after the callback runs (**2). 

The important thing is that the Set (**3) happens before the Get (**4), on the CookieMonster's thread.

....

Failed:

A blink::ScriptPromise blink::CookieStore::DoWrite()
A - void net::CookieMonster::SetCanonicalCookie()
A static void blink::CookieStore::OnSetCanonicalCookieResult()

B void blink::Document::setCookie()
B void blink::SetCookies()

C blink::ScriptPromise blink::CookieStore::DoRead()
C - virtual void net::CookieMonster::GetCookieListWithOptionsAsync()
C - void net::CookieMonster::GetCookieListWithOptions() (**1)
B - virtual void content::RenderFrameMessageFilter::SetCookie() - invoking callback
B - virtual void content::RenderFrameMessageFilter::SetCookie() - issuing async set
B - void net::CookieMonster::SetCanonicalCookie() (**2)
C static void blink::CookieStore::GetAllForUrlToGetResult()

Note here that the Get (**1) happens before the Set (**2), on the CookieMonster's thread. :(



Comment 2 by jsb...@chromium.org, Mar 29 2018

Hrm, that may not be the (only) issue. If I pass the callback through so it is invoked after the set is (theoretically) complete, but back out all the logging (*sigh*) the the flakiness is unchanged.

Sign in to add a comment