You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by mi...@apache.org on 2023/05/17 08:33:26 UTC

[shardingsphere-on-cloud] branch main updated: test(storage-node): add e2e test

This is an automated email from the ASF dual-hosted git repository.

miaoliyao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/shardingsphere-on-cloud.git


The following commit(s) were added to refs/heads/main by this push:
     new f6b3277  test(storage-node): add e2e test
     new 7db0bc9  Merge pull request #368 from Xu-Wentao/storage-node-register
f6b3277 is described below

commit f6b327716a8f7230376ac41523ca1b18fdda0b9e
Author: xuwentao <cu...@yahoo.com>
AuthorDate: Tue May 16 19:30:39 2023 +0800

    test(storage-node): add e2e test
---
 .../api/v1alpha1/storage_node_types.go             |  13 +-
 shardingsphere-operator/go.mod                     |  19 ++-
 shardingsphere-operator/go.sum                     |  43 ++++--
 .../controllers/storage_ndoe_controller_test.go    | 171 ++++++++++++++++++++-
 .../pkg/controllers/storage_node_controller.go     |  75 ++++++---
 .../pkg/reconcile/storagenode/aws/rdsinstance.go   |   5 +
 shardingsphere-operator/test/e2e/e2e_suite_test.go |   1 +
 .../test/e2e/storage_node_controller_test.go       | 116 +++++++++++++-
 8 files changed, 391 insertions(+), 52 deletions(-)

diff --git a/shardingsphere-operator/api/v1alpha1/storage_node_types.go b/shardingsphere-operator/api/v1alpha1/storage_node_types.go
index d193026..8f35a33 100644
--- a/shardingsphere-operator/api/v1alpha1/storage_node_types.go
+++ b/shardingsphere-operator/api/v1alpha1/storage_node_types.go
@@ -39,6 +39,8 @@ const (
 	StorageNodeConditionTypeAvailable StorageNodeConditionType = "Available"
 	// StorageNodeConditionTypeClusterReady means the cluster is ready, does not mean the instances are all ready.
 	StorageNodeConditionTypeClusterReady StorageNodeConditionType = "ClusterReady"
+	// StorageNodeConditionTypeRegistered means the storage node is registered to the cluster.
+	StorageNodeConditionTypeRegistered StorageNodeConditionType = "Registered"
 )
 
 type StorageNodeConditions []*StorageNodeCondition
@@ -85,6 +87,7 @@ type Endpoint struct {
 }
 
 // +kubebuilder:object:root=true
