Use testr and flake8.

Change-Id: I748a0f54416ca540153ed5a9e7edfff739acaaea
This commit is contained in:
Monty Taylor 2013-06-16 16:24:15 -04:00
parent 7cb7093b2e
commit f5aaf25aa4
12 changed files with 70 additions and 37 deletions

1
.gitignore vendored
View File

@ -16,3 +16,4 @@ nosetests.xml
.DS_Store
build/
dist/
.testrepository

4
.testr.conf Normal file
View File

@ -0,0 +1,4 @@
[DEFAULT]
test_command=${PYTHON:-python} -m subunit.run discover -t . ./tests $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list

View File

@ -35,6 +35,7 @@ DEVSTACK_GATE_SECURE_CONFIG = os.environ.get('DEVSTACK_GATE_SECURE_CONFIG',
'~/devstack-gate-secure.conf'))
SKIP_DEVSTACK_GATE_JENKINS = os.environ.get('SKIP_DEVSTACK_GATE_JENKINS', None)
def check_machine(jenkins, machine):
utils.log.debug("Check ID: %s" % machine.id)
@ -54,6 +55,7 @@ def check_machine(jenkins, machine):
machine.delete()
def main():
db = vmdatabase.VMDatabase()

View File

@ -36,6 +36,7 @@ UPSTREAM_JOB_NAME=os.environ.get('UPSTREAM_JOB_NAME', '')
UPSTREAM_BRANCH=os.environ.get('UPSTREAM_BRANCH', '')
BUILD_URL=os.environ.get('BUILD_URL', '')
def main():
db = vmdatabase.VMDatabase()

View File

