1package testing 2 3import ( 4 "strings" 5 "testing" 6 7 "github.com/gophercloud/gophercloud/openstack/clustering/v1/clusters" 8 "github.com/gophercloud/gophercloud/pagination" 9 th "github.com/gophercloud/gophercloud/testhelper" 10 fake "github.com/gophercloud/gophercloud/testhelper/client" 11) 12 13func TestCreateCluster(t *testing.T) { 14 th.SetupHTTP() 15 defer th.TeardownHTTP() 16 17 HandleCreateClusterSuccessfully(t) 18 19 minSize := 1 20 opts := clusters.CreateOpts{ 21 Name: "cluster1", 22 DesiredCapacity: 3, 23 ProfileID: "d8a48377-f6a3-4af4-bbbb-6e8bcaa0cbc0", 24 MinSize: &minSize, 25 MaxSize: 20, 26 Timeout: 3600, 27 Metadata: map[string]interface{}{}, 28 Config: map[string]interface{}{}, 29 } 30 31 res := clusters.Create(fake.ServiceClient(), opts) 32 th.AssertNoErr(t, res.Err) 33 34 location := res.Header.Get("Location") 35 th.AssertEquals(t, "http://senlin.cloud.blizzard.net:8778/v1/actions/625628cd-f877-44be-bde0-fec79f84e13d", location) 36 37 locationFields := strings.Split(location, "actions/") 38 actionID := locationFields[1] 39 th.AssertEquals(t, "625628cd-f877-44be-bde0-fec79f84e13d", actionID) 40 41 actual, err := res.Extract() 42 th.AssertNoErr(t, err) 43 th.AssertDeepEquals(t, ExpectedCluster, *actual) 44} 45 46func TestCreateClusterEmptyTime(t *testing.T) { 47 th.SetupHTTP() 48 defer th.TeardownHTTP() 49 50 HandleCreateClusterEmptyTimeSuccessfully(t) 51 52 minSize := 1 53 opts := clusters.CreateOpts{ 54 Name: "cluster1", 55 DesiredCapacity: 3, 56 ProfileID: "d8a48377-f6a3-4af4-bbbb-6e8bcaa0cbc0", 57 MinSize: &minSize, 58 MaxSize: 20, 59 Timeout: 3600, 60 Metadata: map[string]interface{}{}, 61 Config: map[string]interface{}{}, 62 } 63 64 actual, err := clusters.Create(fake.ServiceClient(), opts).Extract() 65 th.AssertNoErr(t, err) 66 th.AssertDeepEquals(t, ExpectedCluster_EmptyTime, *actual) 67} 68 69func TestCreateClusterMetadata(t *testing.T) { 70 th.SetupHTTP() 71 defer th.TeardownHTTP() 72 73 HandleCreateClusterMetadataSuccessfully(t) 74 75 minSize := 1 76 opts := clusters.CreateOpts{ 77 Name: "cluster1", 78 DesiredCapacity: 3, 79 ProfileID: "d8a48377-f6a3-4af4-bbbb-6e8bcaa0cbc0", 80 MinSize: &minSize, 81 MaxSize: 20, 82 Timeout: 3600, 83 Metadata: map[string]interface{}{ 84 "foo": "bar", 85 "test": map[string]interface{}{ 86 "nil_interface": interface{}(nil), 87 "float_value": float64(123.3), 88 "string_value": "test_string", 89 "bool_value": false, 90 }, 91 }, 92 Config: map[string]interface{}{}, 93 } 94 95 actual, err := clusters.Create(fake.ServiceClient(), opts).Extract() 96 th.AssertNoErr(t, err) 97 th.AssertDeepEquals(t, ExpectedCluster_Metadata, *actual) 98} 99 100func TestGetCluster(t *testing.T) { 101 th.SetupHTTP() 102 defer th.TeardownHTTP() 103 104 HandleGetClusterSuccessfully(t) 105 106 actual, err := clusters.Get(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15").Extract() 107 th.AssertNoErr(t, err) 108 th.AssertDeepEquals(t, ExpectedCluster, *actual) 109} 110 111func TestGetClusterEmptyTime(t *testing.T) { 112 th.SetupHTTP() 113 defer th.TeardownHTTP() 114 115 HandleGetClusterEmptyTimeSuccessfully(t) 116 117 actual, err := clusters.Get(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15").Extract() 118 th.AssertNoErr(t, err) 119 th.AssertDeepEquals(t, ExpectedCluster_EmptyTime, *actual) 120} 121 122func TestListClusters(t *testing.T) { 123 th.SetupHTTP() 124 defer th.TeardownHTTP() 125 126 HandleListClusterSuccessfully(t) 127 128 count := 0 129 130 clusters.List(fake.ServiceClient(), clusters.ListOpts{GlobalProject: new(bool)}).EachPage(func(page pagination.Page) (bool, error) { 131 count++ 132 actual, err := clusters.ExtractClusters(page) 133 th.AssertNoErr(t, err) 134 th.AssertDeepEquals(t, ExpectedClusters, actual) 135 136 return true, nil 137 }) 138 139 if count != 1 { 140 t.Errorf("Expected 1 page, got %d", count) 141 } 142} 143 144func TestUpdateCluster(t *testing.T) { 145 th.SetupHTTP() 146 defer th.TeardownHTTP() 147 148 HandleUpdateClusterSuccessfully(t) 149 150 updateOpts := clusters.UpdateOpts{ 151 Name: "cluster1", 152 ProfileID: "edc63d0a-2ca4-48fa-9854-27926da76a4a", 153 } 154 155 actual, err := clusters.Update(fake.ServiceClient(), ExpectedCluster.ID, updateOpts).Extract() 156 th.AssertNoErr(t, err) 157 th.AssertDeepEquals(t, ExpectedCluster, *actual) 158} 159 160func TestUpdateClusterEmptyTime(t *testing.T) { 161 th.SetupHTTP() 162 defer th.TeardownHTTP() 163 164 HandleUpdateClusterEmptyTimeSuccessfully(t) 165 166 updateOpts := clusters.UpdateOpts{ 167 Name: "cluster1", 168 ProfileID: "edc63d0a-2ca4-48fa-9854-27926da76a4a", 169 } 170 171 actual, err := clusters.Update(fake.ServiceClient(), ExpectedCluster_EmptyTime.ID, updateOpts).Extract() 172 th.AssertNoErr(t, err) 173 th.AssertDeepEquals(t, ExpectedCluster_EmptyTime, *actual) 174} 175 176func TestDeleteCluster(t *testing.T) { 177 th.SetupHTTP() 178 defer th.TeardownHTTP() 179 180 HandleDeleteClusterSuccessfully(t) 181 182 err := clusters.Delete(fake.ServiceClient(), "6dc6d336e3fc4c0a951b5698cd1236ee").ExtractErr() 183 th.AssertNoErr(t, err) 184} 185 186func TestResizeCluster(t *testing.T) { 187 th.SetupHTTP() 188 defer th.TeardownHTTP() 189 190 HandleResizeSuccessfully(t) 191 192 maxSize := 5 193 minSize := 1 194 number := -2 195 strict := true 196 opts := clusters.ResizeOpts{ 197 AdjustmentType: "CHANGE_IN_CAPACITY", 198 MaxSize: &maxSize, 199 MinSize: &minSize, 200 Number: number, 201 Strict: &strict, 202 } 203 204 actionID, err := clusters.Resize(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15", opts).Extract() 205 th.AssertNoErr(t, err) 206 th.AssertEquals(t, ExpectedActionID, actionID) 207} 208 209// Test case for Number field having a float value 210func TestResizeClusterNumberFloat(t *testing.T) { 211 maxSize := 5 212 minSize := 1 213 number := 100.0 214 strict := true 215 opts := clusters.ResizeOpts{ 216 AdjustmentType: "CHANGE_IN_PERCENTAGE", 217 MaxSize: &maxSize, 218 MinSize: &minSize, 219 Number: number, 220 Strict: &strict, 221 } 222 223 _, err := opts.ToClusterResizeMap() 224 th.AssertNoErr(t, err) 225} 226 227// Test case for missing Number field. 228func TestResizeClusterMissingNumber(t *testing.T) { 229 maxSize := 5 230 minSize := 1 231 strict := true 232 opts := clusters.ResizeOpts{ 233 MaxSize: &maxSize, 234 MinSize: &minSize, 235 Strict: &strict, 236 } 237 238 _, err := opts.ToClusterResizeMap() 239 th.AssertNoErr(t, err) 240} 241 242// Test case for missing Number field which is required when AdjustmentType is specified 243func TestResizeClusterInvalidParamsMissingNumber(t *testing.T) { 244 maxSize := 5 245 minSize := 1 246 strict := true 247 opts := clusters.ResizeOpts{ 248 AdjustmentType: "CHANGE_IN_CAPACITY", 249 MaxSize: &maxSize, 250 MinSize: &minSize, 251 Strict: &strict, 252 } 253 254 _, err := opts.ToClusterResizeMap() 255 isValid := err == nil 256 th.AssertEquals(t, false, isValid) 257} 258 259// Test case for float Number field which is only valid for CHANGE_IN_PERCENTAGE. 260func TestResizeClusterInvalidParamsNumberFloat(t *testing.T) { 261 maxSize := 5 262 minSize := 1 263 number := 100.0 264 strict := true 265 opts := clusters.ResizeOpts{ 266 AdjustmentType: "CHANGE_IN_CAPACITY", 267 MaxSize: &maxSize, 268 MinSize: &minSize, 269 Number: number, 270 Strict: &strict, 271 } 272 273 _, err := opts.ToClusterResizeMap() 274 isValid := err == nil 275 th.AssertEquals(t, false, isValid) 276} 277 278func TestClusterScaleIn(t *testing.T) { 279 th.SetupHTTP() 280 defer th.TeardownHTTP() 281 282 HandleScaleInSuccessfully(t) 283 284 count := 5 285 scaleOpts := clusters.ScaleInOpts{ 286 Count: &count, 287 } 288 actionID, err := clusters.ScaleIn(fake.ServiceClient(), "edce3528-864f-41fb-8759-f4707925cc09", scaleOpts).Extract() 289 th.AssertNoErr(t, err) 290 th.AssertEquals(t, ExpectedActionID, actionID) 291} 292 293func TestListClusterPolicies(t *testing.T) { 294 th.SetupHTTP() 295 defer th.TeardownHTTP() 296 297 HandleListPoliciesSuccessfully(t) 298 299 pageCount := 0 300 err := clusters.ListPolicies(fake.ServiceClient(), ExpectedClusterPolicy.ClusterID, clusters.ListPoliciesOpts{Name: "Test"}).EachPage(func(page pagination.Page) (bool, error) { 301 pageCount++ 302 actual, err := clusters.ExtractClusterPolicies(page) 303 th.AssertNoErr(t, err) 304 th.AssertDeepEquals(t, ExpectedListPolicies, actual) 305 306 return true, nil 307 }) 308 309 th.AssertNoErr(t, err) 310 th.AssertEquals(t, pageCount, 1) 311} 312 313func TestGetClusterPolicies(t *testing.T) { 314 th.SetupHTTP() 315 defer th.TeardownHTTP() 316 317 HandleGetPolicySuccessfully(t) 318 319 actual, err := clusters.GetPolicy(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15", "714fe676-a08f-4196-b7af-61d52eeded15").Extract() 320 th.AssertNoErr(t, err) 321 th.AssertDeepEquals(t, ExpectedClusterPolicy, *actual) 322} 323 324func TestClusterRecover(t *testing.T) { 325 th.SetupHTTP() 326 defer th.TeardownHTTP() 327 328 HandleRecoverSuccessfully(t) 329 330 recoverOpts := clusters.RecoverOpts{ 331 Operation: clusters.RebuildRecovery, 332 Check: new(bool), 333 CheckCapacity: new(bool), 334 } 335 actionID, err := clusters.Recover(fake.ServiceClient(), "edce3528-864f-41fb-8759-f4707925cc09", recoverOpts).Extract() 336 th.AssertNoErr(t, err) 337 th.AssertEquals(t, ExpectedActionID, actionID) 338} 339 340func TestAttachPolicy(t *testing.T) { 341 th.SetupHTTP() 342 defer th.TeardownHTTP() 343 344 HandleAttachPolicySuccessfully(t) 345 346 enabled := true 347 opts := clusters.AttachPolicyOpts{ 348 PolicyID: "policy1", 349 Enabled: &enabled, 350 } 351 actionID, err := clusters.AttachPolicy(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15", opts).Extract() 352 th.AssertNoErr(t, err) 353 th.AssertEquals(t, ExpectedActionID, actionID) 354} 355 356func TestDetachPolicy(t *testing.T) { 357 th.SetupHTTP() 358 defer th.TeardownHTTP() 359 360 HandleDetachPolicySuccessfully(t) 361 362 opts := clusters.DetachPolicyOpts{ 363 PolicyID: "policy1", 364 } 365 actionID, err := clusters.DetachPolicy(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15", opts).Extract() 366 th.AssertNoErr(t, err) 367 th.AssertEquals(t, ExpectedActionID, actionID) 368} 369 370func TestUpdatePolicy(t *testing.T) { 371 th.SetupHTTP() 372 defer th.TeardownHTTP() 373 374 HandleUpdatePolicySuccessfully(t) 375 376 enabled := true 377 opts := clusters.UpdatePolicyOpts{ 378 PolicyID: "policy1", 379 Enabled: &enabled, 380 } 381 actionID, err := clusters.UpdatePolicy(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15", opts).Extract() 382 th.AssertNoErr(t, err) 383 th.AssertEquals(t, ExpectedActionID, actionID) 384} 385 386func TestClusterScaleOut(t *testing.T) { 387 th.SetupHTTP() 388 defer th.TeardownHTTP() 389 390 HandleScaleOutSuccessfully(t) 391 392 scaleOutOpts := clusters.ScaleOutOpts{ 393 Count: 5, 394 } 395 actionID, err := clusters.ScaleOut(fake.ServiceClient(), "edce3528-864f-41fb-8759-f4707925cc09", scaleOutOpts).Extract() 396 th.AssertNoErr(t, err) 397 th.AssertEquals(t, ExpectedActionID, actionID) 398} 399 400func TestClusterCheck(t *testing.T) { 401 th.SetupHTTP() 402 defer th.TeardownHTTP() 403 404 HandleCheckSuccessfully(t) 405 406 actionID, err := clusters.Check(fake.ServiceClient(), "edce3528-864f-41fb-8759-f4707925cc09").Extract() 407 th.AssertNoErr(t, err) 408 th.AssertEquals(t, ExpectedActionID, actionID) 409} 410 411func TestLifecycle(t *testing.T) { 412 th.SetupHTTP() 413 defer th.TeardownHTTP() 414 415 HandleLifecycleSuccessfully(t) 416 417 opts := clusters.CompleteLifecycleOpts{ 418 LifecycleActionTokenID: "976528c6-dcf6-4d8d-9f4c-588f4e675f29", 419 } 420 421 res := clusters.CompleteLifecycle(fake.ServiceClient(), "edce3528-864f-41fb-8759-f4707925cc09", opts) 422 location := res.Header.Get("Location") 423 th.AssertEquals(t, "http://senlin.cloud.blizzard.net:8778/v1/actions/2a0ff107-e789-4660-a122-3816c43af703", location) 424 425 actionID, err := res.Extract() 426 th.AssertNoErr(t, err) 427 th.AssertEquals(t, "2a0ff107-e789-4660-a122-3816c43af703", actionID) 428} 429 430func TestAddNodes(t *testing.T) { 431 th.SetupHTTP() 432 defer th.TeardownHTTP() 433 434 HandleAddNodesSuccessfully(t) 435 436 opts := clusters.AddNodesOpts{ 437 Nodes: []string{"node1", "node2", "node3"}, 438 } 439 result, err := clusters.AddNodes(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15", opts).Extract() 440 th.AssertNoErr(t, err) 441 th.AssertEquals(t, result, "2a0ff107-e789-4660-a122-3816c43af703") 442} 443 444func TestRemoveNodes(t *testing.T) { 445 th.SetupHTTP() 446 defer th.TeardownHTTP() 447 448 HandleRemoveNodesSuccessfully(t) 449 450 opts := clusters.RemoveNodesOpts{ 451 Nodes: []string{"node1", "node2", "node3"}, 452 } 453 result, err := clusters.RemoveNodes(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15", opts).Extract() 454 th.AssertNoErr(t, err) 455 th.AssertEquals(t, result, "2a0ff107-e789-4660-a122-3816c43af703") 456} 457 458func TestReplaceNodes(t *testing.T) { 459 th.SetupHTTP() 460 defer th.TeardownHTTP() 461 HandleReplaceNodeSuccessfully(t) 462 opts := clusters.ReplaceNodesOpts{ 463 Nodes: map[string]string{"node-1234": "node-5678"}, 464 } 465 actionID, err := clusters.ReplaceNodes(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15", opts).Extract() 466 th.AssertNoErr(t, err) 467 th.AssertEquals(t, actionID, "2a0ff107-e789-4660-a122-3816c43af703") 468} 469 470func TestClusterCollect(t *testing.T) { 471 th.SetupHTTP() 472 defer th.TeardownHTTP() 473 HandleClusterCollectSuccessfully(t) 474 opts := clusters.CollectOpts{ 475 Path: "foo.bar", 476 } 477 attributes, err := clusters.Collect(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15", opts).Extract() 478 th.AssertNoErr(t, err) 479 th.AssertDeepEquals(t, ExpectedCollectAttributes, attributes) 480} 481 482func TestOperation(t *testing.T) { 483 th.SetupHTTP() 484 defer th.TeardownHTTP() 485 486 HandleOpsSuccessfully(t) 487 488 clusterOpts := clusters.OperationOpts{ 489 Operation: clusters.PauseOperation, 490 Filters: clusters.OperationFilters{"role": "slave"}, 491 Params: clusters.OperationParams{"type": "soft"}, 492 } 493 actual, err := clusters.Ops(fake.ServiceClient(), "7d85f602-a948-4a30-afd4-e84f47471c15", clusterOpts).Extract() 494 th.AssertNoErr(t, err) 495 th.AssertDeepEquals(t, OperationExpectedActionID, actual) 496} 497