Resource locking with @ResourceLock in JUnit - Build an Automation Script
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; import org.junit.jupiter.api.parallel.ResourceLock; import static org.junit.jupiter.api.Assertions.assertTrue; @Execution(ExecutionMode.CONCURRENT) public class ResourceLockTest { private static volatile boolean resourceInUse = false; @Test @ResourceLock("SHARED_RESOURCE") void testMethodOne() throws InterruptedException { assertTrue(acquireResource()); // Simulate work with the resource Thread.sleep(200); releaseResource(); } @Test @ResourceLock("SHARED_RESOURCE") void testMethodTwo() throws InterruptedException { assertTrue(acquireResource()); // Simulate work with the resource Thread.sleep(200); releaseResource(); } private synchronized boolean acquireResource() { if (resourceInUse) { return false; // resource already in use } resourceInUse = true; return true; } private synchronized void releaseResource() { resourceInUse = false; } }
This test class uses @Execution(ExecutionMode.CONCURRENT) to allow parallel test execution.
Both test methods are annotated with @ResourceLock("SHARED_RESOURCE") to lock the same resource name.
The resourceInUse flag simulates the shared resource state. The acquireResource() method ensures only one test can use the resource at a time.
Each test sleeps for 200ms to simulate work, then releases the resource.
Assertions check that the resource was successfully acquired, confirming the lock works.
Because of @ResourceLock, JUnit runs these tests sequentially on the shared resource, preventing concurrent access.
Now add a third test method that locks a different resource and verify it runs concurrently with the others.
Practice
@ResourceLock in JUnit tests?Solution
Step 1: Understand the role of @ResourceLock
@ResourceLock is used to control access to shared resources in tests to avoid conflicts.Step 2: Identify the main purpose
Its main purpose is to prevent tests from interfering with each other when they share resources.Final Answer:
To prevent tests from interfering when sharing resources -> Option BQuick Check:
@ResourceLock prevents interference = C [OK]
- Thinking @ResourceLock speeds up tests
- Confusing @ResourceLock with test disabling
- Assuming it generates test data automatically
@ResourceLock?Solution
Step 1: Recall the correct annotation syntax
The correct syntax uses 'value' for resource name and 'mode' for access mode with enum ResourceAccessMode.Step 2: Match options with correct syntax
@ResourceLock(value = "database", mode = ResourceAccessMode.READ) matches the correct syntax: @ResourceLock(value = "database", mode = ResourceAccessMode.READ).Final Answer:
@ResourceLock(value = "database", mode = ResourceAccessMode.READ) -> Option CQuick Check:
Correct syntax uses value and mode = A [OK]
- Using wrong attribute names like resource or name
- Not using ResourceAccessMode enum
- Omitting enum prefix for mode
@ResourceLock(value = "file", mode = ResourceAccessMode.READ)
void testReadFile() { /* read file */ }
@ResourceLock(value = "file", mode = ResourceAccessMode.WRITE)
void testWriteFile() { /* write file */ }Solution
Step 1: Understand resource locking modes
READ mode allows multiple readers simultaneously, WRITE mode requires exclusive access.Step 2: Analyze parallel execution with conflicting modes
Since one test locks for READ and the other for WRITE on the same resource, they cannot run at the same time.Final Answer:
testReadFile and testWriteFile will run sequentially to avoid conflicts -> Option AQuick Check:
READ + WRITE locks cause sequential run = A [OK]
- Assuming READ and WRITE locks allow parallel runs
- Thinking tests will fail due to locking
- Believing WRITE lock allows multiple writers
@ResourceLock:@ResourceLock(value = "cache", mode = "READ")
void testCacheRead() { /* test code */ }Solution
Step 1: Check the mode attribute type
The mode attribute requires a ResourceAccessMode enum value, not a string.Step 2: Identify the error in the code
Using "READ" as a string causes a syntax error; it should be ResourceAccessMode.READ.Final Answer:
The mode value should be an enum, not a string -> Option AQuick Check:
mode must be enum, not string = B [OK]
- Passing mode as a string instead of enum
- Renaming value attribute incorrectly
- Thinking method must be static
@ResourceLock(value = "service", mode = ResourceAccessMode.READ)
void testServiceRead() { /* read operation */ }
@ResourceLock(value = "service", mode = ResourceAccessMode.READ)
void testAnotherRead() { /* another read */ }
@ResourceLock(value = "service", mode = ResourceAccessMode.WRITE)
void testServiceWrite() { /* write operation */ }How will JUnit handle these tests when running in parallel?
Solution
Step 1: Understand read locks behavior
Multiple tests with READ locks on the same resource can run simultaneously.Step 2: Understand write lock behavior
WRITE lock requires exclusive access, so it must wait until all READ locks finish.Step 3: Determine execution order
Both read tests run in parallel; the write test runs alone after reads complete.Final Answer:
Both read tests run in parallel; write test runs alone after reads finish -> Option DQuick Check:
Multiple READs parallel, WRITE exclusive = D [OK]
- Assuming WRITE runs before READs
- Thinking all tests run simultaneously
- Believing deadlock occurs automatically
Ready to prove it?
Pass the test and this pattern moves unknown
