Merge "Move fwaas jobs to the experimental queue"
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000..6fe7c34
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,4 @@
+reno>=3.1.0 # Apache-2.0
+sphinx>=2.0.0,!=2.1.0 # BSD
+openstackdocstheme>=2.2.1 # Apache-2.0
+
diff --git a/neutron_tempest_plugin/api/test_network_ip_availability.py b/neutron_tempest_plugin/api/test_network_ip_availability.py
index e798680..22d2fc6 100644
--- a/neutron_tempest_plugin/api/test_network_ip_availability.py
+++ b/neutron_tempest_plugin/api/test_network_ip_availability.py
@@ -175,3 +175,22 @@
 class NetworksIpAvailabilityIPv6Test(NetworksIpAvailabilityIPv4Test):
 
     _ip_version = lib_constants.IP_VERSION_6
+
+    def setUp(self):
+        super(NetworksIpAvailabilityIPv6Test, self).setUp()
+        net_name = data_utils.rand_name('network')
+        self.network = self.create_network(network_name=net_name)
+
+    @decorators.idempotent_id('0d5a03f2-fdb7-4ec3-b746-734c51d74b69')
+    def test_list_ipv6_ip_availability_after_subnet_and_ports(self):
+        subnet = self.create_subnet(self.network, ip_version=self._ip_version,
+                                    enable_dhcp=False)
+        prefix = netaddr.IPNetwork(subnet['cidr']).prefixlen
+        body = self.admin_client.list_network_ip_availabilities()
+        used_ips_before_port_create = self._get_used_ips(self.network, body)
+        self.create_port(self.network)
+        net_availability = self.admin_client.list_network_ip_availabilities()
+        self._assert_total_and_used_ips(
+            used_ips_before_port_create + 1,
+            calc_total_ips(prefix, self._ip_version),
+            self.network, net_availability)
diff --git a/neutron_tempest_plugin/api/test_qos_negative.py b/neutron_tempest_plugin/api/test_qos_negative.py
index 8432c6a..f6c4afc 100644
--- a/neutron_tempest_plugin/api/test_qos_negative.py
+++ b/neutron_tempest_plugin/api/test_qos_negative.py
@@ -67,6 +67,28 @@
                           self.client.update_qos_policy, policy['id'],
                           description=LONG_DESCRIPTION_NG)
 
+    @decorators.attr(type='negative')
+    @decorators.idempotent_id('88b54ab0-804b-446c-bc19-8e54222d70ef')
+    def test_get_non_existent_qos_policy(self):
+        non_exist_id = data_utils.rand_name('qos_policy')
+        self.assertRaises(lib_exc.NotFound,
+                          self.admin_client.show_qos_policy, non_exist_id)
+
+    @decorators.attr(type='negative')
+    @decorators.idempotent_id('21050859-1284-4bf5-b05a-13846f83988f')
+    def test_update_non_existent_qos_policy(self):
+        non_exist_id = data_utils.rand_name('qos_policy')
+        self.assertRaises(lib_exc.NotFound,
+                          self.admin_client.update_qos_policy, non_exist_id,
+                          shared=False)
+
+    @decorators.attr(type='negative')
+    @decorators.idempotent_id('09e435b7-44d3-4f9d-8aa8-c295d46b5866')
+    def test_delete_non_existent_qos_policy(self):
+        non_exist_id = data_utils.rand_name('qos_policy')
+        self.assertRaises(lib_exc.NotFound,
+                          self.admin_client.delete_qos_policy, non_exist_id)
+
 
 class QosBandwidthLimitRuleNegativeTestJSON(base.BaseAdminNetworkTest):
 
diff --git a/neutron_tempest_plugin/scenario/test_ports.py b/neutron_tempest_plugin/scenario/test_ports.py
index 3b0408a..b3aeb87 100644
--- a/neutron_tempest_plugin/scenario/test_ports.py
+++ b/neutron_tempest_plugin/scenario/test_ports.py
@@ -12,6 +12,9 @@
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #    License for the specific language governing permissions and limitations
 #    under the License.
+import ipaddress
+
+from oslo_log import log as logging
 from tempest.common import waiters
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
@@ -20,6 +23,7 @@
 from neutron_tempest_plugin.scenario import base
 from neutron_tempest_plugin.scenario import constants as const
 
+LOG = logging.getLogger(__name__)
 CONF = config.CONF
 
 
@@ -78,3 +82,34 @@
                 self.os_primary.servers_client,
                 servers[0]['server']['id'])
             self._try_delete_resource(self.delete_floatingip, fips[0])
+
+    @decorators.idempotent_id('62e32802-1d21-11eb-b322-74e5f9e2a801')
+    def test_port_with_fixed_ip(self):
+        """Test scenario:
+
+        1) Get the last IP from the range of Subnet "Allocation pool"
+        2) Create Port with fixed_ip resolved in #1
+        3) Create a VM using updated Port in #2 and add Floating IP
+        4) Check SSH access to VM
+        """
+        ip_range = [str(ip) for ip in ipaddress.IPv4Network(
+            self.subnet['cidr'])]
+        # Because of the tests executed in Parallel the IP may already
+        # be in use, so we'll try using IPs from Allocation pool
+        # (in reverse order) up until Port is successfully created.
+        for ip in reversed(ip_range):
+            try:
+                port = self.create_port(
+                    self.network,
+                    name=data_utils.rand_name("fixed_ip_port"),
+                    security_groups=[self.secgroup['id']],
+                    fixed_ips=[{'ip_address': ip}])
+                if port is not None:
+                    break
+            except Exception as e:
+                LOG.warn('Failed to create Port, using Fixed_IP:{}, '
+                         'the Error was:{}'.format(ip, e))
+        fip, server = self._create_instance_with_port(port)
+        self.check_connectivity(fip[0]['floating_ip_address'],
+                                CONF.validation.image_ssh_user,
+                                self.keypair['private_key'])
diff --git a/test-requirements.txt b/test-requirements.txt
index bf1c626..f5bac7c 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -7,10 +7,6 @@
 coverage!=4.4,>=4.0 # Apache-2.0
 flake8-import-order==0.12 # LGPLv3
 python-subunit>=1.0.0 # Apache-2.0/BSD
-sphinx>=2.0.0,!=2.1.0 # BSD
 oslotest>=3.2.0 # Apache-2.0
 stestr>=1.0.0 # Apache-2.0
 testtools>=2.2.0 # MIT
-openstackdocstheme>=2.2.1 # Apache-2.0
-# releasenotes
-reno>=3.1.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index 3c18fbf..d3e722a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -39,9 +39,12 @@
     coverage xml -o cover/coverage.xml
 
 [testenv:docs]
+deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
+       -r{toxinidir}/doc/requirements.txt
 commands = sphinx-build -W -b html doc/source doc/build/html
 
 [testenv:releasenotes]
+deps = {[testenv:docs]deps}
 commands =
   sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html