1 package net.pterodactylus.sone.core;
3 import static java.lang.Long.MAX_VALUE;
4 import static net.pterodactylus.sone.main.SonePlugin.VERSION;
5 import static org.hamcrest.MatcherAssert.assertThat;
6 import static org.hamcrest.Matchers.instanceOf;
7 import static org.hamcrest.Matchers.is;
8 import static org.mockito.ArgumentCaptor.forClass;
9 import static org.mockito.Matchers.any;
10 import static org.mockito.Matchers.argThat;
11 import static org.mockito.Mockito.mock;
12 import static org.mockito.Mockito.never;
13 import static org.mockito.Mockito.times;
14 import static org.mockito.Mockito.verify;
15 import static org.mockito.Mockito.when;
17 import java.io.IOException;
18 import java.io.InputStream;
20 import net.pterodactylus.sone.core.FreenetInterface.Callback;
21 import net.pterodactylus.sone.core.FreenetInterface.Fetched;
22 import net.pterodactylus.sone.core.event.UpdateFoundEvent;
23 import net.pterodactylus.util.version.Version;
25 import freenet.client.ClientMetadata;
26 import freenet.client.FetchResult;
27 import freenet.keys.FreenetURI;
28 import freenet.support.api.Bucket;
29 import freenet.support.io.ArrayBucket;
31 import com.google.common.eventbus.EventBus;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.mockito.ArgumentCaptor;
35 import org.mockito.invocation.InvocationOnMock;
36 import org.mockito.stubbing.Answer;
39 * Unit test for {@link UpdateChecker}.
41 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
43 public class UpdateCheckerTest {
45 private final EventBus eventBus = mock(EventBus.class);
46 private final FreenetInterface freenetInterface = mock(FreenetInterface.class);
47 private final Version currentVersion = new Version(1, 0, 0);
48 private final UpdateChecker updateChecker = new UpdateChecker(eventBus, freenetInterface, currentVersion);
51 public void startUpdateChecker() {
52 updateChecker.start();
56 public void newUpdateCheckerDoesNotHaveALatestVersion() {
57 assertThat(updateChecker.hasLatestVersion(), is(false));
58 assertThat(updateChecker.getLatestVersion(), is(currentVersion));
62 public void startingAnUpdateCheckerRegisterAUsk() {
63 verify(freenetInterface).registerUsk(any(FreenetURI.class), any(Callback.class));
67 public void stoppingAnUpdateCheckerUnregistersAUsk() {
69 verify(freenetInterface).unregisterUsk(any(FreenetURI.class));
73 public void callbackDoesNotDownloadIfNewEditionIsNotFound() {
74 setupCallbackWithEdition(MAX_VALUE, false, false);
75 verify(freenetInterface, never()).fetchUri(any(FreenetURI.class));
76 verify(eventBus, never()).post(argThat(instanceOf(UpdateFoundEvent.class)));
79 private void setupCallbackWithEdition(long edition, boolean newKnownGood, boolean newSlot) {
80 ArgumentCaptor<FreenetURI> uri = forClass(FreenetURI.class);
81 ArgumentCaptor<Callback> callback = forClass(Callback.class);
82 verify(freenetInterface).registerUsk(uri.capture(), callback.capture());
83 callback.getValue().editionFound(uri.getValue(), edition, newKnownGood, newSlot);
87 public void callbackStartsIfNewEditionIsFound() {
88 setupFetchResult(createFutureFetchResult());
89 setupCallbackWithEdition(MAX_VALUE, true, false);
90 verifyAFreenetUriIsFetched();
91 ArgumentCaptor<UpdateFoundEvent> updateFoundEvent = forClass(UpdateFoundEvent.class);
92 verify(eventBus, times(1)).post(updateFoundEvent.capture());
93 assertThat(updateFoundEvent.getValue().version(), is(new Version(99, 0, 0)));
94 assertThat(updateFoundEvent.getValue().releaseTime(), is(11865368297000L));
95 assertThat(updateChecker.getLatestVersion(), is(new Version(99, 0, 0)));
96 assertThat(updateChecker.getLatestVersionDate(), is(11865368297000L));
97 assertThat(updateChecker.hasLatestVersion(), is(true));
100 private FetchResult createFutureFetchResult() {
101 ClientMetadata clientMetadata = new ClientMetadata("application/xml");
102 Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
103 "CurrentVersion/Version: 99.0.0\n" +
104 "CurrentVersion/ReleaseTime: 11865368297000").getBytes());
105 return new FetchResult(clientMetadata, fetched);
109 public void callbackDoesNotStartIfNoNewEditionIsFound() {
110 setupFetchResult(createPastFetchResult());
111 setupCallbackWithEdition(updateChecker.getLatestEdition(), true, false);
112 verifyAFreenetUriIsFetched();
113 verifyNoUpdateFoundEventIsFired();
116 private void setupFetchResult(final FetchResult pastFetchResult) {
117 when(freenetInterface.fetchUri(any(FreenetURI.class))).thenAnswer(new Answer<Fetched>() {
119 public Fetched answer(InvocationOnMock invocation) throws Throwable {
120 FreenetURI freenetUri = (FreenetURI) invocation.getArguments()[0];
121 return new Fetched(freenetUri, pastFetchResult);
126 private FetchResult createPastFetchResult() {
127 ClientMetadata clientMetadata = new ClientMetadata("application/xml");
128 Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
129 "CurrentVersion/Version: 0.2\n" +
130 "CurrentVersion/ReleaseTime: 1289417883000").getBytes());
131 return new FetchResult(clientMetadata, fetched);
135 public void invalidUpdateFileDoesNotStartCallback() {
136 setupFetchResult(createInvalidFetchResult());
137 setupCallbackWithEdition(MAX_VALUE, true, false);
138 verifyAFreenetUriIsFetched();
139 verifyNoUpdateFoundEventIsFired();
142 private FetchResult createInvalidFetchResult() {
143 ClientMetadata clientMetadata = new ClientMetadata("text/plain");
144 Bucket fetched = new ArrayBucket("Some other data.".getBytes());
145 return new FetchResult(clientMetadata, fetched);
149 public void nonExistingPropertiesWillNotCauseUpdateToBeFound() {
150 setupCallbackWithEdition(MAX_VALUE, true, false);
151 verifyAFreenetUriIsFetched();
152 verifyNoUpdateFoundEventIsFired();
155 private void verifyNoUpdateFoundEventIsFired() {
156 verify(eventBus, never()).post(any(UpdateFoundEvent.class));
159 private void verifyAFreenetUriIsFetched() {
160 verify(freenetInterface).fetchUri(any(FreenetURI.class));
164 public void brokenBucketDoesNotCauseUpdateToBeFound() {
165 setupFetchResult(createBrokenBucketFetchResult());
166 setupCallbackWithEdition(MAX_VALUE, true, false);
167 verifyAFreenetUriIsFetched();
168 verifyNoUpdateFoundEventIsFired();
171 private FetchResult createBrokenBucketFetchResult() {
172 ClientMetadata clientMetadata = new ClientMetadata("text/plain");
173 Bucket fetched = new ArrayBucket("Some other data.".getBytes()) {
175 public InputStream getInputStream() {
177 return when(mock(InputStream.class).read()).thenThrow(IOException.class).getMock();
178 } catch (IOException ioe1) {
179 /* won’t throw here. */
184 return new FetchResult(clientMetadata, fetched);
188 public void invalidTimeDoesNotCauseAnUpdateToBeFound() {
189 setupFetchResult(createInvalidTimeFetchResult());
190 setupCallbackWithEdition(MAX_VALUE, true, false);
191 verifyAFreenetUriIsFetched();
192 verifyNoUpdateFoundEventIsFired();
195 private FetchResult createInvalidTimeFetchResult() {
196 ClientMetadata clientMetadata = new ClientMetadata("application/xml");
197 Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
198 "CurrentVersion/Version: 0.2\n" +
199 "CurrentVersion/ReleaseTime: invalid").getBytes());
200 return new FetchResult(clientMetadata, fetched);
204 public void invalidPropertiesDoesNotCauseAnUpdateToBeFound() {
205 setupFetchResult(createMissingTimeFetchResult());
206 setupCallbackWithEdition(MAX_VALUE, true, false);
207 verifyAFreenetUriIsFetched();
208 verifyNoUpdateFoundEventIsFired();
211 private FetchResult createMissingTimeFetchResult() {
212 ClientMetadata clientMetadata = new ClientMetadata("application/xml");
213 Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
214 "CurrentVersion/Version: 0.2\n").getBytes());
215 return new FetchResult(clientMetadata, fetched);
219 public void invalidVersionDoesNotCauseAnUpdateToBeFound() {
220 setupFetchResult(createInvalidVersionFetchResult());
221 setupCallbackWithEdition(MAX_VALUE, true, false);
222 verifyAFreenetUriIsFetched();
223 verifyNoUpdateFoundEventIsFired();
226 private FetchResult createInvalidVersionFetchResult() {
227 ClientMetadata clientMetadata = new ClientMetadata("application/xml");
228 Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
229 "CurrentVersion/Version: foo\n" +
230 "CurrentVersion/ReleaseTime: 1289417883000").getBytes());
231 return new FetchResult(clientMetadata, fetched);