Browse Source

Remove in-tree tempest plugin

Remove in-tree tempest plugin in favor of newly
created manila-tempest-plugin repository.

Change-Id: I1fb124598f38067fee469df124ee684f748c6f57
Raissa Sarmento 1 year ago
parent
commit
797048c5ce
100 changed files with 28 additions and 20411 deletions
  1. 19
    0
      .zuul.yaml
  2. 2
    2
      contrib/ci/post_test_hook.sh
  3. 7
    0
      devstack/settings
  4. 0
    6
      manila_tempest_tests/README.rst
  5. 0
    0
      manila_tempest_tests/__init__.py
  6. 0
    32
      manila_tempest_tests/clients.py
  7. 0
    0
      manila_tempest_tests/common/__init__.py
  8. 0
    85
      manila_tempest_tests/common/constants.py
  9. 0
    92
      manila_tempest_tests/common/remote_client.py
  10. 0
    247
      manila_tempest_tests/config.py
  11. 0
    75
      manila_tempest_tests/plugin.py
  12. 0
    0
      manila_tempest_tests/services/__init__.py
  13. 0
    18
      manila_tempest_tests/services/share/__init__.py
  14. 0
    17
      manila_tempest_tests/services/share/json/__init__.py
  15. 0
    760
      manila_tempest_tests/services/share/json/shares_client.py
  16. 0
    18
      manila_tempest_tests/services/share/v2/__init__.py
  17. 0
    0
      manila_tempest_tests/services/share/v2/json/__init__.py
  18. 0
    1735
      manila_tempest_tests/services/share/v2/json/shares_client.py
  19. 0
    77
      manila_tempest_tests/share_exceptions.py
  20. 0
    0
      manila_tempest_tests/tests/__init__.py
  21. 0
    0
      manila_tempest_tests/tests/api/__init__.py
  22. 0
    0
      manila_tempest_tests/tests/api/admin/__init__.py
  23. 0
    128
      manila_tempest_tests/tests/api/admin/test_admin_actions.py
  24. 0
    210
      manila_tempest_tests/tests/api/admin/test_admin_actions_negative.py
  25. 0
    201
      manila_tempest_tests/tests/api/admin/test_export_locations.py
  26. 0
    97
      manila_tempest_tests/tests/api/admin/test_export_locations_negative.py
  27. 0
    634
      manila_tempest_tests/tests/api/admin/test_migration.py
  28. 0
    326
      manila_tempest_tests/tests/api/admin/test_migration_negative.py
  29. 0
    91
      manila_tempest_tests/tests/api/admin/test_multi_backend.py
  30. 0
    759
      manila_tempest_tests/tests/api/admin/test_quotas.py
  31. 0
    357
      manila_tempest_tests/tests/api/admin/test_quotas_negative.py
  32. 0
    183
      manila_tempest_tests/tests/api/admin/test_replication.py
  33. 0
    179
      manila_tempest_tests/tests/api/admin/test_replication_actions.py
  34. 0
    204
      manila_tempest_tests/tests/api/admin/test_scheduler_stats.py
  35. 0
    64
      manila_tempest_tests/tests/api/admin/test_security_services.py
  36. 0
    105
      manila_tempest_tests/tests/api/admin/test_services.py
  37. 0
    100
      manila_tempest_tests/tests/api/admin/test_services_negative.py
  38. 0
    245
      manila_tempest_tests/tests/api/admin/test_share_group_types.py
  39. 0
    146
      manila_tempest_tests/tests/api/admin/test_share_group_types_negative.py
  40. 0
    191
      manila_tempest_tests/tests/api/admin/test_share_groups.py
  41. 0
    56
      manila_tempest_tests/tests/api/admin/test_share_groups_negative.py
  42. 0
    114
      manila_tempest_tests/tests/api/admin/test_share_instances.py
  43. 0
    54
      manila_tempest_tests/tests/api/admin/test_share_instances_negative.py
  44. 0
    252
      manila_tempest_tests/tests/api/admin/test_share_manage.py
  45. 0
    95
      manila_tempest_tests/tests/api/admin/test_share_networks.py
  46. 0
    258
      manila_tempest_tests/tests/api/admin/test_share_servers.py
  47. 0
    108
      manila_tempest_tests/tests/api/admin/test_share_servers_negative.py
  48. 0
    121
      manila_tempest_tests/tests/api/admin/test_share_snapshot_instances.py
  49. 0
    88
      manila_tempest_tests/tests/api/admin/test_share_snapshot_instances_negative.py
  50. 0
    207
      manila_tempest_tests/tests/api/admin/test_share_types.py
  51. 0
    132
      manila_tempest_tests/tests/api/admin/test_share_types_extra_specs.py
  52. 0
    311
      manila_tempest_tests/tests/api/admin/test_share_types_extra_specs_negative.py
  53. 0
    116
      manila_tempest_tests/tests/api/admin/test_share_types_negative.py
  54. 0
    405
      manila_tempest_tests/tests/api/admin/test_shares_actions.py
  55. 0
    140
      manila_tempest_tests/tests/api/admin/test_snapshot_export_locations.py
  56. 0
    140
      manila_tempest_tests/tests/api/admin/test_snapshot_export_locations_negative.py
  57. 0
    170
      manila_tempest_tests/tests/api/admin/test_snapshot_manage.py
  58. 0
    115
      manila_tempest_tests/tests/api/admin/test_snapshot_manage_negative.py
  59. 0
    108
      manila_tempest_tests/tests/api/admin/test_user_messages.py
  60. 0
    58
      manila_tempest_tests/tests/api/admin/test_user_messages_negative.py
  61. 0
    1077
      manila_tempest_tests/tests/api/base.py
  62. 0
    51
      manila_tempest_tests/tests/api/test_availability_zones.py
  63. 0
    43
      manila_tempest_tests/tests/api/test_availability_zones_negative.py
  64. 0
    31
      manila_tempest_tests/tests/api/test_extensions.py
  65. 0
    64
      manila_tempest_tests/tests/api/test_limits.py
  66. 0
    163
      manila_tempest_tests/tests/api/test_metadata.py
  67. 0
    100
      manila_tempest_tests/tests/api/test_metadata_negative.py
  68. 0
    172
      manila_tempest_tests/tests/api/test_microversions.py
  69. 0
    88
      manila_tempest_tests/tests/api/test_quotas.py
  70. 0
    60
      manila_tempest_tests/tests/api/test_quotas_negative.py
  71. 0
    406
      manila_tempest_tests/tests/api/test_replication.py
  72. 0
    215
      manila_tempest_tests/tests/api/test_replication_negative.py
  73. 0
    218
      manila_tempest_tests/tests/api/test_replication_snapshots.py
  74. 0
    161
      manila_tempest_tests/tests/api/test_revert_to_snapshot.py
  75. 0
    159
      manila_tempest_tests/tests/api/test_revert_to_snapshot_negative.py
  76. 0
    631
      manila_tempest_tests/tests/api/test_rules.py
  77. 0
    406
      manila_tempest_tests/tests/api/test_rules_negative.py
  78. 0
    33
      manila_tempest_tests/tests/api/test_scheduler_stats_negative.py
  79. 0
    210
      manila_tempest_tests/tests/api/test_security_services.py
  80. 0
    70
      manila_tempest_tests/tests/api/test_security_services_mapping.py
  81. 0
    173
      manila_tempest_tests/tests/api/test_security_services_mapping_negative.py
  82. 0
    122
      manila_tempest_tests/tests/api/test_security_services_negative.py
  83. 0
    401
      manila_tempest_tests/tests/api/test_share_group_actions.py
  84. 0
    222
      manila_tempest_tests/tests/api/test_share_groups.py
  85. 0
    273
      manila_tempest_tests/tests/api/test_share_groups_negative.py
  86. 0
    298
      manila_tempest_tests/tests/api/test_share_networks.py
  87. 0
    134
      manila_tempest_tests/tests/api/test_share_networks_negative.py
  88. 0
    64
      manila_tempest_tests/tests/api/test_share_types_negative.py
  89. 0
    236
      manila_tempest_tests/tests/api/test_shares.py
  90. 0
    723
      manila_tempest_tests/tests/api/test_shares_actions.py
  91. 0
    245
      manila_tempest_tests/tests/api/test_shares_actions_negative.py
  92. 0
    283
      manila_tempest_tests/tests/api/test_shares_negative.py
  93. 0
    101
      manila_tempest_tests/tests/api/test_snapshot_rules.py
  94. 0
    90
      manila_tempest_tests/tests/api/test_snapshot_rules_negative.py
  95. 0
    0
      manila_tempest_tests/tests/scenario/__init__.py
  96. 0
    1241
      manila_tempest_tests/tests/scenario/manager.py
  97. 0
    253
      manila_tempest_tests/tests/scenario/manager_share.py
  98. 0
    594
      manila_tempest_tests/tests/scenario/test_share_basic_ops.py
  99. 0
    168
      manila_tempest_tests/utils.py
  100. 0
    0
      playbooks/legacy/manila-tempest-dsvm-container-scenario-custom-image/run.yaml

+ 19
- 0
.zuul.yaml View File

@@ -93,6 +93,7 @@
93 93
       - openstack-infra/devstack-gate
94 94
       - openstack/manila
95 95
       - openstack/manila-image-elements
96
+      - openstack/manila-tempest-plugin
96 97
       - openstack/python-manilaclient
97 98
       - openstack/tempest
98 99
 
@@ -106,6 +107,7 @@
106 107
       - openstack-infra/devstack-gate
107 108
       - openstack/manila
108 109
       - openstack/manila-image-elements
110
+      - openstack/manila-tempest-plugin
109 111
       - openstack/python-manilaclient
110 112
       - openstack/tempest
111 113
 
@@ -119,6 +121,7 @@
119 121
       - openstack-infra/devstack-gate
120 122
       - openstack/manila
121 123
       - openstack/manila-image-elements
124
+      - openstack/manila-tempest-plugin
122 125
       - openstack/python-manilaclient
123 126
       - openstack/tempest
124 127
 
@@ -132,6 +135,7 @@
132 135
       - openstack-infra/devstack-gate
133 136
       - openstack/devstack-plugin-glusterfs
134 137
       - openstack/manila
138
+      - openstack/manila-tempest-plugin
135 139
       - openstack/python-manilaclient
136 140
       - openstack/tempest
137 141
 
@@ -145,6 +149,7 @@
145 149
       - openstack-infra/devstack-gate
146 150
       - openstack/devstack-plugin-glusterfs
147 151
       - openstack/manila
152
+      - openstack/manila-tempest-plugin
148 153
       - openstack/python-manilaclient
149 154
       - openstack/tempest
150 155
 
@@ -158,6 +163,7 @@
158 163
       - openstack-infra/devstack-gate
159 164
       - openstack/devstack-plugin-glusterfs
160 165
       - openstack/manila
166
+      - openstack/manila-tempest-plugin
161 167
       - openstack/python-manilaclient
162 168
       - openstack/tempest
163 169
 
@@ -171,6 +177,7 @@
171 177
       - openstack-infra/devstack-gate
172 178
       - openstack/devstack-plugin-glusterfs
173 179
       - openstack/manila
180
+      - openstack/manila-tempest-plugin
174 181
       - openstack/python-manilaclient
175 182
       - openstack/tempest
176 183
 
@@ -184,6 +191,7 @@
184 191
       - openstack-infra/devstack-gate
185 192
       - openstack/devstack-plugin-hdfs
186 193
       - openstack/manila
194
+      - openstack/manila-tempest-plugin
187 195
       - openstack/python-manilaclient
188 196
       - openstack/tempest
189 197
 
@@ -197,6 +205,7 @@
197 205
       - openstack-infra/devstack-gate
198 206
       - openstack/manila
199 207
       - openstack/manila-image-elements
208
+      - openstack/manila-tempest-plugin
200 209
       - openstack/python-manilaclient
201 210
       - openstack/tempest
202 211
 
@@ -210,6 +219,7 @@
210 219
       - openstack-infra/devstack-gate
211 220
       - openstack/manila
212 221
       - openstack/manila-image-elements
222
+      - openstack/manila-tempest-plugin
213 223
       - openstack/python-manilaclient
214 224
       - openstack/tempest
215 225
 
@@ -223,6 +233,7 @@
223 233
       - openstack-infra/devstack-gate
224 234
       - openstack/manila
225 235
       - openstack/manila-image-elements
236
+      - openstack/manila-tempest-plugin
226 237
       - openstack/python-manilaclient
227 238
       - openstack/tempest
228 239
 
@@ -236,6 +247,7 @@
236 247
       - openstack-infra/devstack-gate
237 248
       - openstack/manila
238 249
       - openstack/manila-image-elements
250
+      - openstack/manila-tempest-plugin
239 251
       - openstack/python-manilaclient
