blob: dd0050f899e89ea24dbad4af5844e34ea0a9454c [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
James E. Blairf88b8172017-01-24 13:37:21 -080033 self.zk = zuul.zk.ZooKeeper()
Paul Belanger9790c6a2017-03-20 16:48:11 -040034 self.zk.connect('localhost:2181')
James E. Blairf88b8172017-01-24 13:37:21 -080035
36 self.provisioned_requests = []
37 # This class implements the scheduler methods zuul.nodepool
38 # needs, so we pass 'self' as the scheduler.
39 self.nodepool = zuul.nodepool.Nodepool(self)
40
41 def waitForRequests(self):
42 # Wait until all requests are complete.
43 while self.nodepool.requests:
44 time.sleep(0.1)
45
46 def onNodesProvisioned(self, request):
47 # This is a scheduler method that the nodepool class calls
48 # back when a request is provisioned.
49 self.provisioned_requests.append(request)
50
51 def test_node_request(self):
52 # Test a simple node request
53
54 nodeset = model.NodeSet()
David Shrewsbury349b23b2017-02-09 14:12:41 -050055 nodeset.addNode(model.Node('controller', 'fake-label'))
James E. Blairf88b8172017-01-24 13:37:21 -080056 job = model.Job('testjob')
57 job.nodeset = nodeset
58 request = self.nodepool.requestNodes(None, job)
59 self.waitForRequests()
60 self.assertEqual(len(self.provisioned_requests), 1)
David Shrewsburye054b902017-01-26 08:22:25 -050061 self.assertEqual(request.state, model.STATE_FULFILLED)
James E. Blairf88b8172017-01-24 13:37:21 -080062
63 # Accept the nodes
64 self.nodepool.acceptNodes(request)
65 nodeset = request.nodeset
66
67 for node in nodeset.getNodes():
68 self.assertIsNotNone(node.lock)
David Shrewsburye054b902017-01-26 08:22:25 -050069 self.assertEqual(node.state, model.STATE_READY)
James E. Blairf88b8172017-01-24 13:37:21 -080070
71 # Mark the nodes in use
72 self.nodepool.useNodeSet(nodeset)
73 for node in nodeset.getNodes():
David Shrewsburye054b902017-01-26 08:22:25 -050074 self.assertEqual(node.state, model.STATE_IN_USE)
James E. Blairf88b8172017-01-24 13:37:21 -080075
76 # Return the nodes
77 self.nodepool.returnNodeSet(nodeset)
78 for node in nodeset.getNodes():
79 self.assertIsNone(node.lock)
David Shrewsburye054b902017-01-26 08:22:25 -050080 self.assertEqual(node.state, model.STATE_USED)
81
82 def test_invalid_node_request(self):
83 # Test requests with an invalid node type fail
84 nodeset = model.NodeSet()
85 nodeset.addNode(model.Node('controller', 'invalid-label'))
86 job = model.Job('testjob')
87 job.nodeset = nodeset
88 request = self.nodepool.requestNodes(None, job)
89 self.waitForRequests()
90 self.assertEqual(len(self.provisioned_requests), 1)
91 self.assertEqual(request.state, model.STATE_FAILED)
James E. Blairf88b8172017-01-24 13:37:21 -080092
93 @skip("Disabled until nodepool is ready")
94 def test_node_request_disconnect(self):
95 # Test that node requests are re-submitted after disconnect
96
97 nodeset = model.NodeSet()
98 nodeset.addNode(model.Node('controller', 'ubuntu-xenial'))
99 nodeset.addNode(model.Node('compute', 'ubuntu-xenial'))
100 job = model.Job('testjob')
101 job.nodeset = nodeset
102 self.fake_nodepool.paused = True
103 request = self.nodepool.requestNodes(None, job)
104 self.zk.client.stop()
105 self.zk.client.start()
106 self.fake_nodepool.paused = False
107 self.waitForRequests()
108 self.assertEqual(len(self.provisioned_requests), 1)
David Shrewsburye054b902017-01-26 08:22:25 -0500109 self.assertEqual(request.state, model.STATE_FULFILLED)
James E. Blairf88b8172017-01-24 13:37:21 -0800110
111 @skip("Disabled until nodepool is ready")
112 def test_node_request_canceled(self):
113 # Test that node requests can be canceled
114
115 nodeset = model.NodeSet()
116 nodeset.addNode(model.Node('controller', 'ubuntu-xenial'))
117 nodeset.addNode(model.Node('compute', 'ubuntu-xenial'))
118 job = model.Job('testjob')
119 job.nodeset = nodeset
120 self.fake_nodepool.paused = True
121 request = self.nodepool.requestNodes(None, job)
122 self.nodepool.cancelRequest(request)
123
124 self.waitForRequests()
125 self.assertEqual(len(self.provisioned_requests), 0)