def test_simulates_forwards2(self): o = (Header({'switch': 2, 'port': 1}) |then| forward(2, 2))+\ (Header({'switch': 3, 'port': 1}) |then| forward(3, 2)) r = (Header({'switch': 2, 'port': 1, 'vlan': 2}) |then| forward(2, 2))+\ (Header({'switch': 3, 'port': 1, 'vlan': 2}) |then| forward(3, 2)) self.assertIsNone(sat.simulates_forwards2(topo, o, r)) self.assertIsNotNone(sat.simulates_forwards2(topo, o, r, field='srcmac')) o = (Header({'switch': 2, 'port': 1, 'vlan': 1}) |then| forward(2, 2))+\ (Header({'switch': 3, 'port': 1, 'vlan': 1}) |then| forward(3, 2)) r = (Header({'switch': 2, 'port': 1, 'vlan': 2}) |then| forward(2, 2))+\ (Header({'switch': 3, 'port': 1, 'vlan': 2}) |then| forward(3, 2)) self.assertIsNone(sat.simulates_forwards2(topo, o, r)) self.assertIsNotNone(sat.simulates_forwards2(topo, o, r, field='srcmac')) # This is the corner case that demonstrates that we need to restrict # compiled policies to only one vlan per slice. o = (Header({'switch': 2, 'port': 1}) |then| forward(2, 2))+\ (Header({'switch': 3, 'port': 1}) |then| forward(3, 2))+\ (Header({'switch': 4, 'port': 1}) |then| forward(4, 2)) r = (Header({'switch': 2, 'port': 1, 'vlan': 1}) |then| forward(2, 2))+\ (Header({'switch': 3, 'port': 1, 'vlan': 1}) |then| forward(3, 2))+\ (Header({'switch': 3, 'port': 1, 'vlan': 2}) |then| forward(3, 2))+\ (Header({'switch': 4, 'port': 1, 'vlan': 2}) |then| forward(4, 2)) self.assertIsNone(sat.simulates_forwards(topo, o, r)) # NOTE: We would really like this to be a failure, but it isn't. # Therefore, for compiler correctness, we also need one vlan per edge. self.assertIsNone(sat.simulates_forwards2(topo, o, r)) self.assertIsNotNone(sat.simulates_forwards2(topo, o, r, field='srcmac')) # And verify that the compilation test finds this failure self.assertFalse(sat.compiled_correctly(topo, o, r))
def test_forwards(self): o = Header({'switch': 2}) |then| Action(2, [1]) r = Header({'switch': 2}) |then| Action(2, [1]) self.assertIsNone(sat.simulates_forwards(topo, o, r)) self.assertIsNone(sat.simulates_forwards(topo, r, o)) o = Header({'switch': 2, 'port': 2}) |then| Action(2, [1]) r = Header({'switch': 2, 'port': 2}) |then| Action(2, [1]) self.assertIsNone(sat.simulates_forwards(topo, o, r)) self.assertIsNone(sat.simulates_forwards(topo, r, o)) o = Header({'switch': 2, 'port': 2}) |then| Action(2, [1]) r = Header({'switch': 2, 'port': 2, 'vlan': 2}) |then| Action(2, [1]) self.assertIsNone(sat.simulates_forwards(topo, o, r)) self.assertIsNone(sat.simulates_forwards(topo, r, o)) o = Header({'switch': 2, 'port': 2}) |then| forward(2, 1) r = Header({'switch': 2, 'port': 2, 'vlan': 2}) |then| Action(2, [1], {'vlan': 2}) self.assertIsNone(sat.simulates_forwards(topo, o, r)) self.assertIsNone(sat.simulates_forwards(topo, r, o)) o = Header({'switch': 0, 'port': 1}) |then| Action(0, [1]) r = Header({'switch': 0, 'port': 1, 'vlan': 1}) |then| Action(0, [1], {'vlan': 1}) self.assertIsNone(sat.simulates_forwards(topo, o, r)) self.assertIsNone(sat.simulates_forwards(topo, r, o)) o = Header({'switch': 0, 'port': 1, 'srcmac': 32432, 'dstmac': 324322}) |then| Action(0, [1]) r = Header({'switch': 0, 'port': 1, 'srcmac': 32432, 'dstmac': 324322, 'vlan': 1}) |then| Action(0, [1], {'vlan': 1}) self.assertIsNone(sat.simulates_forwards(topo, o, r)) self.assertIsNone(sat.simulates_forwards(topo, r, o))