new tests added, dead host detection/mitigation, fix bug in specs difference computing code
This commit is contained in:
parent
5f4b7088ff
commit
f078b9b245
8 changed files with 450 additions and 138 deletions
|
|
@ -1,53 +1,83 @@
|
|||
import unittest
|
||||
import sys
|
||||
import etcd3
|
||||
import json
|
||||
import multiprocessing
|
||||
import time
|
||||
|
||||
sys.path.insert(0, "../")
|
||||
from main import accumulated_specs, remaining_resources, VmPool
|
||||
from datetime import datetime
|
||||
from os.path import dirname
|
||||
|
||||
|
||||
BASE_DIR = dirname(dirname(__file__))
|
||||
sys.path.insert(0, BASE_DIR)
|
||||
|
||||
from main import (
|
||||
accumulated_specs,
|
||||
remaining_resources,
|
||||
VmPool,
|
||||
dead_host_detection,
|
||||
dead_host_mitigation,
|
||||
main,
|
||||
)
|
||||
|
||||
from etcd3_wrapper import Etcd3Wrapper
|
||||
|
||||
|
||||
class TestFunctions(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = etcd3.client()
|
||||
self.host_prefix = "/v1/host"
|
||||
self.vm_prefix = "/v1/vm"
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.client = Etcd3Wrapper()
|
||||
cls.host_prefix = "/test/host"
|
||||
cls.vm_prefix = "/test/vm"
|
||||
|
||||
# These deletion could also be in
|
||||
# tearDown() but it is more appropriate here
|
||||
# as it enable us to check the ETCD store
|
||||
# even after test is run
|
||||
self.client.delete_prefix(self.host_prefix)
|
||||
self.client.delete_prefix(self.vm_prefix)
|
||||
cls.client.client.delete_prefix(cls.host_prefix)
|
||||
cls.client.client.delete_prefix(cls.vm_prefix)
|
||||
cls.create_hosts(cls)
|
||||
cls.create_vms(cls)
|
||||
|
||||
self.create_hosts()
|
||||
self.create_vms()
|
||||
cls.p = multiprocessing.Process(
|
||||
target=main, args=[cls.vm_prefix, cls.host_prefix]
|
||||
)
|
||||
cls.p.start()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.p.terminate()
|
||||
|
||||
def create_hosts(self):
|
||||
host1 = """{
|
||||
host1 = {
|
||||
"cpu": 32,
|
||||
"ram": 128,
|
||||
"hdd": 1024,
|
||||
"sdd": 0
|
||||
}"""
|
||||
|
||||
host2 = """{
|
||||
"sdd": 0,
|
||||
"status": "ALIVE",
|
||||
"last_heartbeat": datetime.utcnow().isoformat(),
|
||||
}
|
||||
host2 = {
|
||||
"cpu": 16,
|
||||
"ram": 64,
|
||||
"hdd": 512,
|
||||
"sdd": 0
|
||||
}"""
|
||||
"sdd": 0,
|
||||
"status": "ALIVE",
|
||||
"last_heartbeat": datetime.utcnow().isoformat(),
|
||||
}
|
||||
|
||||
host3 = """{
|
||||
host3 = {
|
||||
"cpu": 16,
|
||||
"ram": 32,
|
||||
"hdd": 256,
|
||||
"sdd": 256
|
||||
}"""
|
||||
with self.client.lock("lock"):
|
||||
self.client.put(f"{self.host_prefix}/1", host1)
|
||||
self.client.put(f"{self.host_prefix}/2", host2)
|
||||
self.client.put(f"{self.host_prefix}/3", host3)
|
||||
"sdd": 256,
|
||||
"status": "ALIVE",
|
||||
"last_heartbeat": datetime.utcnow().isoformat(),
|
||||
}
|
||||
with self.client.client.lock("lock"):
|
||||
self.client.put(f"{self.host_prefix}/1", host1, value_in_json=True)
|
||||
self.client.put(f"{self.host_prefix}/2", host2, value_in_json=True)
|
||||
self.client.put(f"{self.host_prefix}/3", host3, value_in_json=True)
|
||||
|
||||
def create_vms(self):
|
||||
vm1 = json.dumps(
|
||||
|
|
@ -121,35 +151,64 @@ class TestFunctions(unittest.TestCase):
|
|||
{"cpu": 8, "ram": 32},
|
||||
]
|
||||
self.assertEqual(
|
||||
accumulated_specs(vms),
|
||||
{"ssd": 10, "cpu": 16, "ram": 48, "hdd": 10},
|
||||
accumulated_specs(vms), {"ssd": 10, "cpu": 16, "ram": 48, "hdd": 10}
|
||||
)
|
||||
|
||||
def test_remaining_resources(self):
|
||||
host_specs = {"ssd": 10, "cpu": 16, "ram": 48, "hdd": 10}
|
||||
vms_specs = {"ssd": 10, "cpu": 32, "ram": 12, "hdd": 0}
|
||||
resultant_specs = {"ssd": 0, "cpu": -16, "ram": 36, "hdd": 10}
|
||||
self.assertEqual(
|
||||
remaining_resources(host_specs, vms_specs), resultant_specs
|
||||
)
|
||||
self.assertEqual(remaining_resources(host_specs, vms_specs),
|
||||
resultant_specs)
|
||||
|
||||
def test_vmpool(self):
|
||||
self.p.join(1)
|
||||
vm_pool = VmPool(self.client, self.vm_prefix)
|
||||
print(self.client.get(f"{self.vm_prefix}/1")[1].key)
|
||||
self.assertEqual(
|
||||
vm_pool.by_host(vm_pool.vms, f"{self.host_prefix}/1"),
|
||||
[
|
||||
(
|
||||
f"{self.vm_prefix}/1",
|
||||
{
|
||||
"owner": "meow",
|
||||
"specs": {"cpu": 4, "ram": 8, "hdd": 100, "sdd": 256},
|
||||
"hostname": f"{self.host_prefix}/1",
|
||||
"status": "SCHEDULED_DEPLOY",
|
||||
},
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
# vm_pool by host
|
||||
actual = vm_pool.by_host(vm_pool.vms, f"{self.host_prefix}/3")
|
||||
ground_truth = [
|
||||
(
|
||||
f"{self.vm_prefix}/1",
|
||||
{
|
||||
"owner": "meow",
|
||||
"specs": {"cpu": 4, "ram": 8, "hdd": 100, "sdd": 256},
|
||||
"hostname": f"{self.host_prefix}/3",
|
||||
"status": "SCHEDULED_DEPLOY",
|
||||
},
|
||||
)
|
||||
]
|
||||
self.assertEqual(actual[0], ground_truth[0])
|
||||
|
||||
# vm_pool by status
|
||||
actual = vm_pool.by_status(vm_pool.vms, "REQUESTED_NEW")
|
||||
ground_truth = [
|
||||
(
|
||||
f"{self.vm_prefix}/7",
|
||||
{
|
||||
"owner": "meow",
|
||||
"specs": {"cpu": 10, "ram": 22, "hdd": 146, "sdd": 0},
|
||||
"hostname": "",
|
||||
"status": "REQUESTED_NEW",
|
||||
},
|
||||
)
|
||||
]
|
||||
self.assertEqual(actual[0], ground_truth[0])
|
||||
|
||||
# vm_pool by except status
|
||||
actual = vm_pool.except_status(vm_pool.vms, "SCHEDULED_DEPLOY")
|
||||
ground_truth = [
|
||||
(
|
||||
f"{self.vm_prefix}/7",
|
||||
{
|
||||
"owner": "meow",
|
||||
"specs": {"cpu": 10, "ram": 22, "hdd": 146, "sdd": 0},
|
||||
"hostname": "",
|
||||
"status": "REQUESTED_NEW",
|
||||
},
|
||||
)
|
||||
]
|
||||
self.assertEqual(actual[0], ground_truth[0])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
83
tests/test_dead_host_mechanism.py
Normal file
83
tests/test_dead_host_mechanism.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import unittest
|
||||
import sys
|
||||
import json
|
||||
import multiprocessing
|
||||
import time
|
||||
|
||||
from datetime import datetime
|
||||
from os.path import dirname
|
||||
BASE_DIR = dirname(dirname(__file__))
|
||||
sys.path.insert(0, BASE_DIR)
|
||||
|
||||
from main import (
|
||||
accumulated_specs,
|
||||
remaining_resources,
|
||||
VmPool,
|
||||
dead_host_detection,
|
||||
dead_host_mitigation,
|
||||
main,
|
||||
)
|
||||
|
||||
from etcd3_wrapper import Etcd3Wrapper
|
||||
|
||||
|
||||
class TestDeadHostMechanism(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = Etcd3Wrapper()
|
||||
self.host_prefix = "/test/host"
|
||||
self.vm_prefix = "/test/vm"
|
||||
|
||||
self.client.client.delete_prefix(self.host_prefix)
|
||||
self.client.client.delete_prefix(self.vm_prefix)
|
||||
|
||||
self.create_hosts()
|
||||
|
||||
def create_hosts(self):
|
||||
host1 = {
|
||||
"cpu": 32,
|
||||
"ram": 128,
|
||||
"hdd": 1024,
|
||||
"sdd": 0,
|
||||
"status": "ALIVE",
|
||||
"last_heartbeat": datetime.utcnow().isoformat(),
|
||||
}
|
||||
host2 = {
|
||||
"cpu": 16,
|
||||
"ram": 64,
|
||||
"hdd": 512,
|
||||
"sdd": 0,
|
||||
"status": "ALIVE",
|
||||
"last_heartbeat": datetime(2011, 1, 1).isoformat(),
|
||||
}
|
||||
|
||||
host3 = {"cpu": 16, "ram": 32, "hdd": 256, "sdd": 256}
|
||||
host4 = {
|
||||
"cpu": 16,
|
||||
"ram": 32,
|
||||
"hdd": 256,
|
||||
"sdd": 256,
|
||||
"status": "DEAD",
|
||||
"last_heartbeat": datetime(2011, 1, 1).isoformat(),
|
||||
}
|
||||
with self.client.client.lock("lock"):
|
||||
self.client.put(f"{self.host_prefix}/1", host1, value_in_json=True)
|
||||
self.client.put(f"{self.host_prefix}/2", host2, value_in_json=True)
|
||||
self.client.put(f"{self.host_prefix}/3", host3, value_in_json=True)
|
||||
self.client.put(f"{self.host_prefix}/4", host4, value_in_json=True)
|
||||
|
||||
def test_dead_host_detection(self):
|
||||
hosts = self.client.get_prefix(self.host_prefix, value_in_json=True)
|
||||
deads = dead_host_detection(hosts)
|
||||
self.assertEqual(deads, ["/test/host/2", "/test/host/3"])
|
||||
return deads
|
||||
|
||||
def test_dead_host_mitigation(self):
|
||||
deads = self.test_dead_host_detection()
|
||||
dead_host_mitigation(self.client, deads)
|
||||
hosts = self.client.get_prefix(self.host_prefix, value_in_json=True)
|
||||
deads = dead_host_detection(hosts)
|
||||
self.assertEqual(deads, [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue