diff --git a/tck/running_the_tck.asciidoc b/tck/running_the_tck.asciidoc index 4e7dd8bd..b850f21e 100644 --- a/tck/running_the_tck.asciidoc +++ b/tck/running_the_tck.asciidoc @@ -21,22 +21,27 @@ The TCK uses `JUnit 4` and `Arquillian`. The LRA TCK suite can be parametrized by following properties, handled in the suite with MicroProfile Config +`lra.tck.base.url`:: + The URL where the TCK suite deployment is exposed at. The TCK suite will construct path based on this URL. + The default base URL is `http://localhost:8180`. `lra.tck.timeout.factor`:: - timeout factor of default value `1.0`. When set bigger than `1.0` then timeout value will be bigger and waiting time are longer. + Timeout factor of default value `1.0`. When set bigger than `1.0` then timeout value will be bigger and waiting time are longer. When set-up lower then the timeouts will be shorter. `lra.tck.coordinator.waiting`:: - time that the tests waits for the coordinator start-up -`lra.tck.coordinator.hostname`:: - hostname where coordinator is available at for TCK suite can run the LRA status from the coordinator -`lra.tck.coordinator.port`:: - port where coordinator is available at for TCK suite can run the LRA status from the coordinator + Time that the tests waits for the LRA recovery starts-up. +`lra.http.host`, `lra.http.port`:: + Hostname and port where coordinator is available at. This is used for checking if tests can be started as endpoint is ready. +`lra.http.recovery.host`, `lra.http.recovery.port`, `lra.http.recovery.path`:: + Hostname, port and path for the recovery endpoint that will be contacted in tests checking recovery capabilities. == Prerequisites for the MicroProfile LRA TCK implementation -* `pom.xml` dependencies set-up -* MicroProfile Config being available in container for the TCK to run -* Arquillian container configured in `arquillian.xml` (tests could manually deploy with `@ArquillianResource Deployer`) -* `ResourceProvider` implemented and registered providing base URL where container starts the deployments +* `pom.xml` dependencies are set-up +* MicroProfile Config is providedby runtime for the LRA TCK suite could be run +* a default Arquillian container is configured in `arquillian.xml` (tests manually deploy with use of `@ArquillianResource Deployer`) +* implementation provides one implementation of `org.eclipse.microprofile.lra.client.LRAClient` as it's injected by TCK suite +* implementation has to provide one implementation of `org.eclipse.microprofile.lra.tck.spi.ManagementSPI`. This is an interface + with definition of util methods used by the TCK suite for its run. === Setting-up pom.xml dependencies and running the tests @@ -77,12 +82,12 @@ Here we use integration tests with `maven failsafe` where dependency to scan is === MicroProfile Config being available -The testsuite uses uses configuration while expecting MicroProfile Config is available. The maven coordinates +The testsuite uses configuration while expecting MicroProfile Config is available. The maven coordinates of config are `org.eclipse.microprofile.config:microprofile-config-api`. === Arquillian container -The `arquillian-*.xml` has to define a container that will be starated and managed by Arquillian lifecycle +The `arquillian-*.xml` has to define a container that will be started and managed by Arquillian lifecycle but that provide a way to deploy and undeploy deployments. That container to be expected with default type `suite`. @@ -98,36 +103,3 @@ but that provide a way to deploy and undeploy deployments. That container to be ---- - -=== ResourceProvider of base URL endpoint - -As TCK deployment provides LRA annotated JAX-RS classes which exposes REST endpoints. The TCK suite needs to call them. -The implementation has to provide the base URL that the endpoint paths can be constructed with. -The implementation does it by using Arquillian `ResoruceProvider` which returns the base `URL`. - -The LRA TCK suite uses injection - -[source, java] ----- -@ArquillianResource -private URL url; ----- - -The implementation has to define - -[source, java] ----- -public class TCKImplementationUrlProvider implements io.narayana.lra.tck.arquillian.ResourceProvider { - - @Override - public Object lookup(ArquillianResource arquillianResource, Annotation... annotations) { - return new URL("http://localhost:8080"); - } - - public boolean canProvide(Class type) { - return type.isAssignableFrom(URL.class); - } - -} ----- - diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTests.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTests.java index 9fb35519..6e23314b 100644 --- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTests.java +++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTests.java @@ -50,15 +50,14 @@ import javax.ws.rs.core.Response; import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.eclipse.microprofile.lra.annotation.LRAStatus; import org.eclipse.microprofile.lra.client.LRAClient; -import org.eclipse.microprofile.lra.client.LRAInfo; import org.eclipse.microprofile.lra.tck.participant.api.LraController; import org.eclipse.microprofile.lra.tck.participant.api.NoLRAController; import org.eclipse.microprofile.lra.tck.participant.api.Util; +import org.eclipse.microprofile.lra.tck.spi.ManagementSPI; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; -import org.jboss.arquillian.test.api.ArquillianResource; -import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; @@ -100,32 +99,56 @@ public class TckTests { private int coordinatorWaitingTime; /** - * Host name where coordinator is expected to be launch and TCK suite tries to connect to it at. - * The port is specifed by {@link #coordinatorPort}. + * Host name where LRA coordinator is present. */ - @Inject @ConfigProperty(name = "lra.tck.coordinator.hostname", defaultValue = "localhost") + @Inject @ConfigProperty(name = LRAClient.LRA_COORDINATOR_HOST_KEY, defaultValue = "localhost") private String coordinatorHostName; /** - * Port where coordinator is expected to be launch and TCK suite tries to connect to it at. - * The hostname is specifed by {@link #coordinatorHostName}. + * Port where LRA coordinator is present. */ - @Inject @ConfigProperty(name = "lra.tck.coordinator.port", defaultValue = "8080") + @Inject @ConfigProperty(name = LRAClient.LRA_COORDINATOR_PORT_KEY, defaultValue = "8080") private int coordinatorPort; /** - * Injection of base URL of container that deployment path can be constructed from. - * There is expected to be implemented by particular implementation - * the {@link ResourceProvider} that returns the base URL here. + * Host name where LRA recovery is expected to be launch and TCK suite tries to connect to it at. + * The port is specifed by {@link #recoveryPort}. */ - @ArquillianResource - private URL tckSuiteBaseUrl; + @Inject @ConfigProperty(name = LRAClient.LRA_RECOVERY_HOST_KEY, defaultValue = "localhost") + private String recoveryHostName; + + /** + * Port where LRA recovery is expected to be launch and TCK suite tries to connect to it at. + * The hostname is specifed by {@link #recoveryHostName}. + */ + @Inject @ConfigProperty(name = LRAClient.LRA_RECOVERY_PORT_KEY, defaultValue = "8080") + private int recoveryPort; + + /** + * Path where recovery is available to accept requests. + * The hostname of LRA recovery is specifed by {@link #recoveryHostName}, + * the port of LRA recovery is defined by {@link #recoveryPort}. + */ + @Inject @ConfigProperty(name = LRAClient.LRA_RECOVERY_PATH_KEY, defaultValue = "lra-recovery-coordinator") + private int recoveryPath; + + /** + * Base URL of LRA suite is started at. It's URL where container exposes the test suite deployment. + * The test paths will be constructed based on this base URL. + *

