blob: 0a55f9f81893cfe6dea058f3ff4b658e93d823f7 [file] [log] [blame]
James E. Blair15d91cc2017-01-18 09:05:17 -08001# Copyright 2017 Red Hat, Inc.
James E. Blair3897a132016-12-22 18:23:42 -08002#
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
17
18import zuul.zk
19import zuul.nodepool
20from zuul import model
21
22from tests.base import BaseTestCase, ChrootedKazooFixture, FakeNodepool
23
24
25class TestNodepool(BaseTestCase):
26 # Tests the Nodepool interface class using a fake nodepool and
27 # scheduler.
28
29 def setUp(self):
30 super(BaseTestCase, self).setUp()
31
32 self.zk_chroot_fixture = self.useFixture(ChrootedKazooFixture())
James E. Blair0d5a36e2017-02-21 10:53:44 -050033 self.zk_config = '%s:%s%s' % (
James E. Blair3897a132016-12-22 18:23:42 -080034 self.zk_chroot_fixture.zookeeper_host,
35 self.zk_chroot_fixture.zookeeper_port,
36 self.zk_chroot_fixture.zookeeper_chroot)
37
38 self.zk = zuul.zk.ZooKeeper()
James E. Blair0d5a36e2017-02-21 10:53:44 -050039 self.zk.connect(self.zk_config)
James E. Blair8b2a1472017-02-19 15:33:55 -080040 self.hostname = 'nodepool-test-hostname'
James E. Blair3897a132016-12-22 18:23:42 -080041
42 self.provisioned_requests = []
43 # This class implements the scheduler methods zuul.nodepool
44 # needs, so we pass 'self' as the scheduler.
45 self.nodepool = zuul.nodepool.Nodepool(self)
46
James E. Blair0d5a36e2017-02-21 10:53:44 -050047 self.fake_nodepool = FakeNodepool(
48 self.zk_chroot_fixture.zookeeper_host,
49 self.zk_chroot_fixture.zookeeper_port,
50 self.zk_chroot_fixture.zookeeper_chroot)
James E. Blair3897a132016-12-22 18:23:42 -080051
52 def waitForRequests(self):
53 # Wait until all requests are complete.
54 while self.nodepool.requests:
55 time.sleep(0.1)
56
57 def onNodesProvisioned(self, request):
58 # This is a scheduler method that the nodepool class calls
59 # back when a request is provisioned.
60 self.provisioned_requests.append(request)
61
62 def test_node_request(self):
63 # Test a simple node request
64
65 nodeset = model.NodeSet()
66 nodeset.addNode(model.Node('controller', 'ubuntu-xenial'))
67 nodeset.addNode(model.Node('compute', 'ubuntu-xenial'))
68 job = model.Job('testjob')
69 job.nodeset = nodeset
70 request = self.nodepool.requestNodes(None, job)
71 self.waitForRequests()
72 self.assertEqual(len(self.provisioned_requests), 1)
73 self.assertEqual(request.state, 'fulfilled')
James E. Blair15be0e12017-01-03 13:45:20 -080074
James E. Blaira38c28e2017-01-04 10:33:20 -080075 # Accept the nodes
76 self.nodepool.acceptNodes(request)
77 nodeset = request.nodeset
78
79 for node in nodeset.getNodes():
80 self.assertIsNotNone(node.lock)
81 self.assertEqual(node.state, 'ready')
82
James E. Blaircacdf2b2017-01-04 13:14:37 -080083 # Mark the nodes in use
James E. Blair1511bc32017-01-18 09:25:31 -080084 self.nodepool.useNodeSet(nodeset)
James E. Blaircacdf2b2017-01-04 13:14:37 -080085 for node in nodeset.getNodes():
86 self.assertEqual(node.state, 'in-use')
87
James E. Blair62295d32017-01-04 13:27:58 -080088 # Return the nodes
James E. Blair1511bc32017-01-18 09:25:31 -080089 self.nodepool.returnNodeSet(nodeset)
James E. Blair62295d32017-01-04 13:27:58 -080090 for node in nodeset.getNodes():
91 self.assertIsNone(node.lock)
92 self.assertEqual(node.state, 'used')
93
James E. Blair15be0e12017-01-03 13:45:20 -080094 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)
109 self.assertEqual(request.state, 'fulfilled')
James E. Blair01695c32017-01-04 17:29:25 -0800110
111 def test_node_request_canceled(self):
112 # Test that node requests can be canceled
113
114 nodeset = model.NodeSet()
115 nodeset.addNode(model.Node('controller', 'ubuntu-xenial'))
116 nodeset.addNode(model.Node('compute', 'ubuntu-xenial'))
117 job = model.Job('testjob')
118 job.nodeset = nodeset
119 self.fake_nodepool.paused = True
120 request = self.nodepool.requestNodes(None, job)
121 self.nodepool.cancelRequest(request)
122
123 self.waitForRequests()
124 self.assertEqual(len(self.provisioned_requests), 0)