Skip to content

Commit 7338c5e

Browse files
author
Lars Maier
authored
Added test for sync in same cluster and replication of a single database. (#348)
1 parent 781be47 commit 7338c5e

File tree

2 files changed

+190
-0
lines changed

2 files changed

+190
-0
lines changed

tests/sync_test.go

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,171 @@ package tests
2525
import (
2626
"context"
2727
"fmt"
28+
"strings"
2829
"testing"
30+
"time"
31+
32+
"github.com/ghodss/yaml"
2933

3034
"github.com/dchest/uniuri"
35+
"k8s.io/api/core/v1"
36+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
37+
"k8s.io/client-go/kubernetes"
3138

3239
driver "github.com/arangodb/go-driver"
3340
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha"
3441
"github.com/arangodb/kube-arangodb/pkg/client"
42+
"github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned"
3543
"github.com/arangodb/kube-arangodb/pkg/util"
44+
"github.com/arangodb/kube-arangodb/pkg/util/constants"
45+
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
46+
"github.com/arangodb/kube-arangodb/pkg/util/retry"
3647
)
3748

49+
// deployAccessPackage unpacks the secrets from an access package and deploys them
50+
func deployAccessPackage(ap *v1.Secret, kube kubernetes.Interface) error {
51+
if allyaml, ok := ap.Data[constants.SecretAccessPackageYaml]; ok {
52+
secrets := strings.Split(string(allyaml), "---")
53+
for _, secretyaml := range secrets {
54+
var secret v1.Secret
55+
if err := yaml.Unmarshal([]byte(secretyaml), &secret); err != nil {
56+
return err
57+
}
58+
59+
if _, err := kube.Core().Secrets(ap.GetNamespace()).Create(&secret); err != nil {
60+
return err
61+
}
62+
}
63+
64+
return nil
65+
}
66+
return fmt.Errorf("Failed to read access package")
67+
}
68+
69+
// removeAccessPackage fire and forget deletes secrets related to a access package
70+
func removeAccessPackage(name, ns string, kube kubernetes.Interface) {
71+
kube.Core().Secrets(ns).Delete(name+"-auth", &metav1.DeleteOptions{})
72+
kube.Core().Secrets(ns).Delete(name+"-ca", &metav1.DeleteOptions{})
73+
}
74+
75+
// waitUntilReplicationNotFound waits until a replication resource is deleted
76+
func waitUntilReplicationNotFound(ns, name string, cli versioned.Interface) error {
77+
return retry.Retry(func() error {
78+
if _, err := cli.Replication().ArangoDeploymentReplications(ns).Get(name, metav1.GetOptions{}); k8sutil.IsNotFound(err) {
79+
return nil
80+
} else if err != nil {
81+
return err
82+
}
83+
return fmt.Errorf("Resource not yet gone")
84+
}, time.Minute)
85+
}
86+
87+
// TestSyncSameDC create two clusters and configures sync between them.
88+
// Then it creates a test collection in source and waits for it to appear in dest.
89+
func TestSyncSameDC(t *testing.T) {
90+
longOrSkip(t)
91+
img := getEnterpriseImageOrSkip(t)
92+
c := client.MustNewInCluster()
93+
kubecli := mustNewKubeClient(t)
94+
ns := getNamespace(t)
95+
96+
apname := "test-sync-sdc-a-access-package"
97+
98+
depla := newDeployment("test-sync-sdc-a-" + uniuri.NewLen(4))
99+
depla.Spec.Mode = api.NewMode(api.DeploymentModeCluster)
100+
depla.Spec.Image = util.NewString(img)
101+
depla.Spec.Sync.Enabled = util.NewBool(true)
102+
depla.Spec.Sync.ExternalAccess.Type = api.NewExternalAccessType(api.ExternalAccessTypeNone)
103+
depla.Spec.Sync.ExternalAccess.AccessPackageSecretNames = []string{apname}
104+
105+
// Create deployment
106+
_, err := c.DatabaseV1alpha().ArangoDeployments(ns).Create(depla)
107+
if err != nil {
108+
t.Fatalf("Create deployment a failed: %v", err)
109+
}
110+
// Prepare cleanup
111+
defer deferedCleanupDeployment(c, depla.GetName(), ns)
112+
113+
deplb := newDeployment("test-sync-sdc-b-" + uniuri.NewLen(4))
114+
deplb.Spec.Mode = api.NewMode(api.DeploymentModeCluster)
115+
deplb.Spec.Image = util.NewString(img)
116+
deplb.Spec.Sync.Enabled = util.NewBool(true)
117+
deplb.Spec.Sync.ExternalAccess.Type = api.NewExternalAccessType(api.ExternalAccessTypeNone)
118+
119+
// Create deployment
120+
_, err = c.DatabaseV1alpha().ArangoDeployments(ns).Create(deplb)
121+
if err != nil {
122+
t.Fatalf("Create deployment b failed: %v", err)
123+
}
124+
// Prepare cleanup
125+
defer deferedCleanupDeployment(c, deplb.GetName(), ns)
126+
127+
// Wait for deployments to be ready
128+
// Wait for access package
129+
// Deploy access package
130+
ap, err := waitUntilSecret(kubecli, apname, ns, nil, deploymentReadyTimeout)
131+
if err != nil {
132+
t.Fatalf("Failed to get access package: %v", err)
133+
}
134+
if err := deployAccessPackage(ap, kubecli); err != nil {
135+
t.Fatalf("Failed to deploy access package: %v", err)
136+
}
137+
defer removeAccessPackage(apname, ns, kubecli)
138+
139+
// Deploy Replication Resource
140+
repl := newReplication("test-sync-sdc-repl")
141+
repl.Spec.Source.DeploymentName = util.NewString(depla.GetName())
142+
repl.Spec.Source.Authentication.KeyfileSecretName = util.NewString("test-syn-sdc-a-access-package-auth")
143+
repl.Spec.Source.TLS.CASecretName = util.NewString("test-syn-sdc-a-access-package-ca")
144+
repl.Spec.Destination.DeploymentName = util.NewString(deplb.GetName())
145+
_, err = c.ReplicationV1alpha().ArangoDeploymentReplications(ns).Create(repl)
146+
if err != nil {
147+
t.Fatalf("Create replication resource failed: %v", err)
148+
}
149+
defer deferedCleanupReplication(c, repl.GetName(), ns)
150+
151+
deplaobj, err := waitUntilDeployment(c, depla.GetName(), ns, deploymentIsReady())
152+
if err != nil {
153+
t.Fatalf("Deployment A not running in time: %v", err)
154+
}
155+
156+
deplbobj, err := waitUntilDeployment(c, deplb.GetName(), ns, deploymentIsReady())
157+
if err != nil {
158+
t.Fatalf("Deployment B not running in time: %v", err)
159+
}
160+
161+
// Create a database in DC-A
162+
// Wait for database in DC-B
163+
time.Sleep(10 * time.Second)
164+
testdbname := "replicated-db"
165+
166+
ctx := context.Background()
167+
clienta := mustNewArangodDatabaseClient(ctx, kubecli, deplaobj, t, nil)
168+
if _, err := clienta.CreateDatabase(ctx, testdbname, nil); err != nil {
169+
t.Fatalf("Failed to create database in a: %v", err)
170+
}
171+
172+
clientb := mustNewArangodDatabaseClient(ctx, kubecli, deplbobj, t, nil)
173+
retry.Retry(func() error {
174+
if ok, err := clientb.DatabaseExists(ctx, testdbname); err != nil {
175+
return err
176+
} else if !ok {
177+
return fmt.Errorf("Database does not exist")
178+
}
179+
return nil
180+
}, time.Minute)
181+
182+
// Disable replication
183+
removeReplication(c, repl.GetName(), ns)
184+
if err := waitUntilReplicationNotFound(ns, repl.GetName(), c); err != nil {
185+
t.Errorf("Could not remove replication resource: %v", err)
186+
}
187+
188+
// Cleanup
189+
removeDeployment(c, deplb.GetName(), ns)
190+
removeDeployment(c, depla.GetName(), ns)
191+
}
192+
38193
// TestSyncToggleEnabled tests a normal cluster and enables sync later.
39194
// Once sync is active, it is disabled again.
40195
func TestSyncToggleEnabled(t *testing.T) {

tests/test_util.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import (
4848
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
4949

5050
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha"
51+
rapi "github.com/arangodb/kube-arangodb/pkg/apis/replication/v1alpha"
5152
"github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned"
5253
"github.com/arangodb/kube-arangodb/pkg/util"
5354
"github.com/arangodb/kube-arangodb/pkg/util/arangod"
@@ -238,6 +239,20 @@ func getNamespace(t *testing.T) string {
238239
return ns
239240
}
240241

242+
func newReplication(name string) *rapi.ArangoDeploymentReplication {
243+
repl := &rapi.ArangoDeploymentReplication{
244+
TypeMeta: metav1.TypeMeta{
245+
APIVersion: rapi.SchemeGroupVersion.String(),
246+
Kind: rapi.ArangoDeploymentReplicationResourceKind,
247+
},
248+
ObjectMeta: metav1.ObjectMeta{
249+
Name: strings.ToLower(name),
250+
},
251+
}
252+
253+
return repl
254+
}
255+
241256
// newDeployment creates a basic ArangoDeployment with configured
242257
// type, name and image.
243258
func newDeployment(name string) *api.ArangoDeployment {
@@ -549,6 +564,14 @@ func removeDeployment(cli versioned.Interface, deploymentName, ns string) error
549564
return nil
550565
}
551566

567+
// removeReplication removes a deployment
568+
func removeReplication(cli versioned.Interface, replicationName, ns string) error {
569+
if err := cli.Replication().ArangoDeploymentReplications(ns).Delete(replicationName, nil); err != nil && k8sutil.IsNotFound(err) {
570+
return maskAny(err)
571+
}
572+
return nil
573+
}
574+
552575
// deferedCleanupDeployment removes a deployment when shouldCleanDeployments return true.
553576
// This function is intended to be used in a defer statement.
554577
func deferedCleanupDeployment(cli versioned.Interface, deploymentName, ns string) error {
@@ -561,6 +584,18 @@ func deferedCleanupDeployment(cli versioned.Interface, deploymentName, ns string
561584
return nil
562585
}
563586

587+
// deferedCleanupReplication removes a replication when shouldCleanDeployments return true.
588+
// This function is intended to be used in a defer statement.
589+
func deferedCleanupReplication(cli versioned.Interface, replicationName, ns string) error {
590+
if !shouldCleanDeployments() {
591+
return nil
592+
}
593+
if err := removeReplication(cli, replicationName, ns); err != nil {
594+
return maskAny(err)
595+
}
596+
return nil
597+
}
598+
564599
// removeSecret removes a secret
565600
func removeSecret(cli kubernetes.Interface, secretName, ns string) error {
566601
if err := cli.CoreV1().Secrets(ns).Delete(secretName, nil); err != nil && k8sutil.IsNotFound(err) {

0 commit comments

Comments
 (0)