Bug 346010 - [model] strange initialization dependency in OptionTests
Summary: [model] strange initialization dependency in OptionTests
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.7   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.8 M2   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-16 18:07 EDT by Stephan Herrmann CLA
Modified: 2011-09-13 12:27 EDT (History)
3 users (show)

See Also:


Attachments
Tweaks exposing the failure (2.88 KB, patch)
2011-05-16 19:08 EDT, Stephan Herrmann CLA
no flags Details | Diff
proposed fix (3.44 KB, patch)
2011-08-14 11:41 EDT, Stephan Herrmann CLA
no flags Details | Diff
deterministic test (3.68 KB, patch)
2011-08-14 12:14 EDT, Stephan Herrmann CLA
no flags Details | Diff
Improved and combined patch (8.58 KB, patch)
2011-08-23 12:15 EDT, Stephan Herrmann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Stephan Herrmann CLA 2011-05-16 18:07:31 EDT
I was debugging the new tests for 324987 (because with Object Teams in the
loop two of these tests fail), when I found a dependency that doesn't look kosher
to me (the following does not depend on Object Teams!):

When running the single test testBug324987_Project02() it fails,
when running two tests, testBug324987_Project01() and 
testBug324987_Project02() all is well.

This setup I created with
	TESTS_NAMES = new String[] {	"testBug324987_Project01",
			"testBug324987_Project02" };

Using this two-tests setup and doing back-to-back debugging I could narrow
the issue down to the following difference:

If I tweak SetVariableOperation so that it simply returns from its first invocation
without doing anything, the second test fails. Note, that I'm effectively
crippling the first test, which doesn't mind, but the second test seems to
depend on TWO invocations of SetVariableOperation to succeed.

The failure I'm seeing is in the assertEquals where I get a "do not insert"
although "insert" is expected, i.e., the preferences seem corrupted in
some way.

The crippling is done in SetVariableOperation with this simple addition:

	static int count = 0;
	protected void executeOperation() throws JavaModelException {
		  if ((count++) == 0)
			  return;
   // continue as normal

Can anybody reproduce this behavior? 
Any idea what might be going on here?
Comment 1 Stephan Herrmann CLA 2011-05-16 19:08:00 EDT
Created attachment 195797 [details]
Tweaks exposing the failure

This is how far I could get for today: apply this patch and the two-tests
setup will fail. This time I only disabled the following and only during the
first (unaffected!) test:

JavaModelManager.variables.put("JCL_LIB", variablePath);
JavaModelManager.variablePreferencesPut("JCL_LIB", variablePath)

This crippling produces the exact same effect I see when running
only the second test.

Re-enabling either statement repairs that second(!) test.
Comment 2 Ayushman Jain CLA 2011-05-17 03:57:59 EDT
Jay, please investigate. Thanks!
Comment 3 Jay Arthanareeswaran CLA 2011-05-17 06:58:36 EDT
Those two tests and few others have been deprecated, by the way.
Comment 4 Jay Arthanareeswaran CLA 2011-05-17 07:07:38 EDT
(In reply to comment #3)
> Those two tests and few others have been deprecated, by the way.

Sorry I misunderstood the usage of @deprecated in the tests.
Comment 5 Stephan Herrmann CLA 2011-08-14 11:41:38 EDT
Created attachment 201475 [details]
proposed fix

Today I saw more non-deterministic behavior of this bug:
- PASS with Object Teams in the loop
- FAIL with the current patch from bug 349326

After some more debugging I think I found the root cause for non-determinism:

org.eclipse.jdt.internal.core.JavaProject.setOptions(Map) loops over the
entries of the given Map, so this loop has non-deterministic order.
This shouldn't normally hurt, but since bug 324987
JavaModelManager.storePreference(String, String, IEclipsePreferences)
has a non-local side effect: if the given option is deprecated also the
values for its compatible replacements are modified.

Now guess what: if the deprecated option and its compatibles are both
contained in the given map, then
- if the deprecated option happens to be processed first all is well
- if the deprecated option HAPPENS TO BE PROCESSED AFTER its compatible
  the replacement will implicitly overwrite an explicit value

The patch fixes this by passing also the map into storePreferences so that
we can avoid this kind of conflicting overwrites.

Jay, does this all make sense?

I'm currently working on a deterministic test case... if that is possible.
Comment 6 Stephan Herrmann CLA 2011-08-14 12:14:03 EDT
Created attachment 201476 [details]
deterministic test

Here you go: this test uses a special Map with forced order from entrySet().

Deterministically fails without the patch from comment 5 and passes
with that patch :)
Comment 7 Jay Arthanareeswaran CLA 2011-08-16 02:19:09 EDT
I will take a look at the patch and let you know. I have assigned this bug to you, meanwhile.
Comment 8 Jay Arthanareeswaran CLA 2011-08-23 06:00:18 EDT
(In reply to comment #6)
> Created attachment 201476 [details]
> deterministic test
> 
> Here you go: this test uses a special Map with forced order from entrySet().
> 
> Deterministically fails without the patch from comment 5 and passes
> with that patch :)

Stephan, now I understand the fix and the patch looks good. However, this test always passes, with or without the patch. I will try and find out what is wrong.
Comment 9 Jay Arthanareeswaran CLA 2011-08-23 06:42:09 EDT
(In reply to comment #8)
> However, this test
> always passes, with or without the patch. I will try and find out what is
> wrong.

I see the option being removed (without the patch) but when it comes back to the test, the option is not null. Is it getting it from somewhere else, perhaps?
Comment 10 Stephan Herrmann CLA 2011-08-23 12:15:44 EDT
Created attachment 202014 [details]
Improved and combined patch

I don't know what happened to my test, it didn't work because the
ForcedOrderMap didn't properly answer to containsKey() requests,
thus the testOptions map was seen as being empty
(see the for loop in JavaProject.setOptions(Map)).

After adding the missing method I can again reproduce the failure,
that is now reliably toggled by adding/removing the fix.

So, this is what I would release unless you see more issues, Jay?
Comment 11 Jay Arthanareeswaran CLA 2011-08-23 12:58:00 EDT
(In reply to comment #10)
> Created attachment 202014 [details]
> Improved and combined patch
> 
> I don't know what happened to my test, it didn't work because the
> ForcedOrderMap didn't properly answer to containsKey() requests,
> thus the testOptions map was seen as being empty
> (see the for loop in JavaProject.setOptions(Map)).
> 
> After adding the missing method I can again reproduce the failure,
> that is now reliably toggled by adding/removing the fix.
> 
> So, this is what I would release unless you see more issues, Jay?

+1 to the patch.
Comment 12 Stephan Herrmann CLA 2011-08-23 14:05:39 EDT
Released in HEAD for 3.8M2
Comment 13 Olivier Thomann CLA 2011-09-13 12:27:29 EDT
Verified for 3.8M2.