Merge "qos: require min_kbps parameter for minimum bandwidth rule"
diff --git a/neutron/tests/tempest/api/test_revisions.py b/neutron/tests/tempest/api/test_revisions.py
index 92f7866..4284649 100644
--- a/neutron/tests/tempest/api/test_revisions.py
+++ b/neutron/tests/tempest/api/test_revisions.py
@@ -55,6 +55,17 @@
         updated = self.admin_client.update_subnetpool(sp['id'], name='sp2')
         self.assertGreater(updated['subnetpool']['revision'], sp['revision'])
 
+    @test.idempotent_id('e8c5d7db-2b8d-4567-a326-6e123437c4d1')
+    def test_update_subnet_bumps_network_revision(self):
+        net = self.create_network()
+        subnet = self.create_subnet(net)
+        updated = self.client.show_network(net['id'])
+        self.assertGreater(updated['network']['revision'], net['revision'])
+        self.client.delete_subnet(subnet['id'])
+        updated2 = self.client.show_network(net['id'])
+        self.assertGreater(updated2['network']['revision'],
+                           updated['network']['revision'])
+
     @test.idempotent_id('6c256f71-c929-4200-b3dc-4e1843506be5')
     @test.requires_ext(extension="security-group", service="network")
     def test_update_sg_group_bumps_revision(self):
diff --git a/neutron/tests/tempest/api/test_trunk.py b/neutron/tests/tempest/api/test_trunk.py
index c22c334..44adb7e 100644
--- a/neutron/tests/tempest/api/test_trunk.py
+++ b/neutron/tests/tempest/api/test_trunk.py
@@ -58,46 +58,69 @@
         trunks_cleanup(cls.client, cls.trunks)
         super(TrunkTestJSONBase, cls).resource_cleanup()
 
+    def _remove_timestamps(self, trunk):
+        # Let's make sure these fields exist, but let's not
+        # use them in the comparison, in case skews or
+        # roundups get in the way.
+        created_at = trunk.pop('created_at')
+        updated_at = trunk.pop('updated_at')
+        self.assertIsNotNone(created_at)
+        self.assertIsNotNone(updated_at)
+
     def _create_trunk_with_network_and_parent(self, subports, **kwargs):
         network = self.create_network()
         parent_port = self.create_port(network)
         trunk = self.client.create_trunk(parent_port['id'], subports, **kwargs)
         self.trunks.append(trunk['trunk'])
+        self._remove_timestamps(trunk['trunk'])
         return trunk
 
+    def _show_trunk(self, trunk_id):
+        trunk = self.client.show_trunk(trunk_id)
+        self._remove_timestamps(trunk['trunk'])
+        return trunk
+
+    def _list_trunks(self):
+        trunks = self.client.list_trunks()
+        for t in trunks['trunks']:
+            self._remove_timestamps(t)
+        return trunks
+
 
 class TrunkTestJSON(TrunkTestJSONBase):
 
+    def _test_create_trunk(self, subports):
+        trunk = self._create_trunk_with_network_and_parent(subports)
+        observed_trunk = self._show_trunk(trunk['trunk']['id'])
+        self.assertEqual(trunk, observed_trunk)
+
     @test.idempotent_id('e1a6355c-4768-41f3-9bf8-0f1d192bd501')
     def test_create_trunk_empty_subports_list(self):
-        trunk = self._create_trunk_with_network_and_parent([])
-        observed_trunk = self.client.show_trunk(trunk['trunk']['id'])
-        self.assertEqual(trunk, observed_trunk)
+        self._test_create_trunk([])
 
     @test.idempotent_id('382dfa39-ca03-4bd3-9a1c-91e36d2e3796')
     def test_create_trunk_subports_not_specified(self):
-        trunk = self._create_trunk_with_network_and_parent(None)
-        observed_trunk = self.client.show_trunk(trunk['trunk']['id'])
-        self.assertEqual(trunk, observed_trunk)
+        self._test_create_trunk(None)
 
     @test.idempotent_id('7de46c22-e2b6-4959-ac5a-0e624632ab32')
     def test_create_show_delete_trunk(self):
         trunk = self._create_trunk_with_network_and_parent(None)
         trunk_id = trunk['trunk']['id']
         parent_port_id = trunk['trunk']['port_id']
