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