162306a36Sopenharmony_ci#!/usr/bin/perl -w 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only 362306a36Sopenharmony_ci# 462306a36Sopenharmony_ci# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. 562306a36Sopenharmony_ci# 662306a36Sopenharmony_ci 762306a36Sopenharmony_ciuse strict; 862306a36Sopenharmony_ciuse IPC::Open2; 962306a36Sopenharmony_ciuse Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); 1062306a36Sopenharmony_ciuse File::Path qw(mkpath); 1162306a36Sopenharmony_ciuse File::Copy qw(cp); 1262306a36Sopenharmony_ciuse FileHandle; 1362306a36Sopenharmony_ciuse FindBin; 1462306a36Sopenharmony_ciuse IO::Handle; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cimy $VERSION = "0.2"; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci$| = 1; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cimy %opt; 2162306a36Sopenharmony_cimy %repeat_tests; 2262306a36Sopenharmony_cimy %repeats; 2362306a36Sopenharmony_cimy %evals; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#default opts 2662306a36Sopenharmony_cimy %default = ( 2762306a36Sopenharmony_ci "MAILER" => "sendmail", # default mailer 2862306a36Sopenharmony_ci "EMAIL_ON_ERROR" => 1, 2962306a36Sopenharmony_ci "EMAIL_WHEN_FINISHED" => 1, 3062306a36Sopenharmony_ci "EMAIL_WHEN_CANCELED" => 0, 3162306a36Sopenharmony_ci "EMAIL_WHEN_STARTED" => 0, 3262306a36Sopenharmony_ci "NUM_TESTS" => 1, 3362306a36Sopenharmony_ci "TEST_TYPE" => "build", 3462306a36Sopenharmony_ci "BUILD_TYPE" => "oldconfig", 3562306a36Sopenharmony_ci "MAKE_CMD" => "make", 3662306a36Sopenharmony_ci "CLOSE_CONSOLE_SIGNAL" => "INT", 3762306a36Sopenharmony_ci "TIMEOUT" => 120, 3862306a36Sopenharmony_ci "TMP_DIR" => "/tmp/ktest/\${MACHINE}", 3962306a36Sopenharmony_ci "SLEEP_TIME" => 60, # sleep time between tests 4062306a36Sopenharmony_ci "BUILD_NOCLEAN" => 0, 4162306a36Sopenharmony_ci "REBOOT_ON_ERROR" => 0, 4262306a36Sopenharmony_ci "POWEROFF_ON_ERROR" => 0, 4362306a36Sopenharmony_ci "REBOOT_ON_SUCCESS" => 1, 4462306a36Sopenharmony_ci "POWEROFF_ON_SUCCESS" => 0, 4562306a36Sopenharmony_ci "BUILD_OPTIONS" => "", 4662306a36Sopenharmony_ci "BISECT_SLEEP_TIME" => 60, # sleep time between bisects 4762306a36Sopenharmony_ci "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks 4862306a36Sopenharmony_ci "CLEAR_LOG" => 0, 4962306a36Sopenharmony_ci "BISECT_MANUAL" => 0, 5062306a36Sopenharmony_ci "BISECT_SKIP" => 1, 5162306a36Sopenharmony_ci "BISECT_TRIES" => 1, 5262306a36Sopenharmony_ci "MIN_CONFIG_TYPE" => "boot", 5362306a36Sopenharmony_ci "SUCCESS_LINE" => "login:", 5462306a36Sopenharmony_ci "DETECT_TRIPLE_FAULT" => 1, 5562306a36Sopenharmony_ci "NO_INSTALL" => 0, 5662306a36Sopenharmony_ci "BOOTED_TIMEOUT" => 1, 5762306a36Sopenharmony_ci "DIE_ON_FAILURE" => 1, 5862306a36Sopenharmony_ci "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND", 5962306a36Sopenharmony_ci "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE", 6062306a36Sopenharmony_ci "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}", 6162306a36Sopenharmony_ci "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot", 6262306a36Sopenharmony_ci "REBOOT_RETURN_CODE" => 255, 6362306a36Sopenharmony_ci "STOP_AFTER_SUCCESS" => 10, 6462306a36Sopenharmony_ci "STOP_AFTER_FAILURE" => 60, 6562306a36Sopenharmony_ci "STOP_TEST_AFTER" => 600, 6662306a36Sopenharmony_ci "MAX_MONITOR_WAIT" => 1800, 6762306a36Sopenharmony_ci "GRUB_REBOOT" => "grub2-reboot", 6862306a36Sopenharmony_ci "GRUB_BLS_GET" => "grubby --info=ALL", 6962306a36Sopenharmony_ci "SYSLINUX" => "extlinux", 7062306a36Sopenharmony_ci "SYSLINUX_PATH" => "/boot/extlinux", 7162306a36Sopenharmony_ci "CONNECT_TIMEOUT" => 25, 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci# required, and we will ask users if they don't have them but we keep the default 7462306a36Sopenharmony_ci# value something that is common. 7562306a36Sopenharmony_ci "REBOOT_TYPE" => "grub", 7662306a36Sopenharmony_ci "LOCALVERSION" => "-test", 7762306a36Sopenharmony_ci "SSH_USER" => "root", 7862306a36Sopenharmony_ci "BUILD_TARGET" => "arch/x86/boot/bzImage", 7962306a36Sopenharmony_ci "TARGET_IMAGE" => "/boot/vmlinuz-test", 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci "LOG_FILE" => undef, 8262306a36Sopenharmony_ci "IGNORE_UNUSED" => 0, 8362306a36Sopenharmony_ci); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cimy $test_log_start = 0; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cimy $ktest_config = "ktest.conf"; 8862306a36Sopenharmony_cimy $version; 8962306a36Sopenharmony_cimy $have_version = 0; 9062306a36Sopenharmony_cimy $machine; 9162306a36Sopenharmony_cimy $last_machine; 9262306a36Sopenharmony_cimy $ssh_user; 9362306a36Sopenharmony_cimy $tmpdir; 9462306a36Sopenharmony_cimy $builddir; 9562306a36Sopenharmony_cimy $outputdir; 9662306a36Sopenharmony_cimy $output_config; 9762306a36Sopenharmony_cimy $test_type; 9862306a36Sopenharmony_cimy $build_type; 9962306a36Sopenharmony_cimy $build_options; 10062306a36Sopenharmony_cimy $final_post_ktest; 10162306a36Sopenharmony_cimy $pre_ktest; 10262306a36Sopenharmony_cimy $post_ktest; 10362306a36Sopenharmony_cimy $pre_test; 10462306a36Sopenharmony_cimy $pre_test_die; 10562306a36Sopenharmony_cimy $post_test; 10662306a36Sopenharmony_cimy $pre_build; 10762306a36Sopenharmony_cimy $post_build; 10862306a36Sopenharmony_cimy $pre_build_die; 10962306a36Sopenharmony_cimy $post_build_die; 11062306a36Sopenharmony_cimy $reboot_type; 11162306a36Sopenharmony_cimy $reboot_script; 11262306a36Sopenharmony_cimy $power_cycle; 11362306a36Sopenharmony_cimy $reboot; 11462306a36Sopenharmony_cimy $reboot_return_code; 11562306a36Sopenharmony_cimy $reboot_on_error; 11662306a36Sopenharmony_cimy $switch_to_good; 11762306a36Sopenharmony_cimy $switch_to_test; 11862306a36Sopenharmony_cimy $poweroff_on_error; 11962306a36Sopenharmony_cimy $reboot_on_success; 12062306a36Sopenharmony_cimy $die_on_failure; 12162306a36Sopenharmony_cimy $powercycle_after_reboot; 12262306a36Sopenharmony_cimy $poweroff_after_halt; 12362306a36Sopenharmony_cimy $max_monitor_wait; 12462306a36Sopenharmony_cimy $ssh_exec; 12562306a36Sopenharmony_cimy $scp_to_target; 12662306a36Sopenharmony_cimy $scp_to_target_install; 12762306a36Sopenharmony_cimy $power_off; 12862306a36Sopenharmony_cimy $grub_menu; 12962306a36Sopenharmony_cimy $last_grub_menu; 13062306a36Sopenharmony_cimy $grub_file; 13162306a36Sopenharmony_cimy $grub_number; 13262306a36Sopenharmony_cimy $grub_reboot; 13362306a36Sopenharmony_cimy $grub_bls_get; 13462306a36Sopenharmony_cimy $syslinux; 13562306a36Sopenharmony_cimy $syslinux_path; 13662306a36Sopenharmony_cimy $syslinux_label; 13762306a36Sopenharmony_cimy $target; 13862306a36Sopenharmony_cimy $make; 13962306a36Sopenharmony_cimy $pre_install; 14062306a36Sopenharmony_cimy $post_install; 14162306a36Sopenharmony_cimy $no_install; 14262306a36Sopenharmony_cimy $noclean; 14362306a36Sopenharmony_cimy $minconfig; 14462306a36Sopenharmony_cimy $start_minconfig; 14562306a36Sopenharmony_cimy $start_minconfig_defined; 14662306a36Sopenharmony_cimy $output_minconfig; 14762306a36Sopenharmony_cimy $minconfig_type; 14862306a36Sopenharmony_cimy $use_output_minconfig; 14962306a36Sopenharmony_cimy $warnings_file; 15062306a36Sopenharmony_cimy $ignore_config; 15162306a36Sopenharmony_cimy $ignore_errors; 15262306a36Sopenharmony_cimy $addconfig; 15362306a36Sopenharmony_cimy $in_bisect = 0; 15462306a36Sopenharmony_cimy $bisect_bad_commit = ""; 15562306a36Sopenharmony_cimy $reverse_bisect; 15662306a36Sopenharmony_cimy $bisect_manual; 15762306a36Sopenharmony_cimy $bisect_skip; 15862306a36Sopenharmony_cimy $bisect_tries; 15962306a36Sopenharmony_cimy $config_bisect_good; 16062306a36Sopenharmony_cimy $bisect_ret_good; 16162306a36Sopenharmony_cimy $bisect_ret_bad; 16262306a36Sopenharmony_cimy $bisect_ret_skip; 16362306a36Sopenharmony_cimy $bisect_ret_abort; 16462306a36Sopenharmony_cimy $bisect_ret_default; 16562306a36Sopenharmony_cimy $in_patchcheck = 0; 16662306a36Sopenharmony_cimy $run_test; 16762306a36Sopenharmony_cimy $buildlog; 16862306a36Sopenharmony_cimy $testlog; 16962306a36Sopenharmony_cimy $dmesg; 17062306a36Sopenharmony_cimy $monitor_fp; 17162306a36Sopenharmony_cimy $monitor_pid; 17262306a36Sopenharmony_cimy $monitor_cnt = 0; 17362306a36Sopenharmony_cimy $sleep_time; 17462306a36Sopenharmony_cimy $bisect_sleep_time; 17562306a36Sopenharmony_cimy $patchcheck_sleep_time; 17662306a36Sopenharmony_cimy $ignore_warnings; 17762306a36Sopenharmony_cimy $store_failures; 17862306a36Sopenharmony_cimy $store_successes; 17962306a36Sopenharmony_cimy $test_name; 18062306a36Sopenharmony_cimy $timeout; 18162306a36Sopenharmony_cimy $run_timeout; 18262306a36Sopenharmony_cimy $connect_timeout; 18362306a36Sopenharmony_cimy $config_bisect_exec; 18462306a36Sopenharmony_cimy $booted_timeout; 18562306a36Sopenharmony_cimy $detect_triplefault; 18662306a36Sopenharmony_cimy $console; 18762306a36Sopenharmony_cimy $close_console_signal; 18862306a36Sopenharmony_cimy $reboot_success_line; 18962306a36Sopenharmony_cimy $success_line; 19062306a36Sopenharmony_cimy $stop_after_success; 19162306a36Sopenharmony_cimy $stop_after_failure; 19262306a36Sopenharmony_cimy $stop_test_after; 19362306a36Sopenharmony_cimy $build_target; 19462306a36Sopenharmony_cimy $target_image; 19562306a36Sopenharmony_cimy $checkout; 19662306a36Sopenharmony_cimy $localversion; 19762306a36Sopenharmony_cimy $iteration = 0; 19862306a36Sopenharmony_cimy $successes = 0; 19962306a36Sopenharmony_cimy $stty_orig; 20062306a36Sopenharmony_cimy $run_command_status = 0; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_cimy $bisect_good; 20362306a36Sopenharmony_cimy $bisect_bad; 20462306a36Sopenharmony_cimy $bisect_type; 20562306a36Sopenharmony_cimy $bisect_start; 20662306a36Sopenharmony_cimy $bisect_replay; 20762306a36Sopenharmony_cimy $bisect_files; 20862306a36Sopenharmony_cimy $bisect_reverse; 20962306a36Sopenharmony_cimy $bisect_check; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_cimy $config_bisect; 21262306a36Sopenharmony_cimy $config_bisect_type; 21362306a36Sopenharmony_cimy $config_bisect_check; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cimy $patchcheck_type; 21662306a36Sopenharmony_cimy $patchcheck_start; 21762306a36Sopenharmony_cimy $patchcheck_cherry; 21862306a36Sopenharmony_cimy $patchcheck_end; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cimy $build_time; 22162306a36Sopenharmony_cimy $install_time; 22262306a36Sopenharmony_cimy $reboot_time; 22362306a36Sopenharmony_cimy $test_time; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cimy $pwd; 22662306a36Sopenharmony_cimy $dirname = $FindBin::Bin; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cimy $mailto; 22962306a36Sopenharmony_cimy $mailer; 23062306a36Sopenharmony_cimy $mail_path; 23162306a36Sopenharmony_cimy $mail_max_size; 23262306a36Sopenharmony_cimy $mail_command; 23362306a36Sopenharmony_cimy $email_on_error; 23462306a36Sopenharmony_cimy $email_when_finished; 23562306a36Sopenharmony_cimy $email_when_started; 23662306a36Sopenharmony_cimy $email_when_canceled; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_cimy $script_start_time = localtime(); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci# set when a test is something other that just building or install 24162306a36Sopenharmony_ci# which would require more options. 24262306a36Sopenharmony_cimy $buildonly = 1; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci# tell build not to worry about warnings, even when WARNINGS_FILE is set 24562306a36Sopenharmony_cimy $warnings_ok = 0; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci# set when creating a new config 24862306a36Sopenharmony_cimy $newconfig = 0; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cimy %entered_configs; 25162306a36Sopenharmony_cimy %config_help; 25262306a36Sopenharmony_cimy %variable; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci# force_config is the list of configs that we force enabled (or disabled) 25562306a36Sopenharmony_ci# in a .config file. The MIN_CONFIG and ADD_CONFIG configs. 25662306a36Sopenharmony_cimy %force_config; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci# do not force reboots on config problems 25962306a36Sopenharmony_cimy $no_reboot = 1; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci# reboot on success 26262306a36Sopenharmony_cimy $reboot_success = 0; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cimy %option_map = ( 26562306a36Sopenharmony_ci "MAILTO" => \$mailto, 26662306a36Sopenharmony_ci "MAILER" => \$mailer, 26762306a36Sopenharmony_ci "MAIL_PATH" => \$mail_path, 26862306a36Sopenharmony_ci "MAIL_MAX_SIZE" => \$mail_max_size, 26962306a36Sopenharmony_ci "MAIL_COMMAND" => \$mail_command, 27062306a36Sopenharmony_ci "EMAIL_ON_ERROR" => \$email_on_error, 27162306a36Sopenharmony_ci "EMAIL_WHEN_FINISHED" => \$email_when_finished, 27262306a36Sopenharmony_ci "EMAIL_WHEN_STARTED" => \$email_when_started, 27362306a36Sopenharmony_ci "EMAIL_WHEN_CANCELED" => \$email_when_canceled, 27462306a36Sopenharmony_ci "MACHINE" => \$machine, 27562306a36Sopenharmony_ci "SSH_USER" => \$ssh_user, 27662306a36Sopenharmony_ci "TMP_DIR" => \$tmpdir, 27762306a36Sopenharmony_ci "OUTPUT_DIR" => \$outputdir, 27862306a36Sopenharmony_ci "BUILD_DIR" => \$builddir, 27962306a36Sopenharmony_ci "TEST_TYPE" => \$test_type, 28062306a36Sopenharmony_ci "PRE_KTEST" => \$pre_ktest, 28162306a36Sopenharmony_ci "POST_KTEST" => \$post_ktest, 28262306a36Sopenharmony_ci "PRE_TEST" => \$pre_test, 28362306a36Sopenharmony_ci "PRE_TEST_DIE" => \$pre_test_die, 28462306a36Sopenharmony_ci "POST_TEST" => \$post_test, 28562306a36Sopenharmony_ci "BUILD_TYPE" => \$build_type, 28662306a36Sopenharmony_ci "BUILD_OPTIONS" => \$build_options, 28762306a36Sopenharmony_ci "PRE_BUILD" => \$pre_build, 28862306a36Sopenharmony_ci "POST_BUILD" => \$post_build, 28962306a36Sopenharmony_ci "PRE_BUILD_DIE" => \$pre_build_die, 29062306a36Sopenharmony_ci "POST_BUILD_DIE" => \$post_build_die, 29162306a36Sopenharmony_ci "POWER_CYCLE" => \$power_cycle, 29262306a36Sopenharmony_ci "REBOOT" => \$reboot, 29362306a36Sopenharmony_ci "REBOOT_RETURN_CODE" => \$reboot_return_code, 29462306a36Sopenharmony_ci "BUILD_NOCLEAN" => \$noclean, 29562306a36Sopenharmony_ci "MIN_CONFIG" => \$minconfig, 29662306a36Sopenharmony_ci "OUTPUT_MIN_CONFIG" => \$output_minconfig, 29762306a36Sopenharmony_ci "START_MIN_CONFIG" => \$start_minconfig, 29862306a36Sopenharmony_ci "MIN_CONFIG_TYPE" => \$minconfig_type, 29962306a36Sopenharmony_ci "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig, 30062306a36Sopenharmony_ci "WARNINGS_FILE" => \$warnings_file, 30162306a36Sopenharmony_ci "IGNORE_CONFIG" => \$ignore_config, 30262306a36Sopenharmony_ci "TEST" => \$run_test, 30362306a36Sopenharmony_ci "ADD_CONFIG" => \$addconfig, 30462306a36Sopenharmony_ci "REBOOT_TYPE" => \$reboot_type, 30562306a36Sopenharmony_ci "GRUB_MENU" => \$grub_menu, 30662306a36Sopenharmony_ci "GRUB_FILE" => \$grub_file, 30762306a36Sopenharmony_ci "GRUB_REBOOT" => \$grub_reboot, 30862306a36Sopenharmony_ci "GRUB_BLS_GET" => \$grub_bls_get, 30962306a36Sopenharmony_ci "SYSLINUX" => \$syslinux, 31062306a36Sopenharmony_ci "SYSLINUX_PATH" => \$syslinux_path, 31162306a36Sopenharmony_ci "SYSLINUX_LABEL" => \$syslinux_label, 31262306a36Sopenharmony_ci "PRE_INSTALL" => \$pre_install, 31362306a36Sopenharmony_ci "POST_INSTALL" => \$post_install, 31462306a36Sopenharmony_ci "NO_INSTALL" => \$no_install, 31562306a36Sopenharmony_ci "REBOOT_SCRIPT" => \$reboot_script, 31662306a36Sopenharmony_ci "REBOOT_ON_ERROR" => \$reboot_on_error, 31762306a36Sopenharmony_ci "SWITCH_TO_GOOD" => \$switch_to_good, 31862306a36Sopenharmony_ci "SWITCH_TO_TEST" => \$switch_to_test, 31962306a36Sopenharmony_ci "POWEROFF_ON_ERROR" => \$poweroff_on_error, 32062306a36Sopenharmony_ci "REBOOT_ON_SUCCESS" => \$reboot_on_success, 32162306a36Sopenharmony_ci "DIE_ON_FAILURE" => \$die_on_failure, 32262306a36Sopenharmony_ci "POWER_OFF" => \$power_off, 32362306a36Sopenharmony_ci "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot, 32462306a36Sopenharmony_ci "POWEROFF_AFTER_HALT" => \$poweroff_after_halt, 32562306a36Sopenharmony_ci "MAX_MONITOR_WAIT" => \$max_monitor_wait, 32662306a36Sopenharmony_ci "SLEEP_TIME" => \$sleep_time, 32762306a36Sopenharmony_ci "BISECT_SLEEP_TIME" => \$bisect_sleep_time, 32862306a36Sopenharmony_ci "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time, 32962306a36Sopenharmony_ci "IGNORE_WARNINGS" => \$ignore_warnings, 33062306a36Sopenharmony_ci "IGNORE_ERRORS" => \$ignore_errors, 33162306a36Sopenharmony_ci "BISECT_MANUAL" => \$bisect_manual, 33262306a36Sopenharmony_ci "BISECT_SKIP" => \$bisect_skip, 33362306a36Sopenharmony_ci "BISECT_TRIES" => \$bisect_tries, 33462306a36Sopenharmony_ci "CONFIG_BISECT_GOOD" => \$config_bisect_good, 33562306a36Sopenharmony_ci "BISECT_RET_GOOD" => \$bisect_ret_good, 33662306a36Sopenharmony_ci "BISECT_RET_BAD" => \$bisect_ret_bad, 33762306a36Sopenharmony_ci "BISECT_RET_SKIP" => \$bisect_ret_skip, 33862306a36Sopenharmony_ci "BISECT_RET_ABORT" => \$bisect_ret_abort, 33962306a36Sopenharmony_ci "BISECT_RET_DEFAULT" => \$bisect_ret_default, 34062306a36Sopenharmony_ci "STORE_FAILURES" => \$store_failures, 34162306a36Sopenharmony_ci "STORE_SUCCESSES" => \$store_successes, 34262306a36Sopenharmony_ci "TEST_NAME" => \$test_name, 34362306a36Sopenharmony_ci "TIMEOUT" => \$timeout, 34462306a36Sopenharmony_ci "RUN_TIMEOUT" => \$run_timeout, 34562306a36Sopenharmony_ci "CONNECT_TIMEOUT" => \$connect_timeout, 34662306a36Sopenharmony_ci "CONFIG_BISECT_EXEC" => \$config_bisect_exec, 34762306a36Sopenharmony_ci "BOOTED_TIMEOUT" => \$booted_timeout, 34862306a36Sopenharmony_ci "CONSOLE" => \$console, 34962306a36Sopenharmony_ci "CLOSE_CONSOLE_SIGNAL" => \$close_console_signal, 35062306a36Sopenharmony_ci "DETECT_TRIPLE_FAULT" => \$detect_triplefault, 35162306a36Sopenharmony_ci "SUCCESS_LINE" => \$success_line, 35262306a36Sopenharmony_ci "REBOOT_SUCCESS_LINE" => \$reboot_success_line, 35362306a36Sopenharmony_ci "STOP_AFTER_SUCCESS" => \$stop_after_success, 35462306a36Sopenharmony_ci "STOP_AFTER_FAILURE" => \$stop_after_failure, 35562306a36Sopenharmony_ci "STOP_TEST_AFTER" => \$stop_test_after, 35662306a36Sopenharmony_ci "BUILD_TARGET" => \$build_target, 35762306a36Sopenharmony_ci "SSH_EXEC" => \$ssh_exec, 35862306a36Sopenharmony_ci "SCP_TO_TARGET" => \$scp_to_target, 35962306a36Sopenharmony_ci "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install, 36062306a36Sopenharmony_ci "CHECKOUT" => \$checkout, 36162306a36Sopenharmony_ci "TARGET_IMAGE" => \$target_image, 36262306a36Sopenharmony_ci "LOCALVERSION" => \$localversion, 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci "BISECT_GOOD" => \$bisect_good, 36562306a36Sopenharmony_ci "BISECT_BAD" => \$bisect_bad, 36662306a36Sopenharmony_ci "BISECT_TYPE" => \$bisect_type, 36762306a36Sopenharmony_ci "BISECT_START" => \$bisect_start, 36862306a36Sopenharmony_ci "BISECT_REPLAY" => \$bisect_replay, 36962306a36Sopenharmony_ci "BISECT_FILES" => \$bisect_files, 37062306a36Sopenharmony_ci "BISECT_REVERSE" => \$bisect_reverse, 37162306a36Sopenharmony_ci "BISECT_CHECK" => \$bisect_check, 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci "CONFIG_BISECT" => \$config_bisect, 37462306a36Sopenharmony_ci "CONFIG_BISECT_TYPE" => \$config_bisect_type, 37562306a36Sopenharmony_ci "CONFIG_BISECT_CHECK" => \$config_bisect_check, 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci "PATCHCHECK_TYPE" => \$patchcheck_type, 37862306a36Sopenharmony_ci "PATCHCHECK_START" => \$patchcheck_start, 37962306a36Sopenharmony_ci "PATCHCHECK_CHERRY" => \$patchcheck_cherry, 38062306a36Sopenharmony_ci "PATCHCHECK_END" => \$patchcheck_end, 38162306a36Sopenharmony_ci); 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci# Options may be used by other options, record them. 38462306a36Sopenharmony_cimy %used_options; 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci# default variables that can be used 38762306a36Sopenharmony_cichomp ($variable{"PWD"} = `pwd`); 38862306a36Sopenharmony_ci$pwd = $variable{"PWD"}; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci$config_help{"MACHINE"} = << "EOF" 39162306a36Sopenharmony_ci The machine hostname that you will test. 39262306a36Sopenharmony_ci For build only tests, it is still needed to differentiate log files. 39362306a36Sopenharmony_ciEOF 39462306a36Sopenharmony_ci ; 39562306a36Sopenharmony_ci$config_help{"SSH_USER"} = << "EOF" 39662306a36Sopenharmony_ci The box is expected to have ssh on normal bootup, provide the user 39762306a36Sopenharmony_ci (most likely root, since you need privileged operations) 39862306a36Sopenharmony_ciEOF 39962306a36Sopenharmony_ci ; 40062306a36Sopenharmony_ci$config_help{"BUILD_DIR"} = << "EOF" 40162306a36Sopenharmony_ci The directory that contains the Linux source code (full path). 40262306a36Sopenharmony_ci You can use \${PWD} that will be the path where ktest.pl is run, or use 40362306a36Sopenharmony_ci \${THIS_DIR} which is assigned \${PWD} but may be changed later. 40462306a36Sopenharmony_ciEOF 40562306a36Sopenharmony_ci ; 40662306a36Sopenharmony_ci$config_help{"OUTPUT_DIR"} = << "EOF" 40762306a36Sopenharmony_ci The directory that the objects will be built (full path). 40862306a36Sopenharmony_ci (can not be same as BUILD_DIR) 40962306a36Sopenharmony_ci You can use \${PWD} that will be the path where ktest.pl is run, or use 41062306a36Sopenharmony_ci \${THIS_DIR} which is assigned \${PWD} but may be changed later. 41162306a36Sopenharmony_ciEOF 41262306a36Sopenharmony_ci ; 41362306a36Sopenharmony_ci$config_help{"BUILD_TARGET"} = << "EOF" 41462306a36Sopenharmony_ci The location of the compiled file to copy to the target. 41562306a36Sopenharmony_ci (relative to OUTPUT_DIR) 41662306a36Sopenharmony_ciEOF 41762306a36Sopenharmony_ci ; 41862306a36Sopenharmony_ci$config_help{"BUILD_OPTIONS"} = << "EOF" 41962306a36Sopenharmony_ci Options to add to \"make\" when building. 42062306a36Sopenharmony_ci i.e. -j20 42162306a36Sopenharmony_ciEOF 42262306a36Sopenharmony_ci ; 42362306a36Sopenharmony_ci$config_help{"TARGET_IMAGE"} = << "EOF" 42462306a36Sopenharmony_ci The place to put your image on the test machine. 42562306a36Sopenharmony_ciEOF 42662306a36Sopenharmony_ci ; 42762306a36Sopenharmony_ci$config_help{"POWER_CYCLE"} = << "EOF" 42862306a36Sopenharmony_ci A script or command to reboot the box. 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci Here is a digital loggers power switch example 43162306a36Sopenharmony_ci POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL' 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci Here is an example to reboot a virtual box on the current host 43462306a36Sopenharmony_ci with the name "Guest". 43562306a36Sopenharmony_ci POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest 43662306a36Sopenharmony_ciEOF 43762306a36Sopenharmony_ci ; 43862306a36Sopenharmony_ci$config_help{"CONSOLE"} = << "EOF" 43962306a36Sopenharmony_ci The script or command that reads the console 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci If you use ttywatch server, something like the following would work. 44262306a36Sopenharmony_ciCONSOLE = nc -d localhost 3001 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci For a virtual machine with guest name "Guest". 44562306a36Sopenharmony_ciCONSOLE = virsh console Guest 44662306a36Sopenharmony_ciEOF 44762306a36Sopenharmony_ci ; 44862306a36Sopenharmony_ci$config_help{"LOCALVERSION"} = << "EOF" 44962306a36Sopenharmony_ci Required version ending to differentiate the test 45062306a36Sopenharmony_ci from other linux builds on the system. 45162306a36Sopenharmony_ciEOF 45262306a36Sopenharmony_ci ; 45362306a36Sopenharmony_ci$config_help{"REBOOT_TYPE"} = << "EOF" 45462306a36Sopenharmony_ci Way to reboot the box to the test kernel. 45562306a36Sopenharmony_ci Only valid options so far are "grub", "grub2", "grub2bls", "syslinux", and "script". 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci If you specify grub, it will assume grub version 1 45862306a36Sopenharmony_ci and will search in /boot/grub/menu.lst for the title \$GRUB_MENU 45962306a36Sopenharmony_ci and select that target to reboot to the kernel. If this is not 46062306a36Sopenharmony_ci your setup, then specify "script" and have a command or script 46162306a36Sopenharmony_ci specified in REBOOT_SCRIPT to boot to the target. 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci The entry in /boot/grub/menu.lst must be entered in manually. 46462306a36Sopenharmony_ci The test will not modify that file. 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci If you specify grub2, then you also need to specify both \$GRUB_MENU 46762306a36Sopenharmony_ci and \$GRUB_FILE. 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci If you specify grub2bls, then you also need to specify \$GRUB_MENU. 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci If you specify syslinux, then you may use SYSLINUX to define the syslinux 47262306a36Sopenharmony_ci command (defaults to extlinux), and SYSLINUX_PATH to specify the path to 47362306a36Sopenharmony_ci the syslinux install (defaults to /boot/extlinux). But you have to specify 47462306a36Sopenharmony_ci SYSLINUX_LABEL to define the label to boot to for the test kernel. 47562306a36Sopenharmony_ciEOF 47662306a36Sopenharmony_ci ; 47762306a36Sopenharmony_ci$config_help{"GRUB_MENU"} = << "EOF" 47862306a36Sopenharmony_ci The grub title name for the test kernel to boot 47962306a36Sopenharmony_ci (Only mandatory if REBOOT_TYPE = grub or grub2) 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci Note, ktest.pl will not update the grub menu.lst, you need to 48262306a36Sopenharmony_ci manually add an option for the test. ktest.pl will search 48362306a36Sopenharmony_ci the grub menu.lst for this option to find what kernel to 48462306a36Sopenharmony_ci reboot into. 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci For example, if in the /boot/grub/menu.lst the test kernel title has: 48762306a36Sopenharmony_ci title Test Kernel 48862306a36Sopenharmony_ci kernel vmlinuz-test 48962306a36Sopenharmony_ci GRUB_MENU = Test Kernel 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci For grub2, a search of \$GRUB_FILE is performed for the lines 49262306a36Sopenharmony_ci that begin with "menuentry". It will not detect submenus. The 49362306a36Sopenharmony_ci menu must be a non-nested menu. Add the quotes used in the menu 49462306a36Sopenharmony_ci to guarantee your selection, as the first menuentry with the content 49562306a36Sopenharmony_ci of \$GRUB_MENU that is found will be used. 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci For grub2bls, \$GRUB_MENU is searched on the result of \$GRUB_BLS_GET 49862306a36Sopenharmony_ci command for the lines that begin with "title". 49962306a36Sopenharmony_ciEOF 50062306a36Sopenharmony_ci ; 50162306a36Sopenharmony_ci$config_help{"GRUB_FILE"} = << "EOF" 50262306a36Sopenharmony_ci If grub2 is used, the full path for the grub.cfg file is placed 50362306a36Sopenharmony_ci here. Use something like /boot/grub2/grub.cfg to search. 50462306a36Sopenharmony_ciEOF 50562306a36Sopenharmony_ci ; 50662306a36Sopenharmony_ci$config_help{"SYSLINUX_LABEL"} = << "EOF" 50762306a36Sopenharmony_ci If syslinux is used, the label that boots the target kernel must 50862306a36Sopenharmony_ci be specified with SYSLINUX_LABEL. 50962306a36Sopenharmony_ciEOF 51062306a36Sopenharmony_ci ; 51162306a36Sopenharmony_ci$config_help{"REBOOT_SCRIPT"} = << "EOF" 51262306a36Sopenharmony_ci A script to reboot the target into the test kernel 51362306a36Sopenharmony_ci (Only mandatory if REBOOT_TYPE = script) 51462306a36Sopenharmony_ciEOF 51562306a36Sopenharmony_ci ; 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci# used with process_expression() 51862306a36Sopenharmony_cimy $d = 0; 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci# defined before get_test_name() 52162306a36Sopenharmony_cimy $in_die = 0; 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci# defined before process_warning_line() 52462306a36Sopenharmony_cimy $check_build_re = ".*:.*(warning|error|Error):.*"; 52562306a36Sopenharmony_cimy $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})"; 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci# defined before child_finished() 52862306a36Sopenharmony_cimy $child_done; 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci# config_ignore holds the configs that were set (or unset) for 53162306a36Sopenharmony_ci# a good config and we will ignore these configs for the rest 53262306a36Sopenharmony_ci# of a config bisect. These configs stay as they were. 53362306a36Sopenharmony_cimy %config_ignore; 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci# config_set holds what all configs were set as. 53662306a36Sopenharmony_cimy %config_set; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci# config_off holds the set of configs that the bad config had disabled. 53962306a36Sopenharmony_ci# We need to record them and set them in the .config when running 54062306a36Sopenharmony_ci# olddefconfig, because olddefconfig keeps the defaults. 54162306a36Sopenharmony_cimy %config_off; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci# config_off_tmp holds a set of configs to turn off for now 54462306a36Sopenharmony_cimy @config_off_tmp; 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ci# config_list is the set of configs that are being tested 54762306a36Sopenharmony_cimy %config_list; 54862306a36Sopenharmony_cimy %null_config; 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_cimy %dependency; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci# found above run_config_bisect() 55362306a36Sopenharmony_cimy $pass = 1; 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci# found above add_dep() 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_cimy %depends; 55862306a36Sopenharmony_cimy %depcount; 55962306a36Sopenharmony_cimy $iflevel = 0; 56062306a36Sopenharmony_cimy @ifdeps; 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci# prevent recursion 56362306a36Sopenharmony_cimy %read_kconfigs; 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci# found above test_this_config() 56662306a36Sopenharmony_cimy %min_configs; 56762306a36Sopenharmony_cimy %keep_configs; 56862306a36Sopenharmony_cimy %save_configs; 56962306a36Sopenharmony_cimy %processed_configs; 57062306a36Sopenharmony_cimy %nochange_config; 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci# 57362306a36Sopenharmony_ci# These are first defined here, main function later on 57462306a36Sopenharmony_ci# 57562306a36Sopenharmony_cisub run_command; 57662306a36Sopenharmony_cisub start_monitor; 57762306a36Sopenharmony_cisub end_monitor; 57862306a36Sopenharmony_cisub wait_for_monitor; 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_cisub _logit { 58162306a36Sopenharmony_ci if (defined($opt{"LOG_FILE"})) { 58262306a36Sopenharmony_ci print LOG @_; 58362306a36Sopenharmony_ci } 58462306a36Sopenharmony_ci} 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_cisub logit { 58762306a36Sopenharmony_ci if (defined($opt{"LOG_FILE"})) { 58862306a36Sopenharmony_ci _logit @_; 58962306a36Sopenharmony_ci } else { 59062306a36Sopenharmony_ci print @_; 59162306a36Sopenharmony_ci } 59262306a36Sopenharmony_ci} 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_cisub doprint { 59562306a36Sopenharmony_ci print @_; 59662306a36Sopenharmony_ci _logit @_; 59762306a36Sopenharmony_ci} 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_cisub read_prompt { 60062306a36Sopenharmony_ci my ($cancel, $prompt) = @_; 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci my $ans; 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci for (;;) { 60562306a36Sopenharmony_ci if ($cancel) { 60662306a36Sopenharmony_ci print "$prompt [y/n/C] "; 60762306a36Sopenharmony_ci } else { 60862306a36Sopenharmony_ci print "$prompt [Y/n] "; 60962306a36Sopenharmony_ci } 61062306a36Sopenharmony_ci $ans = <STDIN>; 61162306a36Sopenharmony_ci chomp $ans; 61262306a36Sopenharmony_ci if ($ans =~ /^\s*$/) { 61362306a36Sopenharmony_ci if ($cancel) { 61462306a36Sopenharmony_ci $ans = "c"; 61562306a36Sopenharmony_ci } else { 61662306a36Sopenharmony_ci $ans = "y"; 61762306a36Sopenharmony_ci } 61862306a36Sopenharmony_ci } 61962306a36Sopenharmony_ci last if ($ans =~ /^y$/i || $ans =~ /^n$/i); 62062306a36Sopenharmony_ci if ($cancel) { 62162306a36Sopenharmony_ci last if ($ans =~ /^c$/i); 62262306a36Sopenharmony_ci print "Please answer either 'y', 'n' or 'c'.\n"; 62362306a36Sopenharmony_ci } else { 62462306a36Sopenharmony_ci print "Please answer either 'y' or 'n'.\n"; 62562306a36Sopenharmony_ci } 62662306a36Sopenharmony_ci } 62762306a36Sopenharmony_ci if ($ans =~ /^c/i) { 62862306a36Sopenharmony_ci exit; 62962306a36Sopenharmony_ci } 63062306a36Sopenharmony_ci if ($ans !~ /^y$/i) { 63162306a36Sopenharmony_ci return 0; 63262306a36Sopenharmony_ci } 63362306a36Sopenharmony_ci return 1; 63462306a36Sopenharmony_ci} 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_cisub read_yn { 63762306a36Sopenharmony_ci my ($prompt) = @_; 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_ci return read_prompt 0, $prompt; 64062306a36Sopenharmony_ci} 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_cisub read_ync { 64362306a36Sopenharmony_ci my ($prompt) = @_; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci return read_prompt 1, $prompt; 64662306a36Sopenharmony_ci} 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_cisub get_mandatory_config { 64962306a36Sopenharmony_ci my ($config) = @_; 65062306a36Sopenharmony_ci my $ans; 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci return if (defined($opt{$config})); 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci if (defined($config_help{$config})) { 65562306a36Sopenharmony_ci print "\n"; 65662306a36Sopenharmony_ci print $config_help{$config}; 65762306a36Sopenharmony_ci } 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci for (;;) { 66062306a36Sopenharmony_ci print "$config = "; 66162306a36Sopenharmony_ci if (defined($default{$config}) && length($default{$config})) { 66262306a36Sopenharmony_ci print "\[$default{$config}\] "; 66362306a36Sopenharmony_ci } 66462306a36Sopenharmony_ci $ans = <STDIN>; 66562306a36Sopenharmony_ci $ans =~ s/^\s*(.*\S)\s*$/$1/; 66662306a36Sopenharmony_ci if ($ans =~ /^\s*$/) { 66762306a36Sopenharmony_ci if ($default{$config}) { 66862306a36Sopenharmony_ci $ans = $default{$config}; 66962306a36Sopenharmony_ci } else { 67062306a36Sopenharmony_ci print "Your answer can not be blank\n"; 67162306a36Sopenharmony_ci next; 67262306a36Sopenharmony_ci } 67362306a36Sopenharmony_ci } 67462306a36Sopenharmony_ci $entered_configs{$config} = ${ans}; 67562306a36Sopenharmony_ci last; 67662306a36Sopenharmony_ci } 67762306a36Sopenharmony_ci} 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_cisub show_time { 68062306a36Sopenharmony_ci my ($time) = @_; 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci my $hours = 0; 68362306a36Sopenharmony_ci my $minutes = 0; 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci if ($time > 3600) { 68662306a36Sopenharmony_ci $hours = int($time / 3600); 68762306a36Sopenharmony_ci $time -= $hours * 3600; 68862306a36Sopenharmony_ci } 68962306a36Sopenharmony_ci if ($time > 60) { 69062306a36Sopenharmony_ci $minutes = int($time / 60); 69162306a36Sopenharmony_ci $time -= $minutes * 60; 69262306a36Sopenharmony_ci } 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci if ($hours > 0) { 69562306a36Sopenharmony_ci doprint "$hours hour"; 69662306a36Sopenharmony_ci doprint "s" if ($hours > 1); 69762306a36Sopenharmony_ci doprint " "; 69862306a36Sopenharmony_ci } 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci if ($minutes > 0) { 70162306a36Sopenharmony_ci doprint "$minutes minute"; 70262306a36Sopenharmony_ci doprint "s" if ($minutes > 1); 70362306a36Sopenharmony_ci doprint " "; 70462306a36Sopenharmony_ci } 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci doprint "$time second"; 70762306a36Sopenharmony_ci doprint "s" if ($time != 1); 70862306a36Sopenharmony_ci} 70962306a36Sopenharmony_ci 71062306a36Sopenharmony_cisub print_times { 71162306a36Sopenharmony_ci doprint "\n"; 71262306a36Sopenharmony_ci if ($build_time) { 71362306a36Sopenharmony_ci doprint "Build time: "; 71462306a36Sopenharmony_ci show_time($build_time); 71562306a36Sopenharmony_ci doprint "\n"; 71662306a36Sopenharmony_ci } 71762306a36Sopenharmony_ci if ($install_time) { 71862306a36Sopenharmony_ci doprint "Install time: "; 71962306a36Sopenharmony_ci show_time($install_time); 72062306a36Sopenharmony_ci doprint "\n"; 72162306a36Sopenharmony_ci } 72262306a36Sopenharmony_ci if ($reboot_time) { 72362306a36Sopenharmony_ci doprint "Reboot time: "; 72462306a36Sopenharmony_ci show_time($reboot_time); 72562306a36Sopenharmony_ci doprint "\n"; 72662306a36Sopenharmony_ci } 72762306a36Sopenharmony_ci if ($test_time) { 72862306a36Sopenharmony_ci doprint "Test time: "; 72962306a36Sopenharmony_ci show_time($test_time); 73062306a36Sopenharmony_ci doprint "\n"; 73162306a36Sopenharmony_ci } 73262306a36Sopenharmony_ci # reset for iterations like bisect 73362306a36Sopenharmony_ci $build_time = 0; 73462306a36Sopenharmony_ci $install_time = 0; 73562306a36Sopenharmony_ci $reboot_time = 0; 73662306a36Sopenharmony_ci $test_time = 0; 73762306a36Sopenharmony_ci} 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_cisub get_mandatory_configs { 74062306a36Sopenharmony_ci get_mandatory_config("MACHINE"); 74162306a36Sopenharmony_ci get_mandatory_config("BUILD_DIR"); 74262306a36Sopenharmony_ci get_mandatory_config("OUTPUT_DIR"); 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ci if ($newconfig) { 74562306a36Sopenharmony_ci get_mandatory_config("BUILD_OPTIONS"); 74662306a36Sopenharmony_ci } 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci # options required for other than just building a kernel 74962306a36Sopenharmony_ci if (!$buildonly) { 75062306a36Sopenharmony_ci get_mandatory_config("POWER_CYCLE"); 75162306a36Sopenharmony_ci get_mandatory_config("CONSOLE"); 75262306a36Sopenharmony_ci } 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci # options required for install and more 75562306a36Sopenharmony_ci if ($buildonly != 1) { 75662306a36Sopenharmony_ci get_mandatory_config("SSH_USER"); 75762306a36Sopenharmony_ci get_mandatory_config("BUILD_TARGET"); 75862306a36Sopenharmony_ci get_mandatory_config("TARGET_IMAGE"); 75962306a36Sopenharmony_ci } 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_ci get_mandatory_config("LOCALVERSION"); 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci return if ($buildonly); 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_ci my $rtype = $opt{"REBOOT_TYPE"}; 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci if (!defined($rtype)) { 76862306a36Sopenharmony_ci if (!defined($opt{"GRUB_MENU"})) { 76962306a36Sopenharmony_ci get_mandatory_config("REBOOT_TYPE"); 77062306a36Sopenharmony_ci $rtype = $entered_configs{"REBOOT_TYPE"}; 77162306a36Sopenharmony_ci } else { 77262306a36Sopenharmony_ci $rtype = "grub"; 77362306a36Sopenharmony_ci } 77462306a36Sopenharmony_ci } 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci if (($rtype eq "grub") or ($rtype eq "grub2bls")) { 77762306a36Sopenharmony_ci get_mandatory_config("GRUB_MENU"); 77862306a36Sopenharmony_ci } 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ci if ($rtype eq "grub2") { 78162306a36Sopenharmony_ci get_mandatory_config("GRUB_MENU"); 78262306a36Sopenharmony_ci get_mandatory_config("GRUB_FILE"); 78362306a36Sopenharmony_ci } 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci if ($rtype eq "syslinux") { 78662306a36Sopenharmony_ci get_mandatory_config("SYSLINUX_LABEL"); 78762306a36Sopenharmony_ci } 78862306a36Sopenharmony_ci} 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_cisub process_variables { 79162306a36Sopenharmony_ci my ($value, $remove_undef) = @_; 79262306a36Sopenharmony_ci my $retval = ""; 79362306a36Sopenharmony_ci 79462306a36Sopenharmony_ci # We want to check for '\', and it is just easier 79562306a36Sopenharmony_ci # to check the previous characet of '$' and not need 79662306a36Sopenharmony_ci # to worry if '$' is the first character. By adding 79762306a36Sopenharmony_ci # a space to $value, we can just check [^\\]\$ and 79862306a36Sopenharmony_ci # it will still work. 79962306a36Sopenharmony_ci $value = " $value"; 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 80262306a36Sopenharmony_ci my $begin = $1; 80362306a36Sopenharmony_ci my $var = $2; 80462306a36Sopenharmony_ci my $end = $3; 80562306a36Sopenharmony_ci # append beginning of value to retval 80662306a36Sopenharmony_ci $retval = "$retval$begin"; 80762306a36Sopenharmony_ci if ($var =~ s/^shell\s+//) { 80862306a36Sopenharmony_ci $retval = `$var`; 80962306a36Sopenharmony_ci if ($?) { 81062306a36Sopenharmony_ci doprint "WARNING: $var returned an error\n"; 81162306a36Sopenharmony_ci } else { 81262306a36Sopenharmony_ci chomp $retval; 81362306a36Sopenharmony_ci } 81462306a36Sopenharmony_ci } elsif (defined($variable{$var})) { 81562306a36Sopenharmony_ci $retval = "$retval$variable{$var}"; 81662306a36Sopenharmony_ci } elsif (defined($remove_undef) && $remove_undef) { 81762306a36Sopenharmony_ci # for if statements, any variable that is not defined, 81862306a36Sopenharmony_ci # we simple convert to 0 81962306a36Sopenharmony_ci $retval = "${retval}0"; 82062306a36Sopenharmony_ci } else { 82162306a36Sopenharmony_ci # put back the origin piece. 82262306a36Sopenharmony_ci $retval = "$retval\$\{$var\}"; 82362306a36Sopenharmony_ci # This could be an option that is used later, save 82462306a36Sopenharmony_ci # it so we don't warn if this option is not one of 82562306a36Sopenharmony_ci # ktests options. 82662306a36Sopenharmony_ci $used_options{$var} = 1; 82762306a36Sopenharmony_ci } 82862306a36Sopenharmony_ci $value = $end; 82962306a36Sopenharmony_ci } 83062306a36Sopenharmony_ci $retval = "$retval$value"; 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci # remove the space added in the beginning 83362306a36Sopenharmony_ci $retval =~ s/ //; 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci return "$retval"; 83662306a36Sopenharmony_ci} 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_cisub set_value { 83962306a36Sopenharmony_ci my ($lvalue, $rvalue, $override, $overrides, $name) = @_; 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci my $prvalue = process_variables($rvalue); 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci if ($lvalue =~ /^(TEST|BISECT|CONFIG_BISECT)_TYPE(\[.*\])?$/ && 84462306a36Sopenharmony_ci $prvalue !~ /^(config_|)bisect$/ && 84562306a36Sopenharmony_ci $prvalue !~ /^build$/ && 84662306a36Sopenharmony_ci $buildonly) { 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_ci # Note if a test is something other than build, then we 84962306a36Sopenharmony_ci # will need other mandatory options. 85062306a36Sopenharmony_ci if ($prvalue ne "install") { 85162306a36Sopenharmony_ci $buildonly = 0; 85262306a36Sopenharmony_ci } else { 85362306a36Sopenharmony_ci # install still limits some mandatory options. 85462306a36Sopenharmony_ci $buildonly = 2; 85562306a36Sopenharmony_ci } 85662306a36Sopenharmony_ci } 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci if (defined($opt{$lvalue})) { 85962306a36Sopenharmony_ci if (!$override || defined(${$overrides}{$lvalue})) { 86062306a36Sopenharmony_ci my $extra = ""; 86162306a36Sopenharmony_ci if ($override) { 86262306a36Sopenharmony_ci $extra = "In the same override section!\n"; 86362306a36Sopenharmony_ci } 86462306a36Sopenharmony_ci die "$name: $.: Option $lvalue defined more than once!\n$extra"; 86562306a36Sopenharmony_ci } 86662306a36Sopenharmony_ci ${$overrides}{$lvalue} = $prvalue; 86762306a36Sopenharmony_ci } 86862306a36Sopenharmony_ci 86962306a36Sopenharmony_ci $opt{$lvalue} = $prvalue; 87062306a36Sopenharmony_ci} 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_cisub set_eval { 87362306a36Sopenharmony_ci my ($lvalue, $rvalue, $name) = @_; 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci my $prvalue = process_variables($rvalue); 87662306a36Sopenharmony_ci my $arr; 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_ci if (defined($evals{$lvalue})) { 87962306a36Sopenharmony_ci $arr = $evals{$lvalue}; 88062306a36Sopenharmony_ci } else { 88162306a36Sopenharmony_ci $arr = []; 88262306a36Sopenharmony_ci $evals{$lvalue} = $arr; 88362306a36Sopenharmony_ci } 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_ci push @{$arr}, $rvalue; 88662306a36Sopenharmony_ci} 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_cisub set_variable { 88962306a36Sopenharmony_ci my ($lvalue, $rvalue) = @_; 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci if ($rvalue =~ /^\s*$/) { 89262306a36Sopenharmony_ci delete $variable{$lvalue}; 89362306a36Sopenharmony_ci } else { 89462306a36Sopenharmony_ci $rvalue = process_variables($rvalue); 89562306a36Sopenharmony_ci $variable{$lvalue} = $rvalue; 89662306a36Sopenharmony_ci } 89762306a36Sopenharmony_ci} 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_cisub process_compare { 90062306a36Sopenharmony_ci my ($lval, $cmp, $rval) = @_; 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci # remove whitespace 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ci $lval =~ s/^\s*//; 90562306a36Sopenharmony_ci $lval =~ s/\s*$//; 90662306a36Sopenharmony_ci 90762306a36Sopenharmony_ci $rval =~ s/^\s*//; 90862306a36Sopenharmony_ci $rval =~ s/\s*$//; 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_ci if ($cmp eq "==") { 91162306a36Sopenharmony_ci return $lval eq $rval; 91262306a36Sopenharmony_ci } elsif ($cmp eq "!=") { 91362306a36Sopenharmony_ci return $lval ne $rval; 91462306a36Sopenharmony_ci } elsif ($cmp eq "=~") { 91562306a36Sopenharmony_ci return $lval =~ m/$rval/; 91662306a36Sopenharmony_ci } elsif ($cmp eq "!~") { 91762306a36Sopenharmony_ci return $lval !~ m/$rval/; 91862306a36Sopenharmony_ci } 91962306a36Sopenharmony_ci 92062306a36Sopenharmony_ci my $statement = "$lval $cmp $rval"; 92162306a36Sopenharmony_ci my $ret = eval $statement; 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci # $@ stores error of eval 92462306a36Sopenharmony_ci if ($@) { 92562306a36Sopenharmony_ci return -1; 92662306a36Sopenharmony_ci } 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci return $ret; 92962306a36Sopenharmony_ci} 93062306a36Sopenharmony_ci 93162306a36Sopenharmony_cisub value_defined { 93262306a36Sopenharmony_ci my ($val) = @_; 93362306a36Sopenharmony_ci 93462306a36Sopenharmony_ci return defined($variable{$2}) || 93562306a36Sopenharmony_ci defined($opt{$2}); 93662306a36Sopenharmony_ci} 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_cisub process_expression { 93962306a36Sopenharmony_ci my ($name, $val) = @_; 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci my $c = $d++; 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ci while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) { 94462306a36Sopenharmony_ci my $express = $1; 94562306a36Sopenharmony_ci 94662306a36Sopenharmony_ci if (process_expression($name, $express)) { 94762306a36Sopenharmony_ci $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /; 94862306a36Sopenharmony_ci } else { 94962306a36Sopenharmony_ci $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /; 95062306a36Sopenharmony_ci } 95162306a36Sopenharmony_ci } 95262306a36Sopenharmony_ci 95362306a36Sopenharmony_ci $d--; 95462306a36Sopenharmony_ci my $OR = "\\|\\|"; 95562306a36Sopenharmony_ci my $AND = "\\&\\&"; 95662306a36Sopenharmony_ci 95762306a36Sopenharmony_ci while ($val =~ s/^(.*?)($OR|$AND)//) { 95862306a36Sopenharmony_ci my $express = $1; 95962306a36Sopenharmony_ci my $op = $2; 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci if (process_expression($name, $express)) { 96262306a36Sopenharmony_ci if ($op eq "||") { 96362306a36Sopenharmony_ci return 1; 96462306a36Sopenharmony_ci } 96562306a36Sopenharmony_ci } else { 96662306a36Sopenharmony_ci if ($op eq "&&") { 96762306a36Sopenharmony_ci return 0; 96862306a36Sopenharmony_ci } 96962306a36Sopenharmony_ci } 97062306a36Sopenharmony_ci } 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) { 97362306a36Sopenharmony_ci my $ret = process_compare($1, $2, $3); 97462306a36Sopenharmony_ci if ($ret < 0) { 97562306a36Sopenharmony_ci die "$name: $.: Unable to process comparison\n"; 97662306a36Sopenharmony_ci } 97762306a36Sopenharmony_ci return $ret; 97862306a36Sopenharmony_ci } 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) { 98162306a36Sopenharmony_ci if (defined $1) { 98262306a36Sopenharmony_ci return !value_defined($2); 98362306a36Sopenharmony_ci } else { 98462306a36Sopenharmony_ci return value_defined($2); 98562306a36Sopenharmony_ci } 98662306a36Sopenharmony_ci } 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci if ($val =~ s/^\s*NOT\s+(.*)//) { 98962306a36Sopenharmony_ci my $express = $1; 99062306a36Sopenharmony_ci my $ret = process_expression($name, $express); 99162306a36Sopenharmony_ci return !$ret; 99262306a36Sopenharmony_ci } 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_ci if ($val =~ /^\s*0\s*$/) { 99562306a36Sopenharmony_ci return 0; 99662306a36Sopenharmony_ci } elsif ($val =~ /^\s*\d+\s*$/) { 99762306a36Sopenharmony_ci return 1; 99862306a36Sopenharmony_ci } 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_ci die ("$name: $.: Undefined content $val in if statement\n"); 100162306a36Sopenharmony_ci} 100262306a36Sopenharmony_ci 100362306a36Sopenharmony_cisub process_if { 100462306a36Sopenharmony_ci my ($name, $value) = @_; 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci # Convert variables and replace undefined ones with 0 100762306a36Sopenharmony_ci my $val = process_variables($value, 1); 100862306a36Sopenharmony_ci my $ret = process_expression $name, $val; 100962306a36Sopenharmony_ci 101062306a36Sopenharmony_ci return $ret; 101162306a36Sopenharmony_ci} 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_cisub __read_config { 101462306a36Sopenharmony_ci my ($config, $current_test_num) = @_; 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci my $in; 101762306a36Sopenharmony_ci open($in, $config) || die "can't read file $config"; 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci my $name = $config; 102062306a36Sopenharmony_ci $name =~ s,.*/(.*),$1,; 102162306a36Sopenharmony_ci 102262306a36Sopenharmony_ci my $test_num = $$current_test_num; 102362306a36Sopenharmony_ci my $default = 1; 102462306a36Sopenharmony_ci my $repeat = 1; 102562306a36Sopenharmony_ci my $num_tests_set = 0; 102662306a36Sopenharmony_ci my $skip = 0; 102762306a36Sopenharmony_ci my $rest; 102862306a36Sopenharmony_ci my $line; 102962306a36Sopenharmony_ci my $test_case = 0; 103062306a36Sopenharmony_ci my $if = 0; 103162306a36Sopenharmony_ci my $if_set = 0; 103262306a36Sopenharmony_ci my $override = 0; 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_ci my %overrides; 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci while (<$in>) { 103762306a36Sopenharmony_ci 103862306a36Sopenharmony_ci # ignore blank lines and comments 103962306a36Sopenharmony_ci next if (/^\s*$/ || /\s*\#/); 104062306a36Sopenharmony_ci 104162306a36Sopenharmony_ci if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) { 104262306a36Sopenharmony_ci 104362306a36Sopenharmony_ci my $type = $1; 104462306a36Sopenharmony_ci $rest = $2; 104562306a36Sopenharmony_ci $line = $2; 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ci my $old_test_num; 104862306a36Sopenharmony_ci my $old_repeat; 104962306a36Sopenharmony_ci $override = 0; 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_ci if ($type eq "TEST_START") { 105262306a36Sopenharmony_ci if ($num_tests_set) { 105362306a36Sopenharmony_ci die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 105462306a36Sopenharmony_ci } 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci $old_test_num = $test_num; 105762306a36Sopenharmony_ci $old_repeat = $repeat; 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci $test_num += $repeat; 106062306a36Sopenharmony_ci $default = 0; 106162306a36Sopenharmony_ci $repeat = 1; 106262306a36Sopenharmony_ci } else { 106362306a36Sopenharmony_ci $default = 1; 106462306a36Sopenharmony_ci } 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_ci # If SKIP is anywhere in the line, the command will be skipped 106762306a36Sopenharmony_ci if ($rest =~ s/\s+SKIP\b//) { 106862306a36Sopenharmony_ci $skip = 1; 106962306a36Sopenharmony_ci } else { 107062306a36Sopenharmony_ci $test_case = 1; 107162306a36Sopenharmony_ci $skip = 0; 107262306a36Sopenharmony_ci } 107362306a36Sopenharmony_ci 107462306a36Sopenharmony_ci if ($rest =~ s/\sELSE\b//) { 107562306a36Sopenharmony_ci if (!$if) { 107662306a36Sopenharmony_ci die "$name: $.: ELSE found with out matching IF section\n$_"; 107762306a36Sopenharmony_ci } 107862306a36Sopenharmony_ci $if = 0; 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_ci if ($if_set) { 108162306a36Sopenharmony_ci $skip = 1; 108262306a36Sopenharmony_ci } else { 108362306a36Sopenharmony_ci $skip = 0; 108462306a36Sopenharmony_ci } 108562306a36Sopenharmony_ci } 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci if ($rest =~ s/\sIF\s+(.*)//) { 108862306a36Sopenharmony_ci if (process_if($name, $1)) { 108962306a36Sopenharmony_ci $if_set = 1; 109062306a36Sopenharmony_ci } else { 109162306a36Sopenharmony_ci $skip = 1; 109262306a36Sopenharmony_ci } 109362306a36Sopenharmony_ci $if = 1; 109462306a36Sopenharmony_ci } else { 109562306a36Sopenharmony_ci $if = 0; 109662306a36Sopenharmony_ci $if_set = 0; 109762306a36Sopenharmony_ci } 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_ci if (!$skip) { 110062306a36Sopenharmony_ci if ($type eq "TEST_START") { 110162306a36Sopenharmony_ci if ($rest =~ s/\s+ITERATE\s+(\d+)//) { 110262306a36Sopenharmony_ci $repeat = $1; 110362306a36Sopenharmony_ci $repeat_tests{"$test_num"} = $repeat; 110462306a36Sopenharmony_ci } 110562306a36Sopenharmony_ci } elsif ($rest =~ s/\sOVERRIDE\b//) { 110662306a36Sopenharmony_ci # DEFAULT only 110762306a36Sopenharmony_ci $override = 1; 110862306a36Sopenharmony_ci # Clear previous overrides 110962306a36Sopenharmony_ci %overrides = (); 111062306a36Sopenharmony_ci } 111162306a36Sopenharmony_ci } 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci if (!$skip && $rest !~ /^\s*$/) { 111462306a36Sopenharmony_ci die "$name: $.: Garbage found after $type\n$_"; 111562306a36Sopenharmony_ci } 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci if ($skip && $type eq "TEST_START") { 111862306a36Sopenharmony_ci $test_num = $old_test_num; 111962306a36Sopenharmony_ci $repeat = $old_repeat; 112062306a36Sopenharmony_ci } 112162306a36Sopenharmony_ci } elsif (/^\s*ELSE\b(.*)$/) { 112262306a36Sopenharmony_ci if (!$if) { 112362306a36Sopenharmony_ci die "$name: $.: ELSE found with out matching IF section\n$_"; 112462306a36Sopenharmony_ci } 112562306a36Sopenharmony_ci $rest = $1; 112662306a36Sopenharmony_ci if ($if_set) { 112762306a36Sopenharmony_ci $skip = 1; 112862306a36Sopenharmony_ci $rest = ""; 112962306a36Sopenharmony_ci } else { 113062306a36Sopenharmony_ci $skip = 0; 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_ci if ($rest =~ /\sIF\s+(.*)/) { 113362306a36Sopenharmony_ci # May be a ELSE IF section. 113462306a36Sopenharmony_ci if (process_if($name, $1)) { 113562306a36Sopenharmony_ci $if_set = 1; 113662306a36Sopenharmony_ci } else { 113762306a36Sopenharmony_ci $skip = 1; 113862306a36Sopenharmony_ci } 113962306a36Sopenharmony_ci $rest = ""; 114062306a36Sopenharmony_ci } else { 114162306a36Sopenharmony_ci $if = 0; 114262306a36Sopenharmony_ci } 114362306a36Sopenharmony_ci } 114462306a36Sopenharmony_ci 114562306a36Sopenharmony_ci if ($rest !~ /^\s*$/) { 114662306a36Sopenharmony_ci die "$name: $.: Garbage found after DEFAULTS\n$_"; 114762306a36Sopenharmony_ci } 114862306a36Sopenharmony_ci 114962306a36Sopenharmony_ci } elsif (/^\s*INCLUDE\s+(\S+)/) { 115062306a36Sopenharmony_ci 115162306a36Sopenharmony_ci next if ($skip); 115262306a36Sopenharmony_ci 115362306a36Sopenharmony_ci if (!$default) { 115462306a36Sopenharmony_ci die "$name: $.: INCLUDE can only be done in default sections\n$_"; 115562306a36Sopenharmony_ci } 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci my $file = process_variables($1); 115862306a36Sopenharmony_ci 115962306a36Sopenharmony_ci if ($file !~ m,^/,) { 116062306a36Sopenharmony_ci # check the path of the config file first 116162306a36Sopenharmony_ci if ($config =~ m,(.*)/,) { 116262306a36Sopenharmony_ci if (-f "$1/$file") { 116362306a36Sopenharmony_ci $file = "$1/$file"; 116462306a36Sopenharmony_ci } 116562306a36Sopenharmony_ci } 116662306a36Sopenharmony_ci } 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_ci if ( ! -r $file ) { 116962306a36Sopenharmony_ci die "$name: $.: Can't read file $file\n$_"; 117062306a36Sopenharmony_ci } 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ci if (__read_config($file, \$test_num)) { 117362306a36Sopenharmony_ci $test_case = 1; 117462306a36Sopenharmony_ci } 117562306a36Sopenharmony_ci 117662306a36Sopenharmony_ci } elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) { 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_ci next if ($skip); 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci my $lvalue = $1; 118162306a36Sopenharmony_ci my $rvalue = $2; 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_ci if ($default || $lvalue =~ /\[\d+\]$/) { 118462306a36Sopenharmony_ci set_eval($lvalue, $rvalue, $name); 118562306a36Sopenharmony_ci } else { 118662306a36Sopenharmony_ci my $val = "$lvalue\[$test_num\]"; 118762306a36Sopenharmony_ci set_eval($val, $rvalue, $name); 118862306a36Sopenharmony_ci } 118962306a36Sopenharmony_ci 119062306a36Sopenharmony_ci } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 119162306a36Sopenharmony_ci 119262306a36Sopenharmony_ci next if ($skip); 119362306a36Sopenharmony_ci 119462306a36Sopenharmony_ci my $lvalue = $1; 119562306a36Sopenharmony_ci my $rvalue = $2; 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_ci if (!$default && 119862306a36Sopenharmony_ci ($lvalue eq "NUM_TESTS" || 119962306a36Sopenharmony_ci $lvalue eq "LOG_FILE" || 120062306a36Sopenharmony_ci $lvalue eq "CLEAR_LOG")) { 120162306a36Sopenharmony_ci die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 120262306a36Sopenharmony_ci } 120362306a36Sopenharmony_ci 120462306a36Sopenharmony_ci if ($lvalue eq "NUM_TESTS") { 120562306a36Sopenharmony_ci if ($test_num) { 120662306a36Sopenharmony_ci die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 120762306a36Sopenharmony_ci } 120862306a36Sopenharmony_ci if (!$default) { 120962306a36Sopenharmony_ci die "$name: $.: NUM_TESTS must be set in default section\n"; 121062306a36Sopenharmony_ci } 121162306a36Sopenharmony_ci $num_tests_set = 1; 121262306a36Sopenharmony_ci } 121362306a36Sopenharmony_ci 121462306a36Sopenharmony_ci if ($default || $lvalue =~ /\[\d+\]$/) { 121562306a36Sopenharmony_ci set_value($lvalue, $rvalue, $override, \%overrides, $name); 121662306a36Sopenharmony_ci } else { 121762306a36Sopenharmony_ci my $val = "$lvalue\[$test_num\]"; 121862306a36Sopenharmony_ci set_value($val, $rvalue, $override, \%overrides, $name); 121962306a36Sopenharmony_ci 122062306a36Sopenharmony_ci if ($repeat > 1) { 122162306a36Sopenharmony_ci $repeats{$val} = $repeat; 122262306a36Sopenharmony_ci } 122362306a36Sopenharmony_ci } 122462306a36Sopenharmony_ci } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) { 122562306a36Sopenharmony_ci next if ($skip); 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_ci my $lvalue = $1; 122862306a36Sopenharmony_ci my $rvalue = $2; 122962306a36Sopenharmony_ci 123062306a36Sopenharmony_ci # process config variables. 123162306a36Sopenharmony_ci # Config variables are only active while reading the 123262306a36Sopenharmony_ci # config and can be defined anywhere. They also ignore 123362306a36Sopenharmony_ci # TEST_START and DEFAULTS, but are skipped if they are in 123462306a36Sopenharmony_ci # on of these sections that have SKIP defined. 123562306a36Sopenharmony_ci # The save variable can be 123662306a36Sopenharmony_ci # defined multiple times and the new one simply overrides 123762306a36Sopenharmony_ci # the previous one. 123862306a36Sopenharmony_ci set_variable($lvalue, $rvalue); 123962306a36Sopenharmony_ci 124062306a36Sopenharmony_ci } else { 124162306a36Sopenharmony_ci die "$name: $.: Garbage found in config\n$_"; 124262306a36Sopenharmony_ci } 124362306a36Sopenharmony_ci } 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci if ($test_num) { 124662306a36Sopenharmony_ci $test_num += $repeat - 1; 124762306a36Sopenharmony_ci $opt{"NUM_TESTS"} = $test_num; 124862306a36Sopenharmony_ci } 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_ci close($in); 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_ci $$current_test_num = $test_num; 125362306a36Sopenharmony_ci 125462306a36Sopenharmony_ci return $test_case; 125562306a36Sopenharmony_ci} 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_cisub get_test_case { 125862306a36Sopenharmony_ci print "What test case would you like to run?\n"; 125962306a36Sopenharmony_ci print " (build, install or boot)\n"; 126062306a36Sopenharmony_ci print " Other tests are available but require editing ktest.conf\n"; 126162306a36Sopenharmony_ci print " (see tools/testing/ktest/sample.conf)\n"; 126262306a36Sopenharmony_ci my $ans = <STDIN>; 126362306a36Sopenharmony_ci chomp $ans; 126462306a36Sopenharmony_ci $default{"TEST_TYPE"} = $ans; 126562306a36Sopenharmony_ci} 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_cisub read_config { 126862306a36Sopenharmony_ci my ($config) = @_; 126962306a36Sopenharmony_ci 127062306a36Sopenharmony_ci my $test_case; 127162306a36Sopenharmony_ci my $test_num = 0; 127262306a36Sopenharmony_ci 127362306a36Sopenharmony_ci $test_case = __read_config $config, \$test_num; 127462306a36Sopenharmony_ci 127562306a36Sopenharmony_ci # make sure we have all mandatory configs 127662306a36Sopenharmony_ci get_mandatory_configs; 127762306a36Sopenharmony_ci 127862306a36Sopenharmony_ci # was a test specified? 127962306a36Sopenharmony_ci if (!$test_case) { 128062306a36Sopenharmony_ci print "No test case specified.\n"; 128162306a36Sopenharmony_ci get_test_case; 128262306a36Sopenharmony_ci } 128362306a36Sopenharmony_ci 128462306a36Sopenharmony_ci # set any defaults 128562306a36Sopenharmony_ci 128662306a36Sopenharmony_ci foreach my $default (keys %default) { 128762306a36Sopenharmony_ci if (!defined($opt{$default})) { 128862306a36Sopenharmony_ci $opt{$default} = $default{$default}; 128962306a36Sopenharmony_ci } 129062306a36Sopenharmony_ci } 129162306a36Sopenharmony_ci 129262306a36Sopenharmony_ci if ($opt{"IGNORE_UNUSED"} == 1) { 129362306a36Sopenharmony_ci return; 129462306a36Sopenharmony_ci } 129562306a36Sopenharmony_ci 129662306a36Sopenharmony_ci my %not_used; 129762306a36Sopenharmony_ci 129862306a36Sopenharmony_ci # check if there are any stragglers (typos?) 129962306a36Sopenharmony_ci foreach my $option (keys %opt) { 130062306a36Sopenharmony_ci my $op = $option; 130162306a36Sopenharmony_ci # remove per test labels. 130262306a36Sopenharmony_ci $op =~ s/\[.*\]//; 130362306a36Sopenharmony_ci if (!exists($option_map{$op}) && 130462306a36Sopenharmony_ci !exists($default{$op}) && 130562306a36Sopenharmony_ci !exists($used_options{$op})) { 130662306a36Sopenharmony_ci $not_used{$op} = 1; 130762306a36Sopenharmony_ci } 130862306a36Sopenharmony_ci } 130962306a36Sopenharmony_ci 131062306a36Sopenharmony_ci if (%not_used) { 131162306a36Sopenharmony_ci my $s = "s are"; 131262306a36Sopenharmony_ci $s = " is" if (keys %not_used == 1); 131362306a36Sopenharmony_ci print "The following option$s not used; could be a typo:\n"; 131462306a36Sopenharmony_ci foreach my $option (keys %not_used) { 131562306a36Sopenharmony_ci print "$option\n"; 131662306a36Sopenharmony_ci } 131762306a36Sopenharmony_ci print "Set IGNORE_UNUSED = 1 to have ktest ignore unused variables\n"; 131862306a36Sopenharmony_ci if (!read_yn "Do you want to continue?") { 131962306a36Sopenharmony_ci exit -1; 132062306a36Sopenharmony_ci } 132162306a36Sopenharmony_ci } 132262306a36Sopenharmony_ci} 132362306a36Sopenharmony_ci 132462306a36Sopenharmony_cisub __eval_option { 132562306a36Sopenharmony_ci my ($name, $option, $i) = @_; 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci # Add space to evaluate the character before $ 132862306a36Sopenharmony_ci $option = " $option"; 132962306a36Sopenharmony_ci my $retval = ""; 133062306a36Sopenharmony_ci my $repeated = 0; 133162306a36Sopenharmony_ci my $parent = 0; 133262306a36Sopenharmony_ci 133362306a36Sopenharmony_ci foreach my $test (keys %repeat_tests) { 133462306a36Sopenharmony_ci if ($i >= $test && 133562306a36Sopenharmony_ci $i < $test + $repeat_tests{$test}) { 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci $repeated = 1; 133862306a36Sopenharmony_ci $parent = $test; 133962306a36Sopenharmony_ci last; 134062306a36Sopenharmony_ci } 134162306a36Sopenharmony_ci } 134262306a36Sopenharmony_ci 134362306a36Sopenharmony_ci while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 134462306a36Sopenharmony_ci my $start = $1; 134562306a36Sopenharmony_ci my $var = $2; 134662306a36Sopenharmony_ci my $end = $3; 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_ci # Append beginning of line 134962306a36Sopenharmony_ci $retval = "$retval$start"; 135062306a36Sopenharmony_ci 135162306a36Sopenharmony_ci # If the iteration option OPT[$i] exists, then use that. 135262306a36Sopenharmony_ci # otherwise see if the default OPT (without [$i]) exists. 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci my $o = "$var\[$i\]"; 135562306a36Sopenharmony_ci my $parento = "$var\[$parent\]"; 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ci # If a variable contains itself, use the default var 135862306a36Sopenharmony_ci if (($var eq $name) && defined($opt{$var})) { 135962306a36Sopenharmony_ci $o = $opt{$var}; 136062306a36Sopenharmony_ci $retval = "$retval$o"; 136162306a36Sopenharmony_ci } elsif (defined($opt{$o})) { 136262306a36Sopenharmony_ci $o = $opt{$o}; 136362306a36Sopenharmony_ci $retval = "$retval$o"; 136462306a36Sopenharmony_ci } elsif ($repeated && defined($opt{$parento})) { 136562306a36Sopenharmony_ci $o = $opt{$parento}; 136662306a36Sopenharmony_ci $retval = "$retval$o"; 136762306a36Sopenharmony_ci } elsif (defined($opt{$var})) { 136862306a36Sopenharmony_ci $o = $opt{$var}; 136962306a36Sopenharmony_ci $retval = "$retval$o"; 137062306a36Sopenharmony_ci } elsif ($var eq "KERNEL_VERSION" && defined($make)) { 137162306a36Sopenharmony_ci # special option KERNEL_VERSION uses kernel version 137262306a36Sopenharmony_ci get_version(); 137362306a36Sopenharmony_ci $retval = "$retval$version"; 137462306a36Sopenharmony_ci } else { 137562306a36Sopenharmony_ci $retval = "$retval\$\{$var\}"; 137662306a36Sopenharmony_ci } 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_ci $option = $end; 137962306a36Sopenharmony_ci } 138062306a36Sopenharmony_ci 138162306a36Sopenharmony_ci $retval = "$retval$option"; 138262306a36Sopenharmony_ci 138362306a36Sopenharmony_ci $retval =~ s/^ //; 138462306a36Sopenharmony_ci 138562306a36Sopenharmony_ci return $retval; 138662306a36Sopenharmony_ci} 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_cisub process_evals { 138962306a36Sopenharmony_ci my ($name, $option, $i) = @_; 139062306a36Sopenharmony_ci 139162306a36Sopenharmony_ci my $option_name = "$name\[$i\]"; 139262306a36Sopenharmony_ci my $ev; 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_ci my $old_option = $option; 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_ci if (defined($evals{$option_name})) { 139762306a36Sopenharmony_ci $ev = $evals{$option_name}; 139862306a36Sopenharmony_ci } elsif (defined($evals{$name})) { 139962306a36Sopenharmony_ci $ev = $evals{$name}; 140062306a36Sopenharmony_ci } else { 140162306a36Sopenharmony_ci return $option; 140262306a36Sopenharmony_ci } 140362306a36Sopenharmony_ci 140462306a36Sopenharmony_ci for my $e (@{$ev}) { 140562306a36Sopenharmony_ci eval "\$option =~ $e"; 140662306a36Sopenharmony_ci } 140762306a36Sopenharmony_ci 140862306a36Sopenharmony_ci if ($option ne $old_option) { 140962306a36Sopenharmony_ci doprint("$name changed from '$old_option' to '$option'\n"); 141062306a36Sopenharmony_ci } 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci return $option; 141362306a36Sopenharmony_ci} 141462306a36Sopenharmony_ci 141562306a36Sopenharmony_cisub eval_option { 141662306a36Sopenharmony_ci my ($name, $option, $i) = @_; 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ci my $prev = ""; 141962306a36Sopenharmony_ci 142062306a36Sopenharmony_ci # Since an option can evaluate to another option, 142162306a36Sopenharmony_ci # keep iterating until we do not evaluate any more 142262306a36Sopenharmony_ci # options. 142362306a36Sopenharmony_ci my $r = 0; 142462306a36Sopenharmony_ci while ($prev ne $option) { 142562306a36Sopenharmony_ci # Check for recursive evaluations. 142662306a36Sopenharmony_ci # 100 deep should be more than enough. 142762306a36Sopenharmony_ci if ($r++ > 100) { 142862306a36Sopenharmony_ci die "Over 100 evaluations occurred with $option\n" . 142962306a36Sopenharmony_ci "Check for recursive variables\n"; 143062306a36Sopenharmony_ci } 143162306a36Sopenharmony_ci $prev = $option; 143262306a36Sopenharmony_ci $option = __eval_option($name, $option, $i); 143362306a36Sopenharmony_ci } 143462306a36Sopenharmony_ci 143562306a36Sopenharmony_ci $option = process_evals($name, $option, $i); 143662306a36Sopenharmony_ci 143762306a36Sopenharmony_ci return $option; 143862306a36Sopenharmony_ci} 143962306a36Sopenharmony_ci 144062306a36Sopenharmony_cisub reboot { 144162306a36Sopenharmony_ci my ($time) = @_; 144262306a36Sopenharmony_ci my $powercycle = 0; 144362306a36Sopenharmony_ci 144462306a36Sopenharmony_ci # test if the machine can be connected to within a few seconds 144562306a36Sopenharmony_ci my $stat = run_ssh("echo check machine status", $connect_timeout); 144662306a36Sopenharmony_ci if (!$stat) { 144762306a36Sopenharmony_ci doprint("power cycle\n"); 144862306a36Sopenharmony_ci $powercycle = 1; 144962306a36Sopenharmony_ci } 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_ci if ($powercycle) { 145262306a36Sopenharmony_ci run_command "$power_cycle"; 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_ci start_monitor; 145562306a36Sopenharmony_ci # flush out current monitor 145662306a36Sopenharmony_ci # May contain the reboot success line 145762306a36Sopenharmony_ci wait_for_monitor 1; 145862306a36Sopenharmony_ci 145962306a36Sopenharmony_ci } else { 146062306a36Sopenharmony_ci # Make sure everything has been written to disk 146162306a36Sopenharmony_ci run_ssh("sync", 10); 146262306a36Sopenharmony_ci 146362306a36Sopenharmony_ci if (defined($time)) { 146462306a36Sopenharmony_ci start_monitor; 146562306a36Sopenharmony_ci # flush out current monitor 146662306a36Sopenharmony_ci # May contain the reboot success line 146762306a36Sopenharmony_ci wait_for_monitor 1; 146862306a36Sopenharmony_ci } 146962306a36Sopenharmony_ci 147062306a36Sopenharmony_ci # try to reboot normally 147162306a36Sopenharmony_ci if (run_command $reboot) { 147262306a36Sopenharmony_ci if (defined($powercycle_after_reboot)) { 147362306a36Sopenharmony_ci sleep $powercycle_after_reboot; 147462306a36Sopenharmony_ci run_command "$power_cycle"; 147562306a36Sopenharmony_ci } 147662306a36Sopenharmony_ci } else { 147762306a36Sopenharmony_ci # nope? power cycle it. 147862306a36Sopenharmony_ci run_command "$power_cycle"; 147962306a36Sopenharmony_ci } 148062306a36Sopenharmony_ci } 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci if (defined($time)) { 148362306a36Sopenharmony_ci 148462306a36Sopenharmony_ci # We only want to get to the new kernel, don't fail 148562306a36Sopenharmony_ci # if we stumble over a call trace. 148662306a36Sopenharmony_ci my $save_ignore_errors = $ignore_errors; 148762306a36Sopenharmony_ci $ignore_errors = 1; 148862306a36Sopenharmony_ci 148962306a36Sopenharmony_ci # Look for the good kernel to boot 149062306a36Sopenharmony_ci if (wait_for_monitor($time, "Linux version")) { 149162306a36Sopenharmony_ci # reboot got stuck? 149262306a36Sopenharmony_ci doprint "Reboot did not finish. Forcing power cycle\n"; 149362306a36Sopenharmony_ci run_command "$power_cycle"; 149462306a36Sopenharmony_ci } 149562306a36Sopenharmony_ci 149662306a36Sopenharmony_ci $ignore_errors = $save_ignore_errors; 149762306a36Sopenharmony_ci 149862306a36Sopenharmony_ci # Still need to wait for the reboot to finish 149962306a36Sopenharmony_ci wait_for_monitor($time, $reboot_success_line); 150062306a36Sopenharmony_ci } 150162306a36Sopenharmony_ci if ($powercycle || $time) { 150262306a36Sopenharmony_ci end_monitor; 150362306a36Sopenharmony_ci } 150462306a36Sopenharmony_ci} 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_cisub reboot_to_good { 150762306a36Sopenharmony_ci my ($time) = @_; 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_ci if (defined($switch_to_good)) { 151062306a36Sopenharmony_ci run_command $switch_to_good; 151162306a36Sopenharmony_ci } 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci reboot $time; 151462306a36Sopenharmony_ci} 151562306a36Sopenharmony_ci 151662306a36Sopenharmony_cisub do_not_reboot { 151762306a36Sopenharmony_ci my $i = $iteration; 151862306a36Sopenharmony_ci 151962306a36Sopenharmony_ci return $test_type eq "build" || $no_reboot || 152062306a36Sopenharmony_ci ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 152162306a36Sopenharmony_ci ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build") || 152262306a36Sopenharmony_ci ($test_type eq "config_bisect" && $opt{"CONFIG_BISECT_TYPE[$i]"} eq "build"); 152362306a36Sopenharmony_ci} 152462306a36Sopenharmony_ci 152562306a36Sopenharmony_cisub get_test_name() { 152662306a36Sopenharmony_ci my $name; 152762306a36Sopenharmony_ci 152862306a36Sopenharmony_ci if (defined($test_name)) { 152962306a36Sopenharmony_ci $name = "$test_name:$test_type"; 153062306a36Sopenharmony_ci } else { 153162306a36Sopenharmony_ci $name = $test_type; 153262306a36Sopenharmony_ci } 153362306a36Sopenharmony_ci return $name; 153462306a36Sopenharmony_ci} 153562306a36Sopenharmony_ci 153662306a36Sopenharmony_cisub dodie { 153762306a36Sopenharmony_ci # avoid recursion 153862306a36Sopenharmony_ci return if ($in_die); 153962306a36Sopenharmony_ci $in_die = 1; 154062306a36Sopenharmony_ci 154162306a36Sopenharmony_ci if ($monitor_cnt) { 154262306a36Sopenharmony_ci # restore terminal settings 154362306a36Sopenharmony_ci system("stty $stty_orig"); 154462306a36Sopenharmony_ci } 154562306a36Sopenharmony_ci 154662306a36Sopenharmony_ci my $i = $iteration; 154762306a36Sopenharmony_ci 154862306a36Sopenharmony_ci doprint "CRITICAL FAILURE... [TEST $i] ", @_, "\n"; 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ci if ($reboot_on_error && !do_not_reboot) { 155162306a36Sopenharmony_ci doprint "REBOOTING\n"; 155262306a36Sopenharmony_ci reboot_to_good; 155362306a36Sopenharmony_ci } elsif ($poweroff_on_error && defined($power_off)) { 155462306a36Sopenharmony_ci doprint "POWERING OFF\n"; 155562306a36Sopenharmony_ci `$power_off`; 155662306a36Sopenharmony_ci } 155762306a36Sopenharmony_ci 155862306a36Sopenharmony_ci if (defined($opt{"LOG_FILE"})) { 155962306a36Sopenharmony_ci print " See $opt{LOG_FILE} for more info.\n"; 156062306a36Sopenharmony_ci } 156162306a36Sopenharmony_ci 156262306a36Sopenharmony_ci if ($email_on_error) { 156362306a36Sopenharmony_ci my $name = get_test_name; 156462306a36Sopenharmony_ci my $log_file; 156562306a36Sopenharmony_ci 156662306a36Sopenharmony_ci if (defined($opt{"LOG_FILE"})) { 156762306a36Sopenharmony_ci my $whence = 2; # End of file 156862306a36Sopenharmony_ci my $log_size = tell LOG; 156962306a36Sopenharmony_ci my $size = $log_size - $test_log_start; 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_ci if (defined($mail_max_size)) { 157262306a36Sopenharmony_ci if ($size > $mail_max_size) { 157362306a36Sopenharmony_ci $size = $mail_max_size; 157462306a36Sopenharmony_ci } 157562306a36Sopenharmony_ci } 157662306a36Sopenharmony_ci my $pos = - $size; 157762306a36Sopenharmony_ci $log_file = "$tmpdir/log"; 157862306a36Sopenharmony_ci open (L, "$opt{LOG_FILE}") or die "Can't open $opt{LOG_FILE} to read)"; 157962306a36Sopenharmony_ci open (O, "> $tmpdir/log") or die "Can't open $tmpdir/log\n"; 158062306a36Sopenharmony_ci seek(L, $pos, $whence); 158162306a36Sopenharmony_ci while (<L>) { 158262306a36Sopenharmony_ci print O; 158362306a36Sopenharmony_ci } 158462306a36Sopenharmony_ci close O; 158562306a36Sopenharmony_ci close L; 158662306a36Sopenharmony_ci } 158762306a36Sopenharmony_ci 158862306a36Sopenharmony_ci send_email("KTEST: critical failure for test $i [$name]", 158962306a36Sopenharmony_ci "Your test started at $script_start_time has failed with:\n@_\n", $log_file); 159062306a36Sopenharmony_ci } 159162306a36Sopenharmony_ci 159262306a36Sopenharmony_ci if (defined($post_test)) { 159362306a36Sopenharmony_ci run_command $post_test; 159462306a36Sopenharmony_ci } 159562306a36Sopenharmony_ci 159662306a36Sopenharmony_ci die @_, "\n"; 159762306a36Sopenharmony_ci} 159862306a36Sopenharmony_ci 159962306a36Sopenharmony_cisub create_pty { 160062306a36Sopenharmony_ci my ($ptm, $pts) = @_; 160162306a36Sopenharmony_ci my $tmp; 160262306a36Sopenharmony_ci my $TIOCSPTLCK = 0x40045431; 160362306a36Sopenharmony_ci my $TIOCGPTN = 0x80045430; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or 160662306a36Sopenharmony_ci dodie "Can't open /dev/ptmx"; 160762306a36Sopenharmony_ci 160862306a36Sopenharmony_ci # unlockpt() 160962306a36Sopenharmony_ci $tmp = pack("i", 0); 161062306a36Sopenharmony_ci ioctl($ptm, $TIOCSPTLCK, $tmp) or 161162306a36Sopenharmony_ci dodie "ioctl TIOCSPTLCK for /dev/ptmx failed"; 161262306a36Sopenharmony_ci 161362306a36Sopenharmony_ci # ptsname() 161462306a36Sopenharmony_ci ioctl($ptm, $TIOCGPTN, $tmp) or 161562306a36Sopenharmony_ci dodie "ioctl TIOCGPTN for /dev/ptmx failed"; 161662306a36Sopenharmony_ci $tmp = unpack("i", $tmp); 161762306a36Sopenharmony_ci 161862306a36Sopenharmony_ci sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or 161962306a36Sopenharmony_ci dodie "Can't open /dev/pts/$tmp"; 162062306a36Sopenharmony_ci} 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_cisub exec_console { 162362306a36Sopenharmony_ci my ($ptm, $pts) = @_; 162462306a36Sopenharmony_ci 162562306a36Sopenharmony_ci close($ptm); 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci close(\*STDIN); 162862306a36Sopenharmony_ci close(\*STDOUT); 162962306a36Sopenharmony_ci close(\*STDERR); 163062306a36Sopenharmony_ci 163162306a36Sopenharmony_ci open(\*STDIN, '<&', $pts); 163262306a36Sopenharmony_ci open(\*STDOUT, '>&', $pts); 163362306a36Sopenharmony_ci open(\*STDERR, '>&', $pts); 163462306a36Sopenharmony_ci 163562306a36Sopenharmony_ci close($pts); 163662306a36Sopenharmony_ci 163762306a36Sopenharmony_ci exec $console or 163862306a36Sopenharmony_ci dodie "Can't open console $console"; 163962306a36Sopenharmony_ci} 164062306a36Sopenharmony_ci 164162306a36Sopenharmony_cisub open_console { 164262306a36Sopenharmony_ci my ($ptm) = @_; 164362306a36Sopenharmony_ci my $pts = \*PTSFD; 164462306a36Sopenharmony_ci my $pid; 164562306a36Sopenharmony_ci 164662306a36Sopenharmony_ci # save terminal settings 164762306a36Sopenharmony_ci $stty_orig = `stty -g`; 164862306a36Sopenharmony_ci 164962306a36Sopenharmony_ci # place terminal in cbreak mode so that stdin can be read one character at 165062306a36Sopenharmony_ci # a time without having to wait for a newline 165162306a36Sopenharmony_ci system("stty -icanon -echo -icrnl"); 165262306a36Sopenharmony_ci 165362306a36Sopenharmony_ci create_pty($ptm, $pts); 165462306a36Sopenharmony_ci 165562306a36Sopenharmony_ci $pid = fork; 165662306a36Sopenharmony_ci 165762306a36Sopenharmony_ci if (!$pid) { 165862306a36Sopenharmony_ci # child 165962306a36Sopenharmony_ci exec_console($ptm, $pts) 166062306a36Sopenharmony_ci } 166162306a36Sopenharmony_ci 166262306a36Sopenharmony_ci # parent 166362306a36Sopenharmony_ci close($pts); 166462306a36Sopenharmony_ci 166562306a36Sopenharmony_ci return $pid; 166662306a36Sopenharmony_ci 166762306a36Sopenharmony_ci open(PTSFD, "Stop perl from warning about single use of PTSFD"); 166862306a36Sopenharmony_ci} 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_cisub close_console { 167162306a36Sopenharmony_ci my ($fp, $pid) = @_; 167262306a36Sopenharmony_ci 167362306a36Sopenharmony_ci doprint "kill child process $pid\n"; 167462306a36Sopenharmony_ci kill $close_console_signal, $pid; 167562306a36Sopenharmony_ci 167662306a36Sopenharmony_ci doprint "wait for child process $pid to exit\n"; 167762306a36Sopenharmony_ci waitpid($pid, 0); 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci print "closing!\n"; 168062306a36Sopenharmony_ci close($fp); 168162306a36Sopenharmony_ci 168262306a36Sopenharmony_ci # restore terminal settings 168362306a36Sopenharmony_ci system("stty $stty_orig"); 168462306a36Sopenharmony_ci} 168562306a36Sopenharmony_ci 168662306a36Sopenharmony_cisub start_monitor { 168762306a36Sopenharmony_ci if ($monitor_cnt++) { 168862306a36Sopenharmony_ci return; 168962306a36Sopenharmony_ci } 169062306a36Sopenharmony_ci $monitor_fp = \*MONFD; 169162306a36Sopenharmony_ci $monitor_pid = open_console $monitor_fp; 169262306a36Sopenharmony_ci 169362306a36Sopenharmony_ci return; 169462306a36Sopenharmony_ci 169562306a36Sopenharmony_ci open(MONFD, "Stop perl from warning about single use of MONFD"); 169662306a36Sopenharmony_ci} 169762306a36Sopenharmony_ci 169862306a36Sopenharmony_cisub end_monitor { 169962306a36Sopenharmony_ci return if (!defined $console); 170062306a36Sopenharmony_ci if (--$monitor_cnt) { 170162306a36Sopenharmony_ci return; 170262306a36Sopenharmony_ci } 170362306a36Sopenharmony_ci close_console($monitor_fp, $monitor_pid); 170462306a36Sopenharmony_ci} 170562306a36Sopenharmony_ci 170662306a36Sopenharmony_cisub wait_for_monitor { 170762306a36Sopenharmony_ci my ($time, $stop) = @_; 170862306a36Sopenharmony_ci my $full_line = ""; 170962306a36Sopenharmony_ci my $line; 171062306a36Sopenharmony_ci my $booted = 0; 171162306a36Sopenharmony_ci my $start_time = time; 171262306a36Sopenharmony_ci my $skip_call_trace = 0; 171362306a36Sopenharmony_ci my $bug = 0; 171462306a36Sopenharmony_ci my $bug_ignored = 0; 171562306a36Sopenharmony_ci my $now; 171662306a36Sopenharmony_ci 171762306a36Sopenharmony_ci doprint "** Wait for monitor to settle down **\n"; 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci # read the monitor and wait for the system to calm down 172062306a36Sopenharmony_ci while (!$booted) { 172162306a36Sopenharmony_ci $line = wait_for_input($monitor_fp, $time); 172262306a36Sopenharmony_ci last if (!defined($line)); 172362306a36Sopenharmony_ci print "$line"; 172462306a36Sopenharmony_ci $full_line .= $line; 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_ci if (defined($stop) && $full_line =~ /$stop/) { 172762306a36Sopenharmony_ci doprint "wait for monitor detected $stop\n"; 172862306a36Sopenharmony_ci $booted = 1; 172962306a36Sopenharmony_ci } 173062306a36Sopenharmony_ci 173162306a36Sopenharmony_ci if ($full_line =~ /\[ backtrace testing \]/) { 173262306a36Sopenharmony_ci $skip_call_trace = 1; 173362306a36Sopenharmony_ci } 173462306a36Sopenharmony_ci 173562306a36Sopenharmony_ci if ($full_line =~ /call trace:/i) { 173662306a36Sopenharmony_ci if (!$bug && !$skip_call_trace) { 173762306a36Sopenharmony_ci if ($ignore_errors) { 173862306a36Sopenharmony_ci $bug_ignored = 1; 173962306a36Sopenharmony_ci } else { 174062306a36Sopenharmony_ci $bug = 1; 174162306a36Sopenharmony_ci } 174262306a36Sopenharmony_ci } 174362306a36Sopenharmony_ci } 174462306a36Sopenharmony_ci 174562306a36Sopenharmony_ci if ($full_line =~ /\[ end of backtrace testing \]/) { 174662306a36Sopenharmony_ci $skip_call_trace = 0; 174762306a36Sopenharmony_ci } 174862306a36Sopenharmony_ci 174962306a36Sopenharmony_ci if ($full_line =~ /Kernel panic -/) { 175062306a36Sopenharmony_ci $bug = 1; 175162306a36Sopenharmony_ci } 175262306a36Sopenharmony_ci 175362306a36Sopenharmony_ci if ($line =~ /\n/) { 175462306a36Sopenharmony_ci $full_line = ""; 175562306a36Sopenharmony_ci } 175662306a36Sopenharmony_ci $now = time; 175762306a36Sopenharmony_ci if ($now - $start_time >= $max_monitor_wait) { 175862306a36Sopenharmony_ci doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n"; 175962306a36Sopenharmony_ci return 1; 176062306a36Sopenharmony_ci } 176162306a36Sopenharmony_ci } 176262306a36Sopenharmony_ci print "** Monitor flushed **\n"; 176362306a36Sopenharmony_ci 176462306a36Sopenharmony_ci # if stop is defined but wasn't hit, return error 176562306a36Sopenharmony_ci # used by reboot (which wants to see a reboot) 176662306a36Sopenharmony_ci if (defined($stop) && !$booted) { 176762306a36Sopenharmony_ci $bug = 1; 176862306a36Sopenharmony_ci } 176962306a36Sopenharmony_ci return $bug; 177062306a36Sopenharmony_ci} 177162306a36Sopenharmony_ci 177262306a36Sopenharmony_cisub save_logs { 177362306a36Sopenharmony_ci my ($result, $basedir) = @_; 177462306a36Sopenharmony_ci my @t = localtime; 177562306a36Sopenharmony_ci my $date = sprintf "%04d%02d%02d%02d%02d%02d", 177662306a36Sopenharmony_ci 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 177762306a36Sopenharmony_ci 177862306a36Sopenharmony_ci my $type = $build_type; 177962306a36Sopenharmony_ci if ($type =~ /useconfig/) { 178062306a36Sopenharmony_ci $type = "useconfig"; 178162306a36Sopenharmony_ci } 178262306a36Sopenharmony_ci 178362306a36Sopenharmony_ci my $dir = "$machine-$test_type-$type-$result-$date"; 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci $dir = "$basedir/$dir"; 178662306a36Sopenharmony_ci 178762306a36Sopenharmony_ci if (!-d $dir) { 178862306a36Sopenharmony_ci mkpath($dir) or 178962306a36Sopenharmony_ci dodie "can't create $dir"; 179062306a36Sopenharmony_ci } 179162306a36Sopenharmony_ci 179262306a36Sopenharmony_ci my %files = ( 179362306a36Sopenharmony_ci "config" => $output_config, 179462306a36Sopenharmony_ci "buildlog" => $buildlog, 179562306a36Sopenharmony_ci "dmesg" => $dmesg, 179662306a36Sopenharmony_ci "testlog" => $testlog, 179762306a36Sopenharmony_ci ); 179862306a36Sopenharmony_ci 179962306a36Sopenharmony_ci while (my ($name, $source) = each(%files)) { 180062306a36Sopenharmony_ci if (-f "$source") { 180162306a36Sopenharmony_ci cp "$source", "$dir/$name" or 180262306a36Sopenharmony_ci dodie "failed to copy $source"; 180362306a36Sopenharmony_ci } 180462306a36Sopenharmony_ci } 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_ci doprint "*** Saved info to $dir ***\n"; 180762306a36Sopenharmony_ci} 180862306a36Sopenharmony_ci 180962306a36Sopenharmony_cisub fail { 181062306a36Sopenharmony_ci 181162306a36Sopenharmony_ci if ($die_on_failure) { 181262306a36Sopenharmony_ci dodie @_; 181362306a36Sopenharmony_ci } 181462306a36Sopenharmony_ci 181562306a36Sopenharmony_ci doprint "FAILED\n"; 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci my $i = $iteration; 181862306a36Sopenharmony_ci 181962306a36Sopenharmony_ci # no need to reboot for just building. 182062306a36Sopenharmony_ci if (!do_not_reboot) { 182162306a36Sopenharmony_ci doprint "REBOOTING\n"; 182262306a36Sopenharmony_ci reboot_to_good $sleep_time; 182362306a36Sopenharmony_ci } 182462306a36Sopenharmony_ci 182562306a36Sopenharmony_ci my $name = ""; 182662306a36Sopenharmony_ci 182762306a36Sopenharmony_ci if (defined($test_name)) { 182862306a36Sopenharmony_ci $name = " ($test_name)"; 182962306a36Sopenharmony_ci } 183062306a36Sopenharmony_ci 183162306a36Sopenharmony_ci print_times; 183262306a36Sopenharmony_ci 183362306a36Sopenharmony_ci doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 183462306a36Sopenharmony_ci doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 183562306a36Sopenharmony_ci doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n"; 183662306a36Sopenharmony_ci doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 183762306a36Sopenharmony_ci doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 183862306a36Sopenharmony_ci 183962306a36Sopenharmony_ci if (defined($store_failures)) { 184062306a36Sopenharmony_ci save_logs "fail", $store_failures; 184162306a36Sopenharmony_ci } 184262306a36Sopenharmony_ci 184362306a36Sopenharmony_ci if (defined($post_test)) { 184462306a36Sopenharmony_ci run_command $post_test; 184562306a36Sopenharmony_ci } 184662306a36Sopenharmony_ci 184762306a36Sopenharmony_ci return 1; 184862306a36Sopenharmony_ci} 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_cisub run_command { 185162306a36Sopenharmony_ci my ($command, $redirect, $timeout) = @_; 185262306a36Sopenharmony_ci my $start_time; 185362306a36Sopenharmony_ci my $end_time; 185462306a36Sopenharmony_ci my $dolog = 0; 185562306a36Sopenharmony_ci my $dord = 0; 185662306a36Sopenharmony_ci my $dostdout = 0; 185762306a36Sopenharmony_ci my $pid; 185862306a36Sopenharmony_ci my $command_orig = $command; 185962306a36Sopenharmony_ci 186062306a36Sopenharmony_ci $command =~ s/\$SSH_USER/$ssh_user/g; 186162306a36Sopenharmony_ci $command =~ s/\$MACHINE/$machine/g; 186262306a36Sopenharmony_ci 186362306a36Sopenharmony_ci if (!defined($timeout)) { 186462306a36Sopenharmony_ci $timeout = $run_timeout; 186562306a36Sopenharmony_ci } 186662306a36Sopenharmony_ci 186762306a36Sopenharmony_ci if (!defined($timeout)) { 186862306a36Sopenharmony_ci $timeout = -1; # tell wait_for_input to wait indefinitely 186962306a36Sopenharmony_ci } 187062306a36Sopenharmony_ci 187162306a36Sopenharmony_ci doprint("$command ... "); 187262306a36Sopenharmony_ci $start_time = time; 187362306a36Sopenharmony_ci 187462306a36Sopenharmony_ci $pid = open(CMD, "$command 2>&1 |") or 187562306a36Sopenharmony_ci (fail "unable to exec $command" and return 0); 187662306a36Sopenharmony_ci 187762306a36Sopenharmony_ci if (defined($opt{"LOG_FILE"})) { 187862306a36Sopenharmony_ci $dolog = 1; 187962306a36Sopenharmony_ci } 188062306a36Sopenharmony_ci 188162306a36Sopenharmony_ci if (defined($redirect)) { 188262306a36Sopenharmony_ci if ($redirect eq 1) { 188362306a36Sopenharmony_ci $dostdout = 1; 188462306a36Sopenharmony_ci # Have the output of the command on its own line 188562306a36Sopenharmony_ci doprint "\n"; 188662306a36Sopenharmony_ci } else { 188762306a36Sopenharmony_ci open (RD, ">$redirect") or 188862306a36Sopenharmony_ci dodie "failed to write to redirect $redirect"; 188962306a36Sopenharmony_ci $dord = 1; 189062306a36Sopenharmony_ci } 189162306a36Sopenharmony_ci } 189262306a36Sopenharmony_ci 189362306a36Sopenharmony_ci my $hit_timeout = 0; 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_ci while (1) { 189662306a36Sopenharmony_ci my $fp = \*CMD; 189762306a36Sopenharmony_ci my $line = wait_for_input($fp, $timeout); 189862306a36Sopenharmony_ci if (!defined($line)) { 189962306a36Sopenharmony_ci my $now = time; 190062306a36Sopenharmony_ci if ($timeout >= 0 && (($now - $start_time) >= $timeout)) { 190162306a36Sopenharmony_ci doprint "Hit timeout of $timeout, killing process\n"; 190262306a36Sopenharmony_ci $hit_timeout = 1; 190362306a36Sopenharmony_ci kill 9, $pid; 190462306a36Sopenharmony_ci } 190562306a36Sopenharmony_ci last; 190662306a36Sopenharmony_ci } 190762306a36Sopenharmony_ci print LOG $line if ($dolog); 190862306a36Sopenharmony_ci print RD $line if ($dord); 190962306a36Sopenharmony_ci print $line if ($dostdout); 191062306a36Sopenharmony_ci } 191162306a36Sopenharmony_ci 191262306a36Sopenharmony_ci waitpid($pid, 0); 191362306a36Sopenharmony_ci # shift 8 for real exit status 191462306a36Sopenharmony_ci $run_command_status = $? >> 8; 191562306a36Sopenharmony_ci 191662306a36Sopenharmony_ci if ($command_orig eq $default{REBOOT} && 191762306a36Sopenharmony_ci $run_command_status == $reboot_return_code) { 191862306a36Sopenharmony_ci $run_command_status = 0; 191962306a36Sopenharmony_ci } 192062306a36Sopenharmony_ci 192162306a36Sopenharmony_ci close(CMD); 192262306a36Sopenharmony_ci close(RD) if ($dord); 192362306a36Sopenharmony_ci 192462306a36Sopenharmony_ci $end_time = time; 192562306a36Sopenharmony_ci my $delta = $end_time - $start_time; 192662306a36Sopenharmony_ci 192762306a36Sopenharmony_ci if ($delta == 1) { 192862306a36Sopenharmony_ci doprint "[1 second] "; 192962306a36Sopenharmony_ci } else { 193062306a36Sopenharmony_ci doprint "[$delta seconds] "; 193162306a36Sopenharmony_ci } 193262306a36Sopenharmony_ci 193362306a36Sopenharmony_ci if ($hit_timeout) { 193462306a36Sopenharmony_ci $run_command_status = 1; 193562306a36Sopenharmony_ci } 193662306a36Sopenharmony_ci 193762306a36Sopenharmony_ci if ($run_command_status) { 193862306a36Sopenharmony_ci doprint "FAILED!\n"; 193962306a36Sopenharmony_ci } else { 194062306a36Sopenharmony_ci doprint "SUCCESS\n"; 194162306a36Sopenharmony_ci } 194262306a36Sopenharmony_ci 194362306a36Sopenharmony_ci return !$run_command_status; 194462306a36Sopenharmony_ci} 194562306a36Sopenharmony_ci 194662306a36Sopenharmony_cisub run_ssh { 194762306a36Sopenharmony_ci my ($cmd, $timeout) = @_; 194862306a36Sopenharmony_ci my $cp_exec = $ssh_exec; 194962306a36Sopenharmony_ci 195062306a36Sopenharmony_ci $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 195162306a36Sopenharmony_ci return run_command "$cp_exec", undef , $timeout; 195262306a36Sopenharmony_ci} 195362306a36Sopenharmony_ci 195462306a36Sopenharmony_cisub run_scp { 195562306a36Sopenharmony_ci my ($src, $dst, $cp_scp) = @_; 195662306a36Sopenharmony_ci 195762306a36Sopenharmony_ci $cp_scp =~ s/\$SRC_FILE/$src/g; 195862306a36Sopenharmony_ci $cp_scp =~ s/\$DST_FILE/$dst/g; 195962306a36Sopenharmony_ci 196062306a36Sopenharmony_ci return run_command "$cp_scp"; 196162306a36Sopenharmony_ci} 196262306a36Sopenharmony_ci 196362306a36Sopenharmony_cisub run_scp_install { 196462306a36Sopenharmony_ci my ($src, $dst) = @_; 196562306a36Sopenharmony_ci 196662306a36Sopenharmony_ci my $cp_scp = $scp_to_target_install; 196762306a36Sopenharmony_ci 196862306a36Sopenharmony_ci return run_scp($src, $dst, $cp_scp); 196962306a36Sopenharmony_ci} 197062306a36Sopenharmony_ci 197162306a36Sopenharmony_cisub run_scp_mod { 197262306a36Sopenharmony_ci my ($src, $dst) = @_; 197362306a36Sopenharmony_ci 197462306a36Sopenharmony_ci my $cp_scp = $scp_to_target; 197562306a36Sopenharmony_ci 197662306a36Sopenharmony_ci return run_scp($src, $dst, $cp_scp); 197762306a36Sopenharmony_ci} 197862306a36Sopenharmony_ci 197962306a36Sopenharmony_cisub _get_grub_index { 198062306a36Sopenharmony_ci 198162306a36Sopenharmony_ci my ($command, $target, $skip, $submenu) = @_; 198262306a36Sopenharmony_ci 198362306a36Sopenharmony_ci return if (defined($grub_number) && defined($last_grub_menu) && 198462306a36Sopenharmony_ci $last_grub_menu eq $grub_menu && defined($last_machine) && 198562306a36Sopenharmony_ci $last_machine eq $machine); 198662306a36Sopenharmony_ci 198762306a36Sopenharmony_ci doprint "Find $reboot_type menu ... "; 198862306a36Sopenharmony_ci $grub_number = -1; 198962306a36Sopenharmony_ci 199062306a36Sopenharmony_ci my $ssh_grub = $ssh_exec; 199162306a36Sopenharmony_ci $ssh_grub =~ s,\$SSH_COMMAND,$command,g; 199262306a36Sopenharmony_ci 199362306a36Sopenharmony_ci open(IN, "$ssh_grub |") or 199462306a36Sopenharmony_ci dodie "unable to execute $command"; 199562306a36Sopenharmony_ci 199662306a36Sopenharmony_ci my $found = 0; 199762306a36Sopenharmony_ci 199862306a36Sopenharmony_ci my $submenu_number = 0; 199962306a36Sopenharmony_ci 200062306a36Sopenharmony_ci while (<IN>) { 200162306a36Sopenharmony_ci if (/$target/) { 200262306a36Sopenharmony_ci $grub_number++; 200362306a36Sopenharmony_ci $found = 1; 200462306a36Sopenharmony_ci last; 200562306a36Sopenharmony_ci } elsif (defined($submenu) && /$submenu/) { 200662306a36Sopenharmony_ci $submenu_number++; 200762306a36Sopenharmony_ci $grub_number = -1; 200862306a36Sopenharmony_ci } elsif (/$skip/) { 200962306a36Sopenharmony_ci $grub_number++; 201062306a36Sopenharmony_ci } 201162306a36Sopenharmony_ci } 201262306a36Sopenharmony_ci close(IN); 201362306a36Sopenharmony_ci 201462306a36Sopenharmony_ci dodie "Could not find '$grub_menu' through $command on $machine" 201562306a36Sopenharmony_ci if (!$found); 201662306a36Sopenharmony_ci if ($submenu_number > 0) { 201762306a36Sopenharmony_ci $grub_number = "$submenu_number>$grub_number"; 201862306a36Sopenharmony_ci } 201962306a36Sopenharmony_ci doprint "$grub_number\n"; 202062306a36Sopenharmony_ci $last_grub_menu = $grub_menu; 202162306a36Sopenharmony_ci $last_machine = $machine; 202262306a36Sopenharmony_ci} 202362306a36Sopenharmony_ci 202462306a36Sopenharmony_cisub get_grub_index { 202562306a36Sopenharmony_ci 202662306a36Sopenharmony_ci my $command; 202762306a36Sopenharmony_ci my $target; 202862306a36Sopenharmony_ci my $skip; 202962306a36Sopenharmony_ci my $submenu; 203062306a36Sopenharmony_ci my $grub_menu_qt; 203162306a36Sopenharmony_ci 203262306a36Sopenharmony_ci if ($reboot_type !~ /^grub/) { 203362306a36Sopenharmony_ci return; 203462306a36Sopenharmony_ci } 203562306a36Sopenharmony_ci 203662306a36Sopenharmony_ci $grub_menu_qt = quotemeta($grub_menu); 203762306a36Sopenharmony_ci 203862306a36Sopenharmony_ci if ($reboot_type eq "grub") { 203962306a36Sopenharmony_ci $command = "cat /boot/grub/menu.lst"; 204062306a36Sopenharmony_ci $target = '^\s*title\s+' . $grub_menu_qt . '\s*$'; 204162306a36Sopenharmony_ci $skip = '^\s*title\s'; 204262306a36Sopenharmony_ci } elsif ($reboot_type eq "grub2") { 204362306a36Sopenharmony_ci $command = "cat $grub_file"; 204462306a36Sopenharmony_ci $target = '^\s*menuentry.*' . $grub_menu_qt; 204562306a36Sopenharmony_ci $skip = '^\s*menuentry'; 204662306a36Sopenharmony_ci $submenu = '^\s*submenu\s'; 204762306a36Sopenharmony_ci } elsif ($reboot_type eq "grub2bls") { 204862306a36Sopenharmony_ci $command = $grub_bls_get; 204962306a36Sopenharmony_ci $target = '^title=.*' . $grub_menu_qt; 205062306a36Sopenharmony_ci $skip = '^title='; 205162306a36Sopenharmony_ci } else { 205262306a36Sopenharmony_ci return; 205362306a36Sopenharmony_ci } 205462306a36Sopenharmony_ci 205562306a36Sopenharmony_ci _get_grub_index($command, $target, $skip, $submenu); 205662306a36Sopenharmony_ci} 205762306a36Sopenharmony_ci 205862306a36Sopenharmony_cisub wait_for_input { 205962306a36Sopenharmony_ci my ($fp, $time) = @_; 206062306a36Sopenharmony_ci my $start_time; 206162306a36Sopenharmony_ci my $rin; 206262306a36Sopenharmony_ci my $rout; 206362306a36Sopenharmony_ci my $nr; 206462306a36Sopenharmony_ci my $buf; 206562306a36Sopenharmony_ci my $line; 206662306a36Sopenharmony_ci my $ch; 206762306a36Sopenharmony_ci 206862306a36Sopenharmony_ci if (!defined($time)) { 206962306a36Sopenharmony_ci $time = $timeout; 207062306a36Sopenharmony_ci } 207162306a36Sopenharmony_ci 207262306a36Sopenharmony_ci if ($time < 0) { 207362306a36Sopenharmony_ci # Negative number means wait indefinitely 207462306a36Sopenharmony_ci undef $time; 207562306a36Sopenharmony_ci } 207662306a36Sopenharmony_ci 207762306a36Sopenharmony_ci $rin = ''; 207862306a36Sopenharmony_ci vec($rin, fileno($fp), 1) = 1; 207962306a36Sopenharmony_ci vec($rin, fileno(\*STDIN), 1) = 1; 208062306a36Sopenharmony_ci 208162306a36Sopenharmony_ci $start_time = time; 208262306a36Sopenharmony_ci 208362306a36Sopenharmony_ci while (1) { 208462306a36Sopenharmony_ci $nr = select($rout=$rin, undef, undef, $time); 208562306a36Sopenharmony_ci 208662306a36Sopenharmony_ci last if ($nr <= 0); 208762306a36Sopenharmony_ci 208862306a36Sopenharmony_ci # copy data from stdin to the console 208962306a36Sopenharmony_ci if (vec($rout, fileno(\*STDIN), 1) == 1) { 209062306a36Sopenharmony_ci $nr = sysread(\*STDIN, $buf, 1000); 209162306a36Sopenharmony_ci syswrite($fp, $buf, $nr) if ($nr > 0); 209262306a36Sopenharmony_ci } 209362306a36Sopenharmony_ci 209462306a36Sopenharmony_ci # The timeout is based on time waiting for the fp data 209562306a36Sopenharmony_ci if (vec($rout, fileno($fp), 1) != 1) { 209662306a36Sopenharmony_ci last if (defined($time) && (time - $start_time > $time)); 209762306a36Sopenharmony_ci next; 209862306a36Sopenharmony_ci } 209962306a36Sopenharmony_ci 210062306a36Sopenharmony_ci $line = ""; 210162306a36Sopenharmony_ci 210262306a36Sopenharmony_ci # try to read one char at a time 210362306a36Sopenharmony_ci while (sysread $fp, $ch, 1) { 210462306a36Sopenharmony_ci $line .= $ch; 210562306a36Sopenharmony_ci last if ($ch eq "\n"); 210662306a36Sopenharmony_ci } 210762306a36Sopenharmony_ci 210862306a36Sopenharmony_ci last if (!length($line)); 210962306a36Sopenharmony_ci 211062306a36Sopenharmony_ci return $line; 211162306a36Sopenharmony_ci } 211262306a36Sopenharmony_ci return undef; 211362306a36Sopenharmony_ci} 211462306a36Sopenharmony_ci 211562306a36Sopenharmony_cisub reboot_to { 211662306a36Sopenharmony_ci if (defined($switch_to_test)) { 211762306a36Sopenharmony_ci run_command $switch_to_test; 211862306a36Sopenharmony_ci } 211962306a36Sopenharmony_ci 212062306a36Sopenharmony_ci if ($reboot_type eq "grub") { 212162306a36Sopenharmony_ci run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; 212262306a36Sopenharmony_ci } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) { 212362306a36Sopenharmony_ci run_ssh "$grub_reboot \"'$grub_number'\""; 212462306a36Sopenharmony_ci } elsif ($reboot_type eq "syslinux") { 212562306a36Sopenharmony_ci run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path"; 212662306a36Sopenharmony_ci } elsif (defined $reboot_script) { 212762306a36Sopenharmony_ci run_command "$reboot_script"; 212862306a36Sopenharmony_ci } 212962306a36Sopenharmony_ci reboot; 213062306a36Sopenharmony_ci} 213162306a36Sopenharmony_ci 213262306a36Sopenharmony_cisub get_sha1 { 213362306a36Sopenharmony_ci my ($commit) = @_; 213462306a36Sopenharmony_ci 213562306a36Sopenharmony_ci doprint "git rev-list --max-count=1 $commit ... "; 213662306a36Sopenharmony_ci my $sha1 = `git rev-list --max-count=1 $commit`; 213762306a36Sopenharmony_ci my $ret = $?; 213862306a36Sopenharmony_ci 213962306a36Sopenharmony_ci logit $sha1; 214062306a36Sopenharmony_ci 214162306a36Sopenharmony_ci if ($ret) { 214262306a36Sopenharmony_ci doprint "FAILED\n"; 214362306a36Sopenharmony_ci dodie "Failed to get git $commit"; 214462306a36Sopenharmony_ci } 214562306a36Sopenharmony_ci 214662306a36Sopenharmony_ci print "SUCCESS\n"; 214762306a36Sopenharmony_ci 214862306a36Sopenharmony_ci chomp $sha1; 214962306a36Sopenharmony_ci 215062306a36Sopenharmony_ci return $sha1; 215162306a36Sopenharmony_ci} 215262306a36Sopenharmony_ci 215362306a36Sopenharmony_cisub monitor { 215462306a36Sopenharmony_ci my $booted = 0; 215562306a36Sopenharmony_ci my $bug = 0; 215662306a36Sopenharmony_ci my $bug_ignored = 0; 215762306a36Sopenharmony_ci my $skip_call_trace = 0; 215862306a36Sopenharmony_ci my $loops; 215962306a36Sopenharmony_ci 216062306a36Sopenharmony_ci my $start_time = time; 216162306a36Sopenharmony_ci 216262306a36Sopenharmony_ci wait_for_monitor 5; 216362306a36Sopenharmony_ci 216462306a36Sopenharmony_ci my $line; 216562306a36Sopenharmony_ci my $full_line = ""; 216662306a36Sopenharmony_ci 216762306a36Sopenharmony_ci open(DMESG, "> $dmesg") or 216862306a36Sopenharmony_ci dodie "unable to write to $dmesg"; 216962306a36Sopenharmony_ci 217062306a36Sopenharmony_ci reboot_to; 217162306a36Sopenharmony_ci 217262306a36Sopenharmony_ci my $success_start; 217362306a36Sopenharmony_ci my $failure_start; 217462306a36Sopenharmony_ci my $monitor_start = time; 217562306a36Sopenharmony_ci my $done = 0; 217662306a36Sopenharmony_ci my $version_found = 0; 217762306a36Sopenharmony_ci 217862306a36Sopenharmony_ci while (!$done) { 217962306a36Sopenharmony_ci if ($bug && defined($stop_after_failure) && 218062306a36Sopenharmony_ci $stop_after_failure >= 0) { 218162306a36Sopenharmony_ci my $time = $stop_after_failure - (time - $failure_start); 218262306a36Sopenharmony_ci $line = wait_for_input($monitor_fp, $time); 218362306a36Sopenharmony_ci if (!defined($line)) { 218462306a36Sopenharmony_ci doprint "bug timed out after $booted_timeout seconds\n"; 218562306a36Sopenharmony_ci doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 218662306a36Sopenharmony_ci last; 218762306a36Sopenharmony_ci } 218862306a36Sopenharmony_ci } elsif ($booted) { 218962306a36Sopenharmony_ci $line = wait_for_input($monitor_fp, $booted_timeout); 219062306a36Sopenharmony_ci if (!defined($line)) { 219162306a36Sopenharmony_ci my $s = $booted_timeout == 1 ? "" : "s"; 219262306a36Sopenharmony_ci doprint "Successful boot found: break after $booted_timeout second$s\n"; 219362306a36Sopenharmony_ci last; 219462306a36Sopenharmony_ci } 219562306a36Sopenharmony_ci } else { 219662306a36Sopenharmony_ci $line = wait_for_input($monitor_fp); 219762306a36Sopenharmony_ci if (!defined($line)) { 219862306a36Sopenharmony_ci my $s = $timeout == 1 ? "" : "s"; 219962306a36Sopenharmony_ci doprint "Timed out after $timeout second$s\n"; 220062306a36Sopenharmony_ci last; 220162306a36Sopenharmony_ci } 220262306a36Sopenharmony_ci } 220362306a36Sopenharmony_ci 220462306a36Sopenharmony_ci doprint $line; 220562306a36Sopenharmony_ci print DMESG $line; 220662306a36Sopenharmony_ci 220762306a36Sopenharmony_ci # we are not guaranteed to get a full line 220862306a36Sopenharmony_ci $full_line .= $line; 220962306a36Sopenharmony_ci 221062306a36Sopenharmony_ci if ($full_line =~ /$success_line/) { 221162306a36Sopenharmony_ci $booted = 1; 221262306a36Sopenharmony_ci $success_start = time; 221362306a36Sopenharmony_ci } 221462306a36Sopenharmony_ci 221562306a36Sopenharmony_ci if ($booted && defined($stop_after_success) && 221662306a36Sopenharmony_ci $stop_after_success >= 0) { 221762306a36Sopenharmony_ci my $now = time; 221862306a36Sopenharmony_ci if ($now - $success_start >= $stop_after_success) { 221962306a36Sopenharmony_ci doprint "Test forced to stop after $stop_after_success seconds after success\n"; 222062306a36Sopenharmony_ci last; 222162306a36Sopenharmony_ci } 222262306a36Sopenharmony_ci } 222362306a36Sopenharmony_ci 222462306a36Sopenharmony_ci if ($full_line =~ /\[ backtrace testing \]/) { 222562306a36Sopenharmony_ci $skip_call_trace = 1; 222662306a36Sopenharmony_ci } 222762306a36Sopenharmony_ci 222862306a36Sopenharmony_ci if ($full_line =~ /call trace:/i) { 222962306a36Sopenharmony_ci if (!$bug && !$skip_call_trace) { 223062306a36Sopenharmony_ci if ($ignore_errors) { 223162306a36Sopenharmony_ci $bug_ignored = 1; 223262306a36Sopenharmony_ci } else { 223362306a36Sopenharmony_ci $bug = 1; 223462306a36Sopenharmony_ci $failure_start = time; 223562306a36Sopenharmony_ci } 223662306a36Sopenharmony_ci } 223762306a36Sopenharmony_ci } 223862306a36Sopenharmony_ci 223962306a36Sopenharmony_ci if ($bug && defined($stop_after_failure) && 224062306a36Sopenharmony_ci $stop_after_failure >= 0) { 224162306a36Sopenharmony_ci my $now = time; 224262306a36Sopenharmony_ci if ($now - $failure_start >= $stop_after_failure) { 224362306a36Sopenharmony_ci doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 224462306a36Sopenharmony_ci last; 224562306a36Sopenharmony_ci } 224662306a36Sopenharmony_ci } 224762306a36Sopenharmony_ci 224862306a36Sopenharmony_ci if ($full_line =~ /\[ end of backtrace testing \]/) { 224962306a36Sopenharmony_ci $skip_call_trace = 0; 225062306a36Sopenharmony_ci } 225162306a36Sopenharmony_ci 225262306a36Sopenharmony_ci if ($full_line =~ /Kernel panic -/) { 225362306a36Sopenharmony_ci $failure_start = time; 225462306a36Sopenharmony_ci $bug = 1; 225562306a36Sopenharmony_ci } 225662306a36Sopenharmony_ci 225762306a36Sopenharmony_ci # Detect triple faults by testing the banner 225862306a36Sopenharmony_ci if ($full_line =~ /\bLinux version (\S+).*\n/) { 225962306a36Sopenharmony_ci if ($1 eq $version) { 226062306a36Sopenharmony_ci $version_found = 1; 226162306a36Sopenharmony_ci } elsif ($version_found && $detect_triplefault) { 226262306a36Sopenharmony_ci # We already booted into the kernel we are testing, 226362306a36Sopenharmony_ci # but now we booted into another kernel? 226462306a36Sopenharmony_ci # Consider this a triple fault. 226562306a36Sopenharmony_ci doprint "Already booted in Linux kernel $version, but now\n"; 226662306a36Sopenharmony_ci doprint "we booted into Linux kernel $1.\n"; 226762306a36Sopenharmony_ci doprint "Assuming that this is a triple fault.\n"; 226862306a36Sopenharmony_ci doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n"; 226962306a36Sopenharmony_ci last; 227062306a36Sopenharmony_ci } 227162306a36Sopenharmony_ci } 227262306a36Sopenharmony_ci 227362306a36Sopenharmony_ci if ($line =~ /\n/) { 227462306a36Sopenharmony_ci $full_line = ""; 227562306a36Sopenharmony_ci } 227662306a36Sopenharmony_ci 227762306a36Sopenharmony_ci if ($stop_test_after > 0 && !$booted && !$bug) { 227862306a36Sopenharmony_ci if (time - $monitor_start > $stop_test_after) { 227962306a36Sopenharmony_ci doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n"; 228062306a36Sopenharmony_ci $done = 1; 228162306a36Sopenharmony_ci } 228262306a36Sopenharmony_ci } 228362306a36Sopenharmony_ci } 228462306a36Sopenharmony_ci 228562306a36Sopenharmony_ci my $end_time = time; 228662306a36Sopenharmony_ci $reboot_time = $end_time - $start_time; 228762306a36Sopenharmony_ci 228862306a36Sopenharmony_ci close(DMESG); 228962306a36Sopenharmony_ci 229062306a36Sopenharmony_ci if ($bug) { 229162306a36Sopenharmony_ci return 0 if ($in_bisect); 229262306a36Sopenharmony_ci fail "failed - got a bug report" and return 0; 229362306a36Sopenharmony_ci } 229462306a36Sopenharmony_ci 229562306a36Sopenharmony_ci if (!$booted) { 229662306a36Sopenharmony_ci return 0 if ($in_bisect); 229762306a36Sopenharmony_ci fail "failed - never got a boot prompt." and return 0; 229862306a36Sopenharmony_ci } 229962306a36Sopenharmony_ci 230062306a36Sopenharmony_ci if ($bug_ignored) { 230162306a36Sopenharmony_ci doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 230262306a36Sopenharmony_ci } 230362306a36Sopenharmony_ci 230462306a36Sopenharmony_ci return 1; 230562306a36Sopenharmony_ci} 230662306a36Sopenharmony_ci 230762306a36Sopenharmony_cisub eval_kernel_version { 230862306a36Sopenharmony_ci my ($option) = @_; 230962306a36Sopenharmony_ci 231062306a36Sopenharmony_ci $option =~ s/\$KERNEL_VERSION/$version/g; 231162306a36Sopenharmony_ci 231262306a36Sopenharmony_ci return $option; 231362306a36Sopenharmony_ci} 231462306a36Sopenharmony_ci 231562306a36Sopenharmony_cisub do_post_install { 231662306a36Sopenharmony_ci 231762306a36Sopenharmony_ci return if (!defined($post_install)); 231862306a36Sopenharmony_ci 231962306a36Sopenharmony_ci my $cp_post_install = eval_kernel_version $post_install; 232062306a36Sopenharmony_ci run_command "$cp_post_install" or 232162306a36Sopenharmony_ci dodie "Failed to run post install"; 232262306a36Sopenharmony_ci} 232362306a36Sopenharmony_ci 232462306a36Sopenharmony_ci# Sometimes the reboot fails, and will hang. We try to ssh to the box 232562306a36Sopenharmony_ci# and if we fail, we force another reboot, that should powercycle it. 232662306a36Sopenharmony_cisub test_booted { 232762306a36Sopenharmony_ci if (!run_ssh "echo testing connection") { 232862306a36Sopenharmony_ci reboot $sleep_time; 232962306a36Sopenharmony_ci } 233062306a36Sopenharmony_ci} 233162306a36Sopenharmony_ci 233262306a36Sopenharmony_cisub install { 233362306a36Sopenharmony_ci 233462306a36Sopenharmony_ci return if ($no_install); 233562306a36Sopenharmony_ci 233662306a36Sopenharmony_ci my $start_time = time; 233762306a36Sopenharmony_ci 233862306a36Sopenharmony_ci if (defined($pre_install)) { 233962306a36Sopenharmony_ci my $cp_pre_install = eval_kernel_version $pre_install; 234062306a36Sopenharmony_ci run_command "$cp_pre_install" or 234162306a36Sopenharmony_ci dodie "Failed to run pre install"; 234262306a36Sopenharmony_ci } 234362306a36Sopenharmony_ci 234462306a36Sopenharmony_ci my $cp_target = eval_kernel_version $target_image; 234562306a36Sopenharmony_ci 234662306a36Sopenharmony_ci test_booted; 234762306a36Sopenharmony_ci 234862306a36Sopenharmony_ci run_scp_install "$outputdir/$build_target", "$cp_target" or 234962306a36Sopenharmony_ci dodie "failed to copy image"; 235062306a36Sopenharmony_ci 235162306a36Sopenharmony_ci my $install_mods = 0; 235262306a36Sopenharmony_ci 235362306a36Sopenharmony_ci # should we process modules? 235462306a36Sopenharmony_ci $install_mods = 0; 235562306a36Sopenharmony_ci open(IN, "$output_config") or dodie("Can't read config file"); 235662306a36Sopenharmony_ci while (<IN>) { 235762306a36Sopenharmony_ci if (/CONFIG_MODULES(=y)?/) { 235862306a36Sopenharmony_ci if (defined($1)) { 235962306a36Sopenharmony_ci $install_mods = 1; 236062306a36Sopenharmony_ci last; 236162306a36Sopenharmony_ci } 236262306a36Sopenharmony_ci } 236362306a36Sopenharmony_ci } 236462306a36Sopenharmony_ci close(IN); 236562306a36Sopenharmony_ci 236662306a36Sopenharmony_ci if (!$install_mods) { 236762306a36Sopenharmony_ci do_post_install; 236862306a36Sopenharmony_ci doprint "No modules needed\n"; 236962306a36Sopenharmony_ci my $end_time = time; 237062306a36Sopenharmony_ci $install_time = $end_time - $start_time; 237162306a36Sopenharmony_ci return; 237262306a36Sopenharmony_ci } 237362306a36Sopenharmony_ci 237462306a36Sopenharmony_ci run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or 237562306a36Sopenharmony_ci dodie "Failed to install modules"; 237662306a36Sopenharmony_ci 237762306a36Sopenharmony_ci my $modlib = "/lib/modules/$version"; 237862306a36Sopenharmony_ci my $modtar = "ktest-mods.tar.bz2"; 237962306a36Sopenharmony_ci 238062306a36Sopenharmony_ci run_ssh "rm -rf $modlib" or 238162306a36Sopenharmony_ci dodie "failed to remove old mods: $modlib"; 238262306a36Sopenharmony_ci 238362306a36Sopenharmony_ci # would be nice if scp -r did not follow symbolic links 238462306a36Sopenharmony_ci run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 238562306a36Sopenharmony_ci dodie "making tarball"; 238662306a36Sopenharmony_ci 238762306a36Sopenharmony_ci run_scp_mod "$tmpdir/$modtar", "/tmp" or 238862306a36Sopenharmony_ci dodie "failed to copy modules"; 238962306a36Sopenharmony_ci 239062306a36Sopenharmony_ci unlink "$tmpdir/$modtar"; 239162306a36Sopenharmony_ci 239262306a36Sopenharmony_ci run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or 239362306a36Sopenharmony_ci dodie "failed to tar modules"; 239462306a36Sopenharmony_ci 239562306a36Sopenharmony_ci run_ssh "rm -f /tmp/$modtar"; 239662306a36Sopenharmony_ci 239762306a36Sopenharmony_ci do_post_install; 239862306a36Sopenharmony_ci 239962306a36Sopenharmony_ci my $end_time = time; 240062306a36Sopenharmony_ci $install_time = $end_time - $start_time; 240162306a36Sopenharmony_ci} 240262306a36Sopenharmony_ci 240362306a36Sopenharmony_cisub get_version { 240462306a36Sopenharmony_ci # get the release name 240562306a36Sopenharmony_ci return if ($have_version); 240662306a36Sopenharmony_ci doprint "$make kernelrelease ... "; 240762306a36Sopenharmony_ci $version = `$make -s kernelrelease | tail -1`; 240862306a36Sopenharmony_ci chomp($version); 240962306a36Sopenharmony_ci doprint "$version\n"; 241062306a36Sopenharmony_ci $have_version = 1; 241162306a36Sopenharmony_ci} 241262306a36Sopenharmony_ci 241362306a36Sopenharmony_cisub start_monitor_and_install { 241462306a36Sopenharmony_ci # Make sure the stable kernel has finished booting 241562306a36Sopenharmony_ci 241662306a36Sopenharmony_ci # Install bisects, don't need console 241762306a36Sopenharmony_ci if (defined $console) { 241862306a36Sopenharmony_ci start_monitor; 241962306a36Sopenharmony_ci wait_for_monitor 5; 242062306a36Sopenharmony_ci end_monitor; 242162306a36Sopenharmony_ci } 242262306a36Sopenharmony_ci 242362306a36Sopenharmony_ci get_grub_index; 242462306a36Sopenharmony_ci get_version; 242562306a36Sopenharmony_ci install; 242662306a36Sopenharmony_ci 242762306a36Sopenharmony_ci start_monitor if (defined $console); 242862306a36Sopenharmony_ci return monitor; 242962306a36Sopenharmony_ci} 243062306a36Sopenharmony_ci 243162306a36Sopenharmony_cisub process_warning_line { 243262306a36Sopenharmony_ci my ($line) = @_; 243362306a36Sopenharmony_ci 243462306a36Sopenharmony_ci chomp $line; 243562306a36Sopenharmony_ci 243662306a36Sopenharmony_ci # for distcc heterogeneous systems, some compilers 243762306a36Sopenharmony_ci # do things differently causing warning lines 243862306a36Sopenharmony_ci # to be slightly different. This makes an attempt 243962306a36Sopenharmony_ci # to fixe those issues. 244062306a36Sopenharmony_ci 244162306a36Sopenharmony_ci # chop off the index into the line 244262306a36Sopenharmony_ci # using distcc, some compilers give different indexes 244362306a36Sopenharmony_ci # depending on white space 244462306a36Sopenharmony_ci $line =~ s/^(\s*\S+:\d+:)\d+/$1/; 244562306a36Sopenharmony_ci 244662306a36Sopenharmony_ci # Some compilers use UTF-8 extended for quotes and some don't. 244762306a36Sopenharmony_ci $line =~ s/$utf8_quote/'/g; 244862306a36Sopenharmony_ci 244962306a36Sopenharmony_ci return $line; 245062306a36Sopenharmony_ci} 245162306a36Sopenharmony_ci 245262306a36Sopenharmony_ci# Read buildlog and check against warnings file for any 245362306a36Sopenharmony_ci# new warnings. 245462306a36Sopenharmony_ci# 245562306a36Sopenharmony_ci# Returns 1 if OK 245662306a36Sopenharmony_ci# 0 otherwise 245762306a36Sopenharmony_cisub check_buildlog { 245862306a36Sopenharmony_ci return 1 if (!defined $warnings_file); 245962306a36Sopenharmony_ci 246062306a36Sopenharmony_ci my %warnings_list; 246162306a36Sopenharmony_ci 246262306a36Sopenharmony_ci # Failed builds should not reboot the target 246362306a36Sopenharmony_ci my $save_no_reboot = $no_reboot; 246462306a36Sopenharmony_ci $no_reboot = 1; 246562306a36Sopenharmony_ci 246662306a36Sopenharmony_ci if (-f $warnings_file) { 246762306a36Sopenharmony_ci open(IN, $warnings_file) or 246862306a36Sopenharmony_ci dodie "Error opening $warnings_file"; 246962306a36Sopenharmony_ci 247062306a36Sopenharmony_ci while (<IN>) { 247162306a36Sopenharmony_ci if (/$check_build_re/) { 247262306a36Sopenharmony_ci my $warning = process_warning_line $_; 247362306a36Sopenharmony_ci 247462306a36Sopenharmony_ci $warnings_list{$warning} = 1; 247562306a36Sopenharmony_ci } 247662306a36Sopenharmony_ci } 247762306a36Sopenharmony_ci close(IN); 247862306a36Sopenharmony_ci } 247962306a36Sopenharmony_ci 248062306a36Sopenharmony_ci # If warnings file didn't exist, and WARNINGS_FILE exist, 248162306a36Sopenharmony_ci # then we fail on any warning! 248262306a36Sopenharmony_ci 248362306a36Sopenharmony_ci open(IN, $buildlog) or dodie "Can't open $buildlog"; 248462306a36Sopenharmony_ci while (<IN>) { 248562306a36Sopenharmony_ci if (/$check_build_re/) { 248662306a36Sopenharmony_ci my $warning = process_warning_line $_; 248762306a36Sopenharmony_ci 248862306a36Sopenharmony_ci if (!defined $warnings_list{$warning}) { 248962306a36Sopenharmony_ci fail "New warning found (not in $warnings_file)\n$_\n"; 249062306a36Sopenharmony_ci $no_reboot = $save_no_reboot; 249162306a36Sopenharmony_ci return 0; 249262306a36Sopenharmony_ci } 249362306a36Sopenharmony_ci } 249462306a36Sopenharmony_ci } 249562306a36Sopenharmony_ci $no_reboot = $save_no_reboot; 249662306a36Sopenharmony_ci close(IN); 249762306a36Sopenharmony_ci} 249862306a36Sopenharmony_ci 249962306a36Sopenharmony_cisub check_patch_buildlog { 250062306a36Sopenharmony_ci my ($patch) = @_; 250162306a36Sopenharmony_ci 250262306a36Sopenharmony_ci my @files = `git show $patch | diffstat -l`; 250362306a36Sopenharmony_ci 250462306a36Sopenharmony_ci foreach my $file (@files) { 250562306a36Sopenharmony_ci chomp $file; 250662306a36Sopenharmony_ci } 250762306a36Sopenharmony_ci 250862306a36Sopenharmony_ci open(IN, "git show $patch |") or 250962306a36Sopenharmony_ci dodie "failed to show $patch"; 251062306a36Sopenharmony_ci while (<IN>) { 251162306a36Sopenharmony_ci if (m,^--- a/(.*),) { 251262306a36Sopenharmony_ci chomp $1; 251362306a36Sopenharmony_ci $files[$#files] = $1; 251462306a36Sopenharmony_ci } 251562306a36Sopenharmony_ci } 251662306a36Sopenharmony_ci close(IN); 251762306a36Sopenharmony_ci 251862306a36Sopenharmony_ci open(IN, $buildlog) or dodie "Can't open $buildlog"; 251962306a36Sopenharmony_ci while (<IN>) { 252062306a36Sopenharmony_ci if (/^\s*(.*?):.*(warning|error)/) { 252162306a36Sopenharmony_ci my $err = $1; 252262306a36Sopenharmony_ci foreach my $file (@files) { 252362306a36Sopenharmony_ci my $fullpath = "$builddir/$file"; 252462306a36Sopenharmony_ci if ($file eq $err || $fullpath eq $err) { 252562306a36Sopenharmony_ci fail "$file built with warnings" and return 0; 252662306a36Sopenharmony_ci } 252762306a36Sopenharmony_ci } 252862306a36Sopenharmony_ci } 252962306a36Sopenharmony_ci } 253062306a36Sopenharmony_ci close(IN); 253162306a36Sopenharmony_ci 253262306a36Sopenharmony_ci return 1; 253362306a36Sopenharmony_ci} 253462306a36Sopenharmony_ci 253562306a36Sopenharmony_cisub apply_min_config { 253662306a36Sopenharmony_ci my $outconfig = "$output_config.new"; 253762306a36Sopenharmony_ci 253862306a36Sopenharmony_ci # Read the config file and remove anything that 253962306a36Sopenharmony_ci # is in the force_config hash (from minconfig and others) 254062306a36Sopenharmony_ci # then add the force config back. 254162306a36Sopenharmony_ci 254262306a36Sopenharmony_ci doprint "Applying minimum configurations into $output_config.new\n"; 254362306a36Sopenharmony_ci 254462306a36Sopenharmony_ci open (OUT, ">$outconfig") or 254562306a36Sopenharmony_ci dodie "Can't create $outconfig"; 254662306a36Sopenharmony_ci 254762306a36Sopenharmony_ci if (-f $output_config) { 254862306a36Sopenharmony_ci open (IN, $output_config) or 254962306a36Sopenharmony_ci dodie "Failed to open $output_config"; 255062306a36Sopenharmony_ci while (<IN>) { 255162306a36Sopenharmony_ci if (/^(# )?(CONFIG_[^\s=]*)/) { 255262306a36Sopenharmony_ci next if (defined($force_config{$2})); 255362306a36Sopenharmony_ci } 255462306a36Sopenharmony_ci print OUT; 255562306a36Sopenharmony_ci } 255662306a36Sopenharmony_ci close IN; 255762306a36Sopenharmony_ci } 255862306a36Sopenharmony_ci foreach my $config (keys %force_config) { 255962306a36Sopenharmony_ci print OUT "$force_config{$config}\n"; 256062306a36Sopenharmony_ci } 256162306a36Sopenharmony_ci close OUT; 256262306a36Sopenharmony_ci 256362306a36Sopenharmony_ci run_command "mv $outconfig $output_config"; 256462306a36Sopenharmony_ci} 256562306a36Sopenharmony_ci 256662306a36Sopenharmony_cisub make_oldconfig { 256762306a36Sopenharmony_ci 256862306a36Sopenharmony_ci my @force_list = keys %force_config; 256962306a36Sopenharmony_ci 257062306a36Sopenharmony_ci if ($#force_list >= 0) { 257162306a36Sopenharmony_ci apply_min_config; 257262306a36Sopenharmony_ci } 257362306a36Sopenharmony_ci 257462306a36Sopenharmony_ci if (!run_command "$make olddefconfig") { 257562306a36Sopenharmony_ci # Perhaps olddefconfig doesn't exist in this version of the kernel 257662306a36Sopenharmony_ci # try oldnoconfig 257762306a36Sopenharmony_ci doprint "olddefconfig failed, trying make oldnoconfig\n"; 257862306a36Sopenharmony_ci if (!run_command "$make oldnoconfig") { 257962306a36Sopenharmony_ci doprint "oldnoconfig failed, trying yes '' | make oldconfig\n"; 258062306a36Sopenharmony_ci # try a yes '' | oldconfig 258162306a36Sopenharmony_ci run_command "yes '' | $make oldconfig" or 258262306a36Sopenharmony_ci dodie "failed make config oldconfig"; 258362306a36Sopenharmony_ci } 258462306a36Sopenharmony_ci } 258562306a36Sopenharmony_ci} 258662306a36Sopenharmony_ci 258762306a36Sopenharmony_ci# read a config file and use this to force new configs. 258862306a36Sopenharmony_cisub load_force_config { 258962306a36Sopenharmony_ci my ($config) = @_; 259062306a36Sopenharmony_ci 259162306a36Sopenharmony_ci doprint "Loading force configs from $config\n"; 259262306a36Sopenharmony_ci open(IN, $config) or 259362306a36Sopenharmony_ci dodie "failed to read $config"; 259462306a36Sopenharmony_ci while (<IN>) { 259562306a36Sopenharmony_ci chomp; 259662306a36Sopenharmony_ci if (/^(CONFIG[^\s=]*)(\s*=.*)/) { 259762306a36Sopenharmony_ci $force_config{$1} = $_; 259862306a36Sopenharmony_ci } elsif (/^# (CONFIG_\S*) is not set/) { 259962306a36Sopenharmony_ci $force_config{$1} = $_; 260062306a36Sopenharmony_ci } 260162306a36Sopenharmony_ci } 260262306a36Sopenharmony_ci close IN; 260362306a36Sopenharmony_ci} 260462306a36Sopenharmony_ci 260562306a36Sopenharmony_cisub build { 260662306a36Sopenharmony_ci my ($type) = @_; 260762306a36Sopenharmony_ci 260862306a36Sopenharmony_ci unlink $buildlog; 260962306a36Sopenharmony_ci 261062306a36Sopenharmony_ci my $start_time = time; 261162306a36Sopenharmony_ci 261262306a36Sopenharmony_ci # Failed builds should not reboot the target 261362306a36Sopenharmony_ci my $save_no_reboot = $no_reboot; 261462306a36Sopenharmony_ci $no_reboot = 1; 261562306a36Sopenharmony_ci 261662306a36Sopenharmony_ci # Calculate a new version from here. 261762306a36Sopenharmony_ci $have_version = 0; 261862306a36Sopenharmony_ci 261962306a36Sopenharmony_ci if (defined($pre_build)) { 262062306a36Sopenharmony_ci my $ret = run_command $pre_build; 262162306a36Sopenharmony_ci if (!$ret && defined($pre_build_die) && 262262306a36Sopenharmony_ci $pre_build_die) { 262362306a36Sopenharmony_ci dodie "failed to pre_build\n"; 262462306a36Sopenharmony_ci } 262562306a36Sopenharmony_ci } 262662306a36Sopenharmony_ci 262762306a36Sopenharmony_ci if ($type =~ /^useconfig:(.*)/) { 262862306a36Sopenharmony_ci run_command "cp $1 $output_config" or 262962306a36Sopenharmony_ci dodie "could not copy $1 to .config"; 263062306a36Sopenharmony_ci 263162306a36Sopenharmony_ci $type = "oldconfig"; 263262306a36Sopenharmony_ci } 263362306a36Sopenharmony_ci 263462306a36Sopenharmony_ci # old config can ask questions 263562306a36Sopenharmony_ci if ($type eq "oldconfig") { 263662306a36Sopenharmony_ci $type = "olddefconfig"; 263762306a36Sopenharmony_ci 263862306a36Sopenharmony_ci # allow for empty configs 263962306a36Sopenharmony_ci run_command "touch $output_config"; 264062306a36Sopenharmony_ci 264162306a36Sopenharmony_ci if (!$noclean) { 264262306a36Sopenharmony_ci run_command "mv $output_config $outputdir/config_temp" or 264362306a36Sopenharmony_ci dodie "moving .config"; 264462306a36Sopenharmony_ci 264562306a36Sopenharmony_ci run_command "$make mrproper" or dodie "make mrproper"; 264662306a36Sopenharmony_ci 264762306a36Sopenharmony_ci run_command "mv $outputdir/config_temp $output_config" or 264862306a36Sopenharmony_ci dodie "moving config_temp"; 264962306a36Sopenharmony_ci } 265062306a36Sopenharmony_ci } elsif (!$noclean) { 265162306a36Sopenharmony_ci unlink "$output_config"; 265262306a36Sopenharmony_ci run_command "$make mrproper" or 265362306a36Sopenharmony_ci dodie "make mrproper"; 265462306a36Sopenharmony_ci } 265562306a36Sopenharmony_ci 265662306a36Sopenharmony_ci # add something to distinguish this build 265762306a36Sopenharmony_ci open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 265862306a36Sopenharmony_ci print OUT "$localversion\n"; 265962306a36Sopenharmony_ci close(OUT); 266062306a36Sopenharmony_ci 266162306a36Sopenharmony_ci if (defined($minconfig)) { 266262306a36Sopenharmony_ci load_force_config($minconfig); 266362306a36Sopenharmony_ci } 266462306a36Sopenharmony_ci 266562306a36Sopenharmony_ci if ($type ne "olddefconfig") { 266662306a36Sopenharmony_ci run_command "$make $type" or 266762306a36Sopenharmony_ci dodie "failed make config"; 266862306a36Sopenharmony_ci } 266962306a36Sopenharmony_ci # Run old config regardless, to enforce min configurations 267062306a36Sopenharmony_ci make_oldconfig; 267162306a36Sopenharmony_ci 267262306a36Sopenharmony_ci if (not defined($build_options)){ 267362306a36Sopenharmony_ci $build_options = ""; 267462306a36Sopenharmony_ci } 267562306a36Sopenharmony_ci my $build_ret = run_command "$make $build_options", $buildlog; 267662306a36Sopenharmony_ci 267762306a36Sopenharmony_ci if (defined($post_build)) { 267862306a36Sopenharmony_ci # Because a post build may change the kernel version 267962306a36Sopenharmony_ci # do it now. 268062306a36Sopenharmony_ci get_version; 268162306a36Sopenharmony_ci my $ret = run_command $post_build; 268262306a36Sopenharmony_ci if (!$ret && defined($post_build_die) && 268362306a36Sopenharmony_ci $post_build_die) { 268462306a36Sopenharmony_ci dodie "failed to post_build\n"; 268562306a36Sopenharmony_ci } 268662306a36Sopenharmony_ci } 268762306a36Sopenharmony_ci 268862306a36Sopenharmony_ci if (!$build_ret) { 268962306a36Sopenharmony_ci # bisect may need this to pass 269062306a36Sopenharmony_ci if ($in_bisect) { 269162306a36Sopenharmony_ci $no_reboot = $save_no_reboot; 269262306a36Sopenharmony_ci return 0; 269362306a36Sopenharmony_ci } 269462306a36Sopenharmony_ci fail "failed build" and return 0; 269562306a36Sopenharmony_ci } 269662306a36Sopenharmony_ci 269762306a36Sopenharmony_ci $no_reboot = $save_no_reboot; 269862306a36Sopenharmony_ci 269962306a36Sopenharmony_ci my $end_time = time; 270062306a36Sopenharmony_ci $build_time = $end_time - $start_time; 270162306a36Sopenharmony_ci 270262306a36Sopenharmony_ci return 1; 270362306a36Sopenharmony_ci} 270462306a36Sopenharmony_ci 270562306a36Sopenharmony_cisub halt { 270662306a36Sopenharmony_ci if (!run_ssh "halt" or defined($power_off)) { 270762306a36Sopenharmony_ci if (defined($poweroff_after_halt)) { 270862306a36Sopenharmony_ci sleep $poweroff_after_halt; 270962306a36Sopenharmony_ci run_command "$power_off"; 271062306a36Sopenharmony_ci } 271162306a36Sopenharmony_ci } else { 271262306a36Sopenharmony_ci # nope? the zap it! 271362306a36Sopenharmony_ci run_command "$power_off"; 271462306a36Sopenharmony_ci } 271562306a36Sopenharmony_ci} 271662306a36Sopenharmony_ci 271762306a36Sopenharmony_cisub success { 271862306a36Sopenharmony_ci my ($i) = @_; 271962306a36Sopenharmony_ci 272062306a36Sopenharmony_ci $successes++; 272162306a36Sopenharmony_ci 272262306a36Sopenharmony_ci my $name = ""; 272362306a36Sopenharmony_ci 272462306a36Sopenharmony_ci if (defined($test_name)) { 272562306a36Sopenharmony_ci $name = " ($test_name)"; 272662306a36Sopenharmony_ci } 272762306a36Sopenharmony_ci 272862306a36Sopenharmony_ci print_times; 272962306a36Sopenharmony_ci 273062306a36Sopenharmony_ci doprint "\n\n"; 273162306a36Sopenharmony_ci doprint "*******************************************\n"; 273262306a36Sopenharmony_ci doprint "*******************************************\n"; 273362306a36Sopenharmony_ci doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n"; 273462306a36Sopenharmony_ci doprint "*******************************************\n"; 273562306a36Sopenharmony_ci doprint "*******************************************\n"; 273662306a36Sopenharmony_ci 273762306a36Sopenharmony_ci if (defined($store_successes)) { 273862306a36Sopenharmony_ci save_logs "success", $store_successes; 273962306a36Sopenharmony_ci } 274062306a36Sopenharmony_ci 274162306a36Sopenharmony_ci if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 274262306a36Sopenharmony_ci doprint "Reboot and wait $sleep_time seconds\n"; 274362306a36Sopenharmony_ci reboot_to_good $sleep_time; 274462306a36Sopenharmony_ci } 274562306a36Sopenharmony_ci 274662306a36Sopenharmony_ci if (defined($post_test)) { 274762306a36Sopenharmony_ci run_command $post_test; 274862306a36Sopenharmony_ci } 274962306a36Sopenharmony_ci} 275062306a36Sopenharmony_ci 275162306a36Sopenharmony_cisub answer_bisect { 275262306a36Sopenharmony_ci for (;;) { 275362306a36Sopenharmony_ci doprint "Pass, fail, or skip? [p/f/s]"; 275462306a36Sopenharmony_ci my $ans = <STDIN>; 275562306a36Sopenharmony_ci chomp $ans; 275662306a36Sopenharmony_ci if ($ans eq "p" || $ans eq "P") { 275762306a36Sopenharmony_ci return 1; 275862306a36Sopenharmony_ci } elsif ($ans eq "f" || $ans eq "F") { 275962306a36Sopenharmony_ci return 0; 276062306a36Sopenharmony_ci } elsif ($ans eq "s" || $ans eq "S") { 276162306a36Sopenharmony_ci return -1; 276262306a36Sopenharmony_ci } else { 276362306a36Sopenharmony_ci print "Please answer 'p', 'f', or 's'\n"; 276462306a36Sopenharmony_ci } 276562306a36Sopenharmony_ci } 276662306a36Sopenharmony_ci} 276762306a36Sopenharmony_ci 276862306a36Sopenharmony_cisub child_run_test { 276962306a36Sopenharmony_ci 277062306a36Sopenharmony_ci # child should have no power 277162306a36Sopenharmony_ci $reboot_on_error = 0; 277262306a36Sopenharmony_ci $poweroff_on_error = 0; 277362306a36Sopenharmony_ci $die_on_failure = 1; 277462306a36Sopenharmony_ci 277562306a36Sopenharmony_ci run_command $run_test, $testlog; 277662306a36Sopenharmony_ci 277762306a36Sopenharmony_ci exit $run_command_status; 277862306a36Sopenharmony_ci} 277962306a36Sopenharmony_ci 278062306a36Sopenharmony_cisub child_finished { 278162306a36Sopenharmony_ci $child_done = 1; 278262306a36Sopenharmony_ci} 278362306a36Sopenharmony_ci 278462306a36Sopenharmony_cisub do_run_test { 278562306a36Sopenharmony_ci my $child_pid; 278662306a36Sopenharmony_ci my $child_exit; 278762306a36Sopenharmony_ci my $line; 278862306a36Sopenharmony_ci my $full_line; 278962306a36Sopenharmony_ci my $bug = 0; 279062306a36Sopenharmony_ci my $bug_ignored = 0; 279162306a36Sopenharmony_ci 279262306a36Sopenharmony_ci my $start_time = time; 279362306a36Sopenharmony_ci 279462306a36Sopenharmony_ci wait_for_monitor 1; 279562306a36Sopenharmony_ci 279662306a36Sopenharmony_ci doprint "run test $run_test\n"; 279762306a36Sopenharmony_ci 279862306a36Sopenharmony_ci $child_done = 0; 279962306a36Sopenharmony_ci 280062306a36Sopenharmony_ci $SIG{CHLD} = qw(child_finished); 280162306a36Sopenharmony_ci 280262306a36Sopenharmony_ci $child_pid = fork; 280362306a36Sopenharmony_ci 280462306a36Sopenharmony_ci child_run_test if (!$child_pid); 280562306a36Sopenharmony_ci 280662306a36Sopenharmony_ci $full_line = ""; 280762306a36Sopenharmony_ci 280862306a36Sopenharmony_ci do { 280962306a36Sopenharmony_ci $line = wait_for_input($monitor_fp, 1); 281062306a36Sopenharmony_ci if (defined($line)) { 281162306a36Sopenharmony_ci 281262306a36Sopenharmony_ci # we are not guaranteed to get a full line 281362306a36Sopenharmony_ci $full_line .= $line; 281462306a36Sopenharmony_ci doprint $line; 281562306a36Sopenharmony_ci 281662306a36Sopenharmony_ci if ($full_line =~ /call trace:/i) { 281762306a36Sopenharmony_ci if ($ignore_errors) { 281862306a36Sopenharmony_ci $bug_ignored = 1; 281962306a36Sopenharmony_ci } else { 282062306a36Sopenharmony_ci $bug = 1; 282162306a36Sopenharmony_ci } 282262306a36Sopenharmony_ci } 282362306a36Sopenharmony_ci 282462306a36Sopenharmony_ci if ($full_line =~ /Kernel panic -/) { 282562306a36Sopenharmony_ci $bug = 1; 282662306a36Sopenharmony_ci } 282762306a36Sopenharmony_ci 282862306a36Sopenharmony_ci if ($line =~ /\n/) { 282962306a36Sopenharmony_ci $full_line = ""; 283062306a36Sopenharmony_ci } 283162306a36Sopenharmony_ci } 283262306a36Sopenharmony_ci } while (!$child_done && !$bug); 283362306a36Sopenharmony_ci 283462306a36Sopenharmony_ci if (!$bug && $bug_ignored) { 283562306a36Sopenharmony_ci doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 283662306a36Sopenharmony_ci } 283762306a36Sopenharmony_ci 283862306a36Sopenharmony_ci if ($bug) { 283962306a36Sopenharmony_ci my $failure_start = time; 284062306a36Sopenharmony_ci my $now; 284162306a36Sopenharmony_ci do { 284262306a36Sopenharmony_ci $line = wait_for_input($monitor_fp, 1); 284362306a36Sopenharmony_ci if (defined($line)) { 284462306a36Sopenharmony_ci doprint $line; 284562306a36Sopenharmony_ci } 284662306a36Sopenharmony_ci $now = time; 284762306a36Sopenharmony_ci if ($now - $failure_start >= $stop_after_failure) { 284862306a36Sopenharmony_ci last; 284962306a36Sopenharmony_ci } 285062306a36Sopenharmony_ci } while (defined($line)); 285162306a36Sopenharmony_ci 285262306a36Sopenharmony_ci doprint "Detected kernel crash!\n"; 285362306a36Sopenharmony_ci # kill the child with extreme prejudice 285462306a36Sopenharmony_ci kill 9, $child_pid; 285562306a36Sopenharmony_ci } 285662306a36Sopenharmony_ci 285762306a36Sopenharmony_ci waitpid $child_pid, 0; 285862306a36Sopenharmony_ci $child_exit = $? >> 8; 285962306a36Sopenharmony_ci 286062306a36Sopenharmony_ci my $end_time = time; 286162306a36Sopenharmony_ci $test_time = $end_time - $start_time; 286262306a36Sopenharmony_ci 286362306a36Sopenharmony_ci if (!$bug && $in_bisect) { 286462306a36Sopenharmony_ci if (defined($bisect_ret_good)) { 286562306a36Sopenharmony_ci if ($child_exit == $bisect_ret_good) { 286662306a36Sopenharmony_ci return 1; 286762306a36Sopenharmony_ci } 286862306a36Sopenharmony_ci } 286962306a36Sopenharmony_ci if (defined($bisect_ret_skip)) { 287062306a36Sopenharmony_ci if ($child_exit == $bisect_ret_skip) { 287162306a36Sopenharmony_ci return -1; 287262306a36Sopenharmony_ci } 287362306a36Sopenharmony_ci } 287462306a36Sopenharmony_ci if (defined($bisect_ret_abort)) { 287562306a36Sopenharmony_ci if ($child_exit == $bisect_ret_abort) { 287662306a36Sopenharmony_ci fail "test abort" and return -2; 287762306a36Sopenharmony_ci } 287862306a36Sopenharmony_ci } 287962306a36Sopenharmony_ci if (defined($bisect_ret_bad)) { 288062306a36Sopenharmony_ci if ($child_exit == $bisect_ret_skip) { 288162306a36Sopenharmony_ci return 0; 288262306a36Sopenharmony_ci } 288362306a36Sopenharmony_ci } 288462306a36Sopenharmony_ci if (defined($bisect_ret_default)) { 288562306a36Sopenharmony_ci if ($bisect_ret_default eq "good") { 288662306a36Sopenharmony_ci return 1; 288762306a36Sopenharmony_ci } elsif ($bisect_ret_default eq "bad") { 288862306a36Sopenharmony_ci return 0; 288962306a36Sopenharmony_ci } elsif ($bisect_ret_default eq "skip") { 289062306a36Sopenharmony_ci return -1; 289162306a36Sopenharmony_ci } elsif ($bisect_ret_default eq "abort") { 289262306a36Sopenharmony_ci return -2; 289362306a36Sopenharmony_ci } else { 289462306a36Sopenharmony_ci fail "unknown default action: $bisect_ret_default" 289562306a36Sopenharmony_ci and return -2; 289662306a36Sopenharmony_ci } 289762306a36Sopenharmony_ci } 289862306a36Sopenharmony_ci } 289962306a36Sopenharmony_ci 290062306a36Sopenharmony_ci if ($bug || $child_exit) { 290162306a36Sopenharmony_ci return 0 if $in_bisect; 290262306a36Sopenharmony_ci fail "test failed" and return 0; 290362306a36Sopenharmony_ci } 290462306a36Sopenharmony_ci return 1; 290562306a36Sopenharmony_ci} 290662306a36Sopenharmony_ci 290762306a36Sopenharmony_cisub run_git_bisect { 290862306a36Sopenharmony_ci my ($command) = @_; 290962306a36Sopenharmony_ci 291062306a36Sopenharmony_ci doprint "$command ... "; 291162306a36Sopenharmony_ci 291262306a36Sopenharmony_ci my $output = `$command 2>&1`; 291362306a36Sopenharmony_ci my $ret = $?; 291462306a36Sopenharmony_ci 291562306a36Sopenharmony_ci logit $output; 291662306a36Sopenharmony_ci 291762306a36Sopenharmony_ci if ($ret) { 291862306a36Sopenharmony_ci doprint "FAILED\n"; 291962306a36Sopenharmony_ci dodie "Failed to git bisect"; 292062306a36Sopenharmony_ci } 292162306a36Sopenharmony_ci 292262306a36Sopenharmony_ci doprint "SUCCESS\n"; 292362306a36Sopenharmony_ci if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 292462306a36Sopenharmony_ci doprint "$1 [$2]\n"; 292562306a36Sopenharmony_ci } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 292662306a36Sopenharmony_ci $bisect_bad_commit = $1; 292762306a36Sopenharmony_ci doprint "Found bad commit... $1\n"; 292862306a36Sopenharmony_ci return 0; 292962306a36Sopenharmony_ci } else { 293062306a36Sopenharmony_ci # we already logged it, just print it now. 293162306a36Sopenharmony_ci print $output; 293262306a36Sopenharmony_ci } 293362306a36Sopenharmony_ci 293462306a36Sopenharmony_ci return 1; 293562306a36Sopenharmony_ci} 293662306a36Sopenharmony_ci 293762306a36Sopenharmony_cisub bisect_reboot { 293862306a36Sopenharmony_ci doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 293962306a36Sopenharmony_ci reboot_to_good $bisect_sleep_time; 294062306a36Sopenharmony_ci} 294162306a36Sopenharmony_ci 294262306a36Sopenharmony_ci# returns 1 on success, 0 on failure, -1 on skip 294362306a36Sopenharmony_cisub run_bisect_test { 294462306a36Sopenharmony_ci my ($type, $buildtype) = @_; 294562306a36Sopenharmony_ci 294662306a36Sopenharmony_ci my $failed = 0; 294762306a36Sopenharmony_ci my $result; 294862306a36Sopenharmony_ci my $output; 294962306a36Sopenharmony_ci my $ret; 295062306a36Sopenharmony_ci 295162306a36Sopenharmony_ci $in_bisect = 1; 295262306a36Sopenharmony_ci 295362306a36Sopenharmony_ci build $buildtype or $failed = 1; 295462306a36Sopenharmony_ci 295562306a36Sopenharmony_ci if ($type ne "build") { 295662306a36Sopenharmony_ci if ($failed && $bisect_skip) { 295762306a36Sopenharmony_ci $in_bisect = 0; 295862306a36Sopenharmony_ci return -1; 295962306a36Sopenharmony_ci } 296062306a36Sopenharmony_ci dodie "Failed on build" if $failed; 296162306a36Sopenharmony_ci 296262306a36Sopenharmony_ci # Now boot the box 296362306a36Sopenharmony_ci start_monitor_and_install or $failed = 1; 296462306a36Sopenharmony_ci 296562306a36Sopenharmony_ci if ($type ne "boot") { 296662306a36Sopenharmony_ci if ($failed && $bisect_skip) { 296762306a36Sopenharmony_ci end_monitor; 296862306a36Sopenharmony_ci bisect_reboot; 296962306a36Sopenharmony_ci $in_bisect = 0; 297062306a36Sopenharmony_ci return -1; 297162306a36Sopenharmony_ci } 297262306a36Sopenharmony_ci dodie "Failed on boot" if $failed; 297362306a36Sopenharmony_ci 297462306a36Sopenharmony_ci do_run_test or $failed = 1; 297562306a36Sopenharmony_ci } 297662306a36Sopenharmony_ci end_monitor; 297762306a36Sopenharmony_ci } 297862306a36Sopenharmony_ci 297962306a36Sopenharmony_ci if ($failed) { 298062306a36Sopenharmony_ci $result = 0; 298162306a36Sopenharmony_ci } else { 298262306a36Sopenharmony_ci $result = 1; 298362306a36Sopenharmony_ci } 298462306a36Sopenharmony_ci 298562306a36Sopenharmony_ci # reboot the box to a kernel we can ssh to 298662306a36Sopenharmony_ci if ($type ne "build") { 298762306a36Sopenharmony_ci bisect_reboot; 298862306a36Sopenharmony_ci } 298962306a36Sopenharmony_ci $in_bisect = 0; 299062306a36Sopenharmony_ci 299162306a36Sopenharmony_ci return $result; 299262306a36Sopenharmony_ci} 299362306a36Sopenharmony_ci 299462306a36Sopenharmony_cisub run_bisect { 299562306a36Sopenharmony_ci my ($type) = @_; 299662306a36Sopenharmony_ci my $buildtype = "oldconfig"; 299762306a36Sopenharmony_ci 299862306a36Sopenharmony_ci # We should have a minconfig to use? 299962306a36Sopenharmony_ci if (defined($minconfig)) { 300062306a36Sopenharmony_ci $buildtype = "useconfig:$minconfig"; 300162306a36Sopenharmony_ci } 300262306a36Sopenharmony_ci 300362306a36Sopenharmony_ci # If the user sets bisect_tries to less than 1, then no tries 300462306a36Sopenharmony_ci # is a success. 300562306a36Sopenharmony_ci my $ret = 1; 300662306a36Sopenharmony_ci 300762306a36Sopenharmony_ci # Still let the user manually decide that though. 300862306a36Sopenharmony_ci if ($bisect_tries < 1 && $bisect_manual) { 300962306a36Sopenharmony_ci $ret = answer_bisect; 301062306a36Sopenharmony_ci } 301162306a36Sopenharmony_ci 301262306a36Sopenharmony_ci for (my $i = 0; $i < $bisect_tries; $i++) { 301362306a36Sopenharmony_ci if ($bisect_tries > 1) { 301462306a36Sopenharmony_ci my $t = $i + 1; 301562306a36Sopenharmony_ci doprint("Running bisect trial $t of $bisect_tries:\n"); 301662306a36Sopenharmony_ci } 301762306a36Sopenharmony_ci $ret = run_bisect_test $type, $buildtype; 301862306a36Sopenharmony_ci 301962306a36Sopenharmony_ci if ($bisect_manual) { 302062306a36Sopenharmony_ci $ret = answer_bisect; 302162306a36Sopenharmony_ci } 302262306a36Sopenharmony_ci 302362306a36Sopenharmony_ci last if (!$ret); 302462306a36Sopenharmony_ci } 302562306a36Sopenharmony_ci 302662306a36Sopenharmony_ci # Are we looking for where it worked, not failed? 302762306a36Sopenharmony_ci if ($reverse_bisect && $ret >= 0) { 302862306a36Sopenharmony_ci $ret = !$ret; 302962306a36Sopenharmony_ci } 303062306a36Sopenharmony_ci 303162306a36Sopenharmony_ci if ($ret > 0) { 303262306a36Sopenharmony_ci return "good"; 303362306a36Sopenharmony_ci } elsif ($ret == 0) { 303462306a36Sopenharmony_ci return "bad"; 303562306a36Sopenharmony_ci } elsif ($bisect_skip) { 303662306a36Sopenharmony_ci doprint "HIT A BAD COMMIT ... SKIPPING\n"; 303762306a36Sopenharmony_ci return "skip"; 303862306a36Sopenharmony_ci } 303962306a36Sopenharmony_ci} 304062306a36Sopenharmony_ci 304162306a36Sopenharmony_cisub update_bisect_replay { 304262306a36Sopenharmony_ci my $tmp_log = "$tmpdir/ktest_bisect_log"; 304362306a36Sopenharmony_ci run_command "git bisect log > $tmp_log" or 304462306a36Sopenharmony_ci dodie "can't create bisect log"; 304562306a36Sopenharmony_ci return $tmp_log; 304662306a36Sopenharmony_ci} 304762306a36Sopenharmony_ci 304862306a36Sopenharmony_cisub bisect { 304962306a36Sopenharmony_ci my ($i) = @_; 305062306a36Sopenharmony_ci 305162306a36Sopenharmony_ci my $result; 305262306a36Sopenharmony_ci 305362306a36Sopenharmony_ci dodie "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good)); 305462306a36Sopenharmony_ci dodie "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad)); 305562306a36Sopenharmony_ci dodie "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type)); 305662306a36Sopenharmony_ci 305762306a36Sopenharmony_ci my $good = $bisect_good; 305862306a36Sopenharmony_ci my $bad = $bisect_bad; 305962306a36Sopenharmony_ci my $type = $bisect_type; 306062306a36Sopenharmony_ci my $start = $bisect_start; 306162306a36Sopenharmony_ci my $replay = $bisect_replay; 306262306a36Sopenharmony_ci my $start_files = $bisect_files; 306362306a36Sopenharmony_ci 306462306a36Sopenharmony_ci if (defined($start_files)) { 306562306a36Sopenharmony_ci $start_files = " -- " . $start_files; 306662306a36Sopenharmony_ci } else { 306762306a36Sopenharmony_ci $start_files = ""; 306862306a36Sopenharmony_ci } 306962306a36Sopenharmony_ci 307062306a36Sopenharmony_ci # convert to true sha1's 307162306a36Sopenharmony_ci $good = get_sha1($good); 307262306a36Sopenharmony_ci $bad = get_sha1($bad); 307362306a36Sopenharmony_ci 307462306a36Sopenharmony_ci if (defined($bisect_reverse) && $bisect_reverse == 1) { 307562306a36Sopenharmony_ci doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 307662306a36Sopenharmony_ci $reverse_bisect = 1; 307762306a36Sopenharmony_ci } else { 307862306a36Sopenharmony_ci $reverse_bisect = 0; 307962306a36Sopenharmony_ci } 308062306a36Sopenharmony_ci 308162306a36Sopenharmony_ci # Can't have a test without having a test to run 308262306a36Sopenharmony_ci if ($type eq "test" && !defined($run_test)) { 308362306a36Sopenharmony_ci $type = "boot"; 308462306a36Sopenharmony_ci } 308562306a36Sopenharmony_ci 308662306a36Sopenharmony_ci # Check if a bisect was running 308762306a36Sopenharmony_ci my $bisect_start_file = "$builddir/.git/BISECT_START"; 308862306a36Sopenharmony_ci 308962306a36Sopenharmony_ci my $check = $bisect_check; 309062306a36Sopenharmony_ci my $do_check = defined($check) && $check ne "0"; 309162306a36Sopenharmony_ci 309262306a36Sopenharmony_ci if ( -f $bisect_start_file ) { 309362306a36Sopenharmony_ci print "Bisect in progress found\n"; 309462306a36Sopenharmony_ci if ($do_check) { 309562306a36Sopenharmony_ci print " If you say yes, then no checks of good or bad will be done\n"; 309662306a36Sopenharmony_ci } 309762306a36Sopenharmony_ci if (defined($replay)) { 309862306a36Sopenharmony_ci print "** BISECT_REPLAY is defined in config file **"; 309962306a36Sopenharmony_ci print " Ignore config option and perform new git bisect log?\n"; 310062306a36Sopenharmony_ci if (read_ync " (yes, no, or cancel) ") { 310162306a36Sopenharmony_ci $replay = update_bisect_replay; 310262306a36Sopenharmony_ci $do_check = 0; 310362306a36Sopenharmony_ci } 310462306a36Sopenharmony_ci } elsif (read_yn "read git log and continue?") { 310562306a36Sopenharmony_ci $replay = update_bisect_replay; 310662306a36Sopenharmony_ci $do_check = 0; 310762306a36Sopenharmony_ci } 310862306a36Sopenharmony_ci } 310962306a36Sopenharmony_ci 311062306a36Sopenharmony_ci if ($do_check) { 311162306a36Sopenharmony_ci # get current HEAD 311262306a36Sopenharmony_ci my $head = get_sha1("HEAD"); 311362306a36Sopenharmony_ci 311462306a36Sopenharmony_ci if ($check ne "good") { 311562306a36Sopenharmony_ci doprint "TESTING BISECT BAD [$bad]\n"; 311662306a36Sopenharmony_ci run_command "git checkout $bad" or 311762306a36Sopenharmony_ci dodie "Failed to checkout $bad"; 311862306a36Sopenharmony_ci 311962306a36Sopenharmony_ci $result = run_bisect $type; 312062306a36Sopenharmony_ci 312162306a36Sopenharmony_ci if ($result ne "bad") { 312262306a36Sopenharmony_ci fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 312362306a36Sopenharmony_ci } 312462306a36Sopenharmony_ci } 312562306a36Sopenharmony_ci 312662306a36Sopenharmony_ci if ($check ne "bad") { 312762306a36Sopenharmony_ci doprint "TESTING BISECT GOOD [$good]\n"; 312862306a36Sopenharmony_ci run_command "git checkout $good" or 312962306a36Sopenharmony_ci dodie "Failed to checkout $good"; 313062306a36Sopenharmony_ci 313162306a36Sopenharmony_ci $result = run_bisect $type; 313262306a36Sopenharmony_ci 313362306a36Sopenharmony_ci if ($result ne "good") { 313462306a36Sopenharmony_ci fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 313562306a36Sopenharmony_ci } 313662306a36Sopenharmony_ci } 313762306a36Sopenharmony_ci 313862306a36Sopenharmony_ci # checkout where we started 313962306a36Sopenharmony_ci run_command "git checkout $head" or 314062306a36Sopenharmony_ci dodie "Failed to checkout $head"; 314162306a36Sopenharmony_ci } 314262306a36Sopenharmony_ci 314362306a36Sopenharmony_ci run_command "git bisect start$start_files" or 314462306a36Sopenharmony_ci dodie "could not start bisect"; 314562306a36Sopenharmony_ci 314662306a36Sopenharmony_ci if (defined($replay)) { 314762306a36Sopenharmony_ci run_command "git bisect replay $replay" or 314862306a36Sopenharmony_ci dodie "failed to run replay"; 314962306a36Sopenharmony_ci } else { 315062306a36Sopenharmony_ci run_command "git bisect good $good" or 315162306a36Sopenharmony_ci dodie "could not set bisect good to $good"; 315262306a36Sopenharmony_ci 315362306a36Sopenharmony_ci run_git_bisect "git bisect bad $bad" or 315462306a36Sopenharmony_ci dodie "could not set bisect bad to $bad"; 315562306a36Sopenharmony_ci } 315662306a36Sopenharmony_ci 315762306a36Sopenharmony_ci if (defined($start)) { 315862306a36Sopenharmony_ci run_command "git checkout $start" or 315962306a36Sopenharmony_ci dodie "failed to checkout $start"; 316062306a36Sopenharmony_ci } 316162306a36Sopenharmony_ci 316262306a36Sopenharmony_ci my $test; 316362306a36Sopenharmony_ci do { 316462306a36Sopenharmony_ci $result = run_bisect $type; 316562306a36Sopenharmony_ci $test = run_git_bisect "git bisect $result"; 316662306a36Sopenharmony_ci print_times; 316762306a36Sopenharmony_ci } while ($test); 316862306a36Sopenharmony_ci 316962306a36Sopenharmony_ci run_command "git bisect log" or 317062306a36Sopenharmony_ci dodie "could not capture git bisect log"; 317162306a36Sopenharmony_ci 317262306a36Sopenharmony_ci run_command "git bisect reset" or 317362306a36Sopenharmony_ci dodie "could not reset git bisect"; 317462306a36Sopenharmony_ci 317562306a36Sopenharmony_ci doprint "Bad commit was [$bisect_bad_commit]\n"; 317662306a36Sopenharmony_ci 317762306a36Sopenharmony_ci success $i; 317862306a36Sopenharmony_ci} 317962306a36Sopenharmony_ci 318062306a36Sopenharmony_cisub assign_configs { 318162306a36Sopenharmony_ci my ($hash, $config) = @_; 318262306a36Sopenharmony_ci 318362306a36Sopenharmony_ci doprint "Reading configs from $config\n"; 318462306a36Sopenharmony_ci 318562306a36Sopenharmony_ci open (IN, $config) or 318662306a36Sopenharmony_ci dodie "Failed to read $config"; 318762306a36Sopenharmony_ci 318862306a36Sopenharmony_ci while (<IN>) { 318962306a36Sopenharmony_ci chomp; 319062306a36Sopenharmony_ci if (/^((CONFIG\S*)=.*)/) { 319162306a36Sopenharmony_ci ${$hash}{$2} = $1; 319262306a36Sopenharmony_ci } elsif (/^(# (CONFIG\S*) is not set)/) { 319362306a36Sopenharmony_ci ${$hash}{$2} = $1; 319462306a36Sopenharmony_ci } 319562306a36Sopenharmony_ci } 319662306a36Sopenharmony_ci 319762306a36Sopenharmony_ci close(IN); 319862306a36Sopenharmony_ci} 319962306a36Sopenharmony_ci 320062306a36Sopenharmony_cisub process_config_ignore { 320162306a36Sopenharmony_ci my ($config) = @_; 320262306a36Sopenharmony_ci 320362306a36Sopenharmony_ci assign_configs \%config_ignore, $config; 320462306a36Sopenharmony_ci} 320562306a36Sopenharmony_ci 320662306a36Sopenharmony_cisub get_dependencies { 320762306a36Sopenharmony_ci my ($config) = @_; 320862306a36Sopenharmony_ci 320962306a36Sopenharmony_ci my $arr = $dependency{$config}; 321062306a36Sopenharmony_ci if (!defined($arr)) { 321162306a36Sopenharmony_ci return (); 321262306a36Sopenharmony_ci } 321362306a36Sopenharmony_ci 321462306a36Sopenharmony_ci my @deps = @{$arr}; 321562306a36Sopenharmony_ci 321662306a36Sopenharmony_ci foreach my $dep (@{$arr}) { 321762306a36Sopenharmony_ci print "ADD DEP $dep\n"; 321862306a36Sopenharmony_ci @deps = (@deps, get_dependencies $dep); 321962306a36Sopenharmony_ci } 322062306a36Sopenharmony_ci 322162306a36Sopenharmony_ci return @deps; 322262306a36Sopenharmony_ci} 322362306a36Sopenharmony_ci 322462306a36Sopenharmony_cisub save_config { 322562306a36Sopenharmony_ci my ($pc, $file) = @_; 322662306a36Sopenharmony_ci 322762306a36Sopenharmony_ci my %configs = %{$pc}; 322862306a36Sopenharmony_ci 322962306a36Sopenharmony_ci doprint "Saving configs into $file\n"; 323062306a36Sopenharmony_ci 323162306a36Sopenharmony_ci open(OUT, ">$file") or dodie "Can not write to $file"; 323262306a36Sopenharmony_ci 323362306a36Sopenharmony_ci foreach my $config (keys %configs) { 323462306a36Sopenharmony_ci print OUT "$configs{$config}\n"; 323562306a36Sopenharmony_ci } 323662306a36Sopenharmony_ci close(OUT); 323762306a36Sopenharmony_ci} 323862306a36Sopenharmony_ci 323962306a36Sopenharmony_cisub create_config { 324062306a36Sopenharmony_ci my ($name, $pc) = @_; 324162306a36Sopenharmony_ci 324262306a36Sopenharmony_ci doprint "Creating old config from $name configs\n"; 324362306a36Sopenharmony_ci 324462306a36Sopenharmony_ci save_config $pc, $output_config; 324562306a36Sopenharmony_ci 324662306a36Sopenharmony_ci make_oldconfig; 324762306a36Sopenharmony_ci} 324862306a36Sopenharmony_ci 324962306a36Sopenharmony_cisub run_config_bisect_test { 325062306a36Sopenharmony_ci my ($type) = @_; 325162306a36Sopenharmony_ci 325262306a36Sopenharmony_ci my $ret = run_bisect_test $type, "oldconfig"; 325362306a36Sopenharmony_ci 325462306a36Sopenharmony_ci if ($bisect_manual) { 325562306a36Sopenharmony_ci $ret = answer_bisect; 325662306a36Sopenharmony_ci } 325762306a36Sopenharmony_ci 325862306a36Sopenharmony_ci return $ret; 325962306a36Sopenharmony_ci} 326062306a36Sopenharmony_ci 326162306a36Sopenharmony_cisub config_bisect_end { 326262306a36Sopenharmony_ci my ($good, $bad) = @_; 326362306a36Sopenharmony_ci my $diffexec = "diff -u"; 326462306a36Sopenharmony_ci 326562306a36Sopenharmony_ci if (-f "$builddir/scripts/diffconfig") { 326662306a36Sopenharmony_ci $diffexec = "$builddir/scripts/diffconfig"; 326762306a36Sopenharmony_ci } 326862306a36Sopenharmony_ci doprint "\n\n***************************************\n"; 326962306a36Sopenharmony_ci doprint "No more config bisecting possible.\n"; 327062306a36Sopenharmony_ci run_command "$diffexec $good $bad", 1; 327162306a36Sopenharmony_ci doprint "***************************************\n\n"; 327262306a36Sopenharmony_ci} 327362306a36Sopenharmony_ci 327462306a36Sopenharmony_cisub run_config_bisect { 327562306a36Sopenharmony_ci my ($good, $bad, $last_result) = @_; 327662306a36Sopenharmony_ci my $reset = ""; 327762306a36Sopenharmony_ci my $cmd; 327862306a36Sopenharmony_ci my $ret; 327962306a36Sopenharmony_ci 328062306a36Sopenharmony_ci if (!length($last_result)) { 328162306a36Sopenharmony_ci $reset = "-r"; 328262306a36Sopenharmony_ci } 328362306a36Sopenharmony_ci run_command "$config_bisect_exec $reset -b $outputdir $good $bad $last_result", 1; 328462306a36Sopenharmony_ci 328562306a36Sopenharmony_ci # config-bisect returns: 328662306a36Sopenharmony_ci # 0 if there is more to bisect 328762306a36Sopenharmony_ci # 1 for finding a good config 328862306a36Sopenharmony_ci # 2 if it can not find any more configs 328962306a36Sopenharmony_ci # -1 (255) on error 329062306a36Sopenharmony_ci if ($run_command_status) { 329162306a36Sopenharmony_ci return $run_command_status; 329262306a36Sopenharmony_ci } 329362306a36Sopenharmony_ci 329462306a36Sopenharmony_ci $ret = run_config_bisect_test $config_bisect_type; 329562306a36Sopenharmony_ci if ($ret) { 329662306a36Sopenharmony_ci doprint "NEW GOOD CONFIG ($pass)\n"; 329762306a36Sopenharmony_ci system("cp $output_config $tmpdir/good_config.tmp.$pass"); 329862306a36Sopenharmony_ci $pass++; 329962306a36Sopenharmony_ci # Return 3 for good config 330062306a36Sopenharmony_ci return 3; 330162306a36Sopenharmony_ci } else { 330262306a36Sopenharmony_ci doprint "NEW BAD CONFIG ($pass)\n"; 330362306a36Sopenharmony_ci system("cp $output_config $tmpdir/bad_config.tmp.$pass"); 330462306a36Sopenharmony_ci $pass++; 330562306a36Sopenharmony_ci # Return 4 for bad config 330662306a36Sopenharmony_ci return 4; 330762306a36Sopenharmony_ci } 330862306a36Sopenharmony_ci} 330962306a36Sopenharmony_ci 331062306a36Sopenharmony_cisub config_bisect { 331162306a36Sopenharmony_ci my ($i) = @_; 331262306a36Sopenharmony_ci 331362306a36Sopenharmony_ci my $good_config; 331462306a36Sopenharmony_ci my $bad_config; 331562306a36Sopenharmony_ci 331662306a36Sopenharmony_ci my $type = $config_bisect_type; 331762306a36Sopenharmony_ci my $ret; 331862306a36Sopenharmony_ci 331962306a36Sopenharmony_ci $bad_config = $config_bisect; 332062306a36Sopenharmony_ci 332162306a36Sopenharmony_ci if (defined($config_bisect_good)) { 332262306a36Sopenharmony_ci $good_config = $config_bisect_good; 332362306a36Sopenharmony_ci } elsif (defined($minconfig)) { 332462306a36Sopenharmony_ci $good_config = $minconfig; 332562306a36Sopenharmony_ci } else { 332662306a36Sopenharmony_ci doprint "No config specified, checking if defconfig works"; 332762306a36Sopenharmony_ci $ret = run_bisect_test $type, "defconfig"; 332862306a36Sopenharmony_ci if (!$ret) { 332962306a36Sopenharmony_ci fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD"; 333062306a36Sopenharmony_ci return 1; 333162306a36Sopenharmony_ci } 333262306a36Sopenharmony_ci $good_config = $output_config; 333362306a36Sopenharmony_ci } 333462306a36Sopenharmony_ci 333562306a36Sopenharmony_ci if (!defined($config_bisect_exec)) { 333662306a36Sopenharmony_ci # First check the location that ktest.pl ran 333762306a36Sopenharmony_ci my @locations = ( 333862306a36Sopenharmony_ci "$pwd/config-bisect.pl", 333962306a36Sopenharmony_ci "$dirname/config-bisect.pl", 334062306a36Sopenharmony_ci "$builddir/tools/testing/ktest/config-bisect.pl", 334162306a36Sopenharmony_ci undef ); 334262306a36Sopenharmony_ci foreach my $loc (@locations) { 334362306a36Sopenharmony_ci doprint "loc = $loc\n"; 334462306a36Sopenharmony_ci $config_bisect_exec = $loc; 334562306a36Sopenharmony_ci last if (defined($config_bisect_exec && -x $config_bisect_exec)); 334662306a36Sopenharmony_ci } 334762306a36Sopenharmony_ci if (!defined($config_bisect_exec)) { 334862306a36Sopenharmony_ci fail "Could not find an executable config-bisect.pl\n", 334962306a36Sopenharmony_ci " Set CONFIG_BISECT_EXEC to point to config-bisect.pl"; 335062306a36Sopenharmony_ci return 1; 335162306a36Sopenharmony_ci } 335262306a36Sopenharmony_ci } 335362306a36Sopenharmony_ci 335462306a36Sopenharmony_ci # we don't want min configs to cause issues here. 335562306a36Sopenharmony_ci doprint "Disabling 'MIN_CONFIG' for this test\n"; 335662306a36Sopenharmony_ci undef $minconfig; 335762306a36Sopenharmony_ci 335862306a36Sopenharmony_ci my %good_configs; 335962306a36Sopenharmony_ci my %bad_configs; 336062306a36Sopenharmony_ci my %tmp_configs; 336162306a36Sopenharmony_ci 336262306a36Sopenharmony_ci if (-f "$tmpdir/good_config.tmp" || -f "$tmpdir/bad_config.tmp") { 336362306a36Sopenharmony_ci if (read_yn "Interrupted config-bisect. Continue (n - will start new)?") { 336462306a36Sopenharmony_ci if (-f "$tmpdir/good_config.tmp") { 336562306a36Sopenharmony_ci $good_config = "$tmpdir/good_config.tmp"; 336662306a36Sopenharmony_ci } else { 336762306a36Sopenharmony_ci $good_config = "$tmpdir/good_config"; 336862306a36Sopenharmony_ci } 336962306a36Sopenharmony_ci if (-f "$tmpdir/bad_config.tmp") { 337062306a36Sopenharmony_ci $bad_config = "$tmpdir/bad_config.tmp"; 337162306a36Sopenharmony_ci } else { 337262306a36Sopenharmony_ci $bad_config = "$tmpdir/bad_config"; 337362306a36Sopenharmony_ci } 337462306a36Sopenharmony_ci } 337562306a36Sopenharmony_ci } 337662306a36Sopenharmony_ci doprint "Run good configs through make oldconfig\n"; 337762306a36Sopenharmony_ci assign_configs \%tmp_configs, $good_config; 337862306a36Sopenharmony_ci create_config "$good_config", \%tmp_configs; 337962306a36Sopenharmony_ci $good_config = "$tmpdir/good_config"; 338062306a36Sopenharmony_ci system("cp $output_config $good_config") == 0 or dodie "cp good config"; 338162306a36Sopenharmony_ci 338262306a36Sopenharmony_ci doprint "Run bad configs through make oldconfig\n"; 338362306a36Sopenharmony_ci assign_configs \%tmp_configs, $bad_config; 338462306a36Sopenharmony_ci create_config "$bad_config", \%tmp_configs; 338562306a36Sopenharmony_ci $bad_config = "$tmpdir/bad_config"; 338662306a36Sopenharmony_ci system("cp $output_config $bad_config") == 0 or dodie "cp bad config"; 338762306a36Sopenharmony_ci 338862306a36Sopenharmony_ci if (defined($config_bisect_check) && $config_bisect_check ne "0") { 338962306a36Sopenharmony_ci if ($config_bisect_check ne "good") { 339062306a36Sopenharmony_ci doprint "Testing bad config\n"; 339162306a36Sopenharmony_ci 339262306a36Sopenharmony_ci $ret = run_bisect_test $type, "useconfig:$bad_config"; 339362306a36Sopenharmony_ci if ($ret) { 339462306a36Sopenharmony_ci fail "Bad config succeeded when expected to fail!"; 339562306a36Sopenharmony_ci return 0; 339662306a36Sopenharmony_ci } 339762306a36Sopenharmony_ci } 339862306a36Sopenharmony_ci if ($config_bisect_check ne "bad") { 339962306a36Sopenharmony_ci doprint "Testing good config\n"; 340062306a36Sopenharmony_ci 340162306a36Sopenharmony_ci $ret = run_bisect_test $type, "useconfig:$good_config"; 340262306a36Sopenharmony_ci if (!$ret) { 340362306a36Sopenharmony_ci fail "Good config failed when expected to succeed!"; 340462306a36Sopenharmony_ci return 0; 340562306a36Sopenharmony_ci } 340662306a36Sopenharmony_ci } 340762306a36Sopenharmony_ci } 340862306a36Sopenharmony_ci 340962306a36Sopenharmony_ci my $last_run = ""; 341062306a36Sopenharmony_ci 341162306a36Sopenharmony_ci do { 341262306a36Sopenharmony_ci $ret = run_config_bisect $good_config, $bad_config, $last_run; 341362306a36Sopenharmony_ci if ($ret == 3) { 341462306a36Sopenharmony_ci $last_run = "good"; 341562306a36Sopenharmony_ci } elsif ($ret == 4) { 341662306a36Sopenharmony_ci $last_run = "bad"; 341762306a36Sopenharmony_ci } 341862306a36Sopenharmony_ci print_times; 341962306a36Sopenharmony_ci } while ($ret == 3 || $ret == 4); 342062306a36Sopenharmony_ci 342162306a36Sopenharmony_ci if ($ret == 2) { 342262306a36Sopenharmony_ci config_bisect_end "$good_config.tmp", "$bad_config.tmp"; 342362306a36Sopenharmony_ci } 342462306a36Sopenharmony_ci 342562306a36Sopenharmony_ci return $ret if ($ret < 0); 342662306a36Sopenharmony_ci 342762306a36Sopenharmony_ci success $i; 342862306a36Sopenharmony_ci} 342962306a36Sopenharmony_ci 343062306a36Sopenharmony_cisub patchcheck_reboot { 343162306a36Sopenharmony_ci doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; 343262306a36Sopenharmony_ci reboot_to_good $patchcheck_sleep_time; 343362306a36Sopenharmony_ci} 343462306a36Sopenharmony_ci 343562306a36Sopenharmony_cisub patchcheck { 343662306a36Sopenharmony_ci my ($i) = @_; 343762306a36Sopenharmony_ci 343862306a36Sopenharmony_ci dodie "PATCHCHECK_START[$i] not defined\n" 343962306a36Sopenharmony_ci if (!defined($patchcheck_start)); 344062306a36Sopenharmony_ci dodie "PATCHCHECK_TYPE[$i] not defined\n" 344162306a36Sopenharmony_ci if (!defined($patchcheck_type)); 344262306a36Sopenharmony_ci 344362306a36Sopenharmony_ci my $start = $patchcheck_start; 344462306a36Sopenharmony_ci 344562306a36Sopenharmony_ci my $cherry = $patchcheck_cherry; 344662306a36Sopenharmony_ci if (!defined($cherry)) { 344762306a36Sopenharmony_ci $cherry = 0; 344862306a36Sopenharmony_ci } 344962306a36Sopenharmony_ci 345062306a36Sopenharmony_ci my $end = "HEAD"; 345162306a36Sopenharmony_ci if (defined($patchcheck_end)) { 345262306a36Sopenharmony_ci $end = $patchcheck_end; 345362306a36Sopenharmony_ci } elsif ($cherry) { 345462306a36Sopenharmony_ci dodie "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n"; 345562306a36Sopenharmony_ci } 345662306a36Sopenharmony_ci 345762306a36Sopenharmony_ci # Get the true sha1's since we can use things like HEAD~3 345862306a36Sopenharmony_ci $start = get_sha1($start); 345962306a36Sopenharmony_ci $end = get_sha1($end); 346062306a36Sopenharmony_ci 346162306a36Sopenharmony_ci my $type = $patchcheck_type; 346262306a36Sopenharmony_ci 346362306a36Sopenharmony_ci # Can't have a test without having a test to run 346462306a36Sopenharmony_ci if ($type eq "test" && !defined($run_test)) { 346562306a36Sopenharmony_ci $type = "boot"; 346662306a36Sopenharmony_ci } 346762306a36Sopenharmony_ci 346862306a36Sopenharmony_ci if ($cherry) { 346962306a36Sopenharmony_ci open (IN, "git cherry -v $start $end|") or 347062306a36Sopenharmony_ci dodie "could not get git list"; 347162306a36Sopenharmony_ci } else { 347262306a36Sopenharmony_ci open (IN, "git log --pretty=oneline $end|") or 347362306a36Sopenharmony_ci dodie "could not get git list"; 347462306a36Sopenharmony_ci } 347562306a36Sopenharmony_ci 347662306a36Sopenharmony_ci my @list; 347762306a36Sopenharmony_ci 347862306a36Sopenharmony_ci while (<IN>) { 347962306a36Sopenharmony_ci chomp; 348062306a36Sopenharmony_ci # git cherry adds a '+' we want to remove 348162306a36Sopenharmony_ci s/^\+ //; 348262306a36Sopenharmony_ci $list[$#list+1] = $_; 348362306a36Sopenharmony_ci last if (/^$start/); 348462306a36Sopenharmony_ci } 348562306a36Sopenharmony_ci close(IN); 348662306a36Sopenharmony_ci 348762306a36Sopenharmony_ci if (!$cherry) { 348862306a36Sopenharmony_ci if ($list[$#list] !~ /^$start/) { 348962306a36Sopenharmony_ci fail "SHA1 $start not found"; 349062306a36Sopenharmony_ci } 349162306a36Sopenharmony_ci 349262306a36Sopenharmony_ci # go backwards in the list 349362306a36Sopenharmony_ci @list = reverse @list; 349462306a36Sopenharmony_ci } 349562306a36Sopenharmony_ci 349662306a36Sopenharmony_ci doprint("Going to test the following commits:\n"); 349762306a36Sopenharmony_ci foreach my $l (@list) { 349862306a36Sopenharmony_ci doprint "$l\n"; 349962306a36Sopenharmony_ci } 350062306a36Sopenharmony_ci 350162306a36Sopenharmony_ci my $save_clean = $noclean; 350262306a36Sopenharmony_ci my %ignored_warnings; 350362306a36Sopenharmony_ci 350462306a36Sopenharmony_ci if (defined($ignore_warnings)) { 350562306a36Sopenharmony_ci foreach my $sha1 (split /\s+/, $ignore_warnings) { 350662306a36Sopenharmony_ci $ignored_warnings{$sha1} = 1; 350762306a36Sopenharmony_ci } 350862306a36Sopenharmony_ci } 350962306a36Sopenharmony_ci 351062306a36Sopenharmony_ci $in_patchcheck = 1; 351162306a36Sopenharmony_ci foreach my $item (@list) { 351262306a36Sopenharmony_ci my $sha1 = $item; 351362306a36Sopenharmony_ci $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 351462306a36Sopenharmony_ci 351562306a36Sopenharmony_ci doprint "\nProcessing commit \"$item\"\n\n"; 351662306a36Sopenharmony_ci 351762306a36Sopenharmony_ci run_command "git checkout $sha1" or 351862306a36Sopenharmony_ci dodie "Failed to checkout $sha1"; 351962306a36Sopenharmony_ci 352062306a36Sopenharmony_ci # only clean on the first and last patch 352162306a36Sopenharmony_ci if ($item eq $list[0] || 352262306a36Sopenharmony_ci $item eq $list[$#list]) { 352362306a36Sopenharmony_ci $noclean = $save_clean; 352462306a36Sopenharmony_ci } else { 352562306a36Sopenharmony_ci $noclean = 1; 352662306a36Sopenharmony_ci } 352762306a36Sopenharmony_ci 352862306a36Sopenharmony_ci if (defined($minconfig)) { 352962306a36Sopenharmony_ci build "useconfig:$minconfig" or return 0; 353062306a36Sopenharmony_ci } else { 353162306a36Sopenharmony_ci # ?? no config to use? 353262306a36Sopenharmony_ci build "oldconfig" or return 0; 353362306a36Sopenharmony_ci } 353462306a36Sopenharmony_ci 353562306a36Sopenharmony_ci # No need to do per patch checking if warnings file exists 353662306a36Sopenharmony_ci if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) { 353762306a36Sopenharmony_ci check_patch_buildlog $sha1 or return 0; 353862306a36Sopenharmony_ci } 353962306a36Sopenharmony_ci 354062306a36Sopenharmony_ci check_buildlog or return 0; 354162306a36Sopenharmony_ci 354262306a36Sopenharmony_ci next if ($type eq "build"); 354362306a36Sopenharmony_ci 354462306a36Sopenharmony_ci my $failed = 0; 354562306a36Sopenharmony_ci 354662306a36Sopenharmony_ci start_monitor_and_install or $failed = 1; 354762306a36Sopenharmony_ci 354862306a36Sopenharmony_ci if (!$failed && $type ne "boot"){ 354962306a36Sopenharmony_ci do_run_test or $failed = 1; 355062306a36Sopenharmony_ci } 355162306a36Sopenharmony_ci end_monitor; 355262306a36Sopenharmony_ci if ($failed) { 355362306a36Sopenharmony_ci print_times; 355462306a36Sopenharmony_ci return 0; 355562306a36Sopenharmony_ci } 355662306a36Sopenharmony_ci patchcheck_reboot; 355762306a36Sopenharmony_ci print_times; 355862306a36Sopenharmony_ci } 355962306a36Sopenharmony_ci $in_patchcheck = 0; 356062306a36Sopenharmony_ci success $i; 356162306a36Sopenharmony_ci 356262306a36Sopenharmony_ci return 1; 356362306a36Sopenharmony_ci} 356462306a36Sopenharmony_ci 356562306a36Sopenharmony_cisub add_dep { 356662306a36Sopenharmony_ci # $config depends on $dep 356762306a36Sopenharmony_ci my ($config, $dep) = @_; 356862306a36Sopenharmony_ci 356962306a36Sopenharmony_ci if (defined($depends{$config})) { 357062306a36Sopenharmony_ci $depends{$config} .= " " . $dep; 357162306a36Sopenharmony_ci } else { 357262306a36Sopenharmony_ci $depends{$config} = $dep; 357362306a36Sopenharmony_ci } 357462306a36Sopenharmony_ci 357562306a36Sopenharmony_ci # record the number of configs depending on $dep 357662306a36Sopenharmony_ci if (defined $depcount{$dep}) { 357762306a36Sopenharmony_ci $depcount{$dep}++; 357862306a36Sopenharmony_ci } else { 357962306a36Sopenharmony_ci $depcount{$dep} = 1; 358062306a36Sopenharmony_ci } 358162306a36Sopenharmony_ci} 358262306a36Sopenharmony_ci 358362306a36Sopenharmony_ci# taken from streamline_config.pl 358462306a36Sopenharmony_cisub read_kconfig { 358562306a36Sopenharmony_ci my ($kconfig) = @_; 358662306a36Sopenharmony_ci 358762306a36Sopenharmony_ci my $state = "NONE"; 358862306a36Sopenharmony_ci my $config; 358962306a36Sopenharmony_ci my @kconfigs; 359062306a36Sopenharmony_ci 359162306a36Sopenharmony_ci my $cont = 0; 359262306a36Sopenharmony_ci my $line; 359362306a36Sopenharmony_ci 359462306a36Sopenharmony_ci if (! -f $kconfig) { 359562306a36Sopenharmony_ci doprint "file $kconfig does not exist, skipping\n"; 359662306a36Sopenharmony_ci return; 359762306a36Sopenharmony_ci } 359862306a36Sopenharmony_ci 359962306a36Sopenharmony_ci open(KIN, "$kconfig") 360062306a36Sopenharmony_ci or dodie "Can't open $kconfig"; 360162306a36Sopenharmony_ci while (<KIN>) { 360262306a36Sopenharmony_ci chomp; 360362306a36Sopenharmony_ci 360462306a36Sopenharmony_ci # Make sure that lines ending with \ continue 360562306a36Sopenharmony_ci if ($cont) { 360662306a36Sopenharmony_ci $_ = $line . " " . $_; 360762306a36Sopenharmony_ci } 360862306a36Sopenharmony_ci 360962306a36Sopenharmony_ci if (s/\\$//) { 361062306a36Sopenharmony_ci $cont = 1; 361162306a36Sopenharmony_ci $line = $_; 361262306a36Sopenharmony_ci next; 361362306a36Sopenharmony_ci } 361462306a36Sopenharmony_ci 361562306a36Sopenharmony_ci $cont = 0; 361662306a36Sopenharmony_ci 361762306a36Sopenharmony_ci # collect any Kconfig sources 361862306a36Sopenharmony_ci if (/^source\s*"(.*)"/) { 361962306a36Sopenharmony_ci $kconfigs[$#kconfigs+1] = $1; 362062306a36Sopenharmony_ci } 362162306a36Sopenharmony_ci 362262306a36Sopenharmony_ci # configs found 362362306a36Sopenharmony_ci if (/^\s*(menu)?config\s+(\S+)\s*$/) { 362462306a36Sopenharmony_ci $state = "NEW"; 362562306a36Sopenharmony_ci $config = $2; 362662306a36Sopenharmony_ci 362762306a36Sopenharmony_ci for (my $i = 0; $i < $iflevel; $i++) { 362862306a36Sopenharmony_ci add_dep $config, $ifdeps[$i]; 362962306a36Sopenharmony_ci } 363062306a36Sopenharmony_ci 363162306a36Sopenharmony_ci # collect the depends for the config 363262306a36Sopenharmony_ci } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { 363362306a36Sopenharmony_ci 363462306a36Sopenharmony_ci add_dep $config, $1; 363562306a36Sopenharmony_ci 363662306a36Sopenharmony_ci # Get the configs that select this config 363762306a36Sopenharmony_ci } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) { 363862306a36Sopenharmony_ci 363962306a36Sopenharmony_ci # selected by depends on config 364062306a36Sopenharmony_ci add_dep $1, $config; 364162306a36Sopenharmony_ci 364262306a36Sopenharmony_ci # Check for if statements 364362306a36Sopenharmony_ci } elsif (/^if\s+(.*\S)\s*$/) { 364462306a36Sopenharmony_ci my $deps = $1; 364562306a36Sopenharmony_ci # remove beginning and ending non text 364662306a36Sopenharmony_ci $deps =~ s/^[^a-zA-Z0-9_]*//; 364762306a36Sopenharmony_ci $deps =~ s/[^a-zA-Z0-9_]*$//; 364862306a36Sopenharmony_ci 364962306a36Sopenharmony_ci my @deps = split /[^a-zA-Z0-9_]+/, $deps; 365062306a36Sopenharmony_ci 365162306a36Sopenharmony_ci $ifdeps[$iflevel++] = join ':', @deps; 365262306a36Sopenharmony_ci 365362306a36Sopenharmony_ci } elsif (/^endif/) { 365462306a36Sopenharmony_ci 365562306a36Sopenharmony_ci $iflevel-- if ($iflevel); 365662306a36Sopenharmony_ci 365762306a36Sopenharmony_ci # stop on "help" 365862306a36Sopenharmony_ci } elsif (/^\s*help\s*$/) { 365962306a36Sopenharmony_ci $state = "NONE"; 366062306a36Sopenharmony_ci } 366162306a36Sopenharmony_ci } 366262306a36Sopenharmony_ci close(KIN); 366362306a36Sopenharmony_ci 366462306a36Sopenharmony_ci # read in any configs that were found. 366562306a36Sopenharmony_ci foreach $kconfig (@kconfigs) { 366662306a36Sopenharmony_ci if (!defined($read_kconfigs{$kconfig})) { 366762306a36Sopenharmony_ci $read_kconfigs{$kconfig} = 1; 366862306a36Sopenharmony_ci read_kconfig("$builddir/$kconfig"); 366962306a36Sopenharmony_ci } 367062306a36Sopenharmony_ci } 367162306a36Sopenharmony_ci} 367262306a36Sopenharmony_ci 367362306a36Sopenharmony_cisub read_depends { 367462306a36Sopenharmony_ci # find out which arch this is by the kconfig file 367562306a36Sopenharmony_ci open (IN, $output_config) or 367662306a36Sopenharmony_ci dodie "Failed to read $output_config"; 367762306a36Sopenharmony_ci my $arch; 367862306a36Sopenharmony_ci while (<IN>) { 367962306a36Sopenharmony_ci if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) { 368062306a36Sopenharmony_ci $arch = $1; 368162306a36Sopenharmony_ci last; 368262306a36Sopenharmony_ci } 368362306a36Sopenharmony_ci } 368462306a36Sopenharmony_ci close IN; 368562306a36Sopenharmony_ci 368662306a36Sopenharmony_ci if (!defined($arch)) { 368762306a36Sopenharmony_ci doprint "Could not find arch from config file\n"; 368862306a36Sopenharmony_ci doprint "no dependencies used\n"; 368962306a36Sopenharmony_ci return; 369062306a36Sopenharmony_ci } 369162306a36Sopenharmony_ci 369262306a36Sopenharmony_ci # arch is really the subarch, we need to know 369362306a36Sopenharmony_ci # what directory to look at. 369462306a36Sopenharmony_ci if ($arch eq "i386" || $arch eq "x86_64") { 369562306a36Sopenharmony_ci $arch = "x86"; 369662306a36Sopenharmony_ci } 369762306a36Sopenharmony_ci 369862306a36Sopenharmony_ci my $kconfig = "$builddir/arch/$arch/Kconfig"; 369962306a36Sopenharmony_ci 370062306a36Sopenharmony_ci if (! -f $kconfig && $arch =~ /\d$/) { 370162306a36Sopenharmony_ci my $orig = $arch; 370262306a36Sopenharmony_ci # some subarchs have numbers, truncate them 370362306a36Sopenharmony_ci $arch =~ s/\d*$//; 370462306a36Sopenharmony_ci $kconfig = "$builddir/arch/$arch/Kconfig"; 370562306a36Sopenharmony_ci if (! -f $kconfig) { 370662306a36Sopenharmony_ci doprint "No idea what arch dir $orig is for\n"; 370762306a36Sopenharmony_ci doprint "no dependencies used\n"; 370862306a36Sopenharmony_ci return; 370962306a36Sopenharmony_ci } 371062306a36Sopenharmony_ci } 371162306a36Sopenharmony_ci 371262306a36Sopenharmony_ci read_kconfig($kconfig); 371362306a36Sopenharmony_ci} 371462306a36Sopenharmony_ci 371562306a36Sopenharmony_cisub make_new_config { 371662306a36Sopenharmony_ci my @configs = @_; 371762306a36Sopenharmony_ci 371862306a36Sopenharmony_ci open (OUT, ">$output_config") 371962306a36Sopenharmony_ci or dodie "Failed to write $output_config"; 372062306a36Sopenharmony_ci 372162306a36Sopenharmony_ci foreach my $config (@configs) { 372262306a36Sopenharmony_ci print OUT "$config\n"; 372362306a36Sopenharmony_ci } 372462306a36Sopenharmony_ci close OUT; 372562306a36Sopenharmony_ci} 372662306a36Sopenharmony_ci 372762306a36Sopenharmony_cisub chomp_config { 372862306a36Sopenharmony_ci my ($config) = @_; 372962306a36Sopenharmony_ci 373062306a36Sopenharmony_ci $config =~ s/CONFIG_//; 373162306a36Sopenharmony_ci 373262306a36Sopenharmony_ci return $config; 373362306a36Sopenharmony_ci} 373462306a36Sopenharmony_ci 373562306a36Sopenharmony_cisub get_depends { 373662306a36Sopenharmony_ci my ($dep) = @_; 373762306a36Sopenharmony_ci 373862306a36Sopenharmony_ci my $kconfig = chomp_config $dep; 373962306a36Sopenharmony_ci 374062306a36Sopenharmony_ci $dep = $depends{"$kconfig"}; 374162306a36Sopenharmony_ci 374262306a36Sopenharmony_ci # the dep string we have saves the dependencies as they 374362306a36Sopenharmony_ci # were found, including expressions like ! && ||. We 374462306a36Sopenharmony_ci # want to split this out into just an array of configs. 374562306a36Sopenharmony_ci 374662306a36Sopenharmony_ci my $valid = "A-Za-z_0-9"; 374762306a36Sopenharmony_ci 374862306a36Sopenharmony_ci my @configs; 374962306a36Sopenharmony_ci 375062306a36Sopenharmony_ci while ($dep =~ /[$valid]/) { 375162306a36Sopenharmony_ci if ($dep =~ /^[^$valid]*([$valid]+)/) { 375262306a36Sopenharmony_ci my $conf = "CONFIG_" . $1; 375362306a36Sopenharmony_ci 375462306a36Sopenharmony_ci $configs[$#configs + 1] = $conf; 375562306a36Sopenharmony_ci 375662306a36Sopenharmony_ci $dep =~ s/^[^$valid]*[$valid]+//; 375762306a36Sopenharmony_ci } else { 375862306a36Sopenharmony_ci dodie "this should never happen"; 375962306a36Sopenharmony_ci } 376062306a36Sopenharmony_ci } 376162306a36Sopenharmony_ci 376262306a36Sopenharmony_ci return @configs; 376362306a36Sopenharmony_ci} 376462306a36Sopenharmony_ci 376562306a36Sopenharmony_cisub test_this_config { 376662306a36Sopenharmony_ci my ($config) = @_; 376762306a36Sopenharmony_ci 376862306a36Sopenharmony_ci my $found; 376962306a36Sopenharmony_ci 377062306a36Sopenharmony_ci # if we already processed this config, skip it 377162306a36Sopenharmony_ci if (defined($processed_configs{$config})) { 377262306a36Sopenharmony_ci return undef; 377362306a36Sopenharmony_ci } 377462306a36Sopenharmony_ci $processed_configs{$config} = 1; 377562306a36Sopenharmony_ci 377662306a36Sopenharmony_ci # if this config failed during this round, skip it 377762306a36Sopenharmony_ci if (defined($nochange_config{$config})) { 377862306a36Sopenharmony_ci return undef; 377962306a36Sopenharmony_ci } 378062306a36Sopenharmony_ci 378162306a36Sopenharmony_ci my $kconfig = chomp_config $config; 378262306a36Sopenharmony_ci 378362306a36Sopenharmony_ci # Test dependencies first 378462306a36Sopenharmony_ci if (defined($depends{"$kconfig"})) { 378562306a36Sopenharmony_ci my @parents = get_depends $config; 378662306a36Sopenharmony_ci foreach my $parent (@parents) { 378762306a36Sopenharmony_ci # if the parent is in the min config, check it first 378862306a36Sopenharmony_ci next if (!defined($min_configs{$parent})); 378962306a36Sopenharmony_ci $found = test_this_config($parent); 379062306a36Sopenharmony_ci if (defined($found)) { 379162306a36Sopenharmony_ci return $found; 379262306a36Sopenharmony_ci } 379362306a36Sopenharmony_ci } 379462306a36Sopenharmony_ci } 379562306a36Sopenharmony_ci 379662306a36Sopenharmony_ci # Remove this config from the list of configs 379762306a36Sopenharmony_ci # do a make olddefconfig and then read the resulting 379862306a36Sopenharmony_ci # .config to make sure it is missing the config that 379962306a36Sopenharmony_ci # we had before 380062306a36Sopenharmony_ci my %configs = %min_configs; 380162306a36Sopenharmony_ci $configs{$config} = "# $config is not set"; 380262306a36Sopenharmony_ci make_new_config ((values %configs), (values %keep_configs)); 380362306a36Sopenharmony_ci make_oldconfig; 380462306a36Sopenharmony_ci delete $configs{$config}; 380562306a36Sopenharmony_ci undef %configs; 380662306a36Sopenharmony_ci assign_configs \%configs, $output_config; 380762306a36Sopenharmony_ci 380862306a36Sopenharmony_ci if (!defined($configs{$config}) || $configs{$config} =~ /^#/) { 380962306a36Sopenharmony_ci return $config; 381062306a36Sopenharmony_ci } 381162306a36Sopenharmony_ci 381262306a36Sopenharmony_ci doprint "disabling config $config did not change .config\n"; 381362306a36Sopenharmony_ci 381462306a36Sopenharmony_ci $nochange_config{$config} = 1; 381562306a36Sopenharmony_ci 381662306a36Sopenharmony_ci return undef; 381762306a36Sopenharmony_ci} 381862306a36Sopenharmony_ci 381962306a36Sopenharmony_cisub make_min_config { 382062306a36Sopenharmony_ci my ($i) = @_; 382162306a36Sopenharmony_ci 382262306a36Sopenharmony_ci my $type = $minconfig_type; 382362306a36Sopenharmony_ci if ($type ne "boot" && $type ne "test") { 382462306a36Sopenharmony_ci fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" . 382562306a36Sopenharmony_ci " make_min_config works only with 'boot' and 'test'\n" and return; 382662306a36Sopenharmony_ci } 382762306a36Sopenharmony_ci 382862306a36Sopenharmony_ci if (!defined($output_minconfig)) { 382962306a36Sopenharmony_ci fail "OUTPUT_MIN_CONFIG not defined" and return; 383062306a36Sopenharmony_ci } 383162306a36Sopenharmony_ci 383262306a36Sopenharmony_ci # If output_minconfig exists, and the start_minconfig 383362306a36Sopenharmony_ci # came from min_config, than ask if we should use 383462306a36Sopenharmony_ci # that instead. 383562306a36Sopenharmony_ci if (-f $output_minconfig && !$start_minconfig_defined) { 383662306a36Sopenharmony_ci print "$output_minconfig exists\n"; 383762306a36Sopenharmony_ci if (!defined($use_output_minconfig)) { 383862306a36Sopenharmony_ci if (read_yn " Use it as minconfig?") { 383962306a36Sopenharmony_ci $start_minconfig = $output_minconfig; 384062306a36Sopenharmony_ci } 384162306a36Sopenharmony_ci } elsif ($use_output_minconfig > 0) { 384262306a36Sopenharmony_ci doprint "Using $output_minconfig as MIN_CONFIG\n"; 384362306a36Sopenharmony_ci $start_minconfig = $output_minconfig; 384462306a36Sopenharmony_ci } else { 384562306a36Sopenharmony_ci doprint "Set to still use MIN_CONFIG as starting point\n"; 384662306a36Sopenharmony_ci } 384762306a36Sopenharmony_ci } 384862306a36Sopenharmony_ci 384962306a36Sopenharmony_ci if (!defined($start_minconfig)) { 385062306a36Sopenharmony_ci fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return; 385162306a36Sopenharmony_ci } 385262306a36Sopenharmony_ci 385362306a36Sopenharmony_ci my $temp_config = "$tmpdir/temp_config"; 385462306a36Sopenharmony_ci 385562306a36Sopenharmony_ci # First things first. We build an allnoconfig to find 385662306a36Sopenharmony_ci # out what the defaults are that we can't touch. 385762306a36Sopenharmony_ci # Some are selections, but we really can't handle selections. 385862306a36Sopenharmony_ci 385962306a36Sopenharmony_ci my $save_minconfig = $minconfig; 386062306a36Sopenharmony_ci undef $minconfig; 386162306a36Sopenharmony_ci 386262306a36Sopenharmony_ci run_command "$make allnoconfig" or return 0; 386362306a36Sopenharmony_ci 386462306a36Sopenharmony_ci read_depends; 386562306a36Sopenharmony_ci 386662306a36Sopenharmony_ci process_config_ignore $output_config; 386762306a36Sopenharmony_ci 386862306a36Sopenharmony_ci undef %save_configs; 386962306a36Sopenharmony_ci undef %min_configs; 387062306a36Sopenharmony_ci 387162306a36Sopenharmony_ci if (defined($ignore_config)) { 387262306a36Sopenharmony_ci # make sure the file exists 387362306a36Sopenharmony_ci `touch $ignore_config`; 387462306a36Sopenharmony_ci assign_configs \%save_configs, $ignore_config; 387562306a36Sopenharmony_ci } 387662306a36Sopenharmony_ci 387762306a36Sopenharmony_ci %keep_configs = %save_configs; 387862306a36Sopenharmony_ci 387962306a36Sopenharmony_ci doprint "Load initial configs from $start_minconfig\n"; 388062306a36Sopenharmony_ci 388162306a36Sopenharmony_ci # Look at the current min configs, and save off all the 388262306a36Sopenharmony_ci # ones that were set via the allnoconfig 388362306a36Sopenharmony_ci assign_configs \%min_configs, $start_minconfig; 388462306a36Sopenharmony_ci 388562306a36Sopenharmony_ci my @config_keys = keys %min_configs; 388662306a36Sopenharmony_ci 388762306a36Sopenharmony_ci # All configs need a depcount 388862306a36Sopenharmony_ci foreach my $config (@config_keys) { 388962306a36Sopenharmony_ci my $kconfig = chomp_config $config; 389062306a36Sopenharmony_ci if (!defined $depcount{$kconfig}) { 389162306a36Sopenharmony_ci $depcount{$kconfig} = 0; 389262306a36Sopenharmony_ci } 389362306a36Sopenharmony_ci } 389462306a36Sopenharmony_ci 389562306a36Sopenharmony_ci # Remove anything that was set by the make allnoconfig 389662306a36Sopenharmony_ci # we shouldn't need them as they get set for us anyway. 389762306a36Sopenharmony_ci foreach my $config (@config_keys) { 389862306a36Sopenharmony_ci # Remove anything in the ignore_config 389962306a36Sopenharmony_ci if (defined($keep_configs{$config})) { 390062306a36Sopenharmony_ci my $file = $ignore_config; 390162306a36Sopenharmony_ci $file =~ s,.*/(.*?)$,$1,; 390262306a36Sopenharmony_ci doprint "$config set by $file ... ignored\n"; 390362306a36Sopenharmony_ci delete $min_configs{$config}; 390462306a36Sopenharmony_ci next; 390562306a36Sopenharmony_ci } 390662306a36Sopenharmony_ci # But make sure the settings are the same. If a min config 390762306a36Sopenharmony_ci # sets a selection, we do not want to get rid of it if 390862306a36Sopenharmony_ci # it is not the same as what we have. Just move it into 390962306a36Sopenharmony_ci # the keep configs. 391062306a36Sopenharmony_ci if (defined($config_ignore{$config})) { 391162306a36Sopenharmony_ci if ($config_ignore{$config} ne $min_configs{$config}) { 391262306a36Sopenharmony_ci doprint "$config is in allnoconfig as '$config_ignore{$config}'"; 391362306a36Sopenharmony_ci doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n"; 391462306a36Sopenharmony_ci $keep_configs{$config} = $min_configs{$config}; 391562306a36Sopenharmony_ci } else { 391662306a36Sopenharmony_ci doprint "$config set by allnoconfig ... ignored\n"; 391762306a36Sopenharmony_ci } 391862306a36Sopenharmony_ci delete $min_configs{$config}; 391962306a36Sopenharmony_ci } 392062306a36Sopenharmony_ci } 392162306a36Sopenharmony_ci 392262306a36Sopenharmony_ci my $done = 0; 392362306a36Sopenharmony_ci my $take_two = 0; 392462306a36Sopenharmony_ci 392562306a36Sopenharmony_ci while (!$done) { 392662306a36Sopenharmony_ci my $config; 392762306a36Sopenharmony_ci my $found; 392862306a36Sopenharmony_ci 392962306a36Sopenharmony_ci # Now disable each config one by one and do a make oldconfig 393062306a36Sopenharmony_ci # till we find a config that changes our list. 393162306a36Sopenharmony_ci 393262306a36Sopenharmony_ci my @test_configs = keys %min_configs; 393362306a36Sopenharmony_ci 393462306a36Sopenharmony_ci # Sort keys by who is most dependent on 393562306a36Sopenharmony_ci @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} } 393662306a36Sopenharmony_ci @test_configs ; 393762306a36Sopenharmony_ci 393862306a36Sopenharmony_ci # Put configs that did not modify the config at the end. 393962306a36Sopenharmony_ci my $reset = 1; 394062306a36Sopenharmony_ci for (my $i = 0; $i < $#test_configs; $i++) { 394162306a36Sopenharmony_ci if (!defined($nochange_config{$test_configs[0]})) { 394262306a36Sopenharmony_ci $reset = 0; 394362306a36Sopenharmony_ci last; 394462306a36Sopenharmony_ci } 394562306a36Sopenharmony_ci # This config didn't change the .config last time. 394662306a36Sopenharmony_ci # Place it at the end 394762306a36Sopenharmony_ci my $config = shift @test_configs; 394862306a36Sopenharmony_ci push @test_configs, $config; 394962306a36Sopenharmony_ci } 395062306a36Sopenharmony_ci 395162306a36Sopenharmony_ci # if every test config has failed to modify the .config file 395262306a36Sopenharmony_ci # in the past, then reset and start over. 395362306a36Sopenharmony_ci if ($reset) { 395462306a36Sopenharmony_ci undef %nochange_config; 395562306a36Sopenharmony_ci } 395662306a36Sopenharmony_ci 395762306a36Sopenharmony_ci undef %processed_configs; 395862306a36Sopenharmony_ci 395962306a36Sopenharmony_ci foreach my $config (@test_configs) { 396062306a36Sopenharmony_ci 396162306a36Sopenharmony_ci $found = test_this_config $config; 396262306a36Sopenharmony_ci 396362306a36Sopenharmony_ci last if (defined($found)); 396462306a36Sopenharmony_ci 396562306a36Sopenharmony_ci # oh well, try another config 396662306a36Sopenharmony_ci } 396762306a36Sopenharmony_ci 396862306a36Sopenharmony_ci if (!defined($found)) { 396962306a36Sopenharmony_ci # we could have failed due to the nochange_config hash 397062306a36Sopenharmony_ci # reset and try again 397162306a36Sopenharmony_ci if (!$take_two) { 397262306a36Sopenharmony_ci undef %nochange_config; 397362306a36Sopenharmony_ci $take_two = 1; 397462306a36Sopenharmony_ci next; 397562306a36Sopenharmony_ci } 397662306a36Sopenharmony_ci doprint "No more configs found that we can disable\n"; 397762306a36Sopenharmony_ci $done = 1; 397862306a36Sopenharmony_ci last; 397962306a36Sopenharmony_ci } 398062306a36Sopenharmony_ci $take_two = 0; 398162306a36Sopenharmony_ci 398262306a36Sopenharmony_ci $config = $found; 398362306a36Sopenharmony_ci 398462306a36Sopenharmony_ci doprint "Test with $config disabled\n"; 398562306a36Sopenharmony_ci 398662306a36Sopenharmony_ci # set in_bisect to keep build and monitor from dieing 398762306a36Sopenharmony_ci $in_bisect = 1; 398862306a36Sopenharmony_ci 398962306a36Sopenharmony_ci my $failed = 0; 399062306a36Sopenharmony_ci build "oldconfig" or $failed = 1; 399162306a36Sopenharmony_ci if (!$failed) { 399262306a36Sopenharmony_ci start_monitor_and_install or $failed = 1; 399362306a36Sopenharmony_ci 399462306a36Sopenharmony_ci if ($type eq "test" && !$failed) { 399562306a36Sopenharmony_ci do_run_test or $failed = 1; 399662306a36Sopenharmony_ci } 399762306a36Sopenharmony_ci 399862306a36Sopenharmony_ci end_monitor; 399962306a36Sopenharmony_ci } 400062306a36Sopenharmony_ci 400162306a36Sopenharmony_ci $in_bisect = 0; 400262306a36Sopenharmony_ci 400362306a36Sopenharmony_ci if ($failed) { 400462306a36Sopenharmony_ci doprint "$min_configs{$config} is needed to boot the box... keeping\n"; 400562306a36Sopenharmony_ci # this config is needed, add it to the ignore list. 400662306a36Sopenharmony_ci $keep_configs{$config} = $min_configs{$config}; 400762306a36Sopenharmony_ci $save_configs{$config} = $min_configs{$config}; 400862306a36Sopenharmony_ci delete $min_configs{$config}; 400962306a36Sopenharmony_ci 401062306a36Sopenharmony_ci # update new ignore configs 401162306a36Sopenharmony_ci if (defined($ignore_config)) { 401262306a36Sopenharmony_ci open (OUT, ">$temp_config") or 401362306a36Sopenharmony_ci dodie "Can't write to $temp_config"; 401462306a36Sopenharmony_ci foreach my $config (keys %save_configs) { 401562306a36Sopenharmony_ci print OUT "$save_configs{$config}\n"; 401662306a36Sopenharmony_ci } 401762306a36Sopenharmony_ci close OUT; 401862306a36Sopenharmony_ci run_command "mv $temp_config $ignore_config" or 401962306a36Sopenharmony_ci dodie "failed to copy update to $ignore_config"; 402062306a36Sopenharmony_ci } 402162306a36Sopenharmony_ci 402262306a36Sopenharmony_ci } else { 402362306a36Sopenharmony_ci # We booted without this config, remove it from the minconfigs. 402462306a36Sopenharmony_ci doprint "$config is not needed, disabling\n"; 402562306a36Sopenharmony_ci 402662306a36Sopenharmony_ci delete $min_configs{$config}; 402762306a36Sopenharmony_ci 402862306a36Sopenharmony_ci # Also disable anything that is not enabled in this config 402962306a36Sopenharmony_ci my %configs; 403062306a36Sopenharmony_ci assign_configs \%configs, $output_config; 403162306a36Sopenharmony_ci my @config_keys = keys %min_configs; 403262306a36Sopenharmony_ci foreach my $config (@config_keys) { 403362306a36Sopenharmony_ci if (!defined($configs{$config})) { 403462306a36Sopenharmony_ci doprint "$config is not set, disabling\n"; 403562306a36Sopenharmony_ci delete $min_configs{$config}; 403662306a36Sopenharmony_ci } 403762306a36Sopenharmony_ci } 403862306a36Sopenharmony_ci 403962306a36Sopenharmony_ci # Save off all the current mandatory configs 404062306a36Sopenharmony_ci open (OUT, ">$temp_config") or 404162306a36Sopenharmony_ci dodie "Can't write to $temp_config"; 404262306a36Sopenharmony_ci foreach my $config (keys %keep_configs) { 404362306a36Sopenharmony_ci print OUT "$keep_configs{$config}\n"; 404462306a36Sopenharmony_ci } 404562306a36Sopenharmony_ci foreach my $config (keys %min_configs) { 404662306a36Sopenharmony_ci print OUT "$min_configs{$config}\n"; 404762306a36Sopenharmony_ci } 404862306a36Sopenharmony_ci close OUT; 404962306a36Sopenharmony_ci 405062306a36Sopenharmony_ci run_command "mv $temp_config $output_minconfig" or 405162306a36Sopenharmony_ci dodie "failed to copy update to $output_minconfig"; 405262306a36Sopenharmony_ci } 405362306a36Sopenharmony_ci 405462306a36Sopenharmony_ci doprint "Reboot and wait $sleep_time seconds\n"; 405562306a36Sopenharmony_ci reboot_to_good $sleep_time; 405662306a36Sopenharmony_ci } 405762306a36Sopenharmony_ci 405862306a36Sopenharmony_ci success $i; 405962306a36Sopenharmony_ci return 1; 406062306a36Sopenharmony_ci} 406162306a36Sopenharmony_ci 406262306a36Sopenharmony_cisub make_warnings_file { 406362306a36Sopenharmony_ci my ($i) = @_; 406462306a36Sopenharmony_ci 406562306a36Sopenharmony_ci if (!defined($warnings_file)) { 406662306a36Sopenharmony_ci dodie "Must define WARNINGS_FILE for make_warnings_file test"; 406762306a36Sopenharmony_ci } 406862306a36Sopenharmony_ci 406962306a36Sopenharmony_ci if ($build_type eq "nobuild") { 407062306a36Sopenharmony_ci dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test"; 407162306a36Sopenharmony_ci } 407262306a36Sopenharmony_ci 407362306a36Sopenharmony_ci build $build_type or dodie "Failed to build"; 407462306a36Sopenharmony_ci 407562306a36Sopenharmony_ci open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file"; 407662306a36Sopenharmony_ci 407762306a36Sopenharmony_ci open(IN, $buildlog) or dodie "Can't open $buildlog"; 407862306a36Sopenharmony_ci while (<IN>) { 407962306a36Sopenharmony_ci # Some compilers use UTF-8 extended for quotes 408062306a36Sopenharmony_ci # for distcc heterogeneous systems, this causes issues 408162306a36Sopenharmony_ci s/$utf8_quote/'/g; 408262306a36Sopenharmony_ci 408362306a36Sopenharmony_ci if (/$check_build_re/) { 408462306a36Sopenharmony_ci print OUT; 408562306a36Sopenharmony_ci } 408662306a36Sopenharmony_ci } 408762306a36Sopenharmony_ci close(IN); 408862306a36Sopenharmony_ci 408962306a36Sopenharmony_ci close(OUT); 409062306a36Sopenharmony_ci 409162306a36Sopenharmony_ci success $i; 409262306a36Sopenharmony_ci} 409362306a36Sopenharmony_ci 409462306a36Sopenharmony_cisub option_defined { 409562306a36Sopenharmony_ci my ($option) = @_; 409662306a36Sopenharmony_ci 409762306a36Sopenharmony_ci if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) { 409862306a36Sopenharmony_ci return 1; 409962306a36Sopenharmony_ci } 410062306a36Sopenharmony_ci 410162306a36Sopenharmony_ci return 0; 410262306a36Sopenharmony_ci} 410362306a36Sopenharmony_ci 410462306a36Sopenharmony_cisub __set_test_option { 410562306a36Sopenharmony_ci my ($name, $i) = @_; 410662306a36Sopenharmony_ci 410762306a36Sopenharmony_ci my $option = "$name\[$i\]"; 410862306a36Sopenharmony_ci 410962306a36Sopenharmony_ci if (option_defined($option)) { 411062306a36Sopenharmony_ci return $opt{$option}; 411162306a36Sopenharmony_ci } 411262306a36Sopenharmony_ci 411362306a36Sopenharmony_ci foreach my $test (keys %repeat_tests) { 411462306a36Sopenharmony_ci if ($i >= $test && 411562306a36Sopenharmony_ci $i < $test + $repeat_tests{$test}) { 411662306a36Sopenharmony_ci $option = "$name\[$test\]"; 411762306a36Sopenharmony_ci if (option_defined($option)) { 411862306a36Sopenharmony_ci return $opt{$option}; 411962306a36Sopenharmony_ci } 412062306a36Sopenharmony_ci } 412162306a36Sopenharmony_ci } 412262306a36Sopenharmony_ci 412362306a36Sopenharmony_ci if (option_defined($name)) { 412462306a36Sopenharmony_ci return $opt{$name}; 412562306a36Sopenharmony_ci } 412662306a36Sopenharmony_ci 412762306a36Sopenharmony_ci return undef; 412862306a36Sopenharmony_ci} 412962306a36Sopenharmony_ci 413062306a36Sopenharmony_cisub set_test_option { 413162306a36Sopenharmony_ci my ($name, $i) = @_; 413262306a36Sopenharmony_ci 413362306a36Sopenharmony_ci my $option = __set_test_option($name, $i); 413462306a36Sopenharmony_ci return $option if (!defined($option)); 413562306a36Sopenharmony_ci 413662306a36Sopenharmony_ci return eval_option($name, $option, $i); 413762306a36Sopenharmony_ci} 413862306a36Sopenharmony_ci 413962306a36Sopenharmony_cisub find_mailer { 414062306a36Sopenharmony_ci my ($mailer) = @_; 414162306a36Sopenharmony_ci 414262306a36Sopenharmony_ci my @paths = split /:/, $ENV{PATH}; 414362306a36Sopenharmony_ci 414462306a36Sopenharmony_ci # sendmail is usually in /usr/sbin 414562306a36Sopenharmony_ci $paths[$#paths + 1] = "/usr/sbin"; 414662306a36Sopenharmony_ci 414762306a36Sopenharmony_ci foreach my $path (@paths) { 414862306a36Sopenharmony_ci if (-x "$path/$mailer") { 414962306a36Sopenharmony_ci return $path; 415062306a36Sopenharmony_ci } 415162306a36Sopenharmony_ci } 415262306a36Sopenharmony_ci 415362306a36Sopenharmony_ci return undef; 415462306a36Sopenharmony_ci} 415562306a36Sopenharmony_ci 415662306a36Sopenharmony_cisub do_send_mail { 415762306a36Sopenharmony_ci my ($subject, $message, $file) = @_; 415862306a36Sopenharmony_ci 415962306a36Sopenharmony_ci if (!defined($mail_path)) { 416062306a36Sopenharmony_ci # find the mailer 416162306a36Sopenharmony_ci $mail_path = find_mailer $mailer; 416262306a36Sopenharmony_ci if (!defined($mail_path)) { 416362306a36Sopenharmony_ci die "\nCan not find $mailer in PATH\n"; 416462306a36Sopenharmony_ci } 416562306a36Sopenharmony_ci } 416662306a36Sopenharmony_ci 416762306a36Sopenharmony_ci my $header_file = "$tmpdir/header"; 416862306a36Sopenharmony_ci open (HEAD, ">$header_file") or die "Can not create $header_file\n"; 416962306a36Sopenharmony_ci print HEAD "To: $mailto\n"; 417062306a36Sopenharmony_ci print HEAD "Subject: $subject\n\n"; 417162306a36Sopenharmony_ci print HEAD "$message\n"; 417262306a36Sopenharmony_ci close HEAD; 417362306a36Sopenharmony_ci 417462306a36Sopenharmony_ci if (!defined($mail_command)) { 417562306a36Sopenharmony_ci if ($mailer eq "mail" || $mailer eq "mailx") { 417662306a36Sopenharmony_ci $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO"; 417762306a36Sopenharmony_ci } elsif ($mailer eq "sendmail" ) { 417862306a36Sopenharmony_ci $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -t \$MAILTO"; 417962306a36Sopenharmony_ci } else { 418062306a36Sopenharmony_ci die "\nYour mailer: $mailer is not supported.\n"; 418162306a36Sopenharmony_ci } 418262306a36Sopenharmony_ci } 418362306a36Sopenharmony_ci 418462306a36Sopenharmony_ci if (defined($file)) { 418562306a36Sopenharmony_ci $mail_command =~ s/\$BODY_FILE/$file/g; 418662306a36Sopenharmony_ci } else { 418762306a36Sopenharmony_ci $mail_command =~ s/\$BODY_FILE//g; 418862306a36Sopenharmony_ci } 418962306a36Sopenharmony_ci 419062306a36Sopenharmony_ci $mail_command =~ s/\$HEADER_FILE/$header_file/g; 419162306a36Sopenharmony_ci $mail_command =~ s/\$MAILER/$mailer/g; 419262306a36Sopenharmony_ci $mail_command =~ s/\$MAIL_PATH/$mail_path/g; 419362306a36Sopenharmony_ci $mail_command =~ s/\$MAILTO/$mailto/g; 419462306a36Sopenharmony_ci $mail_command =~ s/\$SUBJECT/$subject/g; 419562306a36Sopenharmony_ci $mail_command =~ s/\$MESSAGE/$message/g; 419662306a36Sopenharmony_ci 419762306a36Sopenharmony_ci my $ret = run_command $mail_command; 419862306a36Sopenharmony_ci if (!$ret && defined($file)) { 419962306a36Sopenharmony_ci # try again without the file 420062306a36Sopenharmony_ci $message .= "\n\n*** FAILED TO SEND LOG ***\n\n"; 420162306a36Sopenharmony_ci do_send_email($subject, $message); 420262306a36Sopenharmony_ci } 420362306a36Sopenharmony_ci} 420462306a36Sopenharmony_ci 420562306a36Sopenharmony_cisub send_email { 420662306a36Sopenharmony_ci if (defined($mailto)) { 420762306a36Sopenharmony_ci if (!defined($mailer)) { 420862306a36Sopenharmony_ci doprint "No email sent: email or mailer not specified in config.\n"; 420962306a36Sopenharmony_ci return; 421062306a36Sopenharmony_ci } 421162306a36Sopenharmony_ci do_send_mail @_; 421262306a36Sopenharmony_ci } 421362306a36Sopenharmony_ci} 421462306a36Sopenharmony_ci 421562306a36Sopenharmony_cisub cancel_test { 421662306a36Sopenharmony_ci if ($monitor_cnt) { 421762306a36Sopenharmony_ci end_monitor; 421862306a36Sopenharmony_ci } 421962306a36Sopenharmony_ci if ($email_when_canceled) { 422062306a36Sopenharmony_ci my $name = get_test_name; 422162306a36Sopenharmony_ci send_email("KTEST: Your [$name] test was cancelled", 422262306a36Sopenharmony_ci "Your test started at $script_start_time was cancelled: sig int"); 422362306a36Sopenharmony_ci } 422462306a36Sopenharmony_ci die "\nCaught Sig Int, test interrupted: $!\n" 422562306a36Sopenharmony_ci} 422662306a36Sopenharmony_ci 422762306a36Sopenharmony_ci$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl [config-file]\n"; 422862306a36Sopenharmony_ci 422962306a36Sopenharmony_ciif ($#ARGV == 0) { 423062306a36Sopenharmony_ci $ktest_config = $ARGV[0]; 423162306a36Sopenharmony_ci if (! -f $ktest_config) { 423262306a36Sopenharmony_ci print "$ktest_config does not exist.\n"; 423362306a36Sopenharmony_ci if (!read_yn "Create it?") { 423462306a36Sopenharmony_ci exit 0; 423562306a36Sopenharmony_ci } 423662306a36Sopenharmony_ci } 423762306a36Sopenharmony_ci} 423862306a36Sopenharmony_ci 423962306a36Sopenharmony_ciif (! -f $ktest_config) { 424062306a36Sopenharmony_ci $newconfig = 1; 424162306a36Sopenharmony_ci get_test_case; 424262306a36Sopenharmony_ci open(OUT, ">$ktest_config") or die "Can not create $ktest_config"; 424362306a36Sopenharmony_ci print OUT << "EOF" 424462306a36Sopenharmony_ci# Generated by ktest.pl 424562306a36Sopenharmony_ci# 424662306a36Sopenharmony_ci 424762306a36Sopenharmony_ci# PWD is a ktest.pl variable that will result in the process working 424862306a36Sopenharmony_ci# directory that ktest.pl is executed in. 424962306a36Sopenharmony_ci 425062306a36Sopenharmony_ci# THIS_DIR is automatically assigned the PWD of the path that generated 425162306a36Sopenharmony_ci# the config file. It is best to use this variable when assigning other 425262306a36Sopenharmony_ci# directory paths within this directory. This allows you to easily 425362306a36Sopenharmony_ci# move the test cases to other locations or to other machines. 425462306a36Sopenharmony_ci# 425562306a36Sopenharmony_ciTHIS_DIR := $variable{"PWD"} 425662306a36Sopenharmony_ci 425762306a36Sopenharmony_ci# Define each test with TEST_START 425862306a36Sopenharmony_ci# The config options below it will override the defaults 425962306a36Sopenharmony_ciTEST_START 426062306a36Sopenharmony_ciTEST_TYPE = $default{"TEST_TYPE"} 426162306a36Sopenharmony_ci 426262306a36Sopenharmony_ciDEFAULTS 426362306a36Sopenharmony_ciEOF 426462306a36Sopenharmony_ci; 426562306a36Sopenharmony_ci close(OUT); 426662306a36Sopenharmony_ci} 426762306a36Sopenharmony_ciread_config $ktest_config; 426862306a36Sopenharmony_ci 426962306a36Sopenharmony_ciif (defined($opt{"LOG_FILE"})) { 427062306a36Sopenharmony_ci $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1); 427162306a36Sopenharmony_ci} 427262306a36Sopenharmony_ci 427362306a36Sopenharmony_ci# Append any configs entered in manually to the config file. 427462306a36Sopenharmony_cimy @new_configs = keys %entered_configs; 427562306a36Sopenharmony_ciif ($#new_configs >= 0) { 427662306a36Sopenharmony_ci print "\nAppending entered in configs to $ktest_config\n"; 427762306a36Sopenharmony_ci open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; 427862306a36Sopenharmony_ci foreach my $config (@new_configs) { 427962306a36Sopenharmony_ci print OUT "$config = $entered_configs{$config}\n"; 428062306a36Sopenharmony_ci $opt{$config} = process_variables($entered_configs{$config}); 428162306a36Sopenharmony_ci } 428262306a36Sopenharmony_ci} 428362306a36Sopenharmony_ci 428462306a36Sopenharmony_ciif (defined($opt{"LOG_FILE"})) { 428562306a36Sopenharmony_ci if ($opt{"CLEAR_LOG"}) { 428662306a36Sopenharmony_ci unlink $opt{"LOG_FILE"}; 428762306a36Sopenharmony_ci } 428862306a36Sopenharmony_ci open(LOG, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 428962306a36Sopenharmony_ci LOG->autoflush(1); 429062306a36Sopenharmony_ci} 429162306a36Sopenharmony_ci 429262306a36Sopenharmony_cidoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 429362306a36Sopenharmony_ci 429462306a36Sopenharmony_cifor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 429562306a36Sopenharmony_ci 429662306a36Sopenharmony_ci if (!$i) { 429762306a36Sopenharmony_ci doprint "DEFAULT OPTIONS:\n"; 429862306a36Sopenharmony_ci } else { 429962306a36Sopenharmony_ci doprint "\nTEST $i OPTIONS"; 430062306a36Sopenharmony_ci if (defined($repeat_tests{$i})) { 430162306a36Sopenharmony_ci $repeat = $repeat_tests{$i}; 430262306a36Sopenharmony_ci doprint " ITERATE $repeat"; 430362306a36Sopenharmony_ci } 430462306a36Sopenharmony_ci doprint "\n"; 430562306a36Sopenharmony_ci } 430662306a36Sopenharmony_ci 430762306a36Sopenharmony_ci foreach my $option (sort keys %opt) { 430862306a36Sopenharmony_ci if ($option =~ /\[(\d+)\]$/) { 430962306a36Sopenharmony_ci next if ($i != $1); 431062306a36Sopenharmony_ci } else { 431162306a36Sopenharmony_ci next if ($i); 431262306a36Sopenharmony_ci } 431362306a36Sopenharmony_ci 431462306a36Sopenharmony_ci doprint "$option = $opt{$option}\n"; 431562306a36Sopenharmony_ci } 431662306a36Sopenharmony_ci} 431762306a36Sopenharmony_ci 431862306a36Sopenharmony_ci$SIG{INT} = qw(cancel_test); 431962306a36Sopenharmony_ci 432062306a36Sopenharmony_ci# First we need to do is the builds 432162306a36Sopenharmony_cifor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 432262306a36Sopenharmony_ci 432362306a36Sopenharmony_ci # Do not reboot on failing test options 432462306a36Sopenharmony_ci $no_reboot = 1; 432562306a36Sopenharmony_ci $reboot_success = 0; 432662306a36Sopenharmony_ci 432762306a36Sopenharmony_ci $have_version = 0; 432862306a36Sopenharmony_ci 432962306a36Sopenharmony_ci $iteration = $i; 433062306a36Sopenharmony_ci 433162306a36Sopenharmony_ci $build_time = 0; 433262306a36Sopenharmony_ci $install_time = 0; 433362306a36Sopenharmony_ci $reboot_time = 0; 433462306a36Sopenharmony_ci $test_time = 0; 433562306a36Sopenharmony_ci 433662306a36Sopenharmony_ci undef %force_config; 433762306a36Sopenharmony_ci 433862306a36Sopenharmony_ci my $makecmd = set_test_option("MAKE_CMD", $i); 433962306a36Sopenharmony_ci 434062306a36Sopenharmony_ci $outputdir = set_test_option("OUTPUT_DIR", $i); 434162306a36Sopenharmony_ci $builddir = set_test_option("BUILD_DIR", $i); 434262306a36Sopenharmony_ci 434362306a36Sopenharmony_ci chdir $builddir || dodie "can't change directory to $builddir"; 434462306a36Sopenharmony_ci 434562306a36Sopenharmony_ci if (!-d $outputdir) { 434662306a36Sopenharmony_ci mkpath($outputdir) or 434762306a36Sopenharmony_ci dodie "can't create $outputdir"; 434862306a36Sopenharmony_ci } 434962306a36Sopenharmony_ci 435062306a36Sopenharmony_ci $make = "$makecmd O=$outputdir"; 435162306a36Sopenharmony_ci 435262306a36Sopenharmony_ci # Load all the options into their mapped variable names 435362306a36Sopenharmony_ci foreach my $opt (keys %option_map) { 435462306a36Sopenharmony_ci ${$option_map{$opt}} = set_test_option($opt, $i); 435562306a36Sopenharmony_ci } 435662306a36Sopenharmony_ci 435762306a36Sopenharmony_ci $start_minconfig_defined = 1; 435862306a36Sopenharmony_ci 435962306a36Sopenharmony_ci # The first test may override the PRE_KTEST option 436062306a36Sopenharmony_ci if ($i == 1) { 436162306a36Sopenharmony_ci if (defined($pre_ktest)) { 436262306a36Sopenharmony_ci doprint "\n"; 436362306a36Sopenharmony_ci run_command $pre_ktest; 436462306a36Sopenharmony_ci } 436562306a36Sopenharmony_ci if ($email_when_started) { 436662306a36Sopenharmony_ci my $name = get_test_name; 436762306a36Sopenharmony_ci send_email("KTEST: Your [$name] test was started", 436862306a36Sopenharmony_ci "Your test was started on $script_start_time"); 436962306a36Sopenharmony_ci } 437062306a36Sopenharmony_ci } 437162306a36Sopenharmony_ci 437262306a36Sopenharmony_ci # Any test can override the POST_KTEST option 437362306a36Sopenharmony_ci # The last test takes precedence. 437462306a36Sopenharmony_ci if (defined($post_ktest)) { 437562306a36Sopenharmony_ci $final_post_ktest = $post_ktest; 437662306a36Sopenharmony_ci } 437762306a36Sopenharmony_ci 437862306a36Sopenharmony_ci if (!defined($start_minconfig)) { 437962306a36Sopenharmony_ci $start_minconfig_defined = 0; 438062306a36Sopenharmony_ci $start_minconfig = $minconfig; 438162306a36Sopenharmony_ci } 438262306a36Sopenharmony_ci 438362306a36Sopenharmony_ci if (!-d $tmpdir) { 438462306a36Sopenharmony_ci mkpath($tmpdir) or 438562306a36Sopenharmony_ci dodie "can't create $tmpdir"; 438662306a36Sopenharmony_ci } 438762306a36Sopenharmony_ci 438862306a36Sopenharmony_ci $ENV{"SSH_USER"} = $ssh_user; 438962306a36Sopenharmony_ci $ENV{"MACHINE"} = $machine; 439062306a36Sopenharmony_ci 439162306a36Sopenharmony_ci $buildlog = "$tmpdir/buildlog-$machine"; 439262306a36Sopenharmony_ci $testlog = "$tmpdir/testlog-$machine"; 439362306a36Sopenharmony_ci $dmesg = "$tmpdir/dmesg-$machine"; 439462306a36Sopenharmony_ci $output_config = "$outputdir/.config"; 439562306a36Sopenharmony_ci 439662306a36Sopenharmony_ci if (!$buildonly) { 439762306a36Sopenharmony_ci $target = "$ssh_user\@$machine"; 439862306a36Sopenharmony_ci if (($reboot_type eq "grub") or ($reboot_type eq "grub2bls")) { 439962306a36Sopenharmony_ci dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 440062306a36Sopenharmony_ci } elsif ($reboot_type eq "grub2") { 440162306a36Sopenharmony_ci dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 440262306a36Sopenharmony_ci dodie "GRUB_FILE not defined" if (!defined($grub_file)); 440362306a36Sopenharmony_ci } elsif ($reboot_type eq "syslinux") { 440462306a36Sopenharmony_ci dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label)); 440562306a36Sopenharmony_ci } 440662306a36Sopenharmony_ci } 440762306a36Sopenharmony_ci 440862306a36Sopenharmony_ci my $run_type = $build_type; 440962306a36Sopenharmony_ci if ($test_type eq "patchcheck") { 441062306a36Sopenharmony_ci $run_type = $patchcheck_type; 441162306a36Sopenharmony_ci } elsif ($test_type eq "bisect") { 441262306a36Sopenharmony_ci $run_type = $bisect_type; 441362306a36Sopenharmony_ci } elsif ($test_type eq "config_bisect") { 441462306a36Sopenharmony_ci $run_type = $config_bisect_type; 441562306a36Sopenharmony_ci } elsif ($test_type eq "make_min_config") { 441662306a36Sopenharmony_ci $run_type = ""; 441762306a36Sopenharmony_ci } elsif ($test_type eq "make_warnings_file") { 441862306a36Sopenharmony_ci $run_type = ""; 441962306a36Sopenharmony_ci } 442062306a36Sopenharmony_ci 442162306a36Sopenharmony_ci # mistake in config file? 442262306a36Sopenharmony_ci if (!defined($run_type)) { 442362306a36Sopenharmony_ci $run_type = "ERROR"; 442462306a36Sopenharmony_ci } 442562306a36Sopenharmony_ci 442662306a36Sopenharmony_ci my $installme = ""; 442762306a36Sopenharmony_ci $installme = " no_install" if ($no_install); 442862306a36Sopenharmony_ci 442962306a36Sopenharmony_ci my $name = ""; 443062306a36Sopenharmony_ci 443162306a36Sopenharmony_ci if (defined($test_name)) { 443262306a36Sopenharmony_ci $name = " ($test_name)"; 443362306a36Sopenharmony_ci } 443462306a36Sopenharmony_ci 443562306a36Sopenharmony_ci doprint "\n\n"; 443662306a36Sopenharmony_ci 443762306a36Sopenharmony_ci if (defined($opt{"LOG_FILE"})) { 443862306a36Sopenharmony_ci $test_log_start = tell(LOG); 443962306a36Sopenharmony_ci } 444062306a36Sopenharmony_ci 444162306a36Sopenharmony_ci doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n"; 444262306a36Sopenharmony_ci 444362306a36Sopenharmony_ci if (defined($pre_test)) { 444462306a36Sopenharmony_ci my $ret = run_command $pre_test; 444562306a36Sopenharmony_ci if (!$ret && defined($pre_test_die) && 444662306a36Sopenharmony_ci $pre_test_die) { 444762306a36Sopenharmony_ci dodie "failed to pre_test\n"; 444862306a36Sopenharmony_ci } 444962306a36Sopenharmony_ci } 445062306a36Sopenharmony_ci 445162306a36Sopenharmony_ci unlink $dmesg; 445262306a36Sopenharmony_ci unlink $buildlog; 445362306a36Sopenharmony_ci unlink $testlog; 445462306a36Sopenharmony_ci 445562306a36Sopenharmony_ci if (defined($addconfig)) { 445662306a36Sopenharmony_ci my $min = $minconfig; 445762306a36Sopenharmony_ci if (!defined($minconfig)) { 445862306a36Sopenharmony_ci $min = ""; 445962306a36Sopenharmony_ci } 446062306a36Sopenharmony_ci run_command "cat $addconfig $min > $tmpdir/add_config" or 446162306a36Sopenharmony_ci dodie "Failed to create temp config"; 446262306a36Sopenharmony_ci $minconfig = "$tmpdir/add_config"; 446362306a36Sopenharmony_ci } 446462306a36Sopenharmony_ci 446562306a36Sopenharmony_ci if (defined($checkout)) { 446662306a36Sopenharmony_ci run_command "git checkout $checkout" or 446762306a36Sopenharmony_ci dodie "failed to checkout $checkout"; 446862306a36Sopenharmony_ci } 446962306a36Sopenharmony_ci 447062306a36Sopenharmony_ci $no_reboot = 0; 447162306a36Sopenharmony_ci 447262306a36Sopenharmony_ci # A test may opt to not reboot the box 447362306a36Sopenharmony_ci if ($reboot_on_success) { 447462306a36Sopenharmony_ci $reboot_success = 1; 447562306a36Sopenharmony_ci } 447662306a36Sopenharmony_ci 447762306a36Sopenharmony_ci if ($test_type eq "bisect") { 447862306a36Sopenharmony_ci bisect $i; 447962306a36Sopenharmony_ci next; 448062306a36Sopenharmony_ci } elsif ($test_type eq "config_bisect") { 448162306a36Sopenharmony_ci config_bisect $i; 448262306a36Sopenharmony_ci next; 448362306a36Sopenharmony_ci } elsif ($test_type eq "patchcheck") { 448462306a36Sopenharmony_ci patchcheck $i; 448562306a36Sopenharmony_ci next; 448662306a36Sopenharmony_ci } elsif ($test_type eq "make_min_config") { 448762306a36Sopenharmony_ci make_min_config $i; 448862306a36Sopenharmony_ci next; 448962306a36Sopenharmony_ci } elsif ($test_type eq "make_warnings_file") { 449062306a36Sopenharmony_ci $no_reboot = 1; 449162306a36Sopenharmony_ci make_warnings_file $i; 449262306a36Sopenharmony_ci next; 449362306a36Sopenharmony_ci } 449462306a36Sopenharmony_ci 449562306a36Sopenharmony_ci if ($build_type ne "nobuild") { 449662306a36Sopenharmony_ci build $build_type or next; 449762306a36Sopenharmony_ci check_buildlog or next; 449862306a36Sopenharmony_ci } 449962306a36Sopenharmony_ci 450062306a36Sopenharmony_ci if ($test_type eq "install") { 450162306a36Sopenharmony_ci get_version; 450262306a36Sopenharmony_ci install; 450362306a36Sopenharmony_ci success $i; 450462306a36Sopenharmony_ci next; 450562306a36Sopenharmony_ci } 450662306a36Sopenharmony_ci 450762306a36Sopenharmony_ci if ($test_type ne "build") { 450862306a36Sopenharmony_ci my $failed = 0; 450962306a36Sopenharmony_ci start_monitor_and_install or $failed = 1; 451062306a36Sopenharmony_ci 451162306a36Sopenharmony_ci if (!$failed && $test_type ne "boot" && defined($run_test)) { 451262306a36Sopenharmony_ci do_run_test or $failed = 1; 451362306a36Sopenharmony_ci } 451462306a36Sopenharmony_ci end_monitor; 451562306a36Sopenharmony_ci if ($failed) { 451662306a36Sopenharmony_ci print_times; 451762306a36Sopenharmony_ci next; 451862306a36Sopenharmony_ci } 451962306a36Sopenharmony_ci } 452062306a36Sopenharmony_ci 452162306a36Sopenharmony_ci print_times; 452262306a36Sopenharmony_ci 452362306a36Sopenharmony_ci success $i; 452462306a36Sopenharmony_ci} 452562306a36Sopenharmony_ci 452662306a36Sopenharmony_ciif (defined($final_post_ktest)) { 452762306a36Sopenharmony_ci 452862306a36Sopenharmony_ci my $cp_final_post_ktest = eval_kernel_version $final_post_ktest; 452962306a36Sopenharmony_ci run_command $cp_final_post_ktest; 453062306a36Sopenharmony_ci} 453162306a36Sopenharmony_ci 453262306a36Sopenharmony_ciif ($opt{"POWEROFF_ON_SUCCESS"}) { 453362306a36Sopenharmony_ci halt; 453462306a36Sopenharmony_ci} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) { 453562306a36Sopenharmony_ci reboot_to_good; 453662306a36Sopenharmony_ci} elsif (defined($switch_to_good)) { 453762306a36Sopenharmony_ci # still need to get to the good kernel 453862306a36Sopenharmony_ci run_command $switch_to_good; 453962306a36Sopenharmony_ci} 454062306a36Sopenharmony_ci 454162306a36Sopenharmony_cidoprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 454262306a36Sopenharmony_ci 454362306a36Sopenharmony_ciif ($email_when_finished) { 454462306a36Sopenharmony_ci send_email("KTEST: Your test has finished!", 454562306a36Sopenharmony_ci "$successes of $opt{NUM_TESTS} tests started at $script_start_time were successful!"); 454662306a36Sopenharmony_ci} 454762306a36Sopenharmony_ci 454862306a36Sopenharmony_ciif (defined($opt{"LOG_FILE"})) { 454962306a36Sopenharmony_ci print "\n See $opt{LOG_FILE} for the record of results.\n\n"; 455062306a36Sopenharmony_ci close LOG; 455162306a36Sopenharmony_ci} 455262306a36Sopenharmony_ci 455362306a36Sopenharmony_ciexit 0; 455462306a36Sopenharmony_ci 455562306a36Sopenharmony_ci## 455662306a36Sopenharmony_ci# The following are here to standardize tabs/spaces/etc across the most likely editors 455762306a36Sopenharmony_ci### 455862306a36Sopenharmony_ci 455962306a36Sopenharmony_ci# Local Variables: 456062306a36Sopenharmony_ci# mode: perl 456162306a36Sopenharmony_ci# End: 456262306a36Sopenharmony_ci# vim: softtabstop=4 4563