1# Licensed under the Apache License, Version 2.0 (the "License"); you may 2# not use this file except in compliance with the License. You may obtain 3# a copy of the License at 4# 5# http://www.apache.org/licenses/LICENSE-2.0 6# 7# Unless required by applicable law or agreed to in writing, software 8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10# License for the specific language governing permissions and limitations 11# under the License. 12 13import copy 14import testtools 15 16from openstack.cloud import exc 17from openstack.tests.unit import base 18 19 20CLUSTERING_DICT = { 21 'name': 'fake-name', 22 'profile_id': '1', 23 'desired_capacity': 1, 24 'config': 'fake-config', 25 'max_size': 1, 26 'min_size': 1, 27 'timeout': 100, 28 'metadata': {} 29} 30 31PROFILE_DICT = { 32 'name': 'fake-profile-name', 33 'spec': {}, 34 'metadata': {} 35} 36 37POLICY_DICT = { 38 'name': 'fake-profile-name', 39 'spec': {}, 40} 41 42RECEIVER_DICT = { 43 'action': 'FAKE_CLUSTER_ACTION', 44 'cluster_id': 'fake-cluster-id', 45 'name': 'fake-receiver-name', 46 'params': {}, 47 'type': 'webhook' 48} 49 50NEW_CLUSTERING_DICT = copy.copy(CLUSTERING_DICT) 51NEW_CLUSTERING_DICT['id'] = '1' 52NEW_PROFILE_DICT = copy.copy(PROFILE_DICT) 53NEW_PROFILE_DICT['id'] = '1' 54NEW_POLICY_DICT = copy.copy(POLICY_DICT) 55NEW_POLICY_DICT['id'] = '1' 56NEW_RECEIVER_DICT = copy.copy(RECEIVER_DICT) 57NEW_RECEIVER_DICT['id'] = '1' 58 59 60class TestClustering(base.TestCase): 61 62 def assertAreInstances(self, elements, elem_type): 63 for e in elements: 64 self.assertIsInstance(e, elem_type) 65 66 def setUp(self): 67 super(TestClustering, self).setUp() 68 self.use_senlin() 69 70 def test_create_cluster(self): 71 self.register_uris([ 72 dict(method='GET', 73 uri=self.get_mock_url( 74 'clustering', 'public', append=['v1', 'profiles', '1']), 75 json={ 76 "profiles": [NEW_PROFILE_DICT]}), 77 dict(method='GET', 78 uri=self.get_mock_url( 79 'clustering', 'public', append=['v1', 'profiles']), 80 json={ 81 "profiles": [NEW_PROFILE_DICT]}), 82 dict(method='POST', 83 uri=self.get_mock_url( 84 'clustering', 'public', append=['v1', 'clusters']), 85 json=NEW_CLUSTERING_DICT) 86 ]) 87 profile = self.cloud.get_cluster_profile_by_id(NEW_PROFILE_DICT['id']) 88 c = self.cloud.create_cluster( 89 name=CLUSTERING_DICT['name'], 90 desired_capacity=CLUSTERING_DICT['desired_capacity'], 91 profile=profile, 92 config=CLUSTERING_DICT['config'], 93 max_size=CLUSTERING_DICT['max_size'], 94 min_size=CLUSTERING_DICT['min_size'], 95 metadata=CLUSTERING_DICT['metadata'], 96 timeout=CLUSTERING_DICT['timeout']) 97 98 self.assertEqual(NEW_CLUSTERING_DICT, c) 99 self.assert_calls() 100 101 def test_create_cluster_exception(self): 102 self.register_uris([ 103 dict(method='GET', 104 uri=self.get_mock_url( 105 'clustering', 'public', append=['v1', 'profiles', '1']), 106 json={ 107 "profiles": [NEW_PROFILE_DICT]}), 108 dict(method='GET', 109 uri=self.get_mock_url( 110 'clustering', 'public', append=['v1', 'profiles']), 111 json={ 112 "profiles": [NEW_PROFILE_DICT]}), 113 dict(method='POST', 114 uri=self.get_mock_url( 115 'clustering', 'public', append=['v1', 'clusters']), 116 status_code=500) 117 ]) 118 profile = self.cloud.get_cluster_profile_by_id(NEW_PROFILE_DICT['id']) 119 with testtools.ExpectedException( 120 exc.OpenStackCloudHTTPError, 121 "Error creating cluster fake-name.*"): 122 self.cloud.create_cluster(name='fake-name', profile=profile) 123 self.assert_calls() 124 125 def test_get_cluster_by_id(self): 126 self.register_uris([ 127 dict(method='GET', 128 uri=self.get_mock_url( 129 'clustering', 'public', append=['v1', 'clusters', '1']), 130 json={ 131 "cluster": NEW_CLUSTERING_DICT}) 132 ]) 133 cluster = self.cloud.get_cluster_by_id('1') 134 self.assertEqual(cluster['id'], '1') 135 self.assert_calls() 136 137 def test_get_cluster_not_found_returns_false(self): 138 self.register_uris([ 139 dict(method='GET', 140 uri=self.get_mock_url( 141 'clustering', 'public', append=['v1', 'clusters', 142 'no-cluster']), 143 status_code=404) 144 ]) 145 c = self.cloud.get_cluster_by_id('no-cluster') 146 self.assertFalse(c) 147 self.assert_calls() 148 149 def test_update_cluster(self): 150 new_max_size = 5 151 updated_cluster = copy.copy(NEW_CLUSTERING_DICT) 152 updated_cluster['max_size'] = new_max_size 153 self.register_uris([ 154 dict(method='GET', 155 uri=self.get_mock_url( 156 'clustering', 'public', append=['v1', 'clusters', '1']), 157 json={ 158 "cluster": NEW_CLUSTERING_DICT}), 159 dict(method='PATCH', 160 uri=self.get_mock_url( 161 'clustering', 'public', append=['v1', 'clusters', '1']), 162 json=updated_cluster, 163 ) 164 ]) 165 cluster = self.cloud.get_cluster_by_id('1') 166 c = self.cloud.update_cluster(cluster, new_max_size) 167 self.assertEqual(updated_cluster, c) 168 self.assert_calls() 169 170 def test_delete_cluster(self): 171 self.register_uris([ 172 dict(method='GET', 173 uri=self.get_mock_url( 174 'clustering', 'public', append=['v1', 'clusters']), 175 json={ 176 "clusters": [NEW_CLUSTERING_DICT]}), 177 dict(method='GET', 178 uri=self.get_mock_url( 179 'clustering', 'public', append=['v1', 'clusters', '1', 180 'policies']), 181 json={"cluster_policies": []}), 182 dict(method='GET', 183 uri=self.get_mock_url( 184 'clustering', 'public', append=['v1', 'receivers']), 185 json={"receivers": []}), 186 dict(method='DELETE', 187 uri=self.get_mock_url( 188 'clustering', 'public', append=['v1', 'clusters', '1']), 189 json=NEW_CLUSTERING_DICT) 190 ]) 191 self.assertTrue(self.cloud.delete_cluster('1')) 192 self.assert_calls() 193 194 def test_list_clusters(self): 195 clusters = {'clusters': [NEW_CLUSTERING_DICT]} 196 self.register_uris([ 197 dict(method='GET', 198 uri=self.get_mock_url( 199 'clustering', 'public', append=['v1', 'clusters']), 200 json=clusters) 201 ]) 202 c = self.cloud.list_clusters() 203 204 self.assertIsInstance(c, list) 205 self.assertAreInstances(c, dict) 206 207 self.assert_calls() 208 209 def test_attach_policy_to_cluster(self): 210 policy = { 211 'policy_id': '1', 212 'enabled': 'true' 213 } 214 self.register_uris([ 215 dict(method='GET', 216 uri=self.get_mock_url( 217 'clustering', 'public', append=['v1', 'clusters', '1']), 218 json={ 219 "cluster": NEW_CLUSTERING_DICT}), 220 dict(method='GET', 221 uri=self.get_mock_url( 222 'clustering', 'public', append=['v1', 'policies', '1']), 223 json={ 224 "policy": NEW_POLICY_DICT}), 225 dict(method='POST', 226 uri=self.get_mock_url( 227 'clustering', 'public', append=['v1', 'clusters', '1', 228 'actions']), 229 json={'policy_attach': policy}) 230 ]) 231 cluster = self.cloud.get_cluster_by_id('1') 232 policy = self.cloud.get_cluster_policy_by_id('1') 233 p = self.cloud.attach_policy_to_cluster(cluster, policy, 'true') 234 self.assertTrue(p) 235 self.assert_calls() 236 237 def test_detach_policy_from_cluster(self): 238 updated_cluster = copy.copy(NEW_CLUSTERING_DICT) 239 updated_cluster['policies'] = ['1'] 240 detached_cluster = copy.copy(NEW_CLUSTERING_DICT) 241 detached_cluster['policies'] = [] 242 243 self.register_uris([ 244 dict(method='GET', 245 uri=self.get_mock_url( 246 'clustering', 'public', append=['v1', 'clusters', '1']), 247 json={ 248 "cluster": NEW_CLUSTERING_DICT}), 249 dict(method='GET', 250 uri=self.get_mock_url( 251 'clustering', 'public', append=['v1', 'policies', '1']), 252 json={ 253 "policy": NEW_POLICY_DICT}), 254 dict(method='POST', 255 uri=self.get_mock_url( 256 'clustering', 'public', append=['v1', 'clusters', '1', 257 'actions']), 258 json={'policy_detach': {'policy_id': '1'}}), 259 dict(method='GET', 260 uri=self.get_mock_url( 261 'clustering', 'public', append=['v1', 'clusters', '1']), 262 json={ 263 "cluster": updated_cluster}), 264 dict(method='GET', 265 uri=self.get_mock_url( 266 'clustering', 'public', append=['v1', 'clusters', '1']), 267 json={ 268 "cluster": detached_cluster}), 269 ]) 270 cluster = self.cloud.get_cluster_by_id('1') 271 policy = self.cloud.get_cluster_policy_by_id('1') 272 p = self.cloud.detach_policy_from_cluster(cluster, policy, wait=True) 273 self.assertTrue(p) 274 self.assert_calls() 275 276 def test_get_policy_on_cluster_by_id(self): 277 cluster_policy = { 278 "cluster_id": "1", 279 "cluster_name": "cluster1", 280 "enabled": True, 281 "id": "1", 282 "policy_id": "1", 283 "policy_name": "policy1", 284 "policy_type": "senlin.policy.deletion-1.0" 285 } 286 287 self.register_uris([ 288 dict(method='GET', 289 uri=self.get_mock_url( 290 'clustering', 'public', append=['v1', 'clusters', '1', 291 'policies', '1']), 292 json={ 293 "cluster_policy": cluster_policy}) 294 ]) 295 policy = self.cloud.get_policy_on_cluster('1', '1') 296 self.assertEqual(policy['cluster_id'], '1') 297 self.assert_calls() 298 299 def test_get_policy_on_cluster_not_found_returns_false(self): 300 self.register_uris([ 301 dict(method='GET', 302 uri=self.get_mock_url( 303 'clustering', 'public', append=['v1', 'clusters', '1', 304 'policies', 'no-policy']), 305 status_code=404) 306 ]) 307 p = self.cloud.get_policy_on_cluster('1', 'no-policy') 308 self.assertFalse(p) 309 self.assert_calls() 310 311 def test_update_policy_on_cluster(self): 312 policy = { 313 'policy_id': '1', 314 'enabled': 'true' 315 } 316 updated_cluster = copy.copy(NEW_CLUSTERING_DICT) 317 updated_cluster['policies'] = policy 318 self.register_uris([ 319 dict(method='GET', 320 uri=self.get_mock_url( 321 'clustering', 'public', append=['v1', 'clusters', '1']), 322 json={ 323 "cluster": NEW_CLUSTERING_DICT}), 324 dict(method='GET', 325 uri=self.get_mock_url( 326 'clustering', 'public', append=['v1', 'policies', 327 '1']), 328 json={ 329 "policy": NEW_POLICY_DICT}), 330 dict(method='POST', 331 uri=self.get_mock_url( 332 'clustering', 'public', append=['v1', 'clusters', '1', 333 'actions']), 334 json={'policies': []}) 335 ]) 336 cluster = self.cloud.get_cluster_by_id('1') 337 policy = self.cloud.get_cluster_policy_by_id('1') 338 p = self.cloud.update_policy_on_cluster(cluster, policy, True) 339 self.assertTrue(p) 340 self.assert_calls() 341 342 def test_get_policy_on_cluster(self): 343 cluster_policy = { 344 'cluster_id': '1', 345 'cluster_name': 'cluster1', 346 'enabled': 'true', 347 'id': '1', 348 'policy_id': '1', 349 'policy_name': 'policy1', 350 'policy_type': 'type' 351 } 352 353 self.register_uris([ 354 dict(method='GET', 355 uri=self.get_mock_url( 356 'clustering', 'public', append=['v1', 'clusters', '1', 357 'policies', '1']), 358 json={ 359 "cluster_policy": cluster_policy}) 360 ]) 361 get_policy = self.cloud.get_policy_on_cluster('1', '1') 362 self.assertEqual(get_policy, cluster_policy) 363 self.assert_calls() 364 365 def test_create_cluster_profile(self): 366 self.register_uris([ 367 dict(method='POST', 368 uri=self.get_mock_url( 369 'clustering', 'public', append=['v1', 'profiles']), 370 json={'profile': NEW_PROFILE_DICT}) 371 ]) 372 p = self.cloud.create_cluster_profile('fake-profile-name', {}) 373 374 self.assertEqual(NEW_PROFILE_DICT, p) 375 self.assert_calls() 376 377 def test_create_cluster_profile_exception(self): 378 self.register_uris([ 379 dict(method='POST', 380 uri=self.get_mock_url( 381 'clustering', 'public', append=['v1', 'profiles']), 382 status_code=500) 383 ]) 384 with testtools.ExpectedException( 385 exc.OpenStackCloudHTTPError, 386 "Error creating profile fake-profile-name.*"): 387 self.cloud.create_cluster_profile('fake-profile-name', {}) 388 self.assert_calls() 389 390 def test_list_cluster_profiles(self): 391 profiles = {'profiles': [NEW_PROFILE_DICT]} 392 self.register_uris([ 393 dict(method='GET', 394 uri=self.get_mock_url( 395 'clustering', 'public', append=['v1', 'profiles']), 396 json=profiles) 397 ]) 398 p = self.cloud.list_cluster_profiles() 399 400 self.assertIsInstance(p, list) 401 self.assertAreInstances(p, dict) 402 403 self.assert_calls() 404 405 def test_get_cluster_profile_by_id(self): 406 self.register_uris([ 407 dict(method='GET', 408 uri=self.get_mock_url( 409 'clustering', 'public', append=['v1', 'profiles', '1']), 410 json={ 411 "profile": NEW_PROFILE_DICT}) 412 ]) 413 p = self.cloud.get_cluster_profile_by_id('1') 414 self.assertEqual(p['id'], '1') 415 self.assert_calls() 416 417 def test_get_cluster_profile_not_found_returns_false(self): 418 self.register_uris([ 419 dict(method='GET', 420 uri=self.get_mock_url( 421 'clustering', 'public', append=['v1', 'profiles', 422 'no-profile']), 423 status_code=404) 424 ]) 425 p = self.cloud.get_cluster_profile_by_id('no-profile') 426 self.assertFalse(p) 427 self.assert_calls() 428 429 def test_update_cluster_profile(self): 430 new_name = "new-name" 431 updated_profile = copy.copy(NEW_PROFILE_DICT) 432 updated_profile['name'] = new_name 433 self.register_uris([ 434 dict(method='GET', 435 uri=self.get_mock_url( 436 'clustering', 'public', append=['v1', 'profiles']), 437 json={ 438 "profiles": [NEW_PROFILE_DICT]}), 439 dict(method='PATCH', 440 uri=self.get_mock_url( 441 'clustering', 'public', append=['v1', 'profiles', '1']), 442 json=updated_profile, 443 ) 444 ]) 445 p = self.cloud.update_cluster_profile('1', new_name=new_name) 446 self.assertEqual(updated_profile, p) 447 self.assert_calls() 448 449 def test_delete_cluster_profile(self): 450 self.register_uris([ 451 dict(method='GET', 452 uri=self.get_mock_url( 453 'clustering', 'public', append=['v1', 'profiles', '1']), 454 json={ 455 "profile": NEW_PROFILE_DICT}), 456 dict(method='GET', 457 uri=self.get_mock_url( 458 'clustering', 'public', append=['v1', 'clusters']), 459 json={}), 460 dict(method='DELETE', 461 uri=self.get_mock_url( 462 'clustering', 'public', append=['v1', 'profiles', '1']), 463 json=NEW_PROFILE_DICT) 464 ]) 465 profile = self.cloud.get_cluster_profile_by_id('1') 466 self.assertTrue(self.cloud.delete_cluster_profile(profile)) 467 self.assert_calls() 468 469 def test_create_cluster_policy(self): 470 self.register_uris([ 471 dict(method='POST', 472 uri=self.get_mock_url( 473 'clustering', 'public', append=['v1', 'policies']), 474 json={'policy': NEW_POLICY_DICT}) 475 ]) 476 p = self.cloud.create_cluster_policy('fake-policy-name', {}) 477 478 self.assertEqual(NEW_POLICY_DICT, p) 479 self.assert_calls() 480 481 def test_create_cluster_policy_exception(self): 482 self.register_uris([ 483 dict(method='POST', 484 uri=self.get_mock_url( 485 'clustering', 'public', append=['v1', 'policies']), 486 status_code=500) 487 ]) 488 with testtools.ExpectedException( 489 exc.OpenStackCloudHTTPError, 490 "Error creating policy fake-policy-name.*"): 491 self.cloud.create_cluster_policy('fake-policy-name', {}) 492 self.assert_calls() 493 494 def test_list_cluster_policies(self): 495 policies = {'policies': [NEW_POLICY_DICT]} 496 self.register_uris([ 497 dict(method='GET', 498 uri=self.get_mock_url( 499 'clustering', 'public', append=['v1', 'policies']), 500 json=policies) 501 ]) 502 p = self.cloud.list_cluster_policies() 503 504 self.assertIsInstance(p, list) 505 self.assertAreInstances(p, dict) 506 507 self.assert_calls() 508 509 def test_get_cluster_policy_by_id(self): 510 self.register_uris([ 511 dict(method='GET', 512 uri=self.get_mock_url( 513 'clustering', 'public', append=['v1', 'policies', '1']), 514 json={ 515 "policy": NEW_POLICY_DICT}) 516 ]) 517 p = self.cloud.get_cluster_policy_by_id('1') 518 self.assertEqual(p['id'], '1') 519 self.assert_calls() 520 521 def test_get_cluster_policy_not_found_returns_false(self): 522 self.register_uris([ 523 dict(method='GET', 524 uri=self.get_mock_url( 525 'clustering', 'public', append=['v1', 'policies', 526 'no-policy']), 527 status_code=404) 528 ]) 529 p = self.cloud.get_cluster_policy_by_id('no-policy') 530 self.assertFalse(p) 531 self.assert_calls() 532 533 def test_update_cluster_policy(self): 534 new_name = "new-name" 535 updated_policy = copy.copy(NEW_POLICY_DICT) 536 updated_policy['name'] = new_name 537 self.register_uris([ 538 dict(method='GET', 539 uri=self.get_mock_url( 540 'clustering', 'public', append=['v1', 'policies']), 541 json={ 542 "policies": [NEW_POLICY_DICT]}), 543 dict(method='PATCH', 544 uri=self.get_mock_url( 545 'clustering', 'public', append=['v1', 'policies', '1']), 546 json=updated_policy, 547 ) 548 ]) 549 p = self.cloud.update_cluster_policy('1', new_name=new_name) 550 self.assertEqual(updated_policy, p) 551 self.assert_calls() 552 553 def test_delete_cluster_policy(self): 554 self.register_uris([ 555 dict(method='GET', 556 uri=self.get_mock_url( 557 'clustering', 'public', append=['v1', 'policies', '1']), 558 json={ 559 "policy": NEW_POLICY_DICT}), 560 dict(method='GET', 561 uri=self.get_mock_url( 562 'clustering', 'public', append=['v1', 'clusters']), 563 json={}), 564 dict(method='DELETE', 565 uri=self.get_mock_url( 566 'clustering', 'public', append=['v1', 'policies', '1']), 567 json=NEW_POLICY_DICT) 568 ]) 569 self.assertTrue(self.cloud.delete_cluster_policy('1')) 570 self.assert_calls() 571 572 def test_create_cluster_receiver(self): 573 clusters = {'clusters': [NEW_CLUSTERING_DICT]} 574 self.register_uris([ 575 dict(method='GET', 576 uri=self.get_mock_url( 577 'clustering', 'public', append=['v1', 'clusters']), 578 json=clusters), 579 dict(method='POST', 580 uri=self.get_mock_url( 581 'clustering', 'public', append=['v1', 'receivers']), 582 json={'receiver': NEW_RECEIVER_DICT}) 583 ]) 584 r = self.cloud.create_cluster_receiver('fake-receiver-name', {}) 585 586 self.assertEqual(NEW_RECEIVER_DICT, r) 587 self.assert_calls() 588 589 def test_create_cluster_receiver_exception(self): 590 clusters = {'clusters': [NEW_CLUSTERING_DICT]} 591 self.register_uris([ 592 dict(method='GET', 593 uri=self.get_mock_url( 594 'clustering', 'public', append=['v1', 'clusters']), 595 json=clusters), 596 dict(method='POST', 597 uri=self.get_mock_url( 598 'clustering', 'public', append=['v1', 'receivers']), 599 status_code=500), 600 ]) 601 with testtools.ExpectedException( 602 exc.OpenStackCloudHTTPError, 603 "Error creating receiver fake-receiver-name.*"): 604 self.cloud.create_cluster_receiver('fake-receiver-name', {}) 605 self.assert_calls() 606 607 def test_list_cluster_receivers(self): 608 receivers = {'receivers': [NEW_RECEIVER_DICT]} 609 self.register_uris([ 610 dict(method='GET', 611 uri=self.get_mock_url( 612 'clustering', 'public', append=['v1', 'receivers']), 613 json=receivers) 614 ]) 615 r = self.cloud.list_cluster_receivers() 616 617 self.assertIsInstance(r, list) 618 self.assertAreInstances(r, dict) 619 620 self.assert_calls() 621 622 def test_get_cluster_receiver_by_id(self): 623 self.register_uris([ 624 dict(method='GET', 625 uri=self.get_mock_url( 626 'clustering', 'public', append=['v1', 'receivers', '1']), 627 json={ 628 "receiver": NEW_RECEIVER_DICT}) 629 ]) 630 r = self.cloud.get_cluster_receiver_by_id('1') 631 self.assertEqual(r['id'], '1') 632 self.assert_calls() 633 634 def test_get_cluster_receiver_not_found_returns_false(self): 635 self.register_uris([ 636 dict(method='GET', 637 uri=self.get_mock_url( 638 'clustering', 'public', append=['v1', 'receivers', 639 'no-receiver']), 640 json={'receivers': []}) 641 ]) 642 p = self.cloud.get_cluster_receiver_by_id('no-receiver') 643 self.assertFalse(p) 644 self.assert_calls() 645 646 def test_update_cluster_receiver(self): 647 new_name = "new-name" 648 updated_receiver = copy.copy(NEW_RECEIVER_DICT) 649 updated_receiver['name'] = new_name 650 self.register_uris([ 651 dict(method='GET', 652 uri=self.get_mock_url( 653 'clustering', 'public', append=['v1', 'receivers']), 654 json={ 655 "receivers": [NEW_RECEIVER_DICT]}), 656 dict(method='PATCH', 657 uri=self.get_mock_url( 658 'clustering', 'public', append=['v1', 'receivers', '1']), 659 json=updated_receiver, 660 ) 661 ]) 662 r = self.cloud.update_cluster_receiver('1', new_name=new_name) 663 self.assertEqual(updated_receiver, r) 664 self.assert_calls() 665 666 def test_delete_cluster_receiver(self): 667 self.register_uris([ 668 dict(method='GET', 669 uri=self.get_mock_url( 670 'clustering', 'public', append=['v1', 'receivers']), 671 json={ 672 "receivers": [NEW_RECEIVER_DICT]}), 673 dict(method='DELETE', 674 uri=self.get_mock_url( 675 'clustering', 'public', append=['v1', 'receivers', '1']), 676 json=NEW_RECEIVER_DICT), 677 dict(method='GET', 678 uri=self.get_mock_url( 679 'clustering', 'public', append=['v1', 'receivers', '1']), 680 json={}), 681 ]) 682 self.assertTrue(self.cloud.delete_cluster_receiver('1', wait=True)) 683 self.assert_calls() 684