240 252
       - openstack/tempest
241 253
 
@@ -249,6 +261,7 @@
249 261
       - openstack-infra/devstack-gate
250 262
       - openstack/manila
251 263
       - openstack/manila-image-elements
264
+      - openstack/manila-tempest-plugin
252 265
       - openstack/python-manilaclient
253 266
       - openstack/tempest
254 267
 
@@ -263,6 +276,7 @@
263 276
       - openstack-infra/devstack-gate
264 277
       - openstack/devstack-plugin-ceph
265 278
       - openstack/manila
279
+      - openstack/manila-tempest-plugin
266 280
       - openstack/python-manilaclient
267 281
       - openstack/tempest
268 282
 
@@ -277,6 +291,7 @@
277 291
       - openstack-infra/devstack-gate
278 292
       - openstack/devstack-plugin-ceph
279 293
       - openstack/manila
294
+      - openstack/manila-tempest-plugin
280 295
       - openstack/python-manilaclient
281 296
       - openstack/tempest
282 297
 
@@ -289,6 +304,7 @@
289 304
     required-projects:
290 305
       - openstack-infra/devstack-gate
291 306
       - openstack/manila
307
+      - openstack/manila-tempest-plugin
292 308
       - openstack/python-manilaclient
293 309
       - openstack/tempest
294 310
 
@@ -302,6 +318,7 @@
302 318
     required-projects:
303 319
       - openstack-infra/devstack-gate
304 320
       - openstack/manila
321
+      - openstack/manila-tempest-plugin
305 322
       - openstack/python-manilaclient
306 323
       - openstack/tempest
307 324
 
@@ -316,6 +333,7 @@
316 333
       - openstack-infra/devstack-gate
317 334
       - openstack/devstack-plugin-ceph
318 335
       - openstack/manila
336
+      - openstack/manila-tempest-plugin
319 337
       - openstack/python-manilaclient
320 338
       - openstack/tempest
321 339
 
@@ -330,6 +348,7 @@
330 348
       - openstack-infra/devstack-gate
331 349
       - openstack/devstack-plugin-ceph
332 350
       - openstack/manila
351
+      - openstack/manila-tempest-plugin
333 352
       - openstack/python-manilaclient
334 353
       - openstack/tempest
335 354
 

+ 2
- 2
contrib/ci/post_test_hook.sh View File

@@ -329,7 +329,7 @@ for port in ${UDP_PORTS[*]}; do
329 329
 done
330 330
 
331 331
 echo "Running tempest manila test suites"
332
-sudo -H -u $USER tox -eall-plugin $MANILA_TESTS -- --concurrency=$MANILA_TEMPEST_CONCURRENCY
332
+sudo -H -u $USER tox -eall -- $MANILA_TESTS --concurrency=$MANILA_TEMPEST_CONCURRENCY
333 333
 RETVAL=$?
334 334
 
335 335
 
@@ -351,7 +351,7 @@ if [[ "$DRIVER" == "dummy" ]]; then
351 351
     manila type-key default set driver_handles_share_servers=False
352 352
 
353 353
     echo "Running tempest manila test suites for DHSS=False mode"
354
-    sudo -H -u $USER tox -eall-plugin $MANILA_TESTS -- --concurrency=$MANILA_TEMPEST_CONCURRENCY
354
+    sudo -H -u $USER tox -eall -- $MANILA_TESTS --concurrency=$MANILA_TEMPEST_CONCURRENCY
355 355
     RETVAL2=$?
356 356
     save_tempest_results 2
357 357
 

+ 7
- 0
devstack/settings View File

@@ -192,6 +192,13 @@ MANILA_DATA_NODE_IP=${MANILA_DATA_NODE_IP:=$MANILA_ADMIN_NET_RANGE}
192 192
 # Data Service copy validation
193 193
 MANILA_DATA_COPY_CHECK_HASH=${MANILA_DATA_COPY_CHECK_HASH:=True}
194 194
 
195
+MANILA_TEMPEST_PLUGIN_PATH=$DEST/manila-tempest-plugin
196
+if [[ $TEMPEST_PLUGINS != 0 ]] ; then
197
+    TEMPEST_PLUGINS="$MANILA_TEMPEST_PLUGIN_PATH $TEMPEST_PLUGINS"
198
+else
199
+    TEMPEST_PLUGINS=$MANILA_TEMPEST_PLUGIN_PATH
200
+fi
201
+
195 202
 # Enable manila services
196 203
 # ----------------------
197 204
 # We have to add Manila to enabled services for screen_it to work

+ 0
- 6
manila_tempest_tests/README.rst View File

@@ -1,6 +0,0 @@
1
-====================
2
-Tempest Integration
3
-====================
4
-
5
-This directory contains Tempest tests to cover Manila project.
6
-

+ 0
- 0
manila_tempest_tests/__init__.py View File


+ 0
- 32
manila_tempest_tests/clients.py View File

@@ -1,32 +0,0 @@
1
-# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
2
-#
3
-# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
-# use this file except in compliance with the License. You may obtain a copy of
5
-# the License at
6
-#
7
-#    http://www.apache.org/licenses/LICENSE-2.0
8
-#
9
-# Unless required by applicable law or agreed to in writing, software
10
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
-# License for the specific language governing permissions and limitations under
13
-# the License.
14
-
15
-from tempest import config
16
-from tempest.lib.services import clients
17
-
18
-
19
-CONF = config.CONF
20
-
21
-
22
-class Clients(clients.ServiceClients):
23
-    """Tempest stable service clients and loaded plugins service clients"""
24
-
25
-    def __init__(self, credentials, service=None):
26
-        """Emulate the interface of Tempest's clients.Manager"""
27
-        # Identity settings
28
-        if CONF.identity.auth_version == 'v2':
29
-            identity_uri = CONF.identity.uri
30
-        else:
31
-            identity_uri = CONF.identity.uri_v3
32
-        super(Clients, self).__init__(credentials, identity_uri)

+ 0
- 0
manila_tempest_tests/common/__init__.py View File


+ 0
- 85
manila_tempest_tests/common/constants.py View File

@@ -1,85 +0,0 @@
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
-
13
-# Shares
14
-STATUS_ERROR = 'error'
15
-STATUS_AVAILABLE = 'available'
16
-STATUS_ERROR_DELETING = 'error_deleting'
17
-STATUS_MIGRATING = 'migrating'
18
-
19
-TEMPEST_MANILA_PREFIX = 'tempest-manila'
20
-
21
-# Replication
22
-REPLICATION_STYLE_READABLE = 'readable'
23
-REPLICATION_STYLE_WRITABLE = 'writable'
24
-REPLICATION_STYLE_DR = 'dr'
25
-REPLICATION_TYPE_CHOICES = (
26
-    REPLICATION_STYLE_READABLE,
27
-    REPLICATION_STYLE_WRITABLE,
28
-    REPLICATION_STYLE_DR,
29
-)
30
-REPLICATION_PROMOTION_CHOICES = (
31
-    REPLICATION_STYLE_READABLE,
32
-    REPLICATION_STYLE_DR,
33
-)
34
-REPLICATION_STATE_ACTIVE = 'active'
35
-REPLICATION_STATE_IN_SYNC = 'in_sync'
36
-REPLICATION_STATE_OUT_OF_SYNC = 'out_of_sync'
37
-
38
-# Access Rules
39
-RULE_STATE_ACTIVE = 'active'
40
-RULE_STATE_OUT_OF_SYNC = 'out_of_sync'
41
-RULE_STATE_ERROR = 'error'
42
-
43
-TASK_STATE_MIGRATION_STARTING = 'migration_starting'
44
-TASK_STATE_MIGRATION_IN_PROGRESS = 'migration_in_progress'
45
-TASK_STATE_MIGRATION_COMPLETING = 'migration_completing'
46
-TASK_STATE_MIGRATION_SUCCESS = 'migration_success'
47
-TASK_STATE_MIGRATION_ERROR = 'migration_error'
48
-TASK_STATE_MIGRATION_CANCELLED = 'migration_cancelled'
49
-TASK_STATE_MIGRATION_DRIVER_STARTING = 'migration_driver_starting'
50
-TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS = 'migration_driver_in_progress'
51
-TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE = 'migration_driver_phase1_done'
52
-TASK_STATE_DATA_COPYING_STARTING = 'data_copying_starting'
53
-TASK_STATE_DATA_COPYING_IN_PROGRESS = 'data_copying_in_progress'
54
-TASK_STATE_DATA_COPYING_COMPLETING = 'data_copying_completing'
55
-TASK_STATE_DATA_COPYING_COMPLETED = 'data_copying_completed'
56
-TASK_STATE_DATA_COPYING_CANCELLED = 'data_copying_cancelled'
57
-TASK_STATE_DATA_COPYING_ERROR = 'data_copying_error'
58
-
59
-# Revert to snapshot
60
-REVERT_TO_SNAPSHOT_MICROVERSION = '2.27'
61
-REVERT_TO_SNAPSHOT_SUPPORT = 'revert_to_snapshot_support'
62
-STATUS_RESTORING = 'restoring'
63
-STATUS_REVERTING = 'reverting'
64
-STATUS_REVERTING_ERROR = 'reverting_error'
65
-
66
-# Share groups
67
-MIN_SHARE_GROUP_MICROVERSION = '2.31'
68
-SHARE_GROUP_SIMPLE_KEYS = {
69
-    'id', 'name', 'links',
70
-}
71
-SHARE_GROUP_DETAIL_REQUIRED_KEYS = {
72
-    'id', 'name', 'description', 'created_at', 'status', 'share_types',
73
-    'project_id', 'host', 'links', 'share_group_type_id',
74
-}
75
-SHARE_GROUP_SNAPSHOT_SIMPLE_KEYS = {
76
-    'id', 'name', 'links',
77
-}
78
-SHARE_GROUP_SNAPSHOT_DETAIL_REQUIRED_KEYS = {
79
-    'id', 'name', 'description', 'created_at', 'status', 'project_id',
80
-    'links', 'share_group_id', 'members',
81
-}
82
-
83
-SHARE_GROUP_TYPE_REQUIRED_KEYS = {
84
-    'id', 'name', 'share_types', 'is_public', 'group_specs',
85
-}

+ 0
- 92
manila_tempest_tests/common/remote_client.py View File

@@ -1,92 +0,0 @@
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
-
13
-import six
14
-import sys
15
-
16
-from oslo_log import log
17
-
18
-from tempest import config
19
-from tempest.lib.common import ssh
20
-from tempest.lib.common.utils import test_utils
21
-import tempest.lib.exceptions
22
-
23
-CONF = config.CONF
24
-
25
-LOG = log.getLogger(__name__)
26
-
27
-
28
-def debug_ssh(function):
29
-    """Decorator to generate extra debug info in case of ssh failure"""
30
-    def wrapper(self, *args, **kwargs):
31
-        try:
32
-            return function(self, *args, **kwargs)
33
-        except tempest.lib.exceptions.SSHTimeout:
34
-            try:
35
-                original_exception = sys.exc_info()
36
-                caller = test_utils.find_test_caller() or "not found"
37
-                if self.server:
38
-                    msg = 'Caller: %s. Timeout trying to ssh to server %s'
39
-                    LOG.debug(msg, caller, self.server)
40
-                    if self.log_console and self.servers_client:
41
-                        try:
42
-                            msg = 'Console log for server %s: %s'
43
-                            console_log = (
44
-                                self.servers_client.get_console_output(
45
-                                    self.server['id'])['output'])
46
-                            LOG.debug(msg, self.server['id'], console_log)
47
-                        except Exception:
48
-                            msg = 'Could not get console_log for server %s'
49
-                            LOG.debug(msg, self.server['id'])
50
-                # re-raise the original ssh timeout exception
51
-                six.reraise(*original_exception)
52
-            finally:
53
-                # Delete the traceback to avoid circular references
54
-                _, _, trace = original_exception
55
-                del trace
56
-    return wrapper
57
-
58
-
59
-class RemoteClient(object):
60
-
61
-    def __init__(self, ip_address, username, password=None, pkey=None,
62
-                 server=None, servers_client=None):
63
-        """Executes commands in a VM over ssh
64
-
65
-        :param ip_address: IP address to ssh to
66
-        :param username: ssh username
67
-        :param password: ssh password (optional)
68
-        :param pkey: ssh public key (optional)
69
-        :param server: server dict, used for debugging purposes
70
-        :param servers_client: servers client, used for debugging purposes
71
-        """
72
-        self.server = server
73
-        self.servers_client = servers_client
74
-        self.log_console = CONF.compute_feature_enabled.console_output
75
-
76
-        self.ssh_client = ssh.Client(ip_address, username, password, pkey=pkey)
77
-
78
-    @debug_ssh
79
-    def exec_command(self, cmd):
80
-        # Shell options below add more clearness on failures,
81
-        # path is extended for some non-cirros guest oses (centos7)
82
-        cmd = CONF.validation.ssh_shell_prologue + " " + cmd
83
-        LOG.debug("Remote command: %s", cmd)
84
-        return self.ssh_client.exec_command(cmd)
85
-
86
-    @debug_ssh
87
-    def validate_authentication(self):
88
-        """Validate ssh connection and authentication
89
-
90
-           This method raises an Exception when the validation fails.
91
-        """
92
-        self.ssh_client.test_connection_auth()