-        res = self.client.show_trunk(trunk_id)
+        res = self._show_trunk(trunk_id)
         self.assertEqual(trunk_id, res['trunk']['id'])
         self.assertEqual(parent_port_id, res['trunk']['port_id'])
         self.client.delete_trunk(trunk_id)
-        self.assertRaises(lib_exc.NotFound, self.client.show_trunk, trunk_id)
+        self.assertRaises(lib_exc.NotFound, self._show_trunk, trunk_id)
 
     @test.idempotent_id('4ce46c22-a2b6-4659-bc5a-0ef2463cab32')
     def test_create_update_trunk(self):
         trunk = self._create_trunk_with_network_and_parent(None)
         trunk_id = trunk['trunk']['id']
-        res = self.client.show_trunk(trunk_id)
+        res = self._show_trunk(trunk_id)
         self.assertTrue(res['trunk']['admin_state_up'])
         self.assertEqual("", res['trunk']['name'])
+        self.assertEqual("", res['trunk']['description'])
         res = self.client.update_trunk(
             trunk_id, name='foo', admin_state_up=False)
         self.assertFalse(res['trunk']['admin_state_up'])
@@ -105,13 +128,22 @@
         # enable the trunk so that it can be managed
         self.client.update_trunk(trunk_id, admin_state_up=True)
 
+    @test.idempotent_id('5ff46c22-a2b6-5559-bc5a-0ef2463cab32')
+    def test_create_update_trunk_with_description(self):
+        trunk = self._create_trunk_with_network_and_parent(
+            None, description="foo description")
+        trunk_id = trunk['trunk']['id']
+        self.assertEqual("foo description", trunk['trunk']['description'])
+        trunk = self.client.update_trunk(trunk_id, description='')
+        self.assertEqual('', trunk['trunk']['description'])
+
     @test.idempotent_id('73365f73-bed6-42cd-960b-ec04e0c99d85')
     def test_list_trunks(self):
         trunk1 = self._create_trunk_with_network_and_parent(None)
         trunk2 = self._create_trunk_with_network_and_parent(None)
         expected_trunks = {trunk1['trunk']['id']: trunk1['trunk'],
                            trunk2['trunk']['id']: trunk2['trunk']}
-        trunk_list = self.client.list_trunks()['trunks']
+        trunk_list = self._list_trunks()['trunks']
         matched_trunks = [x for x in trunk_list if x['id'] in expected_trunks]
         self.assertEqual(2, len(matched_trunks))
         for trunk in matched_trunks:
@@ -126,7 +158,7 @@
                      'segmentation_type': 'vlan',
                      'segmentation_id': 2}]
         self.client.add_subports(trunk['trunk']['id'], subports)
-        trunk = self.client.show_trunk(trunk['trunk']['id'])
+        trunk = self._show_trunk(trunk['trunk']['id'])
         observed_subports = trunk['trunk']['sub_ports']
         self.assertEqual(1, len(observed_subports))
         created_subport = observed_subports[0]
@@ -168,7 +200,7 @@
         self.assertEqual(expected_subport, res['sub_ports'][0])
 
         # Validate the results of a subport list
-        trunk = self.client.show_trunk(trunk['trunk']['id'])
+        trunk = self._show_trunk(trunk['trunk']['id'])
         observed_subports = trunk['trunk']['sub_ports']
         self.assertEqual(1, len(observed_subports))
         self.assertEqual(expected_subport, observed_subports[0])
diff --git a/neutron/tests/tempest/services/network/json/network_client.py b/neutron/tests/tempest/services/network/json/network_client.py
index 1105c4e..d788687 100644
--- a/neutron/tests/tempest/services/network/json/network_client.py
+++ b/neutron/tests/tempest/services/network/json/network_client.py
@@ -708,7 +708,8 @@
         return service_client.ResponseBody(resp, body)
 
     def create_trunk(self, parent_port_id, subports,
-                     tenant_id=None, name=None, admin_state_up=None):
+                     tenant_id=None, name=None, admin_state_up=None,
+                     description=None):
         uri = '%s/trunks' % self.uri_prefix
         post_data = {
             'trunk': {
@@ -721,6 +722,8 @@
             post_data['trunk']['tenant_id'] = tenant_id
         if name is not None:
             post_data['trunk']['name'] = name
+        if description is not None:
+            post_data['trunk']['description'] = description
         if admin_state_up is not None:
             post_data['trunk']['admin_state_up'] = admin_state_up
         resp, body = self.post(uri, self.serialize(post_data))