+ * The default base URL where TCK suite is expected to be started is http://localhost:8180/. + */ + @Inject @ConfigProperty(name = "lra.tck.base.url", defaultValue = "http://localhost:8180/") + private String tckSuiteBaseUrl; @Rule public TestName testName = new TestName(); @Inject private LRAClient lraClient; + @Inject + private ManagementSPI lraManagement; + private static URL recoveryCoordinatorBaseUrl; private static Client tckSuiteClient; private static Client recoveryCoordinatorClient; @@ -159,7 +182,7 @@ public void before() { setUpTestCase(); try { - tckSuiteTarget = tckSuiteClient.target(URI.create(new URL(tckSuiteBaseUrl, "/").toExternalForm())); + tckSuiteTarget = tckSuiteClient.target(URI.create(new URL(tckSuiteBaseUrl).toExternalForm())); } catch (MalformedURLException mfe) { throw new IllegalStateException("Cannot create URL for the LRA TCK suite base url " + tckSuiteBaseUrl, mfe); } @@ -168,7 +191,7 @@ public void before() { @After public void after() { - List activeLRAs = lraClient.getActiveLRAs(); + List activeLRAs = lraManagement.getLRAs(LRAStatus.Active); if (activeLRAs.size() != 0) { activeLRAs.forEach(lra -> { @@ -197,9 +220,9 @@ private void setUpTestCase() { while(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) - startTimeS <= coordinatorStartupWaitTime) { isCoordinatorStarted = !Util.isPortAvailable(coordinatorHostName, coordinatorPort); if(isCoordinatorStarted) - break; // coordinator hostname:port is occupied by a process, expecting coordinator is started + break; // hostname:port is occupied by some process, expecting coordinator is started } - Assert.assertTrue(String.format("Unfortunatelly there is no started process at %s:%d where coordinator " + Assert.assertTrue(String.format("Unfortunatelly there is no started process at %s:%d where LRA coordinator endpoint " + "is expected to be present. The test '%s' waited for the coordinator for %s seconds", coordinatorHostName, coordinatorPort, testName.getMethodName(), coordinatorStartupWaitTime), isCoordinatorStarted); @@ -207,8 +230,8 @@ private void setUpTestCase() { return; // we've already set up the recovery urls and REST clients for the tests try { - // TODO: what to do with this? recovery url is needed? - recoveryCoordinatorBaseUrl = new URL(String.format("http://%s:%d/%s", coordinatorHostName, coordinatorPort, "lra-recovery-coordinator")); + // TODO: what to do with this? recovery tests are valid? + recoveryCoordinatorBaseUrl = new URL(String.format("http://%s:%d/%s", recoveryHostName, recoveryPort, recoveryPath)); tckSuiteClient = ClientBuilder.newClient(); recoveryCoordinatorClient = ClientBuilder.newClient(); @@ -237,7 +260,7 @@ public void cancelLRA() throws WebApplicationException { lraClient.cancelLRA(lra); - List allClientLRAs = lraClient.getAllLRAs(); + List allClientLRAs = lraManagement.getLRAs(null); boolean isLraIdInList = containsLraId(allClientLRAs, lra); assertFalse("LRA '" + lra + "' should not be active anymore but was found in the list of all lras " @@ -256,7 +279,7 @@ public void closeLRA() throws WebApplicationException { lraClient.closeLRA(lra); - List allClientLRAs = lraClient.getAllLRAs(); + List allClientLRAs = lraManagement.getLRAs(null); boolean isLraIdInList = containsLraId(allClientLRAs, lra); assertFalse("LRA '" + lra + "' should not be active anymore but was found in the list of all lras " @@ -264,13 +287,13 @@ public void closeLRA() throws WebApplicationException { } /** - * Started LRA should be listed amongst active LRAs, see {@link LRAClient#getActiveLRAs()}. + * Started LRA should be listed amongst active LRAs. */ @Test public void getActiveLRAs() throws WebApplicationException { URL lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS); - List allActiveLRAs = lraClient.getActiveLRAs(); + List allActiveLRAs = lraManagement.getLRAs(LRAStatus.Active); boolean isLraIdInList = containsLraId(allActiveLRAs, lra); assertTrue("LRA '" + lra + "' should be listed in the list of the active LRAs, as it was not closed yet, but it isn't", @@ -280,13 +303,13 @@ public void getActiveLRAs() throws WebApplicationException { } /** - * Started LRA should be listed amongst active LRAs, see {@link LRAClient#getAllLRAs()}. + * Started LRA should be listed amongst active LRAs. */ @Test public void getAllLRAs() throws WebApplicationException { URL lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS); - List allClientLRAs = lraClient.getAllLRAs(); + List allClientLRAs = lraManagement.getLRAs(null); boolean isLraIdInList = containsLraId(allClientLRAs, lra); assertTrue("LRA '" + lra + "' should be listed in the list of the all LRAs, as it was not closed yet, but it isn't", @@ -302,19 +325,19 @@ public void getRecoveringLRAs() throws WebApplicationException { } /** - * Started LRA should in state 'active', see {@link LRAClient#isActiveLRA(URL)}. + * Started LRA should in state 'active'. */ @Test public void isActiveLRA() throws WebApplicationException { URL lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS); - assertTrue("LRA '" + lra + "' is not denoted as active even it was started", lraClient.isActiveLRA(lra)); + assertTrue("LRA '" + lra + "' is not denoted as active even it was started", lraManagement.getStatus(lra).isActive()); lraClient.closeLRA(lra); } /** - * Canceled LRA should in state 'compensated', see {@link LRAClient#isCompensatedLRA(URL)}. + * Canceled LRA should in state 'compensated'. * NOTE: the coordinator cleans up when canceled */ @Test @@ -324,11 +347,11 @@ public void isCompensatedLRA() throws WebApplicationException { lraClient.cancelLRA(lra); - assertTrue("LRA '" + lra + "' is not denoted as compensated even it was canceled", lraClient.isCompensatedLRA(lra)); + assertTrue("LRA '" + lra + "' is not denoted as compensated even it was canceled", lraManagement.getStatus(lra).isCompensated()); } /** - * Closed LRA should in state 'completed', see {@link LRAClient#isCompletedLRA(URL)}. + * Closed LRA should in state 'completed'. * NOTE: the coordinator cleans up when completed */ @Test @@ -338,7 +361,7 @@ public void isCompletedLRA() throws WebApplicationException { lraClient.closeLRA(lra); - assertTrue("LRA '" + lra + "' is not denoted as compensated even it was canceled", lraClient.isCompletedLRA(lra)); + assertTrue("LRA '" + lra + "' is not denoted as compensated even it was canceled", lraManagement.getStatus(lra).isComplete()); } /** @@ -355,7 +378,7 @@ public void joinLRAViaBody() throws WebApplicationException { String lraId = checkStatusReadAndClose(Response.Status.OK, response, resourcePath); // validate that the LRA coordinator no longer knows about lraId - List activeLras = lraClient.getActiveLRAs(); + List activeLras = lraManagement.getLRAs(LRAStatus.Active); boolean isLraIdInList = containsLraId(activeLras, lraId); // the resource /activities/work is annotated with Type.REQUIRED so the container should have ended it @@ -391,7 +414,7 @@ public void nestedActivity() throws WebApplicationException { lraClient.closeLRA(lra); // validate that the nested LRA was closed - List activeLras = lraClient.getActiveLRAs(); + List activeLras = lraManagement.getLRAs(LRAStatus.Active); boolean isLraIdInList = containsLraId(activeLras, nestedLraId); // the resource /activities/work is annotated with Type.REQUIRED so the container should have ended it @@ -430,7 +453,7 @@ public void joinLRAViaHeader() throws WebApplicationException { checkStatusAndClose(Response.Status.OK, response, resourcePath); // validate that the LRA coordinator still knows about lraId - List allActiveLRAs = lraClient.getActiveLRAs(); + List allActiveLRAs = lraManagement.getLRAs(LRAStatus.Active); boolean isLraIdInList = containsLraId(allActiveLRAs, lra); assertTrue("LRA '" + lra + "' should be active as not closed yet. But it was not found in the list of active LRAs " + allActiveLRAs, isLraIdInList); @@ -439,7 +462,7 @@ public void joinLRAViaHeader() throws WebApplicationException { lraClient.closeLRA(lra); // check that LRA coordinator no longer knows about lraId - allActiveLRAs = lraClient.getActiveLRAs(); + allActiveLRAs = lraManagement.getLRAs(LRAStatus.Active); assertFalse("LRA '" + lra + "' should not be active anymore as it was closed yet. But it was not found amongst active LRAs " + allActiveLRAs, containsLraId(allActiveLRAs, lra)); @@ -451,7 +474,7 @@ public void joinLRAViaHeader() throws WebApplicationException { @Test public void join() throws WebApplicationException { - List lras = lraClient.getActiveLRAs(); + List lras = lraManagement.getLRAs(LRAStatus.Active); int count = lras.size(); URL lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS); WebTarget resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path(TRANSACTIONAL_WORK_PATH); @@ -460,7 +483,7 @@ public void join() throws WebApplicationException { checkStatusAndClose(Response.Status.OK, response, resourcePath); lraClient.closeLRA(lra); - lras = lraClient.getActiveLRAs(); + lras = lraManagement.getLRAs(LRAStatus.Active); assertEquals("Number of LRA instances before the test does not match current number of active LRAs. The joint LRA should be closed already. " + "The test call went to LRA controller at " + resourcePath.getUri(), count, lras.size()); } @@ -608,7 +631,7 @@ public void timeLimit() { */ // TODO: is this test to be run? private void testUserData() { - List beforeActiveLRAs = lraClient.getActiveLRAs(); + List beforeActiveLRAs = lraManagement.getLRAs(LRAStatus.Active); String testData = "test participant data"; WebTarget resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path("testUserData"); @@ -617,7 +640,7 @@ private void testUserData() { String activityId = checkStatusReadAndClose(Response.Status.OK, response, resourcePath); - List activeLRAs = lraClient.getActiveLRAs(); + List activeLRAs = lraManagement.getLRAs(LRAStatus.Active); assertEquals("produced the wrong LRA count on call of method " + resourcePath.getUri(), beforeActiveLRAs.size(), activeLRAs.size()); @@ -641,7 +664,7 @@ public void acceptTest() throws WebApplicationException { // TODO the spec does not specifiy recovery semantics private void joinAndEnd(boolean waitForRecovery, boolean close, String path, String path2) throws WebApplicationException { - int beforeActiveLRACount = lraClient.getActiveLRAs().size(); + int beforeActiveLRACount = lraManagement.getLRAs(LRAStatus.Active).size(); URL lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS); WebTarget resourcePath = tckSuiteTarget.path(path).path(path2); @@ -666,7 +689,7 @@ private void joinAndEnd(boolean waitForRecovery, boolean close, String path, Str checkStatusAndClose(Response.Status.OK, response2, resourcePath); } - int activeLRACount = lraClient.getActiveLRAs().size(); + int activeLRACount = lraManagement.getLRAs(LRAStatus.Active).size(); assertEquals("Expecting all LRAs were recovered and the number of active LRAs before test matches the number after. " + "The test call went to " + resourcePath.getUri(), @@ -795,7 +818,7 @@ private void multiLevelNestedActivity(CompletionType how, int nestedCnt) throws assertNotNull("expecting a LRA string returned from " + resourcePath.getUri(), lraStr); assert lraStr != null; String[] lraArray = lraStr.split(","); - final List lras = lraClient.getActiveLRAs(); + final List lras = lraManagement.getLRAs(LRAStatus.Active); URL[] urls = new URL[lraArray.length]; IntStream.range(0, urls.length).forEach(i -> { @@ -857,7 +880,7 @@ private void multiLevelNestedActivity(CompletionType how, int nestedCnt) throws } // validate that the top level and nested LRAs are gone - final List lras2 = lraClient.getActiveLRAs(); + final List lras2 = lraManagement.getLRAs(LRAStatus.Active); IntStream.rangeClosed(0, nestedCnt).forEach(i -> assertFalse( "multiLevelNestedActivity: top level or nested activity still active (called path " + resourcePath.getUri() + ")", @@ -934,7 +957,7 @@ private void cancelCheck(String path) { try { assertTrue("LRA '" + lra + "' should have been cancelled (called to " + resourcePath.getUri() + ")", - !lraClient.isActiveLRA(lra)); + !lraManagement.getStatus(lra).isActive()); } catch (NotFoundException ignore) { // means the LRA has gone } diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraController.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraController.java index ca8bb524..fcb2cc09 100644 --- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraController.java +++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraController.java @@ -32,7 +32,6 @@ import org.eclipse.microprofile.lra.annotation.NestedLRA; import org.eclipse.microprofile.lra.annotation.Status; import org.eclipse.microprofile.lra.client.IllegalLRAStateException; -import org.eclipse.microprofile.lra.tck.participant.model.Activity; import org.eclipse.microprofile.lra.annotation.ParticipantStatus; import javax.enterprise.context.ApplicationScoped;