mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-20 22:10:30 +00:00
438 lines
7.4 KiB
Go
438 lines
7.4 KiB
Go
package odp
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"syscall"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func init() {
|
|
rand.Seed(time.Now().UTC().UnixNano())
|
|
}
|
|
|
|
func checkedCloseDpif(dpif *Dpif, t *testing.T) {
|
|
err := dpif.Close()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestCreateDatapath(t *testing.T) {
|
|
dpif, err := NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedCloseDpif(dpif, t)
|
|
|
|
name := fmt.Sprintf("test%d", rand.Intn(100000))
|
|
|
|
dp, err := dpif.CreateDatapath(name)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = dp.Delete()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestLookupDatapath(t *testing.T) {
|
|
dpif, err := NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedCloseDpif(dpif, t)
|
|
|
|
name := fmt.Sprintf("test%d", rand.Intn(100000))
|
|
dp, err := dpif.LookupDatapath(name)
|
|
if !IsNoSuchDatapathError(err) {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
_, err = dpif.CreateDatapath(name)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
checkedCloseDpif(dpif, t)
|
|
dpif, err = NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedCloseDpif(dpif, t)
|
|
|
|
dp, err = dpif.LookupDatapath(name)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = dp.Delete()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestEnumerateDatapaths(t *testing.T) {
|
|
dpif, err := NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedCloseDpif(dpif, t)
|
|
|
|
var names []string
|
|
var dps []DatapathHandle
|
|
|
|
cleanup := func() {
|
|
for _, dp := range dps {
|
|
dp.Delete()
|
|
}
|
|
}
|
|
|
|
defer cleanup()
|
|
|
|
for i := 0; i < 10; i++ {
|
|
name := fmt.Sprintf("test%d", rand.Intn(100000))
|
|
dp, err := dpif.CreateDatapath(name)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
names = append(names, name)
|
|
dps = append(dps, dp)
|
|
}
|
|
|
|
name2dp, err := dpif.EnumerateDatapaths()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, name := range names {
|
|
_, ok := name2dp[name]
|
|
if !ok {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
cleanup()
|
|
|
|
name2dp, err = dpif.EnumerateDatapaths()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, name := range names {
|
|
_, ok := name2dp[name]
|
|
if ok {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
}
|
|
|
|
func checkedDeleteDatapath(dp DatapathHandle, t *testing.T) {
|
|
err := dp.Delete()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestCreateVport(t *testing.T) {
|
|
dpif, err := NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedCloseDpif(dpif, t)
|
|
|
|
dp, err := dpif.CreateDatapath(fmt.Sprintf("test%d", rand.Intn(100000)))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedDeleteDatapath(dp, t)
|
|
|
|
name := fmt.Sprintf("test%d", rand.Intn(100000))
|
|
vport, err := dp.CreateVport(NewInternalVportSpec(name))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = dp.DeleteVport(vport)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestLookupVport(t *testing.T) {
|
|
dpif, err := NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedCloseDpif(dpif, t)
|
|
|
|
dpname := fmt.Sprintf("test%d", rand.Intn(100000))
|
|
dp, err := dpif.CreateDatapath(dpname)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
name := fmt.Sprintf("test%d", rand.Intn(100000))
|
|
vport, err := dp.LookupVportByName(name)
|
|
if !IsNoSuchVportError(err) {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
_, err = dp.CreateVport(NewInternalVportSpec(name))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
checkedCloseDpif(dpif, t)
|
|
dpif, err = NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedCloseDpif(dpif, t)
|
|
|
|
dp, err = dpif.LookupDatapath(dpname)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer dp.Delete()
|
|
|
|
vport, err = dp.LookupVportByName(name)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = dp.DeleteVport(vport.ID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestEnumerateVports(t *testing.T) {
|
|
dpif, err := NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedCloseDpif(dpif, t)
|
|
|
|
dp, err := dpif.CreateDatapath(fmt.Sprintf("test%d", rand.Intn(100000)))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedDeleteDatapath(dp, t)
|
|
|
|
var names []string
|
|
var vports []VportID
|
|
|
|
for i := 0; i < 10; i++ {
|
|
name := fmt.Sprintf("test%d", rand.Intn(100000))
|
|
vport, err := dp.CreateVport(NewInternalVportSpec(name))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
names = append(names, name)
|
|
vports = append(vports, vport)
|
|
}
|
|
|
|
gotvports, err := dp.EnumerateVports()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
gotnames := make(map[string]bool)
|
|
for _, vport := range gotvports {
|
|
gotnames[vport.Spec.Name()] = true
|
|
}
|
|
|
|
for _, name := range names {
|
|
_, ok := gotnames[name]
|
|
if !ok {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
for _, vport := range vports {
|
|
dp.DeleteVport(vport)
|
|
}
|
|
|
|
gotvports, err = dp.EnumerateVports()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
gotnames = make(map[string]bool)
|
|
for _, vport := range gotvports {
|
|
gotnames[vport.Spec.Name()] = true
|
|
}
|
|
|
|
for _, name := range names {
|
|
_, ok := gotnames[name]
|
|
if ok {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
}
|
|
|
|
var exactOvsKeyEthernetMask OvsKeyEthernet = OvsKeyEthernet{
|
|
EthSrc: [...]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
EthDst: [...]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
}
|
|
|
|
func TestCreateFlow(t *testing.T) {
|
|
dpif, err := NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedCloseDpif(dpif, t)
|
|
|
|
dp, err := dpif.CreateDatapath(fmt.Sprintf("test%d", rand.Intn(100000)))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedDeleteDatapath(dp, t)
|
|
|
|
vpname := fmt.Sprintf("test%d", rand.Intn(100000))
|
|
vport, err := dp.CreateVport(NewInternalVportSpec(vpname))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
f := NewFlowSpec()
|
|
fk := NewEthernetFlowKey()
|
|
fk.SetEthSrc([...]byte{1, 2, 3, 4, 5, 6})
|
|
fk.SetEthDst([...]byte{1, 2, 3, 4, 5, 6})
|
|
f.AddKey(fk)
|
|
f.AddAction(NewOutputAction(vport))
|
|
|
|
err = dp.CreateFlow(f)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = dp.DeleteFlow(f.FlowKeys)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = dp.DeleteFlow(f.FlowKeys)
|
|
if !IsNoSuchFlowError(err) {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
func TestEnumerateFlows(t *testing.T) {
|
|
dpif, err := NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedCloseDpif(dpif, t)
|
|
|
|
dp, err := dpif.CreateDatapath(fmt.Sprintf("test%d", rand.Intn(100000)))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer checkedDeleteDatapath(dp, t)
|
|
|
|
vpname := fmt.Sprintf("test%d", rand.Intn(100000))
|
|
vport, err := dp.CreateVport(NewInternalVportSpec(vpname))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const n = 10
|
|
var flows [n]FlowSpec
|
|
|
|
for i := range flows {
|
|
flow := NewFlowSpec()
|
|
fk := NewEthernetFlowKey()
|
|
fk.SetEthSrc([...]byte{1, 2, 3, 4, 5, byte(i)})
|
|
fk.SetEthDst([...]byte{6, 5, 4, 3, 2, 1})
|
|
flow.AddKey(fk)
|
|
flow.AddAction(NewOutputAction(vport))
|
|
err = dp.CreateFlow(flow)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
flows[i] = flow
|
|
}
|
|
|
|
eflows, err := dp.EnumerateFlows()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if len(eflows) != n {
|
|
t.Fatal()
|
|
}
|
|
|
|
for _, eflow := range eflows {
|
|
found := false
|
|
|
|
for _, flow := range flows {
|
|
if eflow.Equals(flow) {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
t.Fatal(eflow)
|
|
}
|
|
}
|
|
|
|
for _, eflow := range eflows {
|
|
err = dp.DeleteFlow(eflow.FlowKeys)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
eflows, err = dp.EnumerateFlows()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if len(eflows) != 0 {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
func TestConsumeVportEvents(t *testing.T) {
|
|
dpif, err := NewDpif()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
ch := make(chan error)
|
|
cancel, err := dpif.ConsumeVportEvents(vportTestConsumer{ch})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := cancel.Cancel(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if <-ch != syscall.EBADF {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
type vportTestConsumer struct {
|
|
ch chan error
|
|
}
|
|
|
|
func (vportTestConsumer) VportCreated(ifindex int32, vport Vport) error {
|
|
return nil
|
|
}
|
|
|
|
func (vportTestConsumer) VportDeleted(ifindex int32, vport Vport) error {
|
|
return nil
|
|
}
|
|
|
|
func (consumer vportTestConsumer) Error(err error, stopped bool) {
|
|
consumer.ch <- err
|
|
}
|