/** * Runs the same model many times and ensures it is not creating many threads which would finish * blocking the JVM */ @Test public void testModelUsageOfThreads() { // first runs after which the reference will be taken final int HEATING_COUNT = 2; final int TEST_COUNT = 10; // heading period for (int i = 0; i < HEATING_COUNT; i++) runModel(); // take reference final int activeThreads = Thread.activeCount(); final Set<Thread> activeThreadsSet = collectCurrentThreads(); // run many for (int i = 0; i < TEST_COUNT; i++) { System.err.println("exec " + i + " threads " + Thread.activeCount()); runModel(); } if (Thread.activeCount() > activeThreads) { double nbPerIteration = Thread.activeCount() / TEST_COUNT; Set<Thread> threadsNow = collectCurrentThreads(); threadsNow.removeAll(activeThreadsSet); for (Thread t : threadsNow) { System.err.println("extra thread: " + t); t.stop(); } Thread.yield(); System.out.println("did cleaning help ? " + Thread.activeCount() + " / " + activeThreads); threadsNow = collectCurrentThreads(); threadsNow.removeAll(activeThreadsSet); for (Thread t : threadsNow) { System.out.println("extra thread: " + t); } fail( "about " + nbPerIteration + " novel threads are created at each run; this cannot be used in production"); } }
@Test public void recover_with_interrupt() throws InterruptedException { int scale = TT.scale(); if (scale == 0) return; e = openEngine(); if (!e.canRollback() || e instanceof StoreHeap) // TODO engine might have crash recovery, but no rollbacks return; // fill recids final int max = scale * 1000; final ArrayList<Long> recids = new ArrayList<Long>(); final AtomicLong a = new AtomicLong(10); final long counterRecid = e.put(a.get(), Serializer.LONG); Random r = new Random(a.get()); for (int j = 0; j < max; j++) { byte[] b = new byte[r.nextInt(100000)]; r.nextBytes(b); long recid = e.put(b, Serializer.BYTE_ARRAY_NOSIZE); recids.add(recid); } e.commit(); long endTime = TT.nowPlusMinutes(10); while (endTime > System.currentTimeMillis()) { final CountDownLatch latch = new CountDownLatch(1); Thread t = new Thread() { @Override public void run() { try { for (; ; ) { long A = a.incrementAndGet(); Random r = new Random(A); e.update(counterRecid, A, Serializer.LONG); for (long recid : recids) { byte[] b = new byte[r.nextInt(100000)]; r.nextBytes(b); e.update(recid, b, Serializer.BYTE_ARRAY_NOSIZE); } e.commit(); } } finally { latch.countDown(); } } }; t.start(); Thread.sleep(5000); t.stop(); latch.await(); if (!e.isClosed()) { close(); } // reopen and check the content e = openEngine(); // check if A-1 was commited long A = e.get(counterRecid, Serializer.LONG); assertTrue("" + A + " - " + a.get(), A == a.get() || A == a.get() - 1); r = new Random(A); for (long recid : recids) { byte[] b = new byte[r.nextInt(100000)]; r.nextBytes(b); byte[] b2 = e.get(recid, Serializer.BYTE_ARRAY_NOSIZE); assertTrue("Data were not commited recid=" + recid, Arrays.equals(b, b2)); } a.set(A); } e.close(); }