Tests for update_config.py

These are failing on my machine with cloud.log lines like

  2014-08-07 14:34:09,509 Add dev eth2 table Table_eth2 10.0.2.0/24
  2014-08-07 14:34:09,511 Address 10.0.2.106/24 on device eth2 not configured
  2014-08-07 14:34:10,513 Device eth2 cannot be configured - device was not found

I think it's correct that they are failing -- this is work in progress.
This commit is contained in:
Leo Simons 2014-08-07 16:36:16 +02:00 committed by wilderrodrigues
parent 295e2caff0
commit 712fa9c92c
4 changed files with 172 additions and 16 deletions

View File

@ -43,6 +43,8 @@ except (NameError, ImportError):
return output
subprocess.check_output = check_output
import logging
logging.getLogger('paramiko.transport').setLevel(logging.WARNING)
from vagrant import Vagrant
from unittest import TestCase
@ -57,6 +59,7 @@ from StringIO import StringIO
from nose.plugins.attrib import attr
import os.path
import sys
_defaultVagrantDir = os.path.abspath(os.path.join(
@ -180,7 +183,36 @@ class SystemVMTestCase(TestCase):
# env.host_string = self._env_host_string_orig
def has_line(location, line):
def has_line(location, line, ctx=3):
with hide("everything"):
text = run('cat "%s"' % location)
return text.find(line) >= 0
text_len = len(text)
pos = text.find(line)
if pos < 0:
return False, ''
start = end = pos
newlines = 0
while start > 0:
if text[start] == '\n':
newlines += 1
if newlines > ctx:
break
start -= 1
newlines = 0
while end < text_len:
if text[end] == '\n':
newlines += 1
if newlines > ctx:
break
end += 1
context = '...\n' + text[start:end].strip() + '\n...'
return True, context
def print_doc(name, data, target=None):
if target is None:
target = sys.stdout
print >>target, " ", "-" * 4, name, "-" * max(68-4-2-len(name), 0)
for line in data.split('\n'):
print >>target, " ", line
print >>target, " ", "-" * 68

View File

@ -17,35 +17,38 @@
"""Example of using paramiko and envassert for systemvm tests."""
from nose.plugins.attrib import attr
# from nose.plugins.attrib import attr
from envassert import file, package, user
from cuisine import file_write
try:
from . import SystemVMTestCase, has_line
from . import SystemVMTestCase, has_line, print_doc
except (ImportError, ValueError):
from systemvm import SystemVMTestCase, has_line
from systemvm import SystemVMTestCase, has_line, print_doc
class HelloSystemVMTestCase(SystemVMTestCase):
@attr(tags=["systemvm"], required_hardware="true")
def test_hello_systemvm_paramiko(self):
# @attr(tags=["systemvm"], required_hardware="true")
def disabled_hello_systemvm_paramiko(self):
"""Test we can connect to the systemvm over ssh, low-level with paramiko"""
stdin, stdout, stderr = self.sshClient.exec_command('echo hello')
result = stdout.read().strip()
self.assertEqual('hello', result)
@attr(tags=["systemvm"], required_hardware="true")
def test_hello_systemvm_envassert(self):
# @attr(tags=["systemvm"], required_hardware="true")
def disabled_test_hello_systemvm_envassert(self):
"""Test we can run envassert assertions on the systemvm"""
assert file.exists('/etc/hosts')
for packageName in ['dnsmasq', 'haproxy', 'keepalived', 'curl']:
assert package.installed(packageName)
assert package.installed(packageName), 'package %s should be installed' % packageName
assert user.exists('cloud')
assert user.exists('cloud'), 'user cloud should exist'
@attr(tags=["systemvm"], required_hardware="true")
def test_hello_systemvm_cuisine(self):
# @attr(tags=["systemvm"], required_hardware="true")
def disabled_hello_systemvm_cuisine(self):
"""Test we can run cuisine on the systemvm"""
file_write('/tmp/run_cuisine', '\n\nsuccess!\n')
assert has_line('/tmp/run_cuisine', 'success!')
found, context = has_line('/tmp/run_cuisine', 'success!')
if not found:
print_doc('/tmp/cuisine', context)
assert found, '/tmp/run_cuisine should contain "success!"'

View File

@ -0,0 +1,120 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
"""Basic integration test that runs update_config.py."""
from nose.plugins.attrib import attr
from cuisine import file_write, run
from fabric.api import hide
import json
import random
import datetime
try:
from . import SystemVMTestCase, has_line, print_doc
except (ImportError, ValueError):
from systemvm import SystemVMTestCase, has_line, print_doc
def deep_copy(obj):
return json.loads(json.dumps(obj))
class UpdateConfigTestCase(SystemVMTestCase):
basic_config = {
"ip_address": [
{
"public_ip": "10.0.2.102",
"source_nat": True,
"add": True,
"one_to_one_nat": False,
"first_i_p": False,
"gateway": "10.0.2.1",
"netmask": "255.255.255.0",
"vif_mac_address": "06:cb:aa:00:00:03",
"nic_dev_id": 1,
"new_nic": False
}
],
"type": "ips"
}
def update_config(self, config):
config_json = json.dumps(config, indent=2)
print_doc('config.json', config_json)
file_write('/etc/cloudstack/update_config_test.json', config_json)
with hide("everything"):
result = run("python /opt/cloud/bin/update_config.py update_config_test.json",
timeout=600, warn_only=True)
print result
assert result.succeeded, 'update_config.py ran without errors'
assert result.find("Convergence is achieved") >= 0, 'update_config.py should report convergence'
def clear_log(self):
tstamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
run("test -f /var/log/cloud.log && mv /var/log/cloud.log /var/log/cloud.log.%s || true" % tstamp)
def setUp(self):
super(UpdateConfigTestCase, self).setUp()
self.clear_log()
def check_no_errors(self):
# todo config update should exit 1 on convergence errors!
found, context = has_line('/var/log/cloud.log', 'cannot be configured')
if found:
print_doc('/var/log/cloud.log', context)
assert not found, 'cloud.log should not contain "cannot be configured"'
@attr(tags=["systemvm"], required_hardware="true")
def test_basic_config(self):
self.update_config(self.basic_config)
self.check_no_errors()
# should be able to run twice with same config
self.clear_log()
self.update_config(self.basic_config)
self.check_no_errors()
@attr(tags=["systemvm"], required_hardware="true")
def test_various_random_ip_addresses(self):
r = random.Random()
r.seed()
for i in range(0, 10):
# todo need to know what kind of configurations are valid!
config = deep_copy(self.basic_config)
ip_address = deep_copy(self.basic_config["ip_address"][0])
ip_address["public_ip"] = "10.0.2.%d" % (i + 103,)
ip_address["source_nat"] = r.choice((True, False))
ip_address["add"] = r.choice((True, False))
ip_address["one_to_one_nat"] = r.choice((True, False))
ip_address["first_i_p"] = r.choice((True, False))
ip_address["nic_dev_id"] = r.choice((0, 1, 2))
if ip_address["nic_dev_id"] > 0:
ip_address["new_nic"] = True
else:
ip_address["new_nic"] = False
config["ip_address"].append(ip_address)
# runs a bunch of times adding an IP address each time
self.update_config(config)
self.check_no_errors()
self.clear_log()
# run again with just the basic config; this should remove the IP addresses?
self.update_config(self.basic_config)
if __name__ == '__main__':
import unittest
unittest.main()

View File

@ -78,8 +78,9 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
'config/opt' => '/opt',
'config/root' => '/root',
'config/var' => '/var',
'vpn/etc' => '/etc',
'vpn/opt' => '/opt',
# cannot have two rsyncs pointing to the same dir
# 'vpn/etc' => '/etc',
# 'vpn/opt' => '/opt',
'xe' => '/usr/sbin'
}