• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.graph;
18 
19 import static com.google.common.graph.GraphConstants.ENDPOINTS_MISMATCH;
20 import static com.google.common.graph.TestUtil.assertStronglyEquivalent;
21 import static com.google.common.truth.Truth.assertThat;
22 import static com.google.common.truth.Truth8.assertThat;
23 import static java.util.concurrent.Executors.newFixedThreadPool;
24 import static org.junit.Assert.fail;
25 
26 import com.google.common.collect.ImmutableList;
27 import java.util.Optional;
28 import java.util.Set;
29 import java.util.concurrent.Callable;
30 import java.util.concurrent.CyclicBarrier;
31 import java.util.concurrent.ExecutorService;
32 import java.util.concurrent.Future;
33 import org.junit.After;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.junit.runners.JUnit4;
37 
38 /** Tests for {@link StandardMutableValueGraph} and related functionality. */
39 // TODO(user): Expand coverage and move to proper test suite.
40 @RunWith(JUnit4.class)
41 public final class ValueGraphTest {
42   private static final String DEFAULT = "default";
43 
44   MutableValueGraph<Integer, String> graph;
45 
46   @After
validateGraphState()47   public void validateGraphState() {
48     assertStronglyEquivalent(graph, Graphs.copyOf(graph));
49     assertStronglyEquivalent(graph, ImmutableValueGraph.copyOf(graph));
50 
51     Graph<Integer> asGraph = graph.asGraph();
52     AbstractGraphTest.validateGraph(asGraph);
53     assertThat(graph.nodes()).isEqualTo(asGraph.nodes());
54     assertThat(graph.edges()).isEqualTo(asGraph.edges());
55     assertThat(graph.nodeOrder()).isEqualTo(asGraph.nodeOrder());
56     assertThat(graph.incidentEdgeOrder()).isEqualTo(asGraph.incidentEdgeOrder());
57     assertThat(graph.isDirected()).isEqualTo(asGraph.isDirected());
58     assertThat(graph.allowsSelfLoops()).isEqualTo(asGraph.allowsSelfLoops());
59 
60     for (Integer node : graph.nodes()) {
61       assertThat(graph.adjacentNodes(node)).isEqualTo(asGraph.adjacentNodes(node));
62       assertThat(graph.predecessors(node)).isEqualTo(asGraph.predecessors(node));
63       assertThat(graph.successors(node)).isEqualTo(asGraph.successors(node));
64       assertThat(graph.degree(node)).isEqualTo(asGraph.degree(node));
65       assertThat(graph.inDegree(node)).isEqualTo(asGraph.inDegree(node));
66       assertThat(graph.outDegree(node)).isEqualTo(asGraph.outDegree(node));
67 
68       for (Integer otherNode : graph.nodes()) {
69         boolean hasEdge = graph.hasEdgeConnecting(node, otherNode);
70         assertThat(hasEdge).isEqualTo(asGraph.hasEdgeConnecting(node, otherNode));
71         assertThat(graph.edgeValueOrDefault(node, otherNode, null) != null).isEqualTo(hasEdge);
72         assertThat(!graph.edgeValueOrDefault(node, otherNode, DEFAULT).equals(DEFAULT))
73             .isEqualTo(hasEdge);
74       }
75     }
76   }
77 
78   @Test
directedGraph()79   public void directedGraph() {
80     graph = ValueGraphBuilder.directed().allowsSelfLoops(true).build();
81     graph.putEdgeValue(1, 2, "valueA");
82     graph.putEdgeValue(2, 1, "valueB");
83     graph.putEdgeValue(2, 3, "valueC");
84     graph.putEdgeValue(4, 4, "valueD");
85 
86     assertThat(graph.edgeValueOrDefault(1, 2, null)).isEqualTo("valueA");
87     assertThat(graph.edgeValueOrDefault(2, 1, null)).isEqualTo("valueB");
88     assertThat(graph.edgeValueOrDefault(2, 3, null)).isEqualTo("valueC");
89     assertThat(graph.edgeValueOrDefault(4, 4, null)).isEqualTo("valueD");
90     assertThat(graph.edgeValueOrDefault(1, 2, DEFAULT)).isEqualTo("valueA");
91     assertThat(graph.edgeValueOrDefault(2, 1, DEFAULT)).isEqualTo("valueB");
92     assertThat(graph.edgeValueOrDefault(2, 3, DEFAULT)).isEqualTo("valueC");
93     assertThat(graph.edgeValueOrDefault(4, 4, DEFAULT)).isEqualTo("valueD");
94 
95     String toString = graph.toString();
96     assertThat(toString).contains("valueA");
97     assertThat(toString).contains("valueB");
98     assertThat(toString).contains("valueC");
99     assertThat(toString).contains("valueD");
100   }
101 
102   @Test
undirectedGraph()103   public void undirectedGraph() {
104     graph = ValueGraphBuilder.undirected().allowsSelfLoops(true).build();
105     graph.putEdgeValue(1, 2, "valueA");
106     graph.putEdgeValue(2, 1, "valueB"); // overwrites valueA in undirected case
107     graph.putEdgeValue(2, 3, "valueC");
108     graph.putEdgeValue(4, 4, "valueD");
109 
110     assertThat(graph.edgeValueOrDefault(1, 2, null)).isEqualTo("valueB");
111     assertThat(graph.edgeValueOrDefault(2, 1, null)).isEqualTo("valueB");
112     assertThat(graph.edgeValueOrDefault(2, 3, null)).isEqualTo("valueC");
113     assertThat(graph.edgeValueOrDefault(4, 4, null)).isEqualTo("valueD");
114     assertThat(graph.edgeValueOrDefault(1, 2, DEFAULT)).isEqualTo("valueB");
115     assertThat(graph.edgeValueOrDefault(2, 1, DEFAULT)).isEqualTo("valueB");
116     assertThat(graph.edgeValueOrDefault(2, 3, DEFAULT)).isEqualTo("valueC");
117     assertThat(graph.edgeValueOrDefault(4, 4, DEFAULT)).isEqualTo("valueD");
118 
119     String toString = graph.toString();
120     assertThat(toString).doesNotContain("valueA");
121     assertThat(toString).contains("valueB");
122     assertThat(toString).contains("valueC");
123     assertThat(toString).contains("valueD");
124   }
125 
126   @Test
incidentEdgeOrder_unordered()127   public void incidentEdgeOrder_unordered() {
128     graph = ValueGraphBuilder.directed().incidentEdgeOrder(ElementOrder.unordered()).build();
129     assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.unordered());
130   }
131 
132   @Test
incidentEdgeOrder_stable()133   public void incidentEdgeOrder_stable() {
134     graph = ValueGraphBuilder.directed().incidentEdgeOrder(ElementOrder.stable()).build();
135     assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
136   }
137 
138   @Test
hasEdgeConnecting_directed_correct()139   public void hasEdgeConnecting_directed_correct() {
140     graph = ValueGraphBuilder.directed().build();
141     graph.putEdgeValue(1, 2, "A");
142     assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(1, 2))).isTrue();
143   }
144 
145   @Test
hasEdgeConnecting_directed_backwards()146   public void hasEdgeConnecting_directed_backwards() {
147     graph = ValueGraphBuilder.directed().build();
148     graph.putEdgeValue(1, 2, "A");
149     assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(2, 1))).isFalse();
150   }
151 
152   @Test
hasEdgeConnecting_directed_mismatch()153   public void hasEdgeConnecting_directed_mismatch() {
154     graph = ValueGraphBuilder.directed().build();
155     graph.putEdgeValue(1, 2, "A");
156     assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(1, 2))).isFalse();
157     assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(2, 1))).isFalse();
158   }
159 
160   @Test
hasEdgeConnecting_undirected_correct()161   public void hasEdgeConnecting_undirected_correct() {
162     graph = ValueGraphBuilder.undirected().build();
163     graph.putEdgeValue(1, 2, "A");
164     assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(1, 2))).isTrue();
165   }
166 
167   @Test
hasEdgeConnecting_undirected_backwards()168   public void hasEdgeConnecting_undirected_backwards() {
169     graph = ValueGraphBuilder.undirected().build();
170     graph.putEdgeValue(1, 2, "A");
171     assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(2, 1))).isTrue();
172   }
173 
174   @Test
hasEdgeConnecting_undirected_mismatch()175   public void hasEdgeConnecting_undirected_mismatch() {
176     graph = ValueGraphBuilder.undirected().build();
177     graph.putEdgeValue(1, 2, "A");
178     assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(1, 2))).isTrue();
179     assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(2, 1))).isTrue();
180   }
181 
182   @Test
edgeValue_directed_correct()183   public void edgeValue_directed_correct() {
184     graph = ValueGraphBuilder.directed().build();
185     graph.putEdgeValue(1, 2, "A");
186     assertThat(graph.edgeValue(EndpointPair.ordered(1, 2))).hasValue("A");
187   }
188 
189   @Test
edgeValue_directed_backwards()190   public void edgeValue_directed_backwards() {
191     graph = ValueGraphBuilder.directed().build();
192     graph.putEdgeValue(1, 2, "A");
193     assertThat(graph.edgeValue(EndpointPair.ordered(2, 1))).isEmpty();
194   }
195 
196   @Test
edgeValue_directed_mismatch()197   public void edgeValue_directed_mismatch() {
198     graph = ValueGraphBuilder.directed().build();
199     graph.putEdgeValue(1, 2, "A");
200     try {
201       Optional<String> unused = graph.edgeValue(EndpointPair.unordered(1, 2));
202       unused = graph.edgeValue(EndpointPair.unordered(2, 1));
203       fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
204     } catch (IllegalArgumentException e) {
205       assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
206     }
207   }
208 
209   @Test
edgeValue_undirected_correct()210   public void edgeValue_undirected_correct() {
211     graph = ValueGraphBuilder.undirected().build();
212     graph.putEdgeValue(1, 2, "A");
213     assertThat(graph.edgeValue(EndpointPair.unordered(1, 2))).hasValue("A");
214   }
215 
216   @Test
edgeValue_undirected_backwards()217   public void edgeValue_undirected_backwards() {
218     graph = ValueGraphBuilder.undirected().build();
219     graph.putEdgeValue(1, 2, "A");
220     assertThat(graph.edgeValue(EndpointPair.unordered(2, 1))).hasValue("A");
221   }
222 
223   @Test
edgeValue_undirected_mismatch()224   public void edgeValue_undirected_mismatch() {
225     graph = ValueGraphBuilder.undirected().build();
226     graph.putEdgeValue(1, 2, "A");
227     assertThat(graph.edgeValue(EndpointPair.ordered(1, 2))).hasValue("A");
228     assertThat(graph.edgeValue(EndpointPair.ordered(2, 1))).hasValue("A");
229   }
230 
231   @Test
edgeValueOrDefault_directed_correct()232   public void edgeValueOrDefault_directed_correct() {
233     graph = ValueGraphBuilder.directed().build();
234     graph.putEdgeValue(1, 2, "A");
235     assertThat(graph.edgeValueOrDefault(EndpointPair.ordered(1, 2), "default")).isEqualTo("A");
236   }
237 
238   @Test
edgeValueOrDefault_directed_backwards()239   public void edgeValueOrDefault_directed_backwards() {
240     graph = ValueGraphBuilder.directed().build();
241     graph.putEdgeValue(1, 2, "A");
242     assertThat(graph.edgeValueOrDefault(EndpointPair.ordered(2, 1), "default"))
243         .isEqualTo("default");
244   }
245 
246   @Test
edgeValueOrDefault_directed_mismatch()247   public void edgeValueOrDefault_directed_mismatch() {
248     graph = ValueGraphBuilder.directed().build();
249     graph.putEdgeValue(1, 2, "A");
250     try {
251       String unused = graph.edgeValueOrDefault(EndpointPair.unordered(1, 2), "default");
252       unused = graph.edgeValueOrDefault(EndpointPair.unordered(2, 1), "default");
253       fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
254     } catch (IllegalArgumentException e) {
255       assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
256     }
257   }
258 
259   @Test
edgeValueOrDefault_undirected_correct()260   public void edgeValueOrDefault_undirected_correct() {
261     graph = ValueGraphBuilder.undirected().build();
262     graph.putEdgeValue(1, 2, "A");
263     assertThat(graph.edgeValueOrDefault(EndpointPair.unordered(1, 2), "default")).isEqualTo("A");
264   }
265 
266   @Test
edgeValueOrDefault_undirected_backwards()267   public void edgeValueOrDefault_undirected_backwards() {
268     graph = ValueGraphBuilder.undirected().build();
269     graph.putEdgeValue(1, 2, "A");
270     assertThat(graph.edgeValueOrDefault(EndpointPair.unordered(2, 1), "default")).isEqualTo("A");
271   }
272 
273   @Test
edgeValueOrDefault_undirected_mismatch()274   public void edgeValueOrDefault_undirected_mismatch() {
275     graph = ValueGraphBuilder.undirected().build();
276     graph.putEdgeValue(1, 2, "A");
277     assertThat(graph.edgeValueOrDefault(EndpointPair.ordered(2, 1), "default")).isEqualTo("A");
278     assertThat(graph.edgeValueOrDefault(EndpointPair.ordered(2, 1), "default")).isEqualTo("A");
279   }
280 
281   @Test
putEdgeValue_directed()282   public void putEdgeValue_directed() {
283     graph = ValueGraphBuilder.directed().build();
284 
285     assertThat(graph.putEdgeValue(1, 2, "valueA")).isNull();
286     assertThat(graph.putEdgeValue(2, 1, "valueB")).isNull();
287     assertThat(graph.putEdgeValue(1, 2, "valueC")).isEqualTo("valueA");
288     assertThat(graph.putEdgeValue(2, 1, "valueD")).isEqualTo("valueB");
289   }
290 
291   @Test
putEdgeValue_directed_orderMismatch()292   public void putEdgeValue_directed_orderMismatch() {
293     graph = ValueGraphBuilder.directed().build();
294     try {
295       graph.putEdgeValue(EndpointPair.unordered(1, 2), "irrelevant");
296       fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
297     } catch (IllegalArgumentException e) {
298       assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
299     }
300   }
301 
302   @Test
putEdgeValue_undirected_orderMismatch()303   public void putEdgeValue_undirected_orderMismatch() {
304     graph = ValueGraphBuilder.undirected().build();
305     assertThat(graph.putEdgeValue(EndpointPair.ordered(1, 2), "irrelevant")).isNull();
306   }
307 
308   @Test
putEdgeValue_undirected()309   public void putEdgeValue_undirected() {
310     graph = ValueGraphBuilder.undirected().build();
311 
312     assertThat(graph.putEdgeValue(1, 2, "valueA")).isNull();
313     assertThat(graph.putEdgeValue(2, 1, "valueB")).isEqualTo("valueA");
314     assertThat(graph.putEdgeValue(1, 2, "valueC")).isEqualTo("valueB");
315     assertThat(graph.putEdgeValue(2, 1, "valueD")).isEqualTo("valueC");
316   }
317 
318   @Test
removeEdge_directed()319   public void removeEdge_directed() {
320     graph = ValueGraphBuilder.directed().build();
321     graph.putEdgeValue(1, 2, "valueA");
322     graph.putEdgeValue(2, 1, "valueB");
323     graph.putEdgeValue(2, 3, "valueC");
324 
325     assertThat(graph.removeEdge(1, 2)).isEqualTo("valueA");
326     assertThat(graph.removeEdge(1, 2)).isNull();
327     assertThat(graph.removeEdge(2, 1)).isEqualTo("valueB");
328     assertThat(graph.removeEdge(2, 1)).isNull();
329     assertThat(graph.removeEdge(2, 3)).isEqualTo("valueC");
330     assertThat(graph.removeEdge(2, 3)).isNull();
331   }
332 
333   @Test
removeEdge_undirected()334   public void removeEdge_undirected() {
335     graph = ValueGraphBuilder.undirected().build();
336     graph.putEdgeValue(1, 2, "valueA");
337     graph.putEdgeValue(2, 1, "valueB");
338     graph.putEdgeValue(2, 3, "valueC");
339 
340     assertThat(graph.removeEdge(1, 2)).isEqualTo("valueB");
341     assertThat(graph.removeEdge(1, 2)).isNull();
342     assertThat(graph.removeEdge(2, 1)).isNull();
343     assertThat(graph.removeEdge(2, 3)).isEqualTo("valueC");
344     assertThat(graph.removeEdge(2, 3)).isNull();
345   }
346 
347   @Test
removeEdge_directed_orderMismatch()348   public void removeEdge_directed_orderMismatch() {
349     graph = ValueGraphBuilder.directed().build();
350     graph.putEdgeValue(1, 2, "1->2");
351     graph.putEdgeValue(2, 1, "2->1");
352     try {
353       graph.removeEdge(EndpointPair.unordered(1, 2));
354       graph.removeEdge(EndpointPair.unordered(2, 1));
355       fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
356     } catch (IllegalArgumentException e) {
357       assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
358     }
359   }
360 
361   @Test
removeEdge_undirected_orderMismatch()362   public void removeEdge_undirected_orderMismatch() {
363     graph = ValueGraphBuilder.undirected().build();
364     graph.putEdgeValue(1, 2, "1-2");
365     assertThat(graph.removeEdge(EndpointPair.ordered(1, 2))).isEqualTo("1-2");
366   }
367 
368   @Test
edgeValue_missing()369   public void edgeValue_missing() {
370     graph = ValueGraphBuilder.directed().build();
371 
372     assertThat(graph.edgeValueOrDefault(1, 2, DEFAULT)).isEqualTo(DEFAULT);
373     assertThat(graph.edgeValueOrDefault(2, 1, DEFAULT)).isEqualTo(DEFAULT);
374     assertThat(graph.edgeValue(1, 2).orElse(DEFAULT)).isEqualTo(DEFAULT);
375     assertThat(graph.edgeValue(2, 1).orElse(DEFAULT)).isEqualTo(DEFAULT);
376     assertThat(graph.edgeValueOrDefault(1, 2, null)).isNull();
377     assertThat(graph.edgeValueOrDefault(2, 1, null)).isNull();
378     assertThat(graph.edgeValue(1, 2).orElse(null)).isNull();
379     assertThat(graph.edgeValue(2, 1).orElse(null)).isNull();
380 
381     graph.putEdgeValue(1, 2, "valueA");
382     graph.putEdgeValue(2, 1, "valueB");
383     assertThat(graph.edgeValueOrDefault(1, 2, DEFAULT)).isEqualTo("valueA");
384     assertThat(graph.edgeValueOrDefault(2, 1, DEFAULT)).isEqualTo("valueB");
385     assertThat(graph.edgeValueOrDefault(1, 2, null)).isEqualTo("valueA");
386     assertThat(graph.edgeValueOrDefault(2, 1, null)).isEqualTo("valueB");
387     assertThat(graph.edgeValue(1, 2).get()).isEqualTo("valueA");
388     assertThat(graph.edgeValue(2, 1).get()).isEqualTo("valueB");
389 
390     graph.removeEdge(1, 2);
391     graph.putEdgeValue(2, 1, "valueC");
392     assertThat(graph.edgeValueOrDefault(1, 2, DEFAULT)).isEqualTo(DEFAULT);
393     assertThat(graph.edgeValueOrDefault(2, 1, DEFAULT)).isEqualTo("valueC");
394     assertThat(graph.edgeValue(1, 2).orElse(DEFAULT)).isEqualTo(DEFAULT);
395     assertThat(graph.edgeValueOrDefault(1, 2, null)).isNull();
396     assertThat(graph.edgeValueOrDefault(2, 1, null)).isEqualTo("valueC");
397     assertThat(graph.edgeValue(1, 2).orElse(null)).isNull();
398     assertThat(graph.edgeValue(2, 1).get()).isEqualTo("valueC");
399   }
400 
401   @Test
equivalence_considersEdgeValue()402   public void equivalence_considersEdgeValue() {
403     graph = ValueGraphBuilder.undirected().build();
404     graph.putEdgeValue(1, 2, "valueA");
405 
406     MutableValueGraph<Integer, String> otherGraph = ValueGraphBuilder.undirected().build();
407     otherGraph.putEdgeValue(1, 2, "valueA");
408     assertThat(graph).isEqualTo(otherGraph);
409 
410     otherGraph.putEdgeValue(1, 2, "valueB");
411     assertThat(graph).isNotEqualTo(otherGraph); // values differ
412   }
413 
414   @Test
incidentEdges_stableIncidentEdgeOrder_preservesIncidentEdgesOrder_directed()415   public void incidentEdges_stableIncidentEdgeOrder_preservesIncidentEdgesOrder_directed() {
416     graph = ValueGraphBuilder.directed().incidentEdgeOrder(ElementOrder.stable()).build();
417     graph.putEdgeValue(2, 1, "2-1");
418     graph.putEdgeValue(2, 3, "2-3");
419     graph.putEdgeValue(1, 2, "1-2");
420 
421     assertThat(graph.incidentEdges(2))
422         .containsExactly(
423             EndpointPair.ordered(2, 1), EndpointPair.ordered(2, 3), EndpointPair.ordered(1, 2))
424         .inOrder();
425   }
426 
427   @Test
incidentEdges_stableIncidentEdgeOrder_preservesIncidentEdgesOrder_undirected()428   public void incidentEdges_stableIncidentEdgeOrder_preservesIncidentEdgesOrder_undirected() {
429     graph = ValueGraphBuilder.undirected().incidentEdgeOrder(ElementOrder.stable()).build();
430     graph.putEdgeValue(2, 3, "2-3");
431     graph.putEdgeValue(2, 1, "2-1");
432     graph.putEdgeValue(2, 4, "2-4");
433     graph.putEdgeValue(1, 2, "1-2"); // Duplicate nodes, different value
434 
435     assertThat(graph.incidentEdges(2))
436         .containsExactly(
437             EndpointPair.unordered(2, 3),
438             EndpointPair.unordered(1, 2),
439             EndpointPair.unordered(2, 4))
440         .inOrder();
441   }
442 
443   @Test
concurrentIteration()444   public void concurrentIteration() throws Exception {
445     graph = ValueGraphBuilder.directed().build();
446     graph.putEdgeValue(1, 2, "A");
447     graph.putEdgeValue(3, 4, "B");
448     graph.putEdgeValue(5, 6, "C");
449 
450     int threadCount = 20;
451     ExecutorService executor = newFixedThreadPool(threadCount);
452     final CyclicBarrier barrier = new CyclicBarrier(threadCount);
453     ImmutableList.Builder<Future<?>> futures = ImmutableList.builder();
454     for (int i = 0; i < threadCount; i++) {
455       futures.add(
456           executor.submit(
457               new Callable<Object>() {
458                 @Override
459                 public Object call() throws Exception {
460                   barrier.await();
461                   Integer first = graph.nodes().iterator().next();
462                   for (Integer node : graph.nodes()) {
463                     Set<Integer> unused = graph.successors(node);
464                   }
465                   /*
466                    * Also look up an earlier node so that, if the graph is using MapRetrievalCache,
467                    * we read one of the fields declared in that class.
468                    */
469                   Set<Integer> unused = graph.successors(first);
470                   return null;
471                 }
472               }));
473     }
474 
475     // For more about this test, see the equivalent in AbstractNetworkTest.
476     for (Future<?> future : futures.build()) {
477       future.get();
478     }
479     executor.shutdown();
480   }
481 }
482