blob: 881aae784dec4a098e1bbcbc7096212ff7906066 [file] [log] [blame]
James E. Blairf88b8172017-01-24 13:37:21 -08001# Copyright 2017 Red Hat, Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15
16import time
17from unittest import skip
18
19import zuul.zk
20import zuul.nodepool
21from zuul import model
22
23from tests.base import BaseTestCase
24
25
26class TestNodepoolIntegration(BaseTestCase):
27 # Tests the Nodepool interface class using a *real* nodepool and
28 # fake scheduler.
29
30 def setUp(self):
31 super(BaseTestCase, self).setUp()
32
33 self.zk_config = zuul.zk.ZooKeeperConnectionConfig('localhost')
34 self.zk = zuul.zk.ZooKeeper()
35 self.zk.connect([self.zk_config])
36
37 self.provisioned_requests = []
38 # This class implements the scheduler methods zuul.nodepool
39 # needs, so we pass 'self' as the scheduler.
40 self.nodepool = zuul.nodepool.Nodepool(self)
41
42 def waitForRequests(self):
43 # Wait until all requests are complete.
44 while self.nodepool.requests:
45 time.sleep(0.1)
46
47 def onNodesProvisioned(self, request):
48 # This is a scheduler method that the nodepool class calls
49 # back when a request is provisioned.
50 self.provisioned_requests.append(request)
51
52 def test_node_request(self):
53 # Test a simple node request
54
55 nodeset = model.NodeSet()
56 nodeset.addNode(model.Node('controller', 'fake-label'))
57 nodeset.addNode(model.Node('compute', 'fake-label'))
58 job = model.Job('testjob')
59 job.nodeset = nodeset
60 request = self.nodepool.requestNodes(None, job)
61 self.waitForRequests()
62 self.assertEqual(len(self.provisioned_requests), 1)
David Shrewsburye054b902017-01-26 08:22:25 -050063 self.assertEqual(request.state, model.STATE_FULFILLED)
James E. Blairf88b8172017-01-24 13:37:21 -080064
65 # Accept the nodes
66 self.nodepool.acceptNodes(request)
67 nodeset = request.nodeset
68
69 for node in nodeset.getNodes():
70 self.assertIsNotNone(node.lock)
David Shrewsburye054b902017-01-26 08:22:25 -050071 self.assertEqual(node.state, model.STATE_READY)
James E. Blairf88b8172017-01-24 13:37:21 -080072
73 # Mark the nodes in use
74 self.nodepool.useNodeSet(nodeset)
75 for node in nodeset.getNodes():
David Shrewsburye054b902017-01-26 08:22:25 -050076 self.assertEqual(node.state, model.STATE_IN_USE)
James E. Blairf88b8172017-01-24 13:37:21 -080077
78 # Return the nodes
79 self.nodepool.returnNodeSet(nodeset)
80 for node in nodeset.getNodes():
81 self.assertIsNone(node.lock)
David Shrewsburye054b902017-01-26 08:22:25 -050082 self.assertEqual(node.state, model.STATE_USED)
83
84 def test_invalid_node_request(self):
85 # Test requests with an invalid node type fail
86 nodeset = model.NodeSet()
87 nodeset.addNode(model.Node('controller', 'invalid-label'))
88 job = model.Job('testjob')
89 job.nodeset = nodeset
90 request = self.nodepool.requestNodes(None, job)
91 self.waitForRequests()
92 self.assertEqual(len(self.provisioned_requests), 1)
93 self.assertEqual(request.state, model.STATE_FAILED)
James E. Blairf88b8172017-01-24 13:37:21 -080094
95 @skip("Disabled until nodepool is ready")
96 def test_node_request_disconnect(self):
97 # Test that node requests are re-submitted after disconnect
98
99 nodeset = model.NodeSet()
100 nodeset.addNode(model.Node('controller', 'ubuntu-xenial'))
101 nodeset.addNode(model.Node('compute', 'ubuntu-xenial'))
102 job = model.Job('testjob')
103 job.nodeset = nodeset
104 self.fake_nodepool.paused = True
105 request = self.nodepool.requestNodes(None, job)
106 self.zk.client.stop()
107 self.zk.client.start()
108 self.fake_nodepool.paused = False
109 self.waitForRequests()
110 self.assertEqual(len(self.provisioned_requests), 1)
David Shrewsburye054b902017-01-26 08:22:25 -0500111 self.assertEqual(request.state, model.STATE_FULFILLED)
James E. Blairf88b8172017-01-24 13:37:21 -0800112
113 @skip("Disabled until nodepool is ready")
114 def test_node_request_canceled(self):
115 # Test that node requests can be canceled
116
117 nodeset = model.NodeSet()
118 nodeset.addNode(model.Node('controller', 'ubuntu-xenial'))
119 nodeset.addNode(model.Node('compute', 'ubuntu-xenial'))
120 job = model.Job('testjob')
121 job.nodeset = nodeset
122 self.fake_nodepool.paused = True
123 request = self.nodepool.requestNodes(None, job)
124 self.nodepool.cancelRequest(request)
125
126 self.waitForRequests()
127 self.assertEqual(len(self.provisioned_requests), 0)