forked from rook/rook
Sometimes the ci fails to find the object store user, this could be because the user is created before the object store. So first it fails since there is no object store and stay in a retry back-off. Then the object store is created and always need a bit of time, at the same time the object-user is still waiting and the next retry is longer. Creating the object store first and then the user hopefully will help resolve that so we don't have to increase the retry for the object-user presence. The error: ``` 2021-03-26T08:39:34.7283769Z 2021-03-26 08:39:34.727946 I | testutil: All 2 pod(s) with label rook_object_store=teststore are running 2021-03-26T08:39:34.7284744Z 2021-03-26 08:39:34.727972 I | testutil: Running kubectl [apply -f -] 2021-03-26T08:39:35.1110681Z service/rgw-external-teststore created 2021-03-26T08:39:35.1142392Z 2021-03-26 08:39:35.112479 I | integrationTest: Check that RGW pods are Running 2021-03-26T08:39:35.1181683Z 2021-03-26 08:39:35.117763 I | testutil: 2 of 1 pods with label app=rook-ceph-rgw were found 2021-03-26T08:39:35.1251276Z 2021-03-26 08:39:35.124933 I | testutil: 2 of 1 pods with label app=rook-ceph-rgw were found 2021-03-26T08:39:35.1348603Z 2021-03-26 08:39:35.133276 I | integrationTest: RGW pods are running 2021-03-26T08:39:35.1350090Z 2021-03-26 08:39:35.133290 I | integrationTest: Object store created successfully 2021-03-26T08:39:35.1351373Z 2021-03-26 08:39:35.133295 I | integrationTest: Waiting 5 seconds for the object user to be created 2021-03-26T08:39:40.1340659Z 2021-03-26 08:39:40.133401 I | integrationTest: Checking to see if the user secret has been created 2021-03-26T08:39:40.1342715Z 2021-03-26 08:39:40.133440 D | exec: Running command: kubectl get -n smoke-ns secrets -l rook_object_store=teststore -l user=rook-user 2021-03-26T08:39:40.2618726Z 2021-03-26 08:39:40.261412 I | clients: Unable to find user secret 2021-03-26T08:39:40.2619705Z 2021-03-26 08:39:40.261433 I | integrationTest: (0) secret check sleeping for 5 seconds ... 2021-03-26T08:39:45.2621870Z 2021-03-26 08:39:45.261641 D | exec: Running command: kubectl get -n smoke-ns secrets -l rook_object_store=teststore -l user=rook-user 2021-03-26T08:39:45.3863424Z 2021-03-26 08:39:45.386048 I | clients: Unable to find user secret 2021-03-26T08:39:45.3864586Z 2021-03-26 08:39:45.386075 I | integrationTest: (1) secret check sleeping for 5 seconds ... 2021-03-26T08:39:50.3869496Z 2021-03-26 08:39:50.386292 D | exec: Running command: kubectl get -n smoke-ns secrets -l rook_object_store=teststore -l user=rook-user 2021-03-26T08:39:50.4991166Z 2021-03-26 08:39:50.498862 I | clients: Unable to find user secret 2021-03-26T08:39:50.4991987Z 2021-03-26 08:39:50.498881 I | integrationTest: (2) secret check sleeping for 5 seconds ... 2021-03-26T08:39:55.4998176Z 2021-03-26 08:39:55.499038 D | exec: Running command: kubectl get -n smoke-ns secrets -l rook_object_store=teststore -l user=rook-user 2021-03-26T08:39:55.6075640Z 2021-03-26 08:39:55.607337 I | clients: Unable to find user secret 2021-03-26T08:39:55.6076472Z 2021-03-26 08:39:55.607355 I | integrationTest: (3) secret check sleeping for 5 seconds ... 2021-03-26T08:40:00.6080687Z 2021-03-26 08:40:00.607466 D | exec: Running command: kubectl get -n smoke-ns secrets -l rook_object_store=teststore -l user=rook-user 2021-03-26T08:40:00.8415649Z 2021-03-26 08:40:00.841309 I | clients: Unable to find user secret 2021-03-26T08:40:00.8417179Z 2021-03-26 08:40:00.841331 I | integrationTest: (4) secret check sleeping for 5 seconds ... 2021-03-26T08:40:05.8419407Z 2021-03-26 08:40:05.841385 D | exec: Running command: kubectl get -n smoke-ns secrets -l rook_object_store=teststore -l user=rook-user 2021-03-26T08:40:05.9732221Z 2021-03-26 08:40:05.972910 I | clients: Unable to find user secret 2021-03-26T08:40:05.9733777Z 2021-03-26 08:40:05.972932 I | integrationTest: (5) secret check sleeping for 5 seconds ... 2021-03-26T08:40:10.9734134Z 2021-03-26 08:40:10.973067 D | exec: Running command: kubectl get -n smoke-ns secrets -l rook_object_store=teststore -l user=rook-user 2021-03-26T08:40:11.1686581Z 2021-03-26 08:40:11.168373 I | clients: Unable to find user secret 2021-03-26T08:40:11.1687925Z ceph_base_object_test.go:87: 2021-03-26T08:40:11.1688924Z Error Trace: ceph_base_object_test.go:87 2021-03-26T08:40:11.1689961Z ceph_smoke_test.go:132 2021-03-26T08:40:11.1691113Z Error: Should be true 2021-03-26T08:40:11.1692167Z Test: TestCephSmokeSuite/TestObjectStorage_SmokeTest 2021-03-26T08:40:11.1693751Z 2021-03-26 08:40:11.168502 D | ceph-object-controller: getting s3 user "rook-user" 2021-03-26T08:40:11.1695580Z 2021-03-26 08:40:11.168514 D | exec: Running command: kubectl exec -i rook-ceph-tools-78cdfd976c-2nbp2 -n smoke-ns -- timeout 15 radosgw-admin user info --uid rook-user --rgw-realm= --rgw-zonegroup= --rgw-zone= 2021-03-26T08:40:11.6090406Z ceph_base_object_test.go:89: 2021-03-26T08:40:11.6093015Z Error Trace: ceph_base_object_test.go:89 2021-03-26T08:40:11.6093968Z ceph_smoke_test.go:132 2021-03-26T08:40:11.6095116Z Error: Received unexpected error: 2021-03-26T08:40:11.6095798Z failed to get user info: warn: s3 user not found 2021-03-26T08:40:11.6096724Z github.com/rook/rook/pkg/operator/ceph/object.GetUser 2021-03-26T08:40:11.6097795Z /home/runner/work/rook/rook/pkg/operator/ceph/object/user.go:98 2021-03-26T08:40:11.6098764Z github.com/rook/rook/tests/framework/clients.(*ObjectUserOperation).GetUser 2021-03-26T08:40:11.6099814Z /home/runner/work/rook/rook/tests/framework/clients/object_user.go:45 2021-03-26T08:40:11.6100792Z github.com/rook/rook/tests/integration.runObjectE2ETest 2021-03-26T08:40:11.6101858Z /home/runner/work/rook/rook/tests/integration/ceph_base_object_test.go:88 2021-03-26T08:40:11.6103298Z github.com/rook/rook/tests/integration.(*SmokeSuite).TestObjectStorage_SmokeTest 2021-03-26T08:40:11.6104371Z /home/runner/work/rook/rook/tests/integration/ceph_smoke_test.go:132 2021-03-26T08:40:11.6105104Z reflect.Value.call 2021-03-26T08:40:11.6105856Z /opt/hostedtoolcache/go/1.15.10/x64/src/reflect/value.go:476 2021-03-26T08:40:11.6106662Z reflect.Value.Call 2021-03-26T08:40:11.6107412Z /opt/hostedtoolcache/go/1.15.10/x64/src/reflect/value.go:337 2021-03-26T08:40:11.6108217Z github.com/stretchr/testify/suite.Run.func1 2021-03-26T08:40:11.6109104Z /home/runner/go/pkg/mod/github.com/stretchr/testify@v1.6.1/suite/suite.go:158 2021-03-26T08:40:11.6109844Z testing.tRunner 2021-03-26T08:40:11.6110578Z /opt/hostedtoolcache/go/1.15.10/x64/src/testing/testing.go:1123 2021-03-26T08:40:11.6111271Z runtime.goexit 2021-03-26T08:40:11.6112037Z /opt/hostedtoolcache/go/1.15.10/x64/src/runtime/asm_amd64.s:1374 2021-03-26T08:40:11.6112995Z Test: TestCephSmokeSuite/TestObjectStorage_SmokeTest ``` Signed-off-by: Sébastien Han <seb@redhat.com>
253 lines
10 KiB
Go
253 lines
10 KiB
Go
/*
|
|
Copyright 2016 The Rook Authors. All rights reserved.
|
|
|
|
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
|
|
|
|
http://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 integration
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
|
|
"github.com/rook/rook/pkg/daemon/ceph/client"
|
|
rgw "github.com/rook/rook/pkg/operator/ceph/object"
|
|
"github.com/rook/rook/tests/framework/clients"
|
|
"github.com/rook/rook/tests/framework/installer"
|
|
"github.com/rook/rook/tests/framework/utils"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/suite"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
)
|
|
|
|
var (
|
|
userid = "rook-user"
|
|
userdisplayname = "A rook RGW user"
|
|
bucketname = "smokebkt"
|
|
ObjBody = "Test Rook Object Data"
|
|
ObjectKey1 = "rookObj1"
|
|
ObjectKey2 = "rookObj2"
|
|
ObjectKey3 = "rookObj3"
|
|
contentType = "plain/text"
|
|
obcName = "smoke-delete-bucket"
|
|
region = "us-east-1"
|
|
maxObject = "2"
|
|
)
|
|
|
|
// Smoke Test for ObjectStore - Test check the following operations on ObjectStore in order
|
|
// Create object store, Create User, Connect to Object Store, Create Bucket, Read/Write/Delete to bucket,
|
|
// Check issues in MGRs, Delete Bucket and Delete user
|
|
func runObjectE2ETest(helper *clients.TestClient, k8sh *utils.K8sHelper, s suite.Suite, namespace string) {
|
|
ctx := context.TODO()
|
|
storeName := "teststore"
|
|
defer objectStoreCleanUp(s, helper, k8sh, namespace, storeName)
|
|
|
|
logger.Infof("Object Storage End To End Integration Test - Create Object Store, User,Bucket and read/write to bucket")
|
|
logger.Infof("Running on Rook Cluster %s", namespace)
|
|
clusterInfo := client.AdminClusterInfo(namespace)
|
|
|
|
logger.Infof("Step 0 : Create Object Store")
|
|
cobsErr := helper.ObjectClient.Create(namespace, storeName, 3)
|
|
assert.Nil(s.T(), cobsErr)
|
|
|
|
// check that ObjectStore is created
|
|
logger.Infof("Check that RGW pods are Running")
|
|
for i := 0; i < 24 && k8sh.CheckPodCountAndState("rook-ceph-rgw", namespace, 1, "Running") == false; i++ {
|
|
logger.Infof("(%d) RGW pod check sleeping for 5 seconds ...", i)
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
assert.True(s.T(), k8sh.CheckPodCountAndState("rook-ceph-rgw", namespace, 1, "Running"))
|
|
logger.Infof("RGW pods are running")
|
|
logger.Infof("Object store created successfully")
|
|
|
|
// check that ObjectUser is created
|
|
logger.Infof("Step 1 : Create Object Store User")
|
|
cosuErr := helper.ObjectUserClient.Create(namespace, userid, userdisplayname, storeName)
|
|
assert.Nil(s.T(), cosuErr)
|
|
logger.Infof("Waiting 5 seconds for the object user to be created")
|
|
time.Sleep(5 * time.Second)
|
|
logger.Infof("Checking to see if the user secret has been created")
|
|
for i := 0; i < 6 && helper.ObjectUserClient.UserSecretExists(namespace, storeName, userid) == false; i++ {
|
|
logger.Infof("(%d) secret check sleeping for 5 seconds ...", i)
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
|
|
assert.True(s.T(), helper.ObjectUserClient.UserSecretExists(namespace, storeName, userid))
|
|
userInfo, err := helper.ObjectUserClient.GetUser(namespace, storeName, userid)
|
|
assert.NoError(s.T(), err)
|
|
assert.Equal(s.T(), userid, userInfo.UserID)
|
|
assert.Equal(s.T(), userdisplayname, *userInfo.DisplayName)
|
|
logger.Infof("Done creating object store user")
|
|
|
|
// Check object store status
|
|
var i int
|
|
for i = 0; i < 4 && helper.ObjectUserClient.UserSecretExists(namespace, storeName, userid) == false; i++ {
|
|
objectStore, err := k8sh.RookClientset.CephV1().CephObjectStores(namespace).Get(ctx, storeName, metav1.GetOptions{})
|
|
assert.Nil(s.T(), err)
|
|
if objectStore.Status == nil || objectStore.Status.BucketStatus == nil {
|
|
logger.Infof("(%d) bucket status check sleeping for 5 seconds ...", i)
|
|
time.Sleep(5 * time.Second)
|
|
continue
|
|
}
|
|
assert.Equal(s.T(), cephv1.ConditionConnected, objectStore.Status.BucketStatus.Health)
|
|
// Info field has the endpoint in it
|
|
assert.NotEmpty(s.T(), objectStore.Status.Info)
|
|
assert.NotEmpty(s.T(), objectStore.Status.Info["endpoint"])
|
|
break
|
|
}
|
|
assert.NotEqual(s.T(), i, 4)
|
|
|
|
logger.Infof("Step 2 : Test Deleting User")
|
|
dosuErr := helper.ObjectUserClient.Delete(namespace, userid)
|
|
assert.Nil(s.T(), dosuErr)
|
|
logger.Infof("Object store user deleted successfully")
|
|
logger.Infof("Checking to see if the user secret has been deleted")
|
|
for i = 0; i < 4 && helper.ObjectUserClient.UserSecretExists(namespace, storeName, userid) == true; i++ {
|
|
logger.Infof("(%d) secret check sleeping for 5 seconds ...", i)
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
assert.False(s.T(), helper.ObjectUserClient.UserSecretExists(namespace, storeName, userid))
|
|
assert.NotEqual(s.T(), i, 4)
|
|
|
|
logger.Infof("Check that MGRs are not in a crashloop")
|
|
assert.True(s.T(), k8sh.CheckPodCountAndState("rook-ceph-mgr", namespace, 1, "Running"))
|
|
logger.Infof("Ceph MGRs are running")
|
|
|
|
// Testing creation/deletion of objects using Object Bucket Claim
|
|
logger.Infof("Step 3 : Create Object Bucket Claim with reclaim policy delete")
|
|
bucketStorageClassName := "rook-smoke-delete-bucket"
|
|
cobErr := helper.BucketClient.CreateBucketStorageClass(namespace, storeName, bucketStorageClassName, "Delete", region)
|
|
assert.Nil(s.T(), cobErr)
|
|
cobcErr := helper.BucketClient.CreateObc(obcName, bucketStorageClassName, bucketname, maxObject, true)
|
|
assert.Nil(s.T(), cobcErr)
|
|
|
|
created := utils.Retry(12, 2*time.Second, "OBC is created", func() bool {
|
|
return helper.BucketClient.CheckOBC(obcName, "bound")
|
|
})
|
|
assert.True(s.T(), created)
|
|
|
|
logger.Infof("Check if bucket was created")
|
|
context := k8sh.MakeContext()
|
|
rgwcontext := rgw.NewContext(context, clusterInfo, storeName)
|
|
var bkt rgw.ObjectBucket
|
|
for i = 0; i < 4; i++ {
|
|
b, code, err := rgw.GetBucket(rgwcontext, bucketname)
|
|
if b != nil && err == nil {
|
|
bkt = *b
|
|
break
|
|
}
|
|
logger.Warningf("cannot get bucket %q, retrying... bucket: %v. code: %d, err: %v", bucketname, b, code, err)
|
|
logger.Infof("(%d) check bucket exists, sleeping for 5 seconds ...", i)
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
assert.NotEqual(s.T(), i, 4)
|
|
assert.Equal(s.T(), bucketname, bkt.Name)
|
|
logger.Infof("OBC, Secret and ConfigMap created")
|
|
|
|
logger.Infof("Step 4 : Create s3 client")
|
|
s3endpoint, _ := helper.ObjectClient.GetEndPointUrl(namespace, storeName)
|
|
s3AccessKey, _ := helper.BucketClient.GetAccessKey(obcName)
|
|
s3SecretKey, _ := helper.BucketClient.GetSecretKey(obcName)
|
|
s3client, err := rgw.NewS3Agent(s3AccessKey, s3SecretKey, s3endpoint, true)
|
|
assert.Nil(s.T(), err)
|
|
logger.Infof("endpoint (%s) Accesskey (%s) secret (%s)", s3endpoint, s3AccessKey, s3SecretKey)
|
|
|
|
logger.Infof("Step 5 : Put Object on bucket")
|
|
_, poErr := s3client.PutObjectInBucket(bucketname, ObjBody, ObjectKey1, contentType)
|
|
assert.Nil(s.T(), poErr)
|
|
|
|
logger.Infof("Step 6 : Get Object from bucket")
|
|
read, err := s3client.GetObjectInBucket(bucketname, ObjectKey1)
|
|
assert.Nil(s.T(), err)
|
|
assert.Equal(s.T(), ObjBody, read)
|
|
logger.Infof("Object Created and Retrieved on bucket successfully")
|
|
|
|
logger.Infof("Step 7 : Testing Quota for the OBC")
|
|
logger.Infof("Adding one more object to the bucket")
|
|
_, poErr = s3client.PutObjectInBucket(bucketname, ObjBody, ObjectKey2, contentType)
|
|
assert.Nil(s.T(), poErr)
|
|
logger.Infof("Testing the max object limit")
|
|
_, poErr = s3client.PutObjectInBucket(bucketname, ObjBody, ObjectKey3, contentType)
|
|
assert.Error(s.T(), poErr)
|
|
|
|
logger.Infof("Step 8 : Delete objects on bucket")
|
|
_, delobjErr := s3client.DeleteObjectInBucket(bucketname, ObjectKey1)
|
|
assert.Nil(s.T(), delobjErr)
|
|
_, delobjErr = s3client.DeleteObjectInBucket(bucketname, ObjectKey2)
|
|
assert.Nil(s.T(), delobjErr)
|
|
logger.Infof("Objects deleted on bucket successfully")
|
|
|
|
logger.Infof("Step 9 : Delete Object Bucket Claim")
|
|
dobcErr := helper.BucketClient.DeleteObc(obcName, bucketStorageClassName, bucketname, maxObject, true)
|
|
assert.Nil(s.T(), dobcErr)
|
|
logger.Infof("Checking to see if the obc, secret and cm have all been deleted")
|
|
for i = 0; i < 4 && !helper.BucketClient.CheckOBC(obcName, "deleted"); i++ {
|
|
logger.Infof("(%d) obc deleted check, sleeping for 5 seconds ...", i)
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
assert.NotEqual(s.T(), i, 4)
|
|
|
|
logger.Infof("ensure bucket was deleted")
|
|
var rgwErr int
|
|
for i = 0; i < 4; i++ {
|
|
_, rgwErr, _ = rgw.GetBucket(rgwcontext, bucketname)
|
|
if rgwErr == rgw.RGWErrorNotFound {
|
|
break
|
|
}
|
|
logger.Infof("(%d) check bucket deleted, sleeping for 5 seconds ...", i)
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
assert.NotEqual(s.T(), i, 4)
|
|
assert.Equal(s.T(), rgwErr, rgw.RGWErrorNotFound)
|
|
|
|
dobErr := helper.BucketClient.DeleteBucketStorageClass(namespace, storeName, bucketStorageClassName, "Delete", region)
|
|
assert.Nil(s.T(), dobErr)
|
|
logger.Infof("Delete Object Bucket Claim successfully")
|
|
|
|
// TODO : Add case for brownfield/cleanup s3 client}
|
|
}
|
|
|
|
// Test Object StoreCreation on Rook that was installed via helm
|
|
func runObjectE2ETestLite(helper *clients.TestClient, k8sh *utils.K8sHelper, s suite.Suite, settings *installer.TestCephSettings, name string, replicaSize int, deleteStore bool) {
|
|
logger.Infof("Object Storage End To End Integration Test - Create Object Store and check if rgw service is Running")
|
|
logger.Infof("Running on Rook Cluster %s", settings.Namespace)
|
|
|
|
logger.Infof("Step 1 : Create Object Store")
|
|
err := helper.ObjectClient.Create(settings.Namespace, name, int32(replicaSize))
|
|
assert.Nil(s.T(), err)
|
|
|
|
logger.Infof("Step 2 : check rook-ceph-rgw service status and count")
|
|
assert.True(s.T(), k8sh.IsPodInExpectedState("rook-ceph-rgw", settings.Namespace, "Running"),
|
|
"Make sure rook-ceph-rgw is in running state")
|
|
|
|
assert.True(s.T(), k8sh.CheckPodCountAndState("rook-ceph-rgw", settings.Namespace, replicaSize, "Running"),
|
|
"Make sure all rook-ceph-rgw pods are in Running state")
|
|
|
|
assert.True(s.T(), k8sh.IsServiceUp("rook-ceph-rgw-"+name, settings.Namespace))
|
|
|
|
if deleteStore {
|
|
logger.Infof("Delete Object Store")
|
|
err = helper.ObjectClient.Delete(settings.Namespace, name)
|
|
assert.Nil(s.T(), err)
|
|
logger.Infof("Done deleting object store")
|
|
}
|
|
}
|
|
|
|
func objectStoreCleanUp(s suite.Suite, helper *clients.TestClient, k8sh *utils.K8sHelper, namespace, storeName string) {
|
|
logger.Infof("Delete Object Store (will fail if users and buckets still exist)")
|
|
err := helper.ObjectClient.Delete(namespace, storeName)
|
|
assert.Nil(s.T(), err)
|
|
logger.Infof("Done deleting object store")
|
|
}
|