Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad thread-interleaving occurs, as a result test failure happens #132

Open
Alisha-0321 opened this issue Nov 22, 2022 · 0 comments
Open

Comments

@Alisha-0321
Copy link

Commit Version - da35edc

Describe the bug
It is possible to find some bad thread interleaving where one thread reads the value of threadToMonitor from a synchronized block and another thread is writing on the same variable from a non-synchronized method (reset). Here, threadToMonitor is a shared variable, which is updated from a non-synchronized block at Line 78, but another thread uses threadToMonitor at Line 86 which is a synchronized block. I can observe such an execution results in the assertion fail from running an existing test delight.nashornsandbox.TestIssue34#testIssue34_Scenario5 with some added delay just before Line 78 of ThreadMonitor, resulting in the following stack trace.

Debug log
[INFO] Running delight.nashornsandbox.TestIssue34
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.793 s <<< FAILURE! - in delight.nashornsandbox.TestIssue34
[ERROR] delight.nashornsandbox.TestIssue34.testIssue34_Scenario5 Time elapsed: 0.772 s <<< FAILURE!
junit.framework.AssertionFailedError: null
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertTrue(Assert.java:27)
at delight.nashornsandbox.TestIssue34.testIssue34_Scenario5(TestIssue34.java:149)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:377)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:284)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:248)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:167)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:456)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:169)
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:595)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:581)

[ERROR] Failures:
[ERROR] TestIssue34.testIssue34_Scenario5:149 null
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0

To Reproduce
Steps to reproduce the behavior:

Add Thread.sleep(100) before Line 78 of ThreadMonitor.java
Run mvn test -Dtest=delight.nashornsandbox.TestIssue34#testIssue34_Scenario5

Expected behavior
Test failure should not occur

Additional context
When I investigated the ThreadMonitor.java, I find threadToMonitor is a shared variable that is used on Line 78 and Line 86. By injecting a delay before Line 78 of ThreadMonitor.java, I could get a different thread interleaving where the executed thread was late to set the value of threadToMonitor. As a result, other access of this shared variable is not properly worked, which leads the assertion fails.

Environment(please complete the following information):
I ran the test on an Ubuntu 20.04 LTS machine using OpenJDK 1.8.0_312.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant