@@ -1415,3 +1415,240 @@ func mustVerifyFlowBundle(t *testing.T, stdin io.Reader, flows []*Flow, matchFlo
14151415 }
14161416 }
14171417}
1418+
1419+ func TestClientOpenFlowDumpPortMappingsOK (t * testing.T ) {
1420+ want := map [string ]* PortMapping {
1421+ "interface1" : {
1422+ OfPort : 7 ,
1423+ MACAddress : "fe:4f:76:09:88:2b" ,
1424+ },
1425+ "interface2" : {
1426+ OfPort : 8 ,
1427+ MACAddress : "fe:be:7b:0d:53:d8" ,
1428+ },
1429+ "interface3" : {
1430+ OfPort : 9 ,
1431+ MACAddress : "fe:b6:4c:d5:40:79" ,
1432+ },
1433+ "interface4" : {
1434+ OfPort : 20 ,
1435+ MACAddress : "fe:cf:a6:90:30:29" ,
1436+ },
1437+ "LOCAL" : {
1438+ OfPort : 65534 ,
1439+ MACAddress : "fe:74:0f:80:cf:9a" ,
1440+ },
1441+ "eth0" : {
1442+ OfPort : 1 ,
1443+ MACAddress : "aa:bb:cc:dd:ee:ff" ,
1444+ },
1445+ }
1446+
1447+ bridge := "br0"
1448+
1449+ c := testClient ([]OptionFunc {Timeout (1 )}, func (cmd string , args ... string ) ([]byte , error ) {
1450+ // Verify correct command and arguments passed, including option flags
1451+ if want , got := "ovs-ofctl" , cmd ; want != got {
1452+ t .Fatalf ("incorrect command:\n - want: %v\n - got: %v" ,
1453+ want , got )
1454+ }
1455+
1456+ wantArgs := []string {"--timeout=1" , "show" , bridge }
1457+ if want , got := wantArgs , args ; ! reflect .DeepEqual (want , got ) {
1458+ t .Fatalf ("incorrect arguments\n - want: %v\n - got: %v" ,
1459+ want , got )
1460+ }
1461+
1462+ return []byte (`
1463+ OFPT_FEATURES_REPLY (xid=0x2): dpid:0000000000000001
1464+ n_tables:254, n_buffers:256
1465+ capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
1466+ actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
1467+ 7(interface1): addr:fe:4f:76:09:88:2b
1468+ config: 0
1469+ state: 0
1470+ current: 10GB-FD COPPER
1471+ speed: 10000 Mbps now, 0 Mbps max
1472+ 8(interface2): addr:fe:be:7b:0d:53:d8
1473+ config: 0
1474+ state: 0
1475+ current: 10GB-FD COPPER
1476+ speed: 10000 Mbps now, 0 Mbps max
1477+ 9(interface3): addr:fe:b6:4c:d5:40:79
1478+ config: 0
1479+ state: 0
1480+ current: 10GB-FD COPPER
1481+ speed: 10000 Mbps now, 0 Mbps max
1482+ 20(interface4): addr:fe:cf:a6:90:30:29
1483+ config: 0
1484+ state: 0
1485+ current: 10GB-FD COPPER
1486+ speed: 10000 Mbps now, 0 Mbps max
1487+ 65534(LOCAL): addr:fe:74:0f:80:cf:9a
1488+ config: 0
1489+ state: 0
1490+ current: 10GB-FD COPPER
1491+ speed: 10000 Mbps now, 0 Mbps max
1492+ 1(eth0): addr:aa:bb:cc:dd:ee:ff
1493+ config: 0
1494+ state: 0
1495+ ` ), nil
1496+ })
1497+
1498+ got , err := c .OpenFlow .DumpPortMappings (bridge )
1499+ if err != nil {
1500+ t .Fatalf ("unexpected error: %v" , err )
1501+ }
1502+
1503+ if len (want ) != len (got ) {
1504+ t .Fatalf ("unexpected number of mappings:\n - want: %d\n - got: %d" ,
1505+ len (want ), len (got ))
1506+ }
1507+
1508+ for name , wantMapping := range want {
1509+ gotMapping , ok := got [name ]
1510+ if ! ok {
1511+ t .Fatalf ("missing mapping for interface %q" , name )
1512+ }
1513+
1514+ if wantMapping .OfPort != gotMapping .OfPort {
1515+ t .Fatalf ("unexpected OfPort for %q:\n - want: %d\n - got: %d" ,
1516+ name , wantMapping .OfPort , gotMapping .OfPort )
1517+ }
1518+
1519+ if wantMapping .MACAddress != gotMapping .MACAddress {
1520+ t .Fatalf ("unexpected MACAddress for %q:\n - want: %q\n - got: %q" ,
1521+ name , wantMapping .MACAddress , gotMapping .MACAddress )
1522+ }
1523+ }
1524+
1525+ // Verify all interfaces are included
1526+ if _ , ok := got ["eth0" ]; ! ok {
1527+ t .Fatalf ("all interfaces should be included, eth0 missing" )
1528+ }
1529+ }
1530+
1531+ func TestClientOpenFlowDumpPortMappingsEmptyOutput (t * testing.T ) {
1532+ bridge := "br0"
1533+
1534+ c := testClient (nil , func (cmd string , args ... string ) ([]byte , error ) {
1535+ return []byte ("" ), nil
1536+ })
1537+
1538+ got , err := c .OpenFlow .DumpPortMappings (bridge )
1539+ if err != nil {
1540+ t .Fatalf ("unexpected error: %v" , err )
1541+ }
1542+
1543+ if len (got ) != 0 {
1544+ t .Fatalf ("unexpected mappings for empty output:\n - want: 0\n - got: %d" , len (got ))
1545+ }
1546+ }
1547+
1548+ func TestClientOpenFlowDumpPortMappingsAllInterfaces (t * testing.T ) {
1549+ want := map [string ]* PortMapping {
1550+ "eth0" : {
1551+ OfPort : 1 ,
1552+ MACAddress : "aa:bb:cc:dd:ee:ff" ,
1553+ },
1554+ "eth1" : {
1555+ OfPort : 2 ,
1556+ MACAddress : "11:22:33:44:55:66" ,
1557+ },
1558+ }
1559+
1560+ bridge := "br0"
1561+
1562+ c := testClient (nil , func (cmd string , args ... string ) ([]byte , error ) {
1563+ return []byte (`
1564+ OFPT_FEATURES_REPLY (xid=0x2): dpid:0000000000000001
1565+ 1(eth0): addr:aa:bb:cc:dd:ee:ff
1566+ 2(eth1): addr:11:22:33:44:55:66
1567+ ` ), nil
1568+ })
1569+
1570+ got , err := c .OpenFlow .DumpPortMappings (bridge )
1571+ if err != nil {
1572+ t .Fatalf ("unexpected error: %v" , err )
1573+ }
1574+
1575+ if len (want ) != len (got ) {
1576+ t .Fatalf ("unexpected number of mappings:\n - want: %d\n - got: %d" , len (want ), len (got ))
1577+ }
1578+
1579+ for name , wantMapping := range want {
1580+ gotMapping , ok := got [name ]
1581+ if ! ok {
1582+ t .Fatalf ("missing mapping for interface %q" , name )
1583+ }
1584+
1585+ if wantMapping .OfPort != gotMapping .OfPort {
1586+ t .Fatalf ("unexpected OfPort for %q:\n - want: %d\n - got: %d" ,
1587+ name , wantMapping .OfPort , gotMapping .OfPort )
1588+ }
1589+
1590+ if wantMapping .MACAddress != gotMapping .MACAddress {
1591+ t .Fatalf ("unexpected MACAddress for %q:\n - want: %q\n - got: %q" ,
1592+ name , wantMapping .MACAddress , gotMapping .MACAddress )
1593+ }
1594+ }
1595+ }
1596+
1597+ func TestClientOpenFlowDumpPortMappingsOnlyLOCAL (t * testing.T ) {
1598+ want := map [string ]* PortMapping {
1599+ "LOCAL" : {
1600+ OfPort : 65534 ,
1601+ MACAddress : "fe:74:0f:80:cf:9a" ,
1602+ },
1603+ }
1604+
1605+ bridge := "br0"
1606+
1607+ c := testClient (nil , func (cmd string , args ... string ) ([]byte , error ) {
1608+ return []byte (`
1609+ OFPT_FEATURES_REPLY (xid=0x2): dpid:0000000000000001
1610+ 65534(LOCAL): addr:fe:74:0f:80:cf:9a
1611+ ` ), nil
1612+ })
1613+
1614+ got , err := c .OpenFlow .DumpPortMappings (bridge )
1615+ if err != nil {
1616+ t .Fatalf ("unexpected error: %v" , err )
1617+ }
1618+
1619+ if len (want ) != len (got ) {
1620+ t .Fatalf ("unexpected number of mappings:\n - want: %d\n - got: %d" ,
1621+ len (want ), len (got ))
1622+ }
1623+
1624+ for name , wantMapping := range want {
1625+ gotMapping , ok := got [name ]
1626+ if ! ok {
1627+ t .Fatalf ("missing mapping for interface %q" , name )
1628+ }
1629+
1630+ if wantMapping .OfPort != gotMapping .OfPort {
1631+ t .Fatalf ("unexpected OfPort for %q:\n - want: %d\n - got: %d" ,
1632+ name , wantMapping .OfPort , gotMapping .OfPort )
1633+ }
1634+
1635+ if wantMapping .MACAddress != gotMapping .MACAddress {
1636+ t .Fatalf ("unexpected MACAddress for %q:\n - want: %q\n - got: %q" ,
1637+ name , wantMapping .MACAddress , gotMapping .MACAddress )
1638+ }
1639+ }
1640+ }
1641+
1642+ func TestClientOpenFlowDumpPortMappingsCommandError (t * testing.T ) {
1643+ bridge := "br0"
1644+ wantErr := errors .New ("command failed" )
1645+
1646+ c := testClient (nil , func (cmd string , args ... string ) ([]byte , error ) {
1647+ return nil , wantErr
1648+ })
1649+
1650+ _ , err := c .OpenFlow .DumpPortMappings (bridge )
1651+ if err == nil {
1652+ t .Fatalf ("expected error, got nil" )
1653+ }
1654+ }
0 commit comments