From c74a6b50636ab4c13967ac90fa4155eea028b836 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 2 Aug 2014 13:09:04 +0200 Subject: [PATCH] Add more tests of sone inserter. --- .../net/pterodactylus/sone/core/SoneInserter.java | 7 +- .../pterodactylus/sone/core/SoneInserterTest.java | 182 ++++++++++++++++++++- 2 files changed, 183 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/pterodactylus/sone/core/SoneInserter.java b/src/main/java/net/pterodactylus/sone/core/SoneInserter.java index 729f434..1e93aa6 100644 --- a/src/main/java/net/pterodactylus/sone/core/SoneInserter.java +++ b/src/main/java/net/pterodactylus/sone/core/SoneInserter.java @@ -116,12 +116,17 @@ public class SoneInserter extends AbstractService { * The Sone to insert */ public SoneInserter(Core core, EventBus eventBus, FreenetInterface freenetInterface, Sone sone) { + this(core, eventBus, freenetInterface, sone, new SoneModificationDetector(core, sone, insertionDelay)); + } + + @VisibleForTesting + SoneInserter(Core core, EventBus eventBus, FreenetInterface freenetInterface, Sone sone, SoneModificationDetector soneModificationDetector) { super("Sone Inserter for “" + sone.getName() + "”", false); this.core = core; this.eventBus = eventBus; this.freenetInterface = freenetInterface; this.sone = sone; - this.soneModificationDetector = new SoneModificationDetector(core, sone, insertionDelay); + this.soneModificationDetector = soneModificationDetector; } // diff --git a/src/test/java/net/pterodactylus/sone/core/SoneInserterTest.java b/src/test/java/net/pterodactylus/sone/core/SoneInserterTest.java index 05cc49e..b303a1c 100644 --- a/src/test/java/net/pterodactylus/sone/core/SoneInserterTest.java +++ b/src/test/java/net/pterodactylus/sone/core/SoneInserterTest.java @@ -2,21 +2,37 @@ package net.pterodactylus.sone.core; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.HashMap; import net.pterodactylus.sone.core.SoneInserter.InsertInformation; import net.pterodactylus.sone.core.SoneInserter.SetInsertionDelay; +import net.pterodactylus.sone.core.event.SoneEvent; +import net.pterodactylus.sone.core.event.SoneInsertAbortedEvent; +import net.pterodactylus.sone.core.event.SoneInsertedEvent; +import net.pterodactylus.sone.core.event.SoneInsertingEvent; import net.pterodactylus.sone.data.Album; import net.pterodactylus.sone.data.Sone; import freenet.keys.FreenetURI; import com.google.common.eventbus.EventBus; +import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; /** * Unit test for {@link SoneInserter} and its subclasses. @@ -25,6 +41,16 @@ import org.junit.Test; */ public class SoneInserterTest { + private final Core core = mock(Core.class); + private final EventBus eventBus = mock(EventBus.class); + private final FreenetInterface freenetInterface = mock(FreenetInterface.class); + + @Before + public void setupCore() { + UpdateChecker updateChecker = mock(UpdateChecker.class); + when(core.getUpdateChecker()).thenReturn(updateChecker); + } + @Test public void insertionDelayIsForwardedToSoneInserter() { SetInsertionDelay setInsertionDelay = new SetInsertionDelay(); @@ -38,11 +64,6 @@ public class SoneInserterTest { FreenetURI insertUri = mock(FreenetURI.class); String fingerprint = "fingerprint"; Sone sone = createSone(insertUri, fingerprint); - Core core = mock(Core.class); - UpdateChecker updateChecker = mock(UpdateChecker.class); - when(core.getUpdateChecker()).thenReturn(updateChecker); - EventBus eventBus = mock(EventBus.class); - FreenetInterface freenetInterface = mock(FreenetInterface.class); SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone); InsertInformation insertInformation = soneInserter.new InsertInformation(sone); HashMap manifestEntries = insertInformation.generateManifestEntries(); @@ -59,4 +80,155 @@ public class SoneInserterTest { return sone; } + @Test(expected = IllegalArgumentException.class) + public void soneOfSoneInserterCanNotBeSetToADifferentSone() { + Sone sone = mock(Sone.class); + SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone); + soneInserter.setSone(mock(Sone.class)); + } + + @Test + public void soneCanBeSetToEqualSone() { + Sone sone = mock(Sone.class); + SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone); + soneInserter.setSone(sone); + } + + @Test + public void isModifiedIsTrueIfModificationDetectorSaysSo() { + Sone sone = mock(Sone.class); + SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class); + when(soneModificationDetector.isModified()).thenReturn(true); + SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector); + assertThat(soneInserter.isModified(), is(true)); + } + + @Test + public void isModifiedIsFalseIfModificationDetectorSaysSo() { + Sone sone = mock(Sone.class); + SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class); + SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector); + assertThat(soneInserter.isModified(), is(false)); + } + + @Test + public void lastFingerprintIsStoredCorrectly() { + Sone sone = mock(Sone.class); + SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone); + soneInserter.setLastInsertFingerprint("last-fingerprint"); + assertThat(soneInserter.getLastInsertFingerprint(), is("last-fingerprint")); + } + + @Test + public void soneInserterStopsWhenItShould() { + Sone sone = mock(Sone.class); + SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone); + soneInserter.stop(); + soneInserter.serviceRun(); + } + + @Test + public void soneInserterInsertsASoneIfItIsEligible() throws SoneException { + FreenetURI insertUri = mock(FreenetURI.class); + final FreenetURI finalUri = mock(FreenetURI.class); + String fingerprint = "fingerprint"; + Sone sone = createSone(insertUri, fingerprint); + SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class); + when(soneModificationDetector.isEligibleForInsert()).thenReturn(true); + when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenReturn(finalUri); + final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector); + doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + soneInserter.stop(); + return null; + } + }).when(core).touchConfiguration(); + soneInserter.serviceRun(); + ArgumentCaptor soneEvents = ArgumentCaptor.forClass(SoneEvent.class); + verify(freenetInterface).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html")); + verify(eventBus, times(2)).post(soneEvents.capture()); + assertThat(soneEvents.getAllValues().get(0), instanceOf(SoneInsertingEvent.class)); + assertThat(soneEvents.getAllValues().get(0).sone(), is(sone)); + assertThat(soneEvents.getAllValues().get(1), instanceOf(SoneInsertedEvent.class)); + assertThat(soneEvents.getAllValues().get(1).sone(), is(sone)); + } + + @Test + public void soneInserterBailsOutIfItIsStoppedWhileInserting() throws SoneException { + FreenetURI insertUri = mock(FreenetURI.class); + final FreenetURI finalUri = mock(FreenetURI.class); + String fingerprint = "fingerprint"; + Sone sone = createSone(insertUri, fingerprint); + SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class); + when(soneModificationDetector.isEligibleForInsert()).thenReturn(true); + final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector); + when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenAnswer(new Answer() { + @Override + public FreenetURI answer(InvocationOnMock invocation) throws Throwable { + soneInserter.stop(); + return finalUri; + } + }); + soneInserter.serviceRun(); + ArgumentCaptor soneEvents = ArgumentCaptor.forClass(SoneEvent.class); + verify(freenetInterface).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html")); + verify(eventBus, times(2)).post(soneEvents.capture()); + assertThat(soneEvents.getAllValues().get(0), instanceOf(SoneInsertingEvent.class)); + assertThat(soneEvents.getAllValues().get(0).sone(), is(sone)); + assertThat(soneEvents.getAllValues().get(1), instanceOf(SoneInsertedEvent.class)); + assertThat(soneEvents.getAllValues().get(1).sone(), is(sone)); + verify(core, never()).touchConfiguration(); + } + + @Test + public void soneInserterDoesNotInsertSoneIfItIsNotEligible() throws SoneException { + FreenetURI insertUri = mock(FreenetURI.class); + String fingerprint = "fingerprint"; + Sone sone = createSone(insertUri, fingerprint); + SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class); + final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector); + new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(500); + } catch (InterruptedException ie1) { + throw new RuntimeException(ie1); + } + soneInserter.stop(); + } + }).start(); + soneInserter.serviceRun(); + verify(freenetInterface, never()).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html")); + verify(eventBus, never()).post(argThat(org.hamcrest.Matchers.any(SoneEvent.class))); + } + + @Test + public void soneInserterPostsAbortedEventIfAnExceptionOccurs() throws SoneException { + FreenetURI insertUri = mock(FreenetURI.class); + String fingerprint = "fingerprint"; + Sone sone = createSone(insertUri, fingerprint); + SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class); + when(soneModificationDetector.isEligibleForInsert()).thenReturn(true); + final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector); + final SoneException soneException = new SoneException(new Exception()); + when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenAnswer(new Answer() { + @Override + public FreenetURI answer(InvocationOnMock invocation) throws Throwable { + soneInserter.stop(); + throw soneException; + } + }); + soneInserter.serviceRun(); + ArgumentCaptor soneEvents = ArgumentCaptor.forClass(SoneEvent.class); + verify(freenetInterface).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html")); + verify(eventBus, times(2)).post(soneEvents.capture()); + assertThat(soneEvents.getAllValues().get(0), instanceOf(SoneInsertingEvent.class)); + assertThat(soneEvents.getAllValues().get(0).sone(), is(sone)); + assertThat(soneEvents.getAllValues().get(1), instanceOf(SoneInsertAbortedEvent.class)); + assertThat(soneEvents.getAllValues().get(1).sone(), is(sone)); + verify(core, never()).touchConfiguration(); + } + } -- 2.7.4