+ 0
- 247
manila_tempest_tests/config.py View File

@@ -1,247 +0,0 @@
1
-# Copyright 2014 Mirantis Inc.
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
-from __future__ import print_function
17
-
18
-from oslo_config import cfg
19
-
20
-service_option = cfg.BoolOpt("manila",
21
-                             default=True,
22
-                             help="Whether or not manila is expected to be "
23
-                                  "available")
24
-
25
-share_group = cfg.OptGroup(name="share", title="Share Service Options")
26
-
27
-ShareGroup = [
28
-    cfg.StrOpt("min_api_microversion",
29
-               default="2.0",
30
-               help="The minimum api microversion is configured to be the "
31
-                    "value of the minimum microversion supported by Manila."),
32
-    cfg.StrOpt("max_api_microversion",
33
-               default="2.42",
34
-               help="The maximum api microversion is configured to be the "
35
-                    "value of the latest microversion supported by Manila."),
36
-    cfg.StrOpt("region",
37
-               default="",
38
-               help="The share region name to use. If empty, the value "
39
-                    "of identity.region is used instead. If no such region "
40
-                    "is found in the service catalog, the first found one is "
41
-                    "used."),
42
-    cfg.StrOpt("catalog_type",
43
-               default="share",
44
-               help="Catalog type of the Share service."),
45
-    cfg.StrOpt('endpoint_type',
46
-               default='publicURL',
47
-               choices=['public', 'admin', 'internal',
48
-                        'publicURL', 'adminURL', 'internalURL'],
49
-               help="The endpoint type to use for the share service."),
50
-    cfg.BoolOpt("multitenancy_enabled",
51
-                default=True,
52
-                help="This option used to determine backend driver type, "
53
-                     "multitenant driver uses share-networks, but "
54
-                     "single-tenant doesn't."),
55
-    cfg.BoolOpt("create_networks_when_multitenancy_enabled",
56
-                default=True,
57
-                help="This option is used only when other "
58
-                     "'multitenancy_enabled' option is set to 'True'. "
59
-                     "If this one is set to True, then tempest will create "
60
-                     "neutron networks for each new manila share-network "
61
-                     "it creates. Else it will use manila share-networks with "
62
-                     "empty values (case of StandAloneNetworkPlugin and "
63
-                     "NeutronSingleNetworkPlugin)."),
64
-    cfg.ListOpt("enable_protocols",
65
-                default=["nfs", "cifs"],
66
-                help="First value of list is protocol by default, "
67
-                     "items of list show enabled protocols at all."),
68
-    cfg.ListOpt("enable_ip_rules_for_protocols",
69
-                default=["nfs", "cifs", ],
70
-                help="Selection of protocols, that should "
71
-                     "be covered with ip rule tests"),
72
-    cfg.ListOpt("enable_user_rules_for_protocols",
73
-                default=[],
74
-                help="Selection of protocols, that should "
75
-                     "be covered with user rule tests"),
76
-    cfg.ListOpt("enable_cert_rules_for_protocols",
77
-                default=["glusterfs", ],
78
-                help="Protocols that should be covered with cert rule tests."),
79
-    cfg.ListOpt("enable_cephx_rules_for_protocols",
80
-                default=["cephfs", ],
81
-                help="Protocols to be covered with cephx rule tests."),
82
-    cfg.StrOpt("username_for_user_rules",
83
-               default="Administrator",
84
-               help="Username, that will be used in user tests."),
85
-    cfg.ListOpt("enable_ro_access_level_for_protocols",
86
-                default=["nfs", ],
87
-                help="List of protocols to run tests with ro access level."),
88
-
89
-    # Capabilities
90
-    cfg.StrOpt("capability_storage_protocol",
91
-               deprecated_name="storage_protocol",
92
-               default="NFS_CIFS",
93
-               help="Backend protocol to target when creating volume types."),
94
-    cfg.BoolOpt("capability_snapshot_support",
95
-                help="Defines extra spec that satisfies specific back end "
96
-                     "capability called 'snapshot_support' and will be used "
97
-                     "for setting up custom share type. Defaults to value of "
98
-                     "other config option 'run_snapshot_tests'."),
99
-    cfg.BoolOpt("capability_create_share_from_snapshot_support",
100
-                help="Defines extra spec that satisfies specific back end "
101
-                     "capability called 'create_share_from_snapshot_support' "
102
-                     "and will be used for setting up a custom share type. "
103
-                     "Defaults to the value of run_snapshot_tests. Set it to "
104
-                     "False if the driver being tested does not support "
105
-                     "creating shares from snapshots."),
106
-    cfg.BoolOpt("capability_revert_to_snapshot_support",
107
-                deprecated_for_removal=True,
108
-                deprecated_reason="Redundant configuration option. Please use "
109
-                                  "'run_revert_to_snapshot_tests' config "
110
-                                  "option instead.",
111
-                help="Defines extra spec that satisfies specific back end "
112
-                     "capability called 'revert_to_snapshot_support' "
113
-                     "and will be used for setting up custom share type. "
114
-                     "Defaults to the value of run_revert_to_snapshot_tests."),
115
-    cfg.StrOpt("capability_sg_consistent_snapshot_support",
116
-               choices=["host", "pool", None],
117
-               help="Backend capability to create consistent snapshots of "
118
-                    "share group members. Will be used with creation "
119
-                    "of new share group types as group spec."),
120
-    cfg.StrOpt("share_network_id",
121
-               default="",
122
-               help="Some backend drivers requires share network "
123
-                    "for share creation. Share network id, that will be "
124
-                    "used for shares. If not set, it won't be used."),
125
-    cfg.StrOpt("alt_share_network_id",
126
-               default="",
127
-               help="Share network id, that will be used for shares"
128
-                    " in alt tenant. If not set, it won't be used"),
129
-    cfg.StrOpt("admin_share_network_id",
130
-               default="",
131
-               help="Share network id, that will be used for shares"
132
-                    " in admin tenant. If not set, it won't be used"),
133
-    cfg.BoolOpt("multi_backend",
134
-                default=False,
135
-                help="Runs Manila multi-backend tests."),
136
-    cfg.ListOpt("backend_names",
137
-                default=[],
138
-                help="Names of share backends, that will be used with "
139
-                     "multibackend tests. Tempest will use first two values."),
140
-    cfg.IntOpt("share_creation_retry_number",
141
-               default=0,
142
-               help="Defines number of retries for share creation. "
143
-                    "It is useful to avoid failures caused by unstable "
144
-                    "environment."),
145
-    cfg.IntOpt("build_interval",
146
-               default=3,
147
-               help="Time in seconds between share availability checks."),
148
-    cfg.IntOpt("build_timeout",
149
-               default=500,
150
-               help="Timeout in seconds to wait for a share to become"
151
-                    "available."),
152
-    cfg.BoolOpt("suppress_errors_in_cleanup",
153
-                default=False,
154
-                help="Whether to suppress errors with clean up operation "
155
-                     "or not. There are cases when we may want to skip "
156
-                     "such errors and catch only test errors."),
157
-
158
-    # Switching ON/OFF test suites filtered by features
159
-    cfg.BoolOpt("run_quota_tests",
160
-                default=True,
161
-                help="Defines whether to run quota tests or not."),
162
-    cfg.BoolOpt("run_extend_tests",
163
-                default=True,
164
-                help="Defines whether to run share extend tests or not. "
165
-                     "Disable this feature if used driver doesn't "
166
-                     "support it."),
167
-    cfg.BoolOpt("run_shrink_tests",
168
-                default=True,
169
-                help="Defines whether to run share shrink tests or not. "
170
-                     "Disable this feature if used driver doesn't "
171
-                     "support it."),
172
-    cfg.BoolOpt("run_snapshot_tests",
173
-                default=True,
174
-                help="Defines whether to run tests that use share snapshots "
175
-                     "or not. Disable this feature if used driver doesn't "
176
-                     "support it."),
177
-    cfg.BoolOpt("run_revert_to_snapshot_tests",
178
-                default=False,
179
-                help="Defines whether to run tests that revert shares "
180
-                     "to snapshots or not. Enable this feature if used "
181
-                     "driver supports it."),
182
-    cfg.BoolOpt("run_share_group_tests",
183
-                default=True,
184
-                deprecated_name="run_consistency_group_tests",
185
-                help="Defines whether to run share group tests or not."),
186
-    cfg.BoolOpt("run_replication_tests",
187
-                default=False,
188
-                help="Defines whether to run replication tests or not. "
189
-                     "Enable this feature if the driver is configured "
190
-                     "for replication."),
191
-    cfg.BoolOpt("run_multiple_share_replicas_tests",
192
-                default=True,
193
-                help="Defines whether to run multiple replicas creation test "
194
-                     "or not. Enable this if the driver can create more than "
195
-                     "one replica for a share."),
196
-    cfg.BoolOpt("run_host_assisted_migration_tests",
197
-                deprecated_name="run_migration_tests",
198
-                default=False,
199
-                help="Enable or disable host-assisted migration tests."),
200
-    cfg.BoolOpt("run_driver_assisted_migration_tests",
201
-                deprecated_name="run_migration_tests",
202
-                default=False,
203
-                help="Enable or disable driver-assisted migration tests."),
204
-    cfg.BoolOpt("run_migration_with_preserve_snapshots_tests",
205
-                default=False,
206
-                help="Enable or disable migration with "
207
-                     "preserve_snapshots tests set to True."),
208
-    cfg.BoolOpt("run_manage_unmanage_tests",
209
-                default=False,
210
-                help="Defines whether to run manage/unmanage tests or not. "
211
-                     "These test may leave orphaned resources, so be careful "
212
-                     "enabling this opt."),
213
-    cfg.BoolOpt("run_manage_unmanage_snapshot_tests",
214
-                default=False,
215
-                help="Defines whether to run manage/unmanage snapshot tests "
216
-                     "or not. These tests may leave orphaned resources, so be "
217
-                     "careful enabling this opt."),
218
-    cfg.BoolOpt("run_mount_snapshot_tests",
219
-                default=False,
220
-                help="Enable or disable mountable snapshot tests."),
221
-
222
-    cfg.StrOpt("image_with_share_tools",
223
-               default="manila-service-image-master",
224
-               help="Image name for vm booting with nfs/smb clients tool."),
225
-    cfg.StrOpt("image_username",
226
-               default="manila",
227
-               help="Image username."),
228
-    cfg.StrOpt("image_password",
229
-               help="Image password. Should be used for "
230
-                    "'image_with_share_tools' without Nova Metadata support."),
231
-    cfg.StrOpt("client_vm_flavor_ref",
232
-               default="100",
233
-               help="Flavor used for client vm in scenario tests."),
234
-    cfg.IntOpt("migration_timeout",
235
-               default=1500,
236
-               help="Time to wait for share migration before "
237
-                    "timing out (seconds)."),
238
-    cfg.StrOpt("default_share_type_name",
239
-               help="Default share type name to use in tempest tests."),
240
-    cfg.StrOpt("backend_replication_type",
241
-               default='none',
242
-               choices=['none', 'writable', 'readable', 'dr'],
243
-               help="Specify the replication type supported by the backend."),
244
-    cfg.IntOpt("share_size",
245
-               default=1,
246
-               help="Default size in GB for shares created by share tests."),
247
-]

+ 0
- 75
manila_tempest_tests/plugin.py View File

