Skip to content

Commit d816f12

Browse files
committed
test: added test to validate Mongock ChangeUnits execution if pending
1 parent e56935d commit d816f12

5 files changed

Lines changed: 90 additions & 51 deletions

File tree

core/flamingock-core/src/main/java/io/flamingock/internal/core/task/loaded/AbstractLoadedChange.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,19 @@
1515
*/
1616
package io.flamingock.internal.core.task.loaded;
1717

18-
import io.flamingock.api.annotations.Categories;
19-
import io.flamingock.api.task.ChangeCategory;
2018
import io.flamingock.internal.common.core.error.validation.ValidationError;
21-
import io.flamingock.internal.core.pipeline.loaded.stage.StageValidationContext;
22-
import io.flamingock.internal.util.ReflectionUtil;
2319
import io.flamingock.internal.common.core.task.RecoveryDescriptor;
2420
import io.flamingock.internal.common.core.task.TargetSystemDescriptor;
25-
import org.jetbrains.annotations.NotNull;
21+
import io.flamingock.internal.core.pipeline.loaded.stage.StageValidationContext;
2622
import io.flamingock.internal.util.log.FlamingockLoggerFactory;
23+
import org.jetbrains.annotations.NotNull;
2724
import org.slf4j.Logger;
2825

2926
import java.lang.reflect.Constructor;
3027
import java.util.ArrayList;
31-
import java.util.Arrays;
3228
import java.util.List;
3329
import java.util.Optional;
34-
import java.util.Set;
3530
import java.util.regex.Pattern;
36-
import java.util.stream.Collectors;
3731

