def test_add_default_route():
    rib = Rib()
    rib.add_route(default_prefix, default_next_hops)
    assert rib.destinations.get(
        default_prefix)._positive_next_hops == default_next_hops
    assert rib.destinations.get(default_prefix)._negative_next_hops == set()
    assert rib.destinations.get(
        default_prefix).get_next_hops == default_next_hops
    assert rib.fib.routes[default_prefix] == default_next_hops
def test_neg_disagg_fib_unreachable():
    rib = Rib()
    rib.add_route(default_prefix, default_next_hops)
    rib.add_route(unreachable_prefix, unreachable_next_hops, disagg_type=False)
    assert rib.destinations.get(
        unreachable_prefix)._positive_next_hops == set()
    assert rib.destinations.get(
        unreachable_prefix)._negative_next_hops == unreachable_next_hops
    assert rib.destinations.get(unreachable_prefix).get_next_hops == set()
    assert rib.fib.routes[unreachable_prefix] == "unreachable"
def test_neg_disagg_fib_unreachable_recover():
    rib = Rib()
    rib.add_route(default_prefix, default_next_hops)
    rib.add_route(unreachable_prefix, unreachable_next_hops, disagg_type=False)
    recovered_nodes = {"S3"}
    rib.delete_route(unreachable_prefix, recovered_nodes, disagg_type=False)
    assert rib.destinations.get(
        unreachable_prefix)._positive_next_hops == set()
    assert rib.destinations.get(unreachable_prefix)._negative_next_hops == \
           unreachable_next_hops - recovered_nodes
    assert rib.destinations.get(
        unreachable_prefix).get_next_hops == recovered_nodes
    assert rib.fib.routes[unreachable_prefix] == recovered_nodes
def test_add_negative_disaggregation():
    rib = Rib()
    rib.add_route(default_prefix, default_next_hops)
    rib.add_route(first_negative_disagg_prefix,
                  first_negative_disagg_next_hops,
                  disagg_type=False)
    assert rib.destinations.get(
        first_negative_disagg_prefix)._positive_next_hops == set()
    assert rib.destinations.get(first_negative_disagg_prefix)._negative_next_hops == \
           first_negative_disagg_next_hops
    assert rib.destinations.get(first_negative_disagg_prefix).get_next_hops == \
           default_next_hops - first_negative_disagg_next_hops
    assert rib.fib.routes[first_negative_disagg_prefix] == \
           default_next_hops - first_negative_disagg_next_hops
def test_add_subnet_disagg_to_first_negative_disagg():
    rib = Rib()
    rib.add_route(default_prefix, default_next_hops)
    rib.add_route(first_negative_disagg_prefix,
                  first_negative_disagg_next_hops,
                  disagg_type=False)
    rib.add_route(subnet_disagg_prefix,
                  subnet_disagg_next_hops,
                  disagg_type=False)
    assert rib.destinations.get(
        first_negative_disagg_prefix)._positive_next_hops == set()
    assert rib.destinations.get(first_negative_disagg_prefix)._negative_next_hops == \
           first_negative_disagg_next_hops
    assert rib.destinations.get(first_negative_disagg_prefix).get_next_hops == \
           default_next_hops - first_negative_disagg_next_hops
    assert rib.fib.routes[first_negative_disagg_prefix] == \
           default_next_hops - first_negative_disagg_next_hops
    # test for disaggregated subnet
    assert rib.destinations.get(
        subnet_disagg_prefix)._positive_next_hops == set()
    assert rib.destinations.get(
        subnet_disagg_prefix)._negative_next_hops == subnet_disagg_next_hops
    assert rib.destinations.get(subnet_disagg_prefix).get_next_hops == \
           default_next_hops - first_negative_disagg_next_hops - subnet_disagg_next_hops
    assert rib.fib.routes[subnet_disagg_prefix] == \
           default_next_hops - first_negative_disagg_next_hops - subnet_disagg_next_hops
def test_pos_neg_disagg_recursive():
    rib = Rib()
    rib.add_route(default_prefix, default_next_hops)
    rib.add_route(first_negative_disagg_prefix,
                  first_negative_disagg_next_hops,
                  disagg_type=False)
    rib.add_route(subnet_disagg_prefix,
                  subnet_disagg_next_hops,
                  disagg_type=False)
    rib.add_route(subnet_disagg_prefix, first_negative_disagg_next_hops)
    assert rib.destinations.get(subnet_disagg_prefix)._positive_next_hops == \
           first_negative_disagg_next_hops
    assert rib.destinations.get(subnet_disagg_prefix)._negative_next_hops == \
           subnet_disagg_next_hops
    assert rib.destinations.get(subnet_disagg_prefix).get_next_hops == \
           default_next_hops - subnet_disagg_next_hops
    assert rib.fib.routes[
        subnet_disagg_prefix] == default_next_hops - subnet_disagg_next_hops
def test_pos_neg_disagg():
    rib = Rib()
    rib.add_route(default_prefix, default_next_hops)
    rib.add_route(leaf_prefix, leaf_prefix_positive_next_hops)
    rib.add_route(leaf_prefix,
                  leaf_prefix_negative_next_hops,
                  disagg_type=False)
    assert rib.destinations.get(
        leaf_prefix)._positive_next_hops == leaf_prefix_positive_next_hops
    assert rib.destinations.get(
        leaf_prefix)._negative_next_hops == leaf_prefix_negative_next_hops
    assert rib.destinations.get(
        leaf_prefix).get_next_hops == leaf_prefix_positive_next_hops
    assert rib.fib.routes[leaf_prefix] == leaf_prefix_positive_next_hops
