diff --git a/core/pom.xml b/core/pom.xml index d9ffd0294c2ca50eb9ab42e50ac8f481d9100382..f661ff6249578399945673a8a327d9d5149428fb 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -42,6 +42,7 @@ THE SOFTWARE. 1.259 2.5.6.SEC03 2.4.12 + 2.2 @@ -189,10 +190,16 @@ THE SOFTWARE. jenkins-stapler-support 1.1 + + org.hamcrest + hamcrest + ${hamcrest.version} + test + org.hamcrest hamcrest-library - 1.3 + ${hamcrest.version} test diff --git a/core/src/main/java/hudson/model/FingerprintCleanupThread.java b/core/src/main/java/hudson/model/FingerprintCleanupThread.java index f698c6a1d37379c8a646d4a7c9a02b1fbcc5e20d..42631e8b5d0d8db4b88fdd65b8ec0092d453b219 100644 --- a/core/src/main/java/hudson/model/FingerprintCleanupThread.java +++ b/core/src/main/java/hudson/model/FingerprintCleanupThread.java @@ -23,7 +23,6 @@ */ package hudson.model; -import com.thoughtworks.xstream.converters.basic.DateConverter; import hudson.Extension; import hudson.ExtensionList; import hudson.Functions; @@ -35,6 +34,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import java.io.File; import java.io.IOException; +import java.util.Date; import java.util.regex.Pattern; /** @@ -54,8 +54,6 @@ public class FingerprintCleanupThread extends AsyncPeriodicWork { static final String FINGERPRINTS_DIR_NAME = "fingerprints"; private static final Pattern FINGERPRINT_FILE_PATTERN = Pattern.compile("[0-9a-f]{28}\\.xml"); - private static final DateConverter DATE_CONVERTER = new DateConverter(); - public FingerprintCleanupThread() { super("Fingerprint cleanup"); } @@ -118,7 +116,7 @@ public class FingerprintCleanupThread extends AsyncPeriodicWork { } else { if (!fp.isAlive()) { FingerprintFacet deletionBlockerFacet = fp.getFacetBlockingDeletion(); - listener.getLogger().println(deletionBlockerFacet.getClass().getName() + " created on " + DATE_CONVERTER.toString(deletionBlockerFacet.getTimestamp()) + " blocked deletion of " + fingerprintFile); + listener.getLogger().println(deletionBlockerFacet.getClass().getName() + " created on " + new Date(deletionBlockerFacet.getTimestamp()) + " blocked deletion of " + fingerprintFile); } // get the fingerprint in the official map so have the changes visible to Jenkins // otherwise the mutation made in FingerprintMap can override our trimming. diff --git a/core/src/test/java/hudson/model/FingerprintCleanupThreadTest.java b/core/src/test/java/hudson/model/FingerprintCleanupThreadTest.java index 549a50df505332263cfb26fcf26db43f647e8a43..7cf2d780d4848ac083f012581d763f6bd8a58a90 100644 --- a/core/src/test/java/hudson/model/FingerprintCleanupThreadTest.java +++ b/core/src/test/java/hudson/model/FingerprintCleanupThreadTest.java @@ -34,9 +34,17 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import jenkins.model.FingerprintFacet; + +import static org.hamcrest.io.FileMatchers.aReadableFile; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsNot.not; +import static org.hamcrest.core.StringContains.containsString; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertThat; public class FingerprintCleanupThreadTest { @@ -90,6 +98,33 @@ public class FingerprintCleanupThreadTest { assertTrue("Should have logged IOException.", logOutput.contains("ERROR: Failed to process")); } + @Test + public void testBlockingFacetBlocksDeletion() throws IOException { + createFolderStructure(); + TestTaskListener testTaskListener = new TestTaskListener(); + Fingerprint fp = new TestFingerprint(false); + fp.facets.setOwner(Saveable.NOOP); + TestFingperprintFacet facet = new TestFingperprintFacet(fp, System.currentTimeMillis(), true); + fp.facets.add(facet); + FingerprintCleanupThread cleanupThread = new TestFingerprintCleanupThread(fp); + cleanupThread.execute(testTaskListener); + String logOutput = testTaskListener.outputStream.toString(); + assertThat(logOutput, containsString("blocked deletion of")); + } + + @Test + public void testUnblockedFacetsDontBlockDeletion() throws IOException { + createFolderStructure(); + TestTaskListener testTaskListener = new TestTaskListener(); + Fingerprint fp = new TestFingerprint(false); + fp.facets.setOwner(Saveable.NOOP); + TestFingperprintFacet facet = new TestFingperprintFacet(fp, System.currentTimeMillis(), false); + fp.facets.add(facet); + FingerprintCleanupThread cleanupThread = new TestFingerprintCleanupThread(fp); + cleanupThread.execute(testTaskListener); + assertThat(fpFile.toFile(), is(not(aReadableFile()))); + } + private void createFolderStructure() throws IOException { createTestDir(); Path fingerprintsPath = tempDirectory.resolve(FingerprintCleanupThread.FINGERPRINTS_DIR_NAME); @@ -145,6 +180,21 @@ public class FingerprintCleanupThreadTest { } + public static final class TestFingperprintFacet extends FingerprintFacet { + + private boolean deletionBlocked; + + public TestFingperprintFacet(Fingerprint fingerprint, long timestamp, boolean deletionBlocked) { + super(fingerprint, timestamp); + this.deletionBlocked = deletionBlocked; + } + + @Override public boolean isFingerprintDeletionBlocked() { + return deletionBlocked; + } + + } + private static class TestFingerprint extends Fingerprint { private boolean isAlive = true;