00001
00002
00003 STACK_DIR = 'stack_overlay'
00004 DEPENDS_DIR = 'depends_overlay'
00005 DEPENDS_ON_DIR = 'depends_on_overlay'
00006
00007
00008 import roslib; roslib.load_manifest("job_generation")
00009 from roslib import stack_manifest
00010 import rosdistro
00011 from jobs_common import *
00012 from apt_parser import parse_apt
00013 import sys
00014 import os
00015 import optparse
00016 import subprocess
00017 import traceback
00018
00019
00020 def remove(list1, list2):
00021 for l in list2:
00022 if l in list1:
00023 list1.remove(l)
00024
00025
00026 def main():
00027
00028 try:
00029 print "Parsing arguments"
00030
00031
00032 (options, args) = get_options(['stack', 'rosdistro'], ['repeat', 'source-only'])
00033 print "options", options, "args", args
00034 if not options:
00035 return -1
00036
00037
00038 print "Setting up environment"
00039 env = get_environment()
00040 env['ROS_PACKAGE_PATH'] = '%s:%s:%s:/opt/ros/%s/stacks'%(env['INSTALL_DIR']+'/'+STACK_DIR,
00041 env['INSTALL_DIR']+'/'+DEPENDS_DIR,
00042 env['INSTALL_DIR']+'/'+DEPENDS_ON_DIR,
00043 options.rosdistro)
00044 if 'ros' in options.stack:
00045 env['ROS_ROOT'] = env['INSTALL_DIR']+'/'+STACK_DIR+'/ros'
00046 print "We're building ROS, so setting the ROS_ROOT to %s"%(env['ROS_ROOT'])
00047 ros_tested_ignore_return = True
00048 else:
00049 env['ROS_ROOT'] = '/opt/ros/%s/ros'%options.rosdistro
00050 ros_tested_ignore_return = False
00051 env['PYTHONPATH'] = env['ROS_ROOT']+'/core/roslib/src'
00052 env['PATH'] = '/opt/ros/%s/ros/bin:%s'%(options.rosdistro, os.environ['PATH'])
00053 print "Environment set to %s"%str(env)
00054
00055
00056 rosdistro_obj = rosdistro.Distro(get_rosdistro_file(options.rosdistro))
00057 print 'Operating on ROS distro %s'%rosdistro_obj.release_name
00058
00059
00060 print 'Installing the stacks to test from source'
00061 rosinstall = ''
00062 for stack in options.stack:
00063 rosinstall += stack_to_rosinstall(rosdistro_obj.stacks[stack], 'devel')
00064 rosinstall_file = '%s.rosinstall'%STACK_DIR
00065 print 'Generating rosinstall file [%s]'%(rosinstall_file)
00066 print 'Contents:\n\n'+rosinstall+'\n\n'
00067 with open(rosinstall_file, 'w') as f:
00068 f.write(rosinstall)
00069 print 'rosinstall file [%s] generated'%(rosinstall_file)
00070
00071
00072 call('rosinstall --rosdep-yes %s /opt/ros/%s %s'%(STACK_DIR, options.rosdistro, rosinstall_file), env,
00073 'Install the stacks to test from source.', ignore_fail = ros_tested_ignore_return)
00074
00075
00076
00077 print "Computing dependencies of stacks we're testing"
00078 depends_all = []
00079 for stack in options.stack:
00080 stack_xml = '%s/%s/stack.xml'%(STACK_DIR, stack)
00081 call('ls %s'%stack_xml, env, 'Checking if stack %s contains "stack.xml" file'%stack)
00082 with open(stack_xml) as stack_file:
00083 depends_one = [str(d) for d in stack_manifest.parse(stack_file.read()).depends]
00084 print 'Dependencies of stack %s: %s'%(stack, str(depends_one))
00085 for d in depends_one:
00086 if not d in options.stack and not d in depends_all:
00087 print 'Adding dependencies of stack %s'%d
00088 get_depends_all(rosdistro_obj, d, depends_all)
00089 print 'Resulting total dependencies of all stacks that get tested: %s'%str(depends_all)
00090
00091 if len(depends_all) > 0:
00092 if options.source_only:
00093
00094 print 'Installing stack dependencies from source'
00095 rosinstall = stacks_to_rosinstall(depends_all, rosdistro_obj.released_stacks, 'release-tar')
00096 rosinstall_file = '%s.rosinstall'%DEPENDS_DIR
00097 print 'Generating rosinstall file [%s]'%(rosinstall_file)
00098 print 'Contents:\n\n'+rosinstall+'\n\n'
00099 with open(rosinstall_file, 'w') as f:
00100 f.write(rosinstall)
00101 print 'rosinstall file [%s] generated'%(rosinstall_file)
00102 call('rosinstall --rosdep-yes %s /opt/ros/%s %s'%(DEPENDS_DIR, options.rosdistro, rosinstall_file), env,
00103 'Install the stack dependencies from source.', ignore_fail = ros_tested_ignore_return)
00104 else:
00105
00106 print 'Installing debian packages of "%s" dependencies: %s'%(stack, str(depends_all))
00107 call('sudo apt-get update', env)
00108 call('sudo apt-get install %s --yes'%(stacks_to_debs(depends_all, options.rosdistro)), env)
00109 else:
00110 print 'Stack(s) %s do(es) not have any dependencies, not installing anything now'%str(options.stack)
00111
00112
00113
00114 print "Installing system dependencies of stacks we're testing"
00115 call('rosmake rosdep', env)
00116 for stack in options.stack:
00117 call('rosdep install -y %s'%stack, env,
00118 'Install system dependencies of stack %s'%stack)
00119
00120
00121
00122 print "Running Hudson Helper for stacks we're testing"
00123 res = 0
00124 for r in range(0, int(options.repeat)+1):
00125 env['ROS_TEST_RESULTS_DIR'] = env['ROS_TEST_RESULTS_DIR'] + '/' + STACK_DIR + '_run_' + str(r)
00126 helper = subprocess.Popen(('./hudson_helper --dir-test %s build'%STACK_DIR).split(' '), env=env)
00127 helper.communicate()
00128 if helper.returncode != 0:
00129 res = helper.returncode
00130 if res != 0:
00131 return res
00132
00133
00134
00135 (arch, ubuntudistro) = get_sys_info()
00136 print "Parsing apt repository configuration file to get stack dependencies, for %s machine running %s"%(arch, ubuntudistro)
00137 apt_deps = parse_apt(ubuntudistro, arch, options.rosdistro)
00138 if not apt_deps.has_debian_package(options.stack):
00139 print "Stack does not yet have a Debian package. No need to test dependenies"
00140 return 0
00141
00142
00143 depends_on_all = apt_deps.depends_on_all(options.stack)
00144 remove(depends_on_all, options.stack)
00145
00146
00147 variant_stacks = []
00148 for name, v in rosdistro_obj.variants.iteritems():
00149 variant_stacks = variant_stacks + v.stack_names
00150 all_in_variant = True
00151 for s in options.stack:
00152 if not s in variant_stacks:
00153 all_in_variant = False
00154 if all_in_variant:
00155 print "Limiting test to stacks that are in a variant"
00156 for s in depends_on_all:
00157 if not s in variant_stacks:
00158 depends_on_all.remove(s)
00159
00160
00161 depends_all_depends_on_all = apt_deps.depends_all(depends_on_all)
00162 remove(depends_all_depends_on_all, options.stack)
00163 remove(depends_all_depends_on_all, depends_all)
00164
00165
00166
00167 if len(depends_all_depends_on_all) > 0:
00168 print "Install dependencies of depends_on_all stacks, excluding dependencies of test stacks."
00169 if not options.source_only:
00170
00171 print 'Installing Debian package of %s'%str(depends_all_depends_on_all)
00172 call('sudo apt-get install %s --yes'%(stacks_to_debs(depends_all_depends_on_all, options.rosdistro)), env)
00173 else:
00174
00175 print 'Installing source of %s'%str(depends_all_depends_on_all)
00176 rosinstall = stacks_to_rosinstall(depends_all_depends_on_all, rosdistro_obj.released_stacks, 'release-tar')
00177 rosinstall_file = '%s_depends_all_depends_on_all.rosinstall'%DEPENDS_ON_DIR
00178 print 'Generating rosinstall file [%s]'%(rosinstall_file)
00179 print 'Contents:\n\n'+rosinstall+'\n\n'
00180 with open(rosinstall_file, 'w') as f:
00181 f.write(rosinstall)
00182 print 'rosinstall file [%s] generated'%(rosinstall_file)
00183 call('rosinstall --rosdep-yes %s /opt/ros/%s %s %s'%(DEPENDS_ON_DIR, options.rosdistro, STACK_DIR, rosinstall_file), env,
00184 'Install dependencies of depends_on_all stacks, excluding dependencies of test stacks.', ignore_fail = ros_tested_ignore_return)
00185 else:
00186 print "No dependencies of depends_on_all stacks"
00187
00188
00189
00190 if len(depends_on_all) > 0:
00191 print 'Installing depends_on_all stacks from source: %s'%str(depends_on_all)
00192 rosinstall = stacks_to_rosinstall(depends_on_all, rosdistro_obj.released_stacks, 'release-tar')
00193 rosinstall_file = '%s.rosinstall'%DEPENDS_ON_DIR
00194 print 'Generating rosinstall file [%s]'%(rosinstall_file)
00195 print 'Contents:\n\n'+rosinstall+'\n\n'
00196 with open(rosinstall_file, 'w') as f:
00197 f.write(rosinstall)
00198 print 'rosinstall file [%s] generated'%(rosinstall_file)
00199 call('rosinstall --rosdep-yes %s /opt/ros/%s %s %s'%(DEPENDS_ON_DIR, options.rosdistro, STACK_DIR, rosinstall_file), env,
00200 'Install the stacks that depend on the stacks that are getting tested from source.', ignore_fail = ros_tested_ignore_return)
00201
00202
00203 print 'Running Hudson Helper'
00204 env['ROS_TEST_RESULTS_DIR'] = env['ROS_TEST_RESULTS_DIR'] + '/' + DEPENDS_ON_DIR
00205 helper = subprocess.Popen(('./hudson_helper --dir-test %s build'%DEPENDS_ON_DIR).split(' '), env=env)
00206 helper.communicate()
00207 return helper.returncode
00208 else:
00209 print "No stacks depends on this stack. Tests finished"
00210
00211
00212
00213 except Exception, ex:
00214 print "Global exception caught. Generating email. Exception:", ex
00215 generate_email("%s. Check the console output for test failure details."%ex, env)
00216 traceback.print_exc(file=sys.stdout)
00217 raise ex
00218
00219
00220 if __name__ == '__main__':
00221 try:
00222 res = main()
00223 sys.exit( res )
00224 except Exception, ex:
00225 sys.exit(-1)
00226
00227
00228
00229
00230
00231