+
 // StorageNodeList contains a list of StorageNode
 type StorageNodeList struct {
 	metav1.TypeMeta `json:",inline"`
@@ -93,8 +96,12 @@ type StorageNodeList struct {
 }
 
 // +kubebuilder:printcolumn:JSONPath=".metadata.creationTimestamp",name=Age,type=date
+// +kubebuilder:printcolumn:JSONPath=".status.phase",name=Phase,type=string
+// +kubebuilder:printcolumn:JSONPath=".status.Cluster.Status",name=ClusterStatus,type=string
+// +kubebuilder:printcolumn:JSONPath=".status.Registered",name=Registered,type=boolean,priority=1
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
+
 // StorageNode is the Schema for the ShardingSphere storage unit
 type StorageNode struct {
 	metav1.TypeMeta   `json:",inline"`
@@ -134,8 +141,12 @@ type StorageNodeStatus struct {
 	// +optional
 	Cluster ClusterStatus `json:"cluster,omitempty"`
 
-	// Instance contains the current status of the StorageNode instance
+	// Instances contains the current status of the StorageNode instance
 	Instances []InstanceStatus `json:"instances,omitempty"`
+
+	// Registered indicates whether the StorageNode has been registered to shardingsphere
+	// +optional
+	Registered bool `json:"registered,omitempty"`
 }
 
 const (
diff --git a/shardingsphere-operator/go.mod b/shardingsphere-operator/go.mod
index 4babe65..6b14639 100644
--- a/shardingsphere-operator/go.mod
+++ b/shardingsphere-operator/go.mod
@@ -7,12 +7,12 @@ require (
 	github.com/DATA-DOG/go-sqlmock v1.5.0
 	github.com/antlr/antlr4 v0.0.0-20181218183524-be58ebffde8e
 	github.com/chaos-mesh/chaos-mesh/api v0.0.0-20230410023700-25a841a23cd2
-	github.com/database-mesh/golang-sdk v0.0.0-20230420101548-53265cd9883a
+	github.com/database-mesh/golang-sdk v0.0.0-20230517034007-f86740cbb78b
 	github.com/go-logr/logr v1.2.4
 	github.com/go-sql-driver/mysql v1.7.1
 	github.com/golang/mock v1.6.0
-	github.com/onsi/ginkgo/v2 v2.8.0
-	github.com/onsi/gomega v1.26.0
+	github.com/onsi/ginkgo/v2 v2.9.1
+	github.com/onsi/gomega v1.27.4
 	github.com/prometheus/client_golang v1.14.0
 	github.com/stretchr/testify v1.8.1
 	go.uber.org/zap v1.24.0
@@ -20,7 +20,7 @@ require (
 	k8s.io/api v0.26.4
 	k8s.io/apimachinery v0.26.4
 	k8s.io/client-go v0.26.1
-	k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
+	k8s.io/utils v0.0.0-20230505201702-9f6742963106
 	sigs.k8s.io/controller-runtime v0.14.6
 )
 
@@ -52,12 +52,14 @@ require (
 	github.com/go-openapi/jsonpointer v0.19.6 // indirect
 	github.com/go-openapi/jsonreference v0.20.2 // indirect
 	github.com/go-openapi/swag v0.22.3 // indirect
+	github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/google/gnostic v0.6.9 // indirect
 	github.com/google/go-cmp v0.5.9 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
+	github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
 	github.com/google/uuid v1.3.0 // indirect
 	github.com/imdario/mergo v0.3.15 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
@@ -77,12 +79,13 @@ require (
 	github.com/spf13/pflag v1.0.5 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
 	go.uber.org/multierr v1.8.0 // indirect
-	golang.org/x/net v0.9.0 // indirect
+	golang.org/x/net v0.10.0 // indirect
 	golang.org/x/oauth2 v0.6.0 // indirect
-	golang.org/x/sys v0.7.0 // indirect
-	golang.org/x/term v0.7.0 // indirect
+	golang.org/x/sys v0.8.0 // indirect
+	golang.org/x/term v0.8.0 // indirect
 	golang.org/x/text v0.9.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
+	golang.org/x/tools v0.7.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/protobuf v1.30.0 // indirect
@@ -90,7 +93,7 @@ require (
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	k8s.io/apiextensions-apiserver v0.26.1 // indirect
 	k8s.io/component-base v0.26.1 // indirect
-	k8s.io/klog/v2 v2.90.1 // indirect
+	k8s.io/klog/v2 v2.100.1 // indirect
 	k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c // indirect
 	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
diff --git a/shardingsphere-operator/go.sum b/shardingsphere-operator/go.sum
index 7f235c4..cfdae42 100644
--- a/shardingsphere-operator/go.sum
+++ b/shardingsphere-operator/go.sum
@@ -53,13 +53,16 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj
 github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/chaos-mesh/chaos-mesh/api v0.0.0-20230410023700-25a841a23cd2 h1:GSlVaO27tBifERXOOLjIurmyOgwb/I26AMEwvuG84IU=
 github.com/chaos-mesh/chaos-mesh/api v0.0.0-20230410023700-25a841a23cd2/go.mod h1:5qllHIhMkPEWjIimDum42JtMj0P1Tn9x91XUceuPNjY=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/database-mesh/golang-sdk v0.0.0-20230420101548-53265cd9883a h1:DkGqsSh0KgR3bRuk3DKtbVG5nOe6RIea1oikjbGDGIY=
-github.com/database-mesh/golang-sdk v0.0.0-20230420101548-53265cd9883a/go.mod h1:yUEdo+aGdROl9oC7A1GeDB9/ubUtV2k73uLL+qC3PC4=
+github.com/database-mesh/golang-sdk v0.0.0-20230517034007-f86740cbb78b h1:qLK6dB1952pOD2sBNiOBktY9IDmX7Gn/WOG3tEvOw3g=
+github.com/database-mesh/golang-sdk v0.0.0-20230517034007-f86740cbb78b/go.mod h1:yUEdo+aGdROl9oC7A1GeDB9/ubUtV2k73uLL+qC3PC4=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -97,6 +100,8 @@ github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/
 github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
 github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
 github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -136,10 +141,13 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
 github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
+github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
 github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -172,10 +180,10 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI=
-github.com/onsi/ginkgo/v2 v2.8.0/go.mod h1:6JsQiECmxCa3V5st74AL/AmsV482EDdVrGaVW6z3oYU=
-github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
-github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
+github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
+github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=
+github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
+github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -251,8 +259,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
@@ -267,6 +275,7 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -274,11 +283,11 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
-golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
-golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
+golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -298,6 +307,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
+golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -363,12 +374,12 @@ k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU=
 k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE=
 k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4=
 k8s.io/component-base v0.26.1/go.mod h1:VHrLR0b58oC035w6YQiBSbtsf0ThuSwXP+p5dD/kAWU=
-k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
-k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
+k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
 k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c h1:EFfsozyzZ/pggw5qNx7ftTVZdp7WZl+3ih89GEjYEK8=
 k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=
-k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
-k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU=
+k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA=
 sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
diff --git a/shardingsphere-operator/pkg/controllers/storage_ndoe_controller_test.go b/shardingsphere-operator/pkg/controllers/storage_ndoe_controller_test.go
index 8bca029..245facf 100644
--- a/shardingsphere-operator/pkg/controllers/storage_ndoe_controller_test.go
+++ b/shardingsphere-operator/pkg/controllers/storage_ndoe_controller_test.go
@@ -413,10 +413,11 @@ var _ = Describe("StorageNode Controller Mock Test", func() {
 					Name:      nodeName,
 					Namespace: defaultTestNamespace,
 					Annotations: map[string]string{
-						AnnotationKeyRegisterStorageUnitEnabled: "true",
-						AnnotationKeyDatabaseName:               "sharding_db",
-						AnnotationKeyComputeNodeNamespace:       defaultTestNamespace,
-						AnnotationKeyComputeNodeName:            cnName,
+						AnnotationKeyRegisterStorageUnitEnabled:  "true",
+						dbmeshv1alpha1.AnnotationsInstanceDBName: "test_db",
+						AnnotationKeyComputeNodeNamespace:        defaultTestNamespace,
+						AnnotationKeyComputeNodeName:             cnName,
+						AnnotationKeyLogicDatabaseName:           "sharding_db",
 					},
 				},
 				Spec: v1alpha1.StorageNodeSpec{
@@ -480,7 +481,7 @@ var _ = Describe("StorageNode Controller Mock Test", func() {
 			Expect(fakeClient.Create(ctx, svc)).Should(Succeed())
 
 			// mock aws rds client, get available instance
-			mockAws.EXPECT().GetInstance(gomock.Any(), gomock.Any()).Return(ins, nil)
+			mockAws.EXPECT().GetInstance(gomock.Any(), gomock.Any()).Return(ins, nil).AnyTimes()
 			// mock shardingsphere create database
 			mockSS.EXPECT().CreateDatabase(gomock.Any()).Return(nil)
 			// mock shardingsphere register storage unit
@@ -488,12 +489,168 @@ var _ = Describe("StorageNode Controller Mock Test", func() {
 			// mock shardingsphere close connection
 			mockSS.EXPECT().Close()
 
+			// reconcile storage node status to Ready
 			_, err := reconciler.Reconcile(ctx, req)
 			Expect(err).To(BeNil())
+			// reconcile to register storage node
+			_, err = reconciler.Reconcile(ctx, req)
+			Expect(err).To(BeNil())
 
 			registeredSN := &v1alpha1.StorageNode{}
-			Expect(fakeClient.Get(ctx, client.ObjectKey{Name: defaultTestStorageNode, Namespace: defaultTestNamespace}, registeredSN)).Should(Succeed())
-			// TODO update storage node register status
+			Expect(fakeClient.Get(ctx, client.ObjectKey{Name: nodeName, Namespace: defaultTestNamespace}, registeredSN)).Should(Succeed())
+			Expect(registeredSN.Status.Registered).To(BeTrue())
+		})
+	})
+
+	Context("Test getShardingsphereServer", func() {
+		BeforeEach(func() {
+			mockCtrl = gomock.NewController(GinkgoT())
+			mockSS = mock_shardingsphere.NewMockIServer(mockCtrl)
+			monkey.Patch(shardingsphere.NewServer, func(_, _ string, _ uint, _, _ string) (shardingsphere.IServer, error) {
+				return mockSS, nil
+			})
+		})
+		AfterEach(func() {
+			mockCtrl.Finish()
+			monkey.UnpatchAll()
+		})
+		It("should be successful when get shardingsphere server", func() {
+			cn := &v1alpha1.ComputeNode{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-get-shardingsphere-server",
+					Namespace: defaultTestNamespace,
+				},
+				Spec: v1alpha1.ComputeNodeSpec{
+					Bootstrap: v1alpha1.BootstrapConfig{
+						ServerConfig: v1alpha1.ServerConfig{
+							Authority: v1alpha1.ComputeNodeAuthority{
+								Users: []v1alpha1.ComputeNodeUser{
+									{
+										User:     "root",
+										Password: "root",
+									},
+								},
+							},
+						},
+					},
+				},
+			}
+			svc := &corev1.Service{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-get-shardingsphere-server",
+					Namespace: defaultTestNamespace,
+				},
+				Spec: corev1.ServiceSpec{
+					Ports: []corev1.ServicePort{
+						{
+							Name:     "http",
+							Protocol: "TCP",
+							Port:     3307,
+						},
+					},
+				},
+			}
+			Expect(fakeClient.Create(ctx, cn)).Should(Succeed())
+			Expect(fakeClient.Create(ctx, svc)).Should(Succeed())
+
+			sn := &v1alpha1.StorageNode{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-get-shardingsphere-server",
+					Namespace: defaultTestNamespace,
+					Annotations: map[string]string{
+						AnnotationKeyComputeNodeName:      "test-get-shardingsphere-server",
+						AnnotationKeyComputeNodeNamespace: defaultTestNamespace,
+					},
+				},
+			}
+
+			ss, err := reconciler.getShardingsphereServer(ctx, sn)
+			Expect(err).To(BeNil())
+			Expect(ss).ToNot(BeNil())
+		})
+	})
+
+	Context("Test registerStorageUnit", func() {
+		BeforeEach(func() {
+			mockCtrl = gomock.NewController(GinkgoT())
+			mockSS = mock_shardingsphere.NewMockIServer(mockCtrl)
+			monkey.Patch(shardingsphere.NewServer, func(_, _ string, _ uint, _, _ string) (shardingsphere.IServer, error) {
+				return mockSS, nil
+			})
+		})
+		AfterEach(func() {
+			mockCtrl.Finish()
+			monkey.UnpatchAll()
+		})
+		It("should be successful when register storage unit", func() {
+			testName := "test-register-storage-unit"
+			cn := &v1alpha1.ComputeNode{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      testName,
+					Namespace: defaultTestNamespace,
+				},
+				Spec: v1alpha1.ComputeNodeSpec{
+					Bootstrap: v1alpha1.BootstrapConfig{
+						ServerConfig: v1alpha1.ServerConfig{
+							Authority: v1alpha1.ComputeNodeAuthority{
+								Users: []v1alpha1.ComputeNodeUser{
+									{
+										User:     "root",
+										Password: "root",
+									},
+								},
+							},
+						},
+					},
+				},
+			}
+			svc := &corev1.Service{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      testName,
+					Namespace: defaultTestNamespace,
+				},
+				Spec: corev1.ServiceSpec{
+					Ports: []corev1.ServicePort{
+						{
+							Name:     "http",
+							Protocol: "TCP",
+							Port:     3307,
+						},
+					},
+				},
+			}
+			Expect(fakeClient.Create(ctx, cn)).Should(Succeed())
+			Expect(fakeClient.Create(ctx, svc)).Should(Succeed())
+
+			sn := &v1alpha1.StorageNode{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      testName,
+					Namespace: defaultTestNamespace,
+					Annotations: map[string]string{
+						AnnotationKeyComputeNodeName:             testName,
+						AnnotationKeyComputeNodeNamespace:        defaultTestNamespace,
+						AnnotationKeyRegisterStorageUnitEnabled:  "true",
+						AnnotationKeyLogicDatabaseName:           testName,
+						dbmeshv1alpha1.AnnotationsInstanceDBName: testName,
+					},
+				},
+				Status: v1alpha1.StorageNodeStatus{
+					Phase: v1alpha1.StorageNodePhaseReady,
+					Instances: []v1alpha1.InstanceStatus{
+						{
+							Status:   v1alpha1.StorageNodeInstanceStatusAvailable,
+							Endpoint: v1alpha1.Endpoint{},
+						},
+					},
+				},
+			}
+
+			mockSS.EXPECT().CreateDatabase(gomock.Any()).Return(nil)
+			mockSS.EXPECT().Close().Return(nil)
+			mockSS.EXPECT().RegisterStorageUnit(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
+
+			Expect(reconciler.registerStorageUnit(ctx, sn)).To(BeNil())
+			Expect(sn.Status.Registered).To(BeTrue())
 		})
 	})
 })
diff --git a/shardingsphere-operator/pkg/controllers/storage_node_controller.go b/shardingsphere-operator/pkg/controllers/storage_node_controller.go
index 0798020..a4d9ecf 100644
--- a/shardingsphere-operator/pkg/controllers/storage_node_controller.go
+++ b/shardingsphere-operator/pkg/controllers/storage_node_controller.go
@@ -19,6 +19,7 @@ package controllers
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
 	"reflect"
 	"strings"
@@ -48,7 +49,7 @@ const (
 	AnnotationKeyRegisterStorageUnitEnabled = "shardingsphere.apache.org/register-storage-unit-enabled"
 	AnnotationKeyComputeNodeNamespace       = "shardingsphere.apache.org/compute-node-namespace"
 	AnnotationKeyComputeNodeName            = "shardingsphere.apache.org/compute-node-name"
-	AnnotationKeyDatabaseName               = "shardingsphere.apache.org/database-name"
+	AnnotationKeyLogicDatabaseName          = "shardingsphere.apache.org/logic-database-name"
 
 	ShardingSphereProtocolType = "proxy-frontend-database-protocol-type"
 )
@@ -157,7 +158,16 @@ func (r *StorageNodeReconciler) reconcile(ctx context.Context, dbClass *dbmeshv1
 		r.Log.Error(nil, fmt.Sprintf("unsupported database provisioner %s", dbClass.Spec.Provisioner))
 	}
 
-	// update status
+	d, _ := json.MarshalIndent(node.Status, "", "  ")
+	r.Log.Info(string(d))
+
+	// register storage unit if needed.
+	if err := r.registerStorageUnit(ctx, node); err != nil {
+		r.Recorder.Eventf(node, corev1.EventTypeWarning, "RegisterStorageUnitFailed", "unable to register storage unit %s/%s", node.GetNamespace(), node.GetName())
+		return ctrl.Result{Requeue: true}, err
+	}
+
+	// finally, update status
 	desiredState := computeDesiredState(node.Status)
 
 	if !reflect.DeepEqual(node.Status, desiredState) {
@@ -169,11 +179,8 @@ func (r *StorageNodeReconciler) reconcile(ctx context.Context, dbClass *dbmeshv1
 		}
 	}
 
-	// register storage unit if needed.
-	if err := r.registerStorageUnit(ctx, node); err != nil {
-		r.Log.Error(err, fmt.Sprintf("unable to register storage unit %s/%s", node.GetNamespace(), node.GetName()))
-		return ctrl.Result{Requeue: true}, err
-	}
+	d, _ = json.MarshalIndent(node.Status, "", "  ")
+	r.Log.Info(string(d))
 
 	return ctrl.Result{RequeueAfter: defaultRequeueTime}, nil
 }
@@ -204,7 +211,7 @@ func (r *StorageNodeReconciler) getDatabaseClass(ctx context.Context, node *v1al
 	return databaseClass, nil
 }
 
-// nolint:gocritic,gocognit
+// nolint:gocritic
 func computeDesiredState(status v1alpha1.StorageNodeStatus) v1alpha1.StorageNodeStatus {
 	// Initialize a new status object based on the current state
 	desiredState := status
@@ -228,6 +235,13 @@ func computeDesiredState(status v1alpha1.StorageNodeStatus) v1alpha1.StorageNode
 		desiredState.Phase = v1alpha1.StorageNodePhaseDeleteComplete
 	}
 
+	desiredState.Conditions = computeNewConditions(desiredState, status, clusterStatus)
+
+	return desiredState
+}
+
+// nolint:gocritic
+func computeNewConditions(desiredState, status v1alpha1.StorageNodeStatus, clusterStatus string) v1alpha1.StorageNodeConditions {
 	newSNConditions := status.Conditions
 
 	// Update the cluster ready condition if the cluster status is not empty
@@ -268,9 +282,23 @@ func computeDesiredState(status v1alpha1.StorageNodeStatus) v1alpha1.StorageNode
 		})
 	}
 
