watcher-tempest-plugin 3.6.0__tar.gz → 3.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- watcher_tempest_plugin-3.8.0/.zuul.yaml +66 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/AUTHORS +2 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/ChangeLog +27 -0
- {watcher_tempest_plugin-3.6.0/watcher_tempest_plugin.egg-info → watcher_tempest_plugin-3.8.0}/PKG-INFO +17 -4
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/README.rst +4 -0
- watcher_tempest_plugin-3.8.0/releasenotes/notes/parametrize-promtool-write-url-path-3534f2b9.yaml +8 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/setup.cfg +2 -2
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/config.py +18 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/infra_optim_clients.py +1 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/metric/prometheus_client.py +43 -8
- watcher_tempest_plugin-3.8.0/watcher_tempest_plugin/tests/api/admin/base.py +114 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/test_action.py +49 -23
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/test_action_plan.py +25 -10
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/test_audit.py +254 -78
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/test_audit_template.py +6 -7
- watcher_tempest_plugin-3.8.0/watcher_tempest_plugin/tests/common/base.py +375 -0
- watcher_tempest_plugin-3.8.0/watcher_tempest_plugin/tests/scenario/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/base.py +9 -92
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_continuous_audit.py +11 -1
- watcher_tempest_plugin-3.8.0/watcher_tempest_plugin/tests/scenario/test_execute_zone_migration.py +464 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0/watcher_tempest_plugin.egg-info}/PKG-INFO +17 -4
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin.egg-info/SOURCES.txt +3 -0
- watcher_tempest_plugin-3.8.0/watcher_tempest_plugin.egg-info/pbr.json +1 -0
- watcher_tempest_plugin-3.6.0/.zuul.yaml +0 -49
- watcher_tempest_plugin-3.6.0/watcher_tempest_plugin/tests/api/admin/base.py +0 -378
- watcher_tempest_plugin-3.6.0/watcher_tempest_plugin/tests/scenario/test_execute_zone_migration.py +0 -197
- watcher_tempest_plugin-3.6.0/watcher_tempest_plugin.egg-info/pbr.json +0 -1
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/.coveragerc +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/.mailmap +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/.stestr.conf +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/.testr.conf +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/CONTRIBUTING.rst +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/HACKING.rst +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/LICENSE +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/doc/requirements.txt +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/doc/source/conf.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/doc/source/contributing.rst +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/doc/source/index.rst +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/doc/source/readme.rst +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/pyproject.toml +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/releasenotes/notes/.placeholder +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/releasenotes/notes/drop-py-2-7-eb1979587d237f5e.yaml +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/releasenotes/notes/drop-python38-support-eeb09a8bc0170ce2.yaml +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/releasenotes/source/_static/.placeholder +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/releasenotes/source/_templates/.placeholder +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/releasenotes/source/conf.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/releasenotes/source/index.rst +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/releasenotes/source/unreleased.rst +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/requirements.txt +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/setup.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/test-requirements.txt +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/tox.ini +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/plugin.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/base.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/infra_optim/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/infra_optim/v1/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/infra_optim/v1/json/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/infra_optim/v1/json/api_microversion_fixture.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/infra_optim/v1/json/client.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/metric/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/metric/v1/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/metric/v1/json/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/services/metric/v1/json/client.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/test_api_discovery.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/test_data_model.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/test_goal.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/test_scoring_engine.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/test_service.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/api/admin/test_strategy.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/v1/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/v1/base.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/v1/test_action.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/v1/test_action_plan.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/v1/test_audit.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/v1/test_audit_template.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/v1/test_goal.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/v1/test_scoring_engine.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/v1/test_service.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/client_functional/v1/test_strategy.py +0 -0
- {watcher_tempest_plugin-3.6.0/watcher_tempest_plugin/tests/scenario → watcher_tempest_plugin-3.8.0/watcher_tempest_plugin/tests/common}/__init__.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_data_model.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_execute_actuator.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_execute_basic_optim.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_execute_dummy_optim.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_execute_host_maintenance.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_execute_node_resource_consolidation.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_execute_storage_balance.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_execute_strategies_real.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_execute_vm_workload_consolidation.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_execute_workload_balance.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/tests/scenario/test_execute_workload_stabilization.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/utils.py +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin.egg-info/dependency_links.txt +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin.egg-info/entry_points.txt +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin.egg-info/not-zip-safe +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin.egg-info/requires.txt +0 -0
- {watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
- project:
|
|
2
|
+
queue: watcher
|
|
3
|
+
templates:
|
|
4
|
+
- check-requirements
|
|
5
|
+
- tempest-plugin-jobs
|
|
6
|
+
- publish-openstack-docs-pti
|
|
7
|
+
- release-notes-jobs-python3
|
|
8
|
+
check:
|
|
9
|
+
jobs:
|
|
10
|
+
- watcher-tempest-aetos
|
|
11
|
+
- watcher-tempest-gnocchi
|
|
12
|
+
- watcher-tempest-prometheus
|
|
13
|
+
- watcher-tempest-aetos-2026-1
|
|
14
|
+
- watcher-tempest-gnocchi-2026-1
|
|
15
|
+
- watcher-tempest-aetos-2025-2
|
|
16
|
+
- watcher-tempest-gnocchi-2025-2
|
|
17
|
+
- watcher-tempest-gnocchi-2025-1
|
|
18
|
+
- watcher-tempest-prometheus-2025-1
|
|
19
|
+
gate:
|
|
20
|
+
jobs:
|
|
21
|
+
- watcher-tempest-aetos
|
|
22
|
+
- watcher-tempest-gnocchi
|
|
23
|
+
- watcher-tempest-prometheus
|
|
24
|
+
- watcher-tempest-aetos-2026-1
|
|
25
|
+
- watcher-tempest-gnocchi-2026-1
|
|
26
|
+
- watcher-tempest-aetos-2025-2
|
|
27
|
+
- watcher-tempest-gnocchi-2025-2
|
|
28
|
+
- watcher-tempest-gnocchi-2025-1
|
|
29
|
+
- watcher-tempest-prometheus-2025-1
|
|
30
|
+
experimental:
|
|
31
|
+
jobs:
|
|
32
|
+
- watcher-tempest-prometheus-realdata
|
|
33
|
+
- watcher-tempest-aetos-realdata
|
|
34
|
+
|
|
35
|
+
# stable/2026.1 jobs
|
|
36
|
+
- job:
|
|
37
|
+
name: watcher-tempest-aetos-2026-1
|
|
38
|
+
parent: watcher-tempest-aetos
|
|
39
|
+
override-checkout: stable/2026.1
|
|
40
|
+
|
|
41
|
+
- job:
|
|
42
|
+
name: watcher-tempest-gnocchi-2026-1
|
|
43
|
+
parent: watcher-tempest-gnocchi
|
|
44
|
+
override-checkout: stable/2026.1
|
|
45
|
+
|
|
46
|
+
# stable/2025.2 jobs
|
|
47
|
+
- job:
|
|
48
|
+
name: watcher-tempest-aetos-2025-2
|
|
49
|
+
parent: watcher-tempest-aetos
|
|
50
|
+
override-checkout: stable/2025.2
|
|
51
|
+
|
|
52
|
+
- job:
|
|
53
|
+
name: watcher-tempest-gnocchi-2025-2
|
|
54
|
+
parent: watcher-tempest-gnocchi
|
|
55
|
+
override-checkout: stable/2025.2
|
|
56
|
+
|
|
57
|
+
# stable/2025.1 jobs
|
|
58
|
+
- job:
|
|
59
|
+
name: watcher-tempest-gnocchi-2025-1
|
|
60
|
+
parent: watcher-tempest-gnocchi
|
|
61
|
+
override-checkout: stable/2025.1
|
|
62
|
+
|
|
63
|
+
- job:
|
|
64
|
+
name: watcher-tempest-prometheus-2025-1
|
|
65
|
+
parent: watcher-tempest-prometheus
|
|
66
|
+
override-checkout: stable/2025.1
|
|
@@ -9,10 +9,12 @@ Dantali0n <info@dantalion.nl>
|
|
|
9
9
|
David TARDIVEL <David.TARDIVEL@b-com.com>
|
|
10
10
|
Douglas Viroel <viroel@gmail.com>
|
|
11
11
|
Drew Thorstensen <thorst@us.ibm.com>
|
|
12
|
+
Ghanshyam Maan <gmaan@ghanshyammann.com>
|
|
12
13
|
Ghanshyam Mann <gmann@ghanshyammann.com>
|
|
13
14
|
Gábor Antal <antal@inf.u-szeged.hu>
|
|
14
15
|
Hervé Beraud <hberaud@redhat.com>
|
|
15
16
|
Hidekazu Nakamura <hid-nakamura@vf.jp.nec.com>
|
|
17
|
+
Ivan Anfimov <lazekteam@gmail.com>
|
|
16
18
|
Jaewoo Park <jp655p@att.com>
|
|
17
19
|
Jaromir Wysoglad <jwysogla@redhat.com>
|
|
18
20
|
Ken'ichi Ohmichi <ken-oomichi@wx.jp.nec.com>
|
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
CHANGES
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
+
3.8.0
|
|
5
|
+
-----
|
|
6
|
+
|
|
7
|
+
* Remove 2024.2 jobs from the zuul gates
|
|
8
|
+
* Add stable/2026.1 job
|
|
9
|
+
* Parametrize promtool write URL path
|
|
10
|
+
* Add extra checks to zone migration retype test
|
|
11
|
+
* Test zone migration volume and compute migrations
|
|
12
|
+
|
|
13
|
+
3.7.0
|
|
14
|
+
-----
|
|
15
|
+
|
|
16
|
+
* Add test for volume migrate with zone migration
|
|
17
|
+
* Add project badge
|
|
18
|
+
* Consolidate and improve Zuul CI jobs for stable branches
|
|
19
|
+
* Fix unsupported operand types in internal methods
|
|
20
|
+
* Refresh the state of the actionplan before asserting status
|
|
21
|
+
* Fix experimental job names after refactoring watcher jobs
|
|
22
|
+
* Add config flags to control zone migration test execution
|
|
23
|
+
* Skip test api.admin.test\_audit.TestShowListAudit.test\_list\_with\_limit
|
|
24
|
+
* Consolidate and improve Zuul CI job definitions
|
|
25
|
+
* Wait action plan to finish before asserting state
|
|
26
|
+
* Improved continuous audit api test coverage
|
|
27
|
+
* Refactor: Extract common test utilities into shared base class
|
|
28
|
+
* Drop job to test unmaintained 2024.1 branch
|
|
29
|
+
* Drop python 3.9 and support python 3.13
|
|
30
|
+
|
|
4
31
|
3.6.0
|
|
5
32
|
-----
|
|
6
33
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: watcher-tempest-plugin
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.8.0
|
|
4
4
|
Summary: Tempest plugin watcher-tempest-plugin
|
|
5
5
|
Home-page: https://docs.openstack.org/watcher/latest/
|
|
6
6
|
Author: OpenStack
|
|
@@ -14,22 +14,35 @@ Classifier: Programming Language :: Python
|
|
|
14
14
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
15
15
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
22
|
License-File: LICENSE
|
|
23
23
|
Requires-Dist: pbr>=3.1.1
|
|
24
24
|
Requires-Dist: oslo.log>=3.36.0
|
|
25
25
|
Requires-Dist: oslo.utils>=3.33.0
|
|
26
26
|
Requires-Dist: tempest>=27.0.0
|
|
27
27
|
Requires-Dist: os-traits>=0.15.0
|
|
28
|
+
Dynamic: author
|
|
29
|
+
Dynamic: author-email
|
|
30
|
+
Dynamic: classifier
|
|
31
|
+
Dynamic: description
|
|
32
|
+
Dynamic: home-page
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
Dynamic: requires-dist
|
|
35
|
+
Dynamic: requires-python
|
|
36
|
+
Dynamic: summary
|
|
28
37
|
|
|
29
38
|
======================
|
|
30
39
|
watcher-tempest-plugin
|
|
31
40
|
======================
|
|
32
41
|
|
|
42
|
+
.. image:: https://governance.openstack.org/tc/badges/watcher-tempest-plugin.svg
|
|
43
|
+
|
|
44
|
+
.. Change things from this point on
|
|
45
|
+
|
|
33
46
|
This repository contains a `Tempest`_ `test plugin`_ to verify the
|
|
34
47
|
functionality of the `Watcher`_ service.
|
|
35
48
|
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
watcher-tempest-plugin
|
|
3
3
|
======================
|
|
4
4
|
|
|
5
|
+
.. image:: https://governance.openstack.org/tc/badges/watcher-tempest-plugin.svg
|
|
6
|
+
|
|
7
|
+
.. Change things from this point on
|
|
8
|
+
|
|
5
9
|
This repository contains a `Tempest`_ `test plugin`_ to verify the
|
|
6
10
|
functionality of the `Watcher`_ service.
|
|
7
11
|
|
watcher_tempest_plugin-3.8.0/releasenotes/notes/parametrize-promtool-write-url-path-3534f2b9.yaml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
features:
|
|
3
|
+
- |
|
|
4
|
+
Added a new ``prometheus_write_path`` configuration option under the
|
|
5
|
+
``[optimize]`` section to allow customizing the URL path appended to the
|
|
6
|
+
Prometheus base URL for remote write operations. The default value is
|
|
7
|
+
``/api/v1/write``, preserving the existing behavior. Set it to an empty
|
|
8
|
+
string if the base URL already includes the full write endpoint.
|
|
@@ -6,7 +6,7 @@ description_file =
|
|
|
6
6
|
author = OpenStack
|
|
7
7
|
author_email = openstack-discuss@lists.openstack.org
|
|
8
8
|
home_page = https://docs.openstack.org/watcher/latest/
|
|
9
|
-
python_requires = >=3.
|
|
9
|
+
python_requires = >=3.10
|
|
10
10
|
classifier =
|
|
11
11
|
Environment :: OpenStack
|
|
12
12
|
Intended Audience :: Information Technology
|
|
@@ -17,10 +17,10 @@ classifier =
|
|
|
17
17
|
Programming Language :: Python :: Implementation :: CPython
|
|
18
18
|
Programming Language :: Python :: 3 :: Only
|
|
19
19
|
Programming Language :: Python :: 3
|
|
20
|
-
Programming Language :: Python :: 3.9
|
|
21
20
|
Programming Language :: Python :: 3.10
|
|
22
21
|
Programming Language :: Python :: 3.11
|
|
23
22
|
Programming Language :: Python :: 3.12
|
|
23
|
+
Programming Language :: Python :: 3.13
|
|
24
24
|
|
|
25
25
|
[files]
|
|
26
26
|
packages =
|
{watcher_tempest_plugin-3.6.0 → watcher_tempest_plugin-3.8.0}/watcher_tempest_plugin/config.py
RENAMED
|
@@ -96,6 +96,13 @@ OptimizationGroup = [
|
|
|
96
96
|
help="The label that Prometheus uses to store the fqdn of "
|
|
97
97
|
"exporters.",
|
|
98
98
|
),
|
|
99
|
+
cfg.StrOpt(
|
|
100
|
+
"prometheus_write_path",
|
|
101
|
+
default="/api/v1/write",
|
|
102
|
+
help="The URL path to append to the Prometheus base URL for "
|
|
103
|
+
"remote write operations. Set to an empty string if the "
|
|
104
|
+
"base URL already includes the full write endpoint.",
|
|
105
|
+
),
|
|
99
106
|
# Podified control plane configuration
|
|
100
107
|
cfg.StrOpt(
|
|
101
108
|
"podified_kubeconfig_path",
|
|
@@ -144,4 +151,15 @@ OptimizationGroup = [
|
|
|
144
151
|
"`watcher_cluster_data_model_collectors` period configuration is "
|
|
145
152
|
"less than 300 seconds."
|
|
146
153
|
),
|
|
154
|
+
cfg.BoolOpt(
|
|
155
|
+
"run_zone_migration_extra_tests",
|
|
156
|
+
default=False,
|
|
157
|
+
help="Whether or not to run extra zone migration tests that test"
|
|
158
|
+
"migration without specified destination nodes."
|
|
159
|
+
),
|
|
160
|
+
cfg.BoolOpt(
|
|
161
|
+
"run_zone_migration_storage_tests",
|
|
162
|
+
default=False,
|
|
163
|
+
help="Whether or not to run storage zone migration tests."
|
|
164
|
+
),
|
|
147
165
|
]
|
|
@@ -55,6 +55,7 @@ class BaseManager(clients.Manager, metaclass=abc.ABCMeta):
|
|
|
55
55
|
podified_kubeconfig=CONF.optimize.podified_kubeconfig_path,
|
|
56
56
|
prometheus_ssl_cert=CONF.optimize.prometheus_ssl_cert_dir,
|
|
57
57
|
prometheus_fqdn_label=CONF.optimize.prometheus_fqdn_label,
|
|
58
|
+
write_url_path=CONF.optimize.prometheus_write_path,
|
|
58
59
|
)
|
|
59
60
|
|
|
60
61
|
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
# under the License.
|
|
14
14
|
|
|
15
15
|
import json
|
|
16
|
+
from urllib import parse
|
|
16
17
|
|
|
17
18
|
from oslo_log import log
|
|
18
|
-
from urllib.parse import quote
|
|
19
19
|
|
|
20
20
|
from watcher_tempest_plugin.services import base
|
|
21
21
|
|
|
@@ -31,8 +31,32 @@ class PromtoolClient:
|
|
|
31
31
|
proxy_host_pkey=None, proxy_host_pkey_type='rsa',
|
|
32
32
|
podified_ns=None, podified_kubeconfig=None,
|
|
33
33
|
prometheus_ssl_cert=None,
|
|
34
|
-
prometheus_fqdn_label="fqdn"
|
|
35
|
-
|
|
34
|
+
prometheus_fqdn_label="fqdn",
|
|
35
|
+
write_url_path=None):
|
|
36
|
+
"""Initialize PromtoolClient.
|
|
37
|
+
|
|
38
|
+
:param url: Base URL of the Prometheus server (e.g.
|
|
39
|
+
'http://host:9090').
|
|
40
|
+
:param promtool_path: Path to the promtool binary.
|
|
41
|
+
:param openstack_type: Deployment type; use 'podified' for
|
|
42
|
+
Podified Control Plane deployments, 'devstack' otherwise.
|
|
43
|
+
:param proxy_host_address: Optional SSH proxy host address. When
|
|
44
|
+
provided together with proxy_host_user, commands are executed
|
|
45
|
+
over SSH instead of locally.
|
|
46
|
+
:param proxy_host_user: SSH username for the proxy host.
|
|
47
|
+
:param proxy_host_pkey: Path to the SSH private key file.
|
|
48
|
+
:param proxy_host_pkey_type: Type of the SSH private key
|
|
49
|
+
(default: 'rsa').
|
|
50
|
+
:param podified_ns: Kubernetes namespace for podified deployments.
|
|
51
|
+
:param podified_kubeconfig: Path to the kubeconfig file for
|
|
52
|
+
podified deployments.
|
|
53
|
+
:param prometheus_ssl_cert: Directory containing SSL certificates
|
|
54
|
+
used when connecting to Prometheus over HTTPS.
|
|
55
|
+
:param prometheus_fqdn_label: Prometheus label used to identify
|
|
56
|
+
host FQDNs in target metadata (default: 'fqdn').
|
|
57
|
+
:param write_url_path: URL path for the remote-write endpoint
|
|
58
|
+
(default: '/api/v1/write').
|
|
59
|
+
"""
|
|
36
60
|
# Podified Control Plane
|
|
37
61
|
self.is_podified = ("podified" == openstack_type)
|
|
38
62
|
LOG.debug(f"Configuring PromtoolClient for {openstack_type} "
|
|
@@ -61,12 +85,23 @@ class PromtoolClient:
|
|
|
61
85
|
cmd_prefix = self.oc_cmd + ["rsh", self.prometheus_pod]
|
|
62
86
|
self.client.cmd_prefix = " ".join(cmd_prefix)
|
|
63
87
|
|
|
88
|
+
# We keep the raw URL for reference/labels
|
|
64
89
|
self.prometheus_url = url
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
90
|
+
|
|
91
|
+
# Internal base_url ensuring a trailing slash for reliable joining
|
|
92
|
+
base_url = url if url.endswith('/') else url + '/'
|
|
93
|
+
|
|
94
|
+
# Handle write_url_path: handles None/Empty and leading slash issues
|
|
95
|
+
clean_write_path = (write_url_path or "").lstrip('/')
|
|
96
|
+
self.prometheus_write_url = parse.urljoin(base_url, clean_write_path)
|
|
97
|
+
|
|
98
|
+
self.prometheus_delete_series_url = parse.urljoin(
|
|
99
|
+
base_url, "api/v1/admin/tsdb/delete_series"
|
|
100
|
+
)
|
|
68
101
|
# active targets
|
|
69
|
-
self.prometheus_targets_url =
|
|
102
|
+
self.prometheus_targets_url = parse.urljoin(
|
|
103
|
+
base_url, "api/v1/targets?state=active"
|
|
104
|
+
)
|
|
70
105
|
self.prometheus_fqdn_label = prometheus_fqdn_label
|
|
71
106
|
self.promtool_cmd = [promtool_path]
|
|
72
107
|
if prometheus_ssl_cert:
|
|
@@ -137,7 +172,7 @@ class PromtoolClient:
|
|
|
137
172
|
# with double quotes both on direct command and
|
|
138
173
|
# ssh command so using url encoding
|
|
139
174
|
|
|
140
|
-
quoted_expr = quote(expr)
|
|
175
|
+
quoted_expr = parse.quote(expr)
|
|
141
176
|
|
|
142
177
|
cmd = ['curl', '-s', '-k', '-X', 'POST', '-g',
|
|
143
178
|
self.prometheus_delete_series_url + '?match[]=' + quoted_expr]
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
# Copyright (c) 2016 b<>com
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
13
|
+
# implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
from tempest import config
|
|
18
|
+
from tempest.lib.common import api_version_utils
|
|
19
|
+
from tempest.lib.common.utils import test_utils
|
|
20
|
+
from tempest import test
|
|
21
|
+
|
|
22
|
+
from watcher_tempest_plugin import infra_optim_clients as clients
|
|
23
|
+
from watcher_tempest_plugin.services.infra_optim.v1.json import (
|
|
24
|
+
api_microversion_fixture
|
|
25
|
+
)
|
|
26
|
+
from watcher_tempest_plugin.tests.common import base
|
|
27
|
+
|
|
28
|
+
CONF = config.CONF
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class BaseInfraOptimTest(api_version_utils.BaseMicroversionTest,
|
|
32
|
+
test.BaseTestCase,
|
|
33
|
+
base.WatcherHelperMixin):
|
|
34
|
+
"""Base class for Infrastructure Optimization API tests."""
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def skip_checks(cls):
|
|
38
|
+
super(BaseInfraOptimTest, cls).skip_checks()
|
|
39
|
+
if not CONF.service_available.watcher:
|
|
40
|
+
raise cls.skipException('Watcher support is required')
|
|
41
|
+
|
|
42
|
+
api_version_utils.check_skip_with_microversion(
|
|
43
|
+
cls.min_microversion,
|
|
44
|
+
cls.max_microversion,
|
|
45
|
+
CONF.optimize.min_microversion,
|
|
46
|
+
CONF.optimize.max_microversion)
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def setup_credentials(cls):
|
|
50
|
+
super(BaseInfraOptimTest, cls).setup_credentials()
|
|
51
|
+
cls.mgr = clients.AdminManager()
|
|
52
|
+
|
|
53
|
+
@classmethod
|
|
54
|
+
def setup_clients(cls):
|
|
55
|
+
super(BaseInfraOptimTest, cls).setup_clients()
|
|
56
|
+
cls.client = cls.mgr.io_client
|
|
57
|
+
cls.gnocchi = cls.mgr.gn_client
|
|
58
|
+
|
|
59
|
+
def setUp(self):
|
|
60
|
+
super(BaseInfraOptimTest, self).setUp()
|
|
61
|
+
self.useFixture(api_microversion_fixture.APIMicroversionFixture(
|
|
62
|
+
optimize_microversion=self.request_microversion))
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def resource_setup(cls):
|
|
66
|
+
super(BaseInfraOptimTest, cls).resource_setup()
|
|
67
|
+
|
|
68
|
+
# Set of all created audit templates UUIDs
|
|
69
|
+
cls.created_audit_templates = set()
|
|
70
|
+
# Set of all created audit UUIDs
|
|
71
|
+
cls.created_audits = set()
|
|
72
|
+
# Set of all created audit UUIDs. We use it to build the list of
|
|
73
|
+
# action plans to delete (including potential orphan one(s))
|
|
74
|
+
cls.created_action_plans_audit_uuids = set()
|
|
75
|
+
|
|
76
|
+
cls.request_microversion = (
|
|
77
|
+
api_version_utils.select_request_microversion(
|
|
78
|
+
cls.min_microversion,
|
|
79
|
+
CONF.optimize.min_microversion))
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def resource_cleanup(cls):
|
|
83
|
+
"""Ensure that all created objects get destroyed."""
|
|
84
|
+
super(BaseInfraOptimTest, cls).resource_cleanup()
|
|
85
|
+
|
|
86
|
+
def _are_all_action_plans_finished(self):
|
|
87
|
+
_, action_plans = self.client.list_action_plans()
|
|
88
|
+
return all([ap['state'] in self.IDLE_STATES.values()
|
|
89
|
+
for ap in action_plans['action_plans']])
|
|
90
|
+
|
|
91
|
+
def wait_for_all_action_plans_to_finish(self):
|
|
92
|
+
assert test_utils.call_until_true(
|
|
93
|
+
func=self._are_all_action_plans_finished,
|
|
94
|
+
duration=300,
|
|
95
|
+
sleep_for=5
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def validate_self_link(self, resource, uuid, link):
|
|
99
|
+
"""Check whether the given self link formatted correctly."""
|
|
100
|
+
expected_link = "{base}/{pref}/{res}/{uuid}".format(
|
|
101
|
+
base='https?://[^/]*',
|
|
102
|
+
pref=self.client.URI_PREFIX,
|
|
103
|
+
res=resource,
|
|
104
|
+
uuid=uuid
|
|
105
|
+
)
|
|
106
|
+
self.assertRegex(link, expected_link)
|
|
107
|
+
|
|
108
|
+
def assert_expected(self, expected, actual,
|
|
109
|
+
keys=('created_at', 'updated_at', 'deleted_at')):
|
|
110
|
+
# Check if not expected keys/values exists in actual response body
|
|
111
|
+
for key, value in expected.items():
|
|
112
|
+
if key not in keys:
|
|
113
|
+
self.assertIn(key, actual)
|
|
114
|
+
self.assertEqual(value, actual[key])
|
|
@@ -26,21 +26,36 @@ from watcher_tempest_plugin.tests.api.admin import base
|
|
|
26
26
|
class TestShowListAction(base.BaseInfraOptimTest):
|
|
27
27
|
"""Tests for actions"""
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
_,
|
|
33
|
-
_, cls.audit_template = cls.create_audit_template(cls.goal['uuid'])
|
|
34
|
-
_, cls.audit = cls.create_audit(cls.audit_template['uuid'])
|
|
29
|
+
def setUp(self):
|
|
30
|
+
super().setUp()
|
|
31
|
+
_, self.goal = self.client.show_goal("DUMMY")
|
|
32
|
+
_, self.audit_template = self.create_audit_template(self.goal['uuid'])
|
|
35
33
|
|
|
34
|
+
# Wait for any running action plans to finish before creating audit
|
|
35
|
+
self.wait_for_all_action_plans_to_finish()
|
|
36
|
+
|
|
37
|
+
_, self.audit = self.create_audit(self.audit_template['uuid'])
|
|
38
|
+
|
|
39
|
+
# Wait for audit to finish (in any state)
|
|
36
40
|
assert test_utils.call_until_true(
|
|
37
|
-
func=functools.partial(
|
|
41
|
+
func=functools.partial(self.has_audit_finished,
|
|
42
|
+
self.audit['uuid']),
|
|
38
43
|
duration=30,
|
|
39
44
|
sleep_for=.5
|
|
45
|
+
), "Audit %s did not finish within expected time" % self.audit['uuid']
|
|
46
|
+
|
|
47
|
+
# Check if audit succeeded
|
|
48
|
+
_, finished_audit = self.client.show_audit(self.audit['uuid'])
|
|
49
|
+
audit_state = finished_audit.get('state')
|
|
50
|
+
assert audit_state == 'SUCCEEDED', (
|
|
51
|
+
"Audit %s ended in state %s instead of SUCCEEDED" %
|
|
52
|
+
(self.audit['uuid'], audit_state)
|
|
40
53
|
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
54
|
+
|
|
55
|
+
_, action_plans = self.client.list_action_plans(
|
|
56
|
+
audit_uuid=self.audit['uuid'])
|
|
57
|
+
|
|
58
|
+
self.action_plan = action_plans['action_plans'][0]
|
|
44
59
|
|
|
45
60
|
@decorators.attr(type='smoke')
|
|
46
61
|
@decorators.idempotent_id('0390c465-df10-460f-9924-ff3d14779395')
|
|
@@ -119,25 +134,36 @@ class TestPatchAction(base.BaseInfraOptimTest):
|
|
|
119
134
|
# Minimal version required for Actions Patch API
|
|
120
135
|
min_microversion = "1.5"
|
|
121
136
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
137
|
+
def setUp(self):
|
|
138
|
+
super().setUp()
|
|
139
|
+
_, self.goal = self.client.show_goal("DUMMY")
|
|
140
|
+
_, self.audit_template = self.create_audit_template(self.goal['uuid'])
|
|
125
141
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
super(TestPatchAction, cls).resource_setup()
|
|
129
|
-
_, cls.goal = cls.client.show_goal("DUMMY")
|
|
130
|
-
_, cls.audit_template = cls.create_audit_template(cls.goal['uuid'])
|
|
131
|
-
_, cls.audit = cls.create_audit(cls.audit_template['uuid'])
|
|
142
|
+
# Wait for any running action plans to finish before creating audit
|
|
143
|
+
self.wait_for_all_action_plans_to_finish()
|
|
132
144
|
|
|
145
|
+
_, self.audit = self.create_audit(self.audit_template['uuid'])
|
|
146
|
+
|
|
147
|
+
# Wait for audit to finish (in any state)
|
|
133
148
|
assert test_utils.call_until_true(
|
|
134
|
-
func=functools.partial(
|
|
149
|
+
func=functools.partial(self.has_audit_finished,
|
|
150
|
+
self.audit['uuid']),
|
|
135
151
|
duration=30,
|
|
136
152
|
sleep_for=.5
|
|
153
|
+
), "Audit %s did not finish within expected time" % self.audit['uuid']
|
|
154
|
+
|
|
155
|
+
# Check if audit succeeded
|
|
156
|
+
_, finished_audit = self.client.show_audit(self.audit['uuid'])
|
|
157
|
+
audit_state = finished_audit.get('state')
|
|
158
|
+
assert audit_state == 'SUCCEEDED', (
|
|
159
|
+
"Audit %s ended in state %s instead of SUCCEEDED" %
|
|
160
|
+
(self.audit['uuid'], audit_state)
|
|
137
161
|
)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
162
|
+
|
|
163
|
+
_, action_plans = self.client.list_action_plans(
|
|
164
|
+
audit_uuid=self.audit['uuid'])
|
|
165
|
+
|
|
166
|
+
self.action_plan = action_plans['action_plans'][0]
|
|
141
167
|
|
|
142
168
|
@decorators.attr(type="smoke")
|
|
143
169
|
@decorators.idempotent_id('e2360342-8042-4faf-a028-5e63fd844387')
|
|
@@ -52,6 +52,10 @@ class TestCreateDeleteExecuteActionPlan(base.BaseInfraOptimTest):
|
|
|
52
52
|
def test_execute_action_plan(self):
|
|
53
53
|
_, goal = self.client.show_goal("dummy")
|
|
54
54
|
_, audit_template = self.create_audit_template(goal['uuid'])
|
|
55
|
+
|
|
56
|
+
# Wait for any running action plans to finish before creating audit
|
|
57
|
+
self.wait_for_all_action_plans_to_finish()
|
|
58
|
+
|
|
55
59
|
_, audit = self.create_audit(audit_template['uuid'])
|
|
56
60
|
|
|
57
61
|
self.assertTrue(test_utils.call_until_true(
|
|
@@ -59,6 +63,7 @@ class TestCreateDeleteExecuteActionPlan(base.BaseInfraOptimTest):
|
|
|
59
63
|
duration=30,
|
|
60
64
|
sleep_for=.5
|
|
61
65
|
))
|
|
66
|
+
|
|
62
67
|
_, action_plans = self.client.list_action_plans(
|
|
63
68
|
audit_uuid=audit['uuid'])
|
|
64
69
|
action_plan = action_plans['action_plans'][0]
|
|
@@ -76,6 +81,10 @@ class TestCreateDeleteExecuteActionPlan(base.BaseInfraOptimTest):
|
|
|
76
81
|
def test_delete_action_plan(self):
|
|
77
82
|
_, goal = self.client.show_goal("dummy")
|
|
78
83
|
_, audit_template = self.create_audit_template(goal['uuid'])
|
|
84
|
+
|
|
85
|
+
# Wait for any running action plans to finish before creating audit
|
|
86
|
+
self.wait_for_all_action_plans_to_finish()
|
|
87
|
+
|
|
79
88
|
_, audit = self.create_audit(audit_template['uuid'])
|
|
80
89
|
|
|
81
90
|
self.assertTrue(test_utils.call_until_true(
|
|
@@ -83,6 +92,7 @@ class TestCreateDeleteExecuteActionPlan(base.BaseInfraOptimTest):
|
|
|
83
92
|
duration=30,
|
|
84
93
|
sleep_for=.5
|
|
85
94
|
))
|
|
95
|
+
|
|
86
96
|
_, action_plans = self.client.list_action_plans(
|
|
87
97
|
audit_uuid=audit['uuid'])
|
|
88
98
|
action_plan = action_plans['action_plans'][0]
|
|
@@ -98,22 +108,27 @@ class TestCreateDeleteExecuteActionPlan(base.BaseInfraOptimTest):
|
|
|
98
108
|
class TestShowListActionPlan(base.BaseInfraOptimTest):
|
|
99
109
|
"""Tests for action_plan."""
|
|
100
110
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
_,
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
def setUp(self):
|
|
112
|
+
super().setUp()
|
|
113
|
+
_, self.goal = self.client.show_goal("dummy")
|
|
114
|
+
_, self.audit_template = self.create_audit_template(self.goal['uuid'])
|
|
115
|
+
|
|
116
|
+
# Wait for any running action plans to finish before creating audit
|
|
117
|
+
self.wait_for_all_action_plans_to_finish()
|
|
118
|
+
|
|
119
|
+
_, self.audit = self.create_audit(self.audit_template['uuid'])
|
|
107
120
|
|
|
108
121
|
assert test_utils.call_until_true(
|
|
109
|
-
func=functools.partial(
|
|
122
|
+
func=functools.partial(
|
|
123
|
+
self.has_audit_finished, self.audit['uuid']),
|
|
110
124
|
duration=30,
|
|
111
125
|
sleep_for=.5
|
|
112
126
|
)
|
|
113
|
-
|
|
114
|
-
|
|
127
|
+
|
|
128
|
+
_, action_plans = self.client.list_action_plans(
|
|
129
|
+
audit_uuid=self.audit['uuid'])
|
|
115
130
|
if len(action_plans['action_plans']) > 0:
|
|
116
|
-
|
|
131
|
+
self.action_plan = action_plans['action_plans'][0]
|
|
117
132
|
|
|
118
133
|
@decorators.attr(type='smoke')
|
|
119
134
|
@decorators.idempotent_id('33465228-aac1-4688-9db3-6b1532c84323')
|