✅ Add more tests for FreenetTemplatePage
[Sone.git] / src / test / java / net / pterodactylus / sone / core / WebOfTrustUpdaterTest.java
1 package net.pterodactylus.sone.core;
2
3 import static java.lang.Thread.sleep;
4 import static java.util.concurrent.TimeUnit.SECONDS;
5 import static org.hamcrest.MatcherAssert.assertThat;
6 import static org.hamcrest.Matchers.containsString;
7 import static org.hamcrest.Matchers.is;
8 import static org.hamcrest.Matchers.not;
9 import static org.mockito.ArgumentMatchers.eq;
10 import static org.mockito.Mockito.doAnswer;
11 import static org.mockito.Mockito.doThrow;
12 import static org.mockito.Mockito.mock;
13 import static org.mockito.Mockito.never;
14 import static org.mockito.Mockito.verify;
15 import static org.mockito.Mockito.when;
16
17 import java.util.concurrent.CountDownLatch;
18
19 import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.AddContextJob;
20 import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.RemoveContextJob;
21 import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.SetPropertyJob;
22 import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.SetTrustJob;
23 import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.WebOfTrustContextUpdateJob;
24 import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.WebOfTrustUpdateJob;
25 import net.pterodactylus.sone.freenet.plugin.PluginException;
26 import net.pterodactylus.sone.freenet.wot.Identity;
27 import net.pterodactylus.sone.freenet.wot.OwnIdentity;
28 import net.pterodactylus.sone.freenet.wot.Trust;
29 import net.pterodactylus.sone.freenet.wot.WebOfTrustConnector;
30 import net.pterodactylus.sone.freenet.wot.WebOfTrustException;
31
32 import org.junit.Test;
33 import org.mockito.invocation.InvocationOnMock;
34 import org.mockito.stubbing.Answer;
35
36 /**
37  * Unit test for {@link WebOfTrustUpdaterImpl} and its subclasses.
38  */
39 public class WebOfTrustUpdaterTest {
40
41         private static final String CONTEXT = "test-context";
42         private static final Integer SCORE = 50;
43         private static final Integer OTHER_SCORE = 25;
44         private static final String TRUST_COMMENT = "set in a test";
45         private static final String PROPERTY_NAME = "test-property";
46         private final WebOfTrustConnector webOfTrustConnector = mock(WebOfTrustConnector.class);
47         private final WebOfTrustUpdaterImpl webOfTrustUpdater = new WebOfTrustUpdaterImpl(webOfTrustConnector);
48         private final OwnIdentity ownIdentity = when(mock(OwnIdentity.class).getId()).thenReturn("own-identity-id").getMock();
49         private final WebOfTrustUpdateJob successfulWebOfTrustUpdateJob = createWebOfTrustUpdateJob(true);
50         private final WebOfTrustUpdateJob failingWebOfTrustUpdateJob = createWebOfTrustUpdateJob(false);
51         private final WebOfTrustContextUpdateJob contextUpdateJob = webOfTrustUpdater.new WebOfTrustContextUpdateJob(ownIdentity, CONTEXT);
52         private final AddContextJob addContextJob = webOfTrustUpdater.new AddContextJob(ownIdentity, CONTEXT);
53         private final RemoveContextJob removeContextJob = webOfTrustUpdater.new RemoveContextJob(ownIdentity, CONTEXT);
54         private final Identity trustee = when(mock(Identity.class).getId()).thenReturn("trustee-id").getMock();
55
56         private WebOfTrustUpdateJob createWebOfTrustUpdateJob(final boolean success) {
57                 return webOfTrustUpdater.new WebOfTrustUpdateJob() {
58                         @Override
59                         public void run() {
60                                 super.run();
61                                 try {
62                                         sleep(100);
63                                 } catch (InterruptedException ie1) {
64                                         throw new RuntimeException(ie1);
65                                 }
66                                 finish(success);
67                         }
68                 };
69         }
70
71         @Test
72         public void webOfTrustUpdateJobWaitsUntilFinishedHasBeenCalledAndReturnsSuccess() throws InterruptedException {
73                 new Thread(successfulWebOfTrustUpdateJob).start();
74                 assertThat(successfulWebOfTrustUpdateJob.waitForCompletion(), is(true));
75         }
76
77         @Test
78         public void webOfTrustUpdateJobWaitsUntilFinishedHasBeenCalledAndReturnsFailure() throws InterruptedException {
79                 new Thread(failingWebOfTrustUpdateJob).start();
80                 assertThat(failingWebOfTrustUpdateJob.waitForCompletion(), is(false));
81         }
82
83         @Test
84         public void webOfTrustContextUpdateJobsAreEqualIfTheirClassOwnIdentityAndContextAreEqual() {
85                 WebOfTrustContextUpdateJob secondContextUpdateJob = webOfTrustUpdater.new WebOfTrustContextUpdateJob(ownIdentity, CONTEXT);
86                 assertThat(contextUpdateJob.equals(secondContextUpdateJob), is(true));
87                 assertThat(secondContextUpdateJob.equals(contextUpdateJob), is(true));
88                 assertThat(contextUpdateJob.hashCode(), is(secondContextUpdateJob.hashCode()));
89         }
90
91         @Test
92         public void webOfTrustContextUpdatesJobsAreNotEqualIfTheirClassDiffers() {
93                 assertThat(contextUpdateJob.equals(addContextJob), is(false));
94         }
95
96         @Test
97         public void webOfTrustContextUpdateJobToStringContainsIdentityAndContext() {
98                 assertThat(contextUpdateJob.toString(), containsString(ownIdentity.toString()));
99                 assertThat(contextUpdateJob.toString(), containsString(CONTEXT));
100         }
101
102         @Test
103         public void webOfTrustContextUpdateJobsAreNotEqualIfTheIdentitiesDiffer() {
104                 OwnIdentity ownIdentity = mock(OwnIdentity.class);
105                 WebOfTrustContextUpdateJob secondContextUpdateJob = webOfTrustUpdater.new WebOfTrustContextUpdateJob(ownIdentity, CONTEXT);
106                 assertThat(contextUpdateJob.equals(secondContextUpdateJob), is(false));
107                 assertThat(secondContextUpdateJob.equals(contextUpdateJob), is(false));
108         }
109
110         @Test
111         public void webOfTrustContextUpdateJobsAreNotEqualIfTheirContextsDiffer() {
112                 WebOfTrustContextUpdateJob secondContextUpdateJob = webOfTrustUpdater.new WebOfTrustContextUpdateJob(ownIdentity, CONTEXT + CONTEXT);
113                 assertThat(contextUpdateJob.equals(secondContextUpdateJob), is(false));
114                 assertThat(secondContextUpdateJob.equals(contextUpdateJob), is(false));
115         }
116
117         @Test
118         public void webOfTrustContextUpdateJobsAreNotEqualToNull() {
119                 assertThat(contextUpdateJob.equals(null), is(false));
120         }
121
122         @Test
123         public void addContextJobAddsTheContext() throws PluginException {
124                 addContextJob.run();
125                 verify(webOfTrustConnector).addContext(eq(ownIdentity), eq(CONTEXT));
126                 verify(ownIdentity).addContext(eq(CONTEXT));
127                 assertThat(addContextJob.waitForCompletion(), is(true));
128         }
129
130         @Test
131         public void exceptionWhileAddingAContextIsExposed() throws PluginException {
132                 doThrow(PluginException.class).when(webOfTrustConnector).addContext(eq(ownIdentity), eq(CONTEXT));
133                 addContextJob.run();
134                 verify(webOfTrustConnector).addContext(eq(ownIdentity), eq(CONTEXT));
135                 verify(ownIdentity, never()).addContext(eq(CONTEXT));
136                 assertThat(addContextJob.waitForCompletion(), is(false));
137         }
138
139         @Test
140         public void removeContextJobRemovesTheContext() throws PluginException {
141                 removeContextJob.run();
142                 verify(webOfTrustConnector).removeContext(eq(ownIdentity), eq(CONTEXT));
143                 verify(ownIdentity).removeContext(eq(CONTEXT));
144                 assertThat(removeContextJob.waitForCompletion(), is(true));
145         }
146
147         @Test
148         public void exceptionWhileRemovingAContextIsExposed() throws PluginException {
149                 doThrow(PluginException.class).when(webOfTrustConnector).removeContext(eq(ownIdentity), eq(CONTEXT));
150                 removeContextJob.run();
151                 verify(webOfTrustConnector).removeContext(eq(ownIdentity), eq(CONTEXT));
152                 verify(ownIdentity, never()).removeContext(eq(CONTEXT));
153                 assertThat(removeContextJob.waitForCompletion(), is(false));
154         }
155
156         @Test
157         public void settingAPropertySetsTheProperty() throws PluginException {
158                 String propertyName = "property-name";
159                 String propertyValue = "property-value";
160                 SetPropertyJob setPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName, propertyValue);
161                 setPropertyJob.run();
162                 verify(webOfTrustConnector).setProperty(eq(ownIdentity), eq(propertyName), eq(propertyValue));
163                 verify(ownIdentity).setProperty(eq(propertyName), eq(propertyValue));
164                 assertThat(setPropertyJob.waitForCompletion(), is(true));
165         }
166
167         @Test
168         public void settingAPropertyToNullRemovesTheProperty() throws PluginException {
169                 String propertyName = "property-name";
170                 SetPropertyJob setPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName, null);
171                 setPropertyJob.run();
172                 verify(webOfTrustConnector).removeProperty(eq(ownIdentity), eq(propertyName));
173                 verify(ownIdentity).removeProperty(eq(propertyName));
174                 assertThat(setPropertyJob.waitForCompletion(), is(true));
175         }
176
177         @Test
178         public void pluginExceptionWhileSettingAPropertyIsHandled() throws PluginException {
179                 String propertyName = "property-name";
180                 String propertyValue = "property-value";
181                 doThrow(PluginException.class).when(webOfTrustConnector).setProperty(eq(ownIdentity), eq(propertyName), eq(propertyValue));
182                 SetPropertyJob setPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName, propertyValue);
183                 setPropertyJob.run();
184                 verify(webOfTrustConnector).setProperty(eq(ownIdentity), eq(propertyName), eq(propertyValue));
185                 verify(ownIdentity, never()).setProperty(eq(propertyName), eq(propertyValue));
186                 assertThat(setPropertyJob.waitForCompletion(), is(false));
187         }
188
189         @Test
190         public void setPropertyJobsWithSameClassPropertyAndValueAreEqual() {
191                 String propertyName = "property-name";
192                 String propertyValue = "property-value";
193                 SetPropertyJob firstSetPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName, propertyValue);
194                 SetPropertyJob secondSetPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName, propertyValue);
195                 assertThat(firstSetPropertyJob, is(secondSetPropertyJob));
196                 assertThat(secondSetPropertyJob, is(firstSetPropertyJob));
197                 assertThat(firstSetPropertyJob.hashCode(), is(secondSetPropertyJob.hashCode()));
198         }
199
200         @Test
201         public void setPropertyJobsWithDifferentClassesAreNotEqual() {
202                 String propertyName = "property-name";
203                 String propertyValue = "property-value";
204                 SetPropertyJob firstSetPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName, propertyValue);
205                 SetPropertyJob secondSetPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName, propertyValue) {
206                 };
207                 assertThat(firstSetPropertyJob, not(is(secondSetPropertyJob)));
208         }
209
210         @Test
211         public void nullIsNotASetProjectJobEither() {
212                 String propertyName = "property-name";
213                 String propertyValue = "property-value";
214                 SetPropertyJob setPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName, propertyValue);
215                 assertThat(setPropertyJob, not(is((Object) null)));
216         }
217
218         @Test
219         public void setPropertyJobsWithDifferentPropertiesAreNotEqual() {
220                 String propertyName = "property-name";
221                 String propertyValue = "property-value";
222                 SetPropertyJob firstSetPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName, propertyValue);
223                 SetPropertyJob secondSetPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName + "2", propertyValue);
224                 assertThat(firstSetPropertyJob, not(is(secondSetPropertyJob)));
225         }
226
227         @Test
228         public void setPropertyJobsWithDifferentOwnIdentitiesAreNotEqual() {
229                 OwnIdentity otherOwnIdentity = mock(OwnIdentity.class);
230                 String propertyName = "property-name";
231                 String propertyValue = "property-value";
232                 SetPropertyJob firstSetPropertyJob = webOfTrustUpdater.new SetPropertyJob(ownIdentity, propertyName, propertyValue);
233                 SetPropertyJob secondSetPropertyJob = webOfTrustUpdater.new SetPropertyJob(otherOwnIdentity, propertyName, propertyValue);
234                 assertThat(firstSetPropertyJob, not(is(secondSetPropertyJob)));
235         }
236
237         @Test
238         public void setTrustJobSetsTrust() throws PluginException {
239                 SetTrustJob setTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
240                 setTrustJob.run();
241                 verify(webOfTrustConnector).setTrust(eq(ownIdentity), eq(trustee), eq(SCORE), eq(TRUST_COMMENT));
242                 verify(trustee).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
243                 assertThat(setTrustJob.waitForCompletion(), is(true));
244         }
245
246         @Test
247         public void settingNullTrustRemovesTrust() throws WebOfTrustException {
248                 SetTrustJob setTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, null, TRUST_COMMENT);
249                 setTrustJob.run();
250                 verify(webOfTrustConnector).removeTrust(eq(ownIdentity), eq(trustee));
251                 verify(trustee).removeTrust(eq(ownIdentity));
252                 assertThat(setTrustJob.waitForCompletion(), is(true));
253         }
254
255         @Test
256         public void exceptionWhileSettingTrustIsCaught() throws PluginException {
257                 doThrow(PluginException.class).when(webOfTrustConnector).setTrust(eq(ownIdentity), eq(trustee), eq(SCORE), eq(TRUST_COMMENT));
258                 SetTrustJob setTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
259                 setTrustJob.run();
260                 verify(webOfTrustConnector).setTrust(eq(ownIdentity), eq(trustee), eq(SCORE), eq(TRUST_COMMENT));
261                 verify(trustee, never()).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
262                 assertThat(setTrustJob.waitForCompletion(), is(false));
263         }
264
265         @Test
266         public void setTrustJobsWithDifferentClassesAreNotEqual() {
267                 SetTrustJob firstSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
268                 SetTrustJob secondSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT) {
269                 };
270                 assertThat(firstSetTrustJob, not(is(secondSetTrustJob)));
271                 assertThat(secondSetTrustJob, not(is(firstSetTrustJob)));
272         }
273
274         @Test
275         public void setTrustJobsWithDifferentTrustersAreNotEqual() {
276                 SetTrustJob firstSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
277                 SetTrustJob secondSetTrustJob = webOfTrustUpdater.new SetTrustJob(mock(OwnIdentity.class), trustee, SCORE, TRUST_COMMENT);
278                 assertThat(firstSetTrustJob, not(is(secondSetTrustJob)));
279                 assertThat(secondSetTrustJob, not(is(firstSetTrustJob)));
280         }
281
282         @Test
283         public void setTrustJobsWithDifferentTrusteesAreNotEqual() {
284                 SetTrustJob firstSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
285                 SetTrustJob secondSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, mock(Identity.class), SCORE, TRUST_COMMENT);
286                 assertThat(firstSetTrustJob, not(is(secondSetTrustJob)));
287                 assertThat(secondSetTrustJob, not(is(firstSetTrustJob)));
288         }
289
290         @Test
291         public void setTrustJobsWithDifferentScoreAreEqual() {
292                 SetTrustJob firstSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
293                 SetTrustJob secondSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, OTHER_SCORE, TRUST_COMMENT);
294                 assertThat(firstSetTrustJob, is(secondSetTrustJob));
295                 assertThat(secondSetTrustJob, is(firstSetTrustJob));
296                 assertThat(firstSetTrustJob.hashCode(), is(secondSetTrustJob.hashCode()));
297         }
298
299         @Test
300         public void setTrustJobDoesNotEqualNull() {
301                 SetTrustJob setTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
302                 assertThat(setTrustJob, not(is((Object) null)));
303         }
304
305         @Test
306         public void toStringOfSetTrustJobContainsIdsOfTrusterAndTrustee() {
307                 SetTrustJob setTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
308                 assertThat(setTrustJob.toString(), containsString(ownIdentity.getId()));
309                 assertThat(setTrustJob.toString(), containsString(trustee.getId()));
310         }
311
312         @Test
313         public void webOfTrustUpdaterStopsWhenItShould() {
314                 webOfTrustUpdater.stop();
315                 webOfTrustUpdater.serviceRun();
316         }
317
318         @Test
319         public void webOfTrustUpdaterStopsAfterItWasStarted() {
320                 webOfTrustUpdater.start();
321                 webOfTrustUpdater.stop();
322         }
323
324         @Test
325         public void removePropertyRemovesProperty() throws InterruptedException, PluginException {
326                 final CountDownLatch wotCallTriggered = new CountDownLatch(1);
327                 doAnswer(new Answer<Void>() {
328                         @Override
329                         public Void answer(InvocationOnMock invocation) throws Throwable {
330                                 wotCallTriggered.countDown();
331                                 return null;
332                         }
333                 }).when(webOfTrustConnector).removeProperty(eq(ownIdentity), eq(PROPERTY_NAME));
334                 webOfTrustUpdater.removeProperty(ownIdentity, PROPERTY_NAME);
335                 webOfTrustUpdater.start();
336                 assertThat(wotCallTriggered.await(1, SECONDS), is(true));
337         }
338
339         @Test
340         public void multipleCallsToSetPropertyAreCollapsed() throws InterruptedException, PluginException {
341                 final CountDownLatch wotCallTriggered = new CountDownLatch(1);
342                 doAnswer(new Answer<Void>() {
343                         @Override
344                         public Void answer(InvocationOnMock invocation) throws Throwable {
345                                 wotCallTriggered.countDown();
346                                 return null;
347                         }
348                 }).when(webOfTrustConnector).removeProperty(eq(ownIdentity), eq(PROPERTY_NAME));
349                 webOfTrustUpdater.removeProperty(ownIdentity, PROPERTY_NAME);
350                 webOfTrustUpdater.removeProperty(ownIdentity, PROPERTY_NAME);
351                 webOfTrustUpdater.start();
352                 assertThat(wotCallTriggered.await(1, SECONDS), is(true));
353                 verify(webOfTrustConnector).removeProperty(eq(ownIdentity), eq(PROPERTY_NAME));
354         }
355
356         @Test
357         public void addContextWaitWaitsForTheContextToBeAdded() {
358                 webOfTrustUpdater.start();
359                 assertThat(webOfTrustUpdater.addContextWait(ownIdentity, CONTEXT), is(true));
360                 verify(ownIdentity).addContext(eq(CONTEXT));
361         }
362
363         @Test
364         public void removeContextRemovesAContext() throws InterruptedException, PluginException {
365                 webOfTrustUpdater.start();
366                 final CountDownLatch removeContextTrigger = new CountDownLatch(1);
367                 doAnswer(new Answer<Void>() {
368                         @Override
369                         public Void answer(InvocationOnMock invocation) throws Throwable {
370                                 removeContextTrigger.countDown();
371                                 return null;
372                         }
373                 }).when(ownIdentity).removeContext(eq(CONTEXT));
374                 webOfTrustUpdater.removeContext(ownIdentity, CONTEXT);
375                 removeContextTrigger.await(1, SECONDS);
376                 verify(webOfTrustConnector).removeContext(eq(ownIdentity), eq(CONTEXT));
377                 verify(ownIdentity).removeContext(eq(CONTEXT));
378         }
379
380         @Test
381         public void removeContextRequestsAreCoalesced() throws InterruptedException, PluginException {
382                 final CountDownLatch contextRemovedTrigger = new CountDownLatch(1);
383                 doAnswer(new Answer<Void>() {
384                         @Override
385                         public Void answer(InvocationOnMock invocation) throws Throwable {
386                                 contextRemovedTrigger.countDown();
387                                 return null;
388                         }
389                 }).when(ownIdentity).removeContext(eq(CONTEXT));
390                 for (int i = 1; i <= 2; i++) {
391                         /* this is so fucking volatile. */
392                         if (i > 1) {
393                                 sleep(200);
394                         }
395                         new Thread(new Runnable() {
396                                 public void run() {
397                                         webOfTrustUpdater.removeContext(ownIdentity, CONTEXT);
398                                 }
399                         }).start();
400                 }
401                 webOfTrustUpdater.start();
402                 assertThat(contextRemovedTrigger.await(1, SECONDS), is(true));
403                 verify(webOfTrustConnector).removeContext(eq(ownIdentity), eq(CONTEXT));
404                 verify(ownIdentity).removeContext(eq(CONTEXT));
405         }
406
407         @Test
408         public void setTrustSetsTrust() throws InterruptedException, PluginException {
409                 final CountDownLatch trustSetTrigger = new CountDownLatch(1);
410                 doAnswer(new Answer<Void>() {
411                         @Override
412                         public Void answer(InvocationOnMock invocation) throws Throwable {
413                                 trustSetTrigger.countDown();
414                                 return null;
415                         }
416                 }).when(trustee).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
417                 webOfTrustUpdater.start();
418                 webOfTrustUpdater.setTrust(ownIdentity, trustee, SCORE, TRUST_COMMENT);
419                 assertThat(trustSetTrigger.await(1, SECONDS), is(true));
420                 verify(trustee).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
421                 verify(webOfTrustConnector).setTrust(eq(ownIdentity), eq(trustee), eq(SCORE), eq(TRUST_COMMENT));
422         }
423
424         @Test
425         public void setTrustRequestsAreCoalesced() throws InterruptedException, PluginException {
426                 final CountDownLatch trustSetTrigger = new CountDownLatch(1);
427                 doAnswer(new Answer<Void>() {
428                         @Override
429                         public Void answer(InvocationOnMock invocation) throws Throwable {
430                                 trustSetTrigger.countDown();
431                                 return null;
432                         }
433                 }).when(trustee).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
434                 for (int i = 1; i <= 2; i++) {
435                         /* this is so fucking volatile. */
436                         if (i > 1) {
437                                 sleep(200);
438                         }
439                         new Thread(new Runnable() {
440                                 public void run() {
441                                         webOfTrustUpdater.setTrust(ownIdentity, trustee, SCORE, TRUST_COMMENT);
442                                 }
443                         }).start();
444                 }
445                 webOfTrustUpdater.start();
446                 assertThat(trustSetTrigger.await(1, SECONDS), is(true));
447                 verify(trustee).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
448                 verify(webOfTrustConnector).setTrust(eq(ownIdentity), eq(trustee), eq(SCORE), eq(TRUST_COMMENT));
449         }
450
451 }