Preserve the items order when calling ddt.data()

Several calls to ddt.data() change the lists of items into a set
to de-duplicate them. This happens, for example, when the list
constains microversions which may come from some variable.

In order to generate a consistent and predictable list of tests,
which can be compared over time (as ddt adds the index of the
test to the test name), replace the usage of set with
a new function which removes the duplicates but keeps the order.

Change-Id: I9cbd26016238c25487ac8104c1188cd2cf4f467e
diff --git a/manila_tempest_tests/tests/api/admin/test_replication.py b/manila_tempest_tests/tests/api/admin/test_replication.py
index a7bbad2..c435da1 100644
--- a/manila_tempest_tests/tests/api/admin/test_replication.py
+++ b/manila_tempest_tests/tests/api/admin/test_replication.py
@@ -84,9 +84,9 @@
     @decorators.idempotent_id('0213cdfd-6a0f-4f24-a154-69796888a64a')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_REPLICATION_VERSION,
-              constants.SHARE_REPLICA_GRADUATION_VERSION,
-              LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_REPLICATION_VERSION,
+                            constants.SHARE_REPLICA_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_promote_out_of_sync_share_replica(self, version):
         """Test promote 'out_of_sync' share replica to active state."""
         self.skip_if_microversion_not_supported(version)
@@ -145,9 +145,9 @@
     @decorators.idempotent_id('22a199b7-f4f6-4ede-b09f-8047a9d01cad')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_REPLICATION_VERSION,
-              constants.SHARE_REPLICA_GRADUATION_VERSION,
-              LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_REPLICATION_VERSION,
+                            constants.SHARE_REPLICA_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_force_delete_share_replica(self, version):
         """Test force deleting a replica that is in 'error_deleting' status."""
         self.skip_if_microversion_not_supported(version)
@@ -167,9 +167,9 @@
     @decorators.idempotent_id('16bd90f0-c478-4a99-8633-b18703ff56fa')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_REPLICATION_VERSION,
-              constants.SHARE_REPLICA_GRADUATION_VERSION,
-              LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_REPLICATION_VERSION,
+                            constants.SHARE_REPLICA_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_reset_share_replica_status(self, version):
         """Test resetting a replica's 'status' attribute."""
         self.skip_if_microversion_not_supported(version)
@@ -187,9 +187,9 @@
     @decorators.idempotent_id('258844da-a853-42b6-87db-b16e616018c6')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_REPLICATION_VERSION,
-              constants.SHARE_REPLICA_GRADUATION_VERSION,
-              LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_REPLICATION_VERSION,
+                            constants.SHARE_REPLICA_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_reset_share_replica_state(self, version):
         """Test resetting a replica's 'replica_state' attribute."""
         self.skip_if_microversion_not_supported(version)
@@ -207,9 +207,9 @@
     @decorators.idempotent_id('2969565a-85e8-4c61-9dfb-cc7f7ca9f6dd')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_REPLICATION_VERSION,
-              constants.SHARE_REPLICA_GRADUATION_VERSION,
-              LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_REPLICATION_VERSION,
+                            constants.SHARE_REPLICA_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_resync_share_replica(self, version):
         """Test resyncing a replica."""
         self.skip_if_microversion_not_supported(version)
diff --git a/manila_tempest_tests/tests/api/admin/test_share_group_types.py b/manila_tempest_tests/tests/api/admin/test_share_group_types.py
index 3666079..eb62838 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_group_types.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_group_types.py
@@ -147,8 +147,9 @@
     @decorators.idempotent_id('15b44580-a34d-4e0d-a77b-0e76b45d6199')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_update_single_share_group_type_spec(self, version):
         self.skip_if_microversion_not_supported(version)
         name = data_utils.rand_name("tempest-manila")
@@ -202,8 +203,9 @@
     @decorators.idempotent_id('efddee69-ca23-4681-8247-94ded81c4c3a')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_delete_single_share_group_type_spec_min(self, version):
         self.skip_if_microversion_not_supported(version)
         name = data_utils.rand_name("tempest-manila")
@@ -231,8 +233,9 @@
     @decorators.idempotent_id('c2d34b42-e3ec-404e-8b7a-0fe9b1560507')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_private_share_group_type_access(self, version):
         self.skip_if_microversion_not_supported(version)
         name = data_utils.rand_name("tempest-manila")
