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