#!/usr/bin/env python # # Run LKP test suite on Linaro ubuntu # # Copyright (C) 2012 - 2014, Linaro Limited. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # Author: Chase Qi # import os import sys import platform import glob import json import pwd import shutil from subprocess import call LKP_PATH = sys.argv[1] WD = sys.argv[2] JOB = sys.argv[3] COMMIT = sys.argv[4] LOOPS = int(sys.argv[5]) MONITORS = sys.argv[6] HOSTNAME = platform.node() ROOTFS = str.lower(platform.dist()[0]) CONFIG = 'defconfig' COMPILER = os.readlink('/usr/bin/gcc') print 'Working directory: %s' % (WD) print 'LKP test suite path: %s' % (LKP_PATH) print 'About to run %s %s times' % (JOB, LOOPS) def test_result(test_command, test_case_id): # For each step of test run, print pass or fail to test log. if call(test_command) == 0: print '%s pass' % (test_case_id) return True else: print '%s fail' % (test_case_id) return False def find_user(name): try: return pwd.getpwnam(name) except KeyError: return None # pre-config. if not find_user('lkp'): print 'creating user lkp...' call(['useradd', '--create-home', '--home-dir', '/home/lkp', 'lkp']) else: print 'User lkp already exists.' if not os.path.exists('/home/lkp'): os.makedirs('/home/lkp') call(['chown', '-R', 'lkp:lkp', '/home/lkp']) f = open('/etc/apt/sources.list.d/multiverse.list', 'w') f.write('deb http://ports.ubuntu.com/ubuntu-ports/ vivid multiverse\n') f.close() call(['apt-get', 'update']) # Setup test job. SETUP_JOB = [LKP_PATH + '/bin/setup-local', LKP_PATH + '/jobs/' + JOB + '.yaml'] print 'Setup %s test with command: %s' % (JOB, SETUP_JOB) if not test_result(SETUP_JOB, 'setup-' + JOB): sys.exit(1) # Split test job. if not os.path.exists(WD + '/' + JOB): os.makedirs(WD + '/' + JOB) if MONITORS == 'default': MONITORS = '' SPLIT_JOB = [LKP_PATH + '/sbin/split-job', MONITORS, '--kernel', COMMIT, '--output', WD + '/' + JOB, LKP_PATH + '/jobs/' + JOB + '.yaml'] print 'Splitting job %s with command: %s' % (JOB, SPLIT_JOB) if not test_result(SPLIT_JOB, 'split-job-' + JOB): sys.exit(1) # Clean result root directory. if os.path.exists('/result/'): shutil.rmtree('/result/', ignore_errors=True) # Run tests. SUB_TESTS = glob.glob(WD + '/' + JOB + '/*.yaml') for sub_test in SUB_TESTS: count = 1 done = True sub_test_case_id = os.path.basename(sub_test)[:-46] result_root = '/'.join(['/result', JOB, sub_test_case_id[int(len(JOB) + 1):], HOSTNAME, ROOTFS, CONFIG, COMPILER, COMMIT]) while count <= LOOPS: # Set suffix for mutiple runs. if LOOPS > 1: suffix = '-run' + str(count) else: suffix = '' lkp_run = [LKP_PATH + '/bin/run-local', '--set', 'compiler: ' + COMPILER, sub_test] print 'Running test %s%s with command: %s' % (sub_test_case_id, suffix, lkp_run) if not test_result(lkp_run, 'run-' + sub_test_case_id + suffix): done = False break # For each run, decode JOB.json to pick up the scores produced by the # benchmark itself. result_file = result_root + '/' + str(count - 1) + '/' + JOB + '.json' if not os.path.isfile(result_file): print '%s not found' % (result_file) else: json_data = open(result_file) dict = json.load(json_data) for item in dict: call(['lava-test-case', sub_test_case_id + '-' + item + suffix, '--result', 'pass', '--measurement', str(dict[item][0])]) json_data.close() count = count + 1 # For mutiple runs, if all runs are completed and results found, decode # avg.json. if LOOPS > 1 and done: avg_file = result_root + '/' + 'avg.json' if not os.path.isfile(result_file): print '%s not found' % (result_file) elif not os.path.isfile(avg_file): print '%s not found' % (avg_file) else: json_data = open(result_file) avg_json_data = open(avg_file) dict = json.load(json_data) avg_dict = json.load(avg_json_data) for item in dict: if item in avg_dict: call(['lava-test-case', sub_test_case_id + '-' + item + '-avg', '--result', 'pass', '--measurement', str(avg_dict[item])]) json_data.close() avg_json_data.close() # Compress and attach raw data. call(['tar', 'caf', 'lkp-result-' + JOB + '.tar.xz', '/result/' + JOB]) call(['lava-test-run-attach', 'lkp-result-' + JOB + '.tar.xz']) if not done: sys.exit(1) else: sys.exit(0)