Skip to content

Commit

Permalink
add unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
alexmasi committed Jul 7, 2023
1 parent 792a2ce commit 15e7367
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 27 deletions.
15 changes: 14 additions & 1 deletion topo/topo.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,24 @@ func (m *Manager) event() *epb.Topology {
return t
}

var (
// Stubs for testing.
newMetricsReporter = func(ctx context.Context, project, topic string) (metricsReporter, error) {
return metrics.NewReporter(ctx, project, topic)
}
)

type metricsReporter interface {
ReportCreateTopologyStart(context.Context, *epb.Topology) (string, error)
ReportCreateTopologyEnd(context.Context, string, error) error
Close() error
}

// Create creates the topology in the cluster.
func (m *Manager) Create(ctx context.Context, timeout time.Duration) (rerr error) {
log.V(1).Infof("Topology:\n%v", prototext.Format(m.topo))
if m.reportUsage {
r, err := metrics.NewReporter(ctx, m.reportUsageProjectID, m.reportUsageTopicID)
r, err := newMetricsReporter(ctx, m.reportUsageProjectID, m.reportUsageTopicID)
if err != nil {
log.Warningf("Unable to create metrics reporter: %v", err)
} else {
Expand Down
121 changes: 95 additions & 26 deletions topo/topo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package topo
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"testing"
Expand All @@ -28,6 +29,7 @@ import (
tfake "github.com/networkop/meshnet-cni/api/clientset/v1beta1/fake"
topologyv1 "github.com/networkop/meshnet-cni/api/types/v1beta1"
cpb "github.com/openconfig/kne/proto/controller"
epb "github.com/openconfig/kne/proto/event"
tpb "github.com/openconfig/kne/proto/topo"
"github.com/openconfig/kne/topo/node"
"google.golang.org/protobuf/proto"
Expand Down Expand Up @@ -363,40 +365,39 @@ func TestNew(t *testing.T) {
}
}

type fakeMetricsReporter struct {
reportStartErr, reportEndErr error
}

func (f *fakeMetricsReporter) Close() error {
return nil
}

func (f *fakeMetricsReporter) ReportCreateTopologyStart(_ context.Context, _ *epb.Topology) (string, error) {
return "fake-uuid", f.reportStartErr
}

func (f *fakeMetricsReporter) ReportCreateTopologyEnd(_ context.Context, _ string, _ error) error {
return f.reportEndErr
}

func TestCreate(t *testing.T) {
ctx := context.Background()
tf, err := tfake.NewSimpleClientset()
if err != nil {
t.Fatalf("cannot create fake topology clientset: %v", err)
}
kf := kfake.NewSimpleClientset()
kf.PrependReactor("get", "pods", func(action ktest.Action) (bool, runtime.Object, error) {
gAction, ok := action.(ktest.GetAction)
if !ok {
return false, nil, nil
}
p := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: gAction.GetName()}}
switch p.Name {
default:
p.Status.Phase = corev1.PodRunning
p.Status.Conditions = []corev1.PodCondition{{Type: corev1.PodReady, Status: corev1.ConditionTrue}}
case "bad":
p.Status.Phase = corev1.PodFailed
case "hanging":
p.Status.Phase = corev1.PodPending
}
return true, p, nil
})
opts := []Option{
WithClusterConfig(&rest.Config{}),
WithKubeClient(kf),
WithTopoClient(tf),

origNewMetricsReporter := newMetricsReporter
defer func() {
newMetricsReporter = origNewMetricsReporter
}()
newMetricsReporter = func(_ context.Context, _, _ string) (metricsReporter, error) {
return &fakeMetricsReporter{reportStartErr: errors.New("start err"), reportEndErr: errors.New("end err")}, nil
}

node.Vendor(tpb.Vendor(1002), NewConfigurable)
tests := []struct {
desc string
topo *tpb.Topology
timeout time.Duration
opts []Option
wantErr string
}{{
desc: "success",
Expand Down Expand Up @@ -478,9 +479,77 @@ func TestCreate(t *testing.T) {
},
},
wantErr: `Node "bad": Status FAILED`,
}, {
desc: "failed to report metrics, create still passes",
opts: []Option{WithUsageReporting(true, "", "")},
topo: &tpb.Topology{
Name: "test",
Nodes: []*tpb.Node{
{
Name: "r1",
Vendor: tpb.Vendor(1002),
Services: map[uint32]*tpb.Service{
1000: {
Name: "ssh",
},
},
Config: &tpb.Config{},
},
{
Name: "r2",
Vendor: tpb.Vendor(1002),
Services: map[uint32]*tpb.Service{
2000: {
Name: "grpc",
},
3000: {
Name: "gnmi",
},
},
Config: &tpb.Config{},
},
},
Links: []*tpb.Link{
{
ANode: "r1",
AInt: "eth1",
ZNode: "r2",
ZInt: "eth1",
},
},
},
}}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
tf, err := tfake.NewSimpleClientset()
if err != nil {
t.Fatalf("cannot create fake topology clientset: %v", err)
}
kf := kfake.NewSimpleClientset()
kf.PrependReactor("get", "pods", func(action ktest.Action) (bool, runtime.Object, error) {
gAction, ok := action.(ktest.GetAction)
if !ok {
return false, nil, nil
}
p := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: gAction.GetName()}}
switch p.Name {
default:
p.Status.Phase = corev1.PodRunning
p.Status.Conditions = []corev1.PodCondition{{Type: corev1.PodReady, Status: corev1.ConditionTrue}}
case "bad":
p.Status.Phase = corev1.PodFailed
case "hanging":
p.Status.Phase = corev1.PodPending
}
return true, p, nil
})

opts := []Option{
WithClusterConfig(&rest.Config{}),
WithKubeClient(kf),
WithTopoClient(tf),
}
opts = append(opts, tt.opts...)
m, err := New(tt.topo, opts...)
if err != nil {
t.Fatalf("New() failed to create new topology manager: %v", err)
Expand Down

0 comments on commit 15e7367

Please sign in to comment.