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.assertThrows; 25 26 import com.google.common.collect.ImmutableList; 27 import java.util.Set; 28 import java.util.concurrent.Callable; 29 import java.util.concurrent.CyclicBarrier; 30 import java.util.concurrent.ExecutorService; 31 import java.util.concurrent.Future; 32 import org.checkerframework.checker.nullness.qual.Nullable; 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))).isFalse(); 179 assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(2, 1))).isFalse(); 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 IllegalArgumentException e = 201 assertThrows( 202 IllegalArgumentException.class, () -> graph.edgeValue(EndpointPair.unordered(1, 2))); 203 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 204 e = 205 assertThrows( 206 IllegalArgumentException.class, () -> graph.edgeValue(EndpointPair.unordered(2, 1))); 207 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 208 } 209 210 @Test edgeValue_undirected_correct()211 public void edgeValue_undirected_correct() { 212 graph = ValueGraphBuilder.undirected().build(); 213 graph.putEdgeValue(1, 2, "A"); 214 assertThat(graph.edgeValue(EndpointPair.unordered(1, 2))).hasValue("A"); 215 } 216 217 @Test edgeValue_undirected_backwards()218 public void edgeValue_undirected_backwards() { 219 graph = ValueGraphBuilder.undirected().build(); 220 graph.putEdgeValue(1, 2, "A"); 221 assertThat(graph.edgeValue(EndpointPair.unordered(2, 1))).hasValue("A"); 222 } 223 224 @Test edgeValue_undirected_mismatch()225 public void edgeValue_undirected_mismatch() { 226 graph = ValueGraphBuilder.undirected().build(); 227 graph.putEdgeValue(1, 2, "A"); 228 // Check that edgeValue() throws on each possible ordering of an ordered EndpointPair 229 IllegalArgumentException e = 230 assertThrows( 231 IllegalArgumentException.class, () -> graph.edgeValue(EndpointPair.ordered(1, 2))); 232 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 233 e = 234 assertThrows( 235 IllegalArgumentException.class, () -> graph.edgeValue(EndpointPair.ordered(2, 1))); 236 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 237 } 238 239 @Test edgeValueOrDefault_directed_correct()240 public void edgeValueOrDefault_directed_correct() { 241 graph = ValueGraphBuilder.directed().build(); 242 graph.putEdgeValue(1, 2, "A"); 243 assertThat(graph.edgeValueOrDefault(EndpointPair.ordered(1, 2), "default")).isEqualTo("A"); 244 } 245 246 @Test edgeValueOrDefault_directed_backwards()247 public void edgeValueOrDefault_directed_backwards() { 248 graph = ValueGraphBuilder.directed().build(); 249 graph.putEdgeValue(1, 2, "A"); 250 assertThat(graph.edgeValueOrDefault(EndpointPair.ordered(2, 1), "default")) 251 .isEqualTo("default"); 252 } 253 254 @Test edgeValueOrDefault_directed_mismatch()255 public void edgeValueOrDefault_directed_mismatch() { 256 graph = ValueGraphBuilder.directed().build(); 257 graph.putEdgeValue(1, 2, "A"); 258 IllegalArgumentException e = 259 assertThrows( 260 IllegalArgumentException.class, 261 () -> graph.edgeValueOrDefault(EndpointPair.unordered(1, 2), "default")); 262 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 263 e = 264 assertThrows( 265 IllegalArgumentException.class, 266 () -> graph.edgeValueOrDefault(EndpointPair.unordered(2, 1), "default")); 267 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 268 } 269 270 @Test edgeValueOrDefault_undirected_correct()271 public void edgeValueOrDefault_undirected_correct() { 272 graph = ValueGraphBuilder.undirected().build(); 273 graph.putEdgeValue(1, 2, "A"); 274 assertThat(graph.edgeValueOrDefault(EndpointPair.unordered(1, 2), "default")).isEqualTo("A"); 275 } 276 277 @Test edgeValueOrDefault_undirected_backwards()278 public void edgeValueOrDefault_undirected_backwards() { 279 graph = ValueGraphBuilder.undirected().build(); 280 graph.putEdgeValue(1, 2, "A"); 281 assertThat(graph.edgeValueOrDefault(EndpointPair.unordered(2, 1), "default")).isEqualTo("A"); 282 } 283 284 @Test edgeValueOrDefault_undirected_mismatch()285 public void edgeValueOrDefault_undirected_mismatch() { 286 graph = ValueGraphBuilder.undirected().build(); 287 graph.putEdgeValue(1, 2, "A"); 288 // Check that edgeValueOrDefault() throws on each possible ordering of an ordered EndpointPair 289 IllegalArgumentException e = 290 assertThrows( 291 IllegalArgumentException.class, 292 () -> graph.edgeValueOrDefault(EndpointPair.ordered(1, 2), "default")); 293 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 294 e = 295 assertThrows( 296 IllegalArgumentException.class, 297 () -> graph.edgeValueOrDefault(EndpointPair.ordered(2, 1), "default")); 298 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 299 } 300 301 @Test putEdgeValue_directed()302 public void putEdgeValue_directed() { 303 graph = ValueGraphBuilder.directed().build(); 304 305 assertThat(graph.putEdgeValue(1, 2, "valueA")).isNull(); 306 assertThat(graph.putEdgeValue(2, 1, "valueB")).isNull(); 307 assertThat(graph.putEdgeValue(1, 2, "valueC")).isEqualTo("valueA"); 308 assertThat(graph.putEdgeValue(2, 1, "valueD")).isEqualTo("valueB"); 309 } 310 311 @Test putEdgeValue_directed_orderMismatch()312 public void putEdgeValue_directed_orderMismatch() { 313 graph = ValueGraphBuilder.directed().build(); 314 IllegalArgumentException e = 315 assertThrows( 316 IllegalArgumentException.class, 317 () -> graph.putEdgeValue(EndpointPair.unordered(1, 2), "irrelevant")); 318 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 319 } 320 321 @Test putEdgeValue_undirected_orderMismatch()322 public void putEdgeValue_undirected_orderMismatch() { 323 graph = ValueGraphBuilder.undirected().build(); 324 IllegalArgumentException e = 325 assertThrows( 326 IllegalArgumentException.class, 327 () -> graph.putEdgeValue(EndpointPair.ordered(1, 2), "irrelevant")); 328 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 329 } 330 331 @Test putEdgeValue_undirected()332 public void putEdgeValue_undirected() { 333 graph = ValueGraphBuilder.undirected().build(); 334 335 assertThat(graph.putEdgeValue(1, 2, "valueA")).isNull(); 336 assertThat(graph.putEdgeValue(2, 1, "valueB")).isEqualTo("valueA"); 337 assertThat(graph.putEdgeValue(1, 2, "valueC")).isEqualTo("valueB"); 338 assertThat(graph.putEdgeValue(2, 1, "valueD")).isEqualTo("valueC"); 339 } 340 341 @Test removeEdge_directed()342 public void removeEdge_directed() { 343 graph = ValueGraphBuilder.directed().build(); 344 graph.putEdgeValue(1, 2, "valueA"); 345 graph.putEdgeValue(2, 1, "valueB"); 346 graph.putEdgeValue(2, 3, "valueC"); 347 348 assertThat(graph.removeEdge(1, 2)).isEqualTo("valueA"); 349 assertThat(graph.removeEdge(1, 2)).isNull(); 350 assertThat(graph.removeEdge(2, 1)).isEqualTo("valueB"); 351 assertThat(graph.removeEdge(2, 1)).isNull(); 352 assertThat(graph.removeEdge(2, 3)).isEqualTo("valueC"); 353 assertThat(graph.removeEdge(2, 3)).isNull(); 354 } 355 356 @Test removeEdge_undirected()357 public void removeEdge_undirected() { 358 graph = ValueGraphBuilder.undirected().build(); 359 graph.putEdgeValue(1, 2, "valueA"); 360 graph.putEdgeValue(2, 1, "valueB"); 361 graph.putEdgeValue(2, 3, "valueC"); 362 363 assertThat(graph.removeEdge(1, 2)).isEqualTo("valueB"); 364 assertThat(graph.removeEdge(1, 2)).isNull(); 365 assertThat(graph.removeEdge(2, 1)).isNull(); 366 assertThat(graph.removeEdge(2, 3)).isEqualTo("valueC"); 367 assertThat(graph.removeEdge(2, 3)).isNull(); 368 } 369 370 @Test removeEdge_directed_orderMismatch()371 public void removeEdge_directed_orderMismatch() { 372 graph = ValueGraphBuilder.directed().build(); 373 graph.putEdgeValue(1, 2, "1->2"); 374 graph.putEdgeValue(2, 1, "2->1"); 375 IllegalArgumentException e = 376 assertThrows( 377 IllegalArgumentException.class, () -> graph.removeEdge(EndpointPair.unordered(1, 2))); 378 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 379 e = 380 assertThrows( 381 IllegalArgumentException.class, () -> graph.removeEdge(EndpointPair.unordered(2, 1))); 382 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 383 } 384 385 @Test removeEdge_undirected_orderMismatch()386 public void removeEdge_undirected_orderMismatch() { 387 graph = ValueGraphBuilder.undirected().build(); 388 graph.putEdgeValue(1, 2, "1-2"); 389 // Check that removeEdge() throws on each possible ordering of an ordered EndpointPair 390 IllegalArgumentException e = 391 assertThrows( 392 IllegalArgumentException.class, () -> graph.removeEdge(EndpointPair.ordered(1, 2))); 393 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 394 e = 395 assertThrows( 396 IllegalArgumentException.class, () -> graph.removeEdge(EndpointPair.ordered(2, 1))); 397 assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH); 398 } 399 400 @Test edgeValue_missing()401 public void edgeValue_missing() { 402 graph = ValueGraphBuilder.directed().build(); 403 404 assertThat(graph.edgeValueOrDefault(1, 2, DEFAULT)).isEqualTo(DEFAULT); 405 assertThat(graph.edgeValueOrDefault(2, 1, DEFAULT)).isEqualTo(DEFAULT); 406 assertThat(graph.edgeValue(1, 2).orElse(DEFAULT)).isEqualTo(DEFAULT); 407 assertThat(graph.edgeValue(2, 1).orElse(DEFAULT)).isEqualTo(DEFAULT); 408 assertThat(graph.edgeValueOrDefault(1, 2, null)).isNull(); 409 assertThat(graph.edgeValueOrDefault(2, 1, null)).isNull(); 410 assertThat(graph.edgeValue(1, 2).orElse(null)).isNull(); 411 assertThat(graph.edgeValue(2, 1).orElse(null)).isNull(); 412 413 graph.putEdgeValue(1, 2, "valueA"); 414 graph.putEdgeValue(2, 1, "valueB"); 415 assertThat(graph.edgeValueOrDefault(1, 2, DEFAULT)).isEqualTo("valueA"); 416 assertThat(graph.edgeValueOrDefault(2, 1, DEFAULT)).isEqualTo("valueB"); 417 assertThat(graph.edgeValueOrDefault(1, 2, null)).isEqualTo("valueA"); 418 assertThat(graph.edgeValueOrDefault(2, 1, null)).isEqualTo("valueB"); 419 assertThat(graph.edgeValue(1, 2).get()).isEqualTo("valueA"); 420 assertThat(graph.edgeValue(2, 1).get()).isEqualTo("valueB"); 421 422 graph.removeEdge(1, 2); 423 graph.putEdgeValue(2, 1, "valueC"); 424 assertThat(graph.edgeValueOrDefault(1, 2, DEFAULT)).isEqualTo(DEFAULT); 425 assertThat(graph.edgeValueOrDefault(2, 1, DEFAULT)).isEqualTo("valueC"); 426 assertThat(graph.edgeValue(1, 2).orElse(DEFAULT)).isEqualTo(DEFAULT); 427 assertThat(graph.edgeValueOrDefault(1, 2, null)).isNull(); 428 assertThat(graph.edgeValueOrDefault(2, 1, null)).isEqualTo("valueC"); 429 assertThat(graph.edgeValue(1, 2).orElse(null)).isNull(); 430 assertThat(graph.edgeValue(2, 1).get()).isEqualTo("valueC"); 431 } 432 433 @Test equivalence_considersEdgeValue()434 public void equivalence_considersEdgeValue() { 435 graph = ValueGraphBuilder.undirected().build(); 436 graph.putEdgeValue(1, 2, "valueA"); 437 438 MutableValueGraph<Integer, String> otherGraph = ValueGraphBuilder.undirected().build(); 439 otherGraph.putEdgeValue(1, 2, "valueA"); 440 assertThat(graph).isEqualTo(otherGraph); 441 442 otherGraph.putEdgeValue(1, 2, "valueB"); 443 assertThat(graph).isNotEqualTo(otherGraph); // values differ 444 } 445 446 @Test incidentEdges_stableIncidentEdgeOrder_preservesIncidentEdgesOrder_directed()447 public void incidentEdges_stableIncidentEdgeOrder_preservesIncidentEdgesOrder_directed() { 448 graph = ValueGraphBuilder.directed().incidentEdgeOrder(ElementOrder.stable()).build(); 449 graph.putEdgeValue(2, 1, "2-1"); 450 graph.putEdgeValue(2, 3, "2-3"); 451 graph.putEdgeValue(1, 2, "1-2"); 452 453 assertThat(graph.incidentEdges(2)) 454 .containsExactly( 455 EndpointPair.ordered(2, 1), EndpointPair.ordered(2, 3), EndpointPair.ordered(1, 2)) 456 .inOrder(); 457 } 458 459 @Test incidentEdges_stableIncidentEdgeOrder_preservesIncidentEdgesOrder_undirected()460 public void incidentEdges_stableIncidentEdgeOrder_preservesIncidentEdgesOrder_undirected() { 461 graph = ValueGraphBuilder.undirected().incidentEdgeOrder(ElementOrder.stable()).build(); 462 graph.putEdgeValue(2, 3, "2-3"); 463 graph.putEdgeValue(2, 1, "2-1"); 464 graph.putEdgeValue(2, 4, "2-4"); 465 graph.putEdgeValue(1, 2, "1-2"); // Duplicate nodes, different value 466 467 assertThat(graph.incidentEdges(2)) 468 .containsExactly( 469 EndpointPair.unordered(2, 3), 470 EndpointPair.unordered(1, 2), 471 EndpointPair.unordered(2, 4)) 472 .inOrder(); 473 } 474 475 @Test concurrentIteration()476 public void concurrentIteration() throws Exception { 477 graph = ValueGraphBuilder.directed().build(); 478 graph.putEdgeValue(1, 2, "A"); 479 graph.putEdgeValue(3, 4, "B"); 480 graph.putEdgeValue(5, 6, "C"); 481 482 int threadCount = 20; 483 ExecutorService executor = newFixedThreadPool(threadCount); 484 final CyclicBarrier barrier = new CyclicBarrier(threadCount); 485 ImmutableList.Builder<Future<?>> futures = ImmutableList.builder(); 486 for (int i = 0; i < threadCount; i++) { 487 futures.add( 488 executor.submit( 489 new Callable<@Nullable Void>() { 490 @Override 491 public @Nullable Void call() throws Exception { 492 barrier.await(); 493 Integer first = graph.nodes().iterator().next(); 494 for (Integer node : graph.nodes()) { 495 Set<Integer> unused = graph.successors(node); 496 } 497 /* 498 * Also look up an earlier node so that, if the graph is using MapRetrievalCache, 499 * we read one of the fields declared in that class. 500 */ 501 Set<Integer> unused = graph.successors(first); 502 return null; 503 } 504 })); 505 } 506 507 // For more about this test, see the equivalent in AbstractNetworkTest. 508 for (Future<?> future : futures.build()) { 509 future.get(); 510 } 511 executor.shutdown(); 512 } 513 } 514