Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve UT coverage #264

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions internal/criapi/criapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
"k8s.io/cri-api/pkg/apis/runtime/v1"
v1 "k8s.io/cri-api/pkg/apis/runtime/v1"
)

// Client represents the client grpc connection to the ContainerRuntimerInterface
Expand All @@ -46,13 +46,19 @@ var CRIMaxConnectionRetry = 3
// CRINewClientTimeout is the timeout for making a new client.
var CRINewClientTimeout = 90 * time.Second

var (
getGrpcDialContext = func(ctx context.Context, target string, opts ...grpc.DialOption) (conn *grpc.ClientConn, err error) {
return grpc.DialContext(ctx, target, opts...)
}
)

// NewCRIClient returns a new client connection to the ContainerRuntimeInterface or an error
func NewCRIClient(criSock string, _ ...grpc.DialOption) (*Client, error) {
var err error
ctx, cancel := context.WithTimeout(context.Background(), CRINewClientTimeout)
defer cancel()
for i := 0; i < CRIMaxConnectionRetry; i++ {
CRIClient.CRIConn, err = grpc.DialContext(ctx, criSock, grpc.WithInsecure())
CRIClient.CRIConn, err = getGrpcDialContext(ctx, criSock, grpc.WithInsecure())
if err != nil || CRIClient.CRIConn == nil {
var errMsg string
if err == nil {
Expand Down
235 changes: 207 additions & 28 deletions internal/criapi/criapi_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//go:build k8s
// +build k8s

/*
* Copyright (c) 2021-2022 Dell Inc., or its subsidiaries. All Rights Reserved.
*
Expand All @@ -21,41 +18,223 @@ package criapi

import (
"context"
"fmt"
"errors"
"reflect"
"testing"
"time"

"google.golang.org/grpc"
v1 "k8s.io/cri-api/pkg/apis/runtime/v1"
)

func TestListContainers(t *testing.T) {
client, err := NewCRIClient("unix:/var/run/dockershim.sock")
if err != nil {
t.Errorf("NewCRIClient: %s", err)
func TestNewCRIClient(t *testing.T) {
tests := []struct {
name string
criSock string
wantErr bool
}{
{
name: "Valid connection",
criSock: "unix:///var/run/dockershim.sock",
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := NewCRIClient(tt.criSock)
if (err != nil) != tt.wantErr {
t.Errorf("NewCRIClient() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestNewCRIClient_withMocking(t *testing.T) {
copyGetGrpcDialContext := getGrpcDialContext
copyCRIClientDialRetry := CRIClientDialRetry
getGrpcDialContext = func(ctx context.Context, target string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
return nil, nil
}
CRIClientDialRetry = 1 * time.Second

defer func() {
getGrpcDialContext = copyGetGrpcDialContext
CRIClientDialRetry = copyCRIClientDialRetry
}()

tests := []struct {
name string
criSock string
wantErr bool
}{
{
name: "Valid connection",
criSock: "unix:///var/run/dockershim.sock",
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := NewCRIClient(tt.criSock)
if (err != nil) != tt.wantErr {
t.Errorf("NewCRIClient() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestClient_Connected(t *testing.T) {
tests := []struct {
name string
criConn *grpc.ClientConn
want bool
}{
{
name: "CRIConn is nil",
criConn: nil,
want: false,
},
{
name: "CRIConn is not nil",
criConn: &grpc.ClientConn{},
want: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cri := &Client{
CRIConn: tt.criConn,
}
if got := cri.Connected(); got != tt.want {
t.Errorf("Connected() = %v, want %v", got, tt.want)
}
})
}
req := &v1.ListContainersRequest{}
rep, err := client.ListContainers(context.Background(), req)
if err != nil {
t.Errorf("ListContainers: %s", err)
} else {
for _, cont := range rep.Containers {
fmt.Printf("container Id %s Name %s State %s\n", cont.Id, cont.Metadata.Name, cont.State)
}
}

func TestClient_Close(t *testing.T) {
tests := []struct {
name string
criConn *grpc.ClientConn
expectedError error
}{
{
name: "CRIConn is nil",
criConn: nil,
expectedError: nil,
},
}
err = client.Close()
if err != nil {
t.Errorf("Close: %s", err)

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cri := &Client{
CRIConn: tt.criConn,
}
if got := cri.Close(); got != tt.expectedError {
t.Errorf("Close() = %v, want %v", got, tt.expectedError)
}
})
}
}

func TestGetContainerInfo(t *testing.T) {
infoMap, err := CRIClient.GetContainerInfo(context.Background())
if err != nil {
t.Errorf("GetContainerInfo failed: %s", err)
func TestClient_ListContainers(t *testing.T) {
tests := []struct {
name string
criConn *grpc.ClientConn
expectedError error
expectedRep *v1.ListContainersResponse
}{
{
name: "CRIConn is nil",
criConn: nil,
expectedError: errors.New("CRIConn is nil"),
expectedRep: nil,
},
}
for key, value := range infoMap {
if key != value.ID {
t.Error("key != value.ID")
}
fmt.Printf("ContainerInfo %+v\n", *value)

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cri := &Client{
CRIConn: tt.criConn,
}
ctx := context.Background()
req := &v1.ListContainersRequest{}
rep, err := cri.ListContainers(ctx, req)
if (err != nil) != (tt.expectedError != nil) {
t.Errorf("ListContainers() error = %v, expectedError %v", err, tt.expectedError)
return
}
if !reflect.DeepEqual(rep, tt.expectedRep) {
t.Errorf("ListContainers() = %v, want %v", rep, tt.expectedRep)
}
})
}
}

func TestClient_ChooseCRIPath(t *testing.T) {
tests := []struct {
name string
criConn *grpc.ClientConn
expectedPath string
expectedError error
}{
{
name: "CRIConn is nil",
criConn: nil,
expectedPath: "",
expectedError: errors.New("Could not find path for CRI runtime from knownPaths"),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cri := &Client{
CRIConn: tt.criConn,
}
path, err := cri.ChooseCRIPath()
if (err != nil) != (tt.expectedError != nil) {
t.Errorf("ChooseCRIPath() error = %v, expectedError %v", err, tt.expectedError)
return
}
if path != tt.expectedPath {
t.Errorf("ChooseCRIPath() = %v, want %v", path, tt.expectedPath)
}
})
}
}

func TestClient_GetContainerInfo(t *testing.T) {
tests := []struct {
name string
criConn *grpc.ClientConn
expectedError error
expectedRep map[string]*ContainerInfo
}{
{
name: "CRIConn is not nil",
criConn: &grpc.ClientConn{},
expectedError: errors.New("Could not find path for CRI runtime from knownPaths"),
expectedRep: map[string]*ContainerInfo{},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cri := &Client{
CRIConn: tt.criConn,
}
ctx := context.Background()
rep, err := cri.GetContainerInfo(ctx)
if (err != nil) != (tt.expectedError != nil) {
t.Errorf("GetContainerInfo() error = %v, expectedError %v", err, tt.expectedError)
return
}
if !reflect.DeepEqual(rep, tt.expectedRep) {
t.Errorf("GetContainerInfo() = %v, want %v", rep, tt.expectedRep)
}
})
}
}
8 changes: 7 additions & 1 deletion internal/csiapi/csi.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,18 @@ var CSIClient Client
// CSIClientDialRetry is timeout after failure to connect to the CSI Driver
var CSIClientDialRetry = 30 * time.Second

var (
getGrpcDialContext = func(ctx context.Context, target string, opts ...grpc.DialOption) (conn *grpc.ClientConn, err error) {
return grpc.DialContext(ctx, target, opts...)
}
)

// NewCSIClient returns a new CSIApi interface
func NewCSIClient(csiSock string, clientOpts ...grpc.DialOption) (CSIApi, error) {
var err error
for {
// Wait on the driver. It will not open its unix socket until it has become leader.
CSIClient.DriverConn, err = grpc.DialContext(context.Background(), csiSock, clientOpts...)
CSIClient.DriverConn, err = getGrpcDialContext(context.Background(), csiSock, clientOpts...)
log.Debugf("grpc.Dial returned %v %v", CSIClient.DriverConn, err)
if err != nil || CSIClient.DriverConn == nil {
var errMsg string
Expand Down
Loading
Loading