use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.
the class PatchServiceImplTest method bundleUpdatesInPatch.
@Test
@SuppressWarnings("unchecked")
public void bundleUpdatesInPatch() throws Exception {
BundleContext context = mock(BundleContext.class);
Bundle bundle0 = mock(Bundle.class);
when(bundle0.getBundleContext()).thenReturn(context);
when(context.getProperty("karaf.home")).thenReturn("target/bundleUpdatesInPatch");
when(context.getProperty("karaf.base")).thenReturn("target/bundleUpdatesInPatch");
when(context.getProperty("karaf.data")).thenReturn("target/bundleUpdatesInPatch/data");
when(context.getProperty("karaf.etc")).thenReturn("target/bundleUpdatesInPatch/etc");
when(context.getProperty("karaf.name")).thenReturn("root");
when(context.getProperty("karaf.instances")).thenReturn("instances");
when(context.getProperty("karaf.default.repository")).thenReturn("system");
when(context.getProperty("fuse.patch.location")).thenReturn(null);
when(context.getBundle(0)).thenReturn(bundle0);
PatchServiceImpl service = new PatchServiceImpl();
Method m = service.getClass().getDeclaredMethod("bundleUpdatesInPatch", Patch.class, Bundle[].class, Map.class, PatchServiceImpl.BundleVersionHistory.class, Map.class, PatchKind.class, Map.class, List.class);
m.setAccessible(true);
Field f = service.getClass().getDeclaredField("helper");
f.setAccessible(true);
f.set(service, new OSGiPatchHelper(new File("target/bundleUpdatesInPatch"), context) {
@Override
public String[] getBundleIdentity(String url) throws IOException {
Artifact a = Utils.mvnurlToArtifact(url, false);
return a == null ? null : new String[] { a.getArtifactId(), a.getVersion() };
}
});
PatchData pd = new PatchData("patch-x");
// for these two, bundle.getLocation() will return matching location
pd.getBundles().add("mvn:io.fabric8/pax-romana/1.0.1");
pd.getBundles().add("mvn:io.fabric8/pax-hellenica/1.0.1/jar");
// for these two, bundle.getLocation() will return non-matching location
pd.getBundles().add("mvn:io.fabric8/pax-bohemia/1.0.1");
pd.getBundles().add("mvn:io.fabric8/pax-pomerania/1.0.1/jar");
// for these two, bundle.getLocation() will return matching location
pd.getBundles().add("mvn:io.fabric8/pax-avaria/1.0.1/jar/uber");
pd.getBundles().add("mvn:io.fabric8/pax-mazovia/1.0.1//uber");
// for these two, bundle.getLocation() will return non-matching location
pd.getBundles().add("mvn:io.fabric8/pax-novgorod/1.0.1/jar/uber");
pd.getBundles().add("mvn:io.fabric8/pax-castile/1.0.1//uber");
f = pd.getClass().getDeclaredField("versionRanges");
f.setAccessible(true);
f.set(pd, new HashMap<>());
Patch patch = new Patch(pd, null);
Bundle[] bundles = new Bundle[8];
bundles[0] = bundle("mvn:io.fabric8/pax-romana/1.0.0");
bundles[1] = bundle("mvn:io.fabric8/pax-hellenica/1.0.0/jar");
bundles[2] = bundle("mvn:io.fabric8/pax-bohemia/1.0.0/jar");
bundles[3] = bundle("mvn:io.fabric8/pax-pomerania/1.0.0");
bundles[4] = bundle("mvn:io.fabric8/pax-avaria/1.0.0/jar/uber");
bundles[5] = bundle("mvn:io.fabric8/pax-mazovia/1.0.0//uber");
bundles[6] = bundle("mvn:io.fabric8/pax-novgorod/1.0.0//uber");
bundles[7] = bundle("mvn:io.fabric8/pax-castile/1.0.0/jar/uber");
Object _list = m.invoke(service, patch, bundles, new HashMap<>(), new PatchServiceImpl.BundleVersionHistory(new HashMap<String, Patch>()), new HashMap<>(), PatchKind.NON_ROLLUP, new HashMap<>(), null);
List<BundleUpdate> list = (List<BundleUpdate>) _list;
assertThat(list.size(), equalTo(8));
assertThat(list.get(0).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-romana/1.0.0"));
assertThat(list.get(1).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-hellenica/1.0.0/jar"));
assertThat(list.get(2).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-bohemia/1.0.0/jar"));
assertThat(list.get(3).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-pomerania/1.0.0"));
assertThat(list.get(4).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-avaria/1.0.0/jar/uber"));
assertThat(list.get(5).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-mazovia/1.0.0//uber"));
assertThat(list.get(6).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-novgorod/1.0.0//uber"));
assertThat(list.get(7).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-castile/1.0.0/jar/uber"));
assertThat(list.get(0).getNewLocation(), equalTo("mvn:io.fabric8/pax-romana/1.0.1"));
assertThat(list.get(1).getNewLocation(), equalTo("mvn:io.fabric8/pax-hellenica/1.0.1/jar"));
assertThat(list.get(2).getNewLocation(), equalTo("mvn:io.fabric8/pax-bohemia/1.0.1"));
assertThat(list.get(3).getNewLocation(), equalTo("mvn:io.fabric8/pax-pomerania/1.0.1/jar"));
assertThat(list.get(4).getNewLocation(), equalTo("mvn:io.fabric8/pax-avaria/1.0.1/jar/uber"));
assertThat(list.get(5).getNewLocation(), equalTo("mvn:io.fabric8/pax-mazovia/1.0.1//uber"));
assertThat(list.get(6).getNewLocation(), equalTo("mvn:io.fabric8/pax-novgorod/1.0.1/jar/uber"));
assertThat(list.get(7).getNewLocation(), equalTo("mvn:io.fabric8/pax-castile/1.0.1//uber"));
// ---
Repository repository = mock(Repository.class);
File tmp = new File("target/bundleUpdatesInPatch/" + UUID.randomUUID().toString());
tmp.mkdirs();
File startupProperties = new File(tmp, "etc/startup.properties");
FileUtils.copyFile(new File("src/test/resources/uber-startup.properties"), startupProperties);
when(repository.getWorkTree()).thenReturn(tmp);
Git fork = mock(Git.class);
when(fork.getRepository()).thenReturn(repository);
GitPatchManagementServiceImpl gitPatchManagementService = new GitPatchManagementServiceImpl(context);
m = gitPatchManagementService.getClass().getDeclaredMethod("updateFileReferences", Git.class, PatchData.class, List.class);
m.setAccessible(true);
m.invoke(gitPatchManagementService, fork, pd, list);
try (FileReader reader = new FileReader(startupProperties)) {
Properties startup = new Properties();
startup.load(reader);
assertTrue(startup.containsKey("io/fabric8/pax-romana/1.0.1/pax-romana-1.0.1.jar"));
assertTrue(startup.containsKey("io/fabric8/pax-hellenica/1.0.1/pax-hellenica-1.0.1.jar"));
assertTrue(startup.containsKey("io/fabric8/pax-bohemia/1.0.1/pax-bohemia-1.0.1.jar"));
assertTrue(startup.containsKey("io/fabric8/pax-pomerania/1.0.1/pax-pomerania-1.0.1.jar"));
assertTrue(startup.containsKey("io/fabric8/pax-avaria/1.0.1/pax-avaria-1.0.1-uber.jar"));
assertTrue(startup.containsKey("io/fabric8/pax-mazovia/1.0.1/pax-mazovia-1.0.1-uber.jar"));
assertTrue(startup.containsKey("io/fabric8/pax-novgorod/1.0.1/pax-novgorod-1.0.1-uber.jar"));
assertTrue(startup.containsKey("io/fabric8/pax-castile/1.0.1/pax-castile-1.0.1-uber.jar"));
assertFalse(startup.containsKey("io/fabric8/pax-romana/1.0.0/pax-romana-1.0.0.jar"));
assertFalse(startup.containsKey("io/fabric8/pax-hellenica/1.0.0/pax-hellenica-1.0.0.jar"));
assertFalse(startup.containsKey("io/fabric8/pax-bohemia/1.0.0/pax-bohemia-1.0.0.jar"));
assertFalse(startup.containsKey("io/fabric8/pax-pomerania/1.0.0/pax-pomerania-1.0.0.jar"));
assertFalse(startup.containsKey("io/fabric8/pax-avaria/1.0.0/pax-avaria-1.0.0-uber.jar"));
assertFalse(startup.containsKey("io/fabric8/pax-mazovia/1.0.0/pax-mazovia-1.0.0-uber.jar"));
assertFalse(startup.containsKey("io/fabric8/pax-novgorod/1.0.0/pax-novgorod-1.0.0-uber.jar"));
assertFalse(startup.containsKey("io/fabric8/pax-castile/1.0.0/pax-castile-1.0.0-uber.jar"));
}
}
use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.
the class PatchServiceImplTest method testVersionHistory.
@Test
public void testVersionHistory() {
// the same bundle has been patched twice
Patch patch1 = new Patch(new PatchData("patch1", "First patch", null, null, null, null, null), null);
patch1.setResult(new PatchResult(patch1.getPatchData(), true, System.currentTimeMillis(), new LinkedList<org.jboss.fuse.patch.management.BundleUpdate>(), null, null));
patch1.getResult().getBundleUpdates().add(new BundleUpdate("my-bsn", "1.1.0", "mvn:groupId/my-bsn/1.1.0", "1.0.0", "mvn:groupId/my-bsn/1.0.0"));
Patch patch2 = new Patch(new PatchData("patch2", "Second patch", null, null, null, null, null), null);
patch2.setResult(new PatchResult(patch1.getPatchData(), true, System.currentTimeMillis(), new LinkedList<org.jboss.fuse.patch.management.BundleUpdate>(), null, null));
patch2.getResult().getBundleUpdates().add(new BundleUpdate("my-bsn;directive1=true", "1.2.0", "mvn:groupId/my-bsn/1.2.0", "1.1.0", "mvn:groupId/my-bsn/1.1.0"));
Map<String, Patch> patches = new HashMap<String, Patch>();
patches.put("patch1", patch1);
patches.put("patch2", patch2);
// the version history should return the correct URL, even when bundle.getLocation() does not
PatchServiceImpl.BundleVersionHistory history = new PatchServiceImpl.BundleVersionHistory(patches);
assertEquals("Should return version from patch result instead of the original location", "mvn:groupId/my-bsn/1.2.0", history.getLocation(createMockBundle("my-bsn", "1.2.0", "mvn:groupId/my-bsn/1.0.0")));
assertEquals("Should return version from patch result instead of the original location", "mvn:groupId/my-bsn/1.1.0", history.getLocation(createMockBundle("my-bsn", "1.1.0", "mvn:groupId/my-bsn/1.0.0")));
assertEquals("Should return original bundle location if no maching version is found in the history", "mvn:groupId/my-bsn/1.0.0", history.getLocation(createMockBundle("my-bsn", "1.0.0", "mvn:groupId/my-bsn/1.0.0")));
assertEquals("Should return original bundle location if no maching version is found in the history", "mvn:groupId/my-bsn/0.9.0", history.getLocation(createMockBundle("my-bsn", "0.9.0", "mvn:groupId/my-bsn/0.9.0")));
}
use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.
the class PatchServiceImplTest method testLoadWithRanges.
@Test
public void testLoadWithRanges() throws IOException {
PatchServiceImpl service = createMockServiceImpl();
PatchData pd = PatchData.load(getClass().getClassLoader().getResourceAsStream("test2.patch"));
assertEquals(2, pd.getBundles().size());
assertEquals("[1.0.0,2.0.0)", pd.getVersionRange("mvn:io.fabric8.test/test1/1.0.0"));
assertNull(pd.getVersionRange("mvn:io.fabric8.test/test2/1.0.0"));
assertTrue(pd.getRequirements().isEmpty());
}
use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.
the class FileBackupTest method backupSomeDataFiles.
@Test
public void backupSomeDataFiles() throws IOException {
PatchData patchData = new PatchData("my-patch");
patchData.setPatchLocation(new File(karafHome, "patches"));
PatchResult result = new PatchResult(patchData);
// updates installed bundle, has data dir
BundleUpdate b3 = new BundleUpdate("com.irrelevant.services", "1.2", "file:/dev/null", "1.1.0", "file:/dev/random");
// updates installed bundle, has data dir, but special case
BundleUpdate b4 = new BundleUpdate("org.apache.karaf.features.core", "1.3", "file:/dev/null", "1.2.1", "file:/dev/random");
// reinstalled bundle, has data dir
BundleUpdate b5 = new BundleUpdate("com.irrelevant.iot", null, null, "1.2.5", "file:/dev/random");
// reinstalled bundle, no data dir
BundleUpdate b6 = new BundleUpdate("com.irrelevant.space", null, null, "1.1.0", "file:/dev/random");
// update, but not for installed bundle
BundleUpdate b7 = new BundleUpdate("com.irrelevant.the.final.frontier", "1.5", "file:/dev/null", "1.1.3", "file:/dev/random");
result.getBundleUpdates().add(b3);
result.getBundleUpdates().add(b4);
result.getBundleUpdates().add(b5);
result.getBundleUpdates().add(b6);
result.getBundleUpdates().add(b7);
new FileBackupService(sys).backupDataFiles(result, Pending.ROLLUP_INSTALLATION);
Properties props = new Properties();
props.load(new FileInputStream(new File(karafHome, "patches/my-patch.datafiles/backup-install.properties")));
assertThat(props.getProperty("com.irrelevant.services$$1.1.0"), equalTo("com.irrelevant.services$$1.1.0"));
assertThat(props.getProperty("com.irrelevant.services$$1.2"), equalTo("com.irrelevant.services$$1.1.0"));
assertThat(props.getProperty("com.irrelevant.iot$$1.2.5"), equalTo("com.irrelevant.iot$$1.2.5"));
assertThat(props.stringPropertyNames().size(), equalTo(3));
assertTrue(new File(karafHome, "patches/my-patch.datafiles/install/com.irrelevant.services$$1.1.0/data/x").isDirectory());
assertTrue(new File(karafHome, "patches/my-patch.datafiles/install/com.irrelevant.iot$$1.2.5/data/z").isDirectory());
assertFalse(new File(karafHome, "patches/my-patch.datafiles/install/com.irrelevant.the.final.frontier$$1.5").isDirectory());
}
use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.
the class DiffUtils method generateDiffReport.
/**
* <p>Having four commits, generate single, HTML report about all modified files</p>
* <p>Please excuse inline html code.</p>
* @param patch
* @param git
* @param conflicts
* @param base
* @param ours
* @param theirs
* @param resolved
* @param result
*/
public static void generateDiffReport(Patch patch, PatchResult patchResult, Git git, Set<String> conflicts, RevCommit base, RevCommit ours, RevCommit theirs, RevCommit resolved, Writer result) throws IOException {
ObjectReader reader = git.getRepository().newObjectReader();
CanonicalTreeParser ctpBase = new CanonicalTreeParser();
CanonicalTreeParser ctpOurs = new CanonicalTreeParser();
CanonicalTreeParser ctpTheirs = new CanonicalTreeParser();
CanonicalTreeParser ctpResolved = new CanonicalTreeParser();
ctpBase.reset(reader, base.getTree());
ctpOurs.reset(reader, ours.getTree());
ctpTheirs.reset(reader, theirs.getTree());
ctpResolved.reset(reader, resolved.getTree());
// this map will contain 3 diffs for each file/path:
// 0 - diff between base and "ours" ("ours" depends on patch kind and it's really "ours" in P-Patch,
// because patch change is cherry-picked on top of custom change. In R-Patch, custom changes come after
// patch, so they're called "theirs" in diff/git terminology)
// 1 - diff between base and "theirs" (see above)
// 2 - diff between base and resolved, effective and final state of history
Map<String, DiffEntry[]> report = new LinkedHashMap<>();
// 1. base -> ours
TreeWalk walk = new TreeWalk(reader);
walk.addTree(ctpBase);
walk.addTree(ctpOurs);
walk.setRecursive(true);
List<DiffEntry> diffs = DiffEntry.scan(walk);
diffs.forEach(de -> collect(report, de, 0));
// 2. base -> theirs
walk.reset();
ctpBase.reset(reader, base.getTree());
walk.addTree(ctpBase);
walk.addTree(ctpTheirs);
walk.setRecursive(true);
diffs = DiffEntry.scan(walk);
diffs.forEach(de -> collect(report, de, 1));
// 3. base -> resolved
walk.reset();
ctpBase.reset(reader, base.getTree());
walk.addTree(ctpBase);
walk.addTree(ctpResolved);
walk.setRecursive(true);
diffs = DiffEntry.scan(walk);
diffs.forEach(de -> collect(report, de, 2));
// report generation
PatchData pd = patchResult.getPatchData();
result.write(reportHeader.replace("@PATCH_ID@", pd.getId()));
PatchReport pr = patchResult.getReport();
result.write("<table class=\"summary\">\n" + " <tr>\n" + " <td class=\"f\">Patch ID:</td><td>" + pr.getId() + "</td>\n" + " </tr>\n" + " <tr>\n" + " <td class=\"f\">Patch type:</td><td>" + (pr.isRollup() ? "rollup" : "non-rollup") + "</td>\n" + " </tr>\n" + " <tr>\n" + " <td class=\"f\">Installation date:</td><td>" + DATE.format(pr.getTimestamp()) + "</td>\n" + " </tr>\n" + " <tr>\n" + " <td class=\"f\">Bundles updated</td><td>" + pr.getUpdatedBundles() + "</td>\n" + " </tr>\n" + " <tr>\n" + " <td class=\"f\">Features updated</td><td>" + pr.getUpdatedFeatures() + "</td>\n" + " </tr>\n" + " <tr>\n" + " <td class=\"f\">Features overriden</td><td>" + pr.getOverridenFeatures() + "</td>\n" + " </tr>\n" + " <tr>\n" + " <td class=\"f\">File conflicts</td><td>" + conflicts.size() + "</td>\n" + " </tr>\n" + " </table>\n" + "</div>\n");
if (conflicts.size() > 0) {
result.write("<h1 class=\"header\">\n" + " <div>Conflicting files</div>\n" + "</h1>\n");
}
for (Map.Entry<String, DiffEntry[]> e : report.entrySet()) {
if (!conflicts.contains(e.getKey())) {
// we don't care about diffs that aren't really conflicts
continue;
}
result.write(fileHeader1);
result.write(e.getKey());
result.write(fileHeader2);
// we have max 3 entries (not all entries may be present
result.write("<td class=\"side\">\n" + " <div class=\"header\">Custom version</div>\n" + " <div class=\"content" + (e.getValue()[0] != null ? "" : " empty") + "\">");
if (e.getValue()[0] != null) {
// custom change
diff(git, reader, e.getValue()[0], result);
} else {
result.write("No change");
}
result.write("</div>\n" + " </td>");
result.write("<td class=\"side\">\n" + " <div class=\"header\">Patch</div>\n" + " <div class=\"content" + (e.getValue()[1] != null ? "" : " empty") + "\">");
if (e.getValue()[1] != null) {
// patch change
diff(git, reader, e.getValue()[1], result);
} else {
result.write("No change");
}
result.write("</div>\n" + " </td>");
result.write("<td class=\"side\">\n" + " <div class=\"header\">Final version</div>\n" + " <div class=\"content" + (e.getValue()[2] != null ? "" : " empty") + "\">");
if (e.getValue()[2] != null) {
// effective change - should always be available
// or maybe not when both patch and user removed the file?
diff(git, reader, e.getValue()[2], result);
} else {
result.write("No change");
}
result.write("</div>\n" + " </td>");
result.write(fileFooter);
}
result.write(reportFooter);
}
Aggregations