7 running CI tests for ${proj_PREFIX}_ci.
9 --executable Define the executable to run
10 --nevents Define the number of events to process
11 --stage Define the stage number used to parse the right testmask column number
12 --fhicl Set the FHiCl file to use to run the test
13 --input-file Set the file on which you want to run the test
14 --reference-files Set the reference file used by the test, this can be a comma separated list
15 --outputs Define a list of pairs <output_stream>:<output_filename> using "," as separator
16 --stage-name Define the name of the test
17 --testmask Define the bit-mask to enable the different test phases
18 (currently there are 3 test phases: data_production; compare_data_products; compare_data_product_size.)
19 --update-ref-files Flag to activate the "Update Reference Files" mode
20 --input-files-to-fetch List of input files to be downloaded before to execute the data production
21 --reference-files-to-fetch List of reference files to be downloaded before the product comparison
22 --extra-function Define and extra function to run with list of required arguments; the elements need to be comma separated
23 --extra-options Define and extra options/arguments for the executable; the elements need to be comma separated
29 TASKSTRING="initialize"
30 ERRORSTRING="F~Error initializing the test~Check the log"
31 trap 'LASTERR=$?; FUNCTION_NAME=${FUNCNAME[0]:-main}; exitstatus ${LASTERR} trap ${LINENO}; exit ${LASTERR}' ERR
33 echo "running CI tests for ${proj_PREFIX}_ci."
34 echo "ci_cur_exp_name: ${ci_cur_exp_name}"
38 #~~~~~~~~~~~~~~~ DEFAULT VALUES ~~~~~~~~~~~~~~~~
39 EXECUTABLE_NAME=no_executable_defined
43 INPUT_FILES_TO_FETCH=""
45 REFERENCE_FILES_TO_FETCH=""
46 WORKSPACE=${WORKSPACE:-$PWD}
48 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50 #~~~~~~~~~~~~~~~~~~~~~~GET VALUE FROM THE CI_TESTS.CFG ARGS SECTION~~~~~~~~~~~~~~~
54 x-h|x--help) usage; exit;;
55 x--executable) EXECUTABLE_NAME="${2//,/ }"; shift; shift;;
56 x--nevents) NEVENTS="${2}"; shift; shift;;
57 x--stage) STAGE="${2}"; shift; shift;;
58 x--fhicl) FHiCL_FILE="${2}"; shift; shift;;
59 x--input-file) INPUT_FILE="${2}"; shift; shift;;
60 x--reference-files) REFERENCE_FILES="${2}"; shift; shift;;
61 x--outputs) OUTPUT_LIST="${2}"; OUTPUT_STREAM="${OUTPUT_LIST//,/ -o }"; shift; shift;;
62 x--stage-name) STAGE_NAME="${2}"; shift; shift;;
63 x--testmask) TESTMASK="${2}"; shift; shift;;
64 x--update-ref-files) UPDATE_REF_FILE_ON=1; shift;;
65 x--input-files-to-fetch) INPUT_FILES_TO_FETCH="${2}"; shift; shift;;
66 x--reference-files-to-fetch) REFERENCE_FILES_TO_FETCH="${2}"; shift; shift;;
67 x--extra-function) EXTRA_FUNCTION="${2}"; shift; shift;;
68 x--extra-options) EXTRA_OPTIONS="${2//,/ }"; shift; shift;;
70 x*) echo "Unknown argument $1"; usage; exit 1;;
74 if [ ${UPDATE_REF_FILE_ON} -gt 0 ]; then
75 echo -e "\n***************************************************"
76 echo "This CI build is running to update reference files:"
77 echo "- data product comparison is disabled"
78 echo "- number of events is set to 1"
79 echo "- existing reference files will not be used"
80 echo -e "***************************************************\n"
82 if [[ "$(basename ${0})" != *"lariatsoft"* ]]; then
86 REFERENCE_FILES_TO_FETCH=""
89 if [ -n "${INPUT_FILES_TO_FETCH}" ]; then
90 fetch_files input ${INPUT_FILES_TO_FETCH}
92 if [ -n "${REFERENCE_FILES_TO_FETCH}" ]; then
93 fetch_files reference ${REFERENCE_FILES_TO_FETCH}
96 #~~~~~~~~~~~~~~~~~~~~~PARSE THE TESTMASK FILE TO UNDERSTAND WHICH FUNCTION TO RUN ~~~~~~~~~~~~
97 if [ -n "${TESTMASK}" ];then
98 check_data_production=${TESTMASK:0:1}
99 check_compare_names=$((${TESTMASK:1:1}&&${check_data_production}))
100 check_compare_size=$((${TESTMASK:2:1}&&${check_compare_names}))
102 check_data_production=1
103 check_compare_names=0
107 echo "Input file: ${INPUT_FILE}"
108 echo "Output files: ${OUTPUT_LIST}"
109 echo "FHiCL file: ${FHiCL_FILE}"
110 echo "Testmask: ${TESTMASK}"
112 echo -e "\nRunning\n `basename $0` $@"
120 old_taskstring="$TASKSTRING"
121 old_errorstring="$ERRORSTRING"
122 TASKSTRING="fetching $1 files"
124 ERRORSTRING="F~Error in fetching $1 files~Check if the $1 files are available"
126 echo "fetching $1 files for ${proj_PREFIX}_ci."
128 echo "fetch_files $@"
131 maxretries_backup=$IFDH_CP_MAXRETRIES
132 debug_backup=$IFDH_DEBUG
135 export IFDH_CP_MAXRETRIES=0
137 for file in ${2//,/ }
139 echo "Command: ifdh cp -D $file ./"
140 ifdh cp -D $file ./ > fetch_inputs.log 2>&1
141 local copy_exit_code=$?
143 if [[ $copy_exit_code -ne 0 ]]; then
144 echo "Failed to fetch $file"
149 export IFDH_DEBUG=$debug_backup
150 export IFDH_CP_MAXRETRIES=$maxretries_backup
151 exitstatus $copy_exit_code
152 TASKSTRING="$old_taskstring"
153 ERRORSTRING="$old_errorstring"
157 function data_production
159 TASKSTRING="data_production"
160 ERRORSTRING="F~Error in data production~Check the log"
161 trap 'LASTERR=$?; FUNCTION_NAME=${FUNCNAME[0]:-main}; exitstatus ${LASTERR} trap ${LINENO}; exit ${LASTERR}' ERR
163 export TMPDIR=${PWD} #Temporary directory used by IFDHC
165 #~~~~~~~~~~~~~IF THE TESTMASK VALUE IS SET TO 1 THEN RUN THE PRODUCTION OF THR DATA~~~~~~~~~~~~~~~~~~
166 if [[ "${1}" -eq 1 ]]
168 # This is LArIAT specific.
169 # The slicer stage has output filename in the form file_%#.root
170 if [[ "${STAGE_NAME}" == "slicer" && "$(basename ${0})" == *"lariatsoft"* ]]; then # This is LArIAT specific.
171 OUTPUT_STREAM=${OUTPUT_STREAM//.root/_%#.root}
174 echo -e "\nNumber of events for ${STAGE_NAME} stage: $NEVENTS\n"
175 echo ${EXECUTABLE_NAME} --rethrow-all -n ${NEVENTS} ${EXTRA_OPTIONS} ${OUTPUT_STREAM:+-o "$OUTPUT_STREAM"} --config ${FHiCL_FILE} ${INPUT_FILE}
180 local expcode_exitcode=20
181 until [[ ${expcode_exitcode} -ne 20 || ${counter} -gt 5 ]]; do
182 /usr/bin/time ${EXECUTABLE_NAME} --rethrow-all -n ${NEVENTS} ${EXTRA_OPTIONS} ${OUTPUT_STREAM:+-o "$OUTPUT_STREAM"} --config ${FHiCL_FILE} ${INPUT_FILE}
184 (>&2 echo "TIME SIGNATURE" )
185 if [[ ${expcode_exitcode} -eq 20 ]]; then
187 echo -e "\n\n*** ${EXECUTABLE_NAME} can not access the input file, wait 30 s, then retry #${counter}\n\n"
191 exit $expcode_exitcode
195 echo -e "\nCI MSG BEGIN\n Stage: ${STAGE_NAME}\n Task: ${TASKSTRING}\n skipped\nCI MSG END\n"
199 # This is uBooNE specific.
200 # The mergeana stage doesn't produce an artRoot file,
201 # but the CI expect to have it.
202 if [[ "${STAGE_NAME}" == "mergeana" && "$(basename ${0})" == *"uboonecode"* ]]; then
203 for CUR_OUT in ${OUTPUT_STREAM//-o/}; do
208 # This is LArIAT specific.
209 # The slicer stage has output filename in the form file_%#.root
210 if [[ "${OUTPUT_STREAM}" == *"_%#"* && "${STAGE_NAME}" == "slicer" && "$(basename ${0})" == *"lariatsoft"* ]]; then
212 for CUR_OUT in ${OUTPUT_STREAM//-o/} # this is LArIAT specific
214 CUR_OUT=${CUR_OUT//*:/}
215 CUR_OUT2=$(echo $CUR_OUT | sed -e "s/_%#// ; s/_1.root/.root/")
216 ln -fv ${CUR_OUT//_%#.root/_1.root} ${CUR_OUT2} && rm ${CUR_OUT//_%#.root/_1.root}
222 function generate_data_dump
224 TASKSTRING="generate_data_dump for ${file_stream} output stream"
225 ERRORSTRING="W~Error during dump Generation~Check the log"
227 trap 'LASTERR=$?; FUNCTION_NAME=${FUNCNAME[0]:-main}; exitstatus ${LASTERR} trap ${LINENO}; exit ${LASTERR}' ERR
231 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~PRINT THE COMMAND TO LOG AND THEN GENERATE THE DUMP FOR THE REFERENCE FILE ~~~~~~~~~~~~~~~~~~~
232 echo -e "\nGenerating Dump for ${reference_file}"
233 REF_DUMP_FILE=$(basename ${reference_file} | sed -e 's/.root/.dump/')
234 echo "${EXECUTABLE_NAME} --rethrow-all -n ${NEVENTS} --config eventdump.fcl ${reference_file} 2>&1 | tee ${REF_DUMP_FILE}"
240 local expcode_exitcode=20
241 until [[ ${expcode_exitcode} -ne 20 || ${counter} -gt 5 ]]; do
242 ${EXECUTABLE_NAME} --rethrow-all -n ${NEVENTS} --config eventdump.fcl "${reference_file}" 2>&1 | tee ${REF_DUMP_FILE}
244 if [[ ${expcode_exitcode} -eq 20 ]]; then
246 echo -e "\n\n*** ${EXECUTABLE_NAME} can not access the input file, wait 30 s, then retry #${counter}\n\n"
250 exit ${expcode_exitcode}
253 #~~~~~~~~~~~~~~~~~~~~~~~~~SAVE IN A VARIABLE THE PARSED REFERENCE DUMP FILE ~~~~~~~~~~~~~~~~~~~~~~
254 OUTPUT_REFERENCE=$(cat "${REF_DUMP_FILE}" | sed -e '/PRINCIPAL TYPE:/,/^\s*$/!d ; s/PRINCIPAL TYPE:.*$// ; /^\s*$/d' )
256 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~PRINT THE COMMAND TO LOG AND THEN GENERATE THE DUMP FOR THE CURRENT FILE ~~~~~~~~~~~~~~~~~~~
257 echo -e "\nGenerating Dump for ${current_file}"
258 echo "${EXECUTABLE_NAME} --rethrow-all -n ${NEVENTS} --config eventdump.fcl ${current_file} 2>&1 | tee ${current_file//.root}.dump"
264 local expcode_exitcode=20
265 until [[ ${expcode_exitcode} -ne 20 || ${counter} -gt 5 ]]; do
266 ${EXECUTABLE_NAME} --rethrow-all -n ${NEVENTS} --config eventdump.fcl "${current_file}" 2>&1 | tee "${current_file//.root}".dump
268 if [[ ${expcode_exitcode} -eq 20 ]]; then
270 echo -e "\n\n*** ${EXECUTABLE_NAME} can not access the input file, wait 30 s, then retry #${counter}\n\n"
274 exit ${expcode_exitcode}
276 #~~~~~~~~~~~~~~~~~~~~~~~~~SAVE IN A VARIABLE THE PARSED CURRENT DUMP FILE ~~~~~~~~~~~~~~~~~~~~~~
277 OUTPUT_CURRENT=$(cat "${current_file//.root}".dump | sed -e '/PRINCIPAL TYPE:/,/^\s*$/!d ; s/PRINCIPAL TYPE:.*$// ; /^\s*$/d' )
279 echo -e "\nReference files for ${file_stream} output stream:"
280 echo -e "\n${REF_DUMP_FILE}\n"
281 echo "$OUTPUT_REFERENCE"
282 echo -e "\nCurrent files for ${file_stream} output stream:"
283 echo -e "\n${current_file//.root}.dump\n"
284 echo "$OUTPUT_CURRENT"
289 function compare_products_names
291 TASKSTRING="compare_products_names for ${file_stream} output stream"
292 ERRORSTRING="W~Error comparing products names~check the log"
296 REF_DUMP_FILE=$(basename ${reference_file} | sed -e 's/.root/.dump/')
297 echo -e "\nCompare products names for ${file_stream} output stream."
298 #~~~~~~~~~~~~~~~~CHECK IF THERE'S A DIFFERENCE BEETWEEN THE TWO DUMP FILES IN THE FIRST FOUR COLUMNS~~~~~~~~~~~~~~
299 DIFF=$(diff <(sed 's/\.//g ; /PRINCIPAL TYPE:/,/^\s*$/!d ; s/PRINCIPAL TYPE:.*$// ; /^\s*$/d' ${REF_DUMP_FILE} | cut -d "|" -f -4 ) <(sed 's/\.//g ; /PRINCIPAL TYPE:/,/^\s*$/!d ; s/PRINCIPAL TYPE:.*$// ; /^\s*$/d' ${current_file//.root/.dump} | cut -d "|" -f -4 ) )
302 echo -e "\nCheck for added/removed data products"
303 echo -e "difference(s)\n"
304 #~~~~~~~~~~~~~~~IF THERE'S A DIFFERENCE EXIT WITH ERROR CODE 201~~~~~~~~~~~~~~~
305 if [[ "${STATUS}" -ne 0 ]]; then
307 ERRORSTRING="W~Differences in products names~Request new reference files"
313 echo -e "\nCI MSG BEGIN\n Stage: ${STAGE_NAME}\n Task: ${TASKSTRING}\n skipped\nCI MSG END\n"
318 function compare_products_sizes
320 TASKSTRING="compare_products_sizes for ${file_stream} output stream"
321 ERRORSTRING="W~Error comparing product sizes~Check the log"
324 if [[ "${1}" -eq 1 ]]
327 REF_DUMP_FILE=$(basename ${reference_file} | sed -e 's/.root/.dump/')
328 echo -e "\nCompare products sizes for ${file_stream} output stream.\n"
329 #~~~~~~~~~~~~~~~~CHECK IF THERE'S A DIFFERENCE BEETWEEN THE TWO DUMP FILES,IN ALL THE COLUMNS~~~~~~~~~~~~~~
330 DIFF=$(diff <(sed 's/\.//g ; /PRINCIPAL TYPE:/,/^\s*$/!d ; s/PRINCIPAL TYPE:.*$// ; /^\s*$/d' ${REF_DUMP_FILE}) <(sed 's/\.//g ; /PRINCIPAL TYPE:/,/^\s*$/!d ; s/PRINCIPAL TYPE:.*$// ; /^\s*$/d' ${current_file//.root/.dump}) )
332 echo -e "\nCheck for differences in the size of data products"
333 echo -e "difference(s)\n"
335 #~~~~~~~~~~~~~~~IF THERE'S A DIFFERENCE EXIT WITH ERROR CODE 202 ~~~~~~~~~~~~~~~~~~~~~~~
336 if [[ "${STATUS}" -ne 0 ]]; then
338 ERRORSTRING="W~Differences in products sizes~Request new reference files"
344 echo -e "\nCI MSG BEGIN\n Stage: ${STAGE_NAME}\n Task: ${TASKSTRING}\n skipped\nCI MSG END\n"
350 #~~~~~~~~~~~~~~~~~~~~~~~PRINT AN ERROR MESSAGE IN THE PROGRAM EXIT WITH AN ERROR CODE~~~~~~~~~~~~~~~~
354 if [ "$2" == "trap" ];then
355 echo -e "\nCI MSG BEGIN\n Script: `basename $0`\n Function: ${FUNCTION_NAME} - error at line ${3}\n Stage: ${STAGE_NAME}\n Task: ${TASKSTRING}\n exit status: $EXITSTATUS\nCI MSG END\n"
357 echo -e "\nCI MSG BEGIN\n Stage: ${STAGE_NAME}\n Task: ${TASKSTRING}\n exit status: ${EXITSTATUS}\nCI MSG END\n"
359 #don't exit if the fetch of the reference failed,because we need to produce one and then upload it
360 if [[ "${EXITSTATUS}" -ne 0 ]]; then
361 if [[ -n "$ERRORSTRING" ]];then
362 echo "`basename $PWD`~${EXITSTATUS}~$ERRORSTRING" >> $WORKSPACE/data_production_stats${ci_cur_exp_name}.log
364 if [ "$2" == "defer" ];then
365 PREVSTATUS=${EXITSTATUS}
370 if [[ -n "${PREVSTATUS}" && "$2" != "defer" ]]; then
376 #~~~~~~~~~~~~~~~~~~~~~~~EXTRA FUNCTIONS TO RUN SPECIAL TESTS~~~~~~~~~~~~~~~~
377 function compare_anatree
380 source ${GENERIC_CI_DIR}/bin/reporter_functions.sh
382 THISCIDIR=$(eval "echo \${${PROJ_PREFIX}_CI_DIR}")
384 root -l -b -q ${THISCIDIR}/test/compare_anatree.C\(\"${1}\",\"${2}\"\)
388 if [ -n "${BUILD_ID}" ] # not in a jenkins build, don't send plots to CI web app
390 BASE_JOB=`echo $JOB_NAME | sed -e 's;/.*;;' -e 's/_jenkins.*//'`
391 export report_fullname="${BASE_JOB}/${BUILD_NUMBER}"
392 export report_serverurl="${HUDSON_URL}"
397 hist_desc="${bf//.gif/} plot"
398 hist_name="${bf//.gif/}"
399 report_img "ci_tests" "${ci_cur_exp_name}" "" "$(basename $PWD)" "$hist_name" "$f" "$hist_desc"
400 # report_img "ci_tests" "" "end" "$hist_name" "$f" "$hist_desc"
408 #~~~~~~~~~~~~~~~~~~~~~~~~MAIN OF THE SCRIPT~~~~~~~~~~~~~~~~~~
409 trap 'LASTERR=$?; FUNCTION_NAME=${FUNCNAME[0]:-main}; exitstatus ${LASTERR} trap ${LINENO}; exit ${LASTERR}' ERR
413 data_production "${check_data_production}"
415 #~~~~~~~~~~~~~~~~PROCESS ALL THE FILES DECLARED INTO THE OUTPUT LIST~~~~~~~~~~~~~~~~~
416 for filename in ${OUTPUT_LIST//,/ }
418 file_stream=$(echo "${filename}" | cut -d ':' -f 1)
419 current_file=$(echo "${filename}" | cut -d ':' -f 2)
421 echo "filename: ${filename}"
422 echo "file_stream: ${file_stream}"
423 echo "current_file: ${current_file}"
426 if [[ "${REFERENCE_FILES}" = *"xroot"* ]]; then
427 for temp_file in ${REFERENCE_FILES//,/ }
429 if [[ "${temp_file}" = *"${current_file//Current/Reference}"* ]]; then
430 reference_file=${temp_file}
434 ### XROOTD_PATH=$(echo "${reference_file}" | sed -e 's#\(^.*\)/'${STAGE_NAME}'/.*#\1/'${STAGE_NAME}/'#')
437 ### if [ -n "${build_platform}" ]; then
438 ### reference_file=$(echo "${current_file%`echo ${build_platform}`*}${build_platform}${current_file#*`echo ${build_platform}`}")
440 ### reference_file=$(echo "${current_file}")
442 ### reference_file="${reference_file//Current/Reference}"
443 reference_file="${current_file//Current/Reference}"
444 [[ -n "$build_identifier" ]] && reference_file="$(sed -e 's#'${build_identifier}'##' <<< "$reference_file" )"
447 if [[ "${check_compare_names}" -eq 1 || "${check_compare_size}" -eq 1 ]]; then
453 compare_products_names "${check_compare_names}"
455 compare_products_sizes "${check_compare_size}"
457 if [[ -n ${PREVSTATE} ]]; then
463 #~~~~~~~~~~~~~~~~RUN EXTRA FUNCTION~~~~~~~~~~~~~~~~~
464 if [ -n "${EXTRA_FUNCTION}" ]; then
465 ${EXTRA_FUNCTION//,/ }