@@ -1,75 +0,0 @@
1
-# Copyright 2015 Deutsche Telekom AG
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
-import os
18
-
19
-from tempest import config
20
-from tempest.test_discover import plugins
21
-
22
-from manila_tempest_tests import config as config_share
23
-
24
-
25
-class ManilaTempestPlugin(plugins.TempestPlugin):
26
-    def load_tests(self):
27
-        base_path = os.path.split(os.path.dirname(
28
-            os.path.abspath(__file__)))[0]
29
-        test_dir = "manila_tempest_tests/tests"
30
-        full_test_dir = os.path.join(base_path, test_dir)
31
-        return full_test_dir, base_path
32
-
33
-    def register_opts(self, conf):
34
-        conf.register_opt(config_share.service_option,
35
-                          group='service_available')
36
-        conf.register_group(config_share.share_group)
37
-        conf.register_opts(config_share.ShareGroup, group='share')
38
-
39
-        # NOTE(vponomaryov): Set options 'capability_snapshot_support' and
40
-        # 'capability_create_share_from_snapshot_support' to opt
41
-        # 'run_snapshot_tests' if not configured.
42
-        if conf.share.capability_snapshot_support is None:
43
-            conf.set_default(
44
-                "capability_snapshot_support",
45
-                conf.share.run_snapshot_tests,
46
-                group="share",
47
-            )
48
-        if conf.share.capability_create_share_from_snapshot_support is None:
49
-            conf.set_default(
50
-                "capability_create_share_from_snapshot_support",
51
-                conf.share.run_snapshot_tests,
52
-                group="share",
53
-            )
54
-
55
-    def get_opt_lists(self):
56
-        return [(config_share.share_group.name, config_share.ShareGroup),
57
-                ('service_available', [config_share.service_option])]
58
-
59
-    def get_service_clients(self):
60
-        shares_config = config.service_client_config('share')
61
-        v1_params = {
62
-            'name': 'share_v1',
63
-            'service_version': 'share.v1',
64
-            'module_path': 'manila_tempest_tests.services.share.json',
65
-            'client_names': ['SharesClient'],
66
-        }
67
-        v2_params = {
68
-            'name': 'share_v2',
69
-            'service_version': 'share.v2',
70
-            'module_path': 'manila_tempest_tests.services.share.v2',
71
-            'client_names': ['SharesV2Client'],
72
-        }
73
-        v1_params.update(shares_config)
74
-        v2_params.update(shares_config)
75
-        return [v1_params, v2_params]

+ 0
- 0
manila_tempest_tests/services/__init__.py View File


+ 0
- 18
manila_tempest_tests/services/share/__init__.py View File

@@ -1,18 +0,0 @@
1
-# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
2
-#
3
-# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
-# use this file except in compliance with the License. You may obtain a copy of
5
-# the License at
6
-#
7
-#    http://www.apache.org/licenses/LICENSE-2.0
8
-#
9
-# Unless required by applicable law or agreed to in writing, software
10
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
-# License for the specific language governing permissions and limitations under
13
-# the License.
14
-
15
-from manila_tempest_tests.services.share import json as v1
16
-from manila_tempest_tests.services.share.v2 import json as v2
17
-
18
-__all__ = ['v1', 'v2']

+ 0
- 17
manila_tempest_tests/services/share/json/__init__.py View File

@@ -1,17 +0,0 @@
1
-# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
2
-#
3
-# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
-# use this file except in compliance with the License. You may obtain a copy of
5
-# the License at
6
-#
7
-#    http://www.apache.org/licenses/LICENSE-2.0
8
-#
9
-# Unless required by applicable law or agreed to in writing, software
10
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
-# License for the specific language governing permissions and limitations under
13
-# the License.
14
-
15
-from manila_tempest_tests.services.share.json.shares_client import SharesClient
16
-
17
-__all__ = ['SharesClient']

+ 0
- 760
manila_tempest_tests/services/share/json/shares_client.py View File