def test_add_subnet_disagg_recursive_unreachable():
    rib = Rib()
    rib.add_route(default_prefix, default_next_hops)
    rib.add_route(first_negative_disagg_prefix,
                  first_negative_disagg_next_hops,
                  disagg_type=False)
    rib.add_route(subnet_disagg_prefix,
                  subnet_disagg_next_hops,
                  disagg_type=False)
    unreachable_next_hops = default_next_hops - first_negative_disagg_next_hops
    rib.add_route(first_negative_disagg_prefix,
                  unreachable_next_hops,
                  disagg_type=False)
    assert rib.destinations.get(
        first_negative_disagg_prefix)._positive_next_hops == set()
    assert rib.destinations.get(
        first_negative_disagg_prefix)._negative_next_hops == default_next_hops
    assert rib.destinations.get(
        first_negative_disagg_prefix).get_next_hops == set()
    assert rib.fib.routes[first_negative_disagg_prefix] == "unreachable"
    assert not rib.destinations.has_key(subnet_disagg_prefix)
    assert subnet_disagg_prefix not in rib.fib.routes
def test_recursive_recover():
    rib = Rib()
    rib.add_route(default_prefix, default_next_hops)
    rib.add_route(first_negative_disagg_prefix,
                  first_negative_disagg_next_hops,
                  disagg_type=False)
    rib.add_route(subnet_disagg_prefix,
                  subnet_disagg_next_hops,
                  disagg_type=False)
    failed_next_hop = {"S3"}
    rib.delete_route(default_prefix, failed_next_hop)
    rib.add_route(default_prefix, failed_next_hop)
    # test for default
    assert rib.destinations.get(
        default_prefix)._positive_next_hops == default_next_hops
    assert rib.destinations.get(default_prefix)._negative_next_hops == set()
    assert rib.destinations.get(
        default_prefix).get_next_hops == default_next_hops
    assert rib.fib.routes[default_prefix] == default_next_hops
    # test for 10.0.0.0/16
    assert rib.destinations.get(
        first_negative_disagg_prefix)._positive_next_hops == set()
    assert rib.destinations.get(first_negative_disagg_prefix)._negative_next_hops == \
           first_negative_disagg_next_hops
    assert rib.destinations.get(first_negative_disagg_prefix).get_next_hops == \
           default_next_hops - first_negative_disagg_next_hops
    assert rib.fib.routes[first_negative_disagg_prefix] == \
           default_next_hops - first_negative_disagg_next_hops
    # test for 10.0.10.0/24
    assert rib.destinations.get(
        subnet_disagg_prefix)._positive_next_hops == set()
    assert rib.destinations.get(
        subnet_disagg_prefix)._negative_next_hops == subnet_disagg_next_hops
    assert rib.destinations.get(subnet_disagg_prefix).get_next_hops == default_next_hops - \
           first_negative_disagg_next_hops - subnet_disagg_next_hops
    assert rib.fib.routes[subnet_disagg_prefix] == default_next_hops - \
           first_negative_disagg_next_hops - subnet_disagg_next_hops
def test_remove_default_next_hop():
    rib = Rib()
    rib.add_route(default_prefix, default_next_hops)
    rib.add_route(first_negative_disagg_prefix,
                  first_negative_disagg_next_hops,
                  disagg_type=False)
    rib.add_route(second_negative_disagg_prefix,
                  second_negative_disagg_next_hops,
                  disagg_type=False)
    failed_next_hop = {"S2"}
    rib.delete_route(default_prefix, failed_next_hop)
    # test for default
    assert rib.destinations.get(
        default_prefix
    )._positive_next_hops == default_next_hops - failed_next_hop
    assert rib.destinations.get(default_prefix)._negative_next_hops == set()
    assert rib.destinations.get(
        default_prefix).get_next_hops == default_next_hops - failed_next_hop
    assert rib.fib.routes[
        default_prefix] == default_next_hops - failed_next_hop
    # test for 10.0.0.0/16
    assert rib.destinations.get(
        first_negative_disagg_prefix)._positive_next_hops == set()
    assert rib.destinations.get(first_negative_disagg_prefix)._negative_next_hops == \
           first_negative_disagg_next_hops
    assert rib.destinations.get(first_negative_disagg_prefix).get_next_hops == \
           default_next_hops - first_negative_disagg_next_hops - failed_next_hop
    assert rib.fib.routes[first_negative_disagg_prefix] == \
           default_next_hops - first_negative_disagg_next_hops - failed_next_hop
    # test for 10.1.0.0/16
    assert rib.destinations.get(
        second_negative_disagg_prefix)._positive_next_hops == set()
    assert rib.destinations.get(second_negative_disagg_prefix)._negative_next_hops == \
           second_negative_disagg_next_hops
    assert rib.destinations.get(second_negative_disagg_prefix).get_next_hops == \
           default_next_hops - second_negative_disagg_next_hops - failed_next_hop
    assert rib.fib.routes[second_negative_disagg_prefix] == \
           default_next_hops - second_negative_disagg_next_hops - failed_next_hop