Add nodepool integration test
This uses the python unittest framework to run a test similar to
the existing zuul-nodepool unit test, but expecting an actual
running nodepool.
Change-Id: I769e1421c146cc3545dce606487c8c72e3d3a4c5
diff --git a/tests/nodepool/__init__.py b/tests/nodepool/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/nodepool/__init__.py
diff --git a/tests/nodepool/test_nodepool_integration.py b/tests/nodepool/test_nodepool_integration.py
new file mode 100644
index 0000000..95027fe
--- /dev/null
+++ b/tests/nodepool/test_nodepool_integration.py
@@ -0,0 +1,116 @@
+# Copyright 2017 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# 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 time
+from unittest import skip
+
+import zuul.zk
+import zuul.nodepool
+from zuul import model
+
+from tests.base import BaseTestCase
+
+
+class TestNodepoolIntegration(BaseTestCase):
+ # Tests the Nodepool interface class using a *real* nodepool and
+ # fake scheduler.
+
+ def setUp(self):
+ super(BaseTestCase, self).setUp()
+
+ self.zk_config = zuul.zk.ZooKeeperConnectionConfig('localhost')
+ self.zk = zuul.zk.ZooKeeper()
+ self.zk.connect([self.zk_config])
+
+ self.provisioned_requests = []
+ # This class implements the scheduler methods zuul.nodepool
+ # needs, so we pass 'self' as the scheduler.
+ self.nodepool = zuul.nodepool.Nodepool(self)
+
+ def waitForRequests(self):
+ # Wait until all requests are complete.
+ while self.nodepool.requests:
+ time.sleep(0.1)
+
+ def onNodesProvisioned(self, request):
+ # This is a scheduler method that the nodepool class calls
+ # back when a request is provisioned.
+ self.provisioned_requests.append(request)
+
+ def test_node_request(self):
+ # Test a simple node request
+
+ nodeset = model.NodeSet()
+ nodeset.addNode(model.Node('controller', 'fake-label'))
+ nodeset.addNode(model.Node('compute', 'fake-label'))
+ job = model.Job('testjob')
+ job.nodeset = nodeset
+ request = self.nodepool.requestNodes(None, job)
+ self.waitForRequests()
+ self.assertEqual(len(self.provisioned_requests), 1)
+ self.assertEqual(request.state, 'fulfilled')
+
+ # Accept the nodes
+ self.nodepool.acceptNodes(request)
+ nodeset = request.nodeset
+
+ for node in nodeset.getNodes():
+ self.assertIsNotNone(node.lock)
+ self.assertEqual(node.state, 'ready')
+
+ # Mark the nodes in use
+ self.nodepool.useNodeSet(nodeset)
+ for node in nodeset.getNodes():
+ self.assertEqual(node.state, 'in-use')
+
+ # Return the nodes
+ self.nodepool.returnNodeSet(nodeset)
+ for node in nodeset.getNodes():
+ self.assertIsNone(node.lock)
+ self.assertEqual(node.state, 'used')
+
+ @skip("Disabled until nodepool is ready")
+ def test_node_request_disconnect(self):
+ # Test that node requests are re-submitted after disconnect
+
+ nodeset = model.NodeSet()
+ nodeset.addNode(model.Node('controller', 'ubuntu-xenial'))
+ nodeset.addNode(model.Node('compute', 'ubuntu-xenial'))
+ job = model.Job('testjob')
+ job.nodeset = nodeset
+ self.fake_nodepool.paused = True
+ request = self.nodepool.requestNodes(None, job)
+ self.zk.client.stop()
+ self.zk.client.start()
+ self.fake_nodepool.paused = False
+ self.waitForRequests()
+ self.assertEqual(len(self.provisioned_requests), 1)
+ self.assertEqual(request.state, 'fulfilled')
+
+ @skip("Disabled until nodepool is ready")
+ def test_node_request_canceled(self):
+ # Test that node requests can be canceled
+
+ nodeset = model.NodeSet()
+ nodeset.addNode(model.Node('controller', 'ubuntu-xenial'))
+ nodeset.addNode(model.Node('compute', 'ubuntu-xenial'))
+ job = model.Job('testjob')
+ job.nodeset = nodeset
+ self.fake_nodepool.paused = True
+ request = self.nodepool.requestNodes(None, job)
+ self.nodepool.cancelRequest(request)
+
+ self.waitForRequests()
+ self.assertEqual(len(self.provisioned_requests), 0)
diff --git a/tox.ini b/tox.ini
index 9c2daee..b7cbf27 100644
--- a/tox.ini
+++ b/tox.ini
@@ -44,6 +44,11 @@
[testenv:validate-layout]
commands = zuul-server -c etc/zuul.conf-sample -t -l {posargs}
+[testenv:nodepool]
+setenv =
+ OS_TEST_PATH = ./tests/nodepool
+commands = python setup.py testr --slowest --testr-args='--concurrency=1 {posargs}'
+
[flake8]
# These are ignored intentionally in openstack-infra projects;
# please don't submit patches that solely correct them or enable them.