Skip to content
Permalink
Browse files
OAK-9717 - Ensuring custom index definitions do not remove nodes from…
… product indexes in the IndexDefMergerUtils
  • Loading branch information
klcodanr committed Mar 9, 2022
1 parent 77cb7c3 commit b223d5b58b10fa3b11eecda4ffb4cb129c4d324e
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 595 deletions.
@@ -148,6 +148,8 @@ private static String mergeProperty(String path, String property, JsonObject anc
return cp;
} else if (Objects.equals(ap, cp)) {
return pp;
} else if (ap == null) {
return cp;
} else {
conflicts.add("Could not merge value; path=" + path + " property=" + property + "; ancestor=" + ap + "; custom=" + cp
+ "; product=" + pp);
@@ -163,7 +165,9 @@ private static JsonObject mergeChild(String path, String child, int level, JsonO
if (level == 0 && USE_PRODUCT_CHILD_LEVEL_0.contains(child)) {
return p;
}
if (isSameJson(a, p) || isSameJson(c, p)) {
if(c == null && p != null){
return p;
}else if (isSameJson(a, p) || isSameJson(c, p)) {
return c;
} else if (isSameJson(a, c)) {
return p;
@@ -20,55 +20,105 @@

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;

import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.oak.commons.json.JsonObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Test merging index definitions.
*/
@RunWith(Parameterized.class)
public class IndexDefMergerScenariosTest {
@Parameters

private static final Logger log = LoggerFactory.getLogger(IndexDefMergerScenariosTest.class);

@Parameters(name = "{0}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
testCase("should use the latest base version for the base in merges", "merges-base"),
testCase("should use the latest base version for the base in merges when updating multiple version numbers", "merges-multi-version")
testCase("should merge custom into new base index", "basic.json"),
testCase("should use the latest base version for the base in merges", "merges-base.json"),
testCase(
"should use the latest base version for the base in merges when updating multiple version numbers",
"merges-multi-version.json"),
testCase("should not remove child nodes from product index missing from custom index",
"missing-child.json"),
testCase("should support removing adding changing properties from product index in custom index",
"removed-property.json")
});
}

public static Object[] testCase(String name, String baseName) {
public static Object[] testCase(String name, String testCaseFile) {
return new Object[] {
name,
baseName + "_build.json",
baseName + "_run.json",
baseName + "_expected.json"
testCaseFile
};
}

private final String name;
private final String testCaseFile;
private final String testCaseName;
private final JsonObject buildIndexes;
private final JsonObject runIndexes;
private final JsonObject expectedIndexes;

public IndexDefMergerScenariosTest(String name, String buildFile, String runFile, String expectedFile)
public IndexDefMergerScenariosTest(String name, String testCaseFile)
throws IOException {
this.name = name;
this.buildIndexes = JsonObject.fromJson(IndexDefMergerTest.readFromResource(buildFile), true);
this.runIndexes = JsonObject.fromJson(IndexDefMergerTest.readFromResource(runFile), true);
this.expectedIndexes = JsonObject.fromJson(IndexDefMergerTest.readFromResource(expectedFile), true);
this.testCaseName = name;
this.testCaseFile = testCaseFile;
JsonObject testCase = readTestCaseFile(testCaseFile);
this.buildIndexes = getChild(testCase, "build");
this.runIndexes = getChild(testCase, "run");
this.expectedIndexes = getChild(testCase, "expected");
}

private JsonObject readTestCaseFile(String testCaseFileName) {
return Optional.ofNullable(IndexDefMergerScenariosTest.class.getResourceAsStream(testCaseFileName))
.map(in -> {
try {
return IOUtils.toString(in, StandardCharsets.UTF_8.toString());
} catch (IOException e) {
throw new IllegalArgumentException(
"Unexpected IOException reading test case file: " + testCaseFileName, e);
}
})
.map(s -> JsonObject.fromJson(s, true))
.orElseThrow(() -> new IllegalArgumentException("Unable to read test case file: " + testCaseFileName));
}

private JsonObject getChild(JsonObject testCase, String fieldName) {
return Optional.ofNullable(testCase.getChildren().get(fieldName))
.orElseThrow(() -> new IllegalArgumentException(
"Unable to run test: " + testCaseName + ", Expected field " + fieldName + " not set"));
}

@Test
public void testMerge() {
IndexDefMergerUtils.merge(buildIndexes, runIndexes);
assertEquals("Failed to execute test: " + name, expectedIndexes.toString(), buildIndexes.toString());

File output = new File("target" + File.separator + "surefire-output" + File.separator
+ getClass().getCanonicalName().replace(".", "-") + File.separator + testCaseFile);
try {
if (!output.getParentFile().exists()) {
output.getParentFile().mkdirs();
}
IOUtils.write(buildIndexes.toString(), new FileOutputStream(output),
StandardCharsets.UTF_8);
} catch (IOException e) {
log.warn("Failed to write merged index definition to: {}", output, e);
}
assertEquals("Failed to execute test: " + testCaseName, expectedIndexes.toString(), buildIndexes.toString());
}

}
@@ -44,25 +44,6 @@ public void merge() throws IOException, CommitFailedException {
}
}

@Test
public void mergeIndexes() throws IOException, CommitFailedException {
String s = readFromResource("mergeIndexes.txt");
JsonObject json = JsonObject.fromJson(s, true);
for(JsonObject e : array(json.getProperties().get("tests"))) {
mergeIndexes(e);
}
}

private void mergeIndexes(JsonObject e) {
JsonObject all = e.getChildren().get("all");
JsonObject newDefs = e.getChildren().get("new");
JsonObject expectedNew = e.getChildren().get("expectedNew");
IndexDefMergerUtils.merge(newDefs, all);
assertEquals(
expectedNew.toString(),
newDefs.toString());
}

private void merge(JsonObject e) {
JsonObject ancestor = e.getChildren().get("ancestor");
JsonObject custom = e.getChildren().get("custom");
@@ -13,12 +13,6 @@
"product": {"o": {"a": 1, "p": 20}},
"expected": {"merges": ["/oak:index/test-2", "/oak:index/test-1-custom-1"], "o": {"a": 2, "c": 10, "p": 20 }}
},
{
"ancestor": {"o": {"a": 1}},
"custom": {},
"product": {"o": {"a": 2}},
"expected":"Conflicts detected: [Could not merge value; path=/o property=a; ancestor=1; custom=null; product=2]"
},
{
"ancestor": {"a": 1},
"custom": {"a": 2},

This file was deleted.

This file was deleted.

This file was deleted.

0 comments on commit b223d5b

Please sign in to comment.