@@ -137,6 +137,88 @@ func TestCreateServiceDiscoveryHost(t *testing.T) {
137
137
assert .Equal (t , int64 (80 ), aws .Int64Value (registry .ContainerPort ), "Expected container port to match" )
138
138
}
139
139
140
+ func TestCreateServiceDiscoveryForceRecreate (t * testing.T ) {
141
+ oldFindPrivateNamespace := findPrivateNamespace
142
+ defer func () { findPrivateNamespace = oldFindPrivateNamespace }()
143
+ findPrivateNamespace = func (name , vpc string , config * config.CommandConfig ) (* string , error ) {
144
+ // In this test the namespace does pre-exist
145
+ return nil , nil
146
+ }
147
+
148
+ ctrl := gomock .NewController (t )
149
+ defer ctrl .Finish ()
150
+
151
+ describeNamespaceStackResponse := & sdk.DescribeStacksOutput {
152
+ Stacks : []* sdk.Stack {
153
+ & sdk.Stack {
154
+ Outputs : []* sdk.Output {
155
+ & sdk.Output {
156
+ OutputKey : aws .String (cfnTemplateOutputPrivateNamespaceID ),
157
+ OutputValue : aws .String (testNamespaceID ),
158
+ },
159
+ },
160
+ },
161
+ },
162
+ }
163
+
164
+ describeSDSStackResponse := & sdk.DescribeStacksOutput {
165
+ Stacks : []* sdk.Stack {
166
+ & sdk.Stack {
167
+ Outputs : []* sdk.Output {
168
+ & sdk.Output {
169
+ OutputKey : aws .String (cfnTemplateOutputSDSARN ),
170
+ OutputValue : aws .String (testSDSARN ),
171
+ },
172
+ },
173
+ },
174
+ },
175
+ }
176
+
177
+ mockCloudformation := mock_cloudformation .NewMockCloudformationClient (ctrl )
178
+
179
+ gomock .InOrder (
180
+ mockCloudformation .EXPECT ().ValidateStackExists (testNamespaceStackName ).Return (nil ),
181
+ // validate that existing SDS stack is deleted
182
+ mockCloudformation .EXPECT ().DeleteStack (testNamespaceStackName ).Return (nil ),
183
+ mockCloudformation .EXPECT ().WaitUntilDeleteComplete (testNamespaceStackName ).Return (nil ),
184
+ mockCloudformation .EXPECT ().CreateStack (gomock .Any (), testNamespaceStackName , false , gomock .Any ()).Do (func (x , y , w , z interface {}) {
185
+ stackName := y .(string )
186
+ capabilityIAM := w .(bool )
187
+ cfnParams := z .(* cloudformation.CfnStackParams )
188
+ validateCFNParam (testNamespaceName , parameterKeyNamespaceName , cfnParams , t )
189
+ validateCFNParam (testVPCID , parameterKeyVPCID , cfnParams , t )
190
+ assert .False (t , capabilityIAM , "Expected capability capabilityIAM to be false" )
191
+ assert .Equal (t , testNamespaceStackName , stackName , "Expected stack name to match" )
192
+ }).Return ("" , nil ),
193
+ mockCloudformation .EXPECT ().WaitUntilCreateComplete (testNamespaceStackName ).Return (nil ),
194
+ mockCloudformation .EXPECT ().DescribeStacks (testNamespaceStackName ).Return (describeNamespaceStackResponse , nil ),
195
+ mockCloudformation .EXPECT ().ValidateStackExists (testSDSStackName ).Return (nil ),
196
+ // Validate that existing Namespace stack is deleted
197
+ mockCloudformation .EXPECT ().DeleteStack (testSDSStackName ).Return (nil ),
198
+ mockCloudformation .EXPECT ().WaitUntilDeleteComplete (testSDSStackName ).Return (nil ),
199
+ mockCloudformation .EXPECT ().CreateStack (gomock .Any (), testSDSStackName , false , gomock .Any ()).Do (func (x , y , w , z interface {}) {
200
+ stackName := y .(string )
201
+ capabilityIAM := w .(bool )
202
+ cfnParams := z .(* cloudformation.CfnStackParams )
203
+ validateCFNParam (testNamespaceID , parameterKeyNamespaceID , cfnParams , t )
204
+ validateCFNParam (testServiceName , parameterKeySDSName , cfnParams , t )
205
+ validateCFNParam (servicediscovery .RecordTypeA , parameterKeyDNSType , cfnParams , t )
206
+ assert .False (t , capabilityIAM , "Expected capability capabilityIAM to be false" )
207
+ assert .Equal (t , testSDSStackName , stackName , "Expected stack name to match" )
208
+ }).Return ("" , nil ),
209
+ mockCloudformation .EXPECT ().WaitUntilCreateComplete (testSDSStackName ).Return (nil ),
210
+ mockCloudformation .EXPECT ().DescribeStacks (testSDSStackName ).Return (describeSDSStackResponse , nil ),
211
+ )
212
+
213
+ config := & config.CommandConfig {
214
+ Cluster : testClusterName ,
215
+ }
216
+
217
+ registry , err := create (simpleWorkflowContext (), "awsvpc" , testServiceName , mockCloudformation , & utils.ServiceDiscovery {}, config )
218
+ assert .NoError (t , err , "Unexpected Error calling create" )
219
+ assert .Equal (t , testSDSARN , aws .StringValue (registry .RegistryArn ), "Expected SDS ARN to match" )
220
+ }
221
+
140
222
func TestCreateServiceDiscoveryWithECSParams (t * testing.T ) {
141
223
input := & utils.ServiceDiscovery {
142
224
ContainerName : testContainerName ,
@@ -604,15 +686,37 @@ func TestDeleteServiceDiscoveryDeleteNamespace(t *testing.T) {
604
686
assert .NoError (t , err , "Unexpected error calling delete" )
605
687
}
606
688
607
- func TestDeleteServiceDiscoveryStackNotFoundError (t * testing.T ) {
689
+ func TestDeleteServiceDiscoveryStackNotFoundErrorForSDS (t * testing.T ) {
608
690
ctrl := gomock .NewController (t )
609
691
defer ctrl .Finish ()
610
692
mockCloudformation := mock_cloudformation .NewMockCloudformationClient (ctrl )
611
693
gomock .InOrder (
612
694
mockCloudformation .EXPECT ().ValidateStackExists (testSDSStackName ).Return (fmt .Errorf ("Stack not found" )),
613
695
)
614
696
697
+ // If no stack is found, then there is nothing to delete, so no error is returned
615
698
err := delete (emptyContext (), mockCloudformation , testServiceName , testServiceName , testClusterName )
699
+ assert .NoError (t , err , "Expected error calling delete" )
700
+ }
701
+
702
+ func TestDeleteServiceDiscoveryStackNotFoundErrorForNamespaceWithDeleteNamespaceFlag (t * testing.T ) {
703
+ ctrl := gomock .NewController (t )
704
+ defer ctrl .Finish ()
705
+ mockCloudformation := mock_cloudformation .NewMockCloudformationClient (ctrl )
706
+ gomock .InOrder (
707
+ mockCloudformation .EXPECT ().ValidateStackExists (testSDSStackName ).Return (nil ),
708
+ mockCloudformation .EXPECT ().DeleteStack (testSDSStackName ).Return (nil ),
709
+ mockCloudformation .EXPECT ().WaitUntilDeleteComplete (testSDSStackName ).Return (nil ),
710
+ mockCloudformation .EXPECT ().ValidateStackExists (testNamespaceStackName ).Return (fmt .Errorf ("Stack not found" )),
711
+ )
712
+
713
+ flagSet := flag .NewFlagSet ("create-sd" , 0 )
714
+ flagSet .Bool (flags .DeletePrivateNamespaceFlag , true , "" )
715
+
716
+ context := cli .NewContext (nil , flagSet , nil )
717
+
718
+ err := delete (context , mockCloudformation , testServiceName , testServiceName , testClusterName )
719
+ // Since the user requested us to delete their namespace, if we failed to delete it, then that's an error case
616
720
assert .Error (t , err , "Expected error calling delete" )
617
721
}
618
722
@@ -632,6 +736,29 @@ func TestCFNStackName(t *testing.T) {
632
736
assert .True (t , len (namespaceStackName ) <= 128 , "CFN Stack names must be no longer than 128 characters" )
633
737
}
634
738
739
+ // Tests the following weird/rare case which is technically allowed:
740
+ // SDS wasn't create by CLI, so no SDS stack exists, But
741
+ // Namespace was created by CLI, and user wants us to remove it.
742
+ func TestDeleteServiceDiscoveryStackNotFoundErrorForSDSWithDeleteNamespaceFlag (t * testing.T ) {
743
+ ctrl := gomock .NewController (t )
744
+ defer ctrl .Finish ()
745
+ mockCloudformation := mock_cloudformation .NewMockCloudformationClient (ctrl )
746
+ gomock .InOrder (
747
+ mockCloudformation .EXPECT ().ValidateStackExists (testSDSStackName ).Return (fmt .Errorf ("Stack not found" )),
748
+ mockCloudformation .EXPECT ().ValidateStackExists (testNamespaceStackName ).Return (nil ),
749
+ mockCloudformation .EXPECT ().DeleteStack (testNamespaceStackName ).Return (nil ),
750
+ mockCloudformation .EXPECT ().WaitUntilDeleteComplete (testNamespaceStackName ).Return (nil ),
751
+ )
752
+
753
+ flagSet := flag .NewFlagSet ("create-sd" , 0 )
754
+ flagSet .Bool (flags .DeletePrivateNamespaceFlag , true , "" )
755
+
756
+ context := cli .NewContext (nil , flagSet , nil )
757
+
758
+ err := delete (context , mockCloudformation , testServiceName , testServiceName , testClusterName )
759
+ assert .NoError (t , err , "Unexpected error calling delete" )
760
+ }
761
+
635
762
func testCreateServiceDiscovery (t * testing.T , networkMode string , ecsParamsSD * utils.ServiceDiscovery , c * cli.Context , validateNamespace validateNamespaceParamsFunc , validateSDS validateSDSParamsFunc , createNamespace bool ) (* ecs.ServiceRegistry , error ) {
636
763
ctrl := gomock .NewController (t )
637
764
defer ctrl .Finish ()
@@ -669,6 +796,7 @@ func testCreateServiceDiscovery(t *testing.T, networkMode string, ecsParamsSD *u
669
796
var expectedCFNCalls []* gomock.Call
670
797
if createNamespace {
671
798
expectedCFNCalls = append (expectedCFNCalls , []* gomock.Call {
799
+ mockCloudformation .EXPECT ().ValidateStackExists (testNamespaceStackName ).Return (fmt .Errorf ("Stack Not Found" )),
672
800
mockCloudformation .EXPECT ().CreateStack (gomock .Any (), testNamespaceStackName , false , gomock .Any ()).Do (func (x , y , w , z interface {}) {
673
801
stackName := y .(string )
674
802
capabilityIAM := w .(bool )
@@ -682,6 +810,7 @@ func testCreateServiceDiscovery(t *testing.T, networkMode string, ecsParamsSD *u
682
810
}... )
683
811
}
684
812
expectedCFNCalls = append (expectedCFNCalls , []* gomock.Call {
813
+ mockCloudformation .EXPECT ().ValidateStackExists (testSDSStackName ).Return (fmt .Errorf ("Stack Not Found" )),
685
814
mockCloudformation .EXPECT ().CreateStack (gomock .Any (), testSDSStackName , false , gomock .Any ()).Do (func (x , y , w , z interface {}) {
686
815
stackName := y .(string )
687
816
capabilityIAM := w .(bool )
0 commit comments