terracotta/tests/globals/test_manager.py
Anton Beloglazov 5b1f3fa587 Fixed tests
2012-10-16 15:32:35 +11:00

394 lines
16 KiB
Python

# Copyright 2012 Anton Beloglazov
#
# 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.
from mocktest import *
from pyqcy import *
import bottle
from hashlib import sha1
from novaclient.v1_1 import client
import time
import subprocess
import neat.globals.manager as manager
import neat.common as common
import neat.db_utils as db_utils
import logging
logging.disable(logging.CRITICAL)
class GlobalManager(TestCase):
def test_raise_error(self):
for error_code in [400, 401, 403, 405, 412]:
try:
manager.raise_error(error_code)
except bottle.HTTPResponse as e:
assert e.status_code == error_code
else:
assert False
try:
manager.raise_error(1)
except bottle.HTTPResponse as e:
assert e.status_code == 500
else:
assert False
def test_error(self):
try:
manager.error()
except bottle.HTTPResponse as e:
assert e.status_code == 405
else:
assert False
def test_validate_params(self):
with MockTransaction:
expect(manager).raise_error(401).and_return(1).exactly(3).times()
manager.validate_params('test', 'test', {})
manager.validate_params('test', 'test', {'username': 'test'})
manager.validate_params('test', 'test', {'password': 'test'})
with MockTransaction:
expect(manager).raise_error(403).exactly(2).times()
manager.validate_params(
sha1('test').hexdigest(),
sha1('test2').hexdigest(),
{'username': sha1('test1').hexdigest(),
'password': sha1('test2').hexdigest(),
'reason': 0,
'host': 'test'})
manager.validate_params(
sha1('test1').hexdigest(),
sha1('test').hexdigest(),
{'username': sha1('test1').hexdigest(),
'password': sha1('test2').hexdigest(),
'reason': 0,
'host': 'test'})
assert manager.validate_params(
sha1('test1').hexdigest(),
sha1('test2').hexdigest(),
{'username': sha1('test1').hexdigest(),
'password': sha1('test2').hexdigest(),
'time': time.time(),
'reason': 1,
'vm_uuids': ['qwe', 'asd']})
assert manager.validate_params(
sha1('test1').hexdigest(),
sha1('test2').hexdigest(),
{'username': sha1('test1').hexdigest(),
'password': sha1('test2').hexdigest(),
'time': time.time(),
'reason': 0,
'host': 'test'})
with MockTransaction:
expect(manager).raise_error(400).exactly(6).times()
manager.validate_params('test', 'test', {'username': 'test',
'password': 'test',
'time': time.time()})
manager.validate_params('test', 'test', {'username': 'test',
'password': 'test',
'time': time.time(),
'reason': 1})
manager.validate_params('test', 'test', {'username': 'test',
'password': 'test',
'time': time.time(),
'reason': 0})
manager.validate_params('test', 'test', {'username': 'test',
'password': 'test',
'time': time.time(),
'reason': 1,
'host': 'test'})
manager.validate_params('test', 'test', {'username': 'test',
'password': 'test',
'time': time.time(),
'reason': 0,
'vm_uuids': []})
manager.validate_params('test', 'test', {'username': 'test',
'password': 'test',
'reason': 0,
'vm_uuids': []})
with MockTransaction:
expect(manager).raise_error(412).exactly(2).times()
manager.validate_params('test', 'test', {'username': 'test',
'password': 'test',
'time': 1.,
'reason': 0,
'host': 'test'})
manager.validate_params('test', 'test', {'username': 'test',
'password': 'test',
'time': time.time() - 6,
'reason': 0,
'host': 'test'})
assert manager.validate_params('test', 'test',
{'username': 'test',
'password': 'test',
'time': time.time(),
'reason': 0,
'host': 'test'})
assert manager.validate_params('test', 'test',
{'username': 'test',
'password': 'test',
'time': time.time() - 4,
'reason': 0,
'host': 'test'})
def test_start(self):
with MockTransaction:
app = mock('app')
db = mock('db')
hosts = ['host1', 'host2']
state = {'property': 'value',
'db': db,
'compute_hosts': hosts,
'host_macs': {}}
config = {
'log_directory': 'dir',
'log_level': 2,
'global_manager_host': 'localhost',
'global_manager_port': 8080}
paths = [manager.DEFAILT_CONFIG_PATH, manager.CONFIG_PATH]
fields = manager.REQUIRED_FIELDS
expect(manager).read_and_validate_config(paths, fields). \
and_return(config).once()
expect(common).init_logging('dir', 'global-manager.log', 2).once()
expect(manager).init_state(config). \
and_return(state).once()
expect(manager).switch_hosts_on(db, {}, hosts).once()
expect(bottle).app().and_return(app).once()
expect(bottle).run(host='localhost', port=8080).once()
manager.start()
def test_init_state(self):
with MockTransaction:
db = mock('db')
nova = mock('nova')
hosts = ['host1', 'host2']
config = {'sql_connection': 'db',
'os_admin_user': 'user',
'os_admin_password': 'password',
'os_admin_tenant_name': 'tenant',
'os_auth_url': 'url',
'compute_hosts': 'host1, host2'}
expect(manager).init_db('db').and_return(db).once()
expect(client).Client(
'user', 'password', 'tenant', 'url',
service_type='compute'). \
and_return(nova).once()
expect(common).parse_compute_hosts('host1, host2'). \
and_return(hosts).once()
state = manager.init_state(config)
assert state['previous_time'] == 0
assert state['db'] == db
assert state['nova'] == nova
assert state['hashed_username'] == sha1('user').hexdigest()
assert state['hashed_password'] == sha1('password').hexdigest()
assert state['compute_hosts'] == hosts
assert state['host_macs'] == {}
def test_service(self):
app = mock('app')
state = {'hashed_username': 'user',
'hashed_password': 'password'}
config = {'global_manager_host': 'localhost',
'global_manager_port': 8080}
app.state = {'state': state,
'config': config}
with MockTransaction:
params = {'reason': 0,
'host': 'host'}
expect(manager).get_params(Any).and_return(params).once()
expect(manager).get_remote_addr(Any).and_return('addr').once()
expect(bottle).app().and_return(app).once()
expect(manager).validate_params('user', 'password', params). \
and_return(True).once()
expect(manager).execute_underload(config, state, 'host').once()
manager.service()
with MockTransaction:
params = {'reason': 1,
'vm_uuids': 'vm_uuids'}
expect(manager).get_params(Any).and_return(params).once()
expect(manager).get_remote_addr(Any).and_return('addr').once()
expect(bottle).app().and_return(app).once()
expect(manager).validate_params('user', 'password', params). \
and_return(True).once()
expect(manager).execute_overload(config, state, 'vm_uuids'). \
once()
manager.service()
@qc(20)
def vms_by_host(
x=dict_(
keys=str_(of='abc123-', min_length=36, max_length=36),
values=str_(of='abc123-', min_length=10, max_length=10),
min_length=0, max_length=3
),
y=list_(str_(of='abc123-', min_length=36, max_length=36),
min_length=0, max_length=3),
host=str_(of='abc123-', min_length=5, max_length=5)
):
with MockTransaction:
extra_vms = {}
for vm in y:
extra_vms[vm] = host
x.update(extra_vms)
vms = []
for vm_uuid, h in x.items():
vm = mock(vm_uuid)
vm.id = vm_uuid
expect(manager).vm_hostname(vm).and_return(h).once()
vms.append(vm)
nova = mock('nova')
nova.servers = mock('servers')
expect(nova.servers).list().and_return(vms).once()
assert set(manager.vms_by_host(nova, host)) == set(y)
@qc(1)
def vms_by_hosts(
x=list_(str_(of='abc123-', min_length=36, max_length=36),
min_length=0, max_length=3),
y=list_(str_(of='abc123-', min_length=36, max_length=36),
min_length=0, max_length=3),
host1=str_(of='abc123-', min_length=5, max_length=10),
host2=str_(of='abc123-', min_length=5, max_length=10)
):
with MockTransaction:
vms1 = {}
for vm in x:
vms1[vm] = host1
vms2 = {}
for vm in y:
vms2[vm] = host2
vms_all = dict(vms1)
vms_all.update(vms2)
vms = []
for vm_uuid, h in vms_all.items():
vm = mock(vm_uuid)
vm.id = vm_uuid
expect(manager).vm_hostname(vm).and_return(h).once()
vms.append(vm)
nova = mock('nova')
nova.servers = mock('servers')
expect(nova.servers).list().and_return(vms).once()
result = manager.vms_by_hosts(nova, [host1, host2])
result_sets = {}
for host, data in result.items():
result_sets[host] = set(data)
assert result_sets == {host1: set(x), host2: set(y)}
def test_host_used_ram(self):
with MockTransaction:
hostname = 'hosthost'
nova = mock('nova')
nova.hosts = mock('hosts')
host1 = mock('host1')
host1.memory_mb = 4000
host2 = mock('host2')
host2.memory_mb = 3000
expect(nova.hosts).get(hostname). \
and_return([host1, host2]).once()
assert manager.host_used_ram(nova, hostname) == 3000
with MockTransaction:
hostname = 'hosthost'
nova = mock('nova')
nova.hosts = mock('hosts')
host1 = mock('host1')
host1.memory_mb = 4000
host2 = mock('host2')
host2.memory_mb = 3000
host3 = mock('host3')
host3.memory_mb = 3500
expect(nova.hosts).get(hostname). \
and_return([host1, host2, host3]).once()
assert manager.host_used_ram(nova, hostname) == 3500
def test_flavors_ram(self):
with MockTransaction:
nova = mock('nova')
nova.flavors = mock('flavors')
fl1 = mock('fl1')
fl1.id = '1'
fl1.ram = 1000
fl2 = mock('fl2')
fl2.id = '2'
fl2.ram = 2000
expect(nova.flavors).list().and_return([fl1, fl2]).once()
assert manager.flavors_ram(nova) == {'1': 1000, '2': 2000}
def test_vms_ram_limit(self):
with MockTransaction:
nova = mock('nova')
nova.servers = mock('servers')
flavors_to_ram = {'1': 512, '2': 1024}
expect(manager).flavors_ram(nova). \
and_return(flavors_to_ram).once()
vm1 = mock('vm1')
vm1.flavor = {'id': '1'}
vm2 = mock('vm2')
vm2.flavor = {'id': '2'}
expect(nova.servers).get('vm1').and_return(vm1).once()
expect(nova.servers).get('vm2').and_return(vm2).once()
assert manager.vms_ram_limit(nova, ['vm1', 'vm2']) == \
{'vm1': 512, 'vm2': 1024}
def test_switch_hosts_off(self):
db = db_utils.init_db('sqlite:///:memory:')
with MockTransaction:
expect(subprocess).call('ssh h1 "sleep"', shell=True).once()
expect(subprocess).call('ssh h2 "sleep"', shell=True).once()
expect(db).insert_host_states({
'h1': 0,
'h2': 0}).once()
manager.switch_hosts_off(db, 'sleep', ['h1', 'h2'])
with MockTransaction:
expect(subprocess).call.never()
expect(db).insert_host_states({
'h1': 0,
'h2': 0}).once()
manager.switch_hosts_off(db, '', ['h1', 'h2'])
def test_switch_hosts_on(self):
db = db_utils.init_db('sqlite:///:memory:')
with MockTransaction:
expect(subprocess).call('ether-wake mac1', shell=True).once()
expect(subprocess).call('ether-wake mac2', shell=True).once()
expect(manager).host_mac('h1').and_return('mac1').once()
expect(db).insert_host_states({
'h1': 1,
'h2': 1}).once()
manager.switch_hosts_on(db, {'h2': 'mac2'}, ['h1', 'h2'])
with MockTransaction:
expect(subprocess).call('ether-wake mac1', shell=True).once()
expect(subprocess).call('ether-wake mac2', shell=True).once()
expect(manager).host_mac('h1').and_return('mac1').once()
expect(manager).host_mac('h2').and_return('mac2').once()
expect(db).insert_host_states({
'h1': 1,
'h2': 1}).once()
manager.switch_hosts_on(db, {}, ['h1', 'h2'])