/** * Copyright 2011-2012 Akiban Technologies, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.persistit; import static org.junit.Assert.assertEquals; import java.io.InterruptedIOException; import java.util.Timer; import java.util.TimerTask; import org.junit.Ignore; import org.junit.Test; import com.persistit.Transaction.CommitPolicy; import com.persistit.exception.PersistitIOException; import com.persistit.exception.PersistitInterruptedException; /** * Interrupting a thread while it is performing a read or write closes the * underlying FileChannel. Subsequently Persistit emits errors such as the * following discovered on a DP site: * * ERROR [JOURNAL_COPIER] 2011-10-26 12:38:08,904 Slf4jAdapter.java (line 98) * [JOURNAL_COPIER] ERROR com.persistit.exception.PersistitIOException: * java.nio.channels.ClosedChannelException * * ERROR [JOURNAL_COPIER] 2011-10-26 12:38:18,909 Slf4jAdapter.java (line 98) * [JOURNAL_COPIER] ERROR Exception java.nio.channels.ClosedChannelException * while writing volume akiban_data(/var/lib/akiban/akiban_data.v01) page 53,248 * * ERROR [JOURNAL_COPIER] 2011-10-26 12:38:18,909 Slf4jAdapter.java (line 98) * [JOURNAL_COPIER] ERROR */ public class Bug882219Test extends PersistitUnitTestCase { // Thirty seconds final static long TIME = 20L * 1000L * 1000L * 1000L; // Flush caches: // sudo sh -c "echo 3 > /proc/sys/vm/drop_caches" // /* * Note: under Java 7 this test sometimes fails due to a bug in the JDK. The * result is a deadlock that sometimes prevents this test from finishing. * For this reason the test is currently Ignored, but we enable it for * special occasions. * * Reported under http://bugs.sun.com/ bug #9002674 */ @Test @Ignore public void testInterrupts() throws Exception { final Exchange ex = _persistit.getExchange("persistit", "bug882219", true); final Thread foregroundThread = Thread.currentThread(); final Timer timer = new Timer("Interrupter"); timer.schedule(new TimerTask() { @Override public void run() { foregroundThread.interrupt(); } }, 1000, 100); ex.removeAll(); final Transaction txn = ex.getTransaction(); final long start = System.nanoTime(); int errors = 0; int commits = 0; int transactions = 0; try { while (errors == 0 && System.nanoTime() - start < TIME) { boolean began = false; try { txn.begin(); began = true; ex.getValue().put(RED_FOX); for (int i = 0; i < 10000; i++) { ex.to(i).store(); } txn.commit(CommitPolicy.HARD); // force disk I/O commits++; } catch (final PersistitInterruptedException e) { // clear interrupted flag and ignore Thread.interrupted(); } catch (final PersistitIOException e) { if (e.getCause() instanceof InterruptedIOException) { // ignore } } catch (final Exception e) { // of interest e.printStackTrace(); errors++; break; } finally { if (began) { txn.end(); transactions++; } } } } finally { timer.cancel(); // make sure interrupted state is cleared. Thread.interrupted(); } System.out.printf("Transactions=%d Commits=%d Errors=%d", transactions, commits, errors); assertEquals(0, errors); } @Override public void runAllTests() throws Exception { } }