summaryrefslogtreecommitdiffhomepage
path: root/test/packetimpact/testbench/testbench.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/packetimpact/testbench/testbench.go')
-rw-r--r--test/packetimpact/testbench/testbench.go165
1 files changed, 116 insertions, 49 deletions
diff --git a/test/packetimpact/testbench/testbench.go b/test/packetimpact/testbench/testbench.go
index c1db95d8c..92200add9 100644
--- a/test/packetimpact/testbench/testbench.go
+++ b/test/packetimpact/testbench/testbench.go
@@ -31,64 +31,120 @@ import (
var (
// Native indicates that the test is being run natively.
Native = false
- // LocalDevice is the device that testbench uses to inject traffic.
- LocalDevice = ""
- // RemoteDevice is the device name on the DUT, individual tests can
- // use the name to construct tests.
- RemoteDevice = ""
+ // RPCKeepalive is the gRPC keepalive.
+ RPCKeepalive = 10 * time.Second
+ // RPCTimeout is the gRPC timeout.
+ RPCTimeout = 100 * time.Millisecond
+ // dutTestNets is the pool among which the testbench can choose a DUT to work
+ // with.
+ dutTestNets chan *DUTTestNet
+
+ // TODO(zeling): Remove the following variables once the test runner side is
+ // ready.
+ localDevice = ""
+ remoteDevice = ""
+ localIPv4 = ""
+ remoteIPv4 = ""
+ ipv4PrefixLength = 0
+ localIPv6 = ""
+ remoteIPv6 = ""
+ localInterfaceID uint32
+ remoteInterfaceID uint64
+ localMAC = ""
+ remoteMAC = ""
+ posixServerIP = ""
+ posixServerPort = 40000
+)
+
+// DUTTestNet describes the test network setup on dut and how the testbench
+// should connect with an existing DUT.
+type DUTTestNet struct {
+ // LocalMAC is the local MAC address on the test network.
+ LocalMAC net.HardwareAddr
+ // RemoteMAC is the DUT's MAC address on the test network.
+ RemoteMAC net.HardwareAddr
// LocalIPv4 is the local IPv4 address on the test network.
- LocalIPv4 = ""
+ LocalIPv4 net.IP
// RemoteIPv4 is the DUT's IPv4 address on the test network.
- RemoteIPv4 = ""
+ RemoteIPv4 net.IP
// IPv4PrefixLength is the network prefix length of the IPv4 test network.
- IPv4PrefixLength = 0
-
+ IPv4PrefixLength int
// LocalIPv6 is the local IPv6 address on the test network.
- LocalIPv6 = ""
+ LocalIPv6 net.IP
// RemoteIPv6 is the DUT's IPv6 address on the test network.
- RemoteIPv6 = ""
-
- // LocalInterfaceID is the ID of the local interface on the test network.
- LocalInterfaceID uint32
- // RemoteInterfaceID is the ID of the remote interface on the test network.
- //
- // Not using uint32 because package flag does not support uint32.
- RemoteInterfaceID uint64
+ RemoteIPv6 net.IP
+ // LocalDevID is the ID of the local interface on the test network.
+ LocalDevID uint32
+ // RemoteDevID is the ID of the remote interface on the test network.
+ RemoteDevID uint32
+ // LocalDevName is the device that testbench uses to inject traffic.
+ LocalDevName string
+ // RemoteDevName is the device name on the DUT, individual tests can
+ // use the name to construct tests.
+ RemoteDevName string
- // LocalMAC is the local MAC address on the test network.
- LocalMAC = ""
- // RemoteMAC is the DUT's MAC address on the test network.
- RemoteMAC = ""
+ // The following two fields on actually on the control network instead
+ // of the test network, including them for convenience.
// POSIXServerIP is the POSIX server's IP address on the control network.
- POSIXServerIP = ""
+ POSIXServerIP net.IP
// POSIXServerPort is the UDP port the POSIX server is bound to on the
// control network.
- POSIXServerPort = 40000
-
- // RPCKeepalive is the gRPC keepalive.
- RPCKeepalive = 10 * time.Second
- // RPCTimeout is the gRPC timeout.
- RPCTimeout = 100 * time.Millisecond
-)
+ POSIXServerPort uint16
+}
-// RegisterFlags defines flags and associates them with the package-level
+// registerFlags defines flags and associates them with the package-level
// exported variables above. It should be called by tests in their init
// functions.
-func RegisterFlags(fs *flag.FlagSet) {
- fs.StringVar(&POSIXServerIP, "posix_server_ip", POSIXServerIP, "ip address to listen to for UDP commands")
- fs.IntVar(&POSIXServerPort, "posix_server_port", POSIXServerPort, "port to listen to for UDP commands")
+func registerFlags(fs *flag.FlagSet) {
+ fs.StringVar(&posixServerIP, "posix_server_ip", posixServerIP, "ip address to listen to for UDP commands")
+ fs.IntVar(&posixServerPort, "posix_server_port", posixServerPort, "port to listen to for UDP commands")
+ fs.StringVar(&localIPv4, "local_ipv4", localIPv4, "local IPv4 address for test packets")
+ fs.StringVar(&remoteIPv4, "remote_ipv4", remoteIPv4, "remote IPv4 address for test packets")
+ fs.StringVar(&remoteIPv6, "remote_ipv6", remoteIPv6, "remote IPv6 address for test packets")
+ fs.StringVar(&remoteMAC, "remote_mac", remoteMAC, "remote mac address for test packets")
+ fs.StringVar(&localDevice, "local_device", localDevice, "local device to inject traffic")
+ fs.StringVar(&remoteDevice, "remote_device", remoteDevice, "remote device on the DUT")
+ fs.Uint64Var(&remoteInterfaceID, "remote_interface_id", remoteInterfaceID, "remote interface ID for test packets")
+
+ fs.BoolVar(&Native, "native", Native, "whether the test is running natively")
fs.DurationVar(&RPCTimeout, "rpc_timeout", RPCTimeout, "gRPC timeout")
fs.DurationVar(&RPCKeepalive, "rpc_keepalive", RPCKeepalive, "gRPC keepalive")
- fs.StringVar(&LocalIPv4, "local_ipv4", LocalIPv4, "local IPv4 address for test packets")
- fs.StringVar(&RemoteIPv4, "remote_ipv4", RemoteIPv4, "remote IPv4 address for test packets")
- fs.StringVar(&RemoteIPv6, "remote_ipv6", RemoteIPv6, "remote IPv6 address for test packets")
- fs.StringVar(&RemoteMAC, "remote_mac", RemoteMAC, "remote mac address for test packets")
- fs.StringVar(&LocalDevice, "local_device", LocalDevice, "local device to inject traffic")
- fs.StringVar(&RemoteDevice, "remote_device", RemoteDevice, "remote device on the DUT")
- fs.BoolVar(&Native, "native", Native, "whether the test is running natively")
- fs.Uint64Var(&RemoteInterfaceID, "remote_interface_id", RemoteInterfaceID, "remote interface ID for test packets")
+}
+
+// Initialize initializes the testbench, it parse the flags and sets up the
+// pool of test networks for testbench's later use.
+func Initialize(fs *flag.FlagSet) {
+ registerFlags(fs)
+ flag.Parse()
+ if err := genPseudoFlags(); err != nil {
+ panic(err)
+ }
+ var dut DUTTestNet
+ var err error
+ dut.LocalMAC, err = net.ParseMAC(localMAC)
+ if err != nil {
+ panic(err)
+ }
+ dut.RemoteMAC, err = net.ParseMAC(remoteMAC)
+ if err != nil {
+ panic(err)
+ }
+ dut.LocalIPv4 = net.ParseIP(localIPv4).To4()
+ dut.LocalIPv6 = net.ParseIP(localIPv6).To16()
+ dut.RemoteIPv4 = net.ParseIP(remoteIPv4).To4()
+ dut.RemoteIPv6 = net.ParseIP(remoteIPv6).To16()
+ dut.LocalDevID = uint32(localInterfaceID)
+ dut.RemoteDevID = uint32(remoteInterfaceID)
+ dut.LocalDevName = localDevice
+ dut.RemoteDevName = remoteDevice
+ dut.POSIXServerIP = net.ParseIP(posixServerIP)
+ dut.POSIXServerPort = uint16(posixServerPort)
+ dut.IPv4PrefixLength = ipv4PrefixLength
+
+ dutTestNets = make(chan *DUTTestNet, 1)
+ dutTestNets <- &dut
}
// genPseudoFlags populates flag-like global config based on real flags.
@@ -104,21 +160,20 @@ func genPseudoFlags() error {
return fmt.Errorf("parsing devices: %w", err)
}
- _, deviceInfo, err := netdevs.FindDeviceByIP(net.ParseIP(LocalIPv4), devs)
+ _, deviceInfo, err := netdevs.FindDeviceByIP(net.ParseIP(localIPv4), devs)
if err != nil {
return fmt.Errorf("can't find deviceInfo: %w", err)
}
- LocalMAC = deviceInfo.MAC.String()
- LocalIPv6 = deviceInfo.IPv6Addr.String()
- LocalInterfaceID = deviceInfo.ID
+ localMAC = deviceInfo.MAC.String()
+ localIPv6 = deviceInfo.IPv6Addr.String()
+ localInterfaceID = deviceInfo.ID
if deviceInfo.IPv4Net != nil {
- IPv4PrefixLength, _ = deviceInfo.IPv4Net.Mask.Size()
+ ipv4PrefixLength, _ = deviceInfo.IPv4Net.Mask.Size()
} else {
- IPv4PrefixLength, _ = net.ParseIP(LocalIPv4).DefaultMask().Size()
+ ipv4PrefixLength, _ = net.ParseIP(localIPv4).DefaultMask().Size()
}
-
return nil
}
@@ -132,3 +187,15 @@ func GenerateRandomPayload(t *testing.T, n int) []byte {
}
return buf
}
+
+// GetDUTTestNet gets a usable DUTTestNet, the function will block until any
+// becomes available.
+func GetDUTTestNet() *DUTTestNet {
+ return <-dutTestNets
+}
+
+// Release releases the DUTTestNet back to the pool so that some other test
+// can use.
+func (n *DUTTestNet) Release() {
+ dutTestNets <- n
+}