You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/11/18 11:14:53 UTC
[isis] branch master updated: ISIS-2464: make Application-Layer
test code reusable for different aspects of testing
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 97db60a ISIS-2464: make Application-Layer test code reusable for different aspects of testing
97db60a is described below
commit 97db60abadc4df89e6ad0f289d063a08b4e38a49
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Nov 18 12:14:41 2020 +0100
ISIS-2464: make Application-Layer test code reusable for different
aspects of testing
introduces ApplicationLayerTestFactory, which can be used via JUnit5
DynamicTest API
---
.../applayer/auditing/AuditerServiceTest.java | 86 +++++++
.../{ => applayer}/command/CommandTest.java | 4 +-
.../applayer/publishing/PublisherServiceTest.java | 88 ++++++++
.../testdomain/auditing/AuditerServiceTest.java | 194 ----------------
.../publishing/PublisherServiceTest.java | 250 ---------------------
.../applayer/ApplicationLayerTestFactory.java | 197 ++++++++++++++++
.../auditing/AuditerServiceForTesting.java | 2 +-
.../auditing/Configuration_usingAuditing.java | 2 +-
.../publishing/Configuration_usingPublishing.java | 2 +-
.../publishing/PublisherServiceForTesting.java | 28 ++-
.../commons/InteractionTestAbstract.java | 2 +-
.../entitychangetracking/ChangedObjectsTest.java | 6 +-
12 files changed, 407 insertions(+), 454 deletions(-)
diff --git a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/applayer/auditing/AuditerServiceTest.java b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/applayer/auditing/AuditerServiceTest.java
new file mode 100644
index 0000000..f4f0299
--- /dev/null
+++ b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/applayer/auditing/AuditerServiceTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.isis.testdomain.applayer.auditing;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.core.config.presets.IsisPresets;
+import org.apache.isis.testdomain.applayer.ApplicationLayerTestFactory;
+import org.apache.isis.testdomain.conf.Configuration_usingJdo;
+import org.apache.isis.testdomain.util.CollectionAssertions;
+import org.apache.isis.testdomain.util.kv.KVStoreForTesting;
+import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.TestFactory;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+
+import lombok.val;
+
+@SpringBootTest(
+ classes = {
+ Configuration_usingJdo.class,
+ Configuration_usingAuditing.class,
+ ApplicationLayerTestFactory.class
+ },
+ properties = {
+ "logging.level.org.apache.isis.testdomain.util.rest.KVStoreForTesting=DEBUG"
+ })
+@TestPropertySource({
+ IsisPresets.UseLog4j2Test
+})
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+class AuditerServiceTest extends IsisIntegrationTestAbstract {
+
+ @Inject private ApplicationLayerTestFactory testFactory;
+ @Inject private KVStoreForTesting kvStore;
+
+ @TestFactory @DisplayName("Application Layer")
+ List<DynamicTest> generateTests() {
+ return testFactory.generateTests(this::given, this::thenHappyCase, this::thenFailureCase);
+ }
+
+ private void given() {
+ AuditerServiceForTesting.clearAuditEntries(kvStore);
+ }
+
+ private void thenHappyCase() {
+ assertHasAuditEntries(Can.of(
+ "Jdo Book/name: 'Sample Book' -> 'Book #2'"));
+ }
+
+ private void thenFailureCase() {
+ assertHasAuditEntries(Can.empty());
+ }
+
+ // -- HELPER
+
+ private void assertHasAuditEntries(Can<String> expectedAuditEntries) {
+ val actualAuditEntries = AuditerServiceForTesting.getAuditEntries(kvStore);
+ CollectionAssertions.assertComponentWiseEquals(expectedAuditEntries, actualAuditEntries);
+ }
+
+
+}
diff --git a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/command/CommandTest.java b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/applayer/command/CommandTest.java
similarity index 96%
rename from regressiontests/incubating/src/test/java/org/apache/isis/testdomain/command/CommandTest.java
rename to regressiontests/incubating/src/test/java/org/apache/isis/testdomain/applayer/command/CommandTest.java
index 1ce295f..41cea22 100644
--- a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/command/CommandTest.java
+++ b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/applayer/command/CommandTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.testdomain.command;
+package org.apache.isis.testdomain.applayer.command;
import javax.inject.Inject;
@@ -32,7 +32,7 @@ import org.apache.isis.applib.services.factory.FactoryService;
import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.applib.services.wrapper.WrapperFactory;
import org.apache.isis.core.config.presets.IsisPresets;
-import org.apache.isis.testdomain.auditing.Configuration_usingAuditing;
+import org.apache.isis.testdomain.applayer.auditing.Configuration_usingAuditing;
import org.apache.isis.testdomain.conf.Configuration_usingJdo;
import org.apache.isis.testdomain.jdo.JdoInventoryManager;
import org.apache.isis.testdomain.jdo.JdoTestDomainPersona;
diff --git a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/applayer/publishing/PublisherServiceTest.java b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/applayer/publishing/PublisherServiceTest.java
new file mode 100644
index 0000000..ea1d963
--- /dev/null
+++ b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/applayer/publishing/PublisherServiceTest.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.isis.testdomain.applayer.publishing;
+
+import static org.apache.isis.testdomain.applayer.publishing.PublisherServiceForTesting.clearPublishedEntries;
+import static org.apache.isis.testdomain.applayer.publishing.PublisherServiceForTesting.getCreated;
+import static org.apache.isis.testdomain.applayer.publishing.PublisherServiceForTesting.getDeleted;
+import static org.apache.isis.testdomain.applayer.publishing.PublisherServiceForTesting.getLoaded;
+import static org.apache.isis.testdomain.applayer.publishing.PublisherServiceForTesting.getModified;
+import static org.apache.isis.testdomain.applayer.publishing.PublisherServiceForTesting.getUpdated;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.isis.core.config.presets.IsisPresets;
+import org.apache.isis.testdomain.applayer.ApplicationLayerTestFactory;
+import org.apache.isis.testdomain.conf.Configuration_usingJdo;
+import org.apache.isis.testdomain.util.kv.KVStoreForTesting;
+import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+
+@SpringBootTest(
+ classes = {
+ Configuration_usingJdo.class,
+ Configuration_usingPublishing.class,
+ ApplicationLayerTestFactory.class
+ },
+ properties = {
+ "logging.level.org.apache.isis.persistence.jdo.datanucleus5.persistence.IsisTransactionJdo=DEBUG",
+ "logging.level.org.apache.isis.core.runtimeservices.session.IsisInteractionFactoryDefault=DEBUG",
+ "logging.level.org.apache.isis.persistence.jdo.datanucleus5.datanucleus.service.JdoPersistenceLifecycleService=DEBUG"
+ })
+@TestPropertySource({
+ IsisPresets.UseLog4j2Test
+})
+class PublisherServiceTest extends IsisIntegrationTestAbstract {
+
+ @Inject private ApplicationLayerTestFactory testFactory;
+ @Inject private KVStoreForTesting kvStore;
+
+ @TestFactory @DisplayName("Application Layer")
+ List<DynamicTest> generateTests() {
+ return testFactory.generateTests(this::given, this::thenHappyCase, this::thenFailureCase);
+ }
+
+ private void given() {
+ clearPublishedEntries(kvStore);
+ }
+
+ private void thenHappyCase() {
+ assertEquals(0, getCreated(kvStore));
+ assertEquals(0, getDeleted(kvStore));
+ //assertEquals(1, getLoaded()); // not reproducible
+ assertEquals(1, getUpdated(kvStore));
+ assertEquals(1, getModified(kvStore));
+ }
+
+ private void thenFailureCase() {
+ assertEquals(0, getCreated(kvStore));
+ assertEquals(0, getDeleted(kvStore));
+ assertEquals(0, getLoaded(kvStore));
+ assertEquals(0, getUpdated(kvStore));
+ assertEquals(0, getModified(kvStore));
+ }
+
+}
diff --git a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/auditing/AuditerServiceTest.java b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/auditing/AuditerServiceTest.java
deleted file mode 100644
index 484e0f1..0000000
--- a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/auditing/AuditerServiceTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.isis.testdomain.auditing;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.inject.Inject;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.MethodOrderer;
-import org.junit.jupiter.api.Order;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestMethodOrder;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.support.TransactionTemplate;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import org.apache.isis.applib.services.repository.RepositoryService;
-import org.apache.isis.applib.services.wrapper.DisabledException;
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.applib.services.wrapper.control.AsyncControl;
-import org.apache.isis.applib.services.wrapper.control.SyncControl;
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.debug._Probe;
-import org.apache.isis.core.config.presets.IsisPresets;
-import org.apache.isis.testdomain.auditing.AuditerServiceForTesting;
-import org.apache.isis.testdomain.auditing.Configuration_usingAuditing;
-import org.apache.isis.testdomain.conf.Configuration_usingJdo;
-import org.apache.isis.testdomain.jdo.JdoTestDomainPersona;
-import org.apache.isis.testdomain.jdo.entities.JdoBook;
-import org.apache.isis.testdomain.util.CollectionAssertions;
-import org.apache.isis.testdomain.util.kv.KVStoreForTesting;
-import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
-import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
-
-import static org.apache.isis.applib.services.wrapper.control.AsyncControl.returningVoid;
-
-import lombok.val;
-
-@SpringBootTest(
- classes = {
- Configuration_usingJdo.class,
- Configuration_usingAuditing.class
- },
- properties = {
- "logging.level.org.apache.isis.testdomain.util.rest.KVStoreForTesting=DEBUG"
- })
-@TestPropertySource({
- IsisPresets.UseLog4j2Test
-})
-@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
-class AuditerServiceTest extends IsisIntegrationTestAbstract {
-
- @Inject private RepositoryService repository;
- @Inject private FixtureScripts fixtureScripts;
- @Inject private WrapperFactory wrapper;
- @Inject private KVStoreForTesting kvStore;
- @Inject private PlatformTransactionManager txMan;
-
- @BeforeEach
- void setUp() {
- // cleanup
- fixtureScripts.runPersona(JdoTestDomainPersona.PurgeAll);
-
- // given
- fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
- }
-
- @Test @Order(1)
- void auditerService_shouldBeAwareOfInventoryChanges() {
-
- // given
- val book = repository.allInstances(JdoBook.class).listIterator().next();
- AuditerServiceForTesting.clearAuditEntries(kvStore);
-
- _Probe.errOut("(1) BEFORE BOOK UPDATED");
-
- // when - running within its own transactional boundary
- val transactionTemplate = new TransactionTemplate(txMan);
- transactionTemplate.execute(status -> {
-
- book.setName("Book #2");
- repository.persist(book);
-
- // then - before the commit
- assertFalse(kvStore.get(AuditerServiceForTesting.class, "audit").isPresent());
-
- return null;
- });
-
- _Probe.errOut("(1) AFTER BOOK UPDATED");
-
- // then - after the commit
- assertHasAuditEntries(Can.of(
- "Jdo Book/name: 'Sample Book' -> 'Book #2'"));
- }
-
- @Test @Order(2)
- void auditerService_shouldBeAwareOfInventoryChanges_whenUsingSyncExecution() throws ExecutionException, InterruptedException, TimeoutException {
-
- // given
- val book = repository.allInstances(JdoBook.class).listIterator().next();
- AuditerServiceForTesting.clearAuditEntries(kvStore);
-
- _Probe.errOut("(2) BEFORE BOOK UPDATED");
-
- // when - running synchronous
- val control = SyncControl.control().withSkipRules();
- wrapper.wrap(book, control).setName("Book #2");
-
- _Probe.errOut("(2) AFTER BOOK UPDATED");
-
- // then - after the commit
- assertHasAuditEntries(Can.of(
- "Jdo Book/name: 'Sample Book' -> 'Book #2'"));
- }
-
-
- @Test @Order(3)
- void auditerService_shouldBeAwareOfInventoryChanges_whenUsingAsyncExecution() throws ExecutionException, InterruptedException, TimeoutException {
-
- // given
- val book = repository.allInstances(JdoBook.class).listIterator().next();
- AuditerServiceForTesting.clearAuditEntries(kvStore);
- val latch = kvStore.latch(AuditerServiceForTesting.class);
-
- _Probe.errOut("(3) BEFORE BOOK UPDATED");
-
- // when - running within its own background task
- AsyncControl<Void> control = returningVoid().withSkipRules();
- wrapper.asyncWrap(book, control).setName("Book #2");
-
- control.getFuture().get(10, TimeUnit.SECONDS); // blocks the current thread
-
- latch.await(2, TimeUnit.SECONDS);
-
- _Probe.errOut("(3) AFTER BOOK UPDATED");
-
- // then - after the commit
- assertHasAuditEntries(Can.of(
- "Jdo Book/name: 'Sample Book' -> 'Book #2'"));
- }
-
- @Test @Order(4)
- void auditerService_shouldNotBeAwareOfInventoryChanges_whenUsingAsyncExecutionThatFails() {
-
- // given
- val book = repository.allInstances(JdoBook.class).listIterator().next();
- AuditerServiceForTesting.clearAuditEntries(kvStore);
-
- // when - running within its own background task
- assertThrows(DisabledException.class, ()->{
-
- wrapper.asyncWrap(book, returningVoid()).setName("Book #2");
-
- returningVoid().getFuture().get(1000, TimeUnit.SECONDS);
-
- });
-
- // then - after the exception
- assertHasAuditEntries(Can.empty());
- }
-
- // -- HELPER
-
- private void assertHasAuditEntries(Can<String> expectedAuditEntries) {
- val actualAuditEntries = AuditerServiceForTesting.getAuditEntries(kvStore);
- CollectionAssertions.assertComponentWiseEquals(expectedAuditEntries, actualAuditEntries);
- }
-
-
-}
diff --git a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PublisherServiceTest.java b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PublisherServiceTest.java
deleted file mode 100644
index 7eeef99..0000000
--- a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PublisherServiceTest.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.isis.testdomain.publishing;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.inject.Inject;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.MethodOrderer;
-import org.junit.jupiter.api.Order;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestMethodOrder;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.support.TransactionTemplate;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import org.apache.isis.applib.services.publish.PublishedObjects;
-import org.apache.isis.applib.services.repository.RepositoryService;
-import org.apache.isis.applib.services.wrapper.DisabledException;
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.applib.services.wrapper.control.AsyncControl;
-import org.apache.isis.applib.services.wrapper.control.SyncControl;
-import org.apache.isis.applib.services.xactn.TransactionService;
-import org.apache.isis.applib.services.xactn.TransactionState;
-import org.apache.isis.commons.internal.debug._Probe;
-import org.apache.isis.core.config.presets.IsisPresets;
-import org.apache.isis.testdomain.conf.Configuration_usingJdo;
-import org.apache.isis.testdomain.jdo.JdoTestDomainPersona;
-import org.apache.isis.testdomain.jdo.entities.JdoBook;
-import org.apache.isis.testdomain.util.kv.KVStoreForTesting;
-import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
-import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
-
-import static org.apache.isis.applib.services.wrapper.control.AsyncControl.returningVoid;
-
-import lombok.val;
-
-@SpringBootTest(
- classes = {
- Configuration_usingJdo.class,
- Configuration_usingPublishing.class
- },
- properties = {
- "logging.level.org.apache.isis.persistence.jdo.datanucleus5.persistence.IsisTransactionJdo=DEBUG",
- "logging.level.org.apache.isis.core.runtimeservices.session.IsisInteractionFactoryDefault=DEBUG",
- "logging.level.org.apache.isis.persistence.jdo.datanucleus5.datanucleus.service.JdoPersistenceLifecycleService=DEBUG"
- })
-@TestPropertySource({
- IsisPresets.UseLog4j2Test
-})
-@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
-class PublisherServiceTest extends IsisIntegrationTestAbstract {
-
- @Inject private RepositoryService repository;
- @Inject private FixtureScripts fixtureScripts;
- @Inject private WrapperFactory wrapper;
- @Inject private PlatformTransactionManager txMan;
- @Inject private KVStoreForTesting kvStore;
- @Inject private TransactionService transactionService;
-
- @BeforeEach
- void setUp() {
-
- // cleanup
- fixtureScripts.runPersona(JdoTestDomainPersona.PurgeAll);
-
- // given
- fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
- }
-
- @Test @Order(0)
- void no_initial_tx_context() {
- val txState = transactionService.currentTransactionState();
- assertEquals(TransactionState.NONE, txState);
- }
-
- @Test @Order(1)
- void publisherService_shouldBeAwareOfInventoryChanges() {
-
- // given
- val book = repository.allInstances(JdoBook.class).listIterator().next();
- PublisherServiceForTesting.clearPublishedEntries(kvStore);
-
- _Probe.errOut("(1) BEFORE BOOK UPDATED");
-
- // when - running within its own transactional boundary
- val transactionTemplate = new TransactionTemplate(txMan);
- transactionTemplate.execute(status -> {
-
- book.setName("Book #2");
- repository.persist(book);
-
- // then - before the commit
- assertEquals(0, kvStore.countEntries(PublisherServiceForTesting.class));
-
- return null;
- });
-
- _Probe.errOut("(1) AFTER BOOK UPDATED");
-
- // this test does not trigger publishing
- // because invocation happens directly rather than through the means of
- // an implementation of ObjectMemberAbstract, which has the meta-data
- // required to generate the associated CommandDTO
-
- //TODO however, metrics as tested below are still available even though Commands don't have CommandDTOs
-
- // then - after the commit
- assertEquals(0, getCreated());
- assertEquals(0, getDeleted());
- //assertEquals(1, getLoaded()); // not reproducible
- //TODO assertEquals(1, getUpdated());
- //TODO assertEquals(1, getModified());
- }
-
- @Test @Order(2)
- void publisherService_shouldBeAwareOfInventoryChanges_whenUsingSyncExecution()
- throws InterruptedException, ExecutionException, TimeoutException {
-
- // given
- val book = repository.allInstances(JdoBook.class).listIterator().next();
- PublisherServiceForTesting.clearPublishedEntries(kvStore);
-
- _Probe.errOut("(2) BEFORE BOOK UPDATED");
-
- // when - running synchronous
- val syncControl = SyncControl.control().withSkipRules();
- wrapper.wrap(book, syncControl).setName("Book #2"); // don't enforce rules for this test
-
- _Probe.errOut("(2) AFTER BOOK UPDATED");
-
-
- // then - after the commit
- assertEquals(0, getCreated());
- assertEquals(0, getDeleted());
- //assertEquals(1, getLoaded()); // not reproducible
- assertEquals(1, getUpdated());
- assertEquals(1, getModified());
-
- }
-
- @Test @Order(3)
- void publisherService_shouldBeAwareOfInventoryChanges_whenUsingAsyncExecution()
- throws InterruptedException, ExecutionException, TimeoutException {
-
- // given
- val book = repository.allInstances(JdoBook.class).listIterator().next();
- PublisherServiceForTesting.clearPublishedEntries(kvStore);
- val latch = kvStore.latch(PublisherServiceForTesting.class);
-
- _Probe.errOut("(3) BEFORE BOOK UPDATED");
-
- // when - running within its own background task
- AsyncControl<Void> control = returningVoid().withSkipRules();
- wrapper.asyncWrap(book, control).setName("Book #2"); // don't enforce rules for this test
-
- control.getFuture().get(10, TimeUnit.SECONDS);
-
- latch.await(2, TimeUnit.SECONDS);
-
- _Probe.errOut("(3) AFTER BOOK UPDATED");
-
- // then - after the commit
- assertEquals(0, getCreated());
- assertEquals(0, getDeleted());
- //assertEquals(1, getLoaded()); // not reproducible
- assertEquals(1, getUpdated());
- assertEquals(1, getModified());
-
- }
-
-
- @Test @Order(4)
- void publisherService_shouldNotBeAwareOfInventoryChanges_whenUsingAsyncExecutionFails()
- throws InterruptedException, ExecutionException, TimeoutException {
-
- // given
- val book = repository.allInstances(JdoBook.class).listIterator().next();
- PublisherServiceForTesting.clearPublishedEntries(kvStore);
-
- // when - running within its own background task
- assertThrows(DisabledException.class, ()->{
-
- wrapper.asyncWrap(book, returningVoid()).setName("Book #2");
-
- returningVoid().getFuture().get(10, TimeUnit.SECONDS);
-
- });
-
- // then - after the commit
- assertEquals(0, getCreated());
- assertEquals(0, getDeleted());
- assertEquals(0, getLoaded());
- assertEquals(0, getUpdated());
- assertEquals(0, getModified());
-
- }
-
- // -- HELPER
-
- private int getCreated() {
- val publishedObjects = PublisherServiceForTesting.getPublishedObjects(kvStore);
- return publishedObjects.stream().mapToInt(PublishedObjects::getNumberCreated).sum();
- }
-
- private int getDeleted() {
- val publishedObjects = PublisherServiceForTesting.getPublishedObjects(kvStore);
- return publishedObjects.stream().mapToInt(PublishedObjects::getNumberDeleted).sum();
- }
-
- private int getLoaded() {
- val publishedObjects = PublisherServiceForTesting.getPublishedObjects(kvStore);
- return publishedObjects.stream().mapToInt(PublishedObjects::getNumberLoaded).sum();
- }
-
- private int getUpdated() {
- val publishedObjects = PublisherServiceForTesting.getPublishedObjects(kvStore);
- return publishedObjects.stream().mapToInt(PublishedObjects::getNumberUpdated).sum();
- }
-
- private int getModified() {
- val publishedObjects = PublisherServiceForTesting.getPublishedObjects(kvStore);
- return publishedObjects.stream().mapToInt(PublishedObjects::getNumberPropertiesModified).sum();
- }
-
-
-}
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/ApplicationLayerTestFactory.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/ApplicationLayerTestFactory.java
new file mode 100644
index 0000000..899019b
--- /dev/null
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/ApplicationLayerTestFactory.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.isis.testdomain.applayer;
+
+import static org.apache.isis.applib.services.wrapper.control.AsyncControl.returningVoid;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.DynamicTest.dynamicTest;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import org.apache.isis.applib.services.repository.RepositoryService;
+import org.apache.isis.applib.services.wrapper.DisabledException;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.control.SyncControl;
+import org.apache.isis.applib.services.xactn.TransactionService;
+import org.apache.isis.applib.services.xactn.TransactionState;
+import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.testdomain.jdo.JdoTestDomainPersona;
+import org.apache.isis.testdomain.jdo.entities.JdoBook;
+import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
+import org.junit.jupiter.api.DynamicTest;
+import org.springframework.stereotype.Component;
+
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+@Component
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
+public class ApplicationLayerTestFactory {
+
+ private final RepositoryService repository;
+ private final WrapperFactory wrapper;
+ private final TransactionService transactionService;
+ private final FixtureScripts fixtureScripts;
+
+ public List<DynamicTest> generateTests(
+ final Runnable given,
+ final Runnable thenHappyCase,
+ final Runnable thenFailureCase) {
+ return _Lists.of(
+ dynamicTest("No initial Transaction with Test Execution", this::no_initial_tx_context),
+ programmaticExecution(given, thenFailureCase),
+ wrapperSyncExecution(given, thenHappyCase),
+ wrapperSyncExecutionWithFailure(given, thenFailureCase),
+ wrapperAsyncExecution(given, thenHappyCase),
+ wrapperAsyncExecutionWithFailure(given, thenFailureCase)
+ );
+ }
+
+ // -- TEST SETUP
+
+ private JdoBook setupForJdo() {
+ // cleanup
+ fixtureScripts.runPersona(JdoTestDomainPersona.PurgeAll);
+ // given
+ fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
+
+ return repository.allInstances(JdoBook.class).listIterator().next();
+ }
+
+ // -- TESTS - ENSURE TESTS ARE CORRECTLY INVOKED
+
+ void no_initial_tx_context() {
+ val txState = transactionService.currentTransactionState();
+ assertEquals(TransactionState.NONE, txState);
+ }
+
+ // -- TESTS - WRAPPER SYNC
+
+ private DynamicTest programmaticExecution(
+ final Runnable given,
+ final Runnable then) {
+ return dynamicTest("Programmatic Execution", ()->{
+ // given
+ val book = setupForJdo();
+ given.run();
+
+ // when - direct change (circumventing the framework)
+ book.setName("Book #2");
+ repository.persist(book);
+
+ // this test does not trigger publishing
+ // because invocation happens directly rather than through the means of
+ // an implementation of ObjectMemberAbstract, which has the meta-data
+ // required to generate the associated CommandDTO
+
+ //TODO however, we should still be able to receive valid metrics
+ // even though Commands don't have CommandDTOs
+
+ // then
+ then.run();
+ });
+ }
+
+ // -- TESTS - WRAPPER SYNC
+
+ private DynamicTest wrapperSyncExecution(
+ final Runnable given,
+ final Runnable then) {
+ return dynamicTest("Wrapper Sync Execution w/o Rules", ()->{
+ // given
+ val book = setupForJdo();
+ given.run();
+
+ // when - running synchronous
+ val syncControl = SyncControl.control().withSkipRules(); // don't enforce rules
+ wrapper.wrap(book, syncControl).setName("Book #2");
+
+ // then
+ then.run();
+ });
+ }
+
+ private DynamicTest wrapperSyncExecutionWithFailure(
+ final Runnable given,
+ final Runnable then) {
+ return dynamicTest("Wrapper Sync Execution w/ Rules (expected to fail w/ DisabledException)", ()->{
+ // given
+ val book = setupForJdo();
+ given.run();
+
+ // when - running synchronous
+ val syncControl = SyncControl.control().withCheckRules(); // enforce rules
+
+ assertThrows(DisabledException.class, ()->{
+ wrapper.wrap(book, syncControl).setName("Book #2"); // should fail with DisabledException
+ });
+
+ // then
+ then.run();
+ });
+ }
+
+ // -- TESTS - WRAPPER ASYNC
+
+ private DynamicTest wrapperAsyncExecution(
+ final Runnable given,
+ final Runnable then) {
+ return dynamicTest("Wrapper Async Execution w/o Rules", ()->{
+ // given
+ val book = setupForJdo();
+ given.run();
+
+ // when - running asynchronous
+ val asyncControl = returningVoid().withSkipRules(); // don't enforce rules
+ wrapper.asyncWrap(book, asyncControl).setName("Book #2");
+
+ asyncControl.getFuture().get(10, TimeUnit.SECONDS);
+
+ // then
+ then.run();
+ });
+ }
+
+ private DynamicTest wrapperAsyncExecutionWithFailure(
+ final Runnable given,
+ final Runnable then) {
+ return dynamicTest("Wrapper Async Execution w/ Rules (expected to fail w/ DisabledException)", ()->{
+ // given
+ val book = setupForJdo();
+ given.run();
+
+ // when - running synchronous
+ val asyncControl = returningVoid().withCheckRules(); // enforce rules
+
+ assertThrows(DisabledException.class, ()->{
+ wrapper.asyncWrap(book, asyncControl).setName("Book #2"); // should fail with DisabledException
+
+ asyncControl.getFuture().get(10, TimeUnit.SECONDS);
+ });
+
+ // then
+ then.run();
+ });
+ }
+
+}
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/auditing/AuditerServiceForTesting.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/auditing/AuditerServiceForTesting.java
similarity index 98%
rename from regressiontests/stable/src/main/java/org/apache/isis/testdomain/auditing/AuditerServiceForTesting.java
rename to regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/auditing/AuditerServiceForTesting.java
index a780905..6696ad5 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/auditing/AuditerServiceForTesting.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/auditing/AuditerServiceForTesting.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.testdomain.auditing;
+package org.apache.isis.testdomain.applayer.auditing;
import java.sql.Timestamp;
import java.util.ArrayList;
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/auditing/Configuration_usingAuditing.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/auditing/Configuration_usingAuditing.java
similarity index 95%
rename from regressiontests/stable/src/main/java/org/apache/isis/testdomain/auditing/Configuration_usingAuditing.java
rename to regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/auditing/Configuration_usingAuditing.java
index 38b9f7c..bc9579c 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/auditing/Configuration_usingAuditing.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/auditing/Configuration_usingAuditing.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.testdomain.auditing;
+package org.apache.isis.testdomain.applayer.auditing;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/Configuration_usingPublishing.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/publishing/Configuration_usingPublishing.java
similarity index 95%
rename from regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/Configuration_usingPublishing.java
rename to regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/publishing/Configuration_usingPublishing.java
index 3e01444..20b0018 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/Configuration_usingPublishing.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/publishing/Configuration_usingPublishing.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.testdomain.publishing;
+package org.apache.isis.testdomain.applayer.publishing;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublisherServiceForTesting.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/publishing/PublisherServiceForTesting.java
similarity index 74%
rename from regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublisherServiceForTesting.java
rename to regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/publishing/PublisherServiceForTesting.java
index ec900d6..3225f79 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublisherServiceForTesting.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/publishing/PublisherServiceForTesting.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.testdomain.publishing;
+package org.apache.isis.testdomain.applayer.publishing;
import java.util.ArrayList;
import java.util.List;
@@ -95,4 +95,30 @@ public class PublisherServiceForTesting implements PublisherService {
kvStore.clear(PublisherServiceForTesting.class);
}
+ public static int getCreated(KVStoreForTesting kvStore) {
+ val publishedObjects = getPublishedObjects(kvStore);
+ return publishedObjects.stream().mapToInt(PublishedObjects::getNumberCreated).sum();
+ }
+
+ public static int getDeleted(KVStoreForTesting kvStore) {
+ val publishedObjects = getPublishedObjects(kvStore);
+ return publishedObjects.stream().mapToInt(PublishedObjects::getNumberDeleted).sum();
+ }
+
+ public static int getLoaded(KVStoreForTesting kvStore) {
+ val publishedObjects = getPublishedObjects(kvStore);
+ return publishedObjects.stream().mapToInt(PublishedObjects::getNumberLoaded).sum();
+ }
+
+ public static int getUpdated(KVStoreForTesting kvStore) {
+ val publishedObjects = getPublishedObjects(kvStore);
+ return publishedObjects.stream().mapToInt(PublishedObjects::getNumberUpdated).sum();
+ }
+
+ public static int getModified(KVStoreForTesting kvStore) {
+ val publishedObjects = getPublishedObjects(kvStore);
+ return publishedObjects.stream().mapToInt(PublishedObjects::getNumberPropertiesModified).sum();
+ }
+
+
}
\ No newline at end of file
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/commons/InteractionTestAbstract.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/commons/InteractionTestAbstract.java
index dbdcf5c..00334b8 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/commons/InteractionTestAbstract.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/commons/InteractionTestAbstract.java
@@ -43,7 +43,7 @@ import org.apache.isis.core.metamodel.interactions.managed.PropertyInteraction;
import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
import org.apache.isis.core.runtime.iactn.IsisInteractionFactory;
import org.apache.isis.core.runtime.persistence.changetracking.ChangedObjectsService;
-import org.apache.isis.testdomain.auditing.AuditerServiceForTesting;
+import org.apache.isis.testdomain.applayer.auditing.AuditerServiceForTesting;
import org.apache.isis.testdomain.util.CollectionAssertions;
import org.apache.isis.testdomain.util.kv.KVStoreForTesting;
import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/entitychangetracking/ChangedObjectsTest.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/entitychangetracking/ChangedObjectsTest.java
index a6a780c..a62fe63 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/entitychangetracking/ChangedObjectsTest.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/entitychangetracking/ChangedObjectsTest.java
@@ -30,8 +30,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.core.config.presets.IsisPresets;
-import org.apache.isis.testdomain.auditing.AuditerServiceForTesting;
-import org.apache.isis.testdomain.auditing.Configuration_usingAuditing;
+import org.apache.isis.testdomain.applayer.auditing.AuditerServiceForTesting;
+import org.apache.isis.testdomain.applayer.auditing.Configuration_usingAuditing;
+import org.apache.isis.testdomain.applayer.publishing.Configuration_usingPublishing;
import org.apache.isis.testdomain.commons.InteractionBoundaryProbe;
import org.apache.isis.testdomain.commons.InteractionTestAbstract;
import org.apache.isis.testdomain.conf.Configuration_usingJdo;
@@ -39,7 +40,6 @@ import org.apache.isis.testdomain.jdo.JdoInventoryManager;
import org.apache.isis.testdomain.jdo.JdoTestDomainPersona;
import org.apache.isis.testdomain.jdo.entities.JdoBook;
import org.apache.isis.testdomain.jdo.entities.JdoProduct;
-import org.apache.isis.testdomain.publishing.Configuration_usingPublishing;
import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
import lombok.val;