@@ -1,760 +0,0 @@
1
-# Copyright 2014 Mirantis Inc.
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
-import json
17
-import time
18
-
19
-import six
20
-from six.moves.urllib import parse as urlparse
21
-
22
-from tempest import config
23
-from tempest.lib.common import rest_client
24
-from tempest.lib.common.utils import data_utils
25
-from tempest.lib import exceptions
26
-
27
-from manila_tempest_tests import share_exceptions
28
-
29
-CONF = config.CONF
30
-
31
-
32
-class SharesClient(rest_client.RestClient):
33
-    """Tempest REST client for Manila.
34
-
35
-    It handles shares and access to it in OpenStack.
36
-    """
37
-
38
-    def __init__(self, auth_provider, **kwargs):
39
-        super(SharesClient, self).__init__(auth_provider, **kwargs)
40
-        self.share_protocol = None
41
-        if CONF.share.enable_protocols:
42
-            self.share_protocol = CONF.share.enable_protocols[0]
43
-        self.share_network_id = CONF.share.share_network_id
44
-        self.share_size = CONF.share.share_size
45
-
46
-    def create_share(self, share_protocol=None, size=None,
47
-                     name=None, snapshot_id=None, description=None,
48
-                     metadata=None, share_network_id=None,
49
-                     share_type_id=None, is_public=False):
50
-        metadata = metadata or {}
51
-        if name is None:
52
-            name = data_utils.rand_name("tempest-created-share")
53
-        if description is None:
54
-            description = data_utils.rand_name("tempest-created-share-desc")
55
-        if size is None:
56
-            size = self.share_size
57
-        if share_protocol is None:
58
-            share_protocol = self.share_protocol
59
-        if share_protocol is None:
60
-            raise share_exceptions.ShareProtocolNotSpecified()
61
-        post_body = {
62
-            "share": {
63
-                "share_proto": share_protocol,
64
-                "description": description,
65
-                "snapshot_id": snapshot_id,
66
-                "name": name,
67
-                "size": size,
68
-                "metadata": metadata,
69
-                "is_public": is_public,
70
-            }
71
-        }
72
-        if share_network_id:
73
-            post_body["share"]["share_network_id"] = share_network_id
74
-        if share_type_id:
75
-            post_body["share"]["share_type"] = share_type_id
76
-        body = json.dumps(post_body)
77
-        resp, body = self.post("shares", body)
78
-        self.expected_success(200, resp.status)
79
-        return self._parse_resp(body)
80
-
81
-    def delete_share(self, share_id):
82
-        resp, body = self.delete("shares/%s" % share_id)
83
-        self.expected_success(202, resp.status)
84
-        return body
85
-
86
-    def manage_share(self, service_host, protocol, export_path,
87
-                     share_type_id, name=None, description=None):
88
-        post_body = {
89
-            "share": {
90
-                "export_path": export_path,
91
-                "service_host": service_host,
92
-                "protocol": protocol,
93
-                "share_type": share_type_id,
94
-                "name": name,
95
-                "description": description,
96
-            }
97
-        }
98
-        body = json.dumps(post_body)
99
-        resp, body = self.post("os-share-manage", body)
100
-        self.expected_success(200, resp.status)
101
-        return self._parse_resp(body)
102
-
103
-    def unmanage_share(self, share_id):
104
-        resp, body = self.post(
105
-            "os-share-unmanage/%s/unmanage" % share_id, None)
106
-        self.expected_success(202, resp.status)
107
-        return body
108
-
109
-    def list_shares(self, detailed=False, params=None):
110
-        """Get list of shares w/o filters."""
111
-        uri = 'shares/detail' if detailed else 'shares'
112
-        uri += '?%s' % urlparse.urlencode(params) if params else ''
113
-        resp, body = self.get(uri)
114
-        self.expected_success(200, resp.status)
115
-        return self._parse_resp(body)
116
-
117
-    def list_shares_with_detail(self, params=None):
118
-        """Get detailed list of shares w/o filters."""
119
-        return self.list_shares(detailed=True, params=params)
120
-
121
-    def get_share(self, share_id):
122
-        resp, body = self.get("shares/%s" % share_id)
123
-        self.expected_success(200, resp.status)
124
-        return self._parse_resp(body)
125
-
126
-    def create_access_rule(self, share_id, access_type="ip",
127
-                           access_to="0.0.0.0", access_level=None):
128
-        post_body = {
129
-            "os-allow_access": {
130
-                "access_type": access_type,
131
-                "access_to": access_to,
132
-                "access_level": access_level,
133
-            }
134
-        }
135
-        body = json.dumps(post_body)
136
-        resp, body = self.post("shares/%s/action" % share_id, body)
137
-        self.expected_success(200, resp.status)
138
-        return self._parse_resp(body)
139
-
140
-    def list_access_rules(self, share_id):
141
-        body = {"os-access_list": None}
142
-        resp, body = self.post("shares/%s/action" % share_id, json.dumps(body))
143
-        self.expected_success(200, resp.status)
144
-        return self._parse_resp(body)
145
-
146
-    def delete_access_rule(self, share_id, rule_id):
147
-        post_body = {
148
-            "os-deny_access": {
149
-                "access_id": rule_id,
150
-            }
151
-        }
152
-        body = json.dumps(post_body)
153
-        resp, body = self.post("shares/%s/action" % share_id, body)
154
-        self.expected_success(202, resp.status)
155
-        return body
156
-
157
-    def extend_share(self, share_id, new_size):
158
-        post_body = {
159
-            "os-extend": {
160
-                "new_size": new_size,
161
-            }
162
-        }
163
-        body = json.dumps(post_body)
164
-        resp, body = self.post("shares/%s/action" % share_id, body)
165
-        self.expected_success(202, resp.status)
166
-        return body
167
-
168
-    def shrink_share(self, share_id, new_size):
169
-        post_body = {
170
-            "os-shrink": {
171
-                "new_size": new_size,
172
-            }
173
-        }
174
-        body = json.dumps(post_body)
175
-        resp, body = self.post("shares/%s/action" % share_id, body)
176
-        self.expected_success(202, resp.status)
177
-        return body
178
-
179
-    def create_snapshot(self, share_id, name=None, description=None,
180
-                        force=False):
181
-        if name is None:
182
-            name = data_utils.rand_name("tempest-created-share-snap")
183
-        if description is None:
184
-            description = data_utils.rand_name(
185
-                "tempest-created-share-snap-desc")
186
-        post_body = {
187
-            "snapshot": {
188
-                "name": name,
189
-                "force": force,
190
-                "description": description,
191
-                "share_id": share_id,
192
-            }
193
-        }
194
-        body = json.dumps(post_body)
195
-        resp, body = self.post("snapshots", body)
196
-        self.expected_success(202, resp.status)
197
-        return self._parse_resp(body)
198
-
199
-    def get_snapshot(self, snapshot_id):
200
-        resp, body = self.get("snapshots/%s" % snapshot_id)
201
-        self.expected_success(200, resp.status)
202
-        return self._parse_resp(body)
203
-
204
-    def list_snapshots(self, detailed=False, params=None):
205
-        """Get list of share snapshots w/o filters."""
206
-        uri = 'snapshots/detail' if detailed else 'snapshots'
207
-        uri += '?%s' % urlparse.urlencode(params) if params else ''
208
-        resp, body = self.get(uri)
209
-        self.expected_success(200, resp.status)
210
-        return self._parse_resp(body)
211
-
212
-    def list_snapshots_with_detail(self, params=None):
213
-        """Get detailed list of share snapshots w/o filters."""
214
-        return self.list_snapshots(detailed=True, params=params)
215
-
216
-    def delete_snapshot(self, snap_id):
217
-        resp, body = self.delete("snapshots/%s" % snap_id)
218
-        self.expected_success(202, resp.status)
219
-        return body
220
-
221
-    def wait_for_share_status(self, share_id, status):
222
-        """Waits for a share to reach a given status."""
223
-        body = self.get_share(share_id)
224
-        share_name = body['name']
225
-        share_status = body['status']
226
-        start = int(time.time())
227
-
228
-        while share_status != status:
229
-            time.sleep(self.build_interval)
230
-            body = self.get_share(share_id)
231
-            share_status = body['status']
232
-            if share_status == status:
233
-                return
234
-            elif 'error' in share_status.lower():
235
-                raise share_exceptions.ShareBuildErrorException(
236
-                    share_id=share_id)
237
-
238
-            if int(time.time()) - start >= self.build_timeout:
239
-                message = ('Share %s failed to reach %s status within '
240
-                           'the required time (%s s).' %
241
-                           (share_name, status, self.build_timeout))
242
-                raise exceptions.TimeoutException(message)
243
-
244
-    def wait_for_snapshot_status(self, snapshot_id, status):
245
-        """Waits for a snapshot to reach a given status."""
246
-        body = self.get_snapshot(snapshot_id)
247
-        snapshot_name = body['name']
248
-        snapshot_status = body['status']
249
-        start = int(time.time())
250
-
251
-        while snapshot_status != status:
252
-            time.sleep(self.build_interval)
253
-            body = self.get_snapshot(snapshot_id)
254
-            snapshot_status = body['status']
255
-            if 'error' in snapshot_status:
256
-                raise share_exceptions.SnapshotBuildErrorException(
257
-                    snapshot_id=snapshot_id)
258
-
259
-            if int(time.time()) - start >= self.build_timeout:
260
-                message = ('Share Snapshot %s failed to reach %s status '
261
-                           'within the required time (%s s).' %
262
-                           (snapshot_name, status, self.build_timeout))
263
-                raise exceptions.TimeoutException(message)
264
-
265
-    def wait_for_access_rule_status(self, share_id, rule_id, status):
266
-        """Waits for an access rule to reach a given status."""
267
-        rule_status = "new"
268
-        start = int(time.time())
269
-        while rule_status != status:
270
-            time.sleep(self.build_interval)
271
-            rules = self.list_access_rules(share_id)
272
-            for rule in rules:
273
-                if rule["id"] in rule_id:
274
-                    rule_status = rule['state']
275
-                    break
276
-            if 'error' in rule_status:
277
-                raise share_exceptions.AccessRuleBuildErrorException(
278
-                    rule_id=rule_id)
279
-
280
-            if int(time.time()) - start >= self.build_timeout:
281
-                message = ('Share Access Rule %s failed to reach %s status '
282
-                           'within the required time (%s s).' %
283
-                           (rule_id, status, self.build_timeout))
284
-                raise exceptions.TimeoutException(message)
285
-
286
-    def default_quotas(self, tenant_id):
287
-        resp, body = self.get("os-quota-sets/%s/defaults" % tenant_id)
288
-        self.expected_success(200, resp.status)
289
-        return self._parse_resp(body)
290
-
291
-    def show_quotas(self, tenant_id, user_id=None):
292
-        uri = "os-quota-sets/%s" % tenant_id
293
-        if user_id is not None:
294
-            uri += "?user_id=%s" % user_id
295
-        resp, body = self.get(uri)
296
-        self.expected_success(200, resp.status)
297
-        return self._parse_resp(body)
298
-
299
-    def reset_quotas(self, tenant_id, user_id=None):
300
-        uri = "os-quota-sets/%s" % tenant_id
301
-        if user_id is not None:
302
-            uri += "?user_id=%s" % user_id
303
-        resp, body = self.delete(uri)
304
-        self.expected_success(202, resp.status)
305
-        return body
306
-
307
-    def update_quotas(self, tenant_id, user_id=None, shares=None,
308
-                      snapshots=None, gigabytes=None, snapshot_gigabytes=None,
309
-                      share_networks=None, force=True):
310
-        uri = "os-quota-sets/%s" % tenant_id
311
-        if user_id is not None:
312
-            uri += "?user_id=%s" % user_id
313
-
314
-        put_body = {"tenant_id": tenant_id}
315
-        if force:
316
-            put_body["force"] = "true"
317
-        if shares is not None:
318
-            put_body["shares"] = shares
319
-        if snapshots is not None:
320
-            put_body["snapshots"] = snapshots
321
-        if gigabytes is not None:
322
-            put_body["gigabytes"] = gigabytes
323
-        if snapshot_gigabytes is not None:
324
-            put_body["snapshot_gigabytes"] = snapshot_gigabytes
325
-        if share_networks is not None:
326
-            put_body["share_networks"] = share_networks
327
-        put_body = json.dumps({"quota_set": put_body})
328
-
329
-        resp, body = self.put(uri, put_body)
330
-        self.expected_success(200, resp.status)
331
-        return self._parse_resp(body)
332
-
333
-    def get_limits(self):
334
-        resp, body = self.get("limits")
335
-        self.expected_success(200, resp.status)
336
-        return self._parse_resp(body)
337
-
338
-    def is_resource_deleted(self, *args, **kwargs):
339
-        """Verifies whether provided resource deleted or not.
340
-
341
-        :param kwargs: dict with expected keys 'share_id', 'snapshot_id',
342
-        :param kwargs: 'sn_id', 'ss_id', 'vt_id' and 'server_id'
343
-        :raises share_exceptions.InvalidResource
344
-        """
345
-        if "share_id" in kwargs:
346
-            if "rule_id" in kwargs:
347
-                rule_id = kwargs.get("rule_id")
348
-                share_id = kwargs.get("share_id")
349
-                rules = self.list_access_rules(share_id)
350
-                for rule in rules:
351
-                    if rule["id"] == rule_id:
352
-                        return False
353
-                return True
354
-            else:
355
-                return self._is_resource_deleted(
356
-                    self.get_share, kwargs.get("share_id"))
357
-        elif "snapshot_id" in kwargs:
358
-            return self._is_resource_deleted(
359
-                self.get_snapshot, kwargs.get("snapshot_id"))
360
-        elif "sn_id" in kwargs:
361
-            return self._is_resource_deleted(
362
-                self.get_share_network, kwargs.get("sn_id"))
363
-        elif "ss_id" in kwargs:
364
-            return self._is_resource_deleted(
365
-                self.get_security_service, kwargs.get("ss_id"))
366
-        elif "vt_id" in kwargs:
367
-            return self._is_resource_deleted(
368
-                self.get_volume_type, kwargs.get("vt_id"))
369
-        elif "st_id" in kwargs:
370
-            return self._is_resource_deleted(
371
-                self.get_share_type, kwargs.get("st_id"))
372
-        elif "server_id" in kwargs:
373
-            return self._is_resource_deleted(
374
-                self.show_share_server, kwargs.get("server_id"))
375
-        else:
376
-            raise share_exceptions.InvalidResource(
377
-                message=six.text_type(kwargs))
378
-
379
-    def _is_resource_deleted(self, func, res_id):
380
-        try:
381
-            res = func(res_id)
382
-        except exceptions.NotFound:
383
-            return True
384
-        if res.get('status') in ['error_deleting', 'error']:
385
-            # Resource has "error_deleting" status and can not be deleted.
386
-            resource_type = func.__name__.split('_', 1)[-1]
387
-            raise share_exceptions.ResourceReleaseFailed(
388
-                res_type=resource_type, res_id=res_id)
389
-        return False
390
-
391
-    def wait_for_resource_deletion(self, *args, **kwargs):
392
-        """Waits for a resource to be deleted."""
393
-        start_time = int(time.time())
394
-        while True:
395
-            if self.is_resource_deleted(*args, **kwargs):
396
-                return
397
-            if int(time.time()) - start_time >= self.build_timeout:
398
-                raise exceptions.TimeoutException
399
-            time.sleep(self.build_interval)
400
-
401
-    def list_extensions(self):
402
-        resp, extensions = self.get("extensions")
403
-        self.expected_success(200, resp.status)
404
-        return self._parse_resp(extensions)
405
-
406
-    def update_share(self, share_id, name=None, desc=None, is_public=None):
407
-        body = {"share": {}}
408
-        if name is not None:
409
-            body["share"].update({"display_name": name})
410
-        if desc is not None:
411
-            body["share"].update({"display_description": desc})
412
-        if is_public is not None:
413
-            body["share"].update({"is_public": is_public})
414
-        body = json.dumps(body)
415
-        resp, body = self.put("shares/%s" % share_id, body)
416
-        self.expected_success(200, resp.status)
417
-        return self._parse_resp(body)
418
-
419
-    def rename_snapshot(self, snapshot_id, name, desc=None):
420
-        body = {"snapshot": {"display_name": name}}
421
-        if desc is not None:
422
-            body["snapshot"].update({"display_description": desc})
423
-        body = json.dumps(body)
424
-        resp, body = self.put("snapshots/%s" % snapshot_id, body)
425
-        self.expected_success(200, resp.status)
426
-        return self._parse_resp(body)
427
-
428
-    def reset_state(self, s_id, status="error", s_type="shares"):
429
-        """Resets the state of a share or a snapshot.
430
-
431
-        status: available, error, creating, deleting, error_deleting
432
-        s_type: shares, snapshots
433
-        """
434
-        body = {"os-reset_status": {"status": status}}
435
-        body = json.dumps(body)
436
-        resp, body = self.post("%s/%s/action" % (s_type, s_id), body)
437
-        self.expected_success(202, resp.status)
438
-        return body
439
-
440
-    def force_delete(self, s_id, s_type="shares"):
441
-        """Force delete share or snapshot.
442
-
443
-        s_type: shares, snapshots
444
-        """
445
-        body = {"os-force_delete": None}
446
-        body = json.dumps(body)
447
-        resp, body = self.post("%s/%s/action" % (s_type, s_id), body)
448
-        self.expected_success(202, resp.status)
449
-        return body
450
-
451
-###############
452
-
453
-    def list_services(self, params=None):
454
-        """List services."""
455
-        uri = 'os-services'
456
-        if params:
457
-            uri += '?%s' % urlparse.urlencode(params)
458
-        resp, body = self.get(uri)
459
-        self.expected_success(200, resp.status)
460
-        return self._parse_resp(body)
461
-
462
-###############
463
-
464
-    def _update_metadata(self, share_id, metadata=None, method="post"):
465
-        uri = "shares/%s/metadata" % share_id
466
-        if metadata is None:
467
-            metadata = {}
468
-        post_body = {"metadata": metadata}
469
-        body = json.dumps(post_body)
470
-        if method is "post":
471
-            resp, metadata = self.post(uri, body)
472
-        if method is "put":
473
-            resp, metadata = self.put(uri, body)
474
-        self.expected_success(200, resp.status)
475
-        return self._parse_resp(metadata)
476
-
477
-    def set_metadata(self, share_id, metadata=None):
478
-        return self._update_metadata(share_id, metadata)
479
-
480
-    def update_all_metadata(self, share_id, metadata=None):
481
-        return self._update_metadata(share_id, metadata, method="put")
482
-
483
-    def delete_metadata(self, share_id, key):
484
-        resp, body = self.delete("shares/%s/metadata/%s" % (share_id, key))
485
-        self.expected_success(200, resp.status)
486
-        return body
487
-
488
-    def get_metadata(self, share_id):
489
-        resp, body = self.get("shares/%s/metadata" % share_id)
490
-        self.expected_success(200, resp.status)
491
-        return self._parse_resp(body)
492
-
493
-###############
494
-
495
-    def create_security_service(self, ss_type="ldap", **kwargs):
496
-        # ss_type: ldap, kerberos, active_directory
497
-        # kwargs: name, description, dns_ip, server, domain, user, password
498
-        post_body = {"type": ss_type}
499
-        post_body.update(kwargs)
500
-        body = json.dumps({"security_service": post_body})
501
-        resp, body = self.post("security-services", body)
502
-        self.expected_success(200, resp.status)
503
-        return self._parse_resp(body)
504
-
505
-    def update_security_service(self, ss_id, **kwargs):
506
-        # ss_id - id of security-service entity
507
-        # kwargs: dns_ip, server, domain, user, password, name, description
508
-        # for 'active' status can be changed
509
-        # only 'name' and 'description' fields
510
-        body = json.dumps({"security_service": kwargs})
511
-        resp, body = self.put("security-services/%s" % ss_id, body)
512
-        self.expected_success(200, resp.status)
513
-        return self._parse_resp(body)
514
-
515
-    def get_security_service(self, ss_id):
516
-        resp, body = self.get("security-services/%s" % ss_id)
517
-        self.expected_success(200, resp.status)
518
-        return self._parse_resp(body)
519
-
520
-    def list_security_services(self, detailed=False, params=None):
521
-        uri = "security-services"
522
-        if detailed:
523
-            uri += '/detail'
524
-        if params:
525
-            uri += "?%s" % urlparse.urlencode(params)
526
-        resp, body = self.get(uri)
527
-        self.expected_success(200, resp.status)
528
-        return self._parse_resp(body)
529
-
530
-    def delete_security_service(self, ss_id):
531
-        resp, body = self.delete("security-services/%s" % ss_id)
532
-        self.expected_success(202, resp.status)
533
-        return body
534
-
535
-###############
536
-
537
-    def create_share_network(self, **kwargs):
538
-        # kwargs: name, description
539
-        # + for neutron: neutron_net_id, neutron_subnet_id
540
-        body = json.dumps({"share_network": kwargs})
541
-        resp, body = self.post("share-networks", body)
542
-        self.expected_success(200, resp.status)
543
-        return self._parse_resp(body)
544
-
545
-    def update_share_network(self, sn_id, **kwargs):
546
-        # kwargs: name, description
547
-        # + for neutron: neutron_net_id, neutron_subnet_id
548
-        body = json.dumps({"share_network": kwargs})
549
-        resp, body = self.put("share-networks/%s" % sn_id, body)
550
-        self.expected_success(200, resp.status)
551
-        return self._parse_resp(body)
552
-
553
-    def get_share_network(self, sn_id):
554
-        resp, body = self.get("share-networks/%s" % sn_id)
555
-        self.expected_success(200, resp.status)
556
-        return self._parse_resp(body)
557
-
558
-    def list_share_networks(self):
559
-        resp, body = self.get("share-networks")
560
-        self.expected_success(200, resp.status)
561
-        return self._parse_resp(body)
562
-
563
-    def list_share_networks_with_detail(self, params=None):
564
-        """List the details of all shares."""
565
-        uri = "share-networks/detail"
566
-        if params:
567
-            uri += "?%s" % urlparse.urlencode(params)
568
-        resp, body = self.get(uri)
569
-        self.expected_success(200, resp.status)
570
-        return self._parse_resp(body)
571
-
572
-    def delete_share_network(self, sn_id):
573
-        resp, body = self.delete("share-networks/%s" % sn_id)
574
-        self.expected_success(202, resp.status)
575
-        return body
576
-
577
-###############
578
-
579
-    def _map_security_service_and_share_network(self, sn_id, ss_id,
580
-                                                action="add"):
581
-        # sn_id: id of share_network_entity
582
-        # ss_id: id of security service entity
583
-        # action: add, remove
584
-        data = {
585
-            "%s_security_service" % action: {
586
-                "security_service_id": ss_id,
587
-            }
588
-        }
589
-        body = json.dumps(data)
590
-        resp, body = self.post("share-networks/%s/action" % sn_id, body)
591
-        self.expected_success(200, resp.status)
592
-        return self._parse_resp(body)
593
-
594
-    def add_sec_service_to_share_network(self, sn_id, ss_id):
595
-        body = self._map_security_service_and_share_network(sn_id, ss_id)
596
-        return body
597
-
598
-    def remove_sec_service_from_share_network(self, sn_id, ss_id):
599
-        body = self._map_security_service_and_share_network(
600
-            sn_id, ss_id, "remove")
601
-        return body
602
-
603
-    def list_sec_services_for_share_network(self, sn_id):
604
-        resp, body = self.get("security-services?share_network_id=%s" % sn_id)
605
-        self.expected_success(200, resp.status)
606
-        return self._parse_resp(body)
607
-
608
-###############
609
-
610
-    def list_share_types(self, params=None):
611
-        uri = 'types'
612
-        if params is not None:
613
-            uri += '?%s' % urlparse.urlencode(params)
614
-        resp, body = self.get(uri)
615
-        self.expected_success(200, resp.status)
616
-        return self._parse_resp(body)
617
-
618
-    def create_share_type(self, name, is_public=True, **kwargs):
619
-        post_body = {
620
-            'name': name,
621
-            'extra_specs': kwargs.get('extra_specs'),
622
-            'os-share-type-access:is_public': is_public,
623
-        }
624
-        post_body = json.dumps({'share_type': post_body})
625
-        resp, body = self.post('types', post_body)
626
-        self.expected_success(200, resp.status)
627
-        return self._parse_resp(body)
628
-
629
-    def delete_share_type(self, share_type_id):
630
-        resp, body = self.delete("types/%s" % share_type_id)
631
-        self.expected_success(202, resp.status)
632
-        return body
633
-
634
-    def get_share_type(self, share_type_id):
635
-        resp, body = self.get("types/%s" % share_type_id)
636
-        self.expected_success(200, resp.status)
637
-        return self._parse_resp(body)
638
-
639
-    def add_access_to_share_type(self, share_type_id, project_id):
640
-        uri = 'types/%s/action' % share_type_id
641
-        post_body = {'project': project_id}
642
-        post_body = json.dumps({'addProjectAccess': post_body})
643
-        resp, body = self.post(uri, post_body)
644
-        self.expected_success(202, resp.status)
645
-        return body
646
-
647
-    def remove_access_from_share_type(self, share_type_id, project_id):
648
-        uri = 'types/%s/action' % share_type_id
649
-        post_body = {'project': project_id}
650
-        post_body = json.dumps({'removeProjectAccess': post_body})
651
-        resp, body = self.post(uri, post_body)
652
-        self.expected_success(202, resp.status)
653
-        return body
654
-
655
-    def list_access_to_share_type(self, share_type_id):
656
-        uri = 'types/%s/os-share-type-access' % share_type_id
657
-        resp, body = self.get(uri)
658
-        # [{"share_type_id": "%st_id%", "project_id": "%project_id%"}, ]
659
-        self.expected_success(200, resp.status)
660
-        return self._parse_resp(body)
661
-
662
-###############
663
-
664
-    def create_share_type_extra_specs(self, share_type_id, extra_specs):
665
-        url = "types/%s/extra_specs" % share_type_id
666
-        post_body = json.dumps({'extra_specs': extra_specs})
667
-        resp, body = self.post(url, post_body)
668
-        self.expected_success(200, resp.status)
669
-        return self._parse_resp(body)
670
-
671
-    def get_share_type_extra_spec(self, share_type_id, extra_spec_name):
672
-        uri = "types/%s/extra_specs/%s" % (share_type_id, extra_spec_name)
673
-        resp, body = self.get(uri)
674
-        self.expected_success(200, resp.status)
675
-        return self._parse_resp(body)
676
-
677
-    def get_share_type_extra_specs(self, share_type_id, params=None):
678
-        uri = "types/%s/extra_specs" % share_type_id
679
-        if params is not None:
680
-            uri += '?%s' % urlparse.urlencode(params)
681
-        resp, body = self.get(uri)
682
-        self.expected_success(200, resp.status)
683
-        return self._parse_resp(body)
684
-
685
-    def update_share_type_extra_spec(self, share_type_id, spec_name,
686
-                                     spec_value):
687
-        uri = "types/%s/extra_specs/%s" % (share_type_id, spec_name)
688
-        extra_spec = {spec_name: spec_value}
689
-        post_body = json.dumps(extra_spec)
690
-        resp, body = self.put(uri, post_body)
691
-        self.expected_success(200, resp.status)
692
-        return self._parse_resp(body)
693
-
694
-    def update_share_type_extra_specs(self, share_type_id, extra_specs):
695
-        uri = "types/%s/extra_specs" % share_type_id
696
-        extra_specs = {"extra_specs": extra_specs}
697
-        post_body = json.dumps(extra_specs)
698
-        resp, body = self.post(uri, post_body)
699
-        self.expected_success(200, resp.status)
700
-        return self._parse_resp(body)
701
-
702
-    def delete_share_type_extra_spec(self, share_type_id, extra_spec_name):
703
-        uri = "types/%s/extra_specs/%s" % (share_type_id, extra_spec_name)
704
-        resp, body = self.delete(uri)
705
-        self.expected_success(202, resp.status)
706
-        return body
707
-
708
-###############
709
-
710
-    def list_share_servers(self, search_opts=None):
711
-        """Get list of share servers."""
712
-        uri = "share-servers"
713
-        if search_opts:
714
-            uri += "?%s" % urlparse.urlencode(search_opts)
715
-        resp, body = self.get(uri)
716
-        self.expected_success(200, resp.status)
717
-        return self._parse_resp(body)
718
-
719
-    def delete_share_server(self, share_server_id):
720
-        """Delete share server by its ID."""
721
-        uri = "share-servers/%s" % share_server_id
722
-        resp, body = self.delete(uri)
723
-        self.expected_success(202, resp.status)
724
-        return body
725
-
726
-    def show_share_server(self, share_server_id):
727
-        """Get share server info."""
728
-        uri = "share-servers/%s" % share_server_id
729
-        resp, body = self.get(uri)
730
-        self.expected_success(200, resp.status)
731
-        return self._parse_resp(body)
732
-
733
-    def show_share_server_details(self, share_server_id):
734
-        """Get share server details only."""
735
-        uri = "share-servers/%s/details" % share_server_id
736
-        resp, body = self.get(uri)
737
-        self.expected_success(200, resp.status)
738
-        return self._parse_resp(body)
739
-
740
-###############
741
-
742
-    def list_pools(self, detail=False, search_opts=None):
743
-        """Get list of scheduler pools."""
744
-        uri = 'scheduler-stats/pools'
745
-        if detail:
746
-            uri += '/detail'
747
-        if search_opts:
748
-            uri += "?%s" % urlparse.urlencode(search_opts)
749
-        resp, body = self.get(uri)
750
-        self.expected_success(200, resp.status)
751
-        return json.loads(body)
752
-
753
-###############
754
-
755
-    def list_availability_zones(self):
756
-        """Get list of availability zones."""
757
-        uri = 'os-availability-zone'
758
-        resp, body = self.get(uri)
759
-        self.expected_success(200, resp.status)
760
-        return self._parse_resp(body)

