Skip to content
This repository was archived by the owner on May 3, 2022. It is now read-only.

Commit 0409d75

Browse files
committed
Test backup prepare and restore methods
1 parent 346493d commit 0409d75

File tree

5 files changed

+795
-89
lines changed

5 files changed

+795
-89
lines changed

cmd/shipperctl/cmd/backup/prepare.go

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

88
"github.com/spf13/cobra"
99
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/client-go/kubernetes"
1011

1112
"github.com/bookingcom/shipper/cmd/shipperctl/configurator"
1213
"github.com/bookingcom/shipper/cmd/shipperctl/release"
1314
"github.com/bookingcom/shipper/cmd/shipperctl/ui"
15+
shipperclientset "github.com/bookingcom/shipper/pkg/client/clientset/versioned"
1416
)
1517

1618
var (
@@ -38,10 +40,43 @@ func runPrepareCommand(cmd *cobra.Command, args []string) error {
3840
return err
3941
}
4042

41-
namespaceList, err := kubeClient.CoreV1().Namespaces().List(metav1.ListOptions{})
43+
shipperBackupApplications, err := buildShipperBackupApplication(kubeClient, shipperClient)
44+
if err != nil {
45+
confirm, err := ui.AskForConfirmation(
46+
cmd.InOrStdin(),
47+
fmt.Sprintf(
48+
"%s\nContinue anyway?",
49+
err.Error(),
50+
),
51+
)
52+
if err != nil {
53+
return err
54+
}
55+
if !confirm {
56+
return fmt.Errorf(err.Error())
57+
}
58+
}
59+
60+
if verboseFlag {
61+
printShipperBackupApplication(shipperBackupApplications)
62+
}
63+
data, err := marshalShipperBackupApplication(shipperBackupApplications)
4264
if err != nil {
4365
return err
4466
}
67+
if err := ioutil.WriteFile(backupFile, data, 0644); err != nil {
68+
return err
69+
}
70+
71+
cmd.Printf("Backup objects stored in %q\n", backupFile)
72+
return nil
73+
}
74+
75+
func buildShipperBackupApplication(kubeClient kubernetes.Interface, shipperClient shipperclientset.Interface) ([]shipperBackupApplication, error) {
76+
namespaceList, err := kubeClient.CoreV1().Namespaces().List(metav1.ListOptions{})
77+
if err != nil {
78+
return nil, err
79+
}
4580
var errList []string
4681

4782
shipperBackupApplications := []shipperBackupApplication{}
@@ -82,32 +117,7 @@ func runPrepareCommand(cmd *cobra.Command, args []string) error {
82117
}
83118
}
84119
if len(errList) > 0 {
85-
confirm, err := ui.AskForConfirmation(
86-
cmd.InOrStdin(),
87-
fmt.Sprintf(
88-
"Failed to retrieve some objects:\n - %s\n\nContinue anyway?",
89-
strings.Join(errList, "\n - "),
90-
),
91-
)
92-
if err != nil {
93-
return err
94-
}
95-
if !confirm {
96-
return fmt.Errorf(strings.Join(errList, ", "))
97-
}
120+
return nil, fmt.Errorf("Failed to retrieve some objects:\n - %s\n", strings.Join(errList, "\n - "))
98121
}
99-
100-
if verboseFlag {
101-
printShipperBackupApplication(shipperBackupApplications)
102-
}
103-
data, err := marshalShipperBackupApplication(shipperBackupApplications)
104-
if err != nil {
105-
return err
106-
}
107-
if err := ioutil.WriteFile(backupFile, data, 0644); err != nil {
108-
return err
109-
}
110-
111-
fmt.Printf("Backup objects stored in %q\n", backupFile)
112-
return nil
122+
return shipperBackupApplications, nil
113123
}
Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
package backup
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
"testing"
7+
"time"
8+
9+
corev1 "k8s.io/api/core/v1"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
kubefake "k8s.io/client-go/kubernetes/fake"
12+
13+
shipper "github.com/bookingcom/shipper/pkg/apis/shipper/v1alpha1"
14+
shipperfake "github.com/bookingcom/shipper/pkg/client/clientset/versioned/fake"
15+
shippertesting "github.com/bookingcom/shipper/pkg/testing"
16+
)
17+
18+
func TestBuildShipperBackupApplication(t *testing.T) {
19+
application := shipper.Application{
20+
ObjectMeta: metav1.ObjectMeta{
21+
Name: testAppName,
22+
Namespace: testNamespaceName,
23+
UID: appUid,
24+
},
25+
Spec: shipper.ApplicationSpec{
26+
RevisionHistoryLimit: nil,
27+
Template: shipper.ReleaseEnvironment{
28+
Chart: shipper.Chart{
29+
Name: "",
30+
Version: "",
31+
RepoURL: "",
32+
},
33+
Values: nil,
34+
ClusterRequirements: shipper.ClusterRequirements{
35+
Regions: nil,
36+
Capabilities: nil,
37+
},
38+
},
39+
},
40+
Status: shipper.ApplicationStatus{},
41+
}
42+
release := shipper.Release{
43+
ObjectMeta: metav1.ObjectMeta{
44+
45+
Name: testRelName,
46+
Namespace: testNamespaceName,
47+
UID: relUid,
48+
OwnerReferences: []metav1.OwnerReference{
49+
{
50+
APIVersion: "",
51+
Kind: "",
52+
Name: "",
53+
UID: appUid,
54+
},
55+
},
56+
Labels: map[string]string{
57+
shipper.AppLabel: testAppName,
58+
},
59+
},
60+
Spec: shipper.ReleaseSpec{
61+
TargetStep: 0,
62+
Environment: shipper.ReleaseEnvironment{
63+
Chart: shipper.Chart{
64+
Name: "",
65+
Version: "",
66+
RepoURL: "",
67+
},
68+
Values: nil,
69+
ClusterRequirements: shipper.ClusterRequirements{
70+
Regions: nil,
71+
Capabilities: nil,
72+
},
73+
},
74+
},
75+
Status: shipper.ReleaseStatus{},
76+
}
77+
installationTarget := shipper.InstallationTarget{
78+
ObjectMeta: metav1.ObjectMeta{
79+
80+
Name: testRelName,
81+
Namespace: testNamespaceName,
82+
OwnerReferences: []metav1.OwnerReference{
83+
{
84+
APIVersion: "",
85+
Kind: "",
86+
Name: "",
87+
UID: relUid,
88+
},
89+
},
90+
Labels: map[string]string{
91+
shipper.ReleaseLabel: testRelName,
92+
},
93+
},
94+
Spec: shipper.InstallationTargetSpec{
95+
Clusters: nil,
96+
CanOverride: false,
97+
Chart: nil,
98+
},
99+
Status: shipper.InstallationTargetStatus{},
100+
}
101+
trafficTarget := shipper.TrafficTarget{
102+
ObjectMeta: metav1.ObjectMeta{
103+
104+
Name: testRelName,
105+
Namespace: testNamespaceName,
106+
OwnerReferences: []metav1.OwnerReference{
107+
{
108+
APIVersion: "",
109+
Kind: "",
110+
Name: "",
111+
UID: relUid,
112+
},
113+
},
114+
Labels: map[string]string{
115+
shipper.ReleaseLabel: testRelName,
116+
},
117+
},
118+
Spec: shipper.TrafficTargetSpec{
119+
Clusters: nil,
120+
},
121+
Status: shipper.TrafficTargetStatus{},
122+
}
123+
capacityTarget := shipper.CapacityTarget{
124+
ObjectMeta: metav1.ObjectMeta{
125+
CreationTimestamp: metav1.Time{
126+
Time: time.Time{},
127+
},
128+
Name: testRelName,
129+
Namespace: testNamespaceName,
130+
OwnerReferences: []metav1.OwnerReference{
131+
{
132+
APIVersion: "",
133+
Kind: "",
134+
Name: "",
135+
UID: relUid,
136+
},
137+
},
138+
Labels: map[string]string{
139+
shipper.ReleaseLabel: testRelName,
140+
},
141+
},
142+
Spec: shipper.CapacityTargetSpec{
143+
Clusters: nil,
144+
},
145+
Status: shipper.CapacityTargetStatus{},
146+
}
147+
148+
tests := []struct {
149+
Name string
150+
ExpectedBackup []shipperBackupApplication
151+
ExpectedError error
152+
PreTest func() (*shipperfake.Clientset, *kubefake.Clientset, error)
153+
}{
154+
{
155+
Name: "One application with one release tree",
156+
ExpectedBackup: []shipperBackupApplication{
157+
{
158+
Application: application,
159+
BackupReleases: []shipperBackupRelease{
160+
{
161+
Release: release,
162+
InstallationTarget: installationTarget,
163+
TrafficTarget: trafficTarget,
164+
CapacityTarget: capacityTarget,
165+
},
166+
},
167+
},
168+
},
169+
ExpectedError: nil,
170+
PreTest: func() (*shipperfake.Clientset, *kubefake.Clientset, error) {
171+
shipperfakeClient := shipperfake.NewSimpleClientset()
172+
kubefakeClient := kubefake.NewSimpleClientset()
173+
namespace := corev1.Namespace{
174+
ObjectMeta: metav1.ObjectMeta{
175+
Name: testNamespaceName,
176+
},
177+
}
178+
if _, err := kubefakeClient.CoreV1().Namespaces().Create(&namespace); err != nil {
179+
return nil, nil, err
180+
}
181+
if _, err := shipperfakeClient.ShipperV1alpha1().Applications(testNamespaceName).Create(&application); err != nil {
182+
return nil, nil, err
183+
}
184+
if _, err := shipperfakeClient.ShipperV1alpha1().Releases(testNamespaceName).Create(&release); err != nil {
185+
return nil, nil, err
186+
}
187+
if _, err := shipperfakeClient.ShipperV1alpha1().InstallationTargets(testNamespaceName).Create(&installationTarget); err != nil {
188+
return nil, nil, err
189+
}
190+
if _, err := shipperfakeClient.ShipperV1alpha1().TrafficTargets(testNamespaceName).Create(&trafficTarget); err != nil {
191+
return nil, nil, err
192+
}
193+
if _, err := shipperfakeClient.ShipperV1alpha1().CapacityTargets(testNamespaceName).Create(&capacityTarget); err != nil {
194+
return nil, nil, err
195+
}
196+
197+
return shipperfakeClient, kubefakeClient, nil
198+
},
199+
},
200+
{
201+
Name: "One application with release and missing target objects",
202+
ExpectedBackup: nil,
203+
ExpectedError: fmt.Errorf(
204+
"Failed to retrieve some objects:\n - expected 1 shipper.booking.com/v1alpha1, Kind=%s for selector \"%s=%s\", got %d instead\n",
205+
"InstallationTarget",
206+
shipper.ReleaseLabel,
207+
testRelName,
208+
0,
209+
),
210+
PreTest: func() (*shipperfake.Clientset, *kubefake.Clientset, error) {
211+
shipperfakeClient := shipperfake.NewSimpleClientset()
212+
kubefakeClient := kubefake.NewSimpleClientset()
213+
namespace := corev1.Namespace{
214+
ObjectMeta: metav1.ObjectMeta{
215+
Name: testNamespaceName,
216+
},
217+
}
218+
if _, err := kubefakeClient.CoreV1().Namespaces().Create(&namespace); err != nil {
219+
return nil, nil, err
220+
}
221+
if _, err := shipperfakeClient.ShipperV1alpha1().Applications(testNamespaceName).Create(&application); err != nil {
222+
return nil, nil, err
223+
}
224+
if _, err := shipperfakeClient.ShipperV1alpha1().Releases(testNamespaceName).Create(&release); err != nil {
225+
return nil, nil, err
226+
}
227+
228+
return shipperfakeClient, kubefakeClient, nil
229+
},
230+
},
231+
{
232+
Name: "One application with no release or target objects",
233+
ExpectedBackup: []shipperBackupApplication{
234+
{
235+
Application: application,
236+
BackupReleases: []shipperBackupRelease{},
237+
},
238+
},
239+
ExpectedError: nil,
240+
PreTest: func() (*shipperfake.Clientset, *kubefake.Clientset, error) {
241+
shipperfakeClient := shipperfake.NewSimpleClientset()
242+
kubefakeClient := kubefake.NewSimpleClientset()
243+
namespace := corev1.Namespace{
244+
ObjectMeta: metav1.ObjectMeta{
245+
Name: testNamespaceName,
246+
},
247+
}
248+
if _, err := kubefakeClient.CoreV1().Namespaces().Create(&namespace); err != nil {
249+
return nil, nil, err
250+
}
251+
if _, err := shipperfakeClient.ShipperV1alpha1().Applications(testNamespaceName).Create(&application); err != nil {
252+
return nil, nil, err
253+
}
254+
255+
return shipperfakeClient, kubefakeClient, nil
256+
},
257+
},
258+
}
259+
260+
for _, test := range tests {
261+
t.Run(test.Name, func(t *testing.T) {
262+
shipperFakeClient, kubefakeClient, err := test.PreTest()
263+
if err != nil {
264+
t.Fatalf("unexpected error \n%v", err)
265+
}
266+
actualBackup, actualErr := buildShipperBackupApplication(kubefakeClient, shipperFakeClient)
267+
if !reflect.DeepEqual(actualErr, test.ExpectedError) {
268+
t.Fatalf("expected error \n%v\ngot error \n%v", test.ExpectedError, actualErr)
269+
}
270+
eq, diff := shippertesting.DeepEqualDiff(actualBackup, test.ExpectedBackup)
271+
if !eq {
272+
t.Fatalf("backup differ from expected:\n%s", diff)
273+
}
274+
})
275+
}
276+
}

0 commit comments

Comments
 (0)