-	desiredState.Conditions = newSNConditions
-
-	return desiredState
+	// Update the registered condition
+	if status.Registered {
+		newSNConditions.UpsertCondition(&v1alpha1.StorageNodeCondition{
+			Type:           v1alpha1.StorageNodeConditionTypeRegistered,
+			Status:         corev1.ConditionTrue,
+			LastUpdateTime: metav1.Now(),
+			Reason:         "StorageNode is registered",
+		})
+	} else {
+		newSNConditions.UpsertCondition(&v1alpha1.StorageNodeCondition{
+			Type:           v1alpha1.StorageNodeConditionTypeRegistered,
+			Status:         corev1.ConditionFalse,
+			LastUpdateTime: metav1.Now(),
+			Reason:         "StorageNode is not registered",
+		})
+	}
+	return newSNConditions
 }
 
 // allInstancesReady returns true if all instances are ready, false otherwise
@@ -331,7 +359,7 @@ func updateAWSRDSInstanceStatus(node *v1alpha1.StorageNode, instance *rds.DescIn
 			Address: instance.Endpoint.Address,
 			Port:    instance.Endpoint.Port,
 		},
-		Status: status,
+		Status: string(status),
 	})
 
 	node.Status.Instances = instances
@@ -450,10 +478,18 @@ func (r *StorageNodeReconciler) deleteAWSRDSInstance(ctx context.Context, client
 func (r *StorageNodeReconciler) registerStorageUnit(ctx context.Context, node *v1alpha1.StorageNode) error {
 	// if register storage unit is not enabled, return
 	if node.Annotations[AnnotationKeyRegisterStorageUnitEnabled] != "true" {
+		r.Log.Info(fmt.Sprintf("register storage unit is not enabled for node %s/%s", node.GetNamespace(), node.GetName()))
 		return nil
 	}
+
+	// if storage unit is already registered, return
+	if node.Status.Registered {
+		return nil
+	}
+
 	// if node is not ready, return
 	if node.Status.Phase != v1alpha1.StorageNodePhaseReady {
+		r.Recorder.Eventf(node, corev1.EventTypeWarning, "RegisterCanceled", "Canceled to register storage unit for node %s/%s: node is not ready", node.GetNamespace(), node.GetName())
 		return nil
 	}
 
@@ -461,7 +497,8 @@ func (r *StorageNodeReconciler) registerStorageUnit(ctx context.Context, node *v
 		return err
 	}
 
-	dbName := node.Annotations[AnnotationKeyDatabaseName]
+	logicDBName := node.Annotations[AnnotationKeyLogicDatabaseName]
+	dbName := node.Annotations[dbmeshv1alpha1.AnnotationsInstanceDBName]
 
 	ssServer, err := r.getShardingsphereServer(ctx, node)
 	if err != nil {
@@ -470,29 +507,33 @@ func (r *StorageNodeReconciler) registerStorageUnit(ctx context.Context, node *v
 
 	defer ssServer.Close()
 
-	if err := ssServer.CreateDatabase(dbName); err != nil {
+	if err := ssServer.CreateDatabase(logicDBName); err != nil {
 		return fmt.Errorf("create database failed: %w", err)
 	}
+	r.Recorder.Eventf(node, corev1.EventTypeNormal, "LogicDatabaseCreated", "LogicDatabase %s is created", logicDBName)
 
 	// TODO add cluster
 
 	ins := node.Status.Instances[0]
 	host := ins.Endpoint.Address
 	port := ins.Endpoint.Port
-	username := node.Annotations[dbmeshv1alpha1.AnnotationsMasterUsername]
+	username := strings.Split(node.Annotations[dbmeshv1alpha1.AnnotationsMasterUsername], "@")[0]
 	password := node.Annotations[dbmeshv1alpha1.AnnotationsMasterUserPassword]
 
 	// TODO how to set ds name?
 	if err := ssServer.RegisterStorageUnit("ds_0", host, uint(port), dbName, username, password); err != nil {
 		return fmt.Errorf("register storage node failed: %w", err)
 	}
+	r.Recorder.Eventf(node, corev1.EventTypeNormal, "StorageUnitRegistered", "StorageUnit %s:%d/%s is registered", host, port, dbName)
 
+	node.Status.Registered = true
 	return nil
 }
 
 func validateComputeNodeAnnotations(node *v1alpha1.StorageNode) error {
 	requiredAnnos := []string{
-		AnnotationKeyDatabaseName,
+		AnnotationKeyLogicDatabaseName,
+		dbmeshv1alpha1.AnnotationsInstanceDBName,
 		AnnotationKeyComputeNodeNamespace,
 		AnnotationKeyComputeNodeName,
 	}
@@ -562,7 +603,5 @@ func (r *StorageNodeReconciler) getShardingsphereServer(ctx context.Context, nod
 func (r *StorageNodeReconciler) SetupWithManager(mgr ctrl.Manager) error {
 	return ctrl.NewControllerManagedBy(mgr).
 		For(&v1alpha1.StorageNode{}).
-		Owns(&v1alpha1.ComputeNode{}).
-		Owns(&corev1.Service{}).
 		Complete(r)
 }
diff --git a/shardingsphere-operator/pkg/reconcile/storagenode/aws/rdsinstance.go b/shardingsphere-operator/pkg/reconcile/storagenode/aws/rdsinstance.go
index 764d3b4..bd5c27d 100644
--- a/shardingsphere-operator/pkg/reconcile/storagenode/aws/rdsinstance.go
+++ b/shardingsphere-operator/pkg/reconcile/storagenode/aws/rdsinstance.go
@@ -54,6 +54,7 @@ func validCreateInstanceParams(node *v1alpha1.StorageNode, paramsptr *map[string
 			}
 		}
 	}
+
 	if username, ok := params["masterUsername"]; ok {
 		validatedUsername, err := validateusername(username)
 		if err != nil {
@@ -139,6 +140,10 @@ func (c *RdsClient) CreateInstance(ctx context.Context, node *v1alpha1.StorageNo
 		SetMasterUsername(params["masterUsername"]).
 		SetMasterUserPassword(params["masterUserPassword"]).
 		SetAllocatedStorage(int32(storage))
+	// set database name if needed.
+	if v, ok := params[node.Annotations[""]]; ok {
+		instance.SetDBName(v)
+	}
 	return instance.Create(ctx)
 }
 
diff --git a/shardingsphere-operator/test/e2e/e2e_suite_test.go b/shardingsphere-operator/test/e2e/e2e_suite_test.go
index bd7566b..0f76ac7 100644
--- a/shardingsphere-operator/test/e2e/e2e_suite_test.go
+++ b/shardingsphere-operator/test/e2e/e2e_suite_test.go
@@ -112,6 +112,7 @@ var _ = BeforeSuite(func() {
 		Log:      ctrl.Log.WithName("controllers").WithName("StorageNode"),
 		Recorder: k8sManager.GetEventRecorderFor("StorageNode"),
 		AwsRDS:   dbmesh_rds.NewService(sess["AwsRegion"]),
+		Service:  service.NewServiceClient(k8sManager.GetClient()),
 	}).SetupWithManager(k8sManager)
 	Expect(err).ToNot(HaveOccurred())
 
diff --git a/shardingsphere-operator/test/e2e/storage_node_controller_test.go b/shardingsphere-operator/test/e2e/storage_node_controller_test.go
index f3862ce..68264ed 100644
--- a/shardingsphere-operator/test/e2e/storage_node_controller_test.go
+++ b/shardingsphere-operator/test/e2e/storage_node_controller_test.go
@@ -13,21 +13,24 @@
  * 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 e2e
 
 import (
 	"context"
+	"database/sql"
+	"github.com/DATA-DOG/go-sqlmock"
 	"reflect"
+	"regexp"
 	"time"
 
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/controllers"
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode/aws"
-	dbmesh_rds "github.com/database-mesh/golang-sdk/aws/client/rds"
 
 	"bou.ke/monkey"
+	dbmesh_rds "github.com/database-mesh/golang-sdk/aws/client/rds"
 	dbmeshv1alpha1 "github.com/database-mesh/golang-sdk/kubernetes/api/v1alpha1"
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
@@ -141,5 +144,114 @@ var _ = Describe("StorageNode Controller Suite Test", func() {
 				return err != nil
 			}, 10*time.Second, 1*time.Second).Should(BeTrue())
 		})
+
+		It("should register storage unit success", func() {
+			// mock mysql
+			db, dbmock, err := sqlmock.New()
+			Expect(err).Should(Succeed())
+			Expect(dbmock).ShouldNot(BeNil())
+			defer db.Close()
+
+			// mock rds DescribeDBInstances func returns success
+			monkey.PatchInstanceMethod(reflect.TypeOf(&aws.RdsClient{}), "GetInstance", func(_ *aws.RdsClient, _ context.Context, _ *v1alpha1.StorageNode) (*dbmesh_rds.DescInstance, error) {
+				return &dbmesh_rds.DescInstance{
+					DBInstanceStatus: v1alpha1.StorageNodeInstanceStatusAvailable,
+					Endpoint: dbmesh_rds.Endpoint{
+						Address: "127.0.0.1",
+						Port:    3306,
+					},
+				}, nil
+			})
+			monkey.Patch(sql.Open, func(_ string, _ string) (*sql.DB, error) {
+				return db, nil
+			})
+
+			cn := &v1alpha1.ComputeNode{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-compute-node",
+					Namespace: "default",
+					Labels: map[string]string{
+						"app": "test-app",
+					},
+				},
+				Spec: v1alpha1.ComputeNodeSpec{
+					Selector: &metav1.LabelSelector{
+						MatchLabels: map[string]string{
+							"app": "test-app",
+						},
+					},
+					PortBindings: []v1alpha1.PortBinding{
+						{
+							Name:          "http",
+							ContainerPort: 3307,
+							Protocol:      "TCP",
+							ServicePort:   3307,
+						},
+					},
+					Bootstrap: v1alpha1.BootstrapConfig{
+						ServerConfig: v1alpha1.ServerConfig{
+							Authority: v1alpha1.ComputeNodeAuthority{
+								Users: []v1alpha1.ComputeNodeUser{
+									{
+										User:     "test-user",
+										Password: "test-password",
+									},
+								},
+								Privilege: v1alpha1.ComputeNodePrivilege{
+									Type: v1alpha1.AllPermitted,
+								},
+							},
+							Props: map[string]string{
+								"proxy-frontend-database-protocol-type": "MySQL",
+							},
+							Mode: v1alpha1.ComputeNodeServerMode{
+								Repository: v1alpha1.Repository{
+									Type:  "ZooKeeper",
+									Props: nil,
+								},
+								Type: "Zookeeper",
+							},
+						},
+					},
+				},
+			}
+
+			nodeName := "test-storage-node-register"
+			node := &v1alpha1.StorageNode{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      nodeName,
+					Namespace: "default",
+					Annotations: map[string]string{
+						dbmeshv1alpha1.AnnotationsInstanceIdentifier:        "test-instance-identifier",
+						controllers.AnnotationKeyRegisterStorageUnitEnabled: "true",
+						dbmeshv1alpha1.AnnotationsInstanceDBName:            "test-db-name",
+						controllers.AnnotationKeyComputeNodeNamespace:       "default",
+						controllers.AnnotationKeyComputeNodeName:            "test-compute-node",
+						controllers.AnnotationKeyLogicDatabaseName:          "test-logic-db-name",
+					},
+				},
+				Spec: v1alpha1.StorageNodeSpec{
+					DatabaseClassName: databaseClassName,
+				},
+			}
+
+			Expect(k8sClient.Create(ctx, cn)).Should(Succeed())
+			Expect(k8sClient.Create(ctx, node)).Should(Succeed())
+
+			dbmock.ExpectExec(regexp.QuoteMeta("CREATE DATABASE IF NOT EXISTS")).WillReturnResult(sqlmock.NewResult(0, 0))
+			dbmock.ExpectExec(regexp.QuoteMeta("REGISTER STORAGE UNIT IF NOT EXISTS")).WillReturnResult(sqlmock.NewResult(0, 0))
+
+			Eventually(func() v1alpha1.StorageNodePhaseStatus {
+				newSN := &v1alpha1.StorageNode{}
+				Expect(k8sClient.Get(ctx, client.ObjectKey{Name: nodeName, Namespace: "default"}, newSN)).Should(Succeed())
+				return newSN.Status.Phase
+			}, 10, 1).Should(Equal(v1alpha1.StorageNodePhaseReady))
+
+			Eventually(func() bool {
+				newSN := &v1alpha1.StorageNode{}
+				Expect(k8sClient.Get(ctx, client.ObjectKey{Name: nodeName, Namespace: "default"}, newSN)).Should(Succeed())
+				return newSN.Status.Registered
+			}, 10, 1).Should(BeTrue())
+		})
 	})
 })