+ 0
- 18
manila_tempest_tests/services/share/v2/__init__.py View File

@@ -1,18 +0,0 @@
1
-# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
2
-#
3
-# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
-# use this file except in compliance with the License. You may obtain a copy of
5
-# the License at
6
-#
7
-#    http://www.apache.org/licenses/LICENSE-2.0
8
-#
9
-# Unless required by applicable law or agreed to in writing, software
10
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
-# License for the specific language governing permissions and limitations under
13
-# the License.
14
-
15
-from manila_tempest_tests.services.share.v2.json.shares_client import \
16
-    SharesV2Client
17
-
18
-__all__ = ['SharesV2Client']

+ 0
- 0
manila_tempest_tests/services/share/v2/json/__init__.py View File


+ 0
- 1735
manila_tempest_tests/services/share/v2/json/shares_client.py
File diff suppressed because it is too large
View File


+ 0
- 77
manila_tempest_tests/share_exceptions.py View File

@@ -1,77 +0,0 @@
1
-# Copyright 2014 Mirantis Inc.
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
-from tempest.lib import exceptions
17
-
18
-
19
-class ShareBuildErrorException(exceptions.TempestException):
20
-    message = "Share %(share_id)s failed to build and is in ERROR status"
21
-
22
-
23
-class ShareInstanceBuildErrorException(exceptions.TempestException):
24
-    message = "Share instance %(id)s failed to build and is in ERROR status"
25
-
26
-
27
-class ShareGroupBuildErrorException(exceptions.TempestException):
28
-    message = ("Share group %(share_group_id)s failed to build and "
29
-               "is in ERROR status")
30
-
31
-
32
-class AccessRuleBuildErrorException(exceptions.TempestException):
33
-    message = "Share's rule with id %(rule_id)s is in ERROR status"
34
-
35
-
36
-class SnapshotBuildErrorException(exceptions.TempestException):
37
-    message = "Snapshot %(snapshot_id)s failed to build and is in ERROR status"
38
-
39
-
40
-class SnapshotInstanceBuildErrorException(exceptions.TempestException):
41
-    message = ("Snapshot instance %(id)s failed to build and is in "
42
-               "ERROR status.")
43
-
44
-
45
-class ShareGroupSnapshotBuildErrorException(exceptions.TempestException):
46
-    message = ("Share Group Snapshot %(share_group_snapshot_id)s failed "
47
-               "to build and is in ERROR status")
48
-
49
-
50
-class ShareProtocolNotSpecified(exceptions.TempestException):
51
-    message = "Share can not be created, share protocol is not specified"
52
-
53
-
54
-class ShareNetworkNotSpecified(exceptions.TempestException):
55
-    message = "Share can not be created, share network not specified"
56
-
57
-
58
-class NoAvailableNetwork(exceptions.TempestException):
59
-    message = "No available network for service VM"
60
-
61
-
62
-class InvalidResource(exceptions.TempestException):
63
-    message = "Provided invalid resource: %(message)s"
64
-
65
-
66
-class ShareMigrationException(exceptions.TempestException):
67
-    message = ("Share %(share_id)s failed to migrate from "
68
-               "host %(src)s to host %(dest)s.")
69
-
70
-
71
-class ResourceReleaseFailed(exceptions.TempestException):
72
-    message = "Failed to release resource '%(res_type)s' with id '%(res_id)s'."
73
-
74
-
75
-class ShareReplicationTypeException(exceptions.TempestException):
76
-    message = ("Option backend_replication_type is set to incorrect value: "
77
-               "%(replication_type)s")

+ 0
- 0
manila_tempest_tests/tests/__init__.py View File


+ 0
- 0
manila_tempest_tests/tests/api/__init__.py View File


+ 0
- 0
manila_tempest_tests/tests/api/admin/__init__.py View File


+ 0
- 128
manila_tempest_tests/tests/api/admin/test_admin_actions.py View File

