/* * Copyright 2015-present Facebook, 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.facebook.buck.util; import static com.facebook.buck.util.MoreThrowables.getInitialCause; import static com.facebook.buck.util.MoreThrowables.getThrowableOrigin; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InterruptedIOException; import java.net.SocketTimeoutException; import java.nio.channels.ClosedByInterruptException; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; public class MoreThrowablesTest { @Rule public ExpectedException expected = ExpectedException.none(); @Test public void closedByInterruptException() throws InterruptedException { ClosedByInterruptException e = new ClosedByInterruptException(); expected.expect(InterruptedException.class); expected.expect(CausedBy.causedBy(e)); MoreThrowables.propagateIfInterrupt(e); } @Test public void interruptedIOException() throws InterruptedException { InterruptedIOException e = new InterruptedIOException(); expected.expect(InterruptedException.class); expected.expect(CausedBy.causedBy(e)); MoreThrowables.propagateIfInterrupt(e); } @Test public void interruptedException() throws InterruptedException { InterruptedException e = new InterruptedException(); expected.expect(InterruptedException.class); expected.expect(is(e)); MoreThrowables.propagateIfInterrupt(e); } @Test public void socketTimeoutException() throws InterruptedException { MoreThrowables.propagateIfInterrupt(new SocketTimeoutException()); } @Test public void otherException() throws InterruptedException { MoreThrowables.propagateIfInterrupt(new IOException()); } @Test public void testGetInitialCauseSingleThrowable() throws Exception { Exception exception = new Exception(); assertEquals(getInitialCause(exception), exception); } @Test public void testGetInitialCauseChainedThrowables() throws Exception { Exception lowLevelException = new Exception(); Exception midLevelExceptionA = new Exception(lowLevelException); Exception midLevelExceptionB = new Exception(midLevelExceptionA); Exception midLevelExceptionC = new Exception(midLevelExceptionB); Exception highLevelException = new Exception(midLevelExceptionC); assertEquals(getInitialCause(highLevelException), lowLevelException); } @Test public void testGetInitialCauseLoopedThrowables() throws Exception { Exception lowLevelException = new Exception(); Exception midLevelExceptionA = new Exception(lowLevelException); Exception midLevelExceptionB = new Exception(midLevelExceptionA); Exception midLevelExceptionC = new Exception(midLevelExceptionB); Exception highLevelException = new Exception(midLevelExceptionC); lowLevelException.initCause(highLevelException); assertEquals(getInitialCause(highLevelException), lowLevelException); } @Test public void testGetOrigin() throws Exception { Exception exception = new Exception(); String expectedPrefix = this.getClass().getCanonicalName() + ".testGetOrigin" + '(' + this.getClass().getSimpleName() + ".java:"; assertTrue(getThrowableOrigin(exception).startsWith(expectedPrefix)); } public static class CausedBy extends TypeSafeMatcher<Throwable> { private Throwable cause; public CausedBy(Throwable cause) { this.cause = cause; } @Override public boolean matchesSafely(Throwable throwable) { return throwable.getCause() == cause; } @Override public void describeTo(Description description) { description.appendText(String.format("caused by %s", cause.toString())); } public static <T> Matcher<Throwable> causedBy(Throwable throwable) { return new CausedBy(throwable); } } }