diff --git a/e2e/core-e2e/src/test/java/io/flamingock/core/e2e/CoreStrategiesE2ETest.java b/e2e/core-e2e/src/test/java/io/flamingock/core/e2e/CoreStrategiesE2ETest.java index bd7f01b90..e45432c50 100644 --- a/e2e/core-e2e/src/test/java/io/flamingock/core/e2e/CoreStrategiesE2ETest.java +++ b/e2e/core-e2e/src/test/java/io/flamingock/core/e2e/CoreStrategiesE2ETest.java @@ -17,12 +17,8 @@ import io.flamingock.common.test.pipeline.CodeChangeTestDefinition; import io.flamingock.common.test.pipeline.PipelineTestHelper; -import io.flamingock.core.e2e.changes._006__FailingTransactionalChange; -import io.flamingock.core.e2e.changes._003__MultiTest1NonTransactionalChange; -import io.flamingock.core.e2e.changes._004__MultiTest2TransactionalChange; -import io.flamingock.core.e2e.changes._005__SecondRunNonTransactionalChange; -import io.flamingock.core.e2e.changes._001__SimpleNonTransactionalChange; -import io.flamingock.core.e2e.changes._002__SimpleTransactionalChange; +import io.flamingock.core.e2e.changes.*; +import io.flamingock.core.e2e.helpers.Counter; import io.flamingock.core.kit.audit.AuditTestHelper; import io.flamingock.core.kit.inmemory.InMemoryTestKit; import io.flamingock.core.processor.util.Deserializer; @@ -42,8 +38,7 @@ import static io.flamingock.core.kit.audit.AuditEntryExpectation.FAILED; import static io.flamingock.core.kit.audit.AuditEntryExpectation.ROLLED_BACK; import static io.flamingock.core.kit.audit.AuditEntryExpectation.STARTED; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; class CoreStrategiesE2ETest { @@ -230,4 +225,43 @@ void testAlreadyAppliedChangesSkipping() { APPLIED("test5-second-run-change") ); } + + @Test + @DisplayName("Should inject dependencies in rollback for NON-TX change") + void testDependencyInjectionInRollbackForNonTxChange() { + InMemoryTestKit testKit = InMemoryTestKit.create(); + AuditTestHelper auditHelper = testKit.getAuditHelper(); + + Counter counter = new Counter(); + + NonTransactionalTargetSystem targetSystem = new NonTransactionalTargetSystem("kafka") + .addDependency(counter); + + try (MockedStatic mocked = Mockito.mockStatic(Deserializer.class)) { + mocked.when(Deserializer::readPreviewPipelineFromFile).thenReturn( + PipelineTestHelper.getPreviewPipeline( + new CodeChangeTestDefinition(_007__SimpleNonTransactionalChangeWithError.class, Collections.emptyList()) + ) + ); + + PipelineExecutionException exception = assertThrows(PipelineExecutionException.class, () -> { + testKit.createBuilder() + .addTargetSystem(targetSystem) + .build() + .run(); + }); + + assertNotNull(exception); + assertTrue(exception.getMessage().contains("Intentional failure")); + } + + assertTrue(counter.isExecuted(), "Counter.executed should be true after execution"); + assertTrue(counter.isRollbacked(), "Counter.rollbacked should be true after rollback"); + + auditHelper.verifyAuditSequenceStrict( + STARTED("test1-non-tx-change"), + FAILED("test1-non-tx-change"), + ROLLED_BACK("test1-non-tx-change") + ); + } } diff --git a/e2e/core-e2e/src/test/java/io/flamingock/core/e2e/changes/_007__SimpleNonTransactionalChangeWithError.java b/e2e/core-e2e/src/test/java/io/flamingock/core/e2e/changes/_007__SimpleNonTransactionalChangeWithError.java new file mode 100644 index 000000000..40b062ed4 --- /dev/null +++ b/e2e/core-e2e/src/test/java/io/flamingock/core/e2e/changes/_007__SimpleNonTransactionalChangeWithError.java @@ -0,0 +1,42 @@ +/* + * Copyright 2025 Flamingock (https://www.flamingock.io) + * + * 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 io.flamingock.core.e2e.changes; + +import io.flamingock.api.annotations.*; +import io.flamingock.core.e2e.helpers.Counter; + +import javax.inject.Named; + +/** + * Simple non-transactional change for testing core execution strategies. + * Does not require any external dependencies. + */ +@Change(id = "test1-non-tx-change", transactional = false, author = "aperezdieppa") +@TargetSystem(id = "kafka") +public class _007__SimpleNonTransactionalChangeWithError { + + @Apply + public void execution(@NonLockGuarded Counter counter) { + counter.setExecuted(true); + throw new RuntimeException("Intentional failure"); + } + + @Rollback + public void rollback(@NonLockGuarded Counter counter) { + counter.setRollbacked(true); + System.out.println("Rolling back failing transactional change"); + } +} \ No newline at end of file diff --git a/e2e/core-e2e/src/test/java/io/flamingock/core/e2e/helpers/Counter.java b/e2e/core-e2e/src/test/java/io/flamingock/core/e2e/helpers/Counter.java new file mode 100644 index 000000000..69035d225 --- /dev/null +++ b/e2e/core-e2e/src/test/java/io/flamingock/core/e2e/helpers/Counter.java @@ -0,0 +1,38 @@ +/* + * Copyright 2025 Flamingock (https://www.flamingock.io) + * + * 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 io.flamingock.core.e2e.helpers; + +public class Counter { + private boolean executed = false; + private boolean rollbacked = false; + + public boolean isExecuted() { + return executed; + } + + public void setExecuted(boolean executed) { + this.executed = executed; + } + + public boolean isRollbacked() { + return rollbacked; + } + + public void setRollbacked(boolean rollbacked) { + this.rollbacked = rollbacked; + } +} +