Browse Source

Add Additional RBAC Test Coverage for Shipyard

This commit does the following:
- Add test coverage for:
  - Actions API
  - Airflow Monitoring API
  - Log Retrieval API
- Add tox.ini
- Add hacking checks
- Fix pep8 issues

Future work needed to fix some of the Actions API RBAC tests

Change-Id: I6e17ffa3ecc3c8a181790bdb79ad6b29fe127114
Rick Bartra 8 months ago
parent
commit
9f473f288a

+ 3
- 4
airship_tempest_plugin/config.py View File

@@ -24,7 +24,7 @@ ServiceAvailableGroup = [
24 24
 ]
25 25
 
26 26
 shipyard_group = cfg.OptGroup(name='shipyard',
27
-                         title='Shipyard service options')
27
+                              title='Shipyard service options')
28 28
 
29 29
 ShipyardGroup = [
30 30
     cfg.StrOpt('endpoint_type',
@@ -36,10 +36,9 @@ ShipyardGroup = [
36 36
                help="Catalog type of the Shipyard service"),
37 37
 ]
38 38
 
39
+
39 40
 def get_opt_lists(self, conf):
40
-    """
41
-    Get a list of options for sample config generation
42
-    """
41
+    """Get a list of options for sample config generation"""
43 42
     return [
44 43
         (service_available_group, ServiceAvailableGroup),
45 44
         (shipyard_group, ShipyardGroup)

+ 0
- 0
airship_tempest_plugin/hacking/__init__.py View File


+ 209
- 0
airship_tempest_plugin/hacking/checks.py View File

@@ -0,0 +1,209 @@
1
+# Copyright 2013 IBM Corp.
2
+# Copyright 2017 AT&T Corporation.
3
+# All Rights Reserved.
4
+#
5
+#   Licensed under the Apache License, Version 2.0 (the "License"); you may
6
+#   not use this file except in compliance with the License. You may obtain
7
+#   a copy of the License at
8
+#
9
+#     http://www.apache.org/licenses/LICENSE-2.0
10
+#
11
+#   Unless required by applicable law or agreed to in writing, software
12
+#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+#   License for the specific language governing permissions and limitations
15
+#   under the License.
16
+
17
+import os
18
+import re
19
+
20
+import pycodestyle
21
+
22
+
23
+PYTHON_CLIENTS = ['cinder', 'glance', 'keystone', 'nova', 'swift', 'neutron',
24
+                  'ironic', 'heat', 'sahara']
25
+
26
+PYTHON_CLIENT_RE = re.compile('import (%s)client' % '|'.join(PYTHON_CLIENTS))
27
+TEST_DEFINITION = re.compile(r'^\s*def test.*')
28
+SETUP_TEARDOWN_CLASS_DEFINITION = re.compile(r'^\s+def (setUp|tearDown)Class')
29
+SCENARIO_DECORATOR = re.compile(r'\s*@.*services\((.*)\)')
30
+VI_HEADER_RE = re.compile(r"^#\s+vim?:.+")
31
+RAND_NAME_HYPHEN_RE = re.compile(r".*rand_name\(.+[\-\_][\"\']\)")
32
+MUTABLE_DEFAULT_ARGS = re.compile(r"^\s*def .+\((.+=\{\}|.+=\[\])")
33
+TESTTOOLS_SKIP_DECORATOR = re.compile(r'\s*@testtools\.skip\((.*)\)')
34
+CLASS = re.compile(r"^class .+")
35
+RBAC_CLASS_NAME_RE = re.compile(r'class .+RbacTest')
36
+RULE_VALIDATION_DECORATOR = re.compile(
37
+    r'\s*@rbac_rule_validation.action\(.*')
38
+IDEMPOTENT_ID_DECORATOR = re.compile(r'\s*@decorators\.idempotent_id\((.*)\)')
39
+
40
+have_rbac_decorator = False
41
+
42
+
43
+def import_no_clients_in_api_tests(physical_line, filename):
44
+    """Check for client imports from airship_tempest_plugin/tests/api
45
+    T102: Cannot import OpenStack python clients
46
+    """
47
+    if "airship_tempest_plugin/tests/api" in filename:
48
+        res = PYTHON_CLIENT_RE.match(physical_line)
49
+        if res:
50
+            return (physical_line.find(res.group(1)),
51
+                    ("T102: python clients import not allowed "
52
+                     "in airship_tempest_plugin/tests/api/* or "
53
+                     "airship_tempest_plugin/tests/scenario/* tests"))
54
+
55
+
56
+def no_setup_teardown_class_for_tests(physical_line, filename):
57
+    """Check that tests do not use setUpClass/tearDownClass
58
+    T105: Tests cannot use setUpClass/tearDownClass
59
+    """
60
+    if pycodestyle.noqa(physical_line):
61
+        return
62
+
63
+    if SETUP_TEARDOWN_CLASS_DEFINITION.match(physical_line):
64
+        return (physical_line.find('def'),
65
+                "T105: (setUp|tearDown)Class can not be used in tests")
66
+
67
+
68
+def no_vi_headers(physical_line, line_number, lines):
69
+    """Check for vi editor configuration in source files.
70
+    By default vi modelines can only appear in the first or
71
+    last 5 lines of a source file.
72
+    T106
73
+    """
74
+    # NOTE(gilliard): line_number is 1-indexed
75
+    if line_number <= 5 or line_number > len(lines) - 5:
76
+        if VI_HEADER_RE.match(physical_line):
77
+            return 0, "T106: Don't put vi configuration in source files"
78
+
79
+
80
+def service_tags_not_in_module_path(physical_line, filename):
81
+    """Check that a service tag isn't in the module path
82
+    A service tag should only be added if the service name isn't already in
83
+    the module path.
84
+    T107
85
+    """
86
+    matches = SCENARIO_DECORATOR.match(physical_line)
87
+    if matches:
88
+        services = matches.group(1).split(',')
89
+        for service in services:
90
+            service_name = service.strip().strip("'")
91
+            modulepath = os.path.split(filename)[0]
92
+            if service_name in modulepath:
93
+                return (physical_line.find(service_name),
94
+                        "T107: service tag should not be in path")
95
+
96
+
97
+def no_hyphen_at_end_of_rand_name(logical_line, filename):
98
+    """Check no hyphen at the end of rand_name() argument
99
+    T108
100
+    """
101
+    msg = "T108: hyphen should not be specified at the end of rand_name()"
102
+    if RAND_NAME_HYPHEN_RE.match(logical_line):
103
+        return 0, msg
104
+
105
+
106
+def no_mutable_default_args(logical_line):
107
+    """Check that mutable object isn't used as default argument
108
+    N322: Method's default argument shouldn't be mutable
109
+    """
110
+    msg = "N322: Method's default argument shouldn't be mutable!"
111
+    if MUTABLE_DEFAULT_ARGS.match(logical_line):
112
+        yield (0, msg)
113
+
114
+
115
+def no_testtools_skip_decorator(logical_line):
116
+    """Check that methods do not have the testtools.skip decorator
117
+    T109
118
+    """
119
+    if TESTTOOLS_SKIP_DECORATOR.match(logical_line):
120
+        yield (0, "T109: Cannot use testtools.skip decorator; instead use "
121
+               "decorators.skip_because from tempest.lib")
122
+
123
+
124
+def use_rand_uuid_instead_of_uuid4(logical_line, filename):
125
+    """Check that tests use data_utils.rand_uuid() instead of uuid.uuid4()
126
+    T113
127
+    """
128
+    if 'uuid.uuid4()' not in logical_line:
129
+        return
130
+
131
+    msg = ("T113: Tests should use data_utils.rand_uuid()/rand_uuid_hex() "
132
+           "instead of uuid.uuid4()/uuid.uuid4().hex")
133
+    yield (0, msg)
134
+
135
+
136
+def no_rbac_rule_validation_decorator(physical_line, filename):
137
+    """Check that each test has the ``rbac_rule_validation.action`` decorator.
138
+    Checks whether the test function has "@rbac_rule_validation.action"
139
+    above it; otherwise checks that it has "@decorators.idempotent_id" above
140
+    it and "@rbac_rule_validation.action" above that.
141
+    Assumes that ``rbac_rule_validation.action`` decorator is either the first
142
+    or second decorator above the test function; otherwise this check fails.
143
+    P100
144
+    """
145
+    global have_rbac_decorator
146
+
147
+    if ("airship_tempest_plugin/tests/api" in filename or
148
+            "airship_tempest_plugin/tests/scenario" in filename):
149
+
150
+        if RULE_VALIDATION_DECORATOR.match(physical_line):
151
+            have_rbac_decorator = True
152
+            return
153
+
154
+        if TEST_DEFINITION.match(physical_line):
155
+            if not have_rbac_decorator:
156
+                return (0, "Must use rbac_rule_validation.action "
157
+                           "decorator for API and scenario tests")
158
+
159
+            have_rbac_decorator = False
160
+
161
+
162
+def no_rbac_suffix_in_test_filename(filename):
163
+    """Check that RBAC filenames end with "_rbac" suffix.
164
+    P101
165
+    """
166
+    if "airship_tempest_plugin/tests/api" in filename:
167
+
168
+        if filename.endswith('rbac_base.py'):
169
+            return
170
+
171
+        if not filename.endswith('_rbac.py'):
172
+            return 0, "RBAC test filenames must end in _rbac suffix"
173
+
174
+
175
+def no_rbac_test_suffix_in_test_class_name(physical_line, filename):
176
+    """Check that RBAC class names end with "RbacTest"
177
+    P102
178
+    """
179
+    if "airship_tempest_plugin/tests/api" in filename:
180
+
181
+        if filename.endswith('rbac_base.py'):
182
+            return
183
+
184
+        if CLASS.match(physical_line):
185
+            if not RBAC_CLASS_NAME_RE.match(physical_line):
186
+                return 0, "RBAC test class names must end in 'RbacTest'"
187
+
188
+
189
+def no_client_alias_in_test_cases(logical_line, filename):
190
+    """Check that test cases don't use "self.client" to define a client.
191
+    P103
192
+    """
193
+    if "airship_tempest_plugin/tests/api" in filename:
194
+        if "self.client" in logical_line or "cls.client" in logical_line:
195
+            return 0, "Do not use 'self.client' as a service client alias"
196
+
197
+
198
+def factory(register):
199
+    register(import_no_clients_in_api_tests)
200
+    register(no_setup_teardown_class_for_tests)
201
+    register(no_vi_headers)
202
+    register(no_hyphen_at_end_of_rand_name)
203
+    register(no_mutable_default_args)
204
+    register(no_testtools_skip_decorator)
205
+    register(use_rand_uuid_instead_of_uuid4)
206
+    register(service_tags_not_in_module_path)
207
+    register(no_rbac_rule_validation_decorator)
208
+    register(no_rbac_suffix_in_test_filename)
209
+    register(no_rbac_test_suffix_in_test_class_name)

+ 2
- 0
airship_tempest_plugin/plugin.py View File

@@ -34,7 +34,9 @@ class AirshipRbacPlugin(plugins.TempestPlugin):
34 34
         config.register_opt_group(conf, project_config.service_available_group,
35 35
                                   project_config.ServiceAvailableGroup)
36 36
         config.register_opt_group(conf, project_config.shipyard_group,
37
+
37 38
                                   project_config.ShipyardGroup)
39
+
38 40
     def get_opt_lists(self):
39 41
         return [
40 42
             (project_config.service_available_group.name,

+ 42
- 2
airship_tempest_plugin/services/shipyard/json/actions_client.py View File

@@ -19,16 +19,56 @@ http://airship-shipyard.readthedocs.io/en/latest/API.html#action-api
19 19
 """
20 20
 
21 21
 from oslo_serialization import jsonutils as json
22
-from six.moves.urllib import parse as urllib
23 22
 
24 23
 from tempest.lib.common import rest_client
25 24
 
25
+# NOTE(rb560u): The following will need to be rewritten in the future if
26
+# functional testing is desired:
27
+#  - 'def post_actions`
28
+# This initial implementation is just to meet the first use case which is RBAC
29
+# testing. For RBAC testing, we only need to hit the API endpoint and check
30
+# role permission to that API.
31
+
26 32
 
27 33
 class ActionsClient(rest_client.RestClient):
28 34
     api_version = "v1.0"
29 35
 
30
-    def get_actions(self):
36
+    def list_actions(self):
31 37
         resp, body = self.get('actions')
32 38
         self.expected_success(200, resp.status)
33 39
         body = json.loads(body)
34 40
         return rest_client.ResponseBody(resp, body)
41
+
42
+    def create_action(self):
43
+        url = "actions"
44
+        post_body = json.dumps({})
45
+        resp, body = self.post(url, post_body)
46
+        self.expected_success(201, resp.status)
47
+        body = json.loads(body)
48
+        return rest_client.ResponseBody(resp, body)
49
+
50
+    def get_action(self):
51
+        resp, body = self.get('actions/1')
52
+        self.expected_success(200, resp.status)
53
+        body = json.loads(body)
54
+        return rest_client.ResponseBody(resp, body)
55
+
56
+    def get_action_validation(self):
57
+        resp, body = self.get('actions/1/validationdetails/1')
58
+        self.expected_success(200, resp.status)
59
+        body = json.loads(body)
60
+        return rest_client.ResponseBody(resp, body)
61
+
62
+    def get_action_step(self):
63
+        resp, body = self.get('actions/1/steps/1')
64
+        self.expected_success(200, resp.status)
65
+        body = json.loads(body)
66
+        return rest_client.ResponseBody(resp, body)
67
+
68
+    def invoke_action_control(self):
69
+        url = "actions/1/pause"
70
+        post_body = json.dumps({})
71
+        resp, body = self.post(url, post_body)
72
+        self.expected_success(202, resp.status)
73
+        body = json.loads(body)
74
+        return rest_client.ResponseBody(resp, body)

+ 7
- 2
airship_tempest_plugin/services/shipyard/json/airflow_monitoring_client.py View File

@@ -19,7 +19,6 @@ http://airship-shipyard.readthedocs.io/en/latest/API.html#airflow-monitoring-api
19 19
 """
20 20
 
21 21
 from oslo_serialization import jsonutils as json
22
-from six.moves.urllib import parse as urllib
23 22
 
24 23
 from tempest.lib.common import rest_client
25 24
 
@@ -27,8 +26,14 @@ from tempest.lib.common import rest_client
27 26
 class AirflowMonitoringClient(rest_client.RestClient):
28 27
     api_version = "v1.0"
29 28
 
30
-    def get_workflows(self):
29
+    def list_workflows(self):
31 30
         resp, body = self.get('workflows')
32 31
         self.expected_success(200, resp.status)
33 32
         body = json.loads(body)
34 33
         return rest_client.ResponseBody(resp, body)
34
+
35
+    def get_workflow(self):
36
+        resp, body = self.get('workflows/1')
37
+        self.expected_success(200, resp.status)
38
+        body = json.loads(body)
39
+        return rest_client.ResponseBody(resp, body)

+ 4
- 5
airship_tempest_plugin/services/shipyard/json/document_staging_client.py View File

@@ -19,7 +19,6 @@ http://airship-shipyard.readthedocs.io/en/latest/API.html#document-staging-api
19 19
 """
20 20
 
21 21
 from oslo_serialization import jsonutils as json
22
-from six.moves.urllib import parse as urllib
23 22
 
24 23
 from tempest.lib.common import rest_client
25 24
 
@@ -36,13 +35,13 @@ from tempest.lib.common import rest_client
36 35
 class DocumentStagingClient(rest_client.RestClient):
37 36
     api_version = "v1.0"
38 37
 
39
-    def get_configdocs(self):
38
+    def get_configdocs_status(self):
40 39
         resp, body = self.get('configdocs')
41 40
         self.expected_success(200, resp.status)
42 41
         body = json.loads(body)
43 42
         return rest_client.ResponseBody(resp, body)
44 43
 
45
-    def post_configdocs(self):
44
+    def create_configdocs(self):
46 45
         url = "configdocs/1"
47 46
         post_body = json.dumps({})
48 47
         resp, body = self.post(url, post_body)
@@ -50,7 +49,7 @@ class DocumentStagingClient(rest_client.RestClient):
50 49
         body = json.loads(body)
51 50
         return rest_client.ResponseBody(resp, body)
52 51
 
53
-    def get_configdocs_within_collection(self):
52
+    def get_configdocs(self):
54 53
         resp, body = self.get('configdocs/1')
55 54
         self.expected_success(200, resp.status)
56 55
         body = json.loads(body)
@@ -62,7 +61,7 @@ class DocumentStagingClient(rest_client.RestClient):
62 61
         body = json.loads(body)
63 62
         return rest_client.ResponseBody(resp, body)
64 63
 
65
-    def post_commitconfigdocs(self):
64
+    def commit_configdocs(self):
66 65
         post_body = json.dumps({})
67 66
         resp, body = self.post("commitconfigdocs", post_body)
68 67
         self.expected_success(200, resp.status)

+ 33
- 0
airship_tempest_plugin/services/shipyard/json/log_retrieval_client.py View File

@@ -0,0 +1,33 @@
1
+# Copyright 2018 AT&T Corp
2
+# All Rights Reserved.
3
+#
4
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5
+#    not use this file except in compliance with the License. You may obtain
6
+#    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, WITHOUT
12
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+#    License for the specific language governing permissions and limitations
14
+#    under the License.
15
+#
16
+
17
+"""
18
+http://airship-shipyard.readthedocs.io/en/latest/API.html#airflow-monitoring-api
19
+"""
20
+
21
+from oslo_serialization import jsonutils as json
22
+
23
+from tempest.lib.common import rest_client
24
+
25
+
26
+class LogRetrievalClient(rest_client.RestClient):
27
+    api_version = "v1.0"
28
+
29
+    def get_action_step_logs(self):
30
+        resp, body = self.get('actions/1/steps/1/logs')
31
+        self.expected_success(200, resp.status)
32
+        body = json.loads(body)
33
+        return rest_client.ResponseBody(resp, body)

+ 33
- 7
airship_tempest_plugin/tests/api/common/rbac_roles.yaml View File

@@ -1,28 +1,54 @@
1 1
 shipyard:
2
-  get_actions:
2
+  workflow_orchestrator:list_actions:
3 3
     - admin
4 4
     - admin_ucp
5 5
     - admin_ucp_viewer
6
-  get_configdocs:
6
+  workflow_orchestrator:create_action:
7
+    - admin
8
+    - admin_ucp
9
+  workflow_orchestrator:get_action:
10
+    - admin
11
+    - admin_ucp
12
+    - admin_ucp_viewer
13
+  workflow_orchestrator:get_action_validation:
7 14
     - admin
8 15
     - admin_ucp
9 16
     - admin_ucp_viewer
10
-  get_workflows:
17
+  workflow_orchestrator:get_action_step:
18
+    - admin
19
+    - admin_ucp
20
+    - admin_ucp_viewer
21
+  workflow_orchestrator:invoke_action_control:
22
+    - admin
23
+    - admin_ucp
24
+  workflow_orchestrator:get_action_step_logs:
11 25
     - admin
12 26
     - admin_ucp
13 27
     - admin_ucp_viewer
14
-  post_configdocs:
28
+  workflow_orchestrator:get_configdocs:
15 29
     - admin
16 30
     - admin_ucp
17
-  get_configdocs_within_collection:
31
+    - admin_ucp_viewer
32
+  workflow_orchestrator:create_configdocs:
33
+    - admin
34
+    - admin_ucp
35
+  workflow_orchestrator:get_configdocs_status:
36
+    - admin
37
+    - admin_ucp
38
+    - admin_ucp_viewer
39
+  workflow_orchestrator:get_renderedconfigdocs:
40
+    - admin
41
+    - admin_ucp
42
+    - admin_ucp_viewer
43
+  workflow_orchestrator:commit_configdocs:
18 44
     - admin
19 45
     - admin_ucp
20 46
     - admin_ucp_viewer
21
-  get_renderedconfigdocs:
47
+  workflow_orchestrator:list_workflows:
22 48
     - admin
23 49
     - admin_ucp
24 50
     - admin_ucp_viewer
25
-  post_commitconfigdocs:
51
+  workflow_orchestrator:get_workflow:
26 52
     - admin
27 53
     - admin_ucp
28 54
     - admin_ucp_viewer

+ 16
- 6
airship_tempest_plugin/tests/api/shipyard/base.py View File

@@ -14,17 +14,21 @@
14 14
 #    under the License.
15 15
 #
16 16
 
17
-from airship_tempest_plugin.services.shipyard.json.actions_client import ActionsClient
18
-from airship_tempest_plugin.services.shipyard.json.document_staging_client import DocumentStagingClient
19
-from airship_tempest_plugin.services.shipyard.json.airflow_monitoring_client import AirflowMonitoringClient
17
+from airship_tempest_plugin.services.shipyard.json.actions_client \
18
+    import ActionsClient
19
+from airship_tempest_plugin.services.shipyard.json.airflow_monitoring_client \
20
+    import AirflowMonitoringClient
21
+from airship_tempest_plugin.services.shipyard.json.document_staging_client \
22
+    import DocumentStagingClient
23
+from airship_tempest_plugin.services.shipyard.json.log_retrieval_client \
24
+    import LogRetrievalClient
20 25
 
21 26
 from tempest import config
22 27
 from tempest import test
23 28
 
24
-from patrole_tempest_plugin import rbac_utils
25
-
26 29
 CONF = config.CONF
27 30
 
31
+
28 32
 class BaseShipyardTest(test.BaseTestCase):
29 33
     """Base class for Shipyard tests."""
30 34
     credentials = ['primary', 'admin']
@@ -33,7 +37,8 @@ class BaseShipyardTest(test.BaseTestCase):
33 37
     def skip_checks(cls):
34 38
         super(BaseShipyardTest, cls).skip_checks()
35 39
         if not CONF.service_available.shipyard:
36
-            raise cls.skipException("Shipyard is not enabled in the deployment")
40
+            raise cls.skipException("Shipyard is not enabled in "
41
+                                    "the deployment")
37 42
 
38 43
     @classmethod
39 44
     def setup_clients(cls):
@@ -55,3 +60,8 @@ class BaseShipyardTest(test.BaseTestCase):
55 60
             CONF.shipyard.catalog_type,
56 61
             CONF.identity.region,
57 62
             CONF.shipyard.endpoint_type)
63
+        cls.shipyard_log_retrieval_client = LogRetrievalClient(
64
+            cls.auth_provider,
65
+            CONF.shipyard.catalog_type,
66
+            CONF.identity.region,
67
+            CONF.shipyard.endpoint_type)

+ 1
- 1
airship_tempest_plugin/tests/api/shipyard/rbac/rbac_base.py View File

@@ -14,7 +14,6 @@
14 14
 #    under the License.
15 15
 #
16 16
 
17
-from airship_tempest_plugin.services.shipyard.json.actions_client import ActionsClient
18 17
 from airship_tempest_plugin.tests.api.shipyard import base
19 18
 
20 19
 from tempest import config
@@ -23,6 +22,7 @@ from patrole_tempest_plugin import rbac_utils
23 22
 
24 23
 CONF = config.CONF
25 24
 
25
+
26 26
 class BaseShipyardRbacTest(rbac_utils.RbacUtilsMixin,
27 27
                            base.BaseShipyardTest):
28 28
     """Base class for Shipyard RBAC tests."""

+ 68
- 8
airship_tempest_plugin/tests/api/shipyard/rbac/test_actions_rbac.py View File

@@ -18,18 +18,78 @@ from airship_tempest_plugin.tests.api.shipyard.rbac import rbac_base
18 18
 
19 19
 from patrole_tempest_plugin import rbac_rule_validation
20 20
 
21
-from tempest.common import utils
22 21
 from tempest.lib import decorators
23
-from tempest.lib.common.utils import data_utils
24
-from tempest.lib.common.utils import test_utils
22
+from tempest.lib import exceptions
25 23
 
26
-from tempest.api.identity import base
27 24
 
28 25
 class ActionsRbacTest(rbac_base.BaseShipyardRbacTest):
29 26
 
30
-    @rbac_rule_validation.action(service="shipyard",
31
-                                 rules=["get_actions"])
27
+    @rbac_rule_validation.action(
28
+        service="shipyard",
29
+        rules=["workflow_orchestrator:list_actions"])
32 30
     @decorators.idempotent_id('183dd007-8a97-4070-afc3-9318401ebad7')
33
-    def test_get_actions(self):
31
+    def test_list_actions(self):
34 32
         with self.rbac_utils.override_role(self):
35
-            self.shipyard_actions_client.get_actions()
33
+            self.shipyard_actions_client.list_actions()
34
+
35
+    @rbac_rule_validation.action(
36
+        service="shipyard",
37
+        rules=["workflow_orchestrator:create_action"])
38
+    @decorators.idempotent_id('fff43c6f-b6ed-44dd-b47b-02c45d7bdb8c')
39
+    def test_create_action(self):
40
+        with self.rbac_utils.override_role(self):
41
+            # As this is a RBAC test, we only care about whether the role has
42
+            # permission or not. Role permission is checked prior to validating
43
+            # the post body, therefore we will ignore a BadRequest exception
44
+            try:
45
+                self.shipyard_actions_client.create_action()
46
+            except exceptions.BadRequest:
47
+                pass
48
+
49
+    @rbac_rule_validation.action(
50
+        service="shipyard",
51
+        rules=["workflow_orchestrator:get_action"])
52
+    @decorators.idempotent_id('68e2f10f-0676-41bb-8f47-bc695e1aa536')
53
+    def test_get_action(self):
54
+        with self.rbac_utils.override_role(self):
55
+            # As this is a RBAC test, we only care about whether the role has
56
+            # permission or not. Role permission is checked prior to validating
57
+            # the post body, therefore we will ignore a NotFound exception
58
+            try:
59
+                self.shipyard_actions_client.get_action()
60
+            except exceptions.NotFound:
61
+                pass
62
+
63
+    ''' NEEDS REWORK AS SHIPYARD NOT DOING POLICY ENFORCEMENT FIRST
64
+    @rbac_rule_validation.action(
65
+        service="shipyard",
66
+        rules=["workflow_orchestrator:get_action_validation"])
67
+    @decorators.idempotent_id('a5156dcd-2674-4295-aa6a-d8db1bd4cf4b')
68
+    def test_get_action_validation(self):
69
+        with self.rbac_utils.override_role(self):
70
+            self.shipyard_actions_client.get_action_validation()
71
+    '''
72
+
73
+    @rbac_rule_validation.action(
74
+        service="shipyard",
75
+        rules=["workflow_orchestrator:get_action_step"])
76
+    @decorators.idempotent_id('6243d2ff-f88e-41cf-8169-140a551834a4')
77
+    def test_get_action_step(self):
78
+        with self.rbac_utils.override_role(self):
79
+            # As this is a RBAC test, we only care about whether the role has
80
+            # permission or not. Role permission is checked prior to validating
81
+            # the post body, therefore we will ignore a NotFound exception
82
+            try:
83
+                self.shipyard_actions_client.get_action_step()
84
+            except exceptions.NotFound:
85
+                pass
86
+
87
+    ''' NEEDS REWORK AS SHIPYARD NOT DOING POLICY ENFORCEMENT FIRST
88
+    @rbac_rule_validation.action(
89
+        service="shipyard",
90
+        rules=["workflow_orchestrator:invoke_action_control"])
91
+    @decorators.idempotent_id('4f6b6564-ff1d-463a-aee8-ed2d51e2a286')
92
+    def test_invoke_action_control(self):
93
+        with self.rbac_utils.override_role(self):
94
+            self.shipyard_actions_client.invoke_action_control()
95
+    '''

+ 21
- 9
airship_tempest_plugin/tests/api/shipyard/rbac/test_airflow_monitoring_rbac.py View File

@@ -18,18 +18,30 @@ from airship_tempest_plugin.tests.api.shipyard.rbac import rbac_base
18 18
 
19 19
 from patrole_tempest_plugin import rbac_rule_validation
20 20
 
21
-from tempest.common import utils
22 21
 from tempest.lib import decorators
23
-from tempest.lib.common.utils import data_utils
24
-from tempest.lib.common.utils import test_utils
22
+from tempest.lib import exceptions
25 23
 
26
-from tempest.api.identity import base
27 24
 
28 25
 class AirflowMonitoringRbacTest(rbac_base.BaseShipyardRbacTest):
29 26
 
30
-    @rbac_rule_validation.action(service="shipyard",
31
-                                 rules=["get_configdocs"])
32
-    @decorators.idempotent_id('0ab53b15-bce9-494f-9a11-34dd2c44d699')
33
-    def test_get_workflows(self):
27
+    @rbac_rule_validation.action(
28
+        service="shipyard",
29
+        rules=["workflow_orchestrator:list_workflows"])
30
+    @decorators.idempotent_id('fc75a269-04cb-4a8d-a627-907f72081b8a')
31
+    def test_list_workflows(self):
34 32
         with self.rbac_utils.override_role(self):
35
-            self.shipyard_airflow_monitoring_client.get_workflows()
33
+            self.shipyard_airflow_monitoring_client.list_workflows()
34
+
35
+    @rbac_rule_validation.action(
36
+        service="shipyard",
37
+        rules=["workflow_orchestrator:get_workflow"])
38
+    @decorators.idempotent_id('1679c5fa-571a-4af8-8f14-ca0c0a49761b')
39
+    def test_get_workflow(self):
40
+        with self.rbac_utils.override_role(self):
41
+            # As this is a RBAC test, we only care about whether the role has
42
+            # permission or not. Role permission is checked prior to validating
43
+            # the post body, therefore we will ignore a BadRequest exception
44
+            try:
45
+                self.shipyard_airflow_monitoring_client.get_workflow()
46
+            except exceptions.BadRequest:
47
+                pass

+ 40
- 30
airship_tempest_plugin/tests/api/shipyard/rbac/test_document_staging_rbac.py View File

@@ -18,71 +18,81 @@ from airship_tempest_plugin.tests.api.shipyard.rbac import rbac_base
18 18
 
19 19
 from patrole_tempest_plugin import rbac_rule_validation
20 20
 
21
-from tempest.common import utils
22 21
 from tempest.lib import decorators
23 22
 from tempest.lib import exceptions
24
-from tempest.lib.common.utils import data_utils
25
-from tempest.lib.common.utils import test_utils
26 23
 
27
-from tempest.api.identity import base
28 24
 
29 25
 class DocumentStagingRbacTest(rbac_base.BaseShipyardRbacTest):
30 26
 
31
-    @rbac_rule_validation.action(service="shipyard",
32
-                                 rules=["get_configdocs"])
27
+    @rbac_rule_validation.action(
28
+        service="shipyard",
29
+        rules=["workflow_orchestrator:get_configdocs_status"])
33 30
     @decorators.idempotent_id('0ab53b15-bce9-494f-9a11-34dd2c44d699')
34
-    def test_get_configdocs(self):
31
+    def test_get_configdocs_status(self):
35 32
         with self.rbac_utils.override_role(self):
36
-            self.shipyard_document_staging_client.get_configdocs()
33
+            # As this is a RBAC test, we only care about whether the role has
34
+            # permission or not. Role permission is checked prior to validating
35
+            # the request body, therefore we will ignore a ValueError exception
36
+            try:
37
+                self.shipyard_document_staging_client.get_configdocs_status()
38
+            except ValueError:
39
+                pass
37 40
 
38
-    @rbac_rule_validation.action(service="shipyard",
39
-                                 rules=["post_configdocs"])
41
+    @rbac_rule_validation.action(
42
+        service="shipyard",
43
+        rules=["workflow_orchestrator:create_configdocs"])
40 44
     @decorators.idempotent_id('1a0daf92-9dba-470c-a317-66b41c0b3df7')
41
-    def test_post_configdocs(self):
45
+    def test_create_configdocs(self):
42 46
         with self.rbac_utils.override_role(self):
43 47
             # As this is a RBAC test, we only care about whether the role has
44 48
             # permission or not. Role permission is checked prior to validating
45
-            # the post body, therefore we will ignore a BadRequest exception
49
+            # the request body, therefore we will ignore a BadRequest exception
50
+            # and Conflict exception
46 51
             try:
47
-                self.shipyard_document_staging_client.post_configdocs()
48
-            except exceptions.BadRequest:
52
+                self.shipyard_document_staging_client.create_configdocs()
53
+            except (exceptions.BadRequest, exceptions.Conflict):
49 54
                 pass
50 55
 
51
-    @rbac_rule_validation.action(service="shipyard",
52
-                                 rules=["get_configdocs_within_collection"])
56
+    @rbac_rule_validation.action(
57
+        service="shipyard",
58
+        rules=["workflow_orchestrator:get_configdocs"])
53 59
     @decorators.idempotent_id('d64cfa75-3bbe-4688-8849-db5a54ce98ea')
54
-    def test_get_configdocs_within_collection(self):
60
+    def test_get_configdocs(self):
55 61
         with self.rbac_utils.override_role(self):
56 62
             # As this is a RBAC test, we only care about whether the role has
57 63
             # permission or not. Role permission is checked prior to validating
58
-            # the post body, therefore we will ignore a NotFound exception
64
+            # the request body, therefore we will ignore a NotFound exception
59 65
             try:
60
-                self.shipyard_document_staging_client.get_configdocs_within_collection()
66
+                self.shipyard_document_staging_client.get_configdocs()
61 67
             except exceptions.NotFound:
62 68
                 pass
63 69
 
64
-    @rbac_rule_validation.action(service="shipyard",
65
-                                 rules=["get_renderedconfigdocs"])
66
-    @decorators.idempotent_id('0ab53b15-bce9-494f-9a11-34dd2c44d699')
70
+    @rbac_rule_validation.action(
71
+        service="shipyard",
72
+        rules=["workflow_orchestrator:get_renderedconfigdocs"])
73
+    @decorators.idempotent_id('76e81d8d-4e06-42f8-9c9d-082020674994')
67 74
     def test_get_renderedconfigdocs(self):
68 75
         with self.rbac_utils.override_role(self):
69 76
             # As this is a RBAC test, we only care about whether the role has
70 77
             # permission or not. Role permission is checked prior to validating
71
-            # the post body, therefore we will ignore a NotFound exception
78
+            # the request body, therefore we will ignore a NotFound exception
79
+            # and ServerFault exception
72 80
             try:
73 81
                 self.shipyard_document_staging_client.get_renderedconfigdocs()
74
-            except exceptions.NotFound:
82
+            except (exceptions.NotFound, exceptions.ServerFault):
75 83
                 pass
76 84
 
77
-    @rbac_rule_validation.action(service="shipyard",
78
-                                 rules=["post_commitconfigdocs"])
85
+    @rbac_rule_validation.action(
86
+        service="shipyard",
87
+        rules=["workflow_orchestrator:commit_configdocs"])
79 88
     @decorators.idempotent_id('200d1cbf-ca11-4b92-9cfd-6cd2a90bc919')
80
-    def test_post_commitconfigdocs(self):
89
+    def test_commit_configdocs(self):
81 90
         with self.rbac_utils.override_role(self):
82 91
             # As this is a RBAC test, we only care about whether the role has
83 92
             # permission or not. Role permission is checked prior to validating
84
-            # the post body, therefore we will ignore a Conflict exception
93
+            # the request body, therefore we will ignore a Conflict exception
94
+            # and BadRequest exception
85 95
             try:
86
-                self.shipyard_document_staging_client.post_commitconfigdocs()
87
-            except exceptions.Conflict:
96
+                self.shipyard_document_staging_client.commit_configdocs()
97
+            except (exceptions.Conflict, exceptions.BadRequest):
88 98
                 pass

+ 39
- 0
airship_tempest_plugin/tests/api/shipyard/rbac/test_log_retrieval_rbac.py View File

@@ -0,0 +1,39 @@
1
+# Copyright 2018 AT&T Corp
2
+# All Rights Reserved.
3
+#
4
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5
+#    not use this file except in compliance with the License. You may obtain
6
+#    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, WITHOUT
12
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+#    License for the specific language governing permissions and limitations
14
+#    under the License.
15
+#
16
+
17
+from airship_tempest_plugin.tests.api.shipyard.rbac import rbac_base
18
+
19
+from patrole_tempest_plugin import rbac_rule_validation
20
+
21
+from tempest.lib import decorators
22
+from tempest.lib import exceptions
23
+
24
+
25
+class LogRetrievalRbacTest(rbac_base.BaseShipyardRbacTest):
26
+
27
+    @rbac_rule_validation.action(
28
+        service="shipyard",
29
+        rules=["workflow_orchestrator:get_action_step_logs"])
30
+    @decorators.idempotent_id('5fd2c572-a226-482d-bdce-70d3ffcd7495')
31
+    def test_get_action_step_logs(self):
32
+        with self.rbac_utils.override_role(self):
33
+            # As this is a RBAC test, we only care about whether the role has
34
+            # permission or not. Role permission is checked prior to validating
35
+            # the post body, therefore we will ignore a BadRequest exception
36
+            try:
37
+                self.shipyard_log_retrieval_client.get_action_step_logs()
38
+            except exceptions.BadRequest:
39
+                pass

+ 0
- 0
airship_tempest_plugin/tests/unit/__init__.py View File


+ 9
- 0
requirements.txt View File

@@ -0,0 +1,9 @@
1
+# The order of packages is significant, because pip processes them in the order
2
+# of appearance. Changing the order has an impact on the overall integration
3
+# process, which may cause wedges in the gate later.
4
+pbr!=2.1.0,>=2.0.0 # Apache-2.0
5
+oslo.log>=3.36.0 # Apache-2.0
6
+oslo.config>=5.2.0 # Apache-2.0
7
+oslo.policy>=1.30.0 # Apache-2.0
8
+tempest>=17.1.0 # Apache-2.0
9
+stevedore>=1.20.0 # Apache-2.0

+ 10
- 0
test-requirements.txt View File

@@ -0,0 +1,10 @@
1
+# The order of packages is significant, because pip processes them in the order
2
+# of appearance. Changing the order has an impact on the overall integration
3
+# process, which may cause wedges in the gate later.
4
+hacking>=1.1.0,<1.2.0 # Apache-2.0
5
+fixtures>=3.0.0 # Apache-2.0/BSD
6
+mock>=2.0.0 # BSD
7
+coverage!=4.4,>=4.0 # Apache-2.0
8
+nose>=1.3.7 # LGPL
9
+nosexcover>=1.0.10 # BSD
10
+oslotest>=3.2.0 # Apache-2.0

+ 104
- 0
tox.ini View File

@@ -0,0 +1,104 @@
1
+[tox]
2
+minversion = 1.6
3
+envlist = pep8,py35,py27
4
+skipsdist = True
5
+
6
+[testenv]
7
+usedevelop = True
8
+install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
9
+setenv =
10
+   VIRTUAL_ENV={envdir}
11
+   OS_TEST_PATH=./airship_tempest_plugin/tests/unit
12
+   LANGUAGE=en_US
13
+   LC_ALL=en_US.utf-8
14
+   PYTHONWARNINGS=default::DeprecationWarning
15
+passenv = OS_STDOUT_CAPTURE OS_STDERR_CAPTURE OS_TEST_TIMEOUT OS_TEST_LOCK_PATH http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY
16
+whitelist_externals = find
17
+deps = -r{toxinidir}/requirements.txt
18
+       -r{toxinidir}/test-requirements.txt
19
+commands =
20
+    find . -type f -name "*.pyc" -delete
21
+    stestr --test-path ./airship_tempest_plugin/tests/unit run {posargs}
22
+
23
+[testenv:pep8]
24
+basepython = python3
25
+commands = flake8 {posargs}
26
+           check-uuid --package airship_tempest_plugin.tests.api
27
+
28
+[testenv:uuidgen]
29
+basepython = python3
30
+commands = check-uuid --package airship_tempest_plugin.tests.api --fix
31
+
32
+[testenv:venv]
33
+basepython = python3
34
+commands = {posargs}
35
+
36
+[testenv:cover]
37
+basepython = python3
38
+commands = rm -rf *.pyc
39
+           rm -rf cover
40
+           rm -f .coverage
41
+           nosetests {posargs}
42
+setenv = VIRTUAL_ENV={envdir}
43
+         NOSE_WITH_COVERAGE=1
44
+         NOSE_COVER_BRANCHES=1
45
+         NOSE_COVER_PACKAGE=airship_tempest_plugin
46
+         NOSE_COVER_HTML=1
47
+         NOSE_COVER_HTML_DIR={toxinidir}/cover
48
+         NOSE_WHERE=airship_tempest_plugin/tests/unit
49
+whitelist_externals = nosetests
50
+                      rm
51
+
52
+[testenv:docs]
53
+basepython = python3
54
+deps =
55
+  -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
56
+  -r{toxinidir}/requirements.txt
57
+  -r{toxinidir}/doc/requirements.txt
58
+commands =
59
+  rm -rf doc/build
60
+  sphinx-build -W -b html doc/source doc/build/html
61
+whitelist_externals = rm
62
+
63
+[testenv:releasenotes]
64
+basepython = python3
65
+deps =
66
+  -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
67
+  -r{toxinidir}/requirements.txt
68
+  -r{toxinidir}/doc/requirements.txt
69
+commands =
70
+  rm -rf releasenotes/build
71
+  sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
72
+whitelist_externals = rm
73
+
74
+[testenv:debug]
75
+basepython = python3
76
+commands = oslo_debug_helper -t airship_tempest_plugin/tests {posargs}
77
+
78
+[flake8]
79
+# [H106] Don't put vim configuration in source files.
80
+# [H203] Use assertIs(Not)None to check for None.
81
+# [H204] Use assert(Not)Equal to check for equality.
82
+# [H205] Use assert(Greater|Less)(Equal) for comparison.
83
+# [H210] Require 'autospec', 'spec', or 'spec_set' in mock.patch/mock.patch.object calls
84
+# [H904] Delay string interpolations at logging calls.
85
+enable-extensions = H106,H203,H204,H205,H210,H904
86
+show-source = True
87
+# E123, E125 skipped as they are invalid PEP-8.
88
+#
89
+# H405 is another one that is good as a guideline, but sometimes
90
+# multiline doc strings just don't have a natural summary
91
+# line. Rejecting code for this reason is wrong.
92
+ignore = E123,E125,H405
93
+builtins = _
94
+exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
95
+
96
+[hacking]
97
+local-check-factory = airship_tempest_plugin.hacking.checks.factory
98
+
99
+[testenv:lower-constraints]
100
+basepython = python3
101
+deps =
102
+  -c{toxinidir}/lower-constraints.txt
103
+  -r{toxinidir}/test-requirements.txt
104
+  -r{toxinidir}/requirements.txt

Loading…
Cancel
Save