@@ -291,7 +294,7 @@
 
     @decorators.idempotent_id('b8b20a96-cecc-4677-8a77-aae3b93e5b96')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
-    @ddt.data(*set(('2.45', '2.46', LATEST_MICROVERSION)))
+    @ddt.data(*utils.deduplicate(('2.45', '2.46', LATEST_MICROVERSION)))
     def test_share_group_type_create_show_list_with_is_default_key(self,
                                                                    version):
         self.skip_if_microversion_not_supported(version)
diff --git a/manila_tempest_tests/tests/api/admin/test_share_groups.py b/manila_tempest_tests/tests/api/admin/test_share_groups.py
index e88d5ce..207db8c 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_groups.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_groups.py
@@ -63,8 +63,9 @@
     @decorators.idempotent_id('79eaa86f-4c8f-49fd-acb2-ec051aa6bf93')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_create_share_group_with_single_share_type_min(self, version):
         self.skip_if_microversion_not_supported(version)
         share_group = self.create_share_group(
@@ -137,8 +138,9 @@
         CONF.share.default_share_type_name, "Only if defaults are defined.")
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_default_share_group_type_applied(self, version):
         self.skip_if_microversion_not_supported(version)
         try:
diff --git a/manila_tempest_tests/tests/api/admin/test_share_types.py b/manila_tempest_tests/tests/api/admin/test_share_types.py
index 370e014..cb97bc5 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_types.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_types.py
@@ -296,7 +296,7 @@
 
     @decorators.idempotent_id('90dca5c5-f28e-4f16-90ed-78f5d725664e')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
-    @ddt.data(*set(('2.45', '2.46', LATEST_MICROVERSION)))
+    @ddt.data(*utils.deduplicate(('2.45', '2.46', LATEST_MICROVERSION)))
     def test_share_type_create_show_list_with_is_default_key(self, version):
         self.skip_if_microversion_not_supported(version)
         name = data_utils.rand_name("tempest-manila")
diff --git a/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs.py b/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs.py
index 1855713..ec65ab9 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs.py
@@ -22,6 +22,7 @@
 from testtools import testcase as tc
 
 from manila_tempest_tests.tests.api import base
+from manila_tempest_tests import utils
 
 
 CONF = config.CONF
@@ -125,7 +126,7 @@
 
     @decorators.idempotent_id('1b9f501d-8f34-46d0-b318-83bdfed571ec')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
