use of org.jboss.byteman.contrib.bmunit.BMUnitConfig in project partyline by Commonjava.
the class ConcurrentReadWithOneErrorClearLocksTest method run.
/**
* Test that locks for mutiple reads clear correctly. This will setup an script of events for
* a single file, where:
* <ol>
* <li>Multiple reads happen simultaneously, read the content, and close</li>
* <li>A single write at the end ensures the other locks are clear</li>
* </ol>
* @throws Exception
*/
/*@formatter:off*/
@BMRules(rules = { // setup the rendezvous for all threads, which will mean everything waits until all threads are started.
@BMRule(name = "init rendezvous", targetClass = "Partyline", targetMethod = "<init>", targetLocation = "ENTRY", action = "createCountDown(\"JOIN\", 2)"), // When we try to init a new JoinableFile for INPUT, simulate an IOException from somewhere deeper in the stack.
@BMRule(name = "new JoinableFile error", targetClass = "RandomAccessJF", targetMethod = "joinStream", targetLocation = "ENTRY", condition = "countDown(\"JOIN\")", action = "debug(\"Throwing test exception in \" + Thread.currentThread().getName()); " + "throw new java.io.IOException(\"Test exception\")") })
/*@formatter:on*/
@Test
@BMUnitConfig(debug = true)
public // @Ignore( "Inconsistent result between Maven/IDEA executions; needs to be fixed before release!" )
void run() throws Exception {
final ExecutorService execs = Executors.newFixedThreadPool(5);
final File f = temp.newFile("child.txt");
FileUtils.write(f, "test data");
final CountDownLatch latch = new CountDownLatch(4);
CountDownLatch readBeginLatch = new CountDownLatch(3);
CountDownLatch readEndLatch = new CountDownLatch(3);
final Partyline manager = getPartylineInstance();
manager.startReporting(5000, 5000);
final long start = System.currentTimeMillis();
execs.execute(writer(manager, f, latch, readEndLatch));
for (int i = 0; i < 3; i++) {
final int k = i;
execs.execute(reader(k, manager, f, latch, readBeginLatch, readEndLatch, null));
}
latch.await();
}
use of org.jboss.byteman.contrib.bmunit.BMUnitConfig in project partyline by Commonjava.
the class JoinFileWriteAndCloseBeforeFinishedTest method run.
/**
* Test verifies JoinableFile read could be done before its write stream close
* with read close delay, this setup an script of events for one single file, where:
* <ol>
* <li>Simulate JoinableFile write process </li>
* <li>Read should be proceeded before write stream close</li>
* </ol>
* @throws Exception
*/
@BMRules(rules = { // wait for read call to exit
@BMRule(name = "write close", targetClass = "RandomAccessJF", targetMethod = "close", targetLocation = "ENTRY", condition = "incrementCounter($0)==1", action = "debug(\">>>wait for service enter read.\");" + "waitFor(\"read\");" + "debug(\"<<<proceed with write close.\")"), // setup the trigger to signal write close when the read exits
@BMRule(name = "read", targetClass = "RandomAccessJF", targetMethod = "joinStream", targetLocation = "EXIT", action = "debug(\"<<<signalling write close.\"); " + "signalWake(\"read\", true);" + "debug(\"<<<signalled write close.\")") })
@Test
@BMUnitConfig(debug = true)
public void run() throws Exception {
final ExecutorService execs = Executors.newFixedThreadPool(2);
final CountDownLatch latch = new CountDownLatch(2);
final File file = temp.newFile();
String threadName = "writer" + writers++;
final JoinableFile stream = new RandomAccessJFS().getFile(file, new LocalLockOwner(file.getAbsolutePath(), name.getMethodName(), LockLevel.write), null, true, new SignallingLock());
execs.execute(() -> {
Thread.currentThread().setName(threadName);
new TimedFileWriter(stream, 1, latch).run();
});
execs.execute(() -> {
Thread.currentThread().setName("reader" + readers++);
new AsyncFileReader(0, -1, 6000, stream, latch).run();
});
System.out.println("Waiting for " + name.getMethodName() + " threads to complete.");
latch.await();
}
use of org.jboss.byteman.contrib.bmunit.BMUnitConfig in project partyline by Commonjava.
the class CleanupThreadIOExceptionHandleTest method run.
/**
* Simulate an IOException throw when JoinableFileManager try to close an outputStream in the method cleanupCurrentThread.
* Partyline will re-add the outputStream to the Thread Context if an io error occurred during its close process.
* Avoiding Partyline's IO error will be the real solution of caller's stream's re-close issue.
*
* @throws Exception
*/
@BMRule(name = "cleanupThreadIOExceptionHandleTest", targetClass = "java.io.OutputStream", targetMethod = "close", targetLocation = "ENTRY", action = "throw new java.io.IOException()")
@Test
@BMUnitConfig(debug = true)
@Ignore
public void run() throws Exception {
final Partyline manager = getPartylineInstance();
ThreadContext context = ThreadContext.getContext(true);
final File f = temp.newFile("test-byteman.txt");
FileUtils.write(f, "This is an IO Exception byteman test");
try {
manager.openOutputStream(f);
Map<String, WeakReference<Closeable>> open1 = (Map<String, WeakReference<Closeable>>) context.get(PARTYLINE_OPEN_FILES);
assertThat(open1.size(), equalTo(1));
manager.cleanupCurrentThread();
Map<String, WeakReference<Closeable>> open2 = (Map<String, WeakReference<Closeable>>) context.get(PARTYLINE_OPEN_FILES);
assertThat(open2.size(), equalTo(1));
} catch (IOException e) {
e.printStackTrace();
fail("Failed to outputStream io: " + e.getMessage());
}
}
use of org.jboss.byteman.contrib.bmunit.BMUnitConfig in project partyline by Commonjava.
the class ConcurrentReadErrorsClearLocksTest method run.
/**
* Test that locks for mutiple reads clear correctly. This will setup an script of events for
* a single file, where:
* <ol>
* <li>Multiple reads happen simultaneously, read the content, and close</li>
* <li>A single write at the end ensures the other locks are clear</li>
* </ol>
* @throws Exception
*/
/*@formatter:off*/
@BMRules(rules = { // When we try to init a new JoinableFile for INPUT, simulate an IOException from somewhere deeper in the stack.
@BMRule(name = "new JoinableFile error", targetClass = "RandomAccessJF", targetMethod = "<init>", targetLocation = "ENTRY", condition = "$4 == false", action = "debug(\"Throwing test exception.\"); " + "throw new java.io.IOException(\"Test exception\")") })
/*@formatter:on*/
@BMUnitConfig(debug = true)
@Test
public void run() throws Exception {
final ExecutorService execs = Executors.newFixedThreadPool(5);
final File f = temp.newFile("child.txt");
FileUtils.write(f, "test data");
final CountDownLatch latch = new CountDownLatch(4);
CountDownLatch readBeginLatch = new CountDownLatch(3);
CountDownLatch readEndLatch = new CountDownLatch(3);
final Partyline manager = getPartylineInstance();
final long start = System.currentTimeMillis();
execs.execute(writer(manager, f, latch, readEndLatch));
for (int i = 0; i < 3; i++) {
final int k = i;
execs.execute(reader(k, manager, f, latch, readBeginLatch, readEndLatch, null));
}
latch.await();
}
use of org.jboss.byteman.contrib.bmunit.BMUnitConfig in project partyline by Commonjava.
the class ClearCurrentThreadWithAnotherThreadReadingTest method run.
/**
* Given:
* <ul>
* <li>Two threads, T1 and T2</li>
* <li>One file containing some content, targeted for reading by both threads</li>
* </ul>
* <br/>
* Sequence:
* <br/>
* <ol>
* <li>T1 opens input stream</li>
* <li>T1 reads from input stream</li>
* <li>One of the following in unspecified order:
* <ol type="A">
* <li>T1 waits for T2 to open input stream</li>
* <li>T2 opens input stream</li>
* </ol>
* </li>
* <li>T1 calls {@link Partyline#cleanupCurrentThread()}</li>
* <li>T2 reads from input stream</li>
* </ol>
* <br/>
* Expected Result: Both threads successfully read correct content from the file.
*/
@Test
@BMUnitConfig(debug = true)
public void run() throws Exception {
final ExecutorService execs = Executors.newFixedThreadPool(2);
CountDownLatch t1StartLatch = new CountDownLatch(1);
CountDownLatch t2StartLatch = new CountDownLatch(1);
CountDownLatch t1CleanupLatch = new CountDownLatch(1);
final Partyline manager = getPartylineInstance();
final String content = "This is a test";
final File file = temp.newFile();
FileUtils.write(file, content);
List<String> returning = new ArrayList<String>();
execs.execute(() -> {
Thread.currentThread().setName("T1");
readFile(null, t1StartLatch, null, manager, file, returning);
try {
logger.info("Waiting for T2 to get an input stream");
t2StartLatch.await();
} catch (InterruptedException e) {
logger.warn(Thread.currentThread().getName() + " interrupted while waiting for second reader to open input stream.");
}
logger.info("Cleaning up T1 resources");
manager.cleanupCurrentThread();
logger.info("Signaling T1 cleanup is complete.");
t1CleanupLatch.countDown();
});
execs.execute(() -> {
Thread.currentThread().setName("T2");
readFile(t1StartLatch, t2StartLatch, t1CleanupLatch, manager, file, returning);
});
completionLatch.await();
assertThat("Both threads should return content!", returning.size(), equalTo(2));
assertThat(returning.get(0), equalTo(content));
assertThat(returning.get(1), equalTo(content));
}
Aggregations