diff --git a/tests/nodepool/__init__.py b/tests/nodepool/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/nodepool/test_nodepool_integration.py b/tests/nodepool/test_nodepool_integration.py new file mode 100644 index 0000000000..95027feb72 --- /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 9c2daee4af..b7cbf27204 100644 --- a/tox.ini +++ b/tox.ini @@ -44,6 +44,11 @@ commands = {posargs} [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.