Skip to content

Commit

Permalink
Add steps/network tests (#157)
Browse files Browse the repository at this point in the history
* Add steps/network tests
  • Loading branch information
yitsushi authored Oct 22, 2021
1 parent 3d09bf1 commit 87bc452
Show file tree
Hide file tree
Showing 4 changed files with 471 additions and 0 deletions.
4 changes: 4 additions & 0 deletions core/steps/network/interface_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ func (s *createInterface) Do(ctx context.Context) ([]planner.Procedure, error) {
return nil, fmt.Errorf("checking if networking interface exists: %w", err)
}
if exists {
// This whole block is unreachable right now, because
// the Do function is called only if ShouldDo returns
// true. It retruns false if IfaceExists returns true.
// Line 76 will never return exists=true
details, err := s.svc.IfaceDetails(ctx, deviceName)
if err != nil {
return nil, fmt.Errorf("getting interface details: %w", err)
Expand Down
285 changes: 285 additions & 0 deletions core/steps/network/interface_create_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
package network_test

import (
"context"
"testing"

"github.com/golang/mock/gomock"
g "github.com/onsi/gomega"
"github.com/weaveworks/flintlock/core/errors"
"github.com/weaveworks/flintlock/core/models"
"github.com/weaveworks/flintlock/core/ports"
"github.com/weaveworks/flintlock/core/steps/network"
"github.com/weaveworks/flintlock/infrastructure/mock"
)

func TestNewNetworkInterface_everythingIsEmpty(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

g.RegisterTestingT(t)

var status *models.NetworkInterfaceStatus
vmid, _ := models.NewVMID(vmName, nsName)
iface := &models.NetworkInterface{}
svc := mock.NewMockNetworkService(mockCtrl)
ctx := context.Background()

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Times(0)

step := network.NewNetworkInterface(vmid, iface, status, svc)
shouldDo, err := step.ShouldDo(ctx)

g.Expect(err).To(g.BeNil())
g.Expect(shouldDo).To(g.BeTrue())

_, err = step.Do(ctx)

g.Expect(err).To(g.MatchError(errors.ErrGuestDeviceNameRequired))
}

func TestNewNetworkInterface_doesNotExist(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

g.RegisterTestingT(t)

var status *models.NetworkInterfaceStatus
vmid, _ := models.NewVMID(vmName, nsName)
iface := &models.NetworkInterface{GuestDeviceName: defaultEthDevice}
svc := mock.NewMockNetworkService(mockCtrl)
ctx := context.Background()

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Times(0)

step := network.NewNetworkInterface(vmid, iface, status, svc)
shouldDo, err := step.ShouldDo(ctx)

g.Expect(err).To(g.BeNil())
g.Expect(shouldDo).To(g.BeTrue())

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Return(false, nil).
Times(1)

svc.EXPECT().
IfaceCreate(gomock.Eq(ctx), gomock.Eq(ports.IfaceCreateInput{
DeviceName: expectedTapDeviceName,
})).
Return(&ports.IfaceDetails{
DeviceName: expectedTapDeviceName,
Type: models.IfaceTypeTap,
MAC: defaultMACAddress,
Index: 0,
}, nil).
Times(1)

_, err = step.Do(ctx)

g.Expect(err).To(g.BeNil())
}

func TestNewNetworkInterface_existingInterface(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

g.RegisterTestingT(t)

vmid, _ := models.NewVMID(vmName, nsName)
iface := &models.NetworkInterface{
GuestDeviceName: defaultEthDevice,
AllowMetadataRequests: false,
GuestMAC: defaultMACAddress,
Type: models.IfaceTypeTap,
}
status := &models.NetworkInterfaceStatus{
HostDeviceName: expectedTapDeviceName,
Index: 0,
MACAddress: defaultMACAddress,
}
svc := mock.NewMockNetworkService(mockCtrl)
ctx := context.Background()

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Return(true, nil).
Times(1)

step := network.NewNetworkInterface(vmid, iface, status, svc)
shouldDo, err := step.ShouldDo(ctx)

g.Expect(err).To(g.BeNil())
g.Expect(shouldDo).To(g.BeFalse())

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Return(true, nil).
Times(1)

svc.EXPECT().
IfaceDetails(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Return(&ports.IfaceDetails{
DeviceName: expectedTapDeviceName,
Type: models.IfaceTypeTap,
MAC: defaultMACAddress,
Index: 0,
}, nil).
Times(1)

_, err = step.Do(ctx)

g.Expect(err).To(g.BeNil())
}

func TestNewNetworkInterface_missingInterface(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

g.RegisterTestingT(t)

vmid, _ := models.NewVMID(vmName, nsName)
iface, status := fullNetworkInterface()
svc := mock.NewMockNetworkService(mockCtrl)
ctx := context.Background()

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Return(false, nil).
Times(1)

step := network.NewNetworkInterface(vmid, iface, status, svc)
shouldDo, err := step.ShouldDo(ctx)

g.Expect(err).To(g.BeNil())
g.Expect(shouldDo).To(g.BeTrue())

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Return(false, nil).
Times(1)

svc.EXPECT().
IfaceCreate(gomock.Eq(ctx), gomock.Eq(ports.IfaceCreateInput{
DeviceName: expectedTapDeviceName,
MAC: defaultMACAddress,
})).
Return(&ports.IfaceDetails{
DeviceName: expectedTapDeviceName,
Type: models.IfaceTypeTap,
MAC: reverseMACAddress,
Index: 0,
}, nil).
Times(1)

_, err = step.Do(ctx)

g.Expect(err).To(g.BeNil())
g.Expect(status.MACAddress).To(g.Equal(reverseMACAddress))
}

func TestNewNetworkInterface_svcError(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

g.RegisterTestingT(t)

vmid, _ := models.NewVMID(vmName, nsName)
iface, status := fullNetworkInterface()
svc := mock.NewMockNetworkService(mockCtrl)
ctx := context.Background()

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Return(false, errors.ErrParentIfaceRequired).
Times(2)

step := network.NewNetworkInterface(vmid, iface, status, svc)
shouldDo, err := step.ShouldDo(ctx)

g.Expect(err).ToNot(g.BeNil())
g.Expect(shouldDo).To(g.BeFalse())

_, err = step.Do(ctx)

g.Expect(err).To(g.MatchError(errors.ErrParentIfaceRequired))
}

func TestNewNetworkInterface_fillChangedStatus(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

g.RegisterTestingT(t)

vmid, _ := models.NewVMID(vmName, nsName)
iface, status := fullNetworkInterface()
iface.Type = models.IfaceTypeMacvtap
svc := mock.NewMockNetworkService(mockCtrl)
ctx := context.Background()

step := network.NewNetworkInterface(vmid, iface, status, svc)

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedMacvtapDeviceName)).
Return(true, nil).
Times(1)

svc.EXPECT().
IfaceDetails(gomock.Eq(ctx), gomock.Eq(expectedMacvtapDeviceName)).
Return(&ports.IfaceDetails{
DeviceName: expectedMacvtapDeviceName,
Type: models.IfaceTypeMacvtap,
MAC: reverseMACAddress,
Index: 0,
}, nil).
Times(1)

_, err := step.Do(ctx)

g.Expect(err).To(g.BeNil())
g.Expect(status.MACAddress).To(g.Equal(reverseMACAddress))
g.Expect(status.HostDeviceName).To(g.Equal(expectedMacvtapDeviceName))
}

func TestNewNetworkInterface_createError(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

g.RegisterTestingT(t)

vmid, _ := models.NewVMID(vmName, nsName)
status := &models.NetworkInterfaceStatus{}
iface := &models.NetworkInterface{GuestDeviceName: defaultEthDevice}
svc := mock.NewMockNetworkService(mockCtrl)
ctx := context.Background()

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Times(0)

step := network.NewNetworkInterface(vmid, iface, status, svc)
shouldDo, err := step.ShouldDo(ctx)

g.Expect(err).To(g.BeNil())
g.Expect(shouldDo).To(g.BeTrue())

svc.EXPECT().
IfaceExists(gomock.Eq(ctx), gomock.Eq(expectedTapDeviceName)).
Return(false, nil).
Times(1)

svc.EXPECT().
IfaceCreate(gomock.Eq(ctx), gomock.Eq(ports.IfaceCreateInput{
DeviceName: expectedTapDeviceName,
})).
Return(nil, errors.ErrParentIfaceRequired).
Times(1)

_, err = step.Do(ctx)

g.Expect(err).To(g.MatchError(errors.ErrParentIfaceRequired))
}
Loading

0 comments on commit 87bc452

Please sign in to comment.