From 7ead3dd0efd877c1accae358cd866a63878cb7d6 Mon Sep 17 00:00:00 2001 From: Mark Hamzy Date: Fri, 16 Sep 2016 12:36:42 -0500 Subject: [PATCH] Add a bunch of new testcases for molteniron Add tests for adding a BM node, for allocating a BM node, for culling BM nodes, for deallocating a BM node, for deallocating a node's owner, for cleaning the database, for getting a field of a node, for getting the IPs of a node, and for removing a BM node. Change-Id: I666747656948e19d4817327b33017c4f01752baa --- tests/testAddBMNode.py | 134 ++++++++++++ testAllocateBM.py => tests/testAllocateBM.py | 60 ++++-- tests/testCull.py | 203 +++++++++++++++++++ tests/testDeallocateBM.py | 185 +++++++++++++++++ tests/testDeallocateOwner.py | 146 +++++++++++++ tests/testDoClean.py | 138 +++++++++++++ tests/testGetField.py | 142 +++++++++++++ tests/testGetIps.py | 137 +++++++++++++ tests/testRemoveBMNode.py | 132 ++++++++++++ tox.ini | 27 +++ 10 files changed, 1288 insertions(+), 16 deletions(-) create mode 100755 tests/testAddBMNode.py rename testAllocateBM.py => tests/testAllocateBM.py (71%) create mode 100755 tests/testCull.py create mode 100755 tests/testDeallocateBM.py create mode 100755 tests/testDeallocateOwner.py create mode 100755 tests/testDoClean.py create mode 100755 tests/testGetField.py create mode 100755 tests/testGetIps.py create mode 100755 tests/testRemoveBMNode.py diff --git a/tests/testAddBMNode.py b/tests/testAddBMNode.py new file mode 100755 index 0000000..e7a29ea --- /dev/null +++ b/tests/testAddBMNode.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 IBM Corporation. +# +# 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 sys +import os +import yaml +import argparse +from molteniron import moltenirond + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Molteniron command line tool") + parser.add_argument("-c", + "--conf-dir", + action="store", + type=str, + dest="conf_dir", + help="The directory where configuration is stored") + + args = parser.parse_args(sys.argv[1:]) + + if args.conf_dir: + if not os.path.isdir (args.conf_dir): + msg = "Error: %s is not a valid directory" % (args.conf_dir, ) + print >> sys.stderr, msg + sys.exit(1) + + yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, )) + else: + yaml_file = "/usr/local/etc/molteniron/conf.yaml" + + with open(yaml_file, "r") as fobj: + conf = yaml.load(fobj) + + node1 = { + "name": "pkvmci816", + "ipmi_ip": "10.228.219.134", + "ipmi_user": "user", + "ipmi_password": "2f024600fc5ef6f7", + "port_hwaddr": "97:c3:b0:47:0c:0d", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.10,10.228.112.11" + } + node2 = { + "name": "pkvmci818", + "ipmi_ip": "10.228.219.133", + "ipmi_user": "user", + "ipmi_password": "6cf0957c985b2deb", + "port_hwaddr": "2d:9e:3c:83:8a:be", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.8,10.228.112.9" + } + node3 = { + "name": "pkvmci851", + "ipmi_ip": "10.228.118.129", + "ipmi_user": "user", + "ipmi_password": "cc777c10196db585", + "port_hwaddr": "47:b0:dc:d5:82:d9", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", + "timestamp": "1460489832", + "allocation_pool": "10.228.112.12,10.228.112.13" + } + node4 = { + "name": "pkvmci853", + "ipmi_ip": "10.228.118.133", + "ipmi_user": "user", + "ipmi_password": "a700a2d789075276", + "port_hwaddr": "44:94:1a:c7:8a:9f", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", + "timestamp": "1460491566", + "allocation_pool": "10.228.112.14,10.228.112.15" + } + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node1) + print ret + assert ret['status'] == 400 + assert ret['message'] == "Node already exists" + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret['status'] == 400 + assert ret['message'] == "Node already exists" + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret['status'] == 400 + assert ret['message'] == "Node already exists" + + database.close() + del database diff --git a/testAllocateBM.py b/tests/testAllocateBM.py similarity index 71% rename from testAllocateBM.py rename to tests/testAllocateBM.py index 86cb150..337aff1 100755 --- a/testAllocateBM.py +++ b/tests/testAllocateBM.py @@ -1,8 +1,25 @@ #!/usr/bin/env python +# Copyright (c) 2016 IBM Corporation. +# +# 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 sys +import os import yaml -from moltenirond import DataBase, TYPE_SQLITE_MEMORY +import argparse +from molteniron import moltenirond def compare_provisioned_nodes(lhs, rhs): lhs = lhs.copy() @@ -16,12 +33,28 @@ def compare_provisioned_nodes(lhs, rhs): assert lhs == rhs if __name__ == "__main__": - path = sys.argv[0] - dirs = path.split("/") - newPath = "/".join(dirs[:-1]) + "/" + parser = argparse.ArgumentParser(description="Molteniron command line tool") + parser.add_argument("-c", + "--conf-dir", + action="store", + type=str, + dest="conf_dir", + help="The directory where configuration is stored") - fobj = open(newPath + "conf.yaml", "r") - conf = yaml.load(fobj) + args = parser.parse_args(sys.argv[1:]) + + if args.conf_dir: + if not os.path.isdir (args.conf_dir): + msg = "Error: %s is not a valid directory" % (args.conf_dir, ) + print >> sys.stderr, msg + sys.exit(1) + + yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, )) + else: + yaml_file = "/usr/local/etc/molteniron/conf.yaml" + + with open(yaml_file, "r") as fobj: + conf = yaml.load(fobj) node1 = { "name": "pkvmci816", @@ -85,12 +118,7 @@ if __name__ == "__main__": } # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- - database = DataBase(conf, TYPE_SQLITE_MEMORY) - database.delete_db() - database.close() - del database - - database = DataBase(conf, TYPE_SQLITE_MEMORY) + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) ret = database.addBMNode (node1) print ret assert ret == {'status': 200} @@ -114,12 +142,12 @@ if __name__ == "__main__": del database # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- - database = DataBase(conf, TYPE_SQLITE_MEMORY) + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) database.delete_db() database.close() del database - database = DataBase(conf, TYPE_SQLITE_MEMORY) + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) ret = database.addBMNode (node1) print ret assert ret == {'status': 200} @@ -144,12 +172,12 @@ if __name__ == "__main__": del database # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- - database = DataBase(conf, TYPE_SQLITE_MEMORY) + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) database.delete_db() database.close() del database - database = DataBase(conf, TYPE_SQLITE_MEMORY) + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) ret = database.addBMNode (node1) print ret assert ret == {'status': 200} diff --git a/tests/testCull.py b/tests/testCull.py new file mode 100755 index 0000000..70aa9dc --- /dev/null +++ b/tests/testCull.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 IBM Corporation. +# +# 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 sys +import os +import yaml +import argparse +import time +from molteniron import moltenirond + +def compare_culled_nodes(lhs, rhs): + lhs = lhs.copy() + rhs = rhs.copy() + del rhs['allocation_pool'] + # timestamp can be converted on the server + del lhs['timestamp'] + del rhs['timestamp'] + del lhs['id'] + assert lhs == rhs + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Molteniron command line tool") + parser.add_argument("-c", + "--conf-dir", + action="store", + type=str, + dest="conf_dir", + help="The directory where configuration is stored") + + args = parser.parse_args(sys.argv[1:]) + + if args.conf_dir: + if not os.path.isdir (args.conf_dir): + msg = "Error: %s is not a valid directory" % (args.conf_dir, ) + print >> sys.stderr, msg + sys.exit(1) + + yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, )) + else: + yaml_file = "/usr/local/etc/molteniron/conf.yaml" + + with open(yaml_file, "r") as fobj: + conf = yaml.load(fobj) + + node1 = { + "name": "pkvmci816", + "ipmi_ip": "10.228.219.134", + "ipmi_user": "user", + "ipmi_password": "34118fd3509621ba", + "port_hwaddr": "ff:2c:e1:cc:8e:7c", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.10,10.228.112.11" + } + node2 = { + "name": "pkvmci818", + "ipmi_ip": "10.228.219.133", + "ipmi_user": "user", + "ipmi_password": "fa2125690a95b43c", + "port_hwaddr": "f6:58:13:02:64:59", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "-1", + "allocation_pool": "10.228.112.8,10.228.112.9" + } + node3 = { + "name": "pkvmci851", + "ipmi_ip": "10.228.118.129", + "ipmi_user": "user", + "ipmi_password": "3aee014d56425a6c", + "port_hwaddr": "6e:d4:a5:ae:13:55", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", + # NOTE: time() can return fractional values. Ex: 1460560140.47 + "timestamp": str (time.time() - 1000.0), + "allocation_pool": "10.228.112.12,10.228.112.13" + } + node4 = { + "name": "pkvmci853", + "ipmi_ip": "10.228.118.133", + "ipmi_user": "user", + "ipmi_password": "254dd9fb34ddcac7", + "port_hwaddr": "a0:c9:22:23:22:9d", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", + "timestamp": str (time.time() - 2000.0), + "allocation_pool": "10.228.112.14,10.228.112.15" + } + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node4) + print ret + assert ret == {'status': 200} + + ret = database.cull (1000) + print ret + assert ret['status'] == 200 + assert len(ret['nodes']) == 2 + + compare_culled_nodes (ret['nodes']['node_3'], node3) + compare_culled_nodes (ret['nodes']['node_4'], node4) + + database.close() + del database + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + database.delete_db() + database.close() + del database + + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node4) + print ret + assert ret == {'status': 200} + + ret = database.cull (2000) + print ret + assert ret['status'] == 200 + assert len(ret['nodes']) == 1 + + compare_culled_nodes (ret['nodes']['node_4'], node4) + + database.close() + del database + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + database.delete_db() + database.close() + del database + + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node4) + print ret + assert ret == {'status': 200} + + ret = database.cull (3000) + print ret + assert ret['status'] == 200 + assert len(ret['nodes']) == 0 + + database.close() + del database diff --git a/tests/testDeallocateBM.py b/tests/testDeallocateBM.py new file mode 100755 index 0000000..8202b62 --- /dev/null +++ b/tests/testDeallocateBM.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 IBM Corporation. +# +# 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 sys +import os +import yaml +import argparse +from molteniron import moltenirond + +def compare_provisioned_nodes(lhs, rhs): + lhs = lhs.copy() + rhs = rhs.copy() + rhs['provisioned'] = 'hamzy' + del lhs['status'] + del lhs['timestamp'] + del rhs['status'] + del rhs['timestamp'] + del lhs['id'] + assert lhs == rhs + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Molteniron command line tool") + parser.add_argument("-c", + "--conf-dir", + action="store", + type=str, + dest="conf_dir", + help="The directory where configuration is stored") + + args = parser.parse_args(sys.argv[1:]) + + if args.conf_dir: + if not os.path.isdir (args.conf_dir): + msg = "Error: %s is not a valid directory" % (args.conf_dir, ) + print >> sys.stderr, msg + sys.exit(1) + + yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, )) + else: + yaml_file = "/usr/local/etc/molteniron/conf.yaml" + + with open(yaml_file, "r") as fobj: + conf = yaml.load(fobj) + + node1 = { + "name": "pkvmci816", + "ipmi_ip": "10.228.219.134", + "ipmi_user": "user", + "ipmi_password": "16f6954d347c4de2", + "port_hwaddr": "28:5a:e7:e3:fe:75", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.10,10.228.112.11" + } + node2 = { + "name": "pkvmci818", + "ipmi_ip": "10.228.219.133", + "ipmi_user": "user", + "ipmi_password": "3a23241cfa516699", + "port_hwaddr": "7d:0a:e5:b9:41:9b", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.8,10.228.112.9" + } + node3 = { + "name": "pkvmci851", + "ipmi_ip": "10.228.118.129", + "ipmi_user": "user", + "ipmi_password": "4f7e47c57f27ec55", + "port_hwaddr": "5a:e8:11:e9:11:a2", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", + "timestamp": "1460489832", + "allocation_pool": "10.228.112.12,10.228.112.13" + } + node4 = { + "name": "pkvmci853", + "ipmi_ip": "10.228.118.133", + "ipmi_user": "user", + "ipmi_password": "aeff165ded2c2f9f", + "port_hwaddr": "4d:18:82:dc:2c:d6", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", + "timestamp": "1460491566", + "allocation_pool": "10.228.112.14,10.228.112.15" + } + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node4) + print ret + assert ret == {'status': 200} + + ret = database.allocateBM("hamzy", 1) + print ret + assert ret['status'] == 200 + assert len(ret["nodes"]) == 1 + compare_provisioned_nodes (ret["nodes"]["node_1"], node1) + + session = database.get_session() + n1 = session.query(moltenirond.Nodes).filter_by(name=node1["name"]).one() + session.close() + ret = database.deallocateBM(n1.id) + print ret + assert ret['status'] == 200 + + database.close() + del database + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + database.delete_db() + database.close() + del database + + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node4) + print ret + assert ret == {'status': 200} + + ret = database.allocateBM("hamzy", 1) + print ret + assert ret['status'] == 200 + assert len(ret["nodes"]) == 1 + compare_provisioned_nodes (ret["nodes"]["node_1"], node1) + + session = database.get_session() + n1 = session.query(moltenirond.Nodes).filter_by(name=node1["name"]).one() + session.close() + ret = database.deallocateBM(n1.ipmi_ip) + print ret + assert ret['status'] == 200 + + database.close() + del database diff --git a/tests/testDeallocateOwner.py b/tests/testDeallocateOwner.py new file mode 100755 index 0000000..dd7e0df --- /dev/null +++ b/tests/testDeallocateOwner.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 IBM Corporation. +# +# 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 sys +import os +import yaml +import argparse +from molteniron import moltenirond + +def compare_provisioned_nodes(lhs, rhs): + lhs = lhs.copy() + rhs = rhs.copy() + rhs['provisioned'] = 'hamzy' + del lhs['status'] + del lhs['timestamp'] + del rhs['status'] + del rhs['timestamp'] + del lhs['id'] + assert lhs == rhs + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Molteniron command line tool") + parser.add_argument("-c", + "--conf-dir", + action="store", + type=str, + dest="conf_dir", + help="The directory where configuration is stored") + + args = parser.parse_args(sys.argv[1:]) + + if args.conf_dir: + if not os.path.isdir (args.conf_dir): + msg = "Error: %s is not a valid directory" % (args.conf_dir, ) + print >> sys.stderr, msg + sys.exit(1) + + yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, )) + else: + yaml_file = "/usr/local/etc/molteniron/conf.yaml" + + with open(yaml_file, "r") as fobj: + conf = yaml.load(fobj) + + node1 = { + "name": "pkvmci816", + "ipmi_ip": "10.228.219.134", + "ipmi_user": "user", + "ipmi_password": "f367d07be07d6358", + "port_hwaddr": "6d:9a:78:f3:ed:3a", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.10,10.228.112.11" + } + node2 = { + "name": "pkvmci818", + "ipmi_ip": "10.228.219.133", + "ipmi_user": "user", + "ipmi_password": "1c6a27307f8fe79d", + "port_hwaddr": "16:23:e8:07:b4:a9", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.8,10.228.112.9" + } + node3 = { + "name": "pkvmci851", + "ipmi_ip": "10.228.118.129", + "ipmi_user": "user", + "ipmi_password": "1766d597a024dd8d", + "port_hwaddr": "12:33:9f:04:07:9b", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", + "timestamp": "1460489832", + "allocation_pool": "10.228.112.12,10.228.112.13" + } + node4 = { + "name": "pkvmci853", + "ipmi_ip": "10.228.118.133", + "ipmi_user": "user", + "ipmi_password": "7c55be8b4ef42869", + "port_hwaddr": "c2:31:e9:8a:75:96", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", + "timestamp": "1460491566", + "allocation_pool": "10.228.112.14,10.228.112.15" + } + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node4) + print ret + assert ret == {'status': 200} + + ret = database.allocateBM("hamzy", 1) + print ret + assert ret['status'] == 200 + assert len(ret["nodes"]) == 1 + compare_provisioned_nodes (ret["nodes"]["node_1"], node1) + + ret = database.deallocateOwner("hamzy") + print ret + assert ret['status'] == 200 + + database.close() + del database diff --git a/tests/testDoClean.py b/tests/testDoClean.py new file mode 100755 index 0000000..8e9c676 --- /dev/null +++ b/tests/testDoClean.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 IBM Corporation. +# +# 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 sys +import os +import yaml +import argparse +from molteniron import moltenirond + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Molteniron command line tool") + parser.add_argument("-c", + "--conf-dir", + action="store", + type=str, + dest="conf_dir", + help="The directory where configuration is stored") + + args = parser.parse_args(sys.argv[1:]) + + if args.conf_dir: + if not os.path.isdir (args.conf_dir): + msg = "Error: %s is not a valid directory" % (args.conf_dir, ) + print >> sys.stderr, msg + sys.exit(1) + + yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, )) + else: + yaml_file = "/usr/local/etc/molteniron/conf.yaml" + + with open(yaml_file, "r") as fobj: + conf = yaml.load(fobj) + + node1 = { + "name": "pkvmci816", + "ipmi_ip": "10.228.219.134", + "ipmi_user": "user", + "ipmi_password": "e23af1e52896cf02", + "port_hwaddr": "5d:7e:05:dd:fe:65", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.10,10.228.112.11" + } + node2 = { + "name": "pkvmci818", + "ipmi_ip": "10.228.219.133", + "ipmi_user": "user", + "ipmi_password": "57212373db56c76a", + "port_hwaddr": "7e:41:89:e1:28:03", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.8,10.228.112.9" + } + node3 = { + "name": "pkvmci851", + "ipmi_ip": "10.228.118.129", + "ipmi_user": "user", + "ipmi_password": "c2f4b0bfa31fe9de", + "port_hwaddr": "4f:a7:48:59:6a:a7", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", + "timestamp": "1460489832", + "allocation_pool": "10.228.112.12,10.228.112.13" + } + node4 = { + "name": "pkvmci853", + "ipmi_ip": "10.228.118.133", + "ipmi_user": "user", + "ipmi_password": "f99d122fc129c1dd", + "port_hwaddr": "a2:0d:bc:ca:c5:a5", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", + "timestamp": "1460491566", + "allocation_pool": "10.228.112.14,10.228.112.15" + } + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node4) + print ret + assert ret == {'status': 200} + + ret = database.doClean(1) + print ret + assert ret == {'status': 400, 'message': 'The node at 1 has status ready'} + + ret = database.doClean(2) + print ret + assert ret == {'status': 400, 'message': 'The node at 2 has status ready'} + + ret = database.doClean(3) + print ret + assert ret == {'status': 200} + + ret = database.doClean(4) + print ret + assert ret == {'status': 200} diff --git a/tests/testGetField.py b/tests/testGetField.py new file mode 100755 index 0000000..7813b74 --- /dev/null +++ b/tests/testGetField.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 IBM Corporation. +# +# 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 sys +import os +import yaml +import argparse +from molteniron import moltenirond + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Molteniron command line tool") + parser.add_argument("-c", + "--conf-dir", + action="store", + type=str, + dest="conf_dir", + help="The directory where configuration is stored") + + args = parser.parse_args(sys.argv[1:]) + + if args.conf_dir: + if not os.path.isdir (args.conf_dir): + msg = "Error: %s is not a valid directory" % (args.conf_dir, ) + print >> sys.stderr, msg + sys.exit(1) + + yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, )) + else: + yaml_file = "/usr/local/etc/molteniron/conf.yaml" + + with open(yaml_file, "r") as fobj: + conf = yaml.load(fobj) + + node1 = { + "name": "pkvmci816", + "ipmi_ip": "10.228.219.134", + "ipmi_user": "user", + "ipmi_password": "7db1486ac9ea6533", + "port_hwaddr": "ca:2c:ab:88:47:b0", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "hamzy", + "timestamp": "", + "allocation_pool": "10.228.112.10,10.228.112.11" + } + node2 = { + "name": "pkvmci818", + "ipmi_ip": "10.228.219.133", + "ipmi_user": "user", + "ipmi_password": "c3f8e3f3407e880b", + "port_hwaddr": "90:24:5c:d5:0e:b3", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "mjturek", + "timestamp": "", + "allocation_pool": "10.228.112.8,10.228.112.9" + } + node3 = { + "name": "pkvmci851", + "ipmi_ip": "10.228.118.129", + "ipmi_user": "user", + "ipmi_password": "1bcbf739c7108291", + "port_hwaddr": "9c:6b:1b:31:a5:2d", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", + "timestamp": "1460489832", + "allocation_pool": "10.228.112.12,10.228.112.13" + } + node4 = { + "name": "pkvmci853", + "ipmi_ip": "10.228.118.133", + "ipmi_user": "user", + "cpu_arch": "ppc64el", + "ipmi_password": "0c200c858ac46280", + "port_hwaddr": "64:49:12:c6:3f:bd", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "mjturek", + "timestamp": "1460491566", + "allocation_pool": "10.228.112.14,10.228.112.15" + } + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node4) + print ret + assert ret == {'status': 200} + + ret = database.get_field("hamzy", "cpus") + print ret + assert ret['status'] == 200 + assert len(ret['result']) ==1 + assert ret['result'][0]['field'] == node1["cpus"] + + ret = database.get_field("mjturek", "port_hwaddr") + print ret + assert ret['status'] == 200 + assert len(ret['result']) == 2 + assert ret['result'][0]['field'] == node2["port_hwaddr"] + assert ret['result'][1]['field'] == node4["port_hwaddr"] + + ret = database.get_field("mmedvede", "candy") + print ret + assert ret == {'status': 400, 'message': 'field candy does not exist'} + + database.close() + del database diff --git a/tests/testGetIps.py b/tests/testGetIps.py new file mode 100755 index 0000000..2af8fd5 --- /dev/null +++ b/tests/testGetIps.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 IBM Corporation. +# +# 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 sys +import os +import yaml +import argparse +from molteniron import moltenirond + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Molteniron command line tool") + parser.add_argument("-c", + "--conf-dir", + action="store", + type=str, + dest="conf_dir", + help="The directory where configuration is stored") + + args = parser.parse_args(sys.argv[1:]) + + if args.conf_dir: + if not os.path.isdir (args.conf_dir): + msg = "Error: %s is not a valid directory" % (args.conf_dir, ) + print >> sys.stderr, msg + sys.exit(1) + + yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, )) + else: + yaml_file = "/usr/local/etc/molteniron/conf.yaml" + + with open(yaml_file, "r") as fobj: + conf = yaml.load(fobj) + + node1 = { + "name": "pkvmci816", + "ipmi_ip": "10.228.219.134", + "ipmi_user": "user", + "ipmi_password": "1aa328d7767653ad", + "port_hwaddr": "17:e7:f1:ab:a5:9f", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "hamzy", + "timestamp": "", + "allocation_pool": "10.228.112.10,10.228.112.11" + } + node2 = { + "name": "pkvmci818", + "ipmi_ip": "10.228.219.133", + "ipmi_user": "user", + "ipmi_password": "84b9d9ceb866f612", + "port_hwaddr": "0b:f1:9c:9d:a6:eb", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "mjturek", + "timestamp": "", + "allocation_pool": "10.228.112.8,10.228.112.9" + } + node3 = { + "name": "pkvmci851", + "ipmi_ip": "10.228.118.129", + "ipmi_user": "user", + "ipmi_password": "ba60285a1fd69800", + "port_hwaddr": "da:e0:86:2a:80:9c", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", + "timestamp": "1460489832", + "allocation_pool": "10.228.112.12,10.228.112.13" + } + node4 = { + "name": "pkvmci853", + "ipmi_ip": "10.228.118.133", + "ipmi_user": "user", + "cpu_arch": "ppc64el", + "ipmi_password": "7810c66057ef4f2d", + "port_hwaddr": "d6:bc:ca:83:95:e7", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "mjturek", + "timestamp": "1460491566", + "allocation_pool": "10.228.112.14,10.228.112.15" + } + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node4) + print ret + assert ret == {'status': 200} + + ret = database.get_ips("hamzy") + print ret + assert ret['status'] == 200 + assert len(ret['ips']) == 1 + assert ret['ips'] == [ node1["ipmi_ip"] ] + + ret = database.get_ips("mjturek") + print ret + assert ret['status'] == 200 + assert len(ret['ips']) == 2 + assert ret['ips'] == [ node2["ipmi_ip"], node4["ipmi_ip"] ] + + database.close() + del database diff --git a/tests/testRemoveBMNode.py b/tests/testRemoveBMNode.py new file mode 100755 index 0000000..bc8a778 --- /dev/null +++ b/tests/testRemoveBMNode.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 IBM Corporation. +# +# 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 sys +import os +import yaml +import argparse +from molteniron import moltenirond + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Molteniron command line tool") + parser.add_argument("-c", + "--conf-dir", + action="store", + type=str, + dest="conf_dir", + help="The directory where configuration is stored") + + args = parser.parse_args(sys.argv[1:]) + + if args.conf_dir: + if not os.path.isdir (args.conf_dir): + msg = "Error: %s is not a valid directory" % (args.conf_dir, ) + print >> sys.stderr, msg + sys.exit(1) + + yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, )) + else: + yaml_file = "/usr/local/etc/molteniron/conf.yaml" + + with open(yaml_file, "r") as fobj: + conf = yaml.load(fobj) + + node1 = { + "name": "pkvmci816", + "ipmi_ip": "10.228.219.134", + "ipmi_user": "user", + "ipmi_password": "2703f5fee17f2073", + "port_hwaddr": "b1:71:dd:02:9e:20", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.10,10.228.112.11" + } + node2 = { + "name": "pkvmci818", + "ipmi_ip": "10.228.219.133", + "ipmi_user": "user", + "ipmi_password": "c3f06ff4b798a4ea", + "port_hwaddr": "88:6e:9e:fa:65:d8", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "ready", + "provisioned": "", + "timestamp": "", + "allocation_pool": "10.228.112.8,10.228.112.9" + } + node3 = { + "name": "pkvmci851", + "ipmi_ip": "10.228.118.129", + "ipmi_user": "user", + "ipmi_password": "2885d1af50781461", + "port_hwaddr": "a2:a2:64:79:6b:69", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", + "timestamp": "1460489832", + "allocation_pool": "10.228.112.12,10.228.112.13" + } + node4 = { + "name": "pkvmci853", + "ipmi_ip": "10.228.118.133", + "ipmi_user": "user", + "ipmi_password": "3e374dc88ca43b4f", + "port_hwaddr": "50:4a:56:3c:e9:0f", + "cpu_arch": "ppc64el", + "cpus": 20L, + "ram_mb": 51000L, + "disk_gb": 500L, + "status": "used", + "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", + "timestamp": "1460491566", + "allocation_pool": "10.228.112.14,10.228.112.15" + } + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode (node1) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node2) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node3) + print ret + assert ret == {'status': 200} + ret = database.addBMNode (node4) + print ret + assert ret == {'status': 200} + + session = database.get_session() + n1 = session.query(moltenirond.Nodes).filter_by(name=node1["name"]).one() + session.close() + ret = database.removeBMNode(n1.id, False) + print ret + assert ret['status'] == 200 + + database.close() + del database diff --git a/tox.ini b/tox.ini index cca5de5..5a54ac7 100644 --- a/tox.ini +++ b/tox.ini @@ -50,6 +50,33 @@ commands = mkdir -p testenv/var/run/ molteniron \ --conf-dir=testenv/etc/molteniron/ \ release hamzy + python \ + tests/testAllocateBM.py \ + --conf-dir=testenv/etc/molteniron/ + python \ + tests/testAddBMNode.py \ + --conf-dir=testenv/etc/molteniron/ + python \ + tests/testCull.py \ + --conf-dir=testenv/etc/molteniron/ + python \ + tests/testDeallocateBM.py \ + --conf-dir=testenv/etc/molteniron/ + python \ + tests/testDeallocateOwner.py \ + --conf-dir=testenv/etc/molteniron/ + python \ + tests/testDoClean.py \ + --conf-dir=testenv/etc/molteniron/ + python \ + tests/testGetField.py \ + --conf-dir=testenv/etc/molteniron/ + python \ + tests/testGetIps.py \ + --conf-dir=testenv/etc/molteniron/ + python \ + tests/testRemoveBMNode.py \ + --conf-dir=testenv/etc/molteniron/ moltenirond-helper \ --conf-dir=testenv/etc/molteniron/ \ --pid-dir=testenv/var/run/ \