3832
public abstract class AbstractLoadedChange extends AbstractReflectionLoadedTask {
3933

@@ -97,19 +91,19 @@ public List<ValidationError> getValidationErrors(StageValidationContext context)
9791
@NotNull
9892
private Optional<ValidationError> getOrderError(StageValidationContext context) {
9993
String order = getOrder().orElse(null);
100-
if(context.getSortType().isSorted()) {
94+
if (context.getSortType().isSorted()) {
10195
if (order == null || order.isEmpty()) {
10296
return Optional.of(new ValidationError("Change in a sorted stage but no order value was provided", id, "change"));
10397
}
10498

105-
if(context.getSortType() == StageValidationContext.SortType.SEQUENTIAL_FORMATTED) {
99+
if (context.getSortType() == StageValidationContext.SortType.SEQUENTIAL_FORMATTED) {
106100
if (!ORDER_PATTERN.matcher(order).matches()) {
107101
String message = String.format("Invalid order field format in change[%s]. Order must match pattern: %s", id, ORDER_REG_EXP);
108102
return Optional.of(new ValidationError(message, id, "task"));
109103
}
110104
}
111105

112-
} else if(order != null) {
106+
} else if (order != null) {
113107
logger.warn("Change[{}] is in an auto-sorted stage but order value was provided - order will be ignored and managed automatically by Flamingock", id);
114108

115109
}

legacy/mongock-importer-couchbase/src/test/java/io/flamingock/importer/mongock/couchbase/CouchbaseImporterTest.java

Lines changed: 81 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.junit.jupiter.api.AfterEach;
3434
import org.junit.jupiter.api.BeforeAll;
3535
import org.junit.jupiter.api.Disabled;
36+
import org.junit.jupiter.api.DisplayName;
3637
import org.junit.jupiter.api.Test;
3738
import org.testcontainers.couchbase.CouchbaseContainer;
3839
import org.testcontainers.junit.jupiter.Container;
@@ -41,10 +42,13 @@
4142
import java.time.Duration;
4243
import java.time.Instant;
4344
import java.util.List;
45+
import java.util.Map;
46+
import java.util.stream.Collectors;
4447

4548
import static io.flamingock.internal.common.core.metadata.Constants.DEFAULT_MONGOCK_ORIGIN;
4649
import static org.junit.jupiter.api.Assertions.assertEquals;
4750
import static org.junit.jupiter.api.Assertions.assertFalse;
51+
import static org.junit.jupiter.api.Assertions.assertNotNull;
4852
import static org.junit.jupiter.api.Assertions.assertTrue;
4953

5054
@Testcontainers
@@ -99,24 +103,15 @@ void cleanUp() {
99103
}
100104

101105
@Test
102-
void testImporterIntegration() {
106+
@DisplayName("GIVEN all Mongock changeUnits already executed" +
107+
"WHEN migrating to Flamingock Community " +
108+
"THEN should import the entire history " +
109+
"AND execute the pending flamingock changes")
110+
void GIVEN_allMongockChangeUnitsAlreadyExecuted_WHEN_migratingToFlamingockCommunity_THEN_shouldImportEntireHistory() {
103111
Collection originCollection = cluster.bucket(MONGOCK_BUCKET_NAME).scope(MONGOCK_SCOPE_NAME).collection(MONGOCK_COLLECTION_NAME);
104-
JsonObject doc = JsonObject.create()
105-
.put("executionId", "exec-1")
106-
.put("changeId", "change-1")
107-
.put("author", "author1")
108-
.put("timestamp", String.valueOf(Instant.now().toEpochMilli()))
109-
.put("state", "EXECUTED")
110-
.put("type", "EXECUTION")
111-
.put("changeLogClass", "io.flamingock.changelog.Class1")
112-
.put("changeSetMethod", "method1")
113-
.putNull("metadata")
114-
.put("executionMillis", 123L)
115-
.put("executionHostName", "host1")
116-
.putNull("errorTrace")
117-
.put("systemChange", true)
118-
.put("_doctype", "mongockChangeEntry");
119-
originCollection.upsert("change-1", doc);
112+
113+
originCollection.upsert("mongock-change-1", createAuditObject("mongock-change-1"));
114+
originCollection.upsert("mongock-change-2", createAuditObject("mongock-change-2"));
120115

121116
CouchbaseTargetSystem targetSystem = new CouchbaseTargetSystem("couchbase-target-system", cluster, FLAMINGOCK_BUCKET_NAME);
122117

@@ -129,34 +124,84 @@ void testImporterIntegration() {
129124

130125
flamingock.run();
131126

132-
List<JsonObject> auditLog = CouchbaseCollectionHelper.selectAllDocuments(cluster, FLAMINGOCK_BUCKET_NAME, FLAMINGOCK_SCOPE_NAME, FLAMINGOCK_COLLECTION_NAME);
133-
134-
assertFalse(auditLog.isEmpty(), "Audit log should not be empty");
135-
136-
JsonObject entry = auditLog.stream()
137-
.filter(e -> "change-1".equals(e.getString("changeId")))
138-
.findFirst()
139-
.orElseThrow(() -> new AssertionError("Entry with changeId 'change-1' not found"));
127+
validateFlamingockAuditOutput();
140128

141-
assertEquals("change-1", entry.getString("changeId"));
142-
assertEquals("author1", entry.getString("author"));
143-
assertEquals("exec-1", entry.getString("executionId"));
144-
assertEquals("APPLIED", entry.getString("state"));
145-
assertTrue(entry.getBoolean("systemChange"));
146129
}
147130

148131
@Test
149-
@Disabled("restore when https://trello.com/c/4gEQ8Wb4/458-mongock-legacy-targetsystem done")
150-
void failIfEmptyOrigin() {
132+
@DisplayName("GIVEN some Mongock changeUnits already executed " +
133+
"AND some other Mongock changeUnits pending for execution" +
134+
"WHEN migrating to Flamingock Community" +
135+
"THEN migrates the history with the executed changeUnits " +
136+
"AND executes the pending Mongock changeUnits " +
137+
"AND executes the pending Flamingock changes")
138+
void GIVEN_someChangeUnitsAlreadyExecuted_WHEN_migratingToFlamingockCommunity_THEN_shouldImportEntireHistory() {
139+
Collection originCollection = cluster.bucket(MONGOCK_BUCKET_NAME).scope(MONGOCK_SCOPE_NAME).collection(MONGOCK_COLLECTION_NAME);
140+
141+
originCollection.upsert("mongock-change-1", createAuditObject("mongock-change-1"));
142+
143+
CouchbaseTargetSystem targetSystem = new CouchbaseTargetSystem("couchbase-target-system", cluster, FLAMINGOCK_BUCKET_NAME);
144+
151145
Runner flamingock = FlamingockFactory.getCommunityBuilder()
152146
.setAuditStore(new CouchbaseAuditStore(cluster, FLAMINGOCK_BUCKET_NAME)
153147
.withScopeName(FLAMINGOCK_SCOPE_NAME)
154148
.withAuditRepositoryName(FLAMINGOCK_COLLECTION_NAME))
149+
.addTargetSystem(targetSystem)
155150
.build();
156151

157-
org.junit.jupiter.api.Assertions.assertThrows(
158-
io.flamingock.internal.common.core.error.FlamingockException.class,
159-
flamingock::run
160-
);
152+
flamingock.run();
153+
154+
validateFlamingockAuditOutput();
155+
161156
}
157+
158+
159+
private static void validateFlamingockAuditOutput() {
160+
List<JsonObject> auditLog = CouchbaseCollectionHelper.selectAllDocuments(cluster, FLAMINGOCK_BUCKET_NAME, FLAMINGOCK_SCOPE_NAME, FLAMINGOCK_COLLECTION_NAME);
161+
162+
163+
Map<String, JsonObject> byChangeId = auditLog.stream()
164+
.collect(Collectors.toMap(
165+
e -> e.getString("changeId"),
166+
e -> e
167+
));
168+
169+
170+
assertEquals(4, auditLog.size());
171+
JsonObject importAudit = byChangeId.get("migration-mongock-to-flamingock-community");
172+
JsonObject mongockAudit1 = byChangeId.get("mongock-change-1");
173+
JsonObject mongockAudit2 = byChangeId.get("mongock-change-2");
174+
JsonObject flamingockAudit = byChangeId.get("flamingock-change");
175+
assertNotNull(importAudit);
176+
assertEquals("APPLIED", importAudit.getString("state"));
177+
178+
assertNotNull(mongockAudit1);
179+
assertEquals("APPLIED", mongockAudit1.getString("state"));
180+
181+
assertNotNull(mongockAudit2);
182+
assertEquals("APPLIED", mongockAudit2.getString("state"));
183+
184+
assertNotNull(flamingockAudit);
185+
assertEquals("APPLIED", flamingockAudit.getString("state"));
186+
}
187+
188+
private static JsonObject createAuditObject(String value) {
189+
JsonObject doc = JsonObject.create()
190+
.put("executionId", "exec-1")
191+
.put("changeId", value)
192+
.put("author", "author1")
193+
.put("timestamp", String.valueOf(Instant.now().toEpochMilli()))
194+
.put("state", "EXECUTED")
195+
.put("type", "EXECUTION")
196+
.put("changeLogClass", "io.flamingock.changelog.Class1")
197+
.put("changeSetMethod", "method1")
198+
.putNull("metadata")
199+
.put("executionMillis", 123L)
200+
.put("executionHostName", "host1")
201+
.putNull("errorTrace")
202+
.put("systemChange", true)
203+
.put("_doctype", "mongockChangeEntry");
204+
return doc;
205+
}
206+
162207
}

legacy/mongock-importer-couchbase/src/test/java/io/flamingock/importer/mongock/couchbase/changes/MongockChange1.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import io.mongock.api.annotations.ChangeUnit;
1919
import io.mongock.api.annotations.Execution;
2020

21-
@ChangeUnit(id = "client-initializer", order = "1", author = "flamingock-team", transactional = false)
21+
@ChangeUnit(id = "mongock-change-1", order = "1", author = "flamingock-team", transactional = false)
2222
public class MongockChange1 {
2323

2424
@Execution

legacy/mongock-importer-couchbase/src/test/java/io/flamingock/importer/mongock/couchbase/changes/MongockChange2.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import io.mongock.api.annotations.ChangeUnit;
1919
import io.mongock.api.annotations.Execution;
2020

21-
@ChangeUnit(id = "client-updater", order = "2", author = "flamingock-team", transactional = false)
21+
@ChangeUnit(id = "mongock-change-2", order = "2", author = "flamingock-team", transactional = false)
2222
public class MongockChange2 {
2323

2424
@Execution

legacy/mongock-importer-couchbase/src/test/java/io/flamingock/importer/mongock/couchbase/changes/_0001__CreateUsersCollectionChange.java renamed to legacy/mongock-importer-couchbase/src/test/java/io/flamingock/importer/mongock/couchbase/changes/_0003__Flamingock_change.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
import java.util.Collections;
2626

2727
@TargetSystem(id = "couchbase-target-system")
28-
@Change(id = "create-users-collection", author = "importer", transactional = false)
29-
public class _0001__CreateUsersCollectionChange {
28+
@Change(id = "flamingock-change", author = "importer", transactional = false)
29+
public class _0003__Flamingock_change {
3030

3131
@Apply
3232
public void apply(Bucket bucket) {

0 commit comments

Comments
 (0)