diff --git a/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/Integration2PCTest.java b/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/Integration2PCTest.java index 5473f7f82ebc69a39c2c856311299ee90338de7e..aa06aa427bdb744907d058121d91ebe95417aa6b 100644 --- a/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/Integration2PCTest.java +++ b/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/Integration2PCTest.java @@ -336,6 +336,132 @@ public class Integration2PCTest extends AbstractIntegrationTest assertEquals(new String(bytesRead, StandardCharsets.UTF_8), CONTENT); } + @Test + public void testPrepareFailsAtAS() + { + // make prepare fail at AS + setApplicationServerProxyInterceptor((method, defaultAction) -> + { + if (method != null && method.equals("prepareTransaction")) + { + throw new RuntimeException("Test prepare exception"); + } else + { + defaultAction.call(); + } + }); + + OpenBIS openBIS = createOpenBIS(); + openBIS.setInteractiveSessionKey(TEST_INTERACTIVE_SESSION_KEY); + openBIS.login(USER, PASSWORD); + + openBIS.beginTransaction(); + + String owner = OWNER_PREFIX + UUID.randomUUID(); + String source = SOURCE_PREFIX + UUID.randomUUID(); + byte[] bytesToWrite = CONTENT.getBytes(StandardCharsets.UTF_8); + openBIS.getAfsServerFacade().write(owner, source, 0L, bytesToWrite, calculateMD5(bytesToWrite)); + + assertTransactions(coordinatorApi.getTransactionMap(), new TestTransaction(openBIS.getTransactionId(), TransactionStatus.BEGIN_FINISHED)); + + SpaceCreation spaceCreation = new SpaceCreation(); + spaceCreation.setCode(CODE_PREFIX + UUID.randomUUID()); + SpacePermId spaceId = openBIS.createSpaces(List.of(spaceCreation)).get(0); + + try + { + openBIS.commitTransaction(); + fail(); + } catch (Exception e) + { + assertEquals(e.getMessage(), + "Commit transaction '" + openBIS.getTransactionId() + "' failed."); + assertEquals(e.getCause().getMessage(), + "Prepare transaction '" + openBIS.getTransactionId() + + "' failed for participant 'application-server'. The transaction was rolled back."); + } + + assertTransactions(coordinatorApi.getTransactionMap()); + + // check data hasn't been committed + OpenBIS openBISNoTr = createOpenBIS(); + openBISNoTr.login(USER, PASSWORD); + + Space createdSpace = openBISNoTr.getSpaces(List.of(spaceId), new SpaceFetchOptions()).get(spaceId); + assertNull(createdSpace); + + try + { + openBISNoTr.getAfsServerFacade().read(owner, source, 0L, bytesToWrite.length); + fail(); + } catch (Exception expected) + { + } + } + + @Test + public void testPrepareFailsAtAFS() + { + // make prepare fail at AFS + setAfsServerProxyInterceptor((method, defaultAction) -> + { + if (method != null && method.equals("prepare")) + { + throw new RuntimeException("Test prepare exception"); + } else + { + defaultAction.call(); + } + }); + + OpenBIS openBIS = createOpenBIS(); + openBIS.setInteractiveSessionKey(TEST_INTERACTIVE_SESSION_KEY); + openBIS.login(USER, PASSWORD); + + openBIS.beginTransaction(); + + String owner = OWNER_PREFIX + UUID.randomUUID(); + String source = SOURCE_PREFIX + UUID.randomUUID(); + byte[] bytesToWrite = CONTENT.getBytes(StandardCharsets.UTF_8); + openBIS.getAfsServerFacade().write(owner, source, 0L, bytesToWrite, calculateMD5(bytesToWrite)); + + assertTransactions(coordinatorApi.getTransactionMap(), new TestTransaction(openBIS.getTransactionId(), TransactionStatus.BEGIN_FINISHED)); + + SpaceCreation spaceCreation = new SpaceCreation(); + spaceCreation.setCode(CODE_PREFIX + UUID.randomUUID()); + SpacePermId spaceId = openBIS.createSpaces(List.of(spaceCreation)).get(0); + + try + { + openBIS.commitTransaction(); + fail(); + } catch (Exception e) + { + assertEquals(e.getMessage(), + "Commit transaction '" + openBIS.getTransactionId() + "' failed."); + assertEquals(e.getCause().getMessage(), + "Prepare transaction '" + openBIS.getTransactionId() + + "' failed for participant 'afs-server'. The transaction was rolled back."); + } + + assertTransactions(coordinatorApi.getTransactionMap()); + + // check data hasn't been committed + OpenBIS openBISNoTr = createOpenBIS(); + openBISNoTr.login(USER, PASSWORD); + + Space createdSpace = openBISNoTr.getSpaces(List.of(spaceId), new SpaceFetchOptions()).get(spaceId); + assertNull(createdSpace); + + try + { + openBISNoTr.getAfsServerFacade().read(owner, source, 0L, bytesToWrite.length); + fail(); + } catch (Exception expected) + { + } + } + private void rollbackPreparedDatabaseTransactions() throws Exception { try (Connection connection = applicationServerSpringContext.getBean(DataSource.class).getConnection(); diff --git a/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/common/AbstractIntegrationTest.java b/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/common/AbstractIntegrationTest.java index 44614bf3bd250d86ea74cd94f33c4eb8b0cecaf7..b863c0fec0f44f7e43a9f0978410d4e8e181486d 100644 --- a/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/common/AbstractIntegrationTest.java +++ b/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/common/AbstractIntegrationTest.java @@ -147,6 +147,8 @@ public abstract class AbstractIntegrationTest public void beforeMethod(Method method) { log("BEFORE " + method.getDeclaringClass().getName() + "." + method.getName()); + setApplicationServerProxyInterceptor(null); + setAfsServerProxyInterceptor(null); } @AfterMethod @@ -271,7 +273,17 @@ public abstract class AbstractIntegrationTest + Arrays.toString( remoteInvocation.getArguments())); - super.service(proxyRequest, response); + if (applicationServerProxyInterceptor != null) + { + applicationServerProxyInterceptor.invoke(remoteInvocation.getMethodName(), () -> + { + super.service(proxyRequest, response); + return null; + }); + } else + { + super.service(proxyRequest, response); + } } catch (Exception e) { System.out.println("[AS PROXY] failed"); @@ -339,7 +351,7 @@ public abstract class AbstractIntegrationTest if (afsServerProxyInterceptor != null) { - afsServerProxyInterceptor.invoke(parameters.get("method"), parameters, () -> + afsServerProxyInterceptor.invoke(parameters.get("method"), () -> { super.service(proxyRequest, response); return null; @@ -409,7 +421,7 @@ public abstract class AbstractIntegrationTest public interface ProxyInterceptor { - void invoke(String method, Map<String, String> parameters, Callable<Void> defaultAction) throws Exception; + void invoke(String method, Callable<Void> defaultAction) throws Exception; } private static class ProxyRequest extends HttpServletRequestWrapper