-    @ddt.data(*set(['2.24', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['2.24', LATEST_MICROVERSION]))
     def test_delete_snapshot_support_extra_spec(self, version):
         self.skip_if_microversion_not_supported(version)
         # Delete one extra spec for share type
diff --git a/manila_tempest_tests/tests/api/test_replication_export_locations.py b/manila_tempest_tests/tests/api/test_replication_export_locations.py
index 55ea475..c9857e6 100644
--- a/manila_tempest_tests/tests/api/test_replication_export_locations.py
+++ b/manila_tempest_tests/tests/api/test_replication_export_locations.py
@@ -121,7 +121,7 @@
 
     @decorators.idempotent_id('da22cfb8-7dd8-4bf1-87fc-a1f7b51ebf8e')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
-    @ddt.data(*set(['2.46', '2.47', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['2.46', '2.47', LATEST_MICROVERSION]))
     def test_replicated_share_export_locations(self, version):
         """Test behavior changes in the share export locations API at 2.47"""
         self.skip_if_microversion_not_supported(version)
@@ -139,7 +139,7 @@
 
     @decorators.idempotent_id('58430f57-c6eb-44e2-9583-eecb1dd10594')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
-    @ddt.data(*set(['2.46', '2.47', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['2.46', '2.47', LATEST_MICROVERSION]))
     @testtools.skipUnless(
         CONF.share.backend_replication_type in
         (constants.REPLICATION_STYLE_READABLE, constants.REPLICATION_STYLE_DR),
diff --git a/manila_tempest_tests/tests/api/test_rules.py b/manila_tempest_tests/tests/api/test_rules.py
index 71bdd06..2a2420a 100644
--- a/manila_tempest_tests/tests/api/test_rules.py
+++ b/manila_tempest_tests/tests/api/test_rules.py
@@ -216,7 +216,8 @@
     @testtools.skipIf(
         "nfs" not in CONF.share.enable_ro_access_level_for_protocols,
         "RO access rule tests are disabled for NFS protocol.")
-    @ddt.data(*set(['1.0', '2.9', '2.27', '2.28', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['1.0', '2.9', '2.27', '2.28',
+                                 LATEST_MICROVERSION]))
     def test_create_delete_ro_access_rule(self, client_name):
         _create_delete_ro_access_rule(self, client_name)
 
@@ -230,7 +231,8 @@
     @testtools.skipIf(
         "cifs" not in CONF.share.enable_ro_access_level_for_protocols,
         "RO access rule tests are disabled for CIFS protocol.")
-    @ddt.data(*set(['1.0', '2.9', '2.27', '2.28', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['1.0', '2.9', '2.27', '2.28',
+                                 LATEST_MICROVERSION]))
     def test_create_delete_ro_access_rule(self, version):
         _create_delete_ro_access_rule(self, version)
 
@@ -265,7 +267,8 @@
 
     @decorators.idempotent_id('1f87565f-c3d9-448d-b89a-387d6c2fdae6')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
-    @ddt.data(*set(['1.0', '2.9', '2.27', '2.28', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['1.0', '2.9', '2.27', '2.28',
+                                 LATEST_MICROVERSION]))
     def test_create_delete_user_rule(self, version):
 
         # create rule
@@ -314,7 +317,8 @@
     @testtools.skipIf(
         "nfs" not in CONF.share.enable_ro_access_level_for_protocols,
         "RO access rule tests are disabled for NFS protocol.")
-    @ddt.data(*set(['1.0', '2.9', '2.27', '2.28', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['1.0', '2.9', '2.27', '2.28',
+                                 LATEST_MICROVERSION]))
     def test_create_delete_ro_access_rule(self, version):
         _create_delete_ro_access_rule(self, version)
 
@@ -328,7 +332,8 @@
     @testtools.skipIf(
         "cifs" not in CONF.share.enable_ro_access_level_for_protocols,
         "RO access rule tests are disabled for CIFS protocol.")
-    @ddt.data(*set(['1.0', '2.9', '2.27', '2.28', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['1.0', '2.9', '2.27', '2.28',
+                                 LATEST_MICROVERSION]))
     def test_create_delete_ro_access_rule(self, version):
         _create_delete_ro_access_rule(self, version)
 
@@ -364,7 +369,8 @@
 
     @decorators.idempotent_id('775ebc55-4a4d-4012-a030-2eeb7b6d2ce8')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
-    @ddt.data(*set(['1.0', '2.9', '2.27', '2.28', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['1.0', '2.9', '2.27', '2.28',
+                                 LATEST_MICROVERSION]))
     def test_create_delete_cert_rule(self, version):
 
         # create rule
@@ -413,7 +419,8 @@
     @testtools.skipIf(
         "glusterfs" not in CONF.share.enable_ro_access_level_for_protocols,
         "RO access rule tests are disabled for GLUSTERFS protocol.")
-    @ddt.data(*set(['1.0', '2.9', '2.27', '2.28', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['1.0', '2.9', '2.27', '2.28',
+                                 LATEST_MICROVERSION]))
     def test_create_delete_cert_ro_access_rule(self, version):
         if utils.is_microversion_eq(version, '1.0'):
             rule = self.shares_client.create_access_rule(
@@ -570,7 +577,7 @@
 
     @decorators.idempotent_id('c52e95cc-d6ea-4d02-9b52-cd7c1913dfff')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
-    @ddt.data(*set(
+    @ddt.data(*utils.deduplicate(
         ['1.0', '2.9', '2.27', '2.28', '2.45', LATEST_MICROVERSION]))
     def test_list_access_rules(self, version):
         self.skip_if_microversion_not_supported(version)
@@ -664,7 +671,8 @@
 
     @decorators.idempotent_id('b77bcbda-9754-48f0-9be6-79341ad1af64')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
-    @ddt.data(*set(['1.0', '2.9', '2.27', '2.28', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['1.0', '2.9', '2.27', '2.28',
+                                 LATEST_MICROVERSION]))
     def test_access_rules_deleted_if_share_deleted(self, version):
         if (utils.is_microversion_lt(version, '2.13') and
                 CONF.share.enable_cephx_rules_for_protocols):
diff --git a/manila_tempest_tests/tests/api/test_security_services.py b/manila_tempest_tests/tests/api/test_security_services.py
index b300973..81645b5 100644
--- a/manila_tempest_tests/tests/api/test_security_services.py
+++ b/manila_tempest_tests/tests/api/test_security_services.py
@@ -46,7 +46,7 @@
 
     @decorators.idempotent_id('22b22937-7436-458c-ac22-8ff19feab253')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
-    @ddt.data(*set(['1.0', '2.42', '2.44', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['1.0', '2.42', '2.44', LATEST_MICROVERSION]))
     def test_list_security_services_with_detail(self, version):
         self.skip_if_microversion_not_supported(version)
         with_ou = True if utils.is_microversion_ge(version, '2.44') else False
@@ -169,7 +169,7 @@
 
     @decorators.idempotent_id('bb052be4-0176-4613-b7d5-e12bef391ddb')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
-    @ddt.data(*set(['1.0', '2.43', '2.44', LATEST_MICROVERSION]))
+    @ddt.data(*utils.deduplicate(['1.0', '2.43', '2.44', LATEST_MICROVERSION]))
     def test_get_security_service(self, version):
         self.skip_if_microversion_not_supported(version)
         with_ou = True if utils.is_microversion_ge(version, '2.44') else False
diff --git a/manila_tempest_tests/tests/api/test_share_group_actions.py b/manila_tempest_tests/tests/api/test_share_group_actions.py
index 3b2325a..b52d7f6 100644
--- a/manila_tempest_tests/tests/api/test_share_group_actions.py
+++ b/manila_tempest_tests/tests/api/test_share_group_actions.py
@@ -107,8 +107,9 @@
     @decorators.idempotent_id('1e359389-09a7-4235-84c9-7b5c83632fff')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_get_share_group(self, version):
         self.skip_if_microversion_not_supported(version)
 
@@ -161,8 +162,9 @@
     @decorators.idempotent_id('04fcd695-c5f8-4de7-ab09-131424e6bdfb')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_list_share_groups(self, version):
         self.skip_if_microversion_not_supported(version)
 
@@ -192,8 +194,9 @@
     @decorators.idempotent_id('16986c21-ecbc-429e-ab3d-8d1596a3eac4')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION, '2.36',
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION, '2.36',
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_list_share_groups_with_detail_min(self, version):
         self.skip_if_microversion_not_supported(version)
         params = None
@@ -252,8 +255,9 @@
     @decorators.idempotent_id('5d2ca4f5-04da-4528-af47-ec980b95e884')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_get_share_group_snapshot(self, version):
         self.skip_if_microversion_not_supported(version)
 
@@ -308,8 +312,9 @@
     @decorators.idempotent_id('650c5fa7-11f2-48bd-b012-fc2e32b6f446')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_create_share_group_from_populated_share_group_snapshot(self,
                                                                     version):
         self.skip_if_microversion_not_supported(version)
@@ -413,8 +418,9 @@
     @decorators.idempotent_id('7f0a07ce-afdd-4c51-a29c-d8fe6cb5f6a5')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_update_share_group(self, version):
         self.skip_if_microversion_not_supported(version)
 
@@ -453,8 +459,9 @@
     @decorators.idempotent_id('611b1555-df09-499b-8aef-e8261e3f6863')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @ddt.data(
-        *set([constants.MIN_SHARE_GROUP_MICROVERSION,
-              constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION]))
+        *utils.deduplicate([constants.MIN_SHARE_GROUP_MICROVERSION,
+                            constants.SHARE_GROUPS_GRADUATION_VERSION,
+                            LATEST_MICROVERSION]))
     def test_create_update_read_share_group_with_unicode(self, version):
         self.skip_if_microversion_not_supported(version)
 
diff --git a/manila_tempest_tests/utils.py b/manila_tempest_tests/utils.py
index f30c0fc..650614d 100644
--- a/manila_tempest_tests/utils.py
+++ b/manila_tempest_tests/utils.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from collections import OrderedDict
 import random
 import re
 
@@ -27,6 +28,15 @@
 EXPERIMENTAL = {'X-OpenStack-Manila-API-Experimental': 'True'}
 
 
+def deduplicate(items):
+    """De-duplicate a list of items while preserving the order.
+
+    It is useful when passing a list of items to ddt.data, in order
+    to remove duplicated elements which may be specified as constants.
+    """
+    return list(OrderedDict.fromkeys(items))
+
+
 def get_microversion_as_tuple(microversion_str):
     """Transforms string-like microversion to two-value tuple of integers.