Skip to content
This repository has been archived by the owner on Sep 15, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Bug 810439 - mozharness support for mozpool. r=aki
  • Loading branch information
jhopkinsmoz committed Dec 4, 2012
1 parent 3f722e5 commit ed4a254
Show file tree
Hide file tree
Showing 13 changed files with 1,152 additions and 5 deletions.
21 changes: 21 additions & 0 deletions configs/b2g/panda_releng.py
@@ -0,0 +1,21 @@
# This is a template config file for gaia smoketests production.

config = {
# Values for the foopies
"exes": {
'python': '/tools/buildbot/bin/python',
'virtualenv': ['/tools/buildbot/bin/python', '/tools/misc-python/virtualenv.py'],
},
"virtualenv_path": "venv",
"find_links": ["http://puppetagain.pub.build.mozilla.org/data/python/packages"],
"buildbot_json_path": "buildprops.json",
"mozpool_api_url": "http://mobile-imaging-001.p1.releng.scl1.mozilla.com",
"default_actions": [
'clobber',
#'read-buildbot-config',
'create-virtualenv',
'request-device',
'run-test',
'close-request',
],
}
4 changes: 3 additions & 1 deletion mozharness/base/script.py
Expand Up @@ -582,7 +582,9 @@ def get_output_from_command(self, command, cwd=None,
shell = False
p = subprocess.Popen(command, shell=shell, stdout=tmp_stdout,
cwd=cwd, stderr=tmp_stderr, env=env)
self.debug("Temporary files: %s and %s" % (tmp_stdout_filename, tmp_stderr_filename))
#XXX: changed from self.debug to self.log due to this error:
# TypeError: debug() takes exactly 1 argument (2 given)
self.log("Temporary files: %s and %s" % (tmp_stdout_filename, tmp_stderr_filename), level=DEBUG)
p.wait()
tmp_stdout.close()
tmp_stderr.close()
Expand Down
488 changes: 488 additions & 0 deletions mozharness/mozilla/testing/mozpool.py

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions mpunit.sh
@@ -0,0 +1,76 @@
#!/bin/bash

set -x

###########################################################################
# This requires coverage and nosetests:
#
# easy_install coverage
# easy_install nose
# easy_install pylint
# easy_install pyflakes
#
# test_base_vcs_mercurial.py requires hg >= 1.6.0 with mq, rebase, share
# extensions to fully test.
###########################################################################

# this breaks mercurial unit tests
unset HG_SHARE_BASE_DIR

COVERAGE_ARGS="--omit='/usr/*,/opt/*'"
OS_TYPE='linux'
uname -v | grep -q Darwin
if [ $? -eq 0 ] ; then
OS_TYPE='osx'
COVERAGE_ARGS="--omit='/Library/*,/usr/*,/opt/*'"
fi
uname -s | egrep -q MINGW32 # Cygwin will be linux in this case?
if [ $? -eq 0 ] ; then
OS_TYPE='windows'
fi
NOSETESTS=`env which nosetests`

#echo "### Finding mozharness/ .py files..."
#files=`find mozharness -name [a-z]\*.py`
#if [ $OS_TYPE == 'windows' ] ; then
# MOZHARNESS_PY_FILES=""
# for f in $files; do
# file $f | grep -q "Assembler source"
# if [ $? -ne 0 ] ; then
# MOZHARNESS_PY_FILES="$MOZHARNESS_PY_FILES $f"
# fi
# done
#else
# MOZHARNESS_PY_FILES=$files
#fi
echo "### Finding scripts/ .py files..."
files=`find scripts -name [a-z]\*.py`
if [ $OS_TYPE == 'windows' ] ; then
SCRIPTS_PY_FILES=""
for f in $files; do
file $f | grep -q "Assembler source"
if [ $? -ne 0 ] ; then
SCRIPTS_PY_FILES="$SCRIPTS_PY_FILES $f"
fi
done
else
SCRIPTS_PY_FILES=$files
fi
export PYTHONPATH=`env pwd`:$PYTHONPATH

rm -rf logs
#rm -rf build logs
if [ ! -d build ]; then
virtualenv-2.7 --no-site-packages build/venv
build/venv/bin/pip install requests
fi

if [ $OS_TYPE != 'windows' ] ; then
echo "### Testing mozpool unit tests"
coverage run -a --branch $COVERAGE_ARGS $NOSETESTS test/mozpool/test_*.py
echo "### Running *.py [--list-actions]"
else
echo "### Running nosetests..."
nosetests
fi
#rm -rf build logs
152 changes: 152 additions & 0 deletions scripts/b2g_panda.py
@@ -0,0 +1,152 @@
#!/usr/bin/env python
# ***** BEGIN LICENSE BLOCK *****
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
# ***** END LICENSE BLOCK *****

import os
import sys
from time import sleep

# load modules from parent dir
sys.path.insert(1, os.path.dirname(sys.path[0]))

from mozharness.mozilla.buildbot import TBPL_SUCCESS, TBPL_WARNING, TBPL_FAILURE, TBPL_RETRY, BuildbotMixin
from mozharness.base.python import VirtualenvMixin
from mozharness.base.script import BaseScript
from mozharness.mozilla.testing.testbase import TestingMixin
from mozharness.base.log import WARNING, ERROR
from mozharness.mozilla.testing.mozpool import MozpoolMixin, MozpoolConflictException

#TODO - adjust these values
MAX_RETRIES = 20
RETRY_INTERVAL = 60
REQUEST_DURATION = 60 * 40

class PandaTest(TestingMixin, BaseScript, VirtualenvMixin, MozpoolMixin, BuildbotMixin):
config_options = [
[["--mozpool-api-url"], {
"dest": "mozpool_api_url",
"help": "Override mozpool api url",
}],
[["--mozpool-device"], {
"dest": "mozpool_device",
"help": "Set Panda device to run tests on",
}],
[["--mozpool-assignee"], {
"dest": "mozpool_assignee",
"help": "Set mozpool assignee (requestor name, free-form)",
}],
[["--mozpool-b2gbase"], {
"dest": "mozpool_b2gbase",
"help": "Set b2gbase url",
}],
]

error_list = []

mozbase_dir = os.path.join('tests', 'mozbase')
virtualenv_modules = [
'requests',
]

def __init__(self, require_config_file=False):
super(PandaTest, self).__init__(
config_options=self.config_options,
all_actions=['clobber',
'read-buildbot-config',
'create-virtualenv',
'request-device',
'run-test',
'close-request'],
default_actions=['clobber',
'create-virtualenv',
'request-device',
'run-test',
'close-request'],
require_config_file=require_config_file,
config={'virtualenv_modules': self.virtualenv_modules,
'require_test_zip': True,})

# these are necessary since self.config is read only
self.mozpool_device = self.config.get('mozpool_device')
if self.mozpool_device is None:
self.fatal('--mozpool-device is required')
self.mozpool_assignee = self.config.get('mozpool_assignee')
if self.mozpool_assignee is None:
self.mozpool_assignee = self.buildbot_config.get('properties')["slavename"]
if self.mozpool_assignee is None:
self.fatal('--mozpool-assignee is required')
self.mozpool_b2gbase = self.config.get('mozpool_b2gbase')
self.request_url = None

def retry_sleep(self, sleep_time=1, max_retries=5, error_message=None, tbpl_status=None):
for x in range(1, max_retries + 1):
yield x
sleep(sleep_time)
if error_message:
self.error(error_message)
if tbpl_status:
self.buildbot_status(tbpl_status)
self.fatal('Retries limit exceeded')

def request_device(self):
mph = self.query_mozpool_handler()
for retry in self.retry_sleep(sleep_time=RETRY_INTERVAL, max_retries=MAX_RETRIES,
error_message="INFRA-ERROR: Could not request device '%s'" % self.mozpool_device,
tbpl_status=TBPL_RETRY):
try:
duration = REQUEST_DURATION
image = 'b2g'
b2gbase = self.mozpool_b2gbase

response = mph.request_device(self.mozpool_device, self.mozpool_assignee, image, duration, \
b2gbase=b2gbase, pxe_config=None)
break
except MozpoolConflictException:
self.warning("Device unavailable. Retry#%i.." % retry)

self.request_url = response['request']['url']
self.info("Got request, url=%s" % self.request_url)
self.wait_for_request_ready()

def wait_for_request_ready(self):
mph = self.query_mozpool_handler()
for retry in self.retry_sleep(sleep_time=RETRY_INTERVAL, max_retries=MAX_RETRIES,
error_message="INFRA-ERROR: Request did not become ready in time",
tbpl_status=TBPL_RETRY):
response = mph.query_request_status(self.request_url)
state = response['state']
if state == 'ready':
return
self.info("Waiting for request 'ready' stage. Current state: '%s'" % state)

def run_test(self):
"""
Run the Panda tests
"""

'''
level = INFO
if code == 0:
status = "success"
tbpl_status = TBPL_SUCCESS
elif code == 10:
status = "test failures"
tbpl_status = TBPL_WARNING
else:
status = "harness failures"
level = ERROR
tbpl_status = TBPL_FAILURE
'''

def close_request(self):
mph = self.query_mozpool_handler()
mph.close_request(self.request_url)
print("Request '%s' deleted on cleanup" % self.request_url)
self.request_url = None

if __name__ == '__main__':
pandaTest = PandaTest()
pandaTest.run()
65 changes: 65 additions & 0 deletions scripts/mozpooltest.py
@@ -0,0 +1,65 @@
#!/usr/bin/env python
# ***** BEGIN LICENSE BLOCK *****
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
# ***** END LICENSE BLOCK *****
"""mozpooltest.py
"""

import os
import pprint
import sys

sys.path.insert(1, os.path.dirname(sys.path[0]))

from mozharness.base.python import VirtualenvMixin, virtualenv_config_options
from mozharness.base.script import BaseScript
from mozharness.mozilla.testing.mozpool import MozpoolMixin

# MozpoolTest {{{1
class MozpoolTest(VirtualenvMixin, MozpoolMixin, BaseScript):
config_options = virtualenv_config_options + [[
["--mozpool-api-url"],
{"action": "store",
"dest": "mozpool_api_url",
"help": "Specify the URL of the mozpool api"
}
]]
def __init__(self, require_config_file=False):
BaseScript.__init__(
self, config_options=self.config_options,
all_actions=[
'create-virtualenv',
'run-tests',
],
config={
'virtualenv_modules': ['requests'],
'mozpool_api_url': "http://localhost:8080",
'global_retries': 1,
},
require_config_file=require_config_file
)

def run_tests(self):
mph = self.query_mozpool_handler()
self.info("query_all_device_list()")
self.info(pprint.pformat(mph.query_all_device_list()))
self.info("query_all_device_details()")
self.info(pprint.pformat(mph.query_all_device_details()))
self.info("query_device_status('panda-0209')")
self.info(pprint.pformat(mph.query_device_status("panda-0209")))
self.info("query_device_status('ed-209')")
self.info(pprint.pformat(mph.query_device_status("ed-209")))
self.info("request_device('ed-209')")
self.info(pprint.pformat(mph.request_device("ed-209", "me", "imageX", "2d")))
self.info("request_device('any')")
device_blob = mph.request_device("any", "me", "imageX", "1s")
self.info(pprint.pformat(device_blob))


# __main__ {{{1
if __name__ == '__main__':
mozpool_test = MozpoolTest()
mozpool_test.run()
42 changes: 42 additions & 0 deletions test/mozpool/mozpoolmisc.py
@@ -0,0 +1,42 @@
import unittest

from mozharness.base.python import VirtualenvMixin, virtualenv_config_options
from mozharness.base.script import BaseScript
from mozharness.mozilla.testing.mozpool import MozpoolMixin

MIN_TEST_DEVICES = 20
# reduce limit to speed up unit test runs, increase limit to increase device coverage
MAX_DEVICES_TO_CHECK = 10
TEST_DEVICE1 = 'device1'
TEST_DEVICE2 = 'device2'
TEST_ASSIGNEE = 'test@example.com'
TEST_B2GBASE = 'https://pvtbuilds.mozilla.org/pub/mozilla.org/b2g/tinderbox-builds/mozilla-central-panda/20121127133607/'

class BaseMozpoolTest(unittest.TestCase, VirtualenvMixin, MozpoolMixin, BaseScript):

def setup(self):
self.config_options = virtualenv_config_options + [[
["--mozpool-api-url"],
{"action": "store",
"dest": "mozpool_api_url",
"help": "Specify the URL of the mozpool api"
}
]]
BaseScript.__init__(
self, config_options=self.config_options,
all_actions=[
'create-virtualenv',
'run-tests',
],
default_actions=[
'run-tests',
],
config={
'virtualenv_modules': ['requests'],
'mozpool_api_url': "http://localhost:8080",
'global_retries': 1,
},
require_config_file=False,
)
self.mph = self.query_mozpool_handler()

0 comments on commit ed4a254

Please sign in to comment.