package org.rhq.core.domain.drift; import static java.util.Arrays.asList; import static org.rhq.core.domain.drift.DriftCategory.FILE_ADDED; import static org.rhq.core.domain.drift.DriftCategory.FILE_CHANGED; import static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED; import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE; import static org.rhq.core.domain.drift.DriftChangeSetCategory.DRIFT; import static org.rhq.core.domain.drift.DriftFileStatus.LOADED; import static org.rhq.test.AssertUtils.assertCollectionMatchesNoOrder; import static org.testng.Assert.assertEquals; import java.io.Serializable; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.testng.annotations.Test; import org.rhq.core.domain.drift.DriftConfigurationDefinition.DriftHandlingMode; import org.rhq.core.domain.drift.DriftSnapshot.DriftSnapshotDirectory; @SuppressWarnings("unchecked") public class DriftSnapshotTest { @Test public void addChangeSetWithAddedFile() { int defId = 1; DriftSnapshotRequest request = new DriftSnapshotRequest(defId); FakeDriftChangeSet changeSet = new FakeDriftChangeSet(0, COVERAGE, defId).add(new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt")); Set drifts = changeSet.getDrifts(); DriftSnapshot snapshot = new DriftSnapshot(request).addChangeSet(changeSet); assertCollectionMatchesNoOrder(drifts, snapshot.getDriftInstances(), "Failed to build " + "a snapshot that contains a single change set"); assertEquals(snapshot.getVersion(), changeSet.getVersion(), "Snapshot version is wrong"); } @Test public void addChangeSetsWithAddedFiles() { int defId = 1; DriftSnapshotRequest request = new DriftSnapshotRequest(defId, 1); Drift<?, ?> entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt"); FakeDriftChangeSet changeSet0 = new FakeDriftChangeSet(0, COVERAGE, defId).add(entry1); Drift<?, ?> entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("4a5b6c", 1024, LOADED), "/drift/2.txt"); FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(1, DRIFT, defId).add(entry2); DriftSnapshot snapshot = new DriftSnapshot(request).addChangeSet(changeSet0).addChangeSet(changeSet1); // not sure but asSet with one arg was not working for me, so create Set manually Set set = new HashSet<Drift<?, ?>>(); set.add(entry1); set.add(entry2); assertCollectionMatchesNoOrder(set, snapshot.getDriftInstances(), "Failed to build snapshot " + "with two change sets and file added in second change set"); assertEquals(snapshot.getVersion(), changeSet1.getVersion(), "Snapshot version is wrong"); } @Test public void replaceFileWithChangedVersion() { int defId = 1; DriftSnapshotRequest request = new DriftSnapshotRequest(defId, 1); Drift<?, ?> entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt"); FakeDriftChangeSet changeSet0 = new FakeDriftChangeSet(0, COVERAGE, defId).add(entry1); Drift<?, ?> entry2 = new FakeDrift(FILE_CHANGED, new FakeDriftFile("a1b2c3", 1024, LOADED), new FakeDriftFile( "4d5e6f", 1024, LOADED), "/drift/1.txt"); FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(1, DRIFT, defId).add(entry2); DriftSnapshot snapshot = new DriftSnapshot(request).addChangeSet(changeSet0).addChangeSet(changeSet1); // not sure but asSet with one arg was not working for me, so create Set manually Set set = new HashSet<Drift<?, ?>>(); set.add(entry2); assertCollectionMatchesNoOrder(set, snapshot.getDriftInstances(), "Failed to build snapshot with file changed"); } @Test public void deleteFileThatHasBeenRemoved() { int defId = 1; DriftSnapshotRequest request = new DriftSnapshotRequest(defId, 1); Drift<?, ?> entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt"); Drift<?, ?> entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("d1f2a3", 1024, LOADED), "/drift/2.txt"); FakeDriftChangeSet changeSet0 = new FakeDriftChangeSet(0, COVERAGE, defId).add(entry1).add(entry2); Drift entry3 = new FakeDrift(FILE_REMOVED, new FakeDriftFile("a1b2c3", 1024, LOADED), null, "/drift/1.txt"); FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(1, DRIFT, defId).add(entry3); DriftSnapshot snapshot = new DriftSnapshot(request).addChangeSet(changeSet0).addChangeSet(changeSet1); // not sure but asSet with one arg was not working for me, so create Set manually Set set = new HashSet<Drift<?, ?>>(); set.add(entry2); assertCollectionMatchesNoOrder(set, snapshot.getDriftInstances(), "Failed to build snapshot with a file " + "removed."); } @Test public void directorySnapshotTest() { int defId = 1; DriftSnapshotRequest request = new DriftSnapshotRequest(defId, 1, null, null, true, false); Drift<?, ?> entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt"); Drift<?, ?> entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("d1f2a3", 1024, LOADED), "/drift/2.txt"); Drift<?, ?> entry3 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("abcd12", 1024, LOADED), "/another/1.txt"); FakeDriftChangeSet changeSet0 = new FakeDriftChangeSet(0, COVERAGE, defId).add(entry1).add(entry2).add(entry3); Drift entry4 = new FakeDrift(FILE_REMOVED, new FakeDriftFile("a1b2c3", 1024, LOADED), null, "/drift/1.txt"); FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(1, DRIFT, defId).add(entry4); DriftSnapshot snapshot = new DriftSnapshot(request).addChangeSet(changeSet0).addChangeSet(changeSet1); assert null == snapshot.getDriftInstances(); assert null != snapshot.getDriftDirectories(); assert 2 == snapshot.getDriftDirectories().size(); Iterator<DriftSnapshotDirectory> iterator = snapshot.getDriftDirectories().iterator(); // should be sorted alphabetically DriftSnapshotDirectory dir = iterator.next(); assert "/another".equals(dir.getDirectoryPath()); assert 1 == dir.getFiles(); assert 1 == dir.getAdded(); assert 0 == dir.getChanged(); assert 0 == dir.getRemoved(); dir = iterator.next(); assert "/drift".equals(dir.getDirectoryPath()); assert 1 == dir.getFiles(); assert 2 == dir.getAdded(); assert 0 == dir.getChanged(); assert 1 == dir.getRemoved(); } @Test public void diffShowsEntriesInLeftAndNotInRight() { int defId = 1; DriftSnapshotRequest rightRequest = new DriftSnapshotRequest(defId); DriftSnapshotRequest leftRequest = new DriftSnapshotRequest(defId); Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt"); FakeDriftChangeSet rightChangeSet0 = new FakeDriftChangeSet(0, COVERAGE, defId).add(entry1); DriftSnapshot right = new DriftSnapshot(rightRequest).addChangeSet(rightChangeSet0); // recreate rightChangeSet0 because addChangeSet is destructive rightChangeSet0 = new FakeDriftChangeSet(0, COVERAGE, defId).add(entry1); Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a3b6c9", 1024, LOADED), "/drift/2.txt"); FakeDriftChangeSet leftChangeSet0 = new FakeDriftChangeSet(0, COVERAGE, defId).add(entry1).add(entry2); DriftSnapshot left = new DriftSnapshot(leftRequest).addChangeSet(rightChangeSet0).addChangeSet(leftChangeSet0); DriftDiffReport diff = left.diff(right); assertCollectionMatchesNoOrder(asList(entry2), diff.getElementsNotInRight(), "Diff report does not contain " + "elements that are in the left but not in the right."); } @Test public void diffShowsEntriesInRightAndNotInLeft() { int defId = 1; DriftSnapshotRequest rightRequest = new DriftSnapshotRequest(defId); DriftSnapshotRequest leftRequest = new DriftSnapshotRequest(defId); Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt"); FakeDriftChangeSet rightChangeSet0 = new FakeDriftChangeSet(0, COVERAGE, defId).add(entry1); DriftSnapshot right = new DriftSnapshot(rightRequest).addChangeSet(rightChangeSet0); Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a3b6c9", 1024, LOADED), "/drift/2.txt"); FakeDriftChangeSet leftChangeSet0 = new FakeDriftChangeSet(0, COVERAGE, defId).add(entry2); DriftSnapshot left = new DriftSnapshot(leftRequest).addChangeSet(leftChangeSet0); DriftDiffReport diff = left.diff(right); assertCollectionMatchesNoOrder(asList(entry1), diff.getElementsNotInLeft(), "Diff report does not contain " + "elements that are in the left but not in the right"); } @Test public void diffShowsEntriesInLeftAndRightThatAreInConflict() { int defId = 1; DriftSnapshotRequest rightRequest = new DriftSnapshotRequest(defId); DriftSnapshotRequest leftRequest = new DriftSnapshotRequest(defId); Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drfit/1.txt"); FakeDriftChangeSet changeSet0 = new FakeDriftChangeSet(0, COVERAGE, defId).add(entry1); DriftSnapshot right = new DriftSnapshot(rightRequest).addChangeSet(changeSet0); Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("c3b2a1", 1024, LOADED), "/drfit/1.txt"); FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(1, DRIFT, defId).add(entry2); DriftSnapshot left = new DriftSnapshot(leftRequest).addChangeSet(changeSet1); DriftDiffReport diff = left.diff(right); assertCollectionMatchesNoOrder(asList(entry2), diff.getElementsInConflict(), "Diff report does not contain " + "element that are in both left and right and are in conflict"); } <E> Set<E> asSet(E... elements) { HashSet<E> set = new HashSet<E>(); for (E element : elements) { set.add(element); } return set; } static class FakeDriftChangeSet implements DriftChangeSet { private String id; private int version; private DriftChangeSetCategory category; private int configId; private DriftHandlingMode mode = DriftHandlingMode.normal; private Set<Drift> drifts = new HashSet<Drift>(); private long ctime = System.currentTimeMillis(); public FakeDriftChangeSet() { } public FakeDriftChangeSet(int version, DriftChangeSetCategory category, int configId) { this.version = version; this.category = category; this.configId = configId; } @Override public String getId() { return id; } @Override public void setId(String id) { this.id = id; } @Override public Long getCtime() { return ctime; } @Override public int getVersion() { return version; } @Override public void setVersion(int version) { this.version = version; } @Override public DriftChangeSetCategory getCategory() { return category; } @Override public void setCategory(DriftChangeSetCategory category) { this.category = category; } @Override public int getDriftDefinitionId() { return configId; } @Override public void setDriftDefinitionId(int id) { configId = id; } @Override public int getResourceId() { return 0; } @Override public void setResourceId(int id) { } @Override public Set getDrifts() { return drifts; } @Override public void setDrifts(Set drifts) { this.drifts = drifts; } public FakeDriftChangeSet add(Drift drift) { drifts.add(drift); return this; } @Override public DriftHandlingMode getDriftHandlingMode() { return this.mode; } @Override public void setDriftHandlingMode(DriftHandlingMode mode) { this.mode = mode; } } static class FakeDrift implements Drift { private String id; private DriftCategory category; private String path; private String directory; private DriftFile oldFile; private DriftFile newFile; private long ctime = System.currentTimeMillis(); public FakeDrift() { } public FakeDrift(DriftCategory category, DriftFile oldFile, DriftFile newFile, String path) { this.category = category; this.oldFile = oldFile; this.newFile = newFile; this.path = path; } @Override public String getId() { return id; } @Override public void setId(String id) { this.id = id; } @Override public Long getCtime() { return ctime; } @Override public DriftChangeSet getChangeSet() { return null; } @Override public void setChangeSet(DriftChangeSet changeSet) { } @Override public DriftCategory getCategory() { return category; } @Override public void setCategory(DriftCategory category) { this.category = category; } @Override public String getPath() { return path; } @Override public void setPath(String path) { this.path = path; } @Override public String getDirectory() { return this.directory; } @Override public void setDirectory(String directory) { this.directory = directory; } @Override public DriftFile getOldDriftFile() { return oldFile; } @Override public void setOldDriftFile(DriftFile oldDriftFile) { this.oldFile = oldDriftFile; } @Override public DriftFile getNewDriftFile() { return newFile; } @Override public void setNewDriftFile(DriftFile newDriftFile) { newFile = newDriftFile; } @Override public String toString() { return "Drift[category: " + category.code() + ", oldFile: " + oldFile + ", newFile: " + newFile + ", path: " + path + "]"; } } static class FakeDriftFile implements Serializable, DriftFile { private static final long serialVersionUID = 1L; private String hash; private long size; private DriftFileStatus status; private long ctime = System.currentTimeMillis(); public FakeDriftFile() { } public FakeDriftFile(String hash, long size, DriftFileStatus status) { this.hash = hash; this.size = size; this.status = status; } @Override public String getHashId() { return hash; } @Override public void setHashId(String hashId) { hash = hashId; } @Override public Long getCtime() { return ctime; } @Override public Long getDataSize() { return size; } @Override public void setDataSize(Long size) { this.size = size; } @Override public DriftFileStatus getStatus() { return status; } @Override public void setStatus(DriftFileStatus status) { this.status = status; } @Override public String toString() { return "DriftFile[hashId: " + hash + ", dataSize: " + size + ", status: " + status.ordinal() + "]"; } } }