@ -31,8 +31,7 @@ def main(threshold, stat_file):
for provider in db.getProviders():
for base_image in provider.base_images:
ready_nodes = [x for x in base_image.machines \
if x.state == ready]
ready_nodes = [x for x in base_image.machines if x.state == ready]
ready_count = len(ready_nodes)
set_vm_state(ready_count, stat_file)
@ -55,7 +54,7 @@ def usage(msg=None):
stream = sys.stderr
else:
stream = sys.stdout
stream.write("usage: %s [-h] -t threshold [-f stat-file]\n" \
stream.write("usage: %s [-h] -t threshold [-f stat-file]\n"
% os.path.basename(sys.argv[0]))
if msg:
stream.write("\nERROR: " + msg + "\n")

View File

@ -7,11 +7,12 @@ from jenkins import JenkinsException, NODE_TYPE, CREATE_NODE
TOGGLE_OFFLINE = '/computer/%(name)s/toggleOffline?offlineMessage=%(msg)s'
CONFIG_NODE = '/computer/%(name)s/config.xml'
class Jenkins(jenkins.Jenkins):
def disable_node(self, name, msg=''):
'''
Disable a node
@param name: Jenkins node name
@type name: str
@param msg: Offline message
@ -25,7 +26,7 @@ class Jenkins(jenkins.Jenkins):
def enable_node(self, name):
'''
Enable a node
@param name: Jenkins node name
@type name: str
'''
@ -38,7 +39,7 @@ class Jenkins(jenkins.Jenkins):
def get_node_config(self, name):
'''
Get the configuration for a node.
:param name: Jenkins node name, ``str``
'''
get_config_url = self.server + CONFIG_NODE%locals()
@ -47,7 +48,7 @@ class Jenkins(jenkins.Jenkins):
def reconfig_node(self, name, config_xml):
'''
Change the configuration for an existing node.
:param name: Jenkins node name, ``str``
:param config_xml: New XML configuration, ``str``
'''
@ -68,7 +69,7 @@ class Jenkins(jenkins.Jenkins):
@param remoteFS: Remote filesystem location to use
@type remoteFS: str
@param labels: Labels to associate with node
@type labels: str
@type labels: str
@param exclusive: Use this node for tied jobs only
@type exclusive: boolean
@param launcher: The launch method for the slave
@ -78,7 +79,7 @@ class Jenkins(jenkins.Jenkins):
'''
if self.node_exists(name):
raise JenkinsException('node[%s] already exists'%(name))
mode = 'NORMAL'
if exclusive:
mode = 'EXCLUSIVE'
@ -87,7 +88,7 @@ class Jenkins(jenkins.Jenkins):
#hudson.slaves.CommandLauncher
#hudson.os.windows.ManagedWindowsServiceLauncher
launcher_params['stapler-class'] = launcher
inner_params = {
'name' : name,
'nodeDescription' : nodeDescription,
@ -100,13 +101,13 @@ class Jenkins(jenkins.Jenkins):
'nodeProperties' : { 'stapler-class-bag' : 'true' },
'launcher' : launcher_params
}
params = {
'name' : name,
'type' : NODE_TYPE,
'json' : json.dumps(inner_params)
}
self.jenkins_open(urllib2.Request(self.server + CREATE_NODE%urllib.urlencode(params)))
if not self.node_exists(name):

View File

@ -21,6 +21,7 @@
import paramiko
import sys
class SSHClient(object):
def __init__(self, ip, username, password=None, pkey=None):
client = paramiko.SSHClient()
@ -47,5 +48,3 @@ class SSHClient(object):
ftp = self.client.open_sftp()
ftp.put(source, dest)
ftp.close()

0
tests/__init__.py Normal file
View File

View File

@ -18,13 +18,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import vmdatabase
import time
class testVMDatabase(unittest.TestCase):
import testtools
from testtools import content
import vmdatabase
class TestVMDatabase(testtools.TestCase):
def setUp(self):
super(TestVMDatabase, self).setUp()
self.db = vmdatabase.VMDatabase(':memory:')
def test_add_provider(self):
@ -41,7 +46,7 @@ class testVMDatabase(unittest.TestCase):
def test_add_base_image(self):
self.test_add_provider()
provider = self.db.getProvider('rackspace')
base_image1 = provider.newBaseImage('oneiric', 1)
base_image2 = provider.newBaseImage('precise', 2)
@ -54,13 +59,13 @@ class testVMDatabase(unittest.TestCase):
self.test_add_base_image()
provider = self.db.getProvider('rackspace')
base_image1 = provider.getBaseImage('oneiric')
base_image2 = provider.getBaseImage('precise')
base_image2 = provider.getBaseImage('precise')
snapshot_image1 = base_image1.newSnapshotImage('oneiric-1331683549', 1331683549, 201, 301)
snapshot_image2 = base_image2.newSnapshotImage('precise-1331683549', 1331683549, 202, 301)
hp_provider = self.db.getProvider('hpcloud')
hp_base_image1 = hp_provider.getBaseImage('oneiric')
hp_base_image2 = hp_provider.getBaseImage('precise')
hp_base_image2 = hp_provider.getBaseImage('precise')
hp_snapshot_image1 = hp_base_image1.newSnapshotImage('oneiric-1331683549', 1331929410, 211, 311)
hp_snapshot_image2 = hp_base_image2.newSnapshotImage('precise-1331683549', 1331929410, 212, 311)
@ -79,7 +84,7 @@ class testVMDatabase(unittest.TestCase):
assert(snapshot_image1 == base_image1.current_snapshot)
assert(snapshot_image2 == base_image2.current_snapshot)
snapshot_image2_latest = base_image2.newSnapshotImage('precise-1331683550',
snapshot_image2_latest = base_image2.newSnapshotImage('precise-1331683550',
1331683550, 203, 303)
assert(base_image1.current_snapshot)
assert(base_image2.current_snapshot)
@ -195,25 +200,25 @@ class testVMDatabase(unittest.TestCase):
assert(len(hp_provider.ready_machines)==2)
machine = self.db.getMachineForUse('oneiric')
print 'got machine', machine.name
self.addDetail('machine name', content.text_content(machine.name))
assert(len(rs_provider.ready_machines)==1)
assert(len(hp_provider.ready_machines)==2)
assert(machine==machine1)
machine = self.db.getMachineForUse('oneiric')
print 'got machine', machine.name
self.addDetail('machine name', content.text_content(machine.name))
assert(len(rs_provider.ready_machines)==1)
assert(len(hp_provider.ready_machines)==1)
assert(machine==hp_machine1)
machine = self.db.getMachineForUse('precise')
print 'got machine', machine.name
self.addDetail('machine name', content.text_content(machine.name))
assert(len(rs_provider.ready_machines)==1)
assert(len(hp_provider.ready_machines)==0)
assert(machine==hp_machine2)
machine = self.db.getMachineForUse('precise')
print 'got machine', machine.name
self.addDetail('machine name', content.text_content(machine.name))
assert(len(rs_provider.ready_machines)==0)
assert(len(hp_provider.ready_machines)==0)
assert(machine==machine2)
@ -223,7 +228,7 @@ class testVMDatabase(unittest.TestCase):
self.db.print_state()
machine = self.db.getMachineForUse('oneiric')
print 'got machine', machine.name
self.addDetail('machine name', content.text_content(machine.name))
result = machine.newResult('test-job', 82, 1234, 1)
time.sleep(2)
result.setResult(vmdatabase.RESULT_SUCCESS)
@ -245,4 +250,3 @@ class testVMDatabase(unittest.TestCase):
assert(result.gerrit_patchset_number == 1)
else:
assert(len(base_image.results)==0)

View File

@ -1,8 +1,10 @@
# Testing
coverage # computes code coverage percentages
mox # mock object framework
nose # for test discovery and console feedback
nosexcover
pylint # static code analysis
pep8==0.6.1 # checks for PEP8 code style compliance
unittest2 # backport of unittest lib in python 2.7
# Install bounded pep8/pyflakes first, then let flake8 install
hacking>=0.5.3,<0.6
coverage>=3.6
discover
python-subunit
testrepository>=0.0.13
testtools>=0.9.27

15
tox.ini
View File

@ -2,11 +2,20 @@
envlist = py26,py27,pep8
[testenv]
setenv = VIRTUAL_ENV={envdir}
deps = -r{toxinidir}/tools/pip-requires
-r{toxinidir}/tools/test-requires
commands = nosetests {posargs}
commands =
python setup.py testr --slowest --testr-args='{posargs}'
[testenv:pep8]
deps = pep8
commands = pep8 --count --repeat --show-source --exclude=.tox setup.py .
commands = flake8
[testenv:cover]
commands =
python setup.py testr --coverage
[flake8]
exclude = .git,.tox,dist,*egg,build,v1_0
show-source = True
ignore = E12,E2,E501,F,H

View File

@ -39,6 +39,7 @@ handler = logging.handlers.SysLogHandler(address = '/dev/log')
handler.setFormatter(logging.Formatter("devstack-gate: %(message)s"))
log.addHandler(handler)
def iterate_timeout(max_seconds, purpose):
start = time.time()
count = 0
@ -71,6 +72,8 @@ def get_client(provider):
return client
extension_cache = {}
def get_extensions(client):
global extension_cache
cache = extension_cache.get(client)
@ -84,11 +87,13 @@ def get_extensions(client):
extension_cache[client] = extensions
return extensions
def get_flavor(client, min_ram):
flavors = [f for f in client.flavors.list() if f.ram >= min_ram]
flavors.sort(lambda a, b: cmp(a.ram, b.ram))
return flavors[0]
def get_public_ip(server, version=4):
if 'os-floating-ips' in get_extensions(server.manager.api):
print 'using floating ips'
@ -109,6 +114,7 @@ def get_public_ip(server, version=4):
return addr['addr']
return None
def add_public_ip(server):
ip = server.manager.api.floating_ips.create()
print "created floating ip", ip
@ -125,12 +131,14 @@ def add_public_ip(server):
print 'ip has been added'
return
def add_keypair(client, name):
key = paramiko.RSAKey.generate(2048)
public_key = key.get_name() + ' ' + key.get_base64()
kp = client.keypairs.create(name, public_key)
return key, kp
def wait_for_resource(wait_resource):
last_progress = None
last_status = None
@ -154,6 +162,7 @@ def wait_for_resource(wait_resource):
if resource.status == 'ACTIVE':
return resource
def ssh_connect(ip, username, connect_kwargs={}, timeout=60):
# HPcloud may return errno 111 for about 30 seconds after adding the IP
for count in iterate_timeout(timeout, "ssh access"):
@ -168,6 +177,7 @@ def ssh_connect(ip, username, connect_kwargs={}, timeout=60):
return client
return None
def delete_server(server):
try:
if 'os-floating-ips' in get_extensions(server.manager.api):
@ -191,6 +201,7 @@ def delete_server(server):
print "Deleting server", server.id
server.delete()
def update_stats(provider):
state_names = {
vmdatabase.BUILDING: 'building',