...

Source file src/edge-infra.dev/test/e2e/datasync/cloudtoedge/couchdb_creation_deletion_test.go

Documentation: edge-infra.dev/test/e2e/datasync/cloudtoedge

     1  package cloudtoedge
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strings"
     7  	"testing"
     8  
     9  	"cloud.google.com/go/pubsub"
    10  
    11  	dsapi "edge-infra.dev/pkg/edge/datasync/apis/v1alpha1"
    12  	"edge-infra.dev/pkg/edge/datasync/couchdb"
    13  	"edge-infra.dev/pkg/k8s/testing/kmp"
    14  	"edge-infra.dev/test/f2"
    15  	"edge-infra.dev/test/f2/x/ktest"
    16  
    17  	"gotest.tools/v3/assert"
    18  	"gotest.tools/v3/assert/cmp"
    19  	"gotest.tools/v3/poll"
    20  
    21  	corev1 "k8s.io/api/core/v1"
    22  	"sigs.k8s.io/controller-runtime/pkg/client"
    23  )
    24  
    25  func TestDBCreationAndDeletion(t *testing.T) {
    26  	feature := f2.NewFeature("Datasync DB Creation And Deletion").
    27  		Test("Create New Database", func(ctx f2.Context, t *testing.T) f2.Context {
    28  			result := pubSubClient.Topic(pubSubTopic).Publish(ctx, &pubsub.Message{
    29  				Attributes: map[string]string{
    30  					"tenant_id":   bslInfo.OrganizationID,
    31  					"db_name":     fmt.Sprintf("db-%s", ctx.RunID),
    32  					"entity_id":   ctx.RunID,
    33  					"entity_type": "json",
    34  				},
    35  				Data: tlog,
    36  			})
    37  			msgID, err := result.Get(ctx)
    38  			assert.NilError(t, err, "fail to send C2E message to pub/sub")
    39  			t.Log("Sent pub/sub message Id:", msgID)
    40  			return ctx
    41  		}).
    42  		Test("Verify DB Exists In The Cloud", func(ctx f2.Context, t *testing.T) f2.Context {
    43  			k := ktest.FromContextT(ctx, t)
    44  			secret := corev1.Secret{}
    45  			key := client.ObjectKey{Namespace: "couchctl", Name: couchdb.StoreReplicationSecretName}
    46  			err := k.Client.Get(ctx, key, &secret)
    47  			assert.NilError(t, err, "fail to get couchdb master secret")
    48  
    49  			req, err := couchDBRequest(secret, string(secret.Data["uri"]),
    50  				fmt.Sprintf("db-%s", ctx.RunID), ctx.RunID)
    51  			assert.NilError(t, err, "fail to create couchdb request")
    52  
    53  			var resp *http.Response
    54  			poll.WaitOn(t, func(_ poll.LogT) poll.Result {
    55  				resp, err = http.DefaultClient.Do(req)
    56  				if err == nil && resp.StatusCode == 200 {
    57  					return poll.Success()
    58  				}
    59  				return poll.Continue("fail to confirm existence of docs from couchdb master: %s",
    60  					errMessage(resp, req, err))
    61  			}, poll.WithDelay(k.Tick), poll.WithTimeout(k.Timeout*timeoutMultiplier))
    62  			return ctx
    63  		}).
    64  		Test("Verify Replication Is Successful", func(ctx f2.Context, t *testing.T) f2.Context {
    65  			k := ktest.FromContextT(ctx, t)
    66  			replications := dsapi.CouchDBReplicationSetList{}
    67  			err := k.Client.List(ctx, &replications, client.InNamespace(couchNamespace))
    68  			assert.NilError(t, err, "fail to list couchdb replications")
    69  			assert.Check(t, cmp.Len(replications.Items, len(nodes.Items)),
    70  				"number of couchdb replications not equal to number of nodes")
    71  
    72  			for _, replication := range replications.Items {
    73  				repl := replication
    74  				k.WaitOn(t, k.Check(&repl, kmp.IsReady()))
    75  			}
    76  			return ctx
    77  		}).
    78  		Test("Verify Message In CouchDB Store", func(ctx f2.Context, t *testing.T) f2.Context {
    79  			k := ktest.FromContextT(ctx, t)
    80  			secret := corev1.Secret{}
    81  			key := client.ObjectKey{Namespace: couchNamespace, Name: couchdb.StoreSecretName}
    82  
    83  			err := k.Client.Get(ctx, key, &secret)
    84  			assert.NilError(t, err, "fail to get couchdb store secret")
    85  
    86  			servers := dsapi.CouchDBServerList{}
    87  			assert.NilError(t, k.Client.List(ctx, &servers), "fail to list couchdb servers")
    88  
    89  			for _, server := range servers.Items {
    90  				pod := strings.Split(server.Spec.URI, ".")[0]
    91  				portForward := portMapping[pod]
    92  				addr := portForward.Retrieve(t)
    93  				req, err := couchDBRequest(secret, fmt.Sprintf("http://%s", addr),
    94  					fmt.Sprintf("db-%s", ctx.RunID), ctx.RunID)
    95  				assert.NilError(t, err, "fail to create couchdb request")
    96  
    97  				var resp *http.Response
    98  				poll.WaitOn(t, func(_ poll.LogT) poll.Result {
    99  					resp, err = http.DefaultClient.Do(req)
   100  					if err == nil && resp.StatusCode == 200 {
   101  						return poll.Success()
   102  					}
   103  					return poll.Continue("fail to get new db doc from couchdb Store: %s", errMessage(resp, req, err))
   104  				}, poll.WithDelay(k.Tick), poll.WithTimeout(k.Timeout*timeoutMultiplier))
   105  			}
   106  			return ctx
   107  		}).
   108  		Test("Delete Created Database", func(ctx f2.Context, t *testing.T) f2.Context {
   109  			result := pubSubClient.Topic(pubSubTopic).Publish(ctx, &pubsub.Message{
   110  				Attributes: map[string]string{
   111  					"tenant_id":   bslInfo.OrganizationID,
   112  					"db_name":     fmt.Sprintf("db-%s", ctx.RunID),
   113  					"entity_id":   couchdb.AllDocs,
   114  					"deleted":     "true",
   115  					"entity_type": "json",
   116  				},
   117  			})
   118  			msgID, err := result.Get(ctx)
   119  			assert.NilError(t, err, "fail to send delete message to pub/sub")
   120  			t.Log("Sent pub/sub message Id:", msgID)
   121  			return ctx
   122  		}).
   123  		Test("Verify DB Does Not Exists In The Cloud", func(ctx f2.Context, t *testing.T) f2.Context {
   124  			k := ktest.FromContextT(ctx, t)
   125  			secret := corev1.Secret{}
   126  			key := client.ObjectKey{Namespace: "couchctl", Name: couchdb.StoreReplicationSecretName}
   127  			err := k.Client.Get(ctx, key, &secret)
   128  			assert.NilError(t, err, "fail to get couchdb master secret")
   129  
   130  			req, err := couchDBRequest(secret, string(secret.Data["uri"]), fmt.Sprintf("db-%s", ctx.RunID), ctx.RunID)
   131  			assert.NilError(t, err, "fail to create couchdb request")
   132  
   133  			var resp *http.Response
   134  			poll.WaitOn(t, func(_ poll.LogT) poll.Result {
   135  				resp, err = http.DefaultClient.Do(req)
   136  				if is404(resp) {
   137  					return poll.Success()
   138  				}
   139  				return poll.Continue("fail to confirm doc deletion from couchdb master: %s", errMessage(resp, req, err))
   140  			}, poll.WithDelay(k.Tick), poll.WithTimeout(k.Timeout*timeoutMultiplier))
   141  			return ctx
   142  		}).
   143  		Test("Verify Replication Is Successful", func(ctx f2.Context, t *testing.T) f2.Context {
   144  			k := ktest.FromContextT(ctx, t)
   145  			replications := dsapi.CouchDBReplicationSetList{}
   146  			err := k.Client.List(ctx, &replications, client.InNamespace(couchNamespace))
   147  			assert.NilError(t, err, "fail to list couchdb replications")
   148  			assert.Check(t, cmp.Len(replications.Items, len(nodes.Items)),
   149  				"number of couchdb replications not equal to number of nodes")
   150  
   151  			for _, replication := range replications.Items {
   152  				repl := replication
   153  				k.WaitOn(t, k.Check(&repl, kmp.IsReady()))
   154  			}
   155  			return ctx
   156  		}).
   157  		Test("Verify DB Does Not Exists In The Store", func(ctx f2.Context, t *testing.T) f2.Context {
   158  			k := ktest.FromContextT(ctx, t)
   159  			secret := corev1.Secret{}
   160  			key := client.ObjectKey{Namespace: couchNamespace, Name: couchdb.StoreSecretName}
   161  
   162  			err := k.Client.Get(ctx, key, &secret)
   163  			assert.NilError(t, err, "fail to get couchdb store secret")
   164  
   165  			servers := dsapi.CouchDBServerList{}
   166  			assert.NilError(t, k.Client.List(ctx, &servers), "fail to list couchdb servers")
   167  
   168  			for _, server := range servers.Items {
   169  				pod := strings.Split(server.Spec.URI, ".")[0]
   170  				portForward := portMapping[pod]
   171  				addr := portForward.Retrieve(t)
   172  				req, err := couchDBRequest(secret, fmt.Sprintf("http://%s", addr),
   173  					fmt.Sprintf("db-%s", ctx.RunID), ctx.RunID)
   174  				assert.NilError(t, err, "fail to create couchdb request")
   175  
   176  				var resp *http.Response
   177  				poll.WaitOn(t, func(_ poll.LogT) poll.Result {
   178  					resp, err = http.DefaultClient.Do(req)
   179  					if is404(resp) {
   180  						return poll.Success()
   181  					}
   182  					return poll.Continue("fail to confirm doc deletion in couchdb store: %s", errMessage(resp, req, err))
   183  				}, poll.WithDelay(k.Tick), poll.WithTimeout(k.Timeout*timeoutMultiplier))
   184  			}
   185  
   186  			return ctx
   187  		}).
   188  		Feature()
   189  	f.Test(t, feature)
   190  }
   191  
   192  func is404(resp *http.Response) bool {
   193  	if resp != nil && resp.StatusCode == 404 {
   194  		return true
   195  	}
   196  	return false
   197  }
   198  

View as plain text