Skip to content

Commit 3a807e2

Browse files
committed
mco: unit tests and runtime client for mcp list
Added unit tests and switched to the runtime client for the MCP list functions. Also adds unit tests to the remaining untested MCP functions. Now that the package is complete, removes the machineconfig client from clients.
1 parent ba89a24 commit 3a807e2

File tree

4 files changed

+387
-46
lines changed

4 files changed

+387
-46
lines changed

pkg/clients/clients.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111

1212
clientConfigV1 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
1313
v1security "github.com/openshift/client-go/security/clientset/versioned/typed/security/v1"
14-
mcv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
1514

1615
apiExt "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
1716
"k8s.io/apimachinery/pkg/runtime"
@@ -23,8 +22,6 @@ import (
2322
"k8s.io/client-go/tools/clientcmd"
2423
runtimeClient "sigs.k8s.io/controller-runtime/pkg/client"
2524

26-
clientMachineConfigV1 "github.com/openshift/machine-config-operator/pkg/generated/clientset/versioned/typed/machineconfiguration.openshift.io/v1"
27-
2825
agentInstallV1Beta1 "github.com/openshift-kni/eco-goinfra/pkg/schemes/assisted/api/v1beta1"
2926
configV1 "github.com/openshift/api/config/v1"
3027
imageregistryV1 "github.com/openshift/api/imageregistry/v1"
@@ -56,7 +53,6 @@ type Settings struct {
5653
K8sClient kubernetes.Interface
5754
coreV1Client.CoreV1Interface
5855
clientConfigV1.ConfigV1Interface
59-
clientMachineConfigV1.MachineconfigurationV1Interface
6056
networkV1Client.NetworkingV1Interface
6157
appsV1Client.AppsV1Interface
6258
rbacV1Client.RbacV1Interface
@@ -101,7 +97,6 @@ func New(kubeconfig string) *Settings {
10197
clientSet := &Settings{}
10298
clientSet.CoreV1Interface = coreV1Client.NewForConfigOrDie(config)
10399
clientSet.ConfigV1Interface = clientConfigV1.NewForConfigOrDie(config)
104-
clientSet.MachineconfigurationV1Interface = clientMachineConfigV1.NewForConfigOrDie(config)
105100
clientSet.AppsV1Interface = appsV1Client.NewForConfigOrDie(config)
106101
clientSet.NetworkingV1Interface = networkV1Client.NewForConfigOrDie(config)
107102
clientSet.RbacV1Interface = rbacV1Client.NewForConfigOrDie(config)
@@ -143,10 +138,6 @@ func SetScheme(crScheme *runtime.Scheme) error {
143138
return err
144139
}
145140

146-
if err := mcv1.AddToScheme(crScheme); err != nil {
147-
return err
148-
}
149-
150141
if err := apiExt.AddToScheme(crScheme); err != nil {
151142
return err
152143
}

pkg/mco/mcp_test.go

Lines changed: 194 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package mco
22

33
import (
4+
"context"
45
"fmt"
56
"testing"
7+
"time"
68

79
"github.com/openshift-kni/eco-goinfra/pkg/clients"
810
mcv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
@@ -14,10 +16,12 @@ import (
1416

1517
const defaultMCPName = "test-machine-config-pool"
1618

17-
var defaultMCPCondition = mcv1.MachineConfigPoolCondition{
18-
Type: mcv1.MachineConfigPoolBuildSuccess,
19-
Status: corev1.ConditionTrue,
20-
}
19+
var (
20+
updatingMCPCondition = mcv1.MachineConfigPoolCondition{
21+
Type: mcv1.MachineConfigPoolUpdating,
22+
Status: corev1.ConditionTrue,
23+
}
24+
)
2125

2226
func TestNewMCPBuilder(t *testing.T) {
2327
testCases := []struct {
@@ -265,6 +269,158 @@ func TestMachineConfigPoolWithMCSelector(t *testing.T) {
265269
}
266270
}
267271

272+
func TestMachineConfigPoolWaitToBeInCondition(t *testing.T) {
273+
testCases := []struct {
274+
exists bool
275+
valid bool
276+
hasCondition bool
277+
expectedError error
278+
}{
279+
{
280+
exists: true,
281+
valid: true,
282+
hasCondition: true,
283+
expectedError: nil,
284+
},
285+
{
286+
exists: false,
287+
valid: true,
288+
hasCondition: true,
289+
expectedError: context.DeadlineExceeded,
290+
},
291+
{
292+
exists: true,
293+
valid: false,
294+
hasCondition: true,
295+
expectedError: fmt.Errorf("machineconfigpool 'name' cannot be empty"),
296+
},
297+
{
298+
exists: true,
299+
valid: true,
300+
hasCondition: false,
301+
expectedError: context.DeadlineExceeded,
302+
},
303+
}
304+
305+
for _, testCase := range testCases {
306+
testBuilder := buildMCPBuilderWithUpdatingCondition(testCase.exists, testCase.hasCondition, testCase.valid)
307+
err := testBuilder.WaitToBeInCondition(updatingMCPCondition.Type, updatingMCPCondition.Status, time.Second)
308+
309+
assert.Equal(t, testCase.expectedError, err)
310+
}
311+
}
312+
313+
func TestMachineConfigPoolWaitForUpdate(t *testing.T) {
314+
testCases := []struct {
315+
valid bool
316+
exists bool
317+
updating bool
318+
expectedError error
319+
}{
320+
{
321+
valid: true,
322+
exists: true,
323+
updating: false,
324+
expectedError: nil,
325+
},
326+
{
327+
valid: true,
328+
exists: true,
329+
updating: true,
330+
expectedError: context.DeadlineExceeded,
331+
},
332+
{
333+
valid: false,
334+
exists: true,
335+
updating: true,
336+
expectedError: fmt.Errorf("machineconfigpool 'name' cannot be empty"),
337+
},
338+
{
339+
valid: true,
340+
exists: false,
341+
updating: true,
342+
expectedError: fmt.Errorf(
343+
"machineconfigpools.machineconfiguration.openshift.io \"test-machine-config-pool\" not found"),
344+
},
345+
}
346+
347+
for _, testCase := range testCases {
348+
testBuilder := buildMCPBuilderWithUpdatingCondition(testCase.exists, testCase.updating, testCase.valid)
349+
err := testBuilder.WaitForUpdate(time.Second)
350+
351+
if testCase.expectedError == nil {
352+
assert.Nil(t, err)
353+
} else {
354+
assert.Equal(t, testCase.expectedError.Error(), err.Error())
355+
}
356+
}
357+
}
358+
359+
func TestMachineConfigPoolWaitToBeStableFor(t *testing.T) {
360+
testCases := []struct {
361+
valid bool
362+
exists bool
363+
stable bool
364+
expectedError error
365+
}{
366+
{
367+
valid: true,
368+
exists: true,
369+
stable: true,
370+
expectedError: nil,
371+
},
372+
{
373+
valid: false,
374+
exists: true,
375+
stable: true,
376+
expectedError: fmt.Errorf("machineconfigpool 'name' cannot be empty"),
377+
},
378+
{
379+
valid: true,
380+
exists: false,
381+
stable: true,
382+
expectedError: nil,
383+
},
384+
{
385+
valid: true,
386+
exists: true,
387+
stable: false,
388+
expectedError: context.DeadlineExceeded,
389+
},
390+
}
391+
392+
for _, testCase := range testCases {
393+
var (
394+
runtimeObjects []runtime.Object
395+
testBuilder *MCPBuilder
396+
)
397+
398+
if testCase.exists {
399+
mcp := buildDummyMCP(defaultMCPName)
400+
401+
if !testCase.stable {
402+
mcp.Status.DegradedMachineCount = 1
403+
}
404+
405+
runtimeObjects = append(runtimeObjects, mcp)
406+
}
407+
408+
testSettings := clients.GetTestClients(clients.TestClientParams{
409+
K8sMockObjects: runtimeObjects,
410+
SchemeAttachers: testSchemes,
411+
})
412+
413+
if testCase.valid {
414+
testBuilder = buildValidMCPTestBuilder(testSettings)
415+
} else {
416+
testBuilder = buildInvalidMCPTestBuilder(testSettings)
417+
}
418+
419+
err := testBuilder.WaitToBeStableFor(500*time.Millisecond, time.Second)
420+
assert.Equal(t, testCase.expectedError, err)
421+
}
422+
}
423+
268424
func TestMachineConfigPoolWithOptions(t *testing.T) {
269425
testCases := []struct {
270426
testBuilder *MCPBuilder
@@ -340,33 +496,9 @@ func TestMachineConfigPoolIsInCondition(t *testing.T) {
340496
}
341497

342498
for _, testCase := range testCases {
343-
var (
344-
runtimeObjects []runtime.Object
345-
testBuilder *MCPBuilder
346-
)
347-
348-
if testCase.exists {
349-
mcp := buildDummyMCP(defaultMCPName)
350-
351-
if testCase.hasCondition {
352-
mcp.Status.Conditions = []mcv1.MachineConfigPoolCondition{defaultMCPCondition}
353-
}
354-
355-
runtimeObjects = append(runtimeObjects, mcp)
356-
}
357-
358-
testSettings := clients.GetTestClients(clients.TestClientParams{
359-
K8sMockObjects: runtimeObjects,
360-
SchemeAttachers: testSchemes,
361-
})
362-
363-
if testCase.valid {
364-
testBuilder = buildValidMCPTestBuilder(testSettings)
365-
} else {
366-
testBuilder = buildInvalidMCPTestBuilder(testSettings)
367-
}
499+
testBuilder := buildMCPBuilderWithUpdatingCondition(testCase.exists, testCase.hasCondition, testCase.valid)
500+
isInCondition := testBuilder.IsInCondition(updatingMCPCondition.Type)
368501

369-
isInCondition := testBuilder.IsInCondition(defaultMCPCondition.Type)
370502
assert.Equal(t, testCase.isInCondition, isInCondition)
371503
}
372504
}
@@ -399,3 +531,35 @@ func buildValidMCPTestBuilder(apiClient *clients.Settings) *MCPBuilder {
399531
func buildInvalidMCPTestBuilder(apiClient *clients.Settings) *MCPBuilder {
400532
return NewMCPBuilder(apiClient, "")
401533
}
534+
535+
// buildMCPBuilderWithUpdatingCondition returns an MCPBuilder for testing, with the ability to configure whether it
536+
// exists on the test client, has the updating condition, and is valid.
537+
func buildMCPBuilderWithUpdatingCondition(exists, hasCondition, valid bool) *MCPBuilder {
538+
var (
539+
runtimeObjects []runtime.Object
540+
testBuilder *MCPBuilder
541+
)
542+
543+
if exists {
544+
mcp := buildDummyMCP(defaultMCPName)
545+
546+
if hasCondition {
547+
mcp.Status.Conditions = []mcv1.MachineConfigPoolCondition{updatingMCPCondition}
548+
}
549+
550+
runtimeObjects = append(runtimeObjects, mcp)
551+
}
552+
553+
testSettings := clients.GetTestClients(clients.TestClientParams{
554+
K8sMockObjects: runtimeObjects,
555+
SchemeAttachers: testSchemes,
556+
})
557+
558+
if valid {
559+
testBuilder = buildValidMCPTestBuilder(testSettings)
560+
} else {
561+
testBuilder = buildInvalidMCPTestBuilder(testSettings)
562+
}
563+
564+
return testBuilder
565+
}

pkg/mco/mcplist.go

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,28 @@ import (
77

88
"github.com/golang/glog"
99
"github.com/openshift-kni/eco-goinfra/pkg/clients"
10+
mcv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
11+
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
1012

11-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1213
"k8s.io/apimachinery/pkg/util/wait"
1314
)
1415

1516
// ListMCP returns a list of MachineConfigPoolBuilder.
16-
func ListMCP(apiClient *clients.Settings, options ...metav1.ListOptions) ([]*MCPBuilder, error) {
17-
passedOptions := metav1.ListOptions{}
17+
func ListMCP(apiClient *clients.Settings, options ...runtimeclient.ListOptions) ([]*MCPBuilder, error) {
18+
if apiClient == nil {
19+
glog.V(100).Info("MachineConfigPool 'apiClient' can not be empty")
20+
21+
return nil, fmt.Errorf("failed to list MachineConfigPools, 'apiClient' parameter is empty")
22+
}
23+
24+
err := apiClient.AttachScheme(mcv1.Install)
25+
if err != nil {
26+
glog.V(100).Info("Failed to add machineconfig v1 scheme to client schemes")
27+
28+
return nil, err
29+
}
30+
31+
passedOptions := runtimeclient.ListOptions{}
1832
logMessage := "Listing all MCP resources"
1933

2034
if len(options) > 1 {
@@ -30,7 +44,8 @@ func ListMCP(apiClient *clients.Settings, options ...metav1.ListOptions) ([]*MCP
3044

3145
glog.V(100).Infof(logMessage)
3246

33-
mcpList, err := apiClient.MachineConfigPools().List(context.TODO(), passedOptions)
47+
mcpList := new(mcv1.MachineConfigPoolList)
48+
err = apiClient.Client.List(context.TODO(), mcpList, &passedOptions)
3449

3550
if err != nil {
3651
glog.V(100).Infof("Failed to list MCP objects due to %s", err.Error())
@@ -43,7 +58,7 @@ func ListMCP(apiClient *clients.Settings, options ...metav1.ListOptions) ([]*MCP
4358
for _, mcp := range mcpList.Items {
4459
copiedMcp := mcp
4560
mcpBuilder := &MCPBuilder{
46-
apiClient: apiClient,
61+
apiClient: apiClient.Client,
4762
Object: &copiedMcp,
4863
Definition: &copiedMcp,
4964
}
@@ -56,7 +71,7 @@ func ListMCP(apiClient *clients.Settings, options ...metav1.ListOptions) ([]*MCP
5671

5772
// ListMCPByMachineConfigSelector returns a list of MachineConfigurationPoolBuilders for given selector.
5873
func ListMCPByMachineConfigSelector(
59-
apiClient *clients.Settings, mcpLabel string, options ...metav1.ListOptions) (*MCPBuilder, error) {
74+
apiClient *clients.Settings, mcpLabel string, options ...runtimeclient.ListOptions) (*MCPBuilder, error) {
6075
glog.V(100).Infof("GetByLabel returns MachineConfigPool with the specified label: %v", mcpLabel)
6176

6277
mcpList, err := ListMCP(apiClient, options...)
@@ -66,6 +81,10 @@ func ListMCPByMachineConfigSelector(
6681
}
6782

6883
for _, mcp := range mcpList {
84+
if mcp.Object.Spec.MachineConfigSelector == nil {
85+
continue
86+
}
87+
6988
for _, label := range mcp.Object.Spec.MachineConfigSelector.MatchExpressions {
7089
for _, value := range label.Values {
7190
if value == mcpLabel {
@@ -86,7 +105,13 @@ func ListMCPByMachineConfigSelector(
86105

87106
// ListMCPWaitToBeStableFor waits for a given MachineConfigurationPool to be stable for a given period.
88107
func ListMCPWaitToBeStableFor(
89-
apiClient *clients.Settings, stableDuration, timeout time.Duration, options ...metav1.ListOptions) error {
108+
apiClient *clients.Settings, stableDuration, timeout time.Duration, options ...runtimeclient.ListOptions) error {
109+
if apiClient == nil {
110+
glog.V(100).Info("MachineConfigPool 'apiClient' can not be empty")
111+
112+
return fmt.Errorf("failed to list MachineConfigPools, 'apiClient' parameter is empty")
113+
}
114+
90115
glog.V(100).Infof("WaitForMcpListToBeStableFor waits up to duration of %v for "+
91116
"MachineConfigPoolList to be stable for %v", timeout, stableDuration)
92117

0 commit comments

Comments
 (0)