@Test public void testGetAnswerBdds() { BDDPacket pkt = new BDDPacket(); BDDInteger var = pkt.getDstIp(); BDD bdd1 = var.value(1); BDD bdd2 = var.value(2); BDD bdd3 = var.value(3); Location loc = new InterfaceLocation("node", "iface"); { Map<Location, BDD> success = ImmutableMap.of(loc, bdd1); BidirectionalReachabilityResult result = new BidirectionalReachabilityResult(success, ImmutableMap.of()); assertEquals(getAnswerBdds(result, SUCCESS), success); assertTrue(getAnswerBdds(result, FAILURE).isEmpty()); assertTrue(getAnswerBdds(result, MULTIPATH_INCONSISTENT).isEmpty()); } { Map<Location, BDD> failure = ImmutableMap.of(loc, bdd1); BidirectionalReachabilityResult result = new BidirectionalReachabilityResult(ImmutableMap.of(), failure); assertTrue(getAnswerBdds(result, SUCCESS).isEmpty()); assertEquals(getAnswerBdds(result, FAILURE), failure); assertTrue(getAnswerBdds(result, MULTIPATH_INCONSISTENT).isEmpty()); } { Map<Location, BDD> success = ImmutableMap.of(loc, bdd1.or(bdd2)); Map<Location, BDD> failure = ImmutableMap.of(loc, bdd2.or(bdd3)); BidirectionalReachabilityResult result = new BidirectionalReachabilityResult(success, failure); assertEquals(getAnswerBdds(result, SUCCESS), ImmutableMap.of(loc, bdd1)); assertEquals(getAnswerBdds(result, FAILURE), ImmutableMap.of(loc, bdd3)); assertEquals(getAnswerBdds(result, MULTIPATH_INCONSISTENT), ImmutableMap.of(loc, bdd2)); } { Map<Location, BDD> successAndFailure = ImmutableMap.of(loc, bdd1); BidirectionalReachabilityResult result = new BidirectionalReachabilityResult(successAndFailure, successAndFailure); assertEquals(getAnswerBdds(result, SUCCESS), successAndFailure); assertEquals(getAnswerBdds(result, FAILURE), successAndFailure); assertEquals(getAnswerBdds(result, MULTIPATH_INCONSISTENT), successAndFailure); } }
@VisibleForTesting static Map<Location, BDD> getAnswerBdds( BidirectionalReachabilityResult result, ReturnFlowType returnFlowType) { Map<Location, BDD> successBdds = result.getStartLocationReturnPassSuccessBdds(); Map<Location, BDD> failureBdds = result.getStartLocationReturnPassFailureBdds(); switch (returnFlowType) { case SUCCESS: return successBdds.entrySet().stream() .map( entry -> { Location loc = entry.getKey(); BDD success = entry.getValue(); BDD fail = failureBdds.get(loc); BDD successOnly = fail == null ? success : success.diff(fail); return Maps.immutableEntry(loc, successOnly.isZero() ? success : successOnly); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); case FAILURE: return failureBdds.entrySet().stream() .map( entry -> { Location loc = entry.getKey(); BDD fail = entry.getValue(); BDD success = successBdds.get(loc); BDD failOnly = success == null ? fail : fail.diff(success); return Maps.immutableEntry(loc, failOnly.isZero() ? fail : failOnly); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); case MULTIPATH_INCONSISTENT: return successBdds.entrySet().stream() .flatMap( entry -> { Location loc = entry.getKey(); BDD success = entry.getValue(); BDD fail = failureBdds.get(loc); if (fail == null) { return Stream.of(); } BDD multipath = success.and(fail); return multipath.isZero() ? Stream.of() : Stream.of(Maps.immutableEntry(loc, multipath)); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); default: throw new IllegalStateException("Unexpected ReturnFlowType: " + returnFlowType); } }
BidirectionalReachabilityAnswerer extends Answerer { @VisibleForTesting static Map<Location, BDD> getAnswerBdds( BidirectionalReachabilityResult result, ReturnFlowType returnFlowType) { Map<Location, BDD> successBdds = result.getStartLocationReturnPassSuccessBdds(); Map<Location, BDD> failureBdds = result.getStartLocationReturnPassFailureBdds(); switch (returnFlowType) { case SUCCESS: return successBdds.entrySet().stream() .map( entry -> { Location loc = entry.getKey(); BDD success = entry.getValue(); BDD fail = failureBdds.get(loc); BDD successOnly = fail == null ? success : success.diff(fail); return Maps.immutableEntry(loc, successOnly.isZero() ? success : successOnly); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); case FAILURE: return failureBdds.entrySet().stream() .map( entry -> { Location loc = entry.getKey(); BDD fail = entry.getValue(); BDD success = successBdds.get(loc); BDD failOnly = success == null ? fail : fail.diff(success); return Maps.immutableEntry(loc, failOnly.isZero() ? fail : failOnly); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); case MULTIPATH_INCONSISTENT: return successBdds.entrySet().stream() .flatMap( entry -> { Location loc = entry.getKey(); BDD success = entry.getValue(); BDD fail = failureBdds.get(loc); if (fail == null) { return Stream.of(); } BDD multipath = success.and(fail); return multipath.isZero() ? Stream.of() : Stream.of(Maps.immutableEntry(loc, multipath)); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); default: throw new IllegalStateException("Unexpected ReturnFlowType: " + returnFlowType); } } }
BidirectionalReachabilityAnswerer extends Answerer { @VisibleForTesting static Map<Location, BDD> getAnswerBdds( BidirectionalReachabilityResult result, ReturnFlowType returnFlowType) { Map<Location, BDD> successBdds = result.getStartLocationReturnPassSuccessBdds(); Map<Location, BDD> failureBdds = result.getStartLocationReturnPassFailureBdds(); switch (returnFlowType) { case SUCCESS: return successBdds.entrySet().stream() .map( entry -> { Location loc = entry.getKey(); BDD success = entry.getValue(); BDD fail = failureBdds.get(loc); BDD successOnly = fail == null ? success : success.diff(fail); return Maps.immutableEntry(loc, successOnly.isZero() ? success : successOnly); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); case FAILURE: return failureBdds.entrySet().stream() .map( entry -> { Location loc = entry.getKey(); BDD fail = entry.getValue(); BDD success = successBdds.get(loc); BDD failOnly = success == null ? fail : fail.diff(success); return Maps.immutableEntry(loc, failOnly.isZero() ? fail : failOnly); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); case MULTIPATH_INCONSISTENT: return successBdds.entrySet().stream() .flatMap( entry -> { Location loc = entry.getKey(); BDD success = entry.getValue(); BDD fail = failureBdds.get(loc); if (fail == null) { return Stream.of(); } BDD multipath = success.and(fail); return multipath.isZero() ? Stream.of() : Stream.of(Maps.immutableEntry(loc, multipath)); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); default: throw new IllegalStateException("Unexpected ReturnFlowType: " + returnFlowType); } } BidirectionalReachabilityAnswerer(BidirectionalReachabilityQuestion question, IBatfish batfish); }
BidirectionalReachabilityAnswerer extends Answerer { @VisibleForTesting static Map<Location, BDD> getAnswerBdds( BidirectionalReachabilityResult result, ReturnFlowType returnFlowType) { Map<Location, BDD> successBdds = result.getStartLocationReturnPassSuccessBdds(); Map<Location, BDD> failureBdds = result.getStartLocationReturnPassFailureBdds(); switch (returnFlowType) { case SUCCESS: return successBdds.entrySet().stream() .map( entry -> { Location loc = entry.getKey(); BDD success = entry.getValue(); BDD fail = failureBdds.get(loc); BDD successOnly = fail == null ? success : success.diff(fail); return Maps.immutableEntry(loc, successOnly.isZero() ? success : successOnly); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); case FAILURE: return failureBdds.entrySet().stream() .map( entry -> { Location loc = entry.getKey(); BDD fail = entry.getValue(); BDD success = successBdds.get(loc); BDD failOnly = success == null ? fail : fail.diff(success); return Maps.immutableEntry(loc, failOnly.isZero() ? fail : failOnly); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); case MULTIPATH_INCONSISTENT: return successBdds.entrySet().stream() .flatMap( entry -> { Location loc = entry.getKey(); BDD success = entry.getValue(); BDD fail = failureBdds.get(loc); if (fail == null) { return Stream.of(); } BDD multipath = success.and(fail); return multipath.isZero() ? Stream.of() : Stream.of(Maps.immutableEntry(loc, multipath)); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); default: throw new IllegalStateException("Unexpected ReturnFlowType: " + returnFlowType); } } BidirectionalReachabilityAnswerer(BidirectionalReachabilityQuestion question, IBatfish batfish); @Override AnswerElement answer(NetworkSnapshot snapshot); }
BidirectionalReachabilityAnswerer extends Answerer { @VisibleForTesting static Map<Location, BDD> getAnswerBdds( BidirectionalReachabilityResult result, ReturnFlowType returnFlowType) { Map<Location, BDD> successBdds = result.getStartLocationReturnPassSuccessBdds(); Map<Location, BDD> failureBdds = result.getStartLocationReturnPassFailureBdds(); switch (returnFlowType) { case SUCCESS: return successBdds.entrySet().stream() .map( entry -> { Location loc = entry.getKey(); BDD success = entry.getValue(); BDD fail = failureBdds.get(loc); BDD successOnly = fail == null ? success : success.diff(fail); return Maps.immutableEntry(loc, successOnly.isZero() ? success : successOnly); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); case FAILURE: return failureBdds.entrySet().stream() .map( entry -> { Location loc = entry.getKey(); BDD fail = entry.getValue(); BDD success = successBdds.get(loc); BDD failOnly = success == null ? fail : fail.diff(success); return Maps.immutableEntry(loc, failOnly.isZero() ? fail : failOnly); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); case MULTIPATH_INCONSISTENT: return successBdds.entrySet().stream() .flatMap( entry -> { Location loc = entry.getKey(); BDD success = entry.getValue(); BDD fail = failureBdds.get(loc); if (fail == null) { return Stream.of(); } BDD multipath = success.and(fail); return multipath.isZero() ? Stream.of() : Stream.of(Maps.immutableEntry(loc, multipath)); }) .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); default: throw new IllegalStateException("Unexpected ReturnFlowType: " + returnFlowType); } } BidirectionalReachabilityAnswerer(BidirectionalReachabilityQuestion question, IBatfish batfish); @Override AnswerElement answer(NetworkSnapshot snapshot);  }