@@ -1,128 +0,0 @@
1
-# Copyright 2014 Mirantis Inc.
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
-from tempest import config
17
-import testtools
18
-from testtools import testcase as tc
19
-
20
-from manila_tempest_tests.tests.api import base
21
-
22
-
23
-CONF = config.CONF
24
-
25
-
26
-class AdminActionsTest(base.BaseSharesAdminTest):
27
-
28
-    @classmethod
29
-    def resource_setup(cls):
30
-        super(AdminActionsTest, cls).resource_setup()
31
-        cls.states = ["error", "available"]
32
-        cls.task_states = ["migration_starting", "data_copying_in_progress",
33
-                           "migration_success", None]
34
-        cls.bad_status = "error_deleting"
35
-        cls.sh = cls.create_share()
36
-        cls.sh_instance = (
37
-            cls.shares_v2_client.get_instances_of_share(cls.sh["id"])[0]
38
-        )
39
-        if CONF.share.run_snapshot_tests:
40
-            cls.sn = cls.create_snapshot_wait_for_active(cls.sh["id"])
41
-
42
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
43
-    def test_reset_share_state(self):
44
-        for status in self.states:
45
-            self.shares_v2_client.reset_state(self.sh["id"], status=status)
46
-            self.shares_v2_client.wait_for_share_status(self.sh["id"], status)
47
-
48
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
49
-    def test_reset_share_instance_state(self):
50
-        id = self.sh_instance["id"]
51
-        for status in self.states:
52
-            self.shares_v2_client.reset_state(
53
-                id, s_type="share_instances", status=status)
54
-            self.shares_v2_client.wait_for_share_instance_status(id, status)
55
-
56
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
57
-    @testtools.skipUnless(CONF.share.run_snapshot_tests,
58
-                          "Snapshot tests are disabled.")
59
-    def test_reset_snapshot_state_to_error(self):
60
-        for status in self.states:
61
-            self.shares_v2_client.reset_state(
62
-                self.sn["id"], s_type="snapshots", status=status)
63
-            self.shares_v2_client.wait_for_snapshot_status(
64
-                self.sn["id"], status)
65
-
66
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
67
-    def test_force_delete_share(self):
68
-        share = self.create_share()
69
-
70
-        # Change status from 'available' to 'error_deleting'
71
-        self.shares_v2_client.reset_state(share["id"], status=self.bad_status)
72
-
73
-        # Check that status was changed
74
-        check_status = self.shares_v2_client.get_share(share["id"])
75
-        self.assertEqual(self.bad_status, check_status["status"])
76
-
77
-        # Share with status 'error_deleting' should be deleted
78
-        self.shares_v2_client.force_delete(share["id"])
79
-        self.shares_v2_client.wait_for_resource_deletion(share_id=share["id"])
80
-
81
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
82
-    def test_force_delete_share_instance(self):
83
-        share = self.create_share(cleanup_in_class=False)
84
-        instances = self.shares_v2_client.get_instances_of_share(share["id"])
85
-        # Check that instance was created
86
-        self.assertEqual(1, len(instances))
87
-
88
-        instance = instances[0]
89
-
90
-        # Change status from 'available' to 'error_deleting'
91
-        self.shares_v2_client.reset_state(
92
-            instance["id"], s_type="share_instances", status=self.bad_status)
93
-
94
-        # Check that status was changed
95
-        check_status = self.shares_v2_client.get_share_instance(instance["id"])
96
-        self.assertEqual(self.bad_status, check_status["status"])
97
-
98
-        # Share with status 'error_deleting' should be deleted
99
-        self.shares_v2_client.force_delete(
100
-            instance["id"], s_type="share_instances")
101
-        self.shares_v2_client.wait_for_resource_deletion(
102
-            share_instance_id=instance["id"])
103
-
104
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
105
-    @testtools.skipUnless(CONF.share.run_snapshot_tests,
106
-                          "Snapshot tests are disabled.")
107
-    def test_force_delete_snapshot(self):
108
-        sn = self.create_snapshot_wait_for_active(self.sh["id"])
109
-
110
-        # Change status from 'available' to 'error_deleting'
111
-        self.shares_v2_client.reset_state(
112
-            sn["id"], s_type="snapshots", status=self.bad_status)
113
-
114
-        # Check that status was changed
115
-        check_status = self.shares_v2_client.get_snapshot(sn["id"])
116
-        self.assertEqual(self.bad_status, check_status["status"])
117
-
118
-        # Snapshot with status 'error_deleting' should be deleted
119
-        self.shares_v2_client.force_delete(sn["id"], s_type="snapshots")
120
-        self.shares_v2_client.wait_for_resource_deletion(snapshot_id=sn["id"])
121
-
122
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
123
-    @base.skip_if_microversion_lt("2.22")
124
-    def test_reset_share_task_state(self):
125
-        for task_state in self.task_states:
126
-            self.shares_v2_client.reset_task_state(self.sh["id"], task_state)
127
-            self.shares_v2_client.wait_for_share_status(
128
-                self.sh["id"], task_state, 'task_state')

+ 0
- 210
manila_tempest_tests/tests/api/admin/test_admin_actions_negative.py View File

@@ -1,210 +0,0 @@
1
-# Copyright 2014 Mirantis Inc.
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
-import ddt
17
-from tempest import config
18
-from tempest.lib import exceptions as lib_exc
19
-import testtools
20
-from testtools import testcase as tc
21
-
22
-from manila_tempest_tests.tests.api import base
23
-
24
-CONF = config.CONF
25
-
26
-
27
-class AdminActionsNegativeTest(base.BaseSharesMixedTest):
28
-
29
-    @classmethod
30
-    def resource_setup(cls):
31
-        super(AdminActionsNegativeTest, cls).resource_setup()
32
-        cls.admin_client = cls.admin_shares_v2_client
33
-        cls.member_client = cls.shares_v2_client
34
-        cls.sh = cls.create_share(client=cls.admin_client)
35
-        cls.sh_instance = (
36
-            cls.admin_client.get_instances_of_share(cls.sh["id"])[0]
37
-        )
38
-        if CONF.share.run_snapshot_tests:
39
-            cls.sn = cls.create_snapshot_wait_for_active(
40
-                cls.sh["id"], client=cls.admin_client)
41
-
42
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
43
-    def test_reset_share_state_to_unacceptable_state(self):
44
-        self.assertRaises(lib_exc.BadRequest,
45
-                          self.admin_client.reset_state,
46
-                          self.sh["id"], status="fake")
47
-
48
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
49
-    def test_reset_share_instance_state_to_unacceptable_state(self):
50
-        self.assertRaises(
51
-            lib_exc.BadRequest,
52
-            self.admin_client.reset_state,
53
-            self.sh_instance["id"],
54
-            s_type="share_instances",
55
-            status="fake"
56
-        )
57
-
58
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
59
-    @testtools.skipUnless(CONF.share.run_snapshot_tests,
60
-                          "Snapshot tests are disabled.")
61
-    def test_reset_snapshot_state_to_unacceptable_state(self):
62
-        self.assertRaises(lib_exc.BadRequest,
63
-                          self.admin_client.reset_state,
64
-                          self.sn["id"], s_type="snapshots", status="fake")
65
-
66
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
67
-    def test_try_reset_share_state_with_member(self):
68
-        # Even if member from another tenant, it should be unauthorized
69
-        self.assertRaises(lib_exc.Forbidden,
70
-                          self.member_client.reset_state,
71
-                          self.sh["id"])
72
-
73
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
74
-    def test_try_reset_share_instance_state_with_member(self):
75
-        # Even if member from another tenant, it should be unauthorized
76
-        self.assertRaises(lib_exc.Forbidden,
77
-                          self.member_client.reset_state,
78
-                          self.sh_instance["id"], s_type="share_instances")
79
-
80
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
81
-    @testtools.skipUnless(CONF.share.run_snapshot_tests,
82
-                          "Snapshot tests are disabled.")
83
-    def test_try_reset_snapshot_state_with_member(self):
84
-        # Even if member from another tenant, it should be unauthorized
85
-        self.assertRaises(lib_exc.Forbidden,
86
-                          self.member_client.reset_state,
87
-                          self.sn["id"], s_type="snapshots")
88
-
89
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
90
-    def test_try_force_delete_share_with_member(self):
91
-        # If a non-admin tries to do force_delete, it should be unauthorized
92
-        self.assertRaises(lib_exc.Forbidden,
93
-                          self.member_client.force_delete,
94
-                          self.sh["id"])
95
-
96
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
97
-    def test_try_force_delete_share_instance_with_member(self):
98
-        # If a non-admin tries to do force_delete, it should be unauthorized
99
-        self.assertRaises(lib_exc.Forbidden,
100
-                          self.member_client.force_delete,
101
-                          self.sh_instance["id"], s_type="share_instances")
102
-
103
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
104
-    @testtools.skipUnless(CONF.share.run_snapshot_tests,
105
-                          "Snapshot tests are disabled.")
106
-    def test_try_force_delete_snapshot_with_member(self):
107
-        # If a non-admin tries to do force_delete, it should be unauthorized
108
-        self.assertRaises(lib_exc.Forbidden,
109
-                          self.member_client.force_delete,
110
-                          self.sn["id"], s_type="snapshots")
111
-
112
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
113
-    def test_try_get_share_instance_with_member(self):
114
-        # If a non-admin tries to get instance, it should be unauthorized
115
-        self.assertRaises(lib_exc.Forbidden,
116
-                          self.member_client.get_share_instance,
117
-                          self.sh_instance["id"])
118
-
119
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
120
-    def test_try_get_instances_of_share_with_member(self):
121
-        # If a non-admin tries to list instances of given share, it should be
122
-        # unauthorized
123
-        self.assertRaises(lib_exc.Forbidden,
124
-                          self.member_client.get_instances_of_share,
125
-                          self.sh['id'])
126
-
127
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
128
-    @base.skip_if_microversion_lt("2.22")
129
-    def test_reset_task_state_invalid_state(self):
130
-        self.assertRaises(
131
-            lib_exc.BadRequest, self.admin_client.reset_task_state,
132
-            self.sh['id'], 'fake_state')
133
-
134
-
135
-@ddt.ddt
136
-class AdminActionsAPIOnlyNegativeTest(base.BaseSharesMixedTest):
137
-
138
-    @classmethod
139
-    def resource_setup(cls):
140
-        super(AdminActionsAPIOnlyNegativeTest, cls).resource_setup()
141
-        cls.admin_client = cls.admin_shares_v2_client
142
-        cls.member_client = cls.shares_v2_client
143
-
144
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
145
-    def test_try_list_share_instance_with_member(self):
146
-        # If a non-admin tries to list instances, it should be unauthorized
147
-        self.assertRaises(lib_exc.Forbidden,
148
-                          self.member_client.list_share_instances)
149
-
150
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
151
-    @base.skip_if_microversion_lt("2.22")
152
-    def test_reset_task_state_share_not_found(self):
153
-        self.assertRaises(
154
-            lib_exc.NotFound, self.admin_client.reset_task_state,
155
-            'fake_share', 'migration_error')
156
-
157
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
158
-    @testtools.skipUnless(CONF.share.run_snapshot_tests,
159
-                          "Snapshot tests are disabled.")
160
-    def test_force_delete_nonexistent_snapshot(self):
161
-        self.assertRaises(lib_exc.NotFound,
162
-                          self.admin_client.force_delete,
163
-                          "fake",
164
-                          s_type="snapshots")
165
-
166
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
167
-    def test_force_delete_nonexistent_share(self):
168
-        self.assertRaises(lib_exc.NotFound,
169
-                          self.admin_client.force_delete, "fake")
170
-
171
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
172
-    def test_force_delete_nonexistent_share_instance(self):
173
-        self.assertRaises(lib_exc.NotFound,
174
-                          self.admin_client.force_delete,
175
-                          "fake",
176
-                          s_type="share_instances")
177
-
178
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
179
-    def test_reset_nonexistent_share_state(self):
180
-        self.assertRaises(lib_exc.NotFound,
181
-                          self.admin_client.reset_state, "fake")
182
-
183
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
184
-    def test_reset_nonexistent_share_instance_state(self):
185
-        self.assertRaises(lib_exc.NotFound, self.admin_client.reset_state,
186
-                          "fake", s_type="share_instances")
187
-
188
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
189
-    @testtools.skipUnless(CONF.share.run_snapshot_tests,
190
-                          "Snapshot tests are disabled.")
191
-    def test_reset_nonexistent_snapshot_state(self):
192
-        self.assertRaises(lib_exc.NotFound, self.admin_client.reset_state,
193
-                          "fake", s_type="snapshots")
194
-
195
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
196
-    @ddt.data('migrate_share', 'migration_complete', 'reset_task_state',
197
-              'migration_get_progress', 'migration_cancel')
198
-    def test_migration_API_invalid_microversion(self, method_name):
199
-        if method_name == 'migrate_share':
200
-            self.assertRaises(
201
-                lib_exc.NotFound, getattr(self.shares_v2_client, method_name),
202
-                'fake_share', 'fake_host', version='2.21')
203
-        elif method_name == 'reset_task_state':
204
-            self.assertRaises(
205
-                lib_exc.NotFound, getattr(self.shares_v2_client, method_name),
206
-                'fake_share', 'fake_task_state', version='2.21')
207
-        else:
208
-            self.assertRaises(
209
-                lib_exc.NotFound, getattr(self.shares_v2_client, method_name),
210
-                'fake_share', version='2.21')

+ 0
- 201
manila_tempest_tests/tests/api/admin/test_export_locations.py View File

