airshipctl/pkg/clusterctl/client/move_test.go
Arvinderpal Wander 3edf72eeb6 Adds support for clusterctl move of capi and bmo resources
from ephermeral to workload cluster.

Change-Id: Ib6d31282056468d5a153177dfb33ce4a55514ab3
2020-06-04 10:19:41 +00:00

345 lines
8.1 KiB
Go

/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package client
import (
"context"
"testing"
. "github.com/onsi/gomega"
bmoapis "github.com/metal3-io/baremetal-operator/pkg/apis"
bmh "github.com/metal3-io/baremetal-operator/pkg/apis/metal3/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)
var bmh1 = &bmh.BareMetalHost{
TypeMeta: metav1.TypeMeta{
APIVersion: "metal3.io/v1alpha1",
Kind: "BareMetalHost",
},
ObjectMeta: metav1.ObjectMeta{
Name: "bmh1",
Namespace: "ns1",
},
Spec: bmh.BareMetalHostSpec{
Online: false,
BootMACAddress: "00:2e:30:d7:11:19",
},
Status: bmh.BareMetalHostStatus{
HardwareProfile: "bmh1-hw-profile",
},
}
var bmh2 = &bmh.BareMetalHost{
TypeMeta: metav1.TypeMeta{
APIVersion: "metal3.io/v1alpha1",
Kind: "BareMetalHost",
},
ObjectMeta: metav1.ObjectMeta{
Name: "bmh2",
Namespace: "ns1",
},
Spec: bmh.BareMetalHostSpec{
Online: false,
BootMACAddress: "01:23:45:67:89:ab",
},
Status: bmh.BareMetalHostStatus{
HardwareProfile: "bmh2-hw-profile",
},
}
func newClientWithBMHObject() client.Client {
scheme := runtime.NewScheme()
//nolint:errcheck
bmoapis.AddToScheme(scheme)
return fake.NewFakeClientWithScheme(scheme, bmh1)
}
func newClientWithTwoBMHObjects() client.Client {
scheme := runtime.NewScheme()
//nolint:errcheck
bmoapis.AddToScheme(scheme)
return fake.NewFakeClientWithScheme(scheme, bmh1, bmh2)
}
func newClientWithNoBMHObject() client.Client {
scheme := runtime.NewScheme()
//nolint:errcheck
bmoapis.AddToScheme(scheme)
return fake.NewFakeClientWithScheme(scheme)
}
func Test_move_getBMHs(t *testing.T) {
type args struct {
c client.Client
namespace string
}
type want struct {
bmhList bmh.BareMetalHostList
}
tests := []struct {
name string
args args
wantErr bool
want want
}{
{
name: "returns a BareMetalHost object",
args: args{
c: newClientWithBMHObject(),
namespace: "ns1",
},
wantErr: false,
want: want{
bmhList: bmh.BareMetalHostList{
Items: []bmh.BareMetalHost{*bmh1},
},
},
},
{
name: "returns multiple BareMetalHost object",
args: args{
c: newClientWithTwoBMHObjects(),
namespace: "ns1",
},
wantErr: false,
want: want{
bmhList: bmh.BareMetalHostList{
Items: []bmh.BareMetalHost{*bmh1, *bmh2},
},
},
},
{
name: "returns an empty list of BareMetalHost objects",
args: args{
c: newClientWithNoBMHObject(),
namespace: "ns2",
},
wantErr: false,
want: want{
bmhList: bmh.BareMetalHostList{},
},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
bmhList, err := getBMHs(context.TODO(), tt.args.c, tt.args.namespace)
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
return
}
g.Expect(err).NotTo(HaveOccurred())
g.Expect(len(bmhList.Items)).To(BeEquivalentTo(len(tt.want.bmhList.Items)))
})
}
}
func Test_move_pauseUnpauseBMHs(t *testing.T) {
type args struct {
c client.Client
namespace string
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "pause and unpause a single BareMetalHost object",
args: args{
c: newClientWithBMHObject(),
namespace: "ns1",
},
wantErr: false,
},
{
name: "pause and unpause multiple BareMetalHost objects",
args: args{
c: newClientWithTwoBMHObjects(),
namespace: "ns1",
},
wantErr: false,
},
{
name: "pause and unpause should do nothing when there is no BareMetalHost object present",
args: args{
c: newClientWithNoBMHObject(),
namespace: "ns2",
},
wantErr: false,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
err := pauseUnpauseBMHs(context.TODO(), tt.args.c, tt.args.namespace, true)
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
return
}
g.Expect(err).NotTo(HaveOccurred())
bmhList, err := getBMHs(context.TODO(), tt.args.c, tt.args.namespace)
g.Expect(err).NotTo(HaveOccurred())
for _, host := range bmhList.Items {
g.Expect(host.Annotations[bmh.PausedAnnotation]).To(Equal("true"))
}
err = pauseUnpauseBMHs(context.TODO(), tt.args.c, tt.args.namespace, false)
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
return
}
g.Expect(err).NotTo(HaveOccurred())
bmhList, err = getBMHs(context.TODO(), tt.args.c, tt.args.namespace)
g.Expect(err).NotTo(HaveOccurred())
for _, host := range bmhList.Items {
_, present := host.Annotations[bmh.PausedAnnotation]
g.Expect(present).To(Equal(false))
}
})
}
}
var bmh1NoStatus = &bmh.BareMetalHost{
TypeMeta: metav1.TypeMeta{
APIVersion: "metal3.io/v1alpha1",
Kind: "BareMetalHost",
},
ObjectMeta: metav1.ObjectMeta{
Name: "bmh1",
Namespace: "ns1",
},
Spec: bmh.BareMetalHostSpec{
Online: false,
BootMACAddress: "00:2e:30:d7:11:19",
},
}
var bmh2NoStatus = &bmh.BareMetalHost{
TypeMeta: metav1.TypeMeta{
APIVersion: "metal3.io/v1alpha1",
Kind: "BareMetalHost",
},
ObjectMeta: metav1.ObjectMeta{
Name: "bmh2",
Namespace: "ns1",
},
Spec: bmh.BareMetalHostSpec{
Online: false,
BootMACAddress: "01:23:45:67:89:ab",
},
}
func newClientFromCluster() client.Client {
scheme := runtime.NewScheme()
//nolint:errcheck
bmoapis.AddToScheme(scheme)
return fake.NewFakeClientWithScheme(scheme, bmh1, bmh2)
}
func newClientToCluster() client.Client {
scheme := runtime.NewScheme()
//nolint:errcheck
bmoapis.AddToScheme(scheme)
return fake.NewFakeClientWithScheme(scheme, bmh1NoStatus, bmh2NoStatus)
}
func Test_move_copyBMHStatus(t *testing.T) {
type args struct {
cFrom client.Client
cTo client.Client
namespace string
}
type want struct {
bmhList bmh.BareMetalHostList
}
tests := []struct {
name string
args args
wantErr bool
want want
}{
{
name: "copies the status field of multiple BareMetalHost objects",
args: args{
cFrom: newClientFromCluster(),
cTo: newClientToCluster(),
namespace: "ns1",
},
wantErr: false,
want: want{
bmhList: bmh.BareMetalHostList{
Items: []bmh.BareMetalHost{*bmh1, *bmh2},
},
},
},
{
name: "no copy occurs b/c no BareMetalHost objects are present",
args: args{
cFrom: newClientWithNoBMHObject(),
cTo: newClientWithNoBMHObject(),
namespace: "ns1",
},
wantErr: false,
want: want{
bmhList: bmh.BareMetalHostList{
Items: []bmh.BareMetalHost{},
},
},
},
{
name: "error should occur b/c BareMetalHost does not exist in the source cluster",
args: args{
cFrom: newClientWithNoBMHObject(),
cTo: newClientToCluster(),
namespace: "ns1",
},
wantErr: true,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
err := copyBMHStatus(context.TODO(), tt.args.cFrom, tt.args.cTo, tt.args.namespace)
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
return
}
g.Expect(err).NotTo(HaveOccurred())
bmhList, err := getBMHs(context.TODO(), tt.args.cTo, tt.args.namespace)
g.Expect(err).NotTo(HaveOccurred())
NEXTHOST:
for _, host := range bmhList.Items {
for _, wantHost := range tt.want.bmhList.Items {
if host.Name == wantHost.Name {
g.Expect(host.Status.HardwareProfile).To(Equal(wantHost.Status.HardwareProfile))
continue NEXTHOST
}
}
t.Errorf("unexpected host %s", host.Name)
}
})
}
}