@@ -1,201 +0,0 @@
1
-# Copyright 2015 Mirantis Inc.
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
-import ddt
17
-from oslo_utils import timeutils
18
-from oslo_utils import uuidutils
19
-import six
20
-from tempest import config
21
-from testtools import testcase as tc
22
-
23
-from manila_tempest_tests.tests.api import base
24
-from manila_tempest_tests import utils
25
-
26
-CONF = config.CONF
27
-LATEST_MICROVERSION = CONF.share.max_api_microversion
28
-
29
-
30
-@base.skip_if_microversion_not_supported("2.9")
31
-@ddt.ddt
32
-class ExportLocationsTest(base.BaseSharesMixedTest):
33
-
34
-    @classmethod
35
-    def resource_setup(cls):
36
-        super(ExportLocationsTest, cls).resource_setup()
37
-        cls.admin_client = cls.admin_shares_v2_client
38
-        cls.member_client = cls.shares_v2_client
39
-        cls.share = cls.create_share(client=cls.admin_client)
40
-        cls.share = cls.admin_client.get_share(cls.share['id'])
41
-        cls.share_instances = cls.admin_client.get_instances_of_share(
42
-            cls.share['id'])
43
-
44
-    def _verify_export_location_structure(
45
-            self, export_locations, role='admin', version=LATEST_MICROVERSION,
46
-            format='summary'):
47
-
48
-        # Determine which keys to expect based on role, version and format
49
-        summary_keys = ['id', 'path']
50
-        if utils.is_microversion_ge(version, '2.14'):
51
-            summary_keys += ['preferred']
52
-
53
-        admin_summary_keys = summary_keys + [
54
-            'share_instance_id', 'is_admin_only']
55
-
56
-        detail_keys = summary_keys + ['created_at', 'updated_at']
57
-
58
-        admin_detail_keys = admin_summary_keys + ['created_at', 'updated_at']
59
-
60
-        if format == 'summary':
61
-            if role == 'admin':
62
-                expected_keys = admin_summary_keys
63
-            else:
64
-                expected_keys = summary_keys
65
-        else:
66
-            if role == 'admin':
67
-                expected_keys = admin_detail_keys
68
-            else:
69
-                expected_keys = detail_keys
70
-
71
-        if not isinstance(export_locations, (list, tuple, set)):
72
-            export_locations = (export_locations, )
73
-
74
-        for export_location in export_locations:
75
-
76
-            # Check that the correct keys are present
77
-            self.assertEqual(len(expected_keys), len(export_location))
78
-            for key in expected_keys:
79
-                self.assertIn(key, export_location)
80
-
81
-            # Check the format of ever-present summary keys
82
-            self.assertTrue(uuidutils.is_uuid_like(export_location['id']))
83
-            self.assertIsInstance(export_location['path'],
84
-                                  six.string_types)
85
-
86
-            if utils.is_microversion_ge(version, '2.14'):
87
-                self.assertIn(export_location['preferred'], (True, False))
88
-
89
-            if role == 'admin':
90
-                self.assertIn(export_location['is_admin_only'], (True, False))
91
-                self.assertTrue(uuidutils.is_uuid_like(
92
-                    export_location['share_instance_id']))
93
-
94
-            # Check the format of the detail keys
95
-            if format == 'detail':
96
-                for time in (export_location['created_at'],
97
-                             export_location['updated_at']):
98
-                    # If var 'time' has incorrect value then ValueError
99
-                    # exception is expected to be raised. So, just try parse
100
-                    # it making assertion that it has proper date value.
101
-                    timeutils.parse_strtime(time)
102
-
103
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
104
-    @utils.skip_if_microversion_not_supported('2.13')
105
-    def test_list_share_export_locations(self):
106
-        export_locations = self.admin_client.list_share_export_locations(
107
-            self.share['id'], version='2.13')
108
-
109
-        self._verify_export_location_structure(export_locations,
110
-                                               version='2.13')
111
-
112
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
113
-    @utils.skip_if_microversion_not_supported('2.14')
114
-    def test_list_share_export_locations_with_preferred_flag(self):
115
-        export_locations = self.admin_client.list_share_export_locations(
116
-            self.share['id'], version='2.14')
117
-
118
-        self._verify_export_location_structure(export_locations,
119
-                                               version='2.14')
120
-
121
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
122
-    def test_get_share_export_location(self):
123
-        export_locations = self.admin_client.list_share_export_locations(
124
-            self.share['id'])
125
-
126
-        for export_location in export_locations:
127
-            el = self.admin_client.get_share_export_location(
128
-                self.share['id'], export_location['id'])
129
-            self._verify_export_location_structure(el, format='detail')
130
-
131
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
132
-    def test_list_share_export_locations_by_member(self):
133
-        export_locations = self.member_client.list_share_export_locations(
134
-            self.share['id'])
135
-
136
-        self._verify_export_location_structure(export_locations, role='member')
137
-
138
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
139
-    def test_get_share_export_location_by_member(self):
140
-        export_locations = self.admin_client.list_share_export_locations(
141
-            self.share['id'])
142
-
143
-        for export_location in export_locations:
144
-            if export_location['is_admin_only']:
145
-                continue
146
-            el = self.member_client.get_share_export_location(
147
-                self.share['id'], export_location['id'])
148
-            self._verify_export_location_structure(el, role='member',
149
-                                                   format='detail')
150
-
151
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
152
-    @utils.skip_if_microversion_not_supported('2.13')
153
-    def test_list_share_instance_export_locations(self):
154
-        for share_instance in self.share_instances:
155
-            export_locations = (
156
-                self.admin_client.list_share_instance_export_locations(
157
-                    share_instance['id'], version='2.13'))
158
-            self._verify_export_location_structure(export_locations,
159
-                                                   version='2.13')
160
-
161
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
162
-    @utils.skip_if_microversion_not_supported('2.14')
163
-    def test_list_share_instance_export_locations_with_preferred_flag(self):
164
-        for share_instance in self.share_instances:
165
-            export_locations = (
166
-                self.admin_client.list_share_instance_export_locations(
167
-                    share_instance['id'], version='2.14'))
168
-            self._verify_export_location_structure(export_locations,
169
-                                                   version='2.14')
170
-
171
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
172
-    def test_get_share_instance_export_location(self):
173
-        for share_instance in self.share_instances:
174
-            export_locations = (
175
-                self.admin_client.list_share_instance_export_locations(
176
-                    share_instance['id']))
177
-            for el in export_locations:
178
-                el = self.admin_client.get_share_instance_export_location(
179
-                    share_instance['id'], el['id'])
180
-                self._verify_export_location_structure(el, format='detail')
181
-
182
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
183
-    def test_share_contains_all_export_locations_of_all_share_instances(self):
184
-        share_export_locations = self.admin_client.list_share_export_locations(
185
-            self.share['id'])
186
-        share_instances_export_locations = []
187
-        for share_instance in self.share_instances:
188
-            share_instance_export_locations = (
189
-                self.admin_client.list_share_instance_export_locations(
190
-                    share_instance['id']))
191
-            share_instances_export_locations.extend(
192
-                share_instance_export_locations)
193
-
194
-        self.assertEqual(
195
-            len(share_export_locations),
196
-            len(share_instances_export_locations)
197
-        )
198
-        self.assertEqual(
199
-            sorted(share_export_locations, key=lambda el: el['id']),
200
-            sorted(share_instances_export_locations, key=lambda el: el['id'])
201
-        )

+ 0
- 97
manila_tempest_tests/tests/api/admin/test_export_locations_negative.py View File

@@ -1,97 +0,0 @@
1
-# Copyright 2015 Mirantis Inc.
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
-from tempest import config
17
-from tempest.lib import exceptions as lib_exc
18
-from testtools import testcase as tc
19
-
20
-from manila_tempest_tests.tests.api import base
21
-
22
-CONF = config.CONF
23
-
24
-
25
-@base.skip_if_microversion_not_supported("2.9")
26
-class ExportLocationsNegativeTest(base.BaseSharesMixedTest):
27
-
28
-    @classmethod
29
-    def resource_setup(cls):
30
-        super(ExportLocationsNegativeTest, cls).resource_setup()
31
-        cls.admin_client = cls.admin_shares_v2_client
32
-        cls.member_client = cls.shares_v2_client
33
-        cls.share = cls.create_share(client=cls.admin_client)
34
-        cls.share = cls.admin_client.get_share(cls.share['id'])
35
-        cls.share_instances = cls.admin_client.get_instances_of_share(
36
-            cls.share['id'])
37
-
38
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
39
-    def test_get_inexistent_share_export_location(self):
40
-        self.assertRaises(
41
-            lib_exc.NotFound,
42
-            self.admin_client.get_share_export_location,
43
-            self.share['id'],
44
-            "fake-inexistent-share-instance-id",
45
-        )
46
-
47
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
48
-    def test_get_inexistent_share_instance_export_location(self):
49
-        for share_instance in self.share_instances:
50
-            self.assertRaises(
51
-                lib_exc.NotFound,
52
-                self.admin_client.get_share_instance_export_location,
53
-                share_instance['id'],
54
-                "fake-inexistent-share-instance-id",
55
-            )
56
-
57
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
58
-    def test_list_share_instance_export_locations_by_member(self):
59
-        for share_instance in self.share_instances:
60
-            self.assertRaises(
61
-                lib_exc.Forbidden,
62
-                self.member_client.list_share_instance_export_locations,
63
-                "fake-inexistent-share-instance-id",
64
-            )
65
-
66
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
67
-    def test_get_share_instance_export_location_by_member(self):
68
-        for share_instance in self.share_instances:
69
-            export_locations = (
70
-                self.admin_client.list_share_instance_export_locations(
71
-                    share_instance['id']))
72
-            for el in export_locations:
73
-                self.assertRaises(
74
-                    lib_exc.Forbidden,
75
-                    self.member_client.get_share_instance_export_location,
76
-                    share_instance['id'], el['id'],
77
-                )
78
-
79
-
80
-@base.skip_if_microversion_not_supported("2.9")
81
-class ExportLocationsAPIOnlyNegativeTest(base.BaseSharesAdminTest):
82
-
83
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
84
-    def test_get_export_locations_by_nonexistent_share(self):
85
-        self.assertRaises(
86
-            lib_exc.NotFound,
87
-            self.shares_v2_client.list_share_export_locations,
88
-            "fake-inexistent-share-id",
89
-        )
90
-
91
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
92
-    def test_get_export_locations_by_nonexistent_share_instance(self):
93
-        self.assertRaises(
94
-            lib_exc.NotFound,
95
-            self.shares_v2_client.list_share_instance_export_locations,
96
-            "fake-inexistent-share-instance-id",
97
-        )

+ 0
- 634
manila_tempest_tests/tests/api/admin/test_migration.py View File

@@ -1,634 +0,0 @@
1
-# Copyright 2015 Hitachi Data Systems.
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
-import ddt
18
-from tempest import config
19
-from tempest.lib.common.utils import data_utils
20
-import testtools
21
-from testtools import testcase as tc
22
-
23
-from manila_tempest_tests.common import constants
24
-from manila_tempest_tests.tests.api import base
25
-from manila_tempest_tests import utils
26
-
27
-CONF = config.CONF
28
-
29
-
30
-class MigrationBase(base.BaseSharesAdminTest):
31
-    """Base test class for Share Migration.
32
-
33
-    Tests share migration in multi-backend environment.
34
-
35
-    This class covers:
36
-    1) Driver-assisted migration: force_host_assisted_migration, nondisruptive,
37
-    writable and preserve-metadata are False.
38
-    2) Host-assisted migration: force_host_assisted_migration is True,
39
-    nondisruptive, writable, preserve-metadata and preserve-snapshots are
40
-    False.
41
-    3) 2-phase migration of both Host-assisted and Driver-assisted.
42
-    4) Cancelling migration past first phase.
43
-    5) Changing driver modes through migration.
44
-
45
-    No need to test with writable, preserve-metadata and non-disruptive as
46
-    True, values are supplied to the driver which decides what to do. Test
47
-    should be positive, so not being writable, not preserving metadata and
48
-    being disruptive is less restrictive for drivers, which would abort if they
49
-    cannot handle them.
50
-
51
-    Drivers that implement driver-assisted migration should enable the
52
-    configuration flag to be tested.
53
-    """
54
-
55
-    protocol = None
56
-
57
-    @classmethod
58
-    def resource_setup(cls):
59
-        super(MigrationBase, cls).resource_setup()
60
-        if cls.protocol not in CONF.share.enable_protocols:
61
-            message = "%s tests are disabled." % cls.protocol
62
-            raise cls.skipException(message)
63
-        if not (CONF.share.run_host_assisted_migration_tests or
64
-                CONF.share.run_driver_assisted_migration_tests):
65
-            raise cls.skipException("Share migration tests are disabled.")
66
-        cls.pools = cls.shares_v2_client.list_pools(detail=True)['pools']
67
-
68
-        if len(cls.pools) < 2:
69
-            raise cls.skipException("At least two different pool entries are "
70
-                                    "needed to run share migration tests.")
71
-
72
-        cls.new_type = cls.create_share_type(
73
-            name=data_utils.rand_name('new_share_type_for_migration'),
74
-            cleanup_in_class=True,
75
-            extra_specs=utils.get_configured_