From c3912d3410ce752d2e6a32f471656dbc3d7b3a0c Mon Sep 17 00:00:00 2001 From: uwla Date: Wed, 22 Nov 2023 14:37:42 -0300 Subject: [PATCH 001/128] tests: move unit tests to tests/unit, add flag --unit to target them Reestructuring the tests folder by moving unit tests to tests/unit will make KW more organized and prepared for the incoming integration tests. This commit also adds the flag `--unit` to `run_tests`, which limits the scope of the tests to unit test. This may not seem like a big deal yet becayse there are only unit tests, but it will be relevant once the integration tests are incorporated. Reviewed-by: Rodrigo Siqueira Signed-off-by: uwla --- run_tests.sh | 21 +++++++++++++----- tests/{ => unit}/_kw_dash.dsh | 0 tests/{ => unit}/backup_test.sh | 18 +++++++-------- tests/{ => unit}/build_test.sh | 4 ++-- tests/{ => unit}/checkpatch_wrapper_test.sh | 6 ++--- tests/{ => unit}/config_test.sh | 2 +- tests/{ => unit}/debug_test.sh | 2 +- tests/{ => unit}/deploy_test.sh | 2 +- tests/{ => unit}/device_test.sh | 2 +- tests/{ => unit}/diff_test.sh | 2 +- tests/{ => unit}/drm_plugin_test.sh | 2 +- tests/{ => unit}/explore_test.sh | 12 +++++----- tests/{ => unit}/help_test.sh | 2 +- tests/{ => unit}/init_test.sh | 4 ++-- .../{ => unit}/kernel_config_manager_test.sh | 2 +- tests/{ => unit}/kw_dash.sh | 2 +- tests/{ => unit}/kw_db_test.sh | 4 ++-- tests/{ => unit}/kw_env_test.sh | 2 +- tests/{ => unit}/kw_remote_test.sh | 2 +- tests/{ => unit}/kw_ssh_test.sh | 4 ++-- tests/{ => unit}/kw_test.sh | 2 +- tests/{ => unit}/lib/dialog_ui_test.sh | 2 +- tests/{ => unit}/lib/kw_config_loader_test.sh | 4 ++-- tests/{ => unit}/lib/kw_include_test.sh | 2 +- tests/{ => unit}/lib/kw_string_test.sh | 2 +- tests/{ => unit}/lib/kw_time_and_date_test.sh | 2 +- tests/{ => unit}/lib/kwio_test.sh | 14 ++++++------ tests/{ => unit}/lib/kwlib_test.sh | 6 ++--- tests/{ => unit}/lib/lore_test.sh | 2 +- tests/{ => unit}/lib/remote_test.sh | 6 ++--- tests/{ => unit}/lib/signal_manager_test.sh | 2 +- tests/{ => unit}/lib/statistics_test.sh | 6 ++--- tests/{ => unit}/lib/web_test.sh | 2 +- tests/{ => unit}/mail_test.sh | 2 +- tests/{ => unit}/maintainers_test.sh | 12 +++++----- tests/{ => unit}/patch_hub_test.sh | 2 +- tests/{ => unit}/permissions_test.sh | 2 +- .../plugins/kernel_install/arch_test.sh | 2 +- .../kernel_install/bootloader_utils_test.sh | 2 +- .../plugins/kernel_install/debian_test.sh | 2 +- .../plugins/kernel_install/fedora_test.sh | 2 +- .../plugins/kernel_install/grub_test.sh | 2 +- .../plugins/kernel_install/rpi_test.sh | 2 +- .../plugins/kernel_install/utils_test.sh | 4 ++-- .../plugins/kw_mail/to_cc_cmd_test.sh | 2 +- tests/{ => unit}/pomodoro_test.sh | 4 ++-- tests/{ => unit}/report_test.sh | 8 +++---- tests/{ => unit}/samples/.config | 0 tests/{ => unit}/samples/MAINTAINERS | 0 .../samples/boot/config-5.5.0-rc2-VKMS+ | 0 .../samples/boot/config-5.6.0-rc2-AMDGPU+ | 0 tests/{ => unit}/samples/boot/grub/grub.cfg | 0 .../initramfs-5.6.0-rc2-AMDGPU+-fallback.img | 0 .../samples/boot/initramfs-initramfs-.img | 0 .../samples/boot/vmlinuz-5.5.0-rc2-VKMS+ | 0 .../samples/boot/vmlinuz-5.5.0-rc2-VKMS+.old | 0 .../samples/boot/vmlinuz-5.6.0-rc2-AMDGPU+ | 0 tests/{ => unit}/samples/boot/vmlinuz-linux | 0 tests/{ => unit}/samples/build.config | 0 tests/{ => unit}/samples/build_no_llvm.config | 0 tests/{ => unit}/samples/build_no_log.config | 0 .../{ => unit}/samples/build_template.config | 0 tests/{ => unit}/samples/build_x86.config | 0 tests/{ => unit}/samples/codestyle_check.c | 0 tests/{ => unit}/samples/codestyle_check.h | 0 tests/{ => unit}/samples/codestyle_correct.c | 0 tests/{ => unit}/samples/codestyle_error.c | 0 tests/{ => unit}/samples/codestyle_warning.c | 0 .../samples/configs/configs/config-test | 0 .../samples/configs/metadata/config-test | 0 tests/{ => unit}/samples/db_files/init.sql | 0 tests/{ => unit}/samples/db_files/insert.sql | 0 .../db_files/report/fake_entity_insert.sql | 0 .../report/statistics_and_pomodoro_insert.sql | 0 tests/{ => unit}/samples/deploy.config | 0 .../samples/deploy_all_options.config | 0 tests/{ => unit}/samples/deploy_remote.config | 0 tests/{ => unit}/samples/dmesg | 0 tests/{ => unit}/samples/etc/build.config | 0 tests/{ => unit}/samples/etc/kworkflow.config | 0 .../{ => unit}/samples/etc/strings/deploy.txt | 0 .../samples/etc/template_mkinitcpio.preset | 0 tests/{ => unit}/samples/etc/vm.config | 0 .../samples/external/get_maintainer.pl | 0 .../first_set_of_bytes_from_disk/grub2_x86 | Bin .../samples/first_set_of_bytes_from_disk/rpi4 | Bin .../first_set_of_bytes_from_disk/syslinux_x86 | Bin tests/{ => unit}/samples/grep_check.c | 0 .../kw-backup-2021-08-07_23-42-51.tar.gz | Bin tests/{ => unit}/samples/kworkflow.config | 0 .../samples/kworkflow_drm_plugin.config | 0 .../samples/kworkflow_plugin.config | 0 .../samples/kworkflow_space_comments.config | 0 .../samples/kworkflow_ssh_config_file.config | 0 .../samples/kworkflow_template.config | 0 tests/{ => unit}/samples/kworkflow_x86.config | 0 .../file_correct | 0 .../load_module_text_test_samples/file_empty | 0 .../file_repeated_keys | 0 .../file_without_key | 0 .../file_wrong_key | 0 .../samples/lore/query_result_sample.xml | 0 tests/{ => unit}/samples/lore_sample.config | 0 tests/{ => unit}/samples/mail.config | 0 tests/{ => unit}/samples/notification.config | 0 .../samples/os/arch-linux-arm/etc/os-release | 0 .../samples/os/arch/etc/lsb-release | 0 .../{ => unit}/samples/os/arch/etc/os-release | 0 .../samples/os/debian/etc/os-release | 0 .../samples/os/endeavouros/etc/os-release | 0 .../samples/os/fedora/etc/os-release | 0 .../samples/os/manjaro/etc/os-release | 0 .../{ => unit}/samples/os/none/etc/os-release | 0 .../samples/os/popos/etc/os-release | 0 .../samples/os/raspbian/etc/os-release | 0 .../samples/os/steamos/etc/os-release | 0 .../samples/os/ubuntu/etc/os-release | 0 .../samples/pomodoro_data/2020/04/04 | 0 .../samples/pomodoro_data/2020/04/05 | 0 .../samples/pomodoro_data/2021/04/04 | 0 .../samples/pomodoro_data/2021/04/05 | 0 .../samples/pomodoro_data/bad_data/2021/04/04 | 0 .../print_file_author_test_dir/code1.c | 0 .../print_file_author_test_dir/code2.c | 0 .../samples/remote_samples/remote.config | 0 .../samples/remote_samples/remote_2.config | 0 .../samples/remote_samples/remote_3.config | 0 .../samples/remote_samples/remote_4.config | 0 .../remote_samples/remote_global.config | 0 .../remote_samples/remote_prefix.config | 0 .../remote_samples/remote_simple.config | 0 tests/{ => unit}/samples/rpi/config.txt | 0 .../scripts/profiler/multi_threaded/0.csv | 0 .../scripts/profiler/multi_threaded/1.csv | 0 .../scripts/profiler/multi_threaded/2.csv | 0 .../scripts/profiler/single_threaded/0.csv | 0 .../{ => unit}/samples/statistics/2020/05/27 | 0 .../{ => unit}/samples/statistics/2020/05/28 | 0 .../{ => unit}/samples/statistics/2021/10/07 | 0 .../{ => unit}/samples/statistics/2021/10/15 | 0 .../samples/template_mkinitcpio.preset | 0 tests/{ => unit}/samples/test.patch | 16 ++++++------- .../samples/tracing/kw_main_file_mock | 0 .../tracing/src/alternate_return_and_exit.sh | 0 .../tracing/src/background_execution.sh | 0 .../samples/tracing/src/lib/stub.sh | 0 .../samples/tracing/src/nothing_to_inject.sh | 0 .../tracing/src/simple_return_and_exit.sh | 0 .../{ => unit}/samples/tracing/tracing_commit | 0 .../{ => unit}/samples/tracing/tracing_setup | 0 ...drigo_siqueira_dc_patches_june_22_2023.mbx | 0 .../samples/update_patch_test.patch | 0 .../samples/update_patch_test2.patch | 0 .../samples/update_patch_test_model.patch | 0 .../samples/update_patch_test_model2.patch | 0 tests/{ => unit}/samples/vm.config | 0 tests/{ => unit}/samples/vm_x86.config | 0 .../samples/web/reduced_lore_main_page.html | 0 tests/{ => unit}/samples/web/sample1.html | 0 tests/{ => unit}/samples/web/sample2.html | 0 tests/{ => unit}/samples/web/sample3.html | 0 tests/{ => unit}/samples/web/sample4.html | 0 tests/{ => unit}/samples/web/sample5.html | 0 tests/{ => unit}/samples/web/sample6.html | 0 tests/{ => unit}/scripts/profiler_test.sh | 2 +- tests/{ => unit}/self_update_test.sh | 2 +- tests/{ => unit}/tracing/tracing_test.sh | 2 +- ...latest_patchsets_from_mailing_list_test.sh | 2 +- .../ui/patch_hub/lore_mailing_lists_test.sh | 2 +- .../ui/patch_hub/patch_hub_core_test.sh | 2 +- .../patchset_details_and_actions_test.sh | 4 ++-- .../patch_hub/search_string_in_lore_test.sh | 2 +- .../{ => unit}/ui/patch_hub/settings_test.sh | 2 +- tests/{ => unit}/utils.sh | 2 +- tests/{ => unit}/vm_test.sh | 6 ++--- 175 files changed, 125 insertions(+), 114 deletions(-) rename tests/{ => unit}/_kw_dash.dsh (100%) rename tests/{ => unit}/backup_test.sh (94%) rename tests/{ => unit}/build_test.sh (99%) rename tests/{ => unit}/checkpatch_wrapper_test.sh (95%) rename tests/{ => unit}/config_test.sh (99%) rename tests/{ => unit}/debug_test.sh (99%) rename tests/{ => unit}/deploy_test.sh (99%) rename tests/{ => unit}/device_test.sh (99%) rename tests/{ => unit}/diff_test.sh (99%) rename tests/{ => unit}/drm_plugin_test.sh (99%) rename tests/{ => unit}/explore_test.sh (96%) rename tests/{ => unit}/help_test.sh (96%) rename tests/{ => unit}/init_test.sh (98%) rename tests/{ => unit}/kernel_config_manager_test.sh (99%) rename tests/{ => unit}/kw_dash.sh (84%) rename tests/{ => unit}/kw_db_test.sh (99%) rename tests/{ => unit}/kw_env_test.sh (99%) rename tests/{ => unit}/kw_remote_test.sh (99%) rename tests/{ => unit}/kw_ssh_test.sh (99%) rename tests/{ => unit}/kw_test.sh (96%) rename tests/{ => unit}/lib/dialog_ui_test.sh (99%) rename tests/{ => unit}/lib/kw_config_loader_test.sh (99%) rename tests/{ => unit}/lib/kw_include_test.sh (98%) rename tests/{ => unit}/lib/kw_string_test.sh (99%) rename tests/{ => unit}/lib/kw_time_and_date_test.sh (99%) rename tests/{ => unit}/lib/kwio_test.sh (97%) rename tests/{ => unit}/lib/kwlib_test.sh (99%) rename tests/{ => unit}/lib/lore_test.sh (99%) rename tests/{ => unit}/lib/remote_test.sh (99%) rename tests/{ => unit}/lib/signal_manager_test.sh (98%) rename tests/{ => unit}/lib/statistics_test.sh (97%) rename tests/{ => unit}/lib/web_test.sh (99%) rename tests/{ => unit}/mail_test.sh (99%) rename tests/{ => unit}/maintainers_test.sh (92%) rename tests/{ => unit}/patch_hub_test.sh (97%) rename tests/{ => unit}/permissions_test.sh (92%) rename tests/{ => unit}/plugins/kernel_install/arch_test.sh (99%) rename tests/{ => unit}/plugins/kernel_install/bootloader_utils_test.sh (98%) rename tests/{ => unit}/plugins/kernel_install/debian_test.sh (95%) rename tests/{ => unit}/plugins/kernel_install/fedora_test.sh (97%) rename tests/{ => unit}/plugins/kernel_install/grub_test.sh (98%) rename tests/{ => unit}/plugins/kernel_install/rpi_test.sh (99%) rename tests/{ => unit}/plugins/kernel_install/utils_test.sh (99%) rename tests/{ => unit}/plugins/kw_mail/to_cc_cmd_test.sh (98%) rename tests/{ => unit}/pomodoro_test.sh (99%) rename tests/{ => unit}/report_test.sh (98%) rename tests/{ => unit}/samples/.config (100%) rename tests/{ => unit}/samples/MAINTAINERS (100%) rename tests/{ => unit}/samples/boot/config-5.5.0-rc2-VKMS+ (100%) rename tests/{ => unit}/samples/boot/config-5.6.0-rc2-AMDGPU+ (100%) rename tests/{ => unit}/samples/boot/grub/grub.cfg (100%) rename tests/{ => unit}/samples/boot/initramfs-5.6.0-rc2-AMDGPU+-fallback.img (100%) rename tests/{ => unit}/samples/boot/initramfs-initramfs-.img (100%) rename tests/{ => unit}/samples/boot/vmlinuz-5.5.0-rc2-VKMS+ (100%) rename tests/{ => unit}/samples/boot/vmlinuz-5.5.0-rc2-VKMS+.old (100%) rename tests/{ => unit}/samples/boot/vmlinuz-5.6.0-rc2-AMDGPU+ (100%) rename tests/{ => unit}/samples/boot/vmlinuz-linux (100%) rename tests/{ => unit}/samples/build.config (100%) rename tests/{ => unit}/samples/build_no_llvm.config (100%) rename tests/{ => unit}/samples/build_no_log.config (100%) rename tests/{ => unit}/samples/build_template.config (100%) rename tests/{ => unit}/samples/build_x86.config (100%) rename tests/{ => unit}/samples/codestyle_check.c (100%) rename tests/{ => unit}/samples/codestyle_check.h (100%) rename tests/{ => unit}/samples/codestyle_correct.c (100%) rename tests/{ => unit}/samples/codestyle_error.c (100%) rename tests/{ => unit}/samples/codestyle_warning.c (100%) rename tests/{ => unit}/samples/configs/configs/config-test (100%) rename tests/{ => unit}/samples/configs/metadata/config-test (100%) rename tests/{ => unit}/samples/db_files/init.sql (100%) rename tests/{ => unit}/samples/db_files/insert.sql (100%) rename tests/{ => unit}/samples/db_files/report/fake_entity_insert.sql (100%) rename tests/{ => unit}/samples/db_files/report/statistics_and_pomodoro_insert.sql (100%) rename tests/{ => unit}/samples/deploy.config (100%) rename tests/{ => unit}/samples/deploy_all_options.config (100%) rename tests/{ => unit}/samples/deploy_remote.config (100%) rename tests/{ => unit}/samples/dmesg (100%) rename tests/{ => unit}/samples/etc/build.config (100%) rename tests/{ => unit}/samples/etc/kworkflow.config (100%) rename tests/{ => unit}/samples/etc/strings/deploy.txt (100%) rename tests/{ => unit}/samples/etc/template_mkinitcpio.preset (100%) rename tests/{ => unit}/samples/etc/vm.config (100%) rename tests/{ => unit}/samples/external/get_maintainer.pl (100%) rename tests/{ => unit}/samples/first_set_of_bytes_from_disk/grub2_x86 (100%) rename tests/{ => unit}/samples/first_set_of_bytes_from_disk/rpi4 (100%) rename tests/{ => unit}/samples/first_set_of_bytes_from_disk/syslinux_x86 (100%) rename tests/{ => unit}/samples/grep_check.c (100%) rename tests/{ => unit}/samples/kw-backup-2021-08-07_23-42-51.tar.gz (100%) rename tests/{ => unit}/samples/kworkflow.config (100%) rename tests/{ => unit}/samples/kworkflow_drm_plugin.config (100%) rename tests/{ => unit}/samples/kworkflow_plugin.config (100%) rename tests/{ => unit}/samples/kworkflow_space_comments.config (100%) rename tests/{ => unit}/samples/kworkflow_ssh_config_file.config (100%) rename tests/{ => unit}/samples/kworkflow_template.config (100%) rename tests/{ => unit}/samples/kworkflow_x86.config (100%) rename tests/{ => unit}/samples/load_module_text_test_samples/file_correct (100%) rename tests/{ => unit}/samples/load_module_text_test_samples/file_empty (100%) rename tests/{ => unit}/samples/load_module_text_test_samples/file_repeated_keys (100%) rename tests/{ => unit}/samples/load_module_text_test_samples/file_without_key (100%) rename tests/{ => unit}/samples/load_module_text_test_samples/file_wrong_key (100%) rename tests/{ => unit}/samples/lore/query_result_sample.xml (100%) rename tests/{ => unit}/samples/lore_sample.config (100%) rename tests/{ => unit}/samples/mail.config (100%) rename tests/{ => unit}/samples/notification.config (100%) rename tests/{ => unit}/samples/os/arch-linux-arm/etc/os-release (100%) rename tests/{ => unit}/samples/os/arch/etc/lsb-release (100%) rename tests/{ => unit}/samples/os/arch/etc/os-release (100%) rename tests/{ => unit}/samples/os/debian/etc/os-release (100%) rename tests/{ => unit}/samples/os/endeavouros/etc/os-release (100%) rename tests/{ => unit}/samples/os/fedora/etc/os-release (100%) rename tests/{ => unit}/samples/os/manjaro/etc/os-release (100%) rename tests/{ => unit}/samples/os/none/etc/os-release (100%) rename tests/{ => unit}/samples/os/popos/etc/os-release (100%) rename tests/{ => unit}/samples/os/raspbian/etc/os-release (100%) rename tests/{ => unit}/samples/os/steamos/etc/os-release (100%) rename tests/{ => unit}/samples/os/ubuntu/etc/os-release (100%) rename tests/{ => unit}/samples/pomodoro_data/2020/04/04 (100%) rename tests/{ => unit}/samples/pomodoro_data/2020/04/05 (100%) rename tests/{ => unit}/samples/pomodoro_data/2021/04/04 (100%) rename tests/{ => unit}/samples/pomodoro_data/2021/04/05 (100%) rename tests/{ => unit}/samples/pomodoro_data/bad_data/2021/04/04 (100%) rename tests/{ => unit}/samples/print_file_author_test_dir/code1.c (100%) rename tests/{ => unit}/samples/print_file_author_test_dir/code2.c (100%) rename tests/{ => unit}/samples/remote_samples/remote.config (100%) rename tests/{ => unit}/samples/remote_samples/remote_2.config (100%) rename tests/{ => unit}/samples/remote_samples/remote_3.config (100%) rename tests/{ => unit}/samples/remote_samples/remote_4.config (100%) rename tests/{ => unit}/samples/remote_samples/remote_global.config (100%) rename tests/{ => unit}/samples/remote_samples/remote_prefix.config (100%) rename tests/{ => unit}/samples/remote_samples/remote_simple.config (100%) rename tests/{ => unit}/samples/rpi/config.txt (100%) rename tests/{ => unit}/samples/scripts/profiler/multi_threaded/0.csv (100%) rename tests/{ => unit}/samples/scripts/profiler/multi_threaded/1.csv (100%) rename tests/{ => unit}/samples/scripts/profiler/multi_threaded/2.csv (100%) rename tests/{ => unit}/samples/scripts/profiler/single_threaded/0.csv (100%) rename tests/{ => unit}/samples/statistics/2020/05/27 (100%) rename tests/{ => unit}/samples/statistics/2020/05/28 (100%) rename tests/{ => unit}/samples/statistics/2021/10/07 (100%) rename tests/{ => unit}/samples/statistics/2021/10/15 (100%) rename tests/{ => unit}/samples/template_mkinitcpio.preset (100%) rename tests/{ => unit}/samples/test.patch (86%) rename tests/{ => unit}/samples/tracing/kw_main_file_mock (100%) rename tests/{ => unit}/samples/tracing/src/alternate_return_and_exit.sh (100%) rename tests/{ => unit}/samples/tracing/src/background_execution.sh (100%) rename tests/{ => unit}/samples/tracing/src/lib/stub.sh (100%) rename tests/{ => unit}/samples/tracing/src/nothing_to_inject.sh (100%) rename tests/{ => unit}/samples/tracing/src/simple_return_and_exit.sh (100%) rename tests/{ => unit}/samples/tracing/tracing_commit (100%) rename tests/{ => unit}/samples/tracing/tracing_setup (100%) rename tests/{ => unit}/samples/ui/patch-hub/20230622_rodrigo_siqueira_dc_patches_june_22_2023.mbx (100%) rename tests/{ => unit}/samples/update_patch_test.patch (100%) rename tests/{ => unit}/samples/update_patch_test2.patch (100%) rename tests/{ => unit}/samples/update_patch_test_model.patch (100%) rename tests/{ => unit}/samples/update_patch_test_model2.patch (100%) rename tests/{ => unit}/samples/vm.config (100%) rename tests/{ => unit}/samples/vm_x86.config (100%) rename tests/{ => unit}/samples/web/reduced_lore_main_page.html (100%) rename tests/{ => unit}/samples/web/sample1.html (100%) rename tests/{ => unit}/samples/web/sample2.html (100%) rename tests/{ => unit}/samples/web/sample3.html (100%) rename tests/{ => unit}/samples/web/sample4.html (100%) rename tests/{ => unit}/samples/web/sample5.html (100%) rename tests/{ => unit}/samples/web/sample6.html (100%) rename tests/{ => unit}/scripts/profiler_test.sh (99%) rename tests/{ => unit}/self_update_test.sh (98%) rename tests/{ => unit}/tracing/tracing_test.sh (99%) rename tests/{ => unit}/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh (93%) rename tests/{ => unit}/ui/patch_hub/lore_mailing_lists_test.sh (98%) rename tests/{ => unit}/ui/patch_hub/patch_hub_core_test.sh (98%) rename tests/{ => unit}/ui/patch_hub/patchset_details_and_actions_test.sh (97%) rename tests/{ => unit}/ui/patch_hub/search_string_in_lore_test.sh (99%) rename tests/{ => unit}/ui/patch_hub/settings_test.sh (98%) rename tests/{ => unit}/utils.sh (99%) rename tests/{ => unit}/vm_test.sh (97%) diff --git a/run_tests.sh b/run_tests.sh index dd71a5225..c503febff 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -1,15 +1,20 @@ #!/bin/bash . ./src/lib/kw_include.sh --source-only -include './tests/utils.sh' +include './tests/unit/utils.sh' include './src/lib/kwio.sh' function show_help() { - printf '%s\n' "Usage: $0 [help] [list] [test ...]" \ + printf '%s\n' "Usage: $0 [--flags] [help] [list] [test ...]" \ 'Run tests for kworkflow.' \ "Example: $0 test kw_test" \ '' \ + 'OPTIONS' \ + ' -u, --unit' \ + ' Limit tests to unit tests' \ + '' \ + 'COMMANDS' \ ' help - displays this help message' \ ' list - lists all test files under tests/' \ ' test - runs the given test' @@ -63,7 +68,7 @@ function run_tests() local test_failure_list='' for current_test in "${TESTS[@]}"; do - target=$(find ./tests -name "${current_test}*.sh" | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') + target=$(find "$TESTS_DIR" -name "${current_test}*.sh" | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') if [[ -f "$target" ]]; then say "Running test [${current_test}]" say "$SEPARATOR" @@ -100,10 +105,16 @@ function strip_path() done } +declare TESTS_DIR=./tests +if [[ "$1" == '--unit' || "$1" == '-u' ]]; then + TESTS_DIR=./tests/unit + shift +fi + check_files="$?" #shellcheck disable=SC2086 if [[ "$#" -eq 0 ]]; then - files_list=$(find ./tests -name '*_test.sh' | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') + files_list=$(find "$TESTS_DIR" -name '*_test.sh' | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') # Note: Usually we want to use double-quotes on bash variables, however, # in this case we want a set of parameters instead of a single one. strip_path $files_list @@ -112,7 +123,7 @@ if [[ "$#" -eq 0 ]]; then LANGUAGE=en_US.UTF_8 run_tests elif [[ "$1" == 'list' ]]; then index=0 - files_list=$(find ./tests/ -name '*_test.sh') + files_list=$(find "$TESTS_DIR" -name '*_test.sh') strip_path $files_list for test_name in "${TESTS[@]}"; do ((index++)) diff --git a/tests/_kw_dash.dsh b/tests/unit/_kw_dash.dsh similarity index 100% rename from tests/_kw_dash.dsh rename to tests/unit/_kw_dash.dsh diff --git a/tests/backup_test.sh b/tests/unit/backup_test.sh similarity index 94% rename from tests/backup_test.sh rename to tests/unit/backup_test.sh index 38fd69baf..3cb832b36 100755 --- a/tests/backup_test.sh +++ b/tests/unit/backup_test.sh @@ -2,7 +2,7 @@ include './src/backup.sh' include './src/lib/kwlib.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { @@ -12,9 +12,9 @@ function setUp() mkdir -p "$KW_DATA_DIR" mkdir -p "$decompress_path" - cp -r tests/samples/configs "$KW_DATA_DIR" - cp -r tests/samples/pomodoro_data "$KW_DATA_DIR/pomodoro" - cp -r tests/samples/statistics "$KW_DATA_DIR" + cp -r tests/unit/samples/configs "$KW_DATA_DIR" + cp -r tests/unit/samples/pomodoro_data "$KW_DATA_DIR/pomodoro" + cp -r tests/unit/samples/statistics "$KW_DATA_DIR" } function test_create_backup() @@ -49,13 +49,13 @@ function test_restore_backup() output=$(restore_backup "$SHUNIT_TMPDIR"/random/path/backup.tar.gz) assertEquals "($LINENO)" "$output" 'We could not find this file' - output=$(restore_backup tests/samples/kw-backup-2021-08-07_23-42-51.tar.gz) + output=$(restore_backup tests/unit/samples/kw-backup-2021-08-07_23-42-51.tar.gz) assertTrue "($LINENO) Not all files were extracted" \ "[[ -f $KW_DATA_DIR/configs/configs/config-test ]] && [[ -f $KW_DATA_DIR/configs/metadata/config-test ]]" rm -rf "${KW_DATA_DIR:?}"/* options_values['FORCE']=1 - output=$(restore_backup tests/samples/kw-backup-2021-08-07_23-42-51.tar.gz) + output=$(restore_backup tests/unit/samples/kw-backup-2021-08-07_23-42-51.tar.gz) assertTrue "($LINENO) Not all files were extracted" \ "[[ -f $KW_DATA_DIR/configs/configs/config-test ]] && [[ -f $KW_DATA_DIR/configs/metadata/config-test ]]" } @@ -107,7 +107,7 @@ function test_restore_data_from_dir() ) mkdir -p "$decompress_path/pomodoro/" - cp -r tests/samples/pomodoro_data/2021 "$decompress_path/pomodoro/" + cp -r tests/unit/samples/pomodoro_data/2021 "$decompress_path/pomodoro/" # Test duplicate files printf '%s\n' '# This line is different' >> "$decompress_path/pomodoro/2021/04/04" @@ -132,7 +132,7 @@ function test_restore_pomodoro() rm -rf "${KW_DATA_DIR:?}"/* mkdir -p "$decompress_path/pomodoro/" - cp -r tests/samples/pomodoro_data/2021 "$decompress_path/pomodoro/" + cp -r tests/unit/samples/pomodoro_data/2021 "$decompress_path/pomodoro/" touch "$decompress_path/pomodoro/tags" restore_pomodoro @@ -146,7 +146,7 @@ function test_restore_statistics() rm -rf "${KW_DATA_DIR:?}"/* mkdir -p "$decompress_path/statistics/" - cp -r tests/samples/statistics "$decompress_path" + cp -r tests/unit/samples/statistics "$decompress_path" restore_statistics diff --git a/tests/build_test.sh b/tests/unit/build_test.sh similarity index 99% rename from tests/build_test.sh rename to tests/unit/build_test.sh index 7b2aaca7b..b735aba13 100755 --- a/tests/build_test.sh +++ b/tests/unit/build_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/build.sh' > /dev/null -include './tests/utils.sh' +include './tests/unit/utils.sh' oneTimeSetUp() { @@ -540,7 +540,7 @@ function test_build_info() # Change modules modules='Total modules to be compiled: 5' - cp "${original_dir}/tests/samples/.config" '.config' + cp "${original_dir}/tests/unit/samples/.config" '.config' expected_cmd[3]="$modules" output=$(build_kernel_main 'TEST_MODE' '--info') compare_command_sequence '' "$LINENO" 'expected_cmd' "$output" diff --git a/tests/checkpatch_wrapper_test.sh b/tests/unit/checkpatch_wrapper_test.sh similarity index 95% rename from tests/checkpatch_wrapper_test.sh rename to tests/unit/checkpatch_wrapper_test.sh index f4e1a3b39..2ee93843b 100755 --- a/tests/checkpatch_wrapper_test.sh +++ b/tests/unit/checkpatch_wrapper_test.sh @@ -1,17 +1,17 @@ #!/bin/bash include './src/checkpatch_wrapper.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' # Those variables hold the last line execute_checkpatch prints in a code that is # correct, has 1 warning, has 1 erros and has 1 check, respectively. The sample -# codes used in this test are in tests/samples/ +# codes used in this test are in tests/unit/samples/ function oneTimeSetUp() { mk_fake_kernel_root "$SHUNIT_TMPDIR" - cp -r tests/samples "$SHUNIT_TMPDIR" + cp -r tests/unit/samples "$SHUNIT_TMPDIR" parse_configuration "$KW_CONFIG_SAMPLE" } diff --git a/tests/config_test.sh b/tests/unit/config_test.sh similarity index 99% rename from tests/config_test.sh rename to tests/unit/config_test.sh index 0641e2142..32e015382 100755 --- a/tests/config_test.sh +++ b/tests/unit/config_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/config.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/debug_test.sh b/tests/unit/debug_test.sh similarity index 99% rename from tests/debug_test.sh rename to tests/unit/debug_test.sh index 1438c2b0f..4e79d6c25 100755 --- a/tests/debug_test.sh +++ b/tests/unit/debug_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/debug.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' original_dir="$PWD" default_ssh='ssh -p 3333 juca@127.0.0.1' diff --git a/tests/deploy_test.sh b/tests/unit/deploy_test.sh similarity index 99% rename from tests/deploy_test.sh rename to tests/unit/deploy_test.sh index 56d428139..2efca3f0b 100755 --- a/tests/deploy_test.sh +++ b/tests/unit/deploy_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/deploy.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/device_test.sh b/tests/unit/device_test.sh similarity index 99% rename from tests/device_test.sh rename to tests/unit/device_test.sh index 8fb2748b3..64850987f 100755 --- a/tests/device_test.sh +++ b/tests/unit/device_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/device_info.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { diff --git a/tests/diff_test.sh b/tests/unit/diff_test.sh similarity index 99% rename from tests/diff_test.sh rename to tests/unit/diff_test.sh index fe1eafc03..cf4c4dee6 100755 --- a/tests/diff_test.sh +++ b/tests/unit/diff_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/diff.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function test_diff_main() { diff --git a/tests/drm_plugin_test.sh b/tests/unit/drm_plugin_test.sh similarity index 99% rename from tests/drm_plugin_test.sh rename to tests/unit/drm_plugin_test.sh index b120fb4d8..44b327c2f 100755 --- a/tests/drm_plugin_test.sh +++ b/tests/unit/drm_plugin_test.sh @@ -2,7 +2,7 @@ include './src/plugins/subsystems/drm/drm.sh' include './src/lib/kwlib.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/explore_test.sh b/tests/unit/explore_test.sh similarity index 96% rename from tests/explore_test.sh rename to tests/unit/explore_test.sh index 5c8732620..5596e35c9 100755 --- a/tests/explore_test.sh +++ b/tests/unit/explore_test.sh @@ -1,9 +1,9 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' include './src/explore.sh' -# Note: these file names came from tests/samples/ +# Note: these file names came from tests/unit/samples/ declare -a samples_names=( 'codestyle_check.c' 'codestyle_correct.c' @@ -25,12 +25,12 @@ function setUp() for commit in {0..4}; do local file_name="${samples_names[$commit]}" - cp "$current_path/tests/samples/$file_name" ./ + cp "$current_path/tests/unit/samples/$file_name" ./ git add "$file_name" &> /dev/null git commit -m "Commit number $commit" &> /dev/null done - cp "$current_path/tests/samples/grep_check.c" .git + cp "$current_path/tests/unit/samples/grep_check.c" .git cd "$current_path" || { fail "($LINENO) It was not possible to move back from temp directory" @@ -71,7 +71,7 @@ function test_explore_files_under_git_repo() assertEquals "($LINENO)" "$expected_result" "$output" # Test if search only in files under git control - cp "$current_path/tests/samples/grep_check.c" ./ + cp "$current_path/tests/unit/samples/grep_check.c" ./ MSG_OUT='GNU grep' output=$(explore_main 'GNU grep' | cut -d: -f1) assertEquals "($LINENO)" '' "$output" @@ -161,7 +161,7 @@ function test_explore_git() assertEquals "($LINENO)" '' "$output" # Test if search files not under git control - cp "$current_path/tests/samples/grep_check.c" ./ + cp "$current_path/tests/unit/samples/grep_check.c" ./ MSG_OUT='GNU grep' output=$(explore_main --all 'GNU grep' | cut -d: -f1) assertEquals "($LINENO)" 'grep_check.c' "$output" diff --git a/tests/help_test.sh b/tests/unit/help_test.sh similarity index 96% rename from tests/help_test.sh rename to tests/unit/help_test.sh index 776b2a572..8f76e292c 100755 --- a/tests/help_test.sh +++ b/tests/unit/help_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' include './src/help.sh' function test_kworkflow_help() diff --git a/tests/init_test.sh b/tests/unit/init_test.sh similarity index 98% rename from tests/init_test.sh rename to tests/unit/init_test.sh index 44e8cfbd9..4957be5d5 100755 --- a/tests/init_test.sh +++ b/tests/unit/init_test.sh @@ -1,13 +1,13 @@ #!/bin/bash include './src/init.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { original_path="$PWD" - export KW_SOUND_DIR="$PWD/tests/samples/share/sound/kw" + export KW_SOUND_DIR="$PWD/tests/unit/samples/share/sound/kw" export HOME="$SHUNIT_TMPDIR" export USER="kw_test" export KWORKFLOW="kw_dir_test" diff --git a/tests/kernel_config_manager_test.sh b/tests/unit/kernel_config_manager_test.sh similarity index 99% rename from tests/kernel_config_manager_test.sh rename to tests/unit/kernel_config_manager_test.sh index 2bb6218f6..89f76fae5 100755 --- a/tests/kernel_config_manager_test.sh +++ b/tests/unit/kernel_config_manager_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/kernel_config_manager.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { diff --git a/tests/kw_dash.sh b/tests/unit/kw_dash.sh similarity index 84% rename from tests/kw_dash.sh rename to tests/unit/kw_dash.sh index 0811a36bc..647f5a503 100755 --- a/tests/kw_dash.sh +++ b/tests/unit/kw_dash.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' function test_check_dash_integration_with_kw() { diff --git a/tests/kw_db_test.sh b/tests/unit/kw_db_test.sh similarity index 99% rename from tests/kw_db_test.sh rename to tests/unit/kw_db_test.sh index d8b05def0..ca30a10fb 100755 --- a/tests/kw_db_test.sh +++ b/tests/unit/kw_db_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' include './src/lib/kw_db.sh' function oneTimeSetUp() @@ -10,7 +10,7 @@ function oneTimeSetUp() declare -g DB_FILES - DB_FILES="$(realpath './tests/samples/db_files')" + DB_FILES="$(realpath './tests/unit/samples/db_files')" mkdir -p "$FAKE_DATA" diff --git a/tests/kw_env_test.sh b/tests/unit/kw_env_test.sh similarity index 99% rename from tests/kw_env_test.sh rename to tests/unit/kw_env_test.sh index f740cb3b0..f995c166a 100755 --- a/tests/kw_env_test.sh +++ b/tests/unit/kw_env_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/kw_env.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' setUp() { diff --git a/tests/kw_remote_test.sh b/tests/unit/kw_remote_test.sh similarity index 99% rename from tests/kw_remote_test.sh rename to tests/unit/kw_remote_test.sh index f7136dfa7..6aa17bef1 100755 --- a/tests/kw_remote_test.sh +++ b/tests/unit/kw_remote_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/kw_remote.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/kw_ssh_test.sh b/tests/unit/kw_ssh_test.sh similarity index 99% rename from tests/kw_ssh_test.sh rename to tests/unit/kw_ssh_test.sh index f23ac18a0..bcd3d7469 100755 --- a/tests/kw_ssh_test.sh +++ b/tests/unit/kw_ssh_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/kw_ssh.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' ### SSH tests ### # @@ -23,7 +23,7 @@ function setUp() mkdir -p "$TEST_PATH" mkdir -p "${SHUNIT_TMPDIR}/.kw" cp "${KW_REMOTE_SAMPLES_DIR}/remote.config" "${SHUNIT_TMPDIR}/.kw" - cp -f 'tests/samples/dmesg' "$TEST_PATH" + cp -f 'tests/unit/samples/dmesg' "$TEST_PATH" remote_parameters['REMOTE_USER']='' remote_parameters['REMOTE_IP']='' diff --git a/tests/kw_test.sh b/tests/unit/kw_test.sh similarity index 96% rename from tests/kw_test.sh rename to tests/unit/kw_test.sh index 27b4699b5..f6d692283 100755 --- a/tests/kw_test.sh +++ b/tests/unit/kw_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' unset -v KW_LIB_DIR # to be able to test the developer mode include './kw' > /dev/null # when imported kw prints the help function and we don“t want diff --git a/tests/lib/dialog_ui_test.sh b/tests/unit/lib/dialog_ui_test.sh similarity index 99% rename from tests/lib/dialog_ui_test.sh rename to tests/unit/lib/dialog_ui_test.sh index 93fa96c40..5450af320 100755 --- a/tests/lib/dialog_ui_test.sh +++ b/tests/unit/lib/dialog_ui_test.sh @@ -1,7 +1,7 @@ #!/bin/bash # include './src/lib/dialog_ui.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/lib/kw_config_loader_test.sh b/tests/unit/lib/kw_config_loader_test.sh similarity index 99% rename from tests/lib/kw_config_loader_test.sh rename to tests/unit/lib/kw_config_loader_test.sh index f7ba6d3e8..290d5bde8 100755 --- a/tests/lib/kw_config_loader_test.sh +++ b/tests/unit/lib/kw_config_loader_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' include './src/lib/kw_config_loader.sh' KWORKFLOW='kw' @@ -81,7 +81,7 @@ function test_parse_configuration_config_with_spaces_and_comments() function test_parser_configuration_failed_exit_code() { - parse_configuration 'tests/foobarpotato' + parse_configuration 'tests/unit/foobarpotato' assertEquals "($LINENO)" "$?" 22 } diff --git a/tests/lib/kw_include_test.sh b/tests/unit/lib/kw_include_test.sh similarity index 98% rename from tests/lib/kw_include_test.sh rename to tests/unit/lib/kw_include_test.sh index 010a0deda..964a70473 100755 --- a/tests/lib/kw_include_test.sh +++ b/tests/unit/lib/kw_include_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { diff --git a/tests/lib/kw_string_test.sh b/tests/unit/lib/kw_string_test.sh similarity index 99% rename from tests/lib/kw_string_test.sh rename to tests/unit/lib/kw_string_test.sh index 86081edae..d9fcd80af 100755 --- a/tests/lib/kw_string_test.sh +++ b/tests/unit/lib/kw_string_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/lib/kw_string.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function test_chop() { diff --git a/tests/lib/kw_time_and_date_test.sh b/tests/unit/lib/kw_time_and_date_test.sh similarity index 99% rename from tests/lib/kw_time_and_date_test.sh rename to tests/unit/lib/kw_time_and_date_test.sh index 3e320438e..c883f1588 100755 --- a/tests/lib/kw_time_and_date_test.sh +++ b/tests/unit/lib/kw_time_and_date_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/lib/kw_time_and_date.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/lib/kwio_test.sh b/tests/unit/lib/kwio_test.sh similarity index 97% rename from tests/lib/kwio_test.sh rename to tests/unit/lib/kwio_test.sh index 2f476c3b9..f1b082acb 100755 --- a/tests/lib/kwio_test.sh +++ b/tests/unit/lib/kwio_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' include './src/lib/kwio.sh' include './src/lib/kwlib.sh' @@ -10,21 +10,21 @@ include './src/lib/kwlib.sh' # the function will return before the background commands finish. declare -A notification_config -declare -g load_module_text_path="$PWD/tests/samples/load_module_text_test_samples/" +declare -g load_module_text_path="$PWD/tests/unit/samples/load_module_text_test_samples/" -sound_file="$PWD/tests/lib/.kwio_test_aux/sound.file" -visual_file="$PWD/tests/lib/.kwio_test_aux/visual.file" +sound_file="$PWD/tests/unit/lib/.kwio_test_aux/sound.file" +visual_file="$PWD/tests/unit/lib/.kwio_test_aux/visual.file" function setUp() { - mkdir -p tests/lib/.kwio_test_aux + mkdir -p tests/unit/lib/.kwio_test_aux notification_config['sound_alert_command']="touch $sound_file" notification_config['visual_alert_command']="touch $visual_file" } function tearDown() { - rm -rf tests/lib/.kwio_test_aux + rm -rf tests/unit/lib/.kwio_test_aux } function test_alert_completion_options() @@ -66,7 +66,7 @@ function test_alert_completion_options() function test_alert_completition_validate_config_file_options() { - mkdir -p tests/lib/.kwio_test_aux + mkdir -p tests/unit/lib/.kwio_test_aux rm -f "$sound_file" "$visual_file" notification_config['alert']='vs' diff --git a/tests/lib/kwlib_test.sh b/tests/unit/lib/kwlib_test.sh similarity index 99% rename from tests/lib/kwlib_test.sh rename to tests/unit/lib/kwlib_test.sh index 57edc528f..b1eac70aa 100755 --- a/tests/lib/kwlib_test.sh +++ b/tests/unit/lib/kwlib_test.sh @@ -2,7 +2,7 @@ include './src/maintainers.sh' include './src/lib/kwlib.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { @@ -19,7 +19,7 @@ function oneTimeSetUp() function setupPatch() { - cp -f tests/samples/test.patch "$SHUNIT_TMPDIR" + cp -f tests/unit/samples/test.patch "$SHUNIT_TMPDIR" } function setupFakeKernelRepo() @@ -54,7 +54,7 @@ function setupFakeKernelRepo() fail "($LINENO) It was not possible to move back to original directory" return } - cp -f tests/samples/MAINTAINERS "$SHUNIT_TMPDIR/MAINTAINERS" + cp -f tests/unit/samples/MAINTAINERS "$SHUNIT_TMPDIR/MAINTAINERS" } function tearDown() diff --git a/tests/lib/lore_test.sh b/tests/unit/lib/lore_test.sh similarity index 99% rename from tests/lib/lore_test.sh rename to tests/unit/lib/lore_test.sh index 7ea4a1615..1146c77a3 100755 --- a/tests/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/lib/lore.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { diff --git a/tests/lib/remote_test.sh b/tests/unit/lib/remote_test.sh similarity index 99% rename from tests/lib/remote_test.sh rename to tests/unit/lib/remote_test.sh index 787cc11b6..4c7afc349 100755 --- a/tests/lib/remote_test.sh +++ b/tests/unit/lib/remote_test.sh @@ -3,7 +3,7 @@ include './src/lib/remote.sh' include './src/lib/kwlib.sh' include './src/lib/kw_config_loader.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function which_distro_mock() { @@ -34,8 +34,8 @@ function oneTimeSetUp() mkdir -p "$FAKE_KW" mkdir -p "$TEST_PATH/.kw" - cp -f 'tests/samples/kworkflow.config' "$TEST_PATH/.kw/" - cp -f 'tests/samples/dmesg' "$TEST_PATH" + cp -f 'tests/unit/samples/kworkflow.config' "$TEST_PATH/.kw/" + cp -f 'tests/unit/samples/dmesg' "$TEST_PATH" cp -f "${KW_REMOTE_SAMPLES_DIR}/remote.config" "${TEST_PATH}/.kw/" cp -f "${KW_REMOTE_SAMPLES_DIR}/remote_4.config" "${TEST_PATH}/.kw/" diff --git a/tests/lib/signal_manager_test.sh b/tests/unit/lib/signal_manager_test.sh similarity index 98% rename from tests/lib/signal_manager_test.sh rename to tests/unit/lib/signal_manager_test.sh index 9eb7d8cee..f6b54725e 100755 --- a/tests/lib/signal_manager_test.sh +++ b/tests/unit/lib/signal_manager_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/lib/signal_manager.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { diff --git a/tests/lib/statistics_test.sh b/tests/unit/lib/statistics_test.sh similarity index 97% rename from tests/lib/statistics_test.sh rename to tests/unit/lib/statistics_test.sh index 2d3d18dc2..f16660a47 100755 --- a/tests/lib/statistics_test.sh +++ b/tests/unit/lib/statistics_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/lib/statistics.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' # Pre-calculated: # Values: "9433 8750 4316 13 18 145 107 282 45 13 57 37 4 44" @@ -10,10 +10,10 @@ include './tests/utils.sh' # Max: 9433 function setUp() { - export KW_DATA_DIR='tests/samples' + export KW_DATA_DIR='tests/unit/samples' # Samples file data - base_statistics='tests/samples/statistics/2020' + base_statistics='tests/unit/samples/statistics/2020' sample_total='19' sample_build_avg='00:00:23' #23 sample_build_min='00:00:06' #6 diff --git a/tests/lib/web_test.sh b/tests/unit/lib/web_test.sh similarity index 99% rename from tests/lib/web_test.sh rename to tests/unit/lib/web_test.sh index 8125ed114..f48421a21 100755 --- a/tests/lib/web_test.sh +++ b/tests/unit/lib/web_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/lib/web.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' oneTimeSetUp() { diff --git a/tests/mail_test.sh b/tests/unit/mail_test.sh similarity index 99% rename from tests/mail_test.sh rename to tests/unit/mail_test.sh index c7ec7dc55..5e115e551 100755 --- a/tests/mail_test.sh +++ b/tests/unit/mail_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/mail.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { diff --git a/tests/maintainers_test.sh b/tests/unit/maintainers_test.sh similarity index 92% rename from tests/maintainers_test.sh rename to tests/unit/maintainers_test.sh index b190ef630..4a1b19dec 100755 --- a/tests/maintainers_test.sh +++ b/tests/unit/maintainers_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/maintainers.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' # TODO: make maintainers_main's tests cover more corner cases? @@ -51,9 +51,9 @@ function oneTimeSetUp() # get_maintainer.pl prints when no .git is found. local original_dir="$PWD" mk_fake_kernel_root "$FAKE_KERNEL" - cp -f tests/samples/MAINTAINERS "$FAKE_KERNEL"/MAINTAINERS - cp -f tests/samples/external/get_maintainer.pl "$FAKE_KERNEL"/scripts/ - cp -f tests/samples/update_patch_test{_model,}{,2}.patch "$FAKE_KERNEL"/ + cp -f tests/unit/samples/MAINTAINERS "$FAKE_KERNEL"/MAINTAINERS + cp -f tests/unit/samples/external/get_maintainer.pl "$FAKE_KERNEL"/scripts/ + cp -f tests/unit/samples/update_patch_test{_model,}{,2}.patch "$FAKE_KERNEL"/ cd "$FAKE_KERNEL" || { fail "($LINENO) It was not possible to move to temporary directory" return @@ -79,13 +79,13 @@ function oneTimeTearDown() function test_print_files_authors() { - local -r ret=$(print_files_authors "tests/samples/print_file_author_test_dir/code1.c") + local -r ret=$(print_files_authors "tests/unit/samples/print_file_author_test_dir/code1.c") multilineAssertEquals "$ret" "$CORRECT_FILE_MSG" } function test_print_files_authors_from_dir() { - local -r ret=$(print_files_authors "tests/samples/print_file_author_test_dir") + local -r ret=$(print_files_authors "tests/unit/samples/print_file_author_test_dir") multilineAssertEquals "$ret" "$CORRECT_DIR_MSG" } diff --git a/tests/patch_hub_test.sh b/tests/unit/patch_hub_test.sh similarity index 97% rename from tests/patch_hub_test.sh rename to tests/unit/patch_hub_test.sh index e636757e1..1353ed0b9 100755 --- a/tests/patch_hub_test.sh +++ b/tests/unit/patch_hub_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/patch_hub.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { diff --git a/tests/permissions_test.sh b/tests/unit/permissions_test.sh similarity index 92% rename from tests/permissions_test.sh rename to tests/unit/permissions_test.sh index ac0a0fc68..5eb4adf49 100755 --- a/tests/permissions_test.sh +++ b/tests/unit/permissions_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' function test_src_permissions() { diff --git a/tests/plugins/kernel_install/arch_test.sh b/tests/unit/plugins/kernel_install/arch_test.sh similarity index 99% rename from tests/plugins/kernel_install/arch_test.sh rename to tests/unit/plugins/kernel_install/arch_test.sh index 7aacc3e95..887de86a0 100755 --- a/tests/plugins/kernel_install/arch_test.sh +++ b/tests/unit/plugins/kernel_install/arch_test.sh @@ -3,7 +3,7 @@ include './src/plugins/kernel_install/utils.sh' include './src/plugins/kernel_install/arch.sh' include './src/lib/kwio.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/plugins/kernel_install/bootloader_utils_test.sh b/tests/unit/plugins/kernel_install/bootloader_utils_test.sh similarity index 98% rename from tests/plugins/kernel_install/bootloader_utils_test.sh rename to tests/unit/plugins/kernel_install/bootloader_utils_test.sh index 5dee4373a..d2ce7db4b 100755 --- a/tests/plugins/kernel_install/bootloader_utils_test.sh +++ b/tests/unit/plugins/kernel_install/bootloader_utils_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/plugins/kernel_install/bootloader_utils.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' declare -r TEST_ROOT_PATH="$PWD" diff --git a/tests/plugins/kernel_install/debian_test.sh b/tests/unit/plugins/kernel_install/debian_test.sh similarity index 95% rename from tests/plugins/kernel_install/debian_test.sh rename to tests/unit/plugins/kernel_install/debian_test.sh index fed262d59..66f80036f 100755 --- a/tests/plugins/kernel_install/debian_test.sh +++ b/tests/unit/plugins/kernel_install/debian_test.sh @@ -3,7 +3,7 @@ include './src/plugins/kernel_install/utils.sh' include './src/plugins/kernel_install/debian.sh' include './src/lib/kwio.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/plugins/kernel_install/fedora_test.sh b/tests/unit/plugins/kernel_install/fedora_test.sh similarity index 97% rename from tests/plugins/kernel_install/fedora_test.sh rename to tests/unit/plugins/kernel_install/fedora_test.sh index 419d51245..0a235b682 100755 --- a/tests/plugins/kernel_install/fedora_test.sh +++ b/tests/unit/plugins/kernel_install/fedora_test.sh @@ -3,7 +3,7 @@ include './src/plugins/kernel_install/utils.sh' include './src/plugins/kernel_install/fedora.sh' include './src/lib/kwio.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/plugins/kernel_install/grub_test.sh b/tests/unit/plugins/kernel_install/grub_test.sh similarity index 98% rename from tests/plugins/kernel_install/grub_test.sh rename to tests/unit/plugins/kernel_install/grub_test.sh index d9408e4d2..a3e68497b 100755 --- a/tests/plugins/kernel_install/grub_test.sh +++ b/tests/unit/plugins/kernel_install/grub_test.sh @@ -3,7 +3,7 @@ include './src/plugins/kernel_install/utils.sh' include './src/plugins/kernel_install/grub.sh' include './src/lib/kwio.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function test_grub() { diff --git a/tests/plugins/kernel_install/rpi_test.sh b/tests/unit/plugins/kernel_install/rpi_test.sh similarity index 99% rename from tests/plugins/kernel_install/rpi_test.sh rename to tests/unit/plugins/kernel_install/rpi_test.sh index 7cec46519..67ccd161f 100755 --- a/tests/plugins/kernel_install/rpi_test.sh +++ b/tests/unit/plugins/kernel_install/rpi_test.sh @@ -2,7 +2,7 @@ include './src/plugins/kernel_install/utils.sh' include './src/plugins/kernel_install/rpi_bootloader.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/plugins/kernel_install/utils_test.sh b/tests/unit/plugins/kernel_install/utils_test.sh similarity index 99% rename from tests/plugins/kernel_install/utils_test.sh rename to tests/unit/plugins/kernel_install/utils_test.sh index 64d95c22b..8c30a7807 100755 --- a/tests/plugins/kernel_install/utils_test.sh +++ b/tests/unit/plugins/kernel_install/utils_test.sh @@ -1,7 +1,7 @@ #!/bin/bash # We load utils in the oneTimeSetUp() to ensure we can replace some kw functions -include './tests/utils.sh' +include './tests/unit/utils.sh' include './src/lib/kwio.sh' declare -r TEST_ROOT_PATH="$PWD" @@ -34,7 +34,7 @@ function oneTimeSetUp() . ./src/plugins/kernel_install/utils.sh --source-only - REMOTE_KW_DEPLOY="$PWD/tests/samples" + REMOTE_KW_DEPLOY="$PWD/tests/unit/samples" INSTALLED_KERNELS_PATH="$REMOTE_KW_DEPLOY/INSTALLED_KERNELS" } diff --git a/tests/plugins/kw_mail/to_cc_cmd_test.sh b/tests/unit/plugins/kw_mail/to_cc_cmd_test.sh similarity index 98% rename from tests/plugins/kw_mail/to_cc_cmd_test.sh rename to tests/unit/plugins/kw_mail/to_cc_cmd_test.sh index d1a27cad2..c636a10ec 100755 --- a/tests/plugins/kw_mail/to_cc_cmd_test.sh +++ b/tests/unit/plugins/kw_mail/to_cc_cmd_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { diff --git a/tests/pomodoro_test.sh b/tests/unit/pomodoro_test.sh similarity index 99% rename from tests/pomodoro_test.sh rename to tests/unit/pomodoro_test.sh index ecaf8f648..b6756c990 100755 --- a/tests/pomodoro_test.sh +++ b/tests/unit/pomodoro_test.sh @@ -2,12 +2,12 @@ include './src/pomodoro.sh' include './src/lib/kw_db.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { declare -g DB_FILES - DB_FILES="$(realpath './tests/samples/db_files')" + DB_FILES="$(realpath './tests/unit/samples/db_files')" export KW_DATA_DIR="${SHUNIT_TMPDIR}" KW_DB_DIR="$(realpath './database')" } diff --git a/tests/report_test.sh b/tests/unit/report_test.sh similarity index 98% rename from tests/report_test.sh rename to tests/unit/report_test.sh index be006bbae..6a3d57cd8 100755 --- a/tests/report_test.sh +++ b/tests/unit/report_test.sh @@ -2,12 +2,12 @@ include './src/report.sh' include './src/lib/kw_db.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { declare -g DB_FILES - DB_FILES="$(realpath './tests/samples/db_files/report')" + DB_FILES="$(realpath './tests/unit/samples/db_files/report')" export KW_DATA_DIR="${SHUNIT_TMPDIR}" KW_DB_DIR="$(realpath './database')" } @@ -239,7 +239,7 @@ function test_set_raw_data_setting_raw_data() { local expected - # See the file tests/samples/db-files/report/statistics_and_pomodoro_insert.sql + # See the file tests/unit/samples/db-files/report/statistics_and_pomodoro_insert.sql # for context of the next tests. sqlite3 "${KW_DATA_DIR}/kw.db" < "${DB_FILES}/statistics_and_pomodoro_insert.sql" @@ -300,7 +300,7 @@ function test_get_raw_data_from_period_of_time() local output local expected - # See the file tests/samples/db-files/report/fake_entity_insert.sql + # See the file tests/unit/samples/db-files/report/fake_entity_insert.sql # for context of the next tests. sqlite3 "${KW_DATA_DIR}/kw.db" < "${DB_FILES}/fake_entity_insert.sql" diff --git a/tests/samples/.config b/tests/unit/samples/.config similarity index 100% rename from tests/samples/.config rename to tests/unit/samples/.config diff --git a/tests/samples/MAINTAINERS b/tests/unit/samples/MAINTAINERS similarity index 100% rename from tests/samples/MAINTAINERS rename to tests/unit/samples/MAINTAINERS diff --git a/tests/samples/boot/config-5.5.0-rc2-VKMS+ b/tests/unit/samples/boot/config-5.5.0-rc2-VKMS+ similarity index 100% rename from tests/samples/boot/config-5.5.0-rc2-VKMS+ rename to tests/unit/samples/boot/config-5.5.0-rc2-VKMS+ diff --git a/tests/samples/boot/config-5.6.0-rc2-AMDGPU+ b/tests/unit/samples/boot/config-5.6.0-rc2-AMDGPU+ similarity index 100% rename from tests/samples/boot/config-5.6.0-rc2-AMDGPU+ rename to tests/unit/samples/boot/config-5.6.0-rc2-AMDGPU+ diff --git a/tests/samples/boot/grub/grub.cfg b/tests/unit/samples/boot/grub/grub.cfg similarity index 100% rename from tests/samples/boot/grub/grub.cfg rename to tests/unit/samples/boot/grub/grub.cfg diff --git a/tests/samples/boot/initramfs-5.6.0-rc2-AMDGPU+-fallback.img b/tests/unit/samples/boot/initramfs-5.6.0-rc2-AMDGPU+-fallback.img similarity index 100% rename from tests/samples/boot/initramfs-5.6.0-rc2-AMDGPU+-fallback.img rename to tests/unit/samples/boot/initramfs-5.6.0-rc2-AMDGPU+-fallback.img diff --git a/tests/samples/boot/initramfs-initramfs-.img b/tests/unit/samples/boot/initramfs-initramfs-.img similarity index 100% rename from tests/samples/boot/initramfs-initramfs-.img rename to tests/unit/samples/boot/initramfs-initramfs-.img diff --git a/tests/samples/boot/vmlinuz-5.5.0-rc2-VKMS+ b/tests/unit/samples/boot/vmlinuz-5.5.0-rc2-VKMS+ similarity index 100% rename from tests/samples/boot/vmlinuz-5.5.0-rc2-VKMS+ rename to tests/unit/samples/boot/vmlinuz-5.5.0-rc2-VKMS+ diff --git a/tests/samples/boot/vmlinuz-5.5.0-rc2-VKMS+.old b/tests/unit/samples/boot/vmlinuz-5.5.0-rc2-VKMS+.old similarity index 100% rename from tests/samples/boot/vmlinuz-5.5.0-rc2-VKMS+.old rename to tests/unit/samples/boot/vmlinuz-5.5.0-rc2-VKMS+.old diff --git a/tests/samples/boot/vmlinuz-5.6.0-rc2-AMDGPU+ b/tests/unit/samples/boot/vmlinuz-5.6.0-rc2-AMDGPU+ similarity index 100% rename from tests/samples/boot/vmlinuz-5.6.0-rc2-AMDGPU+ rename to tests/unit/samples/boot/vmlinuz-5.6.0-rc2-AMDGPU+ diff --git a/tests/samples/boot/vmlinuz-linux b/tests/unit/samples/boot/vmlinuz-linux similarity index 100% rename from tests/samples/boot/vmlinuz-linux rename to tests/unit/samples/boot/vmlinuz-linux diff --git a/tests/samples/build.config b/tests/unit/samples/build.config similarity index 100% rename from tests/samples/build.config rename to tests/unit/samples/build.config diff --git a/tests/samples/build_no_llvm.config b/tests/unit/samples/build_no_llvm.config similarity index 100% rename from tests/samples/build_no_llvm.config rename to tests/unit/samples/build_no_llvm.config diff --git a/tests/samples/build_no_log.config b/tests/unit/samples/build_no_log.config similarity index 100% rename from tests/samples/build_no_log.config rename to tests/unit/samples/build_no_log.config diff --git a/tests/samples/build_template.config b/tests/unit/samples/build_template.config similarity index 100% rename from tests/samples/build_template.config rename to tests/unit/samples/build_template.config diff --git a/tests/samples/build_x86.config b/tests/unit/samples/build_x86.config similarity index 100% rename from tests/samples/build_x86.config rename to tests/unit/samples/build_x86.config diff --git a/tests/samples/codestyle_check.c b/tests/unit/samples/codestyle_check.c similarity index 100% rename from tests/samples/codestyle_check.c rename to tests/unit/samples/codestyle_check.c diff --git a/tests/samples/codestyle_check.h b/tests/unit/samples/codestyle_check.h similarity index 100% rename from tests/samples/codestyle_check.h rename to tests/unit/samples/codestyle_check.h diff --git a/tests/samples/codestyle_correct.c b/tests/unit/samples/codestyle_correct.c similarity index 100% rename from tests/samples/codestyle_correct.c rename to tests/unit/samples/codestyle_correct.c diff --git a/tests/samples/codestyle_error.c b/tests/unit/samples/codestyle_error.c similarity index 100% rename from tests/samples/codestyle_error.c rename to tests/unit/samples/codestyle_error.c diff --git a/tests/samples/codestyle_warning.c b/tests/unit/samples/codestyle_warning.c similarity index 100% rename from tests/samples/codestyle_warning.c rename to tests/unit/samples/codestyle_warning.c diff --git a/tests/samples/configs/configs/config-test b/tests/unit/samples/configs/configs/config-test similarity index 100% rename from tests/samples/configs/configs/config-test rename to tests/unit/samples/configs/configs/config-test diff --git a/tests/samples/configs/metadata/config-test b/tests/unit/samples/configs/metadata/config-test similarity index 100% rename from tests/samples/configs/metadata/config-test rename to tests/unit/samples/configs/metadata/config-test diff --git a/tests/samples/db_files/init.sql b/tests/unit/samples/db_files/init.sql similarity index 100% rename from tests/samples/db_files/init.sql rename to tests/unit/samples/db_files/init.sql diff --git a/tests/samples/db_files/insert.sql b/tests/unit/samples/db_files/insert.sql similarity index 100% rename from tests/samples/db_files/insert.sql rename to tests/unit/samples/db_files/insert.sql diff --git a/tests/samples/db_files/report/fake_entity_insert.sql b/tests/unit/samples/db_files/report/fake_entity_insert.sql similarity index 100% rename from tests/samples/db_files/report/fake_entity_insert.sql rename to tests/unit/samples/db_files/report/fake_entity_insert.sql diff --git a/tests/samples/db_files/report/statistics_and_pomodoro_insert.sql b/tests/unit/samples/db_files/report/statistics_and_pomodoro_insert.sql similarity index 100% rename from tests/samples/db_files/report/statistics_and_pomodoro_insert.sql rename to tests/unit/samples/db_files/report/statistics_and_pomodoro_insert.sql diff --git a/tests/samples/deploy.config b/tests/unit/samples/deploy.config similarity index 100% rename from tests/samples/deploy.config rename to tests/unit/samples/deploy.config diff --git a/tests/samples/deploy_all_options.config b/tests/unit/samples/deploy_all_options.config similarity index 100% rename from tests/samples/deploy_all_options.config rename to tests/unit/samples/deploy_all_options.config diff --git a/tests/samples/deploy_remote.config b/tests/unit/samples/deploy_remote.config similarity index 100% rename from tests/samples/deploy_remote.config rename to tests/unit/samples/deploy_remote.config diff --git a/tests/samples/dmesg b/tests/unit/samples/dmesg similarity index 100% rename from tests/samples/dmesg rename to tests/unit/samples/dmesg diff --git a/tests/samples/etc/build.config b/tests/unit/samples/etc/build.config similarity index 100% rename from tests/samples/etc/build.config rename to tests/unit/samples/etc/build.config diff --git a/tests/samples/etc/kworkflow.config b/tests/unit/samples/etc/kworkflow.config similarity index 100% rename from tests/samples/etc/kworkflow.config rename to tests/unit/samples/etc/kworkflow.config diff --git a/tests/samples/etc/strings/deploy.txt b/tests/unit/samples/etc/strings/deploy.txt similarity index 100% rename from tests/samples/etc/strings/deploy.txt rename to tests/unit/samples/etc/strings/deploy.txt diff --git a/tests/samples/etc/template_mkinitcpio.preset b/tests/unit/samples/etc/template_mkinitcpio.preset similarity index 100% rename from tests/samples/etc/template_mkinitcpio.preset rename to tests/unit/samples/etc/template_mkinitcpio.preset diff --git a/tests/samples/etc/vm.config b/tests/unit/samples/etc/vm.config similarity index 100% rename from tests/samples/etc/vm.config rename to tests/unit/samples/etc/vm.config diff --git a/tests/samples/external/get_maintainer.pl b/tests/unit/samples/external/get_maintainer.pl similarity index 100% rename from tests/samples/external/get_maintainer.pl rename to tests/unit/samples/external/get_maintainer.pl diff --git a/tests/samples/first_set_of_bytes_from_disk/grub2_x86 b/tests/unit/samples/first_set_of_bytes_from_disk/grub2_x86 similarity index 100% rename from tests/samples/first_set_of_bytes_from_disk/grub2_x86 rename to tests/unit/samples/first_set_of_bytes_from_disk/grub2_x86 diff --git a/tests/samples/first_set_of_bytes_from_disk/rpi4 b/tests/unit/samples/first_set_of_bytes_from_disk/rpi4 similarity index 100% rename from tests/samples/first_set_of_bytes_from_disk/rpi4 rename to tests/unit/samples/first_set_of_bytes_from_disk/rpi4 diff --git a/tests/samples/first_set_of_bytes_from_disk/syslinux_x86 b/tests/unit/samples/first_set_of_bytes_from_disk/syslinux_x86 similarity index 100% rename from tests/samples/first_set_of_bytes_from_disk/syslinux_x86 rename to tests/unit/samples/first_set_of_bytes_from_disk/syslinux_x86 diff --git a/tests/samples/grep_check.c b/tests/unit/samples/grep_check.c similarity index 100% rename from tests/samples/grep_check.c rename to tests/unit/samples/grep_check.c diff --git a/tests/samples/kw-backup-2021-08-07_23-42-51.tar.gz b/tests/unit/samples/kw-backup-2021-08-07_23-42-51.tar.gz similarity index 100% rename from tests/samples/kw-backup-2021-08-07_23-42-51.tar.gz rename to tests/unit/samples/kw-backup-2021-08-07_23-42-51.tar.gz diff --git a/tests/samples/kworkflow.config b/tests/unit/samples/kworkflow.config similarity index 100% rename from tests/samples/kworkflow.config rename to tests/unit/samples/kworkflow.config diff --git a/tests/samples/kworkflow_drm_plugin.config b/tests/unit/samples/kworkflow_drm_plugin.config similarity index 100% rename from tests/samples/kworkflow_drm_plugin.config rename to tests/unit/samples/kworkflow_drm_plugin.config diff --git a/tests/samples/kworkflow_plugin.config b/tests/unit/samples/kworkflow_plugin.config similarity index 100% rename from tests/samples/kworkflow_plugin.config rename to tests/unit/samples/kworkflow_plugin.config diff --git a/tests/samples/kworkflow_space_comments.config b/tests/unit/samples/kworkflow_space_comments.config similarity index 100% rename from tests/samples/kworkflow_space_comments.config rename to tests/unit/samples/kworkflow_space_comments.config diff --git a/tests/samples/kworkflow_ssh_config_file.config b/tests/unit/samples/kworkflow_ssh_config_file.config similarity index 100% rename from tests/samples/kworkflow_ssh_config_file.config rename to tests/unit/samples/kworkflow_ssh_config_file.config diff --git a/tests/samples/kworkflow_template.config b/tests/unit/samples/kworkflow_template.config similarity index 100% rename from tests/samples/kworkflow_template.config rename to tests/unit/samples/kworkflow_template.config diff --git a/tests/samples/kworkflow_x86.config b/tests/unit/samples/kworkflow_x86.config similarity index 100% rename from tests/samples/kworkflow_x86.config rename to tests/unit/samples/kworkflow_x86.config diff --git a/tests/samples/load_module_text_test_samples/file_correct b/tests/unit/samples/load_module_text_test_samples/file_correct similarity index 100% rename from tests/samples/load_module_text_test_samples/file_correct rename to tests/unit/samples/load_module_text_test_samples/file_correct diff --git a/tests/samples/load_module_text_test_samples/file_empty b/tests/unit/samples/load_module_text_test_samples/file_empty similarity index 100% rename from tests/samples/load_module_text_test_samples/file_empty rename to tests/unit/samples/load_module_text_test_samples/file_empty diff --git a/tests/samples/load_module_text_test_samples/file_repeated_keys b/tests/unit/samples/load_module_text_test_samples/file_repeated_keys similarity index 100% rename from tests/samples/load_module_text_test_samples/file_repeated_keys rename to tests/unit/samples/load_module_text_test_samples/file_repeated_keys diff --git a/tests/samples/load_module_text_test_samples/file_without_key b/tests/unit/samples/load_module_text_test_samples/file_without_key similarity index 100% rename from tests/samples/load_module_text_test_samples/file_without_key rename to tests/unit/samples/load_module_text_test_samples/file_without_key diff --git a/tests/samples/load_module_text_test_samples/file_wrong_key b/tests/unit/samples/load_module_text_test_samples/file_wrong_key similarity index 100% rename from tests/samples/load_module_text_test_samples/file_wrong_key rename to tests/unit/samples/load_module_text_test_samples/file_wrong_key diff --git a/tests/samples/lore/query_result_sample.xml b/tests/unit/samples/lore/query_result_sample.xml similarity index 100% rename from tests/samples/lore/query_result_sample.xml rename to tests/unit/samples/lore/query_result_sample.xml diff --git a/tests/samples/lore_sample.config b/tests/unit/samples/lore_sample.config similarity index 100% rename from tests/samples/lore_sample.config rename to tests/unit/samples/lore_sample.config diff --git a/tests/samples/mail.config b/tests/unit/samples/mail.config similarity index 100% rename from tests/samples/mail.config rename to tests/unit/samples/mail.config diff --git a/tests/samples/notification.config b/tests/unit/samples/notification.config similarity index 100% rename from tests/samples/notification.config rename to tests/unit/samples/notification.config diff --git a/tests/samples/os/arch-linux-arm/etc/os-release b/tests/unit/samples/os/arch-linux-arm/etc/os-release similarity index 100% rename from tests/samples/os/arch-linux-arm/etc/os-release rename to tests/unit/samples/os/arch-linux-arm/etc/os-release diff --git a/tests/samples/os/arch/etc/lsb-release b/tests/unit/samples/os/arch/etc/lsb-release similarity index 100% rename from tests/samples/os/arch/etc/lsb-release rename to tests/unit/samples/os/arch/etc/lsb-release diff --git a/tests/samples/os/arch/etc/os-release b/tests/unit/samples/os/arch/etc/os-release similarity index 100% rename from tests/samples/os/arch/etc/os-release rename to tests/unit/samples/os/arch/etc/os-release diff --git a/tests/samples/os/debian/etc/os-release b/tests/unit/samples/os/debian/etc/os-release similarity index 100% rename from tests/samples/os/debian/etc/os-release rename to tests/unit/samples/os/debian/etc/os-release diff --git a/tests/samples/os/endeavouros/etc/os-release b/tests/unit/samples/os/endeavouros/etc/os-release similarity index 100% rename from tests/samples/os/endeavouros/etc/os-release rename to tests/unit/samples/os/endeavouros/etc/os-release diff --git a/tests/samples/os/fedora/etc/os-release b/tests/unit/samples/os/fedora/etc/os-release similarity index 100% rename from tests/samples/os/fedora/etc/os-release rename to tests/unit/samples/os/fedora/etc/os-release diff --git a/tests/samples/os/manjaro/etc/os-release b/tests/unit/samples/os/manjaro/etc/os-release similarity index 100% rename from tests/samples/os/manjaro/etc/os-release rename to tests/unit/samples/os/manjaro/etc/os-release diff --git a/tests/samples/os/none/etc/os-release b/tests/unit/samples/os/none/etc/os-release similarity index 100% rename from tests/samples/os/none/etc/os-release rename to tests/unit/samples/os/none/etc/os-release diff --git a/tests/samples/os/popos/etc/os-release b/tests/unit/samples/os/popos/etc/os-release similarity index 100% rename from tests/samples/os/popos/etc/os-release rename to tests/unit/samples/os/popos/etc/os-release diff --git a/tests/samples/os/raspbian/etc/os-release b/tests/unit/samples/os/raspbian/etc/os-release similarity index 100% rename from tests/samples/os/raspbian/etc/os-release rename to tests/unit/samples/os/raspbian/etc/os-release diff --git a/tests/samples/os/steamos/etc/os-release b/tests/unit/samples/os/steamos/etc/os-release similarity index 100% rename from tests/samples/os/steamos/etc/os-release rename to tests/unit/samples/os/steamos/etc/os-release diff --git a/tests/samples/os/ubuntu/etc/os-release b/tests/unit/samples/os/ubuntu/etc/os-release similarity index 100% rename from tests/samples/os/ubuntu/etc/os-release rename to tests/unit/samples/os/ubuntu/etc/os-release diff --git a/tests/samples/pomodoro_data/2020/04/04 b/tests/unit/samples/pomodoro_data/2020/04/04 similarity index 100% rename from tests/samples/pomodoro_data/2020/04/04 rename to tests/unit/samples/pomodoro_data/2020/04/04 diff --git a/tests/samples/pomodoro_data/2020/04/05 b/tests/unit/samples/pomodoro_data/2020/04/05 similarity index 100% rename from tests/samples/pomodoro_data/2020/04/05 rename to tests/unit/samples/pomodoro_data/2020/04/05 diff --git a/tests/samples/pomodoro_data/2021/04/04 b/tests/unit/samples/pomodoro_data/2021/04/04 similarity index 100% rename from tests/samples/pomodoro_data/2021/04/04 rename to tests/unit/samples/pomodoro_data/2021/04/04 diff --git a/tests/samples/pomodoro_data/2021/04/05 b/tests/unit/samples/pomodoro_data/2021/04/05 similarity index 100% rename from tests/samples/pomodoro_data/2021/04/05 rename to tests/unit/samples/pomodoro_data/2021/04/05 diff --git a/tests/samples/pomodoro_data/bad_data/2021/04/04 b/tests/unit/samples/pomodoro_data/bad_data/2021/04/04 similarity index 100% rename from tests/samples/pomodoro_data/bad_data/2021/04/04 rename to tests/unit/samples/pomodoro_data/bad_data/2021/04/04 diff --git a/tests/samples/print_file_author_test_dir/code1.c b/tests/unit/samples/print_file_author_test_dir/code1.c similarity index 100% rename from tests/samples/print_file_author_test_dir/code1.c rename to tests/unit/samples/print_file_author_test_dir/code1.c diff --git a/tests/samples/print_file_author_test_dir/code2.c b/tests/unit/samples/print_file_author_test_dir/code2.c similarity index 100% rename from tests/samples/print_file_author_test_dir/code2.c rename to tests/unit/samples/print_file_author_test_dir/code2.c diff --git a/tests/samples/remote_samples/remote.config b/tests/unit/samples/remote_samples/remote.config similarity index 100% rename from tests/samples/remote_samples/remote.config rename to tests/unit/samples/remote_samples/remote.config diff --git a/tests/samples/remote_samples/remote_2.config b/tests/unit/samples/remote_samples/remote_2.config similarity index 100% rename from tests/samples/remote_samples/remote_2.config rename to tests/unit/samples/remote_samples/remote_2.config diff --git a/tests/samples/remote_samples/remote_3.config b/tests/unit/samples/remote_samples/remote_3.config similarity index 100% rename from tests/samples/remote_samples/remote_3.config rename to tests/unit/samples/remote_samples/remote_3.config diff --git a/tests/samples/remote_samples/remote_4.config b/tests/unit/samples/remote_samples/remote_4.config similarity index 100% rename from tests/samples/remote_samples/remote_4.config rename to tests/unit/samples/remote_samples/remote_4.config diff --git a/tests/samples/remote_samples/remote_global.config b/tests/unit/samples/remote_samples/remote_global.config similarity index 100% rename from tests/samples/remote_samples/remote_global.config rename to tests/unit/samples/remote_samples/remote_global.config diff --git a/tests/samples/remote_samples/remote_prefix.config b/tests/unit/samples/remote_samples/remote_prefix.config similarity index 100% rename from tests/samples/remote_samples/remote_prefix.config rename to tests/unit/samples/remote_samples/remote_prefix.config diff --git a/tests/samples/remote_samples/remote_simple.config b/tests/unit/samples/remote_samples/remote_simple.config similarity index 100% rename from tests/samples/remote_samples/remote_simple.config rename to tests/unit/samples/remote_samples/remote_simple.config diff --git a/tests/samples/rpi/config.txt b/tests/unit/samples/rpi/config.txt similarity index 100% rename from tests/samples/rpi/config.txt rename to tests/unit/samples/rpi/config.txt diff --git a/tests/samples/scripts/profiler/multi_threaded/0.csv b/tests/unit/samples/scripts/profiler/multi_threaded/0.csv similarity index 100% rename from tests/samples/scripts/profiler/multi_threaded/0.csv rename to tests/unit/samples/scripts/profiler/multi_threaded/0.csv diff --git a/tests/samples/scripts/profiler/multi_threaded/1.csv b/tests/unit/samples/scripts/profiler/multi_threaded/1.csv similarity index 100% rename from tests/samples/scripts/profiler/multi_threaded/1.csv rename to tests/unit/samples/scripts/profiler/multi_threaded/1.csv diff --git a/tests/samples/scripts/profiler/multi_threaded/2.csv b/tests/unit/samples/scripts/profiler/multi_threaded/2.csv similarity index 100% rename from tests/samples/scripts/profiler/multi_threaded/2.csv rename to tests/unit/samples/scripts/profiler/multi_threaded/2.csv diff --git a/tests/samples/scripts/profiler/single_threaded/0.csv b/tests/unit/samples/scripts/profiler/single_threaded/0.csv similarity index 100% rename from tests/samples/scripts/profiler/single_threaded/0.csv rename to tests/unit/samples/scripts/profiler/single_threaded/0.csv diff --git a/tests/samples/statistics/2020/05/27 b/tests/unit/samples/statistics/2020/05/27 similarity index 100% rename from tests/samples/statistics/2020/05/27 rename to tests/unit/samples/statistics/2020/05/27 diff --git a/tests/samples/statistics/2020/05/28 b/tests/unit/samples/statistics/2020/05/28 similarity index 100% rename from tests/samples/statistics/2020/05/28 rename to tests/unit/samples/statistics/2020/05/28 diff --git a/tests/samples/statistics/2021/10/07 b/tests/unit/samples/statistics/2021/10/07 similarity index 100% rename from tests/samples/statistics/2021/10/07 rename to tests/unit/samples/statistics/2021/10/07 diff --git a/tests/samples/statistics/2021/10/15 b/tests/unit/samples/statistics/2021/10/15 similarity index 100% rename from tests/samples/statistics/2021/10/15 rename to tests/unit/samples/statistics/2021/10/15 diff --git a/tests/samples/template_mkinitcpio.preset b/tests/unit/samples/template_mkinitcpio.preset similarity index 100% rename from tests/samples/template_mkinitcpio.preset rename to tests/unit/samples/template_mkinitcpio.preset diff --git a/tests/samples/test.patch b/tests/unit/samples/test.patch similarity index 86% rename from tests/samples/test.patch rename to tests/unit/samples/test.patch index e5f96d822..7596c3e9c 100644 --- a/tests/samples/test.patch +++ b/tests/unit/samples/test.patch @@ -27,7 +27,7 @@ check for the case that does not have any issue in the code. --- src/checkpatch_wrapper.sh | 8 ++++++-- - tests/checkpatch_wrapper_test.sh | 14 +++++++++----- + tests/unit/checkpatch_wrapper_test.sh | 14 +++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/checkpatch_wrapper.sh b/src/checkpatch_wrapper.sh @@ -60,10 +60,10 @@ index 63949fc..cb38f78 100755 + done } -diff --git a/tests/checkpatch_wrapper_test.sh b/tests/checkpatch_wrapper_test.sh +diff --git a/tests/unit/checkpatch_wrapper_test.sh b/tests/unit/checkpatch_wrapper_test.sh index c079b32..cc60012 100755 ---- a/tests/checkpatch_wrapper_test.sh -+++ b/tests/checkpatch_wrapper_test.sh +--- a/tests/unit/checkpatch_wrapper_test.sh ++++ b/tests/unit/checkpatch_wrapper_test.sh @@ -8,18 +8,17 @@ function suite suite_addTest "testWarning" suite_addTest "testError" @@ -73,7 +73,7 @@ index c079b32..cc60012 100755 # Those variables hold the last line execute_checkpatch prints in a code that is correct, has # 1 warning, has 1 erros and has 1 check, respectively. The sample codes used in this test are - # in tests/samples/ + # in tests/unit/samples/ -CORRECT_MSG="=========================================================" WARNING_MSG="total: 0 errors, 1 warnings, 0 checks, 25 lines checked" ERROR_MSG="total: 1 errors, 0 warnings, 0 checks, 25 lines checked" @@ -88,10 +88,10 @@ index c079b32..cc60012 100755 function checkpatch { -- res=$(execute_checkpatch "tests/samples/codestyle_$1.c" 2>&1 | tail -n 1 ) +- res=$(execute_checkpatch "tests/unit/samples/codestyle_$1.c" 2>&1 | tail -n 1 ) - [[ "$res" != "${!MSG[$1]}" ]] && fail "Checkpatch should output:\n${!MSG[$1]}" - true # Reset return value -+ res=$(execute_checkpatch "tests/samples/codestyle_$1.c" 2>&1) ++ res=$(execute_checkpatch "tests/unit/samples/codestyle_$1.c" 2>&1) + assertTrue "Checkpatch should output:\n${!MSG[$1]}" '[[ $res =~ ${!MSG[$1]} ]]' } @@ -102,7 +102,7 @@ index c079b32..cc60012 100755 +function testNothing +{ -+ res=$(execute_checkpatch "tests/samples/codestyle_nothing.c" 2>&1) ++ res=$(execute_checkpatch "tests/unit/samples/codestyle_nothing.c" 2>&1) + assertFail "Checkpatch should not show anything" '[[ $res =~ total ]]' +} + diff --git a/tests/samples/tracing/kw_main_file_mock b/tests/unit/samples/tracing/kw_main_file_mock similarity index 100% rename from tests/samples/tracing/kw_main_file_mock rename to tests/unit/samples/tracing/kw_main_file_mock diff --git a/tests/samples/tracing/src/alternate_return_and_exit.sh b/tests/unit/samples/tracing/src/alternate_return_and_exit.sh similarity index 100% rename from tests/samples/tracing/src/alternate_return_and_exit.sh rename to tests/unit/samples/tracing/src/alternate_return_and_exit.sh diff --git a/tests/samples/tracing/src/background_execution.sh b/tests/unit/samples/tracing/src/background_execution.sh similarity index 100% rename from tests/samples/tracing/src/background_execution.sh rename to tests/unit/samples/tracing/src/background_execution.sh diff --git a/tests/samples/tracing/src/lib/stub.sh b/tests/unit/samples/tracing/src/lib/stub.sh similarity index 100% rename from tests/samples/tracing/src/lib/stub.sh rename to tests/unit/samples/tracing/src/lib/stub.sh diff --git a/tests/samples/tracing/src/nothing_to_inject.sh b/tests/unit/samples/tracing/src/nothing_to_inject.sh similarity index 100% rename from tests/samples/tracing/src/nothing_to_inject.sh rename to tests/unit/samples/tracing/src/nothing_to_inject.sh diff --git a/tests/samples/tracing/src/simple_return_and_exit.sh b/tests/unit/samples/tracing/src/simple_return_and_exit.sh similarity index 100% rename from tests/samples/tracing/src/simple_return_and_exit.sh rename to tests/unit/samples/tracing/src/simple_return_and_exit.sh diff --git a/tests/samples/tracing/tracing_commit b/tests/unit/samples/tracing/tracing_commit similarity index 100% rename from tests/samples/tracing/tracing_commit rename to tests/unit/samples/tracing/tracing_commit diff --git a/tests/samples/tracing/tracing_setup b/tests/unit/samples/tracing/tracing_setup similarity index 100% rename from tests/samples/tracing/tracing_setup rename to tests/unit/samples/tracing/tracing_setup diff --git a/tests/samples/ui/patch-hub/20230622_rodrigo_siqueira_dc_patches_june_22_2023.mbx b/tests/unit/samples/ui/patch-hub/20230622_rodrigo_siqueira_dc_patches_june_22_2023.mbx similarity index 100% rename from tests/samples/ui/patch-hub/20230622_rodrigo_siqueira_dc_patches_june_22_2023.mbx rename to tests/unit/samples/ui/patch-hub/20230622_rodrigo_siqueira_dc_patches_june_22_2023.mbx diff --git a/tests/samples/update_patch_test.patch b/tests/unit/samples/update_patch_test.patch similarity index 100% rename from tests/samples/update_patch_test.patch rename to tests/unit/samples/update_patch_test.patch diff --git a/tests/samples/update_patch_test2.patch b/tests/unit/samples/update_patch_test2.patch similarity index 100% rename from tests/samples/update_patch_test2.patch rename to tests/unit/samples/update_patch_test2.patch diff --git a/tests/samples/update_patch_test_model.patch b/tests/unit/samples/update_patch_test_model.patch similarity index 100% rename from tests/samples/update_patch_test_model.patch rename to tests/unit/samples/update_patch_test_model.patch diff --git a/tests/samples/update_patch_test_model2.patch b/tests/unit/samples/update_patch_test_model2.patch similarity index 100% rename from tests/samples/update_patch_test_model2.patch rename to tests/unit/samples/update_patch_test_model2.patch diff --git a/tests/samples/vm.config b/tests/unit/samples/vm.config similarity index 100% rename from tests/samples/vm.config rename to tests/unit/samples/vm.config diff --git a/tests/samples/vm_x86.config b/tests/unit/samples/vm_x86.config similarity index 100% rename from tests/samples/vm_x86.config rename to tests/unit/samples/vm_x86.config diff --git a/tests/samples/web/reduced_lore_main_page.html b/tests/unit/samples/web/reduced_lore_main_page.html similarity index 100% rename from tests/samples/web/reduced_lore_main_page.html rename to tests/unit/samples/web/reduced_lore_main_page.html diff --git a/tests/samples/web/sample1.html b/tests/unit/samples/web/sample1.html similarity index 100% rename from tests/samples/web/sample1.html rename to tests/unit/samples/web/sample1.html diff --git a/tests/samples/web/sample2.html b/tests/unit/samples/web/sample2.html similarity index 100% rename from tests/samples/web/sample2.html rename to tests/unit/samples/web/sample2.html diff --git a/tests/samples/web/sample3.html b/tests/unit/samples/web/sample3.html similarity index 100% rename from tests/samples/web/sample3.html rename to tests/unit/samples/web/sample3.html diff --git a/tests/samples/web/sample4.html b/tests/unit/samples/web/sample4.html similarity index 100% rename from tests/samples/web/sample4.html rename to tests/unit/samples/web/sample4.html diff --git a/tests/samples/web/sample5.html b/tests/unit/samples/web/sample5.html similarity index 100% rename from tests/samples/web/sample5.html rename to tests/unit/samples/web/sample5.html diff --git a/tests/samples/web/sample6.html b/tests/unit/samples/web/sample6.html similarity index 100% rename from tests/samples/web/sample6.html rename to tests/unit/samples/web/sample6.html diff --git a/tests/scripts/profiler_test.sh b/tests/unit/scripts/profiler_test.sh similarity index 99% rename from tests/scripts/profiler_test.sh rename to tests/unit/scripts/profiler_test.sh index cdb1ea1ee..c4a61cd21 100755 --- a/tests/scripts/profiler_test.sh +++ b/tests/unit/scripts/profiler_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './scripts/profiler.sh' > '/dev/null' 2>&1 -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/self_update_test.sh b/tests/unit/self_update_test.sh similarity index 98% rename from tests/self_update_test.sh rename to tests/unit/self_update_test.sh index 888ca72f5..a6e9dcd21 100755 --- a/tests/self_update_test.sh +++ b/tests/unit/self_update_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/self_update.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { diff --git a/tests/tracing/tracing_test.sh b/tests/unit/tracing/tracing_test.sh similarity index 99% rename from tests/tracing/tracing_test.sh rename to tests/unit/tracing/tracing_test.sh index 30521b5c0..d89f056ef 100755 --- a/tests/tracing/tracing_test.sh +++ b/tests/unit/tracing/tracing_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './tracing/tracing.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh b/tests/unit/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh similarity index 93% rename from tests/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh rename to tests/unit/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh index 4278cdd8f..ee86553eb 100755 --- a/tests/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh +++ b/tests/unit/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/ui/patch_hub/latest_patchsets_from_mailing_list.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/ui/patch_hub/lore_mailing_lists_test.sh b/tests/unit/ui/patch_hub/lore_mailing_lists_test.sh similarity index 98% rename from tests/ui/patch_hub/lore_mailing_lists_test.sh rename to tests/unit/ui/patch_hub/lore_mailing_lists_test.sh index 21205993e..bf915b479 100755 --- a/tests/ui/patch_hub/lore_mailing_lists_test.sh +++ b/tests/unit/ui/patch_hub/lore_mailing_lists_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/ui/patch_hub/lore_mailing_lists.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/ui/patch_hub/patch_hub_core_test.sh b/tests/unit/ui/patch_hub/patch_hub_core_test.sh similarity index 98% rename from tests/ui/patch_hub/patch_hub_core_test.sh rename to tests/unit/ui/patch_hub/patch_hub_core_test.sh index afeb6c196..5c2fb9785 100755 --- a/tests/ui/patch_hub/patch_hub_core_test.sh +++ b/tests/unit/ui/patch_hub/patch_hub_core_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/ui/patch_hub/patch_hub_core.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/ui/patch_hub/patchset_details_and_actions_test.sh b/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh similarity index 97% rename from tests/ui/patch_hub/patchset_details_and_actions_test.sh rename to tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh index 4d842dc6d..9f25f25c0 100755 --- a/tests/ui/patch_hub/patchset_details_and_actions_test.sh +++ b/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh @@ -1,14 +1,14 @@ #!/bin/bash include './src/ui/patch_hub/patchset_details_and_actions.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function oneTimeSetUp() { export LORE_DATA_DIR="${SHUNIT_TMPDIR}/lore" export BOOKMARKED_SERIES_PATH="${LORE_DATA_DIR}/lore_bookmarked_series" # shellcheck disable=SC2155 - export sample_mbx_file_path=$(realpath './tests/samples/ui/patch-hub/20230622_rodrigo_siqueira_dc_patches_june_22_2023.mbx') + export sample_mbx_file_path=$(realpath './tests/unit/samples/ui/patch-hub/20230622_rodrigo_siqueira_dc_patches_june_22_2023.mbx') cp "$sample_mbx_file_path" "$SHUNIT_TMPDIR" } diff --git a/tests/ui/patch_hub/search_string_in_lore_test.sh b/tests/unit/ui/patch_hub/search_string_in_lore_test.sh similarity index 99% rename from tests/ui/patch_hub/search_string_in_lore_test.sh rename to tests/unit/ui/patch_hub/search_string_in_lore_test.sh index 85c18ade9..60575e450 100755 --- a/tests/ui/patch_hub/search_string_in_lore_test.sh +++ b/tests/unit/ui/patch_hub/search_string_in_lore_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/ui/patch_hub/search_string_in_lore.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/ui/patch_hub/settings_test.sh b/tests/unit/ui/patch_hub/settings_test.sh similarity index 98% rename from tests/ui/patch_hub/settings_test.sh rename to tests/unit/ui/patch_hub/settings_test.sh index 75da2fd53..f00a999e2 100755 --- a/tests/ui/patch_hub/settings_test.sh +++ b/tests/unit/ui/patch_hub/settings_test.sh @@ -1,7 +1,7 @@ #!/bin/bash include './src/ui/patch_hub/settings.sh' -include './tests/utils.sh' +include './tests/unit/utils.sh' function setUp() { diff --git a/tests/utils.sh b/tests/unit/utils.sh similarity index 99% rename from tests/utils.sh rename to tests/unit/utils.sh index 4c72df1ed..1ed27750c 100755 --- a/tests/utils.sh +++ b/tests/unit/utils.sh @@ -1,7 +1,7 @@ #!/bin/bash REPO_ROOT_PATH="$PWD" -TEST_DIR="$PWD/tests" +TEST_DIR="$PWD/tests/unit" SAMPLES_DIR="$TEST_DIR/samples" EXTERNAL_DIR="$TEST_DIR/external" TMP_TEST_DIR="$TEST_DIR/.tmp" diff --git a/tests/vm_test.sh b/tests/unit/vm_test.sh similarity index 97% rename from tests/vm_test.sh rename to tests/unit/vm_test.sh index 3edf9164b..6ab43c39f 100755 --- a/tests/vm_test.sh +++ b/tests/unit/vm_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './tests/utils.sh' +include './tests/unit/utils.sh' include './src/lib/kw_config_loader.sh' include './src/vm.sh' @@ -56,7 +56,7 @@ function test_vm_mount() chmod a-r "${PREFIX}boot/vmlinuz-$(uname)" # Suppose it's a debian system - cp -f "$tests/samples/os/debian/etc/os-release" "$PREFIX/etc" + cp -f "$tests/unit/samples/os/debian/etc/os-release" "$PREFIX/etc" expected_cmd=( 'To mount the VM, the kernel image needs to be readable' @@ -70,7 +70,7 @@ function test_vm_mount() # Suppose it's not debian rm -rf "${etc:?}/"* - cp -f "$tests/samples/os/arch/etc/os-release" "$PREFIX/etc" + cp -f "$tests/unit/samples/os/arch/etc/os-release" "$PREFIX/etc" expected_cmd[1]="sudo chmod +r ${PREFIX}boot/vmlinuz-$(uname -r)" output=$(printf '%s\n' 'y' | vm_mount 'TEST_MODE' "$qemu_path" "$mount_point") From 8ffad839f7574dc6d7638b208ced164bd694b139 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 6 Nov 2023 18:43:23 -0700 Subject: [PATCH 002/128] src: debug: Use a proper string concatenation This commit only add {} around variables in a string concatenation. Reviewed-by: David Tadokoro Signed-off-by: Rodrigo Siqueira --- src/debug.sh | 114 +++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/debug.sh b/src/debug.sh index b6afa7941..2fc22a2ee 100644 --- a/src/debug.sh +++ b/src/debug.sh @@ -150,7 +150,7 @@ function list_debug() ftrace_list "$target" "$flag" ;; *) - complain "Invalid option: $list_target. Do you mean events or ftrace?" + complain "Invalid option: ${list_target}. Do you mean events or ftrace?" return 22 # EINVAL ;; esac @@ -175,19 +175,19 @@ function reset_debug() # Note that event already clean part of the ftrace files, except by the # ftrace filter reset_cmd=$(build_event_command_string '' 0) - reset_cmd+=" && printf '' > $FTRACE_FILTER" + reset_cmd+=" && printf '' > ${FTRACE_FILTER}" # We might have a hang process on trace_pipe, let's make sure we kill it - kill_hang_cmd="lsof 2>/dev/null | grep $TRACE_PIPE | tr -s ' ' | cut -d ' ' -f2" + kill_hang_cmd="lsof 2>/dev/null | grep ${TRACE_PIPE} | tr -s ' ' | cut -d ' ' -f2" kill_hang_cmd+=" | xargs -I{} kill -9 {}" # Make sure the we clean trace pipe - reset_cmd+=" && printf '' > $TRACING_BASE_PATH/trace_pipe" - reset_cmd+=" && $kill_hang_cmd" + reset_cmd+=" && printf '' > ${TRACING_BASE_PATH}/trace_pipe" + reset_cmd+=" && ${kill_hang_cmd}" case "$target" in 2) # LOCAL - cmd_manager "$flag" "sudo bash -c \"$reset_cmd\"" + cmd_manager "$flag" "sudo bash -c \"${reset_cmd}\"" ;; 3 | 1) # REMOTE && VM local remote="${remote_parameters['REMOTE_IP']}" @@ -231,27 +231,27 @@ function dmesg_debug() local screen_cmd if [[ -n "$follow" ]]; then - cmd="$std_dmesg_cmd --follow" + cmd="${std_dmesg_cmd} --follow" else - cmd="$std_dmesg_cmd --nopager" + cmd="${std_dmesg_cmd} --nopager" fi # Capture data if [[ -n "$base_log_path" ]]; then - touch "$base_log_path/dmesg" - printf '\n' > "$base_log_path/dmesg" - save_following_log="$base_log_path/dmesg" + touch "${base_log_path}/dmesg" + printf '\n' > "${base_log_path}/dmesg" + save_following_log="${base_log_path}/dmesg" fi # User command if [[ -n "$user_cmd" ]]; then - cmd="dmesg --clear && $user_cmd && $cmd" + cmd="dmesg --clear && ${user_cmd} && ${cmd}" if [[ -n "$follow" ]]; then screen_id=$(get_today_info '+kw_%Y_%m_%d-%H_%M_%S') - screen_cmd="screen -dmS $screen_id $user_cmd" - interrupt_data_hash['DMESG']="screen -S $screen_id -X quit > /dev/null" - cmd="dmesg --clear && $screen_cmd && $std_dmesg_cmd --follow" + screen_cmd="screen -dmS ${screen_id} ${user_cmd}" + interrupt_data_hash['DMESG']="screen -S ${screen_id} -X quit > /dev/null" + cmd="dmesg --clear && ${screen_cmd} && ${std_dmesg_cmd} --follow" fi fi @@ -319,21 +319,21 @@ function event_debug() # Capture data if [[ -n "$base_log_path" ]]; then - touch "$base_log_path/event" - printf '\n' > "$base_log_path/event" - save_following_log="$base_log_path/event" + touch "${base_log_path}/event" + printf '\n' > "${base_log_path}/event" + save_following_log="${base_log_path}/event" fi if [[ "$follow" == 1 ]]; then - command="$command && cat $TRACE_PIPE" + command="${command} && cat ${TRACE_PIPE}" fi if [[ -n "$user_cmd" && -z "$disable" ]]; then - save_following_log="$base_log_path/event" + save_following_log="${base_log_path}/event" screen_nick=$(get_today_info '+kw_%Y_%m_%d-%H_%M_%S') - screen_cmd="screen -L -Logfile ~/$screen_nick -dmS $screen_nick cat $TRACE_PIPE" - screen_end_cmd="screen -S $screen_nick -X quit" - command="$command && $screen_cmd && $user_cmd && $disable_cmd && $screen_end_cmd" + screen_cmd="screen -L -Logfile ~/${screen_nick} -dmS ${screen_nick} cat ${TRACE_PIPE}" + screen_end_cmd="screen -S ${screen_nick} -X quit" + command="${command} && ${screen_cmd} && ${user_cmd} && ${disable_cmd} && ${screen_end_cmd}" fi if [[ "$disable" == 1 ]]; then @@ -348,16 +348,16 @@ function event_debug() 2) # LOCAL if [[ -n "$list" ]]; then flag=${flag:-'SILENT'} - list_output=$(cmd_manager "$flag" "$save_following_log" "sudo bash -c \"$command\"") + list_output=$(cmd_manager "$flag" "$save_following_log" "sudo bash -c \"${command}\"") show_list "$list_output" "$event" return "$ret" fi [[ -n "$save_following_log" ]] && redirect_mode='KW_REDIRECT_MODE' - cmd_manager "$flag" "sudo bash -c \"$command\"" "$redirect_mode" "$save_following_log" + cmd_manager "$flag" "sudo bash -c \"${command}\"" "$redirect_mode" "$save_following_log" if [[ -n "$user_cmd" ]]; then - command="sudo cp /root/$screen_nick $save_following_log && sudo chown $USER:$USER $save_following_log" + command="sudo cp /root/${screen_nick} ${save_following_log} && sudo chown ${USER}:${USER} ${save_following_log}" cmd_manager "$flag" "$command" fi ;; @@ -406,11 +406,11 @@ function ftrace_list() local raw_data='' local index=1 local ret - local cmd_list="cat $TRACING_BASE_PATH/available_tracers" + local cmd_list="cat ${TRACING_BASE_PATH}/available_tracers" case "$target" in 2) # LOCAL - raw_data=$(cmd_manager "$flag" "sudo -E $cmd_list") + raw_data=$(cmd_manager "$flag" "sudo -E ${cmd_list}") ret="$?" ;; 3 | 1) # REMOTE && VM @@ -486,12 +486,12 @@ function ftrace_debug() # Handling command if [[ -n "$user_cmd" && -z "$disable" ]]; then - save_following_log="$base_log_path/ftrace" + save_following_log="${base_log_path}/ftrace" screen_nick=$(get_today_info '+kw_%Y_%m_%d-%H_%M_%S') - screen_cmd="screen -L -Logfile ~/$screen_nick -dmS $screen_nick cat $TRACE_PIPE" - screen_end_cmd="screen -S $screen_nick -X quit > /dev/null" + screen_cmd="screen -L -Logfile ~/${screen_nick} -dmS ${screen_nick} cat ${TRACE_PIPE}" + screen_end_cmd="screen -S ${screen_nick} -X quit > /dev/null" disable_cmd=$(build_ftrace_command_string '' 1) - cmd_ftrace="$cmd_ftrace && $screen_cmd && $user_cmd && $disable_cmd && $screen_end_cmd" + cmd_ftrace="${cmd_ftrace} && ${screen_cmd} && ${user_cmd} && ${disable_cmd} && ${screen_end_cmd}" fi case "$target" in @@ -502,7 +502,7 @@ function ftrace_debug() ret="$?" if [[ -n "$user_cmd" ]]; then - cmd_ftrace="sudo cp /root/$screen_nick $save_following_log && sudo chown $USER:$USER $save_following_log" + cmd_ftrace="sudo cp /root/${screen_nick} ${save_following_log} && sudo chown ${USER}:${USER} ${save_following_log}" cmd_manager "$flag" "$cmd_ftrace" fi ;; @@ -525,7 +525,7 @@ function ftrace_debug() # 130 - Owner died happens during the interruption if [[ "$ret" != 0 && "$ret" != 130 ]]; then - complain "Fail to enable ftrace: $ftrace_syntax - $ret" + complain "Fail to enable ftrace: ${ftrace_syntax} - ${ret}" complain 'Hint: try to use a wildcard in the filter' complain 'Hint: try to use: kw debug --reset' return "$ret" @@ -546,14 +546,14 @@ function build_ftrace_command_string() local char_repetition local ftrace_filters local ftrace_type - local cmd_disable_ftrace="printf '0' > $TRACING_ON" - local cmd_enable_ftrace="printf '1' > $TRACING_ON" + local cmd_disable_ftrace="printf '0' > ${TRACING_ON}" + local cmd_enable_ftrace="printf '1' > ${TRACING_ON}" local cmd_ftrace="$cmd_disable_ftrace" declare -a filter_list if [[ -n "$ftrace_disable" ]]; then - cmd_ftrace+=" && printf '' > $FTRACE_FILTER" - cmd_ftrace+=" && printf 'nop' > $FTRACE_CURRENT_PATH" + cmd_ftrace+=" && printf '' > ${FTRACE_FILTER}" + cmd_ftrace+=" && printf 'nop' > ${FTRACE_CURRENT_PATH}" printf '%s' "$cmd_ftrace" return fi @@ -578,7 +578,7 @@ function build_ftrace_command_string() # Set ftrace type ftrace_type=$(printf '%s' "$ftrace_syntax" | cut -d ':' -f1) ftrace_type=$(str_strip "$ftrace_type") - cmd_ftrace+=" && printf '%s' '$ftrace_type' > $FTRACE_CURRENT_PATH" + cmd_ftrace+=" && printf '%s' '${ftrace_type}' > ${FTRACE_CURRENT_PATH}" # We have filters if [[ "$char_repetition" -eq 1 ]]; then @@ -606,11 +606,11 @@ function build_ftrace_command_string() # Set ftrace filters for filter in "${filter_list[@]}"; do - cmd_ftrace+=" && printf '%s' '$filter' >> $FTRACE_FILTER" + cmd_ftrace+=" && printf '%s' '${filter}' >> ${FTRACE_FILTER}" done # Enable traces - cmd_ftrace+=" && $cmd_enable_ftrace" + cmd_ftrace+=" && ${cmd_enable_ftrace}" printf '%s' "$cmd_ftrace" } @@ -630,7 +630,7 @@ function build_ftrace_command_string() function prepare_log_database() { local keep_history="$1" - local debug_files_dir="$PWD/$KW_DEBUG" + local debug_files_dir="${PWD}/${KW_DEBUG}" local tmp_id='' local dir_id local id=1 @@ -743,31 +743,31 @@ function build_event_command_string() local global_trace enable=${enable:-'1'} - global_trace="printf '%s\n' $enable > $TRACING_ON" + global_trace="printf '%s\n' ${enable} > ${TRACING_ON}" # Enable events for event in "${!events_hash[@]}"; do - local current_event_enable="printf '%s\n' $enable > $event/enable" + local current_event_enable="printf '%s\n' ${enable} > ${event}/enable" local filter="${events_hash[$event]}" if [[ -n "$list" ]]; then if [[ "$second_time" == 1 ]]; then - list_events="$list_events && ls $event" + list_events="${list_events} && ls ${event}" else - list_events="ls $event" + list_events="ls ${event}" second_time=1 fi continue fi if [[ -n "$filter" ]]; then - filter="printf '%s\n' '$filter' > $event/filter" + filter="printf '%s\n' '${filter}' > ${event}/filter" set_filters+="$filter;" fi # If disable, clean filters if [[ "$enable" != 1 && -n "$event" ]]; then - filter="printf '0\n' > $event/filter" + filter="printf '0\n' > ${event}/filter" set_filters+="$filter;" fi @@ -775,19 +775,19 @@ function build_event_command_string() enable_events="$current_event_enable" continue fi - enable_events="$enable_events; $current_event_enable" + enable_events="${enable_events}; ${current_event_enable}" done if [[ -n "$list" ]]; then printf '%s\n' "$list_events" else if [[ "$enable" != 1 ]]; then - [[ -n "$set_filters" ]] && global_trace+=" && $set_filters $enable_events" + [[ -n "$set_filters" ]] && global_trace+=" && ${set_filters} ${enable_events}" # Let's ensure that ftrace is disabled - global_trace+=" && printf 'nop' > $FTRACE_CURRENT_PATH" + global_trace+=" && printf 'nop' > ${FTRACE_CURRENT_PATH}" printf '%s\n' "$global_trace" else - printf '%s\n' "$set_filters $enable_events && $global_trace" + printf '%s\n' "${set_filters} ${enable_events} && ${global_trace}" fi fi } @@ -819,7 +819,7 @@ function convert_event_syntax_to_sys_path_hash() return 22 # EINVAL fi elif [[ -n "$event" && ! "$event" =~ .*','.* ]]; then - events_hash["$EVENT_BASE_PATH/$event"]='' + events_hash["${EVENT_BASE_PATH}/${event}"]='' continue else return 22 # EINVAL @@ -838,7 +838,7 @@ function convert_event_syntax_to_sys_path_hash() specific_event=$(cut -d "[" -f1 <<< "$specific_event") fi - hash_key="$EVENT_BASE_PATH/$root_event/$specific_event" + hash_key="${EVENT_BASE_PATH}/${root_event}/${specific_event}" events_hash["$hash_key"]="$specific_filter" done done @@ -918,7 +918,7 @@ function parser_debug_options() # Set default values if [[ -n ${deploy_config[default_deploy_target]} ]]; then transition_variables=${deploy_config[default_deploy_target]} - options_values['TARGET']=${deploy_target_opt[$transition_variables]} + options_values['TARGET']=${deploy_target_opt["$transition_variables"]} else options_values['TARGET']="$LOCAL_TARGET" fi @@ -931,7 +931,7 @@ function parser_debug_options() if [[ -n ${configurations[debug_event]} ]]; then transition_variables=${configurations[debug_event]} - options_values['EVENT']=${deploy_target_opt[$transition_variables]} + options_values['EVENT']=${deploy_target_opt["$transition_variables"]} fi eval "set -- $options" @@ -1014,7 +1014,7 @@ function parser_debug_options() function debug_help() { if [[ "$1" == --help ]]; then - include "$KW_LIB_DIR/help.sh" + include "${KW_LIB_DIR}/help.sh" kworkflow_man 'debug' return fi From 5b1776eb19a8483f71432038c77cbf7309c79365 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Tue, 7 Nov 2023 19:00:49 -0700 Subject: [PATCH 003/128] src: debug: Add basic verbose code Enable verbose for debug. Reviewed-by: David Tadokoro Signed-off-by: Rodrigo Siqueira --- documentation/man/features/kw-debug.rst | 6 ++ src/_kw | 1 + src/bash_autocomplete.sh | 2 +- src/debug.sh | 51 ++++++++--- src/device_info.sh | 8 -- src/lib/kwlib.sh | 8 ++ tests/unit/debug_test.sh | 108 ++++++++++++++++-------- tests/unit/lib/kwlib_test.sh | 17 ++++ 8 files changed, 145 insertions(+), 56 deletions(-) diff --git a/documentation/man/features/kw-debug.rst b/documentation/man/features/kw-debug.rst index 9e1700ce3..3097a5fa2 100644 --- a/documentation/man/features/kw-debug.rst +++ b/documentation/man/features/kw-debug.rst @@ -12,6 +12,7 @@ SYNOPSIS | *kw* *debug* [(-l | \--list)[=( | )]] [(-e | \--event)] | *kw* *debug* [\--reset] | *kw* *debug* [(-h | \--help)] +| *kw* *debug* [(\--verbose)] DESCRIPTION =========== @@ -123,6 +124,11 @@ OPTIONS `\--dmesg`, kw will (1) clean the dmesg log, (2) run the command, (3) and collect the log. +\--verbose: + Verbose mode is an option that causes the kw program to display debug + messages to track its steps. This functionality is very useful during the + debugging process, allowing you to identify possible errors more easily. + EXAMPLES ======== diff --git a/src/_kw b/src/_kw index 9b8b22a45..082f7ea0c 100644 --- a/src/_kw +++ b/src/_kw @@ -178,6 +178,7 @@ _kw_debug() '(-e --event -r --reset -l --list -t --ftrace -g --dmesg)'{-e,--event}'[events trace]: : ' \ '(-t --ftrace -r --reset -l --list -e --event -g --dmesg)'{-t,--ftrace}'[ftrace trace]: : ' \ '(-g --dmesg -r --reset -l --list -e --event -t --ftrace)'{-g,--dmesg}'[dmesg log]' \ + '(--verbose)--verbose[enable verbose mode]' \ '(--remote)--local[set local machine as target]' \ '(--local)--remote[set remote machine as target]: : ' \ $disable \ diff --git a/src/bash_autocomplete.sh b/src/bash_autocomplete.sh index 4d1ae80e3..ecccd4d98 100644 --- a/src/bash_autocomplete.sh +++ b/src/bash_autocomplete.sh @@ -66,7 +66,7 @@ function _kw_autocomplete() kw_options['backup']='--restore --force --verbose --help' - kw_options['debug']='--remote --local --event --ftrace --dmesg --cmd + kw_options['debug']='--remote --local --event --ftrace --dmesg --cmd --verbose --history --disable --reset --list --follow --help' kw_options['mail']='--list --send --to --cc --simulate --setup --email --name --smtpencryption diff --git a/src/debug.sh b/src/debug.sh index 2fc22a2ee..cb5e596e2 100644 --- a/src/debug.sh +++ b/src/debug.sh @@ -63,6 +63,9 @@ function debug_main() follow="${options_values['FOLLOW']}" reset="${options_values['RESET']}" + [[ -n "${options_values['VERBOSE']}" ]] && flag='VERBOSE' + flag=${flag:-'SILENT'} + # Base path for saving log files base_log_path=$(prepare_log_database "$keep_history") @@ -85,7 +88,7 @@ function debug_main() fi if [[ -n "$reset" ]]; then - reset_debug "$target" + reset_debug "$target" "$flag" return "$?" fi @@ -126,6 +129,7 @@ function list_debug() local flag="$3" local char_repetition local specific_event + local cmd # List all options if [[ "$list_target" == 1 ]]; then @@ -138,8 +142,13 @@ function list_debug() char_repetition=$(str_count_char_repetition "$list_target" ':') if [[ "$char_repetition" -ge 1 ]]; then - specific_event=$(printf '%s' "$list_target" | cut -d ':' -f2) - list_target=$(printf '%s' "$list_target" | cut -d ':' -f1) + cmd="printf '%s' ${list_target} | cut -d ':' -f2" + show_verbose "$flag" "$cmd" + specific_event=$(cmd_manager "$flag" "$cmd") + + cmd="printf '%s' ${list_target} | cut -d ':' -f1" + show_verbose "$flag" "$cmd" + list_target=$(cmd_manager "$flag" "$cmd") fi case "$list_target" in @@ -238,8 +247,8 @@ function dmesg_debug() # Capture data if [[ -n "$base_log_path" ]]; then - touch "${base_log_path}/dmesg" - printf '\n' > "${base_log_path}/dmesg" + cmd_manager "$flag" "touch ${base_log_path}/dmesg" + cmd_manager "$flag" "printf '\n' > ${base_log_path}/dmesg" save_following_log="${base_log_path}/dmesg" fi @@ -305,6 +314,7 @@ function event_debug() local screen_end_cmd local save_following_log local ret + local cmd convert_event_syntax_to_sys_path_hash "$event" ret="$?" @@ -319,8 +329,12 @@ function event_debug() # Capture data if [[ -n "$base_log_path" ]]; then - touch "${base_log_path}/event" - printf '\n' > "${base_log_path}/event" + cmd="touch ${base_log_path}/event" + cmd_manager "$flag" "$cmd" + + cmd="printf '\n' > ${base_log_path}/event" + cmd_manager "$flag" "$cmd" + save_following_log="${base_log_path}/event" fi @@ -372,7 +386,8 @@ function event_debug() fi if [[ -n "$list" ]]; then - list_output=$(cmd_remotely "$command" "$flag" "$remote" "$port" "$user") + show_verbose "$flag" "$command" + list_output=$(cmd_remotely "$command" 'SILENT' "$remote" "$port" "$user") show_list "$list_output" "$event" ret="$?" return "$ret" @@ -407,10 +422,13 @@ function ftrace_list() local index=1 local ret local cmd_list="cat ${TRACING_BASE_PATH}/available_tracers" + local cmd case "$target" in 2) # LOCAL - raw_data=$(cmd_manager "$flag" "sudo -E ${cmd_list}") + cmd="sudo -E ${cmd_list}" + show_verbose "$flag" "$cmd" + raw_data=$(cmd_manager 'SILENT' "$cmd") ret="$?" ;; 3 | 1) # REMOTE && VM @@ -423,7 +441,8 @@ function ftrace_list() # TODO: We should check if the VM is up and running fi - raw_data=$(cmd_remotely "$cmd_list" "$flag" "$remote" "$port" "$user") + show_verbose "$flag" "$cmd_list" + raw_data=$(cmd_remotely "$cmd_list" 'SILENT' "$remote" "$port" "$user") ret="$?" ;; esac @@ -474,8 +493,8 @@ function ftrace_debug() # Capture data if [[ -n "$base_log_path" ]]; then - touch "$base_log_path/ftrace" - printf '\n' > "$base_log_path/ftrace" + cmd_manager "$flag" "touch ${base_log_path}/ftrace" + cmd_manager "$flag" "printf '\n' > ${base_log_path}/ftrace" save_following_log="$base_log_path/ftrace" fi @@ -894,7 +913,7 @@ function parser_debug_options() local long_options local transition_variables - long_options='remote:,event:,ftrace:,dmesg,cmd:,local,history,disable,list::,follow,reset,help' + long_options='remote:,event:,ftrace:,dmesg,cmd:,local,history,disable,list::,follow,reset,help,verbose' short_options='r:,e:,t:,g,f,c:,k,d,l::,h' options=$(kw_parse "$short_options" "$long_options" "$@") @@ -914,6 +933,7 @@ function parser_debug_options() options_values['DISABLE']='' options_values['LIST']='' options_values['FOLLOW']='' + options_values['VERBOSE']='' # Set default values if [[ -n ${deploy_config[default_deploy_target]} ]]; then @@ -992,6 +1012,10 @@ function parser_debug_options() options_values['FOLLOW']=1 shift ;; + --verbose) + options_values['VERBOSE']=1 + shift + ;; --help | -h) debug_help "$1" exit @@ -1029,6 +1053,7 @@ function debug_help() ' debug (--event | -e) [--disable] "" - Trace specific event' \ ' debug (--ftrace | -t) [--disable] "" - Use ftrace to identify code path' \ ' debug (--reset) - Reset debug values in the target machine' \ + ' debug (--verbose) - Show a detailed output' \ ' You can combine some of the above options' } diff --git a/src/device_info.sh b/src/device_info.sh index c02334873..4beb7781b 100644 --- a/src/device_info.sh +++ b/src/device_info.sh @@ -61,14 +61,6 @@ function device_main() show_data "$flag" } -function show_verbose() -{ - local flag="$1" - local cmd="$2" - - [[ "$flag" == 'VERBOSE' ]] && printf '%s\n' "$cmd" -} - # This function populates the ram element from the device_info_data global # variable with the total RAM memory from the target machine in kB. # diff --git a/src/lib/kwlib.sh b/src/lib/kwlib.sh index 3f258275c..2ccb6f5f1 100644 --- a/src/lib/kwlib.sh +++ b/src/lib/kwlib.sh @@ -118,6 +118,14 @@ function cmd_manager() eval "$command_for_eval" } +function show_verbose() +{ + local flag="$1" + local cmd="$2" + + [[ "$flag" == 'VERBOSE' ]] && say "$cmd" +} + # Checks if a directory is a kernel tree root # # @DIR A directory path diff --git a/tests/unit/debug_test.sh b/tests/unit/debug_test.sh index 4e79d6c25..67ad786b6 100755 --- a/tests/unit/debug_test.sh +++ b/tests/unit/debug_test.sh @@ -517,19 +517,30 @@ function test_ftrace_debug() mkdir 'kw_debug' + declare -a expected_sequence=( + 'touch kw_debug/ftrace' + "printf '\n' > kw_debug/ftrace" + "${expected_cmd_base} | tee kw_debug/ftrace" + ) + output=$(ftrace_debug 2 'TEST_MODE' 'function_graph: amdgpu_dm*' 'kw_debug') - expected_cmd="$expected_cmd_base | tee kw_debug/ftrace" - assert_equals_helper '[local] We expected a log file' "$LINENO" "$expected_cmd" "$output" - # Check if was created a ftrace file - assertTrue "($LINENO) Expected to find kw_debug/ftrace file" '[[ -f "$PWD/kw_debug/ftrace" ]]' + compare_array_values expected_sequence output "$LINENO" + declare -a expected_sequence=( + 'touch kw_debug/ftrace' + "printf '\n' > kw_debug/ftrace" + "${expected_cmd_base} && cat ${trace_pipe} | tee kw_debug/ftrace" + ) output=$(ftrace_debug 2 'TEST_MODE' 'function_graph: amdgpu_dm*' 'kw_debug' 1) - expected_cmd="$expected_cmd_base && cat $trace_pipe | tee kw_debug/ftrace" - assert_equals_helper '[local] We expected a log file' "$LINENO" "$expected_cmd" "$output" + compare_array_values expected_sequence output "$LINENO" + declare -a expected_sequence=( + 'touch kw_debug/ftrace' + "printf '\n' > kw_debug/ftrace" + "${default_ssh} \"${expected_cmd_base} && cat ${trace_pipe}\" | tee kw_debug/ftrace" + ) output=$(ftrace_debug 3 'TEST_MODE' 'function_graph: amdgpu_dm*' 'kw_debug' 1) - expected_cmd="$default_ssh \"$expected_cmd_base && cat $trace_pipe\" | tee kw_debug/ftrace" - assert_equals_helper '[remote] We expected a log file' "$LINENO" "$expected_cmd" "$output" + compare_array_values expected_sequence output "$LINENO" # Test cmd option; unfortunately, it is a horrible command sequence. expected_cmd="$expected_cmd_base" @@ -541,12 +552,15 @@ function test_ftrace_debug() screen_command="screen -S $screen_id -X quit > /dev/null" expected_cmd+=" && $screen_command | tee kw_debug/ftrace" USER='MOCK' - declare -a expected_cmd_seq=( + + declare -a expected_sequence=( + 'touch kw_debug/ftrace' + "printf '\n' > kw_debug/ftrace" "$expected_cmd" "sudo cp /root/kw_2021_10_22-07_34_07 kw_debug/ftrace && sudo chown $USER:$USER kw_debug/ftrace" ) output=$(ftrace_debug 2 'TEST_MODE' 'function_graph:amdgpu_dm*' 'kw_debug' '' './root/something') - compare_command_sequence '' "$LINENO" 'expected_cmd_seq' "$output" + compare_command_sequence '' "$LINENO" 'expected_sequence' "$output" cd "$original_dir" || { fail "($LINENO) It was not possible to move back to original directory" @@ -646,24 +660,34 @@ function test_dmesg_debug() mkdir 'kw_debug' + declare -a expected_sequence=( + 'touch kw_debug/dmesg' + "printf '\n' > kw_debug/dmesg" + "${std_dmesg} --nopager | tee kw_debug/dmesg" + ) output=$(dmesg_debug 2 'TEST_MODE' 'kw_debug' '' '') - expected_cmd="$std_dmesg --nopager | tee kw_debug/dmesg" - assert_equals_helper '[local] We expected a log file' "$LINENO" "$expected_cmd" "$output" + compare_array_values expected_sequence output "$LINENO" + declare -a expected_sequence=( + 'touch kw_debug/dmesg' + "printf '\n' > kw_debug/dmesg" + "${std_dmesg} --follow | tee kw_debug/dmesg" + ) output=$(dmesg_debug 2 'TEST_MODE' 'kw_debug' 1 '') - expected_cmd="$std_dmesg --follow | tee kw_debug/dmesg" - assert_equals_helper '[local] Log file with follow' "$LINENO" "$expected_cmd" "$output" - - # Check if was created a dmesg file - assertTrue "($LINENO) Expected to find kw_debug/dmesg file" '[[ -f "$PWD/kw_debug/dmesg" ]]' + compare_array_values expected_sequence output "$LINENO" remote_parameters['REMOTE_IP']='127.0.0.1' remote_parameters['REMOTE_PORT']='3333' remote_parameters['REMOTE_USER']='juca' + declare -a expected_sequence=( + 'touch kw_debug/dmesg' + "printf '\n' > kw_debug/dmesg" + "${std_ssh} sudo \"${std_dmesg} --follow\" | tee kw_debug/dmesg" + ) + output=$(dmesg_debug 3 'TEST_MODE' 'kw_debug' 1 '') - expected_cmd="$std_ssh sudo \"$std_dmesg --follow\" | tee kw_debug/dmesg" - assert_equals_helper '[remote] Log file created' "$LINENO" "$expected_cmd" "$output" + compare_array_values expected_sequence output "$LINENO" # Check cmd option # Local @@ -673,15 +697,24 @@ function test_dmesg_debug() assert_equals_helper '[local] dmesg with CMD' "$LINENO" "$expected_cmd" "$output" # --cmd "SOMETHING" --history + declare -a expected_sequence=( + 'touch kw_debug/dmesg' + "printf '\n' > kw_debug/dmesg" + "dmesg --clear && ${igt_cmd_sample} && ${std_dmesg} --nopager | tee kw_debug/dmesg" + ) output=$(dmesg_debug 2 'TEST_MODE' 'kw_debug' '' "$igt_cmd_sample") - expected_cmd="dmesg --clear && $igt_cmd_sample && $std_dmesg --nopager | tee kw_debug/dmesg" - assert_equals_helper '[local] dmesg with CMD' "$LINENO" "$expected_cmd" "$output" + compare_array_values expected_sequence output "$LINENO" # --cmd "SOMETHING" --follow --history + cmd_intermediary="screen -dmS kw_2021_10_22-07_34_07 ${igt_cmd_sample}" + declare -a expected_sequence=( + 'touch kw_debug/dmesg' + "printf '\n' > kw_debug/dmesg" + "dmesg --clear && ${cmd_intermediary} && ${std_dmesg} --follow | tee kw_debug/dmesg" + ) + output=$(dmesg_debug 2 'TEST_MODE' 'kw_debug' 1 "$igt_cmd_sample") - cmd_intermediary="screen -dmS kw_2021_10_22-07_34_07 $igt_cmd_sample" - expected_cmd="dmesg --clear && $cmd_intermediary && $std_dmesg --follow | tee kw_debug/dmesg" - assert_equals_helper '[local] dmesg with CMD' "$LINENO" "$expected_cmd" "$output" + compare_array_values expected_sequence output "$LINENO" # Remote # --remote --cmd "SOMETHING" @@ -691,14 +724,23 @@ function test_dmesg_debug() # --remote --cmd "SOMETHING" --history output=$(dmesg_debug 3 'TEST_MODE' 'kw_debug' '' "$igt_cmd_sample") - expected_cmd="$std_ssh sudo \"dmesg --clear && $igt_cmd_sample && $std_dmesg --nopager\" | tee kw_debug/dmesg" - assert_equals_helper '[remote]' "$LINENO" "$expected_cmd" "$output" + expected_cmd= + declare -a expected_sequence=( + 'touch kw_debug/dmesg' + "printf '\n' > kw_debug/dmesg" + "${std_ssh} sudo \"dmesg --clear && ${igt_cmd_sample} && ${std_dmesg} --nopager\" | tee kw_debug/dmesg" + ) + compare_array_values expected_sequence output "$LINENO" # --cmd "SOMETHING" --follow --history + cmd_intermediary="screen -dmS kw_2021_10_22-07_34_07 ${igt_cmd_sample}" + declare -a expected_sequence=( + 'touch kw_debug/dmesg' + "printf '\n' > kw_debug/dmesg" + "${std_ssh} sudo \"dmesg --clear && ${cmd_intermediary} && ${std_dmesg} --follow\" | tee kw_debug/dmesg" + ) output=$(dmesg_debug 3 'TEST_MODE' 'kw_debug' 1 "$igt_cmd_sample") - cmd_intermediary="screen -dmS kw_2021_10_22-07_34_07 $igt_cmd_sample" - expected_cmd="$std_ssh sudo \"dmesg --clear && $cmd_intermediary && $std_dmesg --follow\" | tee kw_debug/dmesg" - assert_equals_helper '[remote]' "$LINENO" "$expected_cmd" "$output" + compare_array_values expected_sequence output "$LINENO" cd "$original_dir" || { fail "($LINENO) It was not possible to move back to original directory" @@ -724,13 +766,9 @@ function test_event_debug() assert_equals_helper 'Invalid syntax' "$LINENO" "$ret" 22 # List - output=$(event_debug 3 'TEST_MODE' 'amdgpu_dm' '' '' '' 1) - ret="$?" - assert_equals_helper 'List' "$LINENO" "$ret" 0 - output=$(event_debug 2 'TEST_MODE' 'amdgpu_dm' '' '' '' 1) ret="$?" - assert_equals_helper 'List' "$LINENO" "$ret" 0 + assert_equals_helper 'List' "$LINENO" 0 "$ret" # Simple case output=$(event_debug 3 'TEST_MODE' 'amdgpu_dm') @@ -759,6 +797,8 @@ function test_event_debug() expected_cmd+=" && printf 'nop' > $FTRACE_CURRENT_PATH" expected_cmd+=" && screen -S kw_2021_10_22-07_34_07 -X quit" declare -a expected_cmd_seq=( + "touch kw_debug/event" + "printf '\n' > kw_debug/event" "$default_ssh sudo \" $expected_cmd\" | tee kw_debug/event" "rsync --info=progress2 -e 'ssh -p 3333' juca@127.0.0.1:${HOME}/kw_2021_10_22-07_34_07 kw_debug/event -LrlptD --rsync-path='sudo rsync'" ) diff --git a/tests/unit/lib/kwlib_test.sh b/tests/unit/lib/kwlib_test.sh index b1eac70aa..49811e8f5 100755 --- a/tests/unit/lib/kwlib_test.sh +++ b/tests/unit/lib/kwlib_test.sh @@ -948,4 +948,21 @@ function test_get_git_repository_branches() teardownGitRepository } +function test_show_verbose_no_verbose() +{ + local output + + output=$(show_verbose 'TEST_MODE' 'it shoud not display anything') + assert_equals_helper 'Expected an empty string' "$LINENO" '' "$output" +} + +function test_show_verbose() +{ + local output + local cmd='some command' + + output=$(show_verbose 'VERBOSE' "$cmd") + assert_equals_helper 'Expected value of command' "$LINENO" "$cmd" "$output" +} + invoke_shunit From fb19daf5e7d9df62ef19b2ffd565921ded05075f Mon Sep 17 00:00:00 2001 From: uwla Date: Fri, 24 Nov 2023 15:55:58 -0300 Subject: [PATCH 004/128] src: config: distinguish variable sources (global/local) in output The `config --show` command now prints a header specifying the source of variables along with them. This requires the test to adapt to the new output: ignore the keywords GLOBAL/LOCAL in the output and expect the default scope to be empty. A note about the new default value for scope: If scope defaults to local, the configuration output would only show local variables. If defaults to global, it would only show global variables. But if defaults to empty, we can know the user has not specified an scope and therefore we should show both global and local configs. That's why its default value is now an empty string. Closes: #894 Reviewed-by: David Tadokoro Signed-off-by: uwla --- src/config.sh | 53 +++++++++++++++++++++++++++++-------- src/lib/kw_config_loader.sh | 33 +++++++++++++++++++---- tests/unit/config_test.sh | 15 ++++++++--- 3 files changed, 81 insertions(+), 20 deletions(-) diff --git a/src/config.sh b/src/config.sh index 6f5e9cc3f..ecdaadb81 100644 --- a/src/config.sh +++ b/src/config.sh @@ -222,7 +222,7 @@ function parse_config_options() fi # Default values - options_values['SCOPE']='local' + options_values['SCOPE']='' options_values['PARAMETERS']='' options_values['IS_SHOW_CONFIGURATIONS']='' options_values['VERBOSE']='' @@ -294,7 +294,6 @@ function show_configurations() read -ra configs <<< "${!config_file_list[@]}" fi - # For each config file for config in "${configs[@]}"; do # Check if it is a valid config if ! is_config_file_valid "$config"; then @@ -305,23 +304,55 @@ function show_configurations() # Load corresponding config file eval "load_${config}_config" - # This part is heavily depedent of the names defined in kw_config_loader if [[ "$config" == 'kworkflow' ]]; then - declare -n config_array='configurations' + declare -n config_array_local="configurations_local" + declare -n config_array_global="configurations_global" else - declare -n config_array="${config}_config" + declare -n config_array_local="${config}_config_local" + declare -n config_array_global="${config}_config_global" fi - # For each possible option in a config file options_buffer=$(printf '%s' "${config_file_list[$config]}" | sed --null-data 's/\n/ /g') read -ra options <<< "${options_buffer}" for option in "${options[@]}"; do - value="${config_array[$option]}" - if [[ -z "$value" ]]; then - warning "${config}.${option}=N/A" - else - printf '%s\n' "${config}.${option}=${value}" + + # if user specified global or local scope, we won't append scope prefixes + if [[ -n "${options_values['SCOPE']}" ]]; then + if [[ "${options_values['SCOPE']}" == 'local' ]]; then + value="${config_array_local[$option]}" + elif [[ "${options_values['SCOPE']}" == 'global' ]]; then + value="${config_array_global[$option]}" + fi + + if [[ -n "$value" ]]; then + # value is defined globally or locally + printf '%s.%s=%s\n' "$config" "$option" "$value" + else + # undefined value + warning "${config}.${option}=N/A" + fi + continue + fi + + # Otherwise, we append an indicator prefix before the config. + # That way, the user knows if the config is defined locally or globally. + + # config comes from local source + value="${config_array_local[$option]}" + if [[ -n "$value" ]]; then + printf '[LOCAL ] %s.%s=%s\n' "$config" "$option" "$value" + continue fi + + # config comes from global source + value="${config_array_global[$option]}" + if [[ -n "$value" ]]; then + printf '[GLOBAL] %s.%s=%s\n' "$config" "$option" "$value" + continue + fi + + # config is undefined + warning "[ ] ${config}.${option}=N/A" done done diff --git a/src/lib/kw_config_loader.sh b/src/lib/kw_config_loader.sh index 03c0f5456..3131afcef 100644 --- a/src/lib/kw_config_loader.sh +++ b/src/lib/kw_config_loader.sh @@ -20,24 +20,38 @@ TARGET="$VM_TARGET" # Default configuration declare -gA configurations +declare -gA configurations_global +declare -gA configurations_local # Build configuration declare -gA build_config +declare -gA build_config_global +declare -gA build_config_local # Deploy configuration declare -gA deploy_config +declare -gA deploy_config_global +declare -gA deploy_config_local # VM configuration declare -gA vm_config +declare -gA vm_config_global +declare -gA vm_config_local # Mail configuration declare -gA mail_config +declare -gA mail_config_global +declare -gA mail_config_local # Notification configuration declare -gA notification_config +declare -gA notification_config_global +declare -gA notification_config_local # Notification configuration declare -gA lore_config +declare -gA lore_config_global +declare -gA lore_config_local # Default target option from kworkflow.config declare -gA deploy_target_opt=(['local']=2 ['remote']=3) @@ -338,6 +352,7 @@ function parse_configuration() { local config_path="$1" local config_array="${2:-configurations}" + local config_array_scope="$3" local value if [ ! -f "$config_path" ]; then @@ -354,6 +369,9 @@ function parse_configuration() value="$(sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' <<< "$value")" eval "${config_array}"'["$varname"]="$value"' + if [[ -n "${config_array_scope}" ]]; then + eval "${config_array_scope}"'["$varname"]="$value"' + fi fi done < "$config_path" } @@ -366,6 +384,8 @@ function load_configuration() local target_config="$1" local target_config_file local target_array='configurations' + local target_array_global='' + local target_array_local='' local -a config_dirs local config_dirs_size local IFS=: @@ -393,8 +413,11 @@ function load_configuration() ;; esac + target_array_global="${target_array}_global" + target_array_local="${target_array}_local" + target_config_file="${target_config}.config" - parse_configuration "${KW_ETC_DIR}/${target_config_file}" "$target_array" + parse_configuration "${KW_ETC_DIR}/${target_config_file}" "$target_array" "$target_array_global" # XDG_CONFIG_DIRS is a colon-separated list of directories for config # files to be searched, in order of preference. Since this function @@ -405,10 +428,10 @@ function load_configuration() # /etc/xdg. config_dirs_size="${#config_dirs[@]}" for ((i = config_dirs_size - 1; i >= 0; i--)); do - parse_configuration "${config_dirs["$i"]}/${KWORKFLOW}/${target_config_file}" "$target_array" + parse_configuration "${config_dirs["$i"]}/${KWORKFLOW}/${target_config_file}" "$target_array" "$target_array_global" done - parse_configuration "${XDG_CONFIG_HOME:-"${HOME}/.config"}/${KWORKFLOW}/${target_config_file}" "$target_array" + parse_configuration "${XDG_CONFIG_HOME:-"${HOME}/.config"}/${KWORKFLOW}/${target_config_file}" "$target_array" "$target_array_global" # Old users may have kworkflow.config at $PWD if [[ -f "$PWD/$CONFIG_FILENAME" ]]; then @@ -418,12 +441,12 @@ function load_configuration() mkdir -p "$PWD/$KW_DIR/" mv "$PWD/$CONFIG_FILENAME" "$PWD/$KW_DIR/$CONFIG_FILENAME" else - parse_configuration "${PWD}/${CONFIG_FILENAME}" "$target_array" + parse_configuration "${PWD}/${CONFIG_FILENAME}" "$target_array" "$target_array_local" fi fi if [[ -f "${PWD}/${KW_DIR}/${target_config_file}" ]]; then - parse_configuration "${PWD}/${KW_DIR}/${target_config_file}" "$target_array" + parse_configuration "${PWD}/${KW_DIR}/${target_config_file}" "$target_array" "$target_array_local" fi } diff --git a/tests/unit/config_test.sh b/tests/unit/config_test.sh index 32e015382..ac6b62387 100755 --- a/tests/unit/config_test.sh +++ b/tests/unit/config_test.sh @@ -36,6 +36,13 @@ function tearDown() rm -rf "${KW_CONFIG_BASE_PATH}" } +# Show configurations WITHOUT the prefixes [GLOBAL]/[LOCAL]. +# The tests do not expect the output to have source indicators prefixes. +function show_raw_configurations() +{ + show_configurations "$@" | sed 's;\[[A-Z ]\+\] ;;' +} + function test_is_config_file_valid() { is_config_file_valid 'invalid' @@ -161,8 +168,8 @@ function test_parse_config_options() reset_options_values parse_config_options - assert_equals_helper 'Expected local as a default scope' \ - "($LINENO)" 'local' "${options_values['SCOPE']}" + assert_equals_helper 'Expected empty string as a default scope' \ + "($LINENO)" '' "${options_values['SCOPE']}" # test default options reset_options_values @@ -200,7 +207,7 @@ function test_show_configurations_without_parameters() return } - output=$(show_configurations) + output=$(show_raw_configurations) assert_line_match "$LINENO" 'vm.virtualizer=libvirt' "$output" assert_line_match "$LINENO" 'vm.mount_point=/home/lala' "$output" @@ -258,7 +265,7 @@ function test_show_configurations_with_parameters() return } - output=$(show_configurations 'vm notification') + output=$(show_raw_configurations 'vm notification') assert_line_match "$LINENO" 'vm.virtualizer=libvirt' "$output" assert_line_match "$LINENO" 'vm.mount_point=/home/lala' "$output" From 9c37b48dad491f4e73372f6b119b5fd73f921486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Gustavo=20Nakagomi=20Lopez?= Date: Sat, 2 Dec 2023 09:29:43 -0300 Subject: [PATCH 005/128] src: checkpatch_wrapper: rename to codestyle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The name of checkpatch_wrapper.sh didn't fit with the project standard, so rename checkpatch_wrapper.sh to codestyle.sh, and rename checkpatch_wrapper_test.sh to codestyle_test.sh. Reviewed-by: Rodrigo Siqueira Signed-off-by: André Gustavo Nakagomi Lopez Co-authored-by: João Paulo Pereira --- kw | 2 +- src/{checkpatch_wrapper.sh => codestyle.sh} | 0 tests/unit/{checkpatch_wrapper_test.sh => codestyle_test.sh} | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/{checkpatch_wrapper.sh => codestyle.sh} (100%) rename tests/unit/{checkpatch_wrapper_test.sh => codestyle_test.sh} (98%) diff --git a/kw b/kw index 8c176eb77..363eb4825 100755 --- a/kw +++ b/kw @@ -165,7 +165,7 @@ function kw() ;; codestyle | c) ( - include "${KW_LIB_DIR}/checkpatch_wrapper.sh" + include "${KW_LIB_DIR}/codestyle.sh" execute_checkpatch "$@" ) diff --git a/src/checkpatch_wrapper.sh b/src/codestyle.sh similarity index 100% rename from src/checkpatch_wrapper.sh rename to src/codestyle.sh diff --git a/tests/unit/checkpatch_wrapper_test.sh b/tests/unit/codestyle_test.sh similarity index 98% rename from tests/unit/checkpatch_wrapper_test.sh rename to tests/unit/codestyle_test.sh index 2ee93843b..a8835c06f 100755 --- a/tests/unit/checkpatch_wrapper_test.sh +++ b/tests/unit/codestyle_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -include './src/checkpatch_wrapper.sh' +include './src/codestyle.sh' include './tests/unit/utils.sh' # Those variables hold the last line execute_checkpatch prints in a code that is From d3b4f11b47a1d6d3837f987b13c17b713bc86cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Gustavo=20Nakagomi=20Lopez?= Date: Sat, 2 Dec 2023 09:36:19 -0300 Subject: [PATCH 006/128] src: checkpatch_wrapper: Modernize codestyle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The checkpatch_wrapper script was out of date in terms of code style, so modernize checkpatch_wrapper.sh to follow the current code standard. Changes include: - Use parse function to parse arguments, so now arguments work in any order - Update man page to include verbose option - Update autocomplete to include help and verbose options Issue #935 Reviewed-by: Rodrigo Siqueira Signed-off-by: André Gustavo Nakagomi Lopez Co-authored-by: João Paulo Pereira da Silva --- documentation/man/features/kw-codestyle.rst | 7 +- kw | 2 +- src/_kw | 3 + src/bash_autocomplete.sh | 3 + src/codestyle.sh | 112 +++++++++++++++----- tests/unit/codestyle_test.sh | 26 ++--- 6 files changed, 109 insertions(+), 44 deletions(-) diff --git a/documentation/man/features/kw-codestyle.rst b/documentation/man/features/kw-codestyle.rst index 29c9587e1..e3c1abf90 100644 --- a/documentation/man/features/kw-codestyle.rst +++ b/documentation/man/features/kw-codestyle.rst @@ -6,7 +6,9 @@ kw-codestyle SYNOPSIS ======== -*kw* (*c* | *codestyle*) [ | | ] +| *kw* (*c* | *codestyle*) +| *kw* (*c* | *codestyle*) [ | | ] +| *kw* (*c* | *codestyle*) [\--verbose] [ | | ] DESCRIPTION =========== @@ -22,6 +24,9 @@ OPTIONS Define which files to run checkpatch on. Defaults to current working directory if it is a kernel tree. +\--verbose: + Display commands executed under the hood. + EXAMPLES ======== For these examples, we suppose the fields in your **kworkflow.config** file are diff --git a/kw b/kw index 363eb4825..2b3bbd7c0 100755 --- a/kw +++ b/kw @@ -167,7 +167,7 @@ function kw() ( include "${KW_LIB_DIR}/codestyle.sh" - execute_checkpatch "$@" + codestyle_main "$@" ) ;; self-update | u) diff --git a/src/_kw b/src/_kw index 082f7ea0c..4355fcb3c 100644 --- a/src/_kw +++ b/src/_kw @@ -117,6 +117,9 @@ _kw_c() { _kw_codestyle } _kw_codestyle() { _arguments : \ + '(--verbose)--verbose[enable verbose mode]' \ + '(--help)--help[check man page for command]' \ + '(-h)-h[print command arguments]' \ '(*): :_files' } diff --git a/src/bash_autocomplete.sh b/src/bash_autocomplete.sh index ecccd4d98..b85dbd4b7 100644 --- a/src/bash_autocomplete.sh +++ b/src/bash_autocomplete.sh @@ -85,6 +85,9 @@ function _kw_autocomplete() kw_options['clear-cache']='--verbose' + kw_options['codestyle']='--verbose --help' + kw_options['c']="${kw_options['codestyle']}" + mapfile -t COMPREPLY < <(compgen -W "${kw_options[${previous_command}]} " -- "${current_command}") # TODO: diff --git a/src/codestyle.sh b/src/codestyle.sh index ad799057c..fd0a85a30 100644 --- a/src/codestyle.sh +++ b/src/codestyle.sh @@ -5,41 +5,47 @@ include "${KW_LIB_DIR}/lib/kw_config_loader.sh" include "${KW_LIB_DIR}/lib/kwlib.sh" +declare -gA options_values + # Runs checkpatch in the given path, which might be a file or directory. # # @FILE_OR_DIR_CHECK Target path for running checkpatch script -function execute_checkpatch() +function codestyle_main() { - local FILE_OR_DIR_CHECK="$1" - local flag="$2" - - if [[ "$FILE_OR_DIR_CHECK" =~ ^-h|^--help ]]; then - codestyle_help "$1" - return 0 - fi - # TODO: Note that codespell file is not specified yet because of the poluted - # output. It could be nice if we can add another option just for this sort - # of check. - - local options="${configurations[checkpatch_opts]}" + local path + local flag + local checkpatch_options="${configurations[checkpatch_opts]}" local -r original_working_dir="$PWD" local kernel_root + local checkpatch local cmd_script - FILE_OR_DIR_CHECK=${FILE_OR_DIR_CHECK:-'.'} + parse_codestyle_options "$@" + if [[ "$?" != 0 ]]; then + complain "Invalid option: ${options_values['ERROR']}" + return 22 # EINVAL + fi + + flag=${options_values['TEST_MODE']} + [[ -n "${options_values['VERBOSE']}" ]] && flag='VERBOSE' + flag=${flag:-'SILENT'} + # TODO: Note that codespell file is not specified yet because of the poluted + # output. It could be nice if we can add another option just for this sort + # of check. - # Check if is a valid path - if [[ ! -d "$FILE_OR_DIR_CHECK" && ! -f "$FILE_OR_DIR_CHECK" ]]; then - complain 'Invalid path' + path="${options_values['PATH']}" + path=${path:-'.'} + if [[ ! -d "$path" && ! -f "$path" ]]; then + complain "Invalid path: ${path}" return 2 # ENOENT fi # Get realpath for using inside checkpatch - FILE_OR_DIR_CHECK="$(realpath "$FILE_OR_DIR_CHECK")" + path="$(realpath "$path")" # Try to find kernel root at given path - kernel_root="$(find_kernel_root "$FILE_OR_DIR_CHECK")" + kernel_root="$(find_kernel_root "$path")" if [[ -z "$kernel_root" ]]; then # Fallback: try to find kernel root at working path kernel_root="$(find_kernel_root "$original_working_dir")" @@ -52,19 +58,20 @@ function execute_checkpatch() fi # Build a list of file to apply check patch - FLIST=$(find "$FILE_OR_DIR_CHECK" -type f ! -name '*\.mod\.c' | grep "\.[ch]$") + FLIST=$(find "$path" -type f ! -name '*\.mod\.c' | grep "\.[ch]$") - say "Running checkpatch.pl on: $FILE_OR_DIR_CHECK" + say "Running checkpatch.pl on: ${path}" say "$SEPARATOR" # Define different rules for patch and files - if is_a_patch "$FILE_OR_DIR_CHECK"; then - FLIST="$FILE_OR_DIR_CHECK" + if is_a_patch "$path"; then + FLIST="$path" else - options="--terse $options --file" + checkpatch_options="--terse ${checkpatch_options} --file" fi - cmd_script="perl scripts/checkpatch.pl $options" + checkpatch=$(join_path "$kernel_root" 'scripts/checkpatch.pl') + cmd_script="perl ${checkpatch} ${checkpatch_options}" for current_file in $FLIST; do file="$current_file" @@ -74,12 +81,58 @@ function execute_checkpatch() continue fi - cd "$kernel_root" || exit_msg 'It was not possible to move to kernel root dir' - cmd_manager "$flag" "$cmd_script $file" [[ "$?" != 0 ]] && say "$SEPARATOR" + done +} + +# This function gets raw data and based on that fill out the options values to +# be used in another function. +# +# Return: +# In case of successful return 0, otherwise, return 22. +function parse_codestyle_options() +{ + local long_options='verbose,help' + local short_options='h' + local options + + options="$(kw_parse "$short_options" "$long_options" "$@")" + + if [[ "$?" != 0 ]]; then + options_values['ERROR']="$(kw_parse_get_errors 'kw diff' "$short_options" \ + "$long_options" "$@")" + return 22 # EINVAL + fi - cd "$original_working_dir" || exit_msg 'It was not possible to move back from kernel dir' + # Default values + options_values['VERBOSE']='' + options_values['TEST_MODE']='' + + eval "set -- $options" + + while [[ "$#" -gt 0 ]]; do + case "$1" in + --verbose) + options_values['VERBOSE']=1 + shift + ;; + TEST_MODE) + options_values['TEST_MODE']='TEST_MODE' + shift + ;; + --help | -h) + codestyle_help "$1" + exit + ;; + --) + shift + ;; + *) + options_values['PATH']="$1" + shift + ;; + esac done } @@ -91,7 +144,8 @@ function codestyle_help() return fi printf '%s\n' 'kw codestyle:' \ - ' codestyle [||] - Use checkpatch on target' + ' codestyle [||] - Use checkpatch on target' \ + ' codestyle (--verbose) [||] - Show detailed output' } load_kworkflow_config diff --git a/tests/unit/codestyle_test.sh b/tests/unit/codestyle_test.sh index a8835c06f..2b9c377e2 100755 --- a/tests/unit/codestyle_test.sh +++ b/tests/unit/codestyle_test.sh @@ -3,7 +3,7 @@ include './src/codestyle.sh' include './tests/unit/utils.sh' -# Those variables hold the last line execute_checkpatch prints in a code that is +# Those variables hold the last line codestyle_main prints in a code that is # correct, has 1 warning, has 1 erros and has 1 check, respectively. The sample # codes used in this test are in tests/unit/samples/ @@ -24,7 +24,7 @@ function test_invalid_path() build_fake_path=$(create_invalid_file_path) - output=$(execute_checkpatch "$build_fake_path") + output=$(codestyle_main "$build_fake_path") ret="$?" assertEquals 'We forced an invalid path and we expect an error' '2' "$ret" } @@ -38,7 +38,7 @@ function test_no_kernel_directory() # basic setup but we rebuild it at the end of the test oneTimeTearDown - output=$(execute_checkpatch "$sample_one") + output=$(codestyle_main "$sample_one") ret="$?" assertFalse 'We forced an invalid path and we expect an error' '[[ $ret != 22 ]]' @@ -51,7 +51,7 @@ function test_multiple_files_output() local array=() local output - output=$(execute_checkpatch "$SHUNIT_TMPDIR/samples" 2>&1) + output=$(codestyle_main "$SHUNIT_TMPDIR/samples" 2>&1) # Reference: https://www.tutorialkart.com/bash-shell-scripting/bash-split-string/ s="$output$delimiter" @@ -66,11 +66,11 @@ function test_multiple_files_output() assertFalse 'We could not find more then two SEPARATOR sequence' '[[ $size -lt "3" ]]' } -function test_run_checkpatch_in_a_path() +function test_run_codestyle_in_a_path() { - local cmd='perl scripts/checkpatch.pl --no-tree --color=always --strict' - local patch_path="$TMP_TEST_DIR/samples/test.patch" - local patch_path="$SHUNIT_TMPDIR/samples/test.patch" + local cmd="perl ${SHUNIT_TMPDIR}/scripts/checkpatch.pl --no-tree --color=always --strict" + local patch_path="${TMP_TEST_DIR}/samples/test.patch" + local patch_path="${SHUNIT_TMPDIR}/samples/test.patch" local output local real_path local base_msg @@ -84,14 +84,14 @@ function test_run_checkpatch_in_a_path() "$cmd $real_path" ) - output=$(execute_checkpatch "$patch_path" 'TEST_MODE' 2>&1) + output=$(codestyle_main "$patch_path" 'TEST_MODE' 2>&1) compare_command_sequence '' "$LINENO" 'expected_cmd' "$output" } -function test_run_checkpatch_in_a_file() +function test_run_codestyle_in_a_file() { - local cmd='perl scripts/checkpatch.pl --terse --no-tree --color=always --strict --file' - local patch_path="$SHUNIT_TMPDIR/samples/codestyle_correct.c" + local cmd="perl ${SHUNIT_TMPDIR}/scripts/checkpatch.pl --terse --no-tree --color=always --strict --file" + local patch_path="${SHUNIT_TMPDIR}/samples/codestyle_correct.c" local output local real_path local base_msg @@ -105,7 +105,7 @@ function test_run_checkpatch_in_a_file() "$cmd $real_path" ) - output=$(execute_checkpatch "$patch_path" 'TEST_MODE' 2>&1) + output=$(codestyle_main "$patch_path" 'TEST_MODE' 2>&1) compare_command_sequence '' "$LINENO" 'expected_cmd' "$output" } From 4ab86a74c6f7cf8a67f7a72ab722aee4d7df2e15 Mon Sep 17 00:00:00 2001 From: uwla Date: Fri, 1 Dec 2023 15:07:41 -0300 Subject: [PATCH 007/128] src: config.sh: remove duplicated config entries in config list Remove duplicated config entries in deploy config list. Reviewed-by: Rodrigo Siqueira Signed-off-by: uwla --- src/config.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/config.sh b/src/config.sh index ecdaadb81..6cae6c5da 100644 --- a/src/config.sh +++ b/src/config.sh @@ -12,8 +12,7 @@ declare -gA config_file_list=( ['mail']='send_opts blocked_emails default_to_recipients default_cc_recipients' ['deploy']='kw_files_remote_path deploy_temporary_files_path deploy_default_compression dtb_copy_pattern default_deploy_target - reboot_after_deploy strip_modules_debug_option - default_deploy_target reboot_after_deploy' + reboot_after_deploy strip_modules_debug_option' ['notification']='alert sound_alert_command visual_alert_command' ['kworkflow']='ssh_user ssh_ip ssh_port ssh_configfile hostname disable_statistics_data_track gui_on gui_off send_opts From 96e243f3457471512ade4b55f3a8934d2bb4b3e0 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Sat, 25 Nov 2023 10:46:32 -0700 Subject: [PATCH 008/128] documentation: man: features: Add whatis entry While packaging kw for Debian, we got multiple warnings like this: kworkflow: bad-whatis-entry [usr/share/man/man1/kw-build.1.gz] This commit introduce the whatis for each kw feature. Reviewed-by: David Tadokoro Signed-off-by: Rodrigo Siqueira --- documentation/man/features/kw-backup.rst | 8 ++++---- documentation/man/features/kw-build.rst | 8 ++++---- documentation/man/features/kw-codestyle.rst | 6 +++--- documentation/man/features/kw-config.rst | 6 +++--- documentation/man/features/kw-debug.rst | 6 +++--- documentation/man/features/kw-deploy.rst | 6 +++--- documentation/man/features/kw-device.rst | 6 +++--- documentation/man/features/kw-diff.rst | 8 ++++---- documentation/man/features/kw-drm.rst | 6 +++--- documentation/man/features/kw-env.rst | 6 +++--- documentation/man/features/kw-explore.rst | 6 +++--- documentation/man/features/kw-init.rst | 6 +++--- .../man/features/kw-kernel-config-manager.rst | 6 +++--- documentation/man/features/kw-mail.rst | 10 +++++----- documentation/man/features/kw-maintainers.rst | 6 +++--- documentation/man/features/kw-patch-hub.rst | 6 +++--- documentation/man/features/kw-pomodoro.rst | 6 +++--- documentation/man/features/kw-remote.rst | 6 +++--- documentation/man/features/kw-report.rst | 7 ++++--- documentation/man/features/kw-self-update.rst | 6 +++--- documentation/man/features/kw-ssh.rst | 6 +++--- documentation/man/features/kw-vars.rst | 6 +++--- documentation/man/features/kw-vm.rst | 6 +++--- documentation/man/kw.rst | 10 +++------- 24 files changed, 78 insertions(+), 81 deletions(-) diff --git a/documentation/man/features/kw-backup.rst b/documentation/man/features/kw-backup.rst index 35f6a756e..69f1c484d 100644 --- a/documentation/man/features/kw-backup.rst +++ b/documentation/man/features/kw-backup.rst @@ -1,6 +1,6 @@ -========= -kw-backup -========= +============================================= +kw-backup - Save and restore kw internal data +============================================= .. _backup-doc: @@ -45,4 +45,4 @@ save it into /documents/backup, then run:: To restore a backup, use the `\--restore` option. Suppose you want to restore the backup stored in /documents/backup/kw-backup-from-yesterday.tar.gz, run:: - kw backup --restore /documents/backup/kw-backup-from-yesterday.tar.gz \ No newline at end of file + kw backup --restore /documents/backup/kw-backup-from-yesterday.tar.gz diff --git a/documentation/man/features/kw-build.rst b/documentation/man/features/kw-build.rst index 0a8af5129..8fd82b455 100644 --- a/documentation/man/features/kw-build.rst +++ b/documentation/man/features/kw-build.rst @@ -1,6 +1,6 @@ -======== -kw-build -======== +======================= +kw-build - Build kernel +======================= .. _build-doc: @@ -157,4 +157,4 @@ If you want to reset the kernel tree to its default, `all config and script outp If you want to use cflags:: - kw b --cflags "-O3 -pipe -march=native" \ No newline at end of file + kw b --cflags "-O3 -pipe -march=native" diff --git a/documentation/man/features/kw-codestyle.rst b/documentation/man/features/kw-codestyle.rst index e3c1abf90..02d3cfab5 100644 --- a/documentation/man/features/kw-codestyle.rst +++ b/documentation/man/features/kw-codestyle.rst @@ -1,6 +1,6 @@ -============ -kw-codestyle -============ +================================= +kw-codestyle - Checkpatch wrapper +================================= .. _codestyle-doc: diff --git a/documentation/man/features/kw-config.rst b/documentation/man/features/kw-config.rst index 0e9842222..48a4d1878 100644 --- a/documentation/man/features/kw-config.rst +++ b/documentation/man/features/kw-config.rst @@ -1,6 +1,6 @@ -========= -kw-config -========= +========================================= +kw-config - Manage kw configuration files +========================================= .. _config-doc: diff --git a/documentation/man/features/kw-debug.rst b/documentation/man/features/kw-debug.rst index 3097a5fa2..d485692ed 100644 --- a/documentation/man/features/kw-debug.rst +++ b/documentation/man/features/kw-debug.rst @@ -1,6 +1,6 @@ -======== -kw-debug -======== +======================= +kw-debug - Kernel debug +======================= .. _debug-doc: diff --git a/documentation/man/features/kw-deploy.rst b/documentation/man/features/kw-deploy.rst index 130dae224..096f84f0a 100644 --- a/documentation/man/features/kw-deploy.rst +++ b/documentation/man/features/kw-deploy.rst @@ -1,6 +1,6 @@ -========= -kw-deploy -========= +========================= +kw-deploy - Deploy kernel +========================= .. _deploy-doc: diff --git a/documentation/man/features/kw-device.rst b/documentation/man/features/kw-device.rst index 63114c1d4..26e1d25e1 100644 --- a/documentation/man/features/kw-device.rst +++ b/documentation/man/features/kw-device.rst @@ -1,6 +1,6 @@ -========= -kw-device -========= +========================================= +kw-device - Retrieve hardware information +========================================= .. _device-doc: diff --git a/documentation/man/features/kw-diff.rst b/documentation/man/features/kw-diff.rst index 505771e7e..688bfed9e 100644 --- a/documentation/man/features/kw-diff.rst +++ b/documentation/man/features/kw-diff.rst @@ -1,6 +1,6 @@ -======= -kw-diff -======= +=================== +kw-diff - Diff tool +=================== .. _diff-doc: @@ -22,4 +22,4 @@ OPTIONS \--verbose: Verbose mode is an option that causes the kw program to display debug messages to track its progress. This functionality is very useful during the debugging process, allowing - you to identify possible errors more easily. \ No newline at end of file + you to identify possible errors more easily. diff --git a/documentation/man/features/kw-drm.rst b/documentation/man/features/kw-drm.rst index bca5e6655..3368d269a 100644 --- a/documentation/man/features/kw-drm.rst +++ b/documentation/man/features/kw-drm.rst @@ -1,6 +1,6 @@ -====== -kw-drm -====== +============================ +kw-drm - DRM subsystem tools +============================ .. _drm-doc: diff --git a/documentation/man/features/kw-env.rst b/documentation/man/features/kw-env.rst index f67cbf78a..8ec4b4574 100644 --- a/documentation/man/features/kw-env.rst +++ b/documentation/man/features/kw-env.rst @@ -1,6 +1,6 @@ -====== -kw-env -====== +=============================== +kw-env - kw environment manager +=============================== .. _env-doc: diff --git a/documentation/man/features/kw-explore.rst b/documentation/man/features/kw-explore.rst index 965fc1006..5138c3bce 100644 --- a/documentation/man/features/kw-explore.rst +++ b/documentation/man/features/kw-explore.rst @@ -1,6 +1,6 @@ -========== -kw-explore -========== +=========================== +kw-explore - Explore folder +=========================== .. _explore-doc: diff --git a/documentation/man/features/kw-init.rst b/documentation/man/features/kw-init.rst index 394b5fb26..8d85b095a 100644 --- a/documentation/man/features/kw-init.rst +++ b/documentation/man/features/kw-init.rst @@ -1,6 +1,6 @@ -======= -kw-init -======= +====================================== +kw-init - Create kw basic config files +====================================== .. _init-doc: diff --git a/documentation/man/features/kw-kernel-config-manager.rst b/documentation/man/features/kw-kernel-config-manager.rst index 21780f458..0c4a13595 100644 --- a/documentation/man/features/kw-kernel-config-manager.rst +++ b/documentation/man/features/kw-kernel-config-manager.rst @@ -1,6 +1,6 @@ -======================== -kw-kernel-config-manager -======================== +===================================================== +kw-kernel-config-manager - Kernel config file manager +===================================================== .. _kernel-config-manager-doc: diff --git a/documentation/man/features/kw-mail.rst b/documentation/man/features/kw-mail.rst index bd62a16f8..62f3429ad 100644 --- a/documentation/man/features/kw-mail.rst +++ b/documentation/man/features/kw-mail.rst @@ -1,6 +1,6 @@ -======= -kw-mail -======= +=================================== +kw-mail - Send patches through mail +=================================== .. _mail-doc: @@ -43,7 +43,7 @@ the union of the recipients of each patch as the recipients of the cover-letter. OPTIONS ======= -s, \--send: - Send a patch by email using ``git send-email`` to the email adresses + Send a patch by email using ``git send-email`` to the email addresses specified with ``--to`` and ``--cc``. You can provide ** to be passed directly to ``git send-email``, they should be placed after the double dash (``--``) argument. By default this function assumes these arguments to @@ -68,7 +68,7 @@ OPTIONS ``git send-email``'s ``--dry-run`` option. \--private: - Supress auto generation of recipients. + Suppress auto generation of recipients. \--rfc: Add a request for comment prefix to the e-mail's subject. diff --git a/documentation/man/features/kw-maintainers.rst b/documentation/man/features/kw-maintainers.rst index 5686b431d..e44347bf7 100644 --- a/documentation/man/features/kw-maintainers.rst +++ b/documentation/man/features/kw-maintainers.rst @@ -1,6 +1,6 @@ -============== -kw-maintainers -============== +=========================================== +kw-maintainers - Display module maintainers +=========================================== .. _maintainers-doc: diff --git a/documentation/man/features/kw-patch-hub.rst b/documentation/man/features/kw-patch-hub.rst index f2c59916a..f70f5b474 100644 --- a/documentation/man/features/kw-patch-hub.rst +++ b/documentation/man/features/kw-patch-hub.rst @@ -1,6 +1,6 @@ -====================== -kw-patch-hub -====================== +=============================================== +kw-patch-hub - UI with lore.kernel.org archives +=============================================== .. _patch-hub-doc: diff --git a/documentation/man/features/kw-pomodoro.rst b/documentation/man/features/kw-pomodoro.rst index 3e330687a..74ed33ec6 100644 --- a/documentation/man/features/kw-pomodoro.rst +++ b/documentation/man/features/kw-pomodoro.rst @@ -1,6 +1,6 @@ -=========== -kw-pomodoro -=========== +=============================================== +kw-pomodoro - Create and manage Pomodoro timers +=============================================== .. _pomodoro-doc: diff --git a/documentation/man/features/kw-remote.rst b/documentation/man/features/kw-remote.rst index 47487138a..10654fef5 100644 --- a/documentation/man/features/kw-remote.rst +++ b/documentation/man/features/kw-remote.rst @@ -1,6 +1,6 @@ -========= -kw-remote -========= +=============================================== +kw-remote - Manage set of tracked test machines +=============================================== .. _remote-doc: diff --git a/documentation/man/features/kw-report.rst b/documentation/man/features/kw-report.rst index 86f64e589..9ef12d78f 100644 --- a/documentation/man/features/kw-report.rst +++ b/documentation/man/features/kw-report.rst @@ -1,9 +1,10 @@ -========= -kw-report -========= +================================ +kw-report - Display user reports +================================ .. _report-doc: + SYNOPSIS ======== | *kw* (*r* | *report*) [\--year []] [\--output ] [\--verbose] diff --git a/documentation/man/features/kw-self-update.rst b/documentation/man/features/kw-self-update.rst index f870eba31..273d8a522 100644 --- a/documentation/man/features/kw-self-update.rst +++ b/documentation/man/features/kw-self-update.rst @@ -1,6 +1,6 @@ -============== -kw-self-update -============== +========================================= +kw-self-update - kw self-update mechanism +========================================= .. _self-update-doc: diff --git a/documentation/man/features/kw-ssh.rst b/documentation/man/features/kw-ssh.rst index 7d5d39929..7ca708fac 100644 --- a/documentation/man/features/kw-ssh.rst +++ b/documentation/man/features/kw-ssh.rst @@ -1,6 +1,6 @@ -====== -kw-ssh -====== +============================== +kw-ssh - Access remote via ssh +============================== .. _ssh-doc: diff --git a/documentation/man/features/kw-vars.rst b/documentation/man/features/kw-vars.rst index d7f7341f8..8cf3b0a54 100644 --- a/documentation/man/features/kw-vars.rst +++ b/documentation/man/features/kw-vars.rst @@ -1,6 +1,6 @@ -======= -kw-vars -======= +=============================== +kw-vars - View kw config values +=============================== .. _vars-doc: diff --git a/documentation/man/features/kw-vm.rst b/documentation/man/features/kw-vm.rst index 7b685b9ea..fb78e9dd9 100644 --- a/documentation/man/features/kw-vm.rst +++ b/documentation/man/features/kw-vm.rst @@ -1,6 +1,6 @@ -===== -kw-vm -===== +====================================== +kw-vm - Commands to work with QEMU VMs +====================================== .. _vm-doc: diff --git a/documentation/man/kw.rst b/documentation/man/kw.rst index de7087f81..adbcb2ab3 100644 --- a/documentation/man/kw.rst +++ b/documentation/man/kw.rst @@ -1,13 +1,9 @@ -===== - kw -===== +=============================================== + kw - Inglorious kernel developer workflow tool +=============================================== .. _manual: ------------------------------------------ -Inglorious kernel developer workflow tool ------------------------------------------ - :Author: Rodrigo Siqueira :Author: Matheus Tavares :Date: 2018-05-18 From 6f24433bcc64ea07d5ace096ee4320bfa62d5c3a Mon Sep 17 00:00:00 2001 From: uwla Date: Fri, 1 Dec 2023 15:22:18 -0300 Subject: [PATCH 009/128] setup.sh: add flag --skip-docs to skip creation of man pages With this new flag, the user can install KW without creating man pages, which takes time due to sphinx. This drastically reduce installation time and is specially useful in cases where the manual pages are not needed, such as local development and continuous integration. Reviewed-by: David Tadokoro Signed-off-by: uwla --- setup.sh | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/setup.sh b/setup.sh index 11e80755a..a85949767 100755 --- a/setup.sh +++ b/setup.sh @@ -9,6 +9,7 @@ SILENT=1 VERBOSE=0 FORCE=0 SKIPCHECKS=0 +SKIPDOCS=0 ENABLE_TRACING=0 declare -r app_name='kw' @@ -224,6 +225,7 @@ function usage() say "--install | -i Install $app_name" say "--uninstall | -u Uninstall $app_name" say '--skip-checks Skip checks (use this when packaging)' + say '--skip-docs Skip creation of man pages (use this when installing)' say '--verbose Explain what is being done' say '--force Never prompt' say "--completely-remove Remove $app_name and all files under its responsibility" @@ -368,22 +370,24 @@ function synchronize_files() ASSERT_IF_NOT_EQ_ZERO "The command 'rsync -vr $DOCUMENTATION $docdir' failed" "$?" # man file - mkdir -p "$mandir" - - python3 -m venv "$DOCS_VIRTUAL_ENV" - - # Activate python virtual env - source "${DOCS_VIRTUAL_ENV}/bin/activate" - say 'Creating python virtual env...' - cmd="pip --quiet --require-virtualenv install --requirement \"${DOCUMENTATION}/dependencies/pip.dependencies\"" - eval "$cmd" - cmd_output_manager "sphinx-build -nW -b man $DOCUMENTATION $mandir" "$verbose" - ASSERT_IF_NOT_EQ_ZERO "'sphinx-build -nW -b man $DOCUMENTATION $mandir' failed" "$?" - # Deactivate python virtual env - deactivate - - if [[ -d "$DOCS_VIRTUAL_ENV" ]]; then - rm -r "$DOCS_VIRTUAL_ENV" + if [[ "$SKIPDOCS" == 0 ]]; then + mkdir -p "$mandir" + + python3 -m venv "$DOCS_VIRTUAL_ENV" + + # Activate python virtual env + source "${DOCS_VIRTUAL_ENV}/bin/activate" + say 'Creating python virtual env...' + cmd="pip --quiet --require-virtualenv install --requirement \"${DOCUMENTATION}/dependencies/pip.dependencies\"" + eval "$cmd" + cmd_output_manager "sphinx-build -nW -b man $DOCUMENTATION $mandir" "$verbose" + ASSERT_IF_NOT_EQ_ZERO "'sphinx-build -nW -b man $DOCUMENTATION $mandir' failed" "$?" + # Deactivate python virtual env + deactivate + + if [[ -d "$DOCS_VIRTUAL_ENV" ]]; then + rm -r "$DOCS_VIRTUAL_ENV" + fi fi # etc files @@ -570,6 +574,10 @@ for arg; do SKIPCHECKS=1 continue fi + if [[ "$arg" = '--skip-docs' ]]; then + SKIPDOCS=1 + continue + fi if [[ "$arg" = '--enable-tracing' ]]; then include 'tracing/tracing.sh' ENABLE_TRACING=1 From 68f59239c29ed97228955bd05eb4ac98cd000bf1 Mon Sep 17 00:00:00 2001 From: Joao Paulo Pereira da Silva Date: Sat, 2 Dec 2023 11:08:43 -0300 Subject: [PATCH 010/128] src: lib: lore: Add pagination support to mailing lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'Registered/Unregistered Mailing Lists' screen has some missing mailing lists, due to the pagination of lore.kernel.org response. For example, the mailing list 'lvm-devel' doesn't appear in patch-hub because it is in the second page of lore.kernel.org. So, add pagination factor to display all the available mailing lists. Closes: #901 Reviewed-by: David Tadokoro Signed-off-by: André Gustavo Nakagomi Lopez Co-authored-by: Joao Paulo Pereira da Silva --- src/lib/lore.sh | 52 +++++++++++++------ tests/unit/lib/lore_test.sh | 8 ++- ...ain_page.html => reduced_lore_page_0.html} | 0 .../unit/samples/web/reduced_lore_page_1.html | 32 ++++++++++++ .../unit/samples/web/reduced_lore_page_2.html | 18 +++++++ 5 files changed, 92 insertions(+), 18 deletions(-) rename tests/unit/samples/web/{reduced_lore_main_page.html => reduced_lore_page_0.html} (100%) create mode 100644 tests/unit/samples/web/reduced_lore_page_1.html create mode 100644 tests/unit/samples/web/reduced_lore_page_2.html diff --git a/src/lib/lore.sh b/src/lib/lore.sh index ba17d9473..e03d28b92 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -12,11 +12,11 @@ declare -gr LORE_URL='https://lore.kernel.org' # Lore cache directory declare -g CACHE_LORE_DIR="${KW_CACHE_DIR}/lore" -# File name for the lore list -declare -gr MAILING_LISTS_PAGE='lore_main_page.html' +# File name for the lore page +declare -gr MAILING_LISTS_PAGE_NAME='lore_page' -# Path to mailing list file to be parsed -declare -g LIST_PAGE_PATH="${CACHE_LORE_DIR}/${MAILING_LISTS_PAGE}" +# File extension for the lore list file +declare -gr MAILING_LISTS_PAGE_EXTENSION='html' # Directory for storing every data related to lore declare -g LORE_DATA_DIR="${KW_DATA_DIR}/lore" @@ -88,9 +88,11 @@ function setup_cache() mkdir -p "${CACHE_LORE_DIR}" } -# This function downloads the lore archive main page and retrieves the names -# and descriptions of the mailing lists currently available in the archive, it -# then saves that information in the `available_lore_mailing_lists` +# This function downloads lore archive pages and retrieves names and +# descriptions of the currently available mailing lists in the archive. It then +# saves that information in the `available_lore_mailing_lists` global array. +# This function takes care of the pagination from the Lore response, by fetching +# adjacent pages until there are no more mailing lists to be listed. # # @flag Flag to control function output function retrieve_available_mailing_lists() @@ -98,23 +100,39 @@ function retrieve_available_mailing_lists() local flag="$1" local index='' local pre_processed + local entries=0 + local page_filename + local page=0 + local offset=0 flag=${flag:-'SILENT'} setup_cache - download "$LORE_URL" "$MAILING_LISTS_PAGE" "$CACHE_LORE_DIR" "$flag" || return "$?" + # When there are no more mailing lists to be listed, only the `all` list is returned + while [[ "$entries" -ne 1 ]]; do - pre_processed=$(sed -nE -e 's/^href="(.*)\/?">\1<\/a>$/\1/p; s/^ (.*)$/\1/p' "${LIST_PAGE_PATH}") + entries=0 + page_filename="${MAILING_LISTS_PAGE_NAME}_${page}.${MAILING_LISTS_PAGE_EXTENSION}" - while IFS= read -r line; do - if [[ -z "$index" ]]; then - index="$line" - else - available_lore_mailing_lists["$index"]="$line" - index='' - fi - done <<< "$pre_processed" + offset=$((LORE_PAGE_SIZE * page)) + page_url="${LORE_URL}/?&o=${offset}" + + download "$page_url" "$page_filename" "$CACHE_LORE_DIR" "$flag" || return "$?" + pre_processed=$(sed -nE -e 's/^href="(.*)\/?">\1<\/a>$/\1/p; s/^ (.*)$/\1/p' "${CACHE_LORE_DIR}/${page_filename}") + + while IFS= read -r line; do + if [[ -z "$index" ]]; then + index="$line" + ((entries++)) + else + available_lore_mailing_lists["$index"]="$line" + index='' + fi + done <<< "$pre_processed" + + ((page++)) + done } # This function parser the message-id link for trying to find if the target diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index 1146c77a3..0f1beb1c4 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -14,7 +14,9 @@ function oneTimeSetUp() mkdir -p "$CACHE_LORE_DIR" mkdir -p "${LORE_DATA_DIR}" - cp "${SAMPLES_DIR}/web/reduced_lore_main_page.html" "${CACHE_LORE_DIR}/lore_main_page.html" + cp "${SAMPLES_DIR}/web/reduced_lore_page_0.html" "${CACHE_LORE_DIR}/lore_page_0.html" + cp "${SAMPLES_DIR}/web/reduced_lore_page_1.html" "${CACHE_LORE_DIR}/lore_page_1.html" + cp "${SAMPLES_DIR}/web/reduced_lore_page_2.html" "${CACHE_LORE_DIR}/lore_page_2.html" cp "${SAMPLES_DIR}/lore_sample.config" "${SHUNIT_TMPDIR}/lore.config" cp "${SAMPLES_DIR}/lore/query_result_sample.xml" "${SHUNIT_TMPDIR}/query_result_sample.xml" } @@ -54,6 +56,10 @@ function test_retrieve_available_mailing_lists() ['linux-pm']='Linux-PM Archive on lore.kernel.org' ['amd-gfx']='AMD-GFX Archive on lore.kernel.org' ['dri-devel']='dri-devel Archive on lore.kernel.org' + ["oe-linux-nfc"]='NFC on Linux' + ['linux-nfc']='Linux-NFC Archive on lore.kernel.org' + ['linux-x11']='Linux X11 Discussion Archive on lore.kernel.org' + ['ultralinux']='Ultralinux archive on lore.kernel.org' ) retrieve_available_mailing_lists 'TEST_MODE' &> /dev/null diff --git a/tests/unit/samples/web/reduced_lore_main_page.html b/tests/unit/samples/web/reduced_lore_page_0.html similarity index 100% rename from tests/unit/samples/web/reduced_lore_main_page.html rename to tests/unit/samples/web/reduced_lore_page_0.html diff --git a/tests/unit/samples/web/reduced_lore_page_1.html b/tests/unit/samples/web/reduced_lore_page_1.html new file mode 100644 index 000000000..30a58cd01 --- /dev/null +++ b/tests/unit/samples/web/reduced_lore_page_1.html @@ -0,0 +1,32 @@ +public-inbox listing
* 2023-12-04 20:18 - all
+  All of lore.kernel.org
+
+* 2022-10-21 14:17 - oe-linux-nfc
+  NFC on Linux
+
+* 2022-09-20 13:54 - linux-nfc
+  Linux-NFC Archive on lore.kernel.org
+
+* 2013-10-02  1:48 - linux-x11
+  Linux X11 Discussion Archive on lore.kernel.org
+
+* 2008-01-06  8:35 - ultralinux
+  Ultralinux archive on lore.kernel.org
+

Results 201-298 of 298	 | reverse

This is a listing of public inboxes, see the `mirror' link of each inbox
+for instructions on how to mirror all the data and code on this site.
diff --git a/tests/unit/samples/web/reduced_lore_page_2.html b/tests/unit/samples/web/reduced_lore_page_2.html new file mode 100644 index 000000000..9f813c031 --- /dev/null +++ b/tests/unit/samples/web/reduced_lore_page_2.html @@ -0,0 +1,18 @@ +public-inbox listing
* 2023-12-04 20:23 - all
+  All of lore.kernel.org
+

No more results, only 298	prev (newer) | reverse

This is a listing of public inboxes, see the `mirror' link of each inbox
+for instructions on how to mirror all the data and code on this site.
From bbb0553bdf4a8e974fa4203c7ce4a64543a8c481 Mon Sep 17 00:00:00 2001 From: uwla Date: Wed, 6 Dec 2023 16:16:33 -0300 Subject: [PATCH 011/128] setup.sh: fix --force flag interactive behavior in ArchLinux The flag `--force` should never prompt during installation, but it does prompt in ArchLinux. Adding the flag `--noconfirm` to pacman's cmd fixes this issue. Closes #983 Reviewed-by: David Tadokoro Signed-off-by: uwla --- setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.sh b/setup.sh index a85949767..fdc64310b 100755 --- a/setup.sh +++ b/setup.sh @@ -64,7 +64,7 @@ function check_dependencies() installed=$(pacman -Ql "$package" &> /dev/null) [[ "$?" != 0 ]] && package_list="$package $package_list" done < "$DOCUMENTATION/dependencies/arch.dependencies" - cmd="pacman -S $package_list" + cmd="pacman -Sy --noconfirm ${package_list}" elif [[ "$distro" =~ 'debian' ]]; then while IFS='' read -r package; do installed=$(dpkg-query -W --showformat='${Status}\n' "$package" 2> /dev/null | grep -c 'ok installed') From 77d6333a758109e5f6df89a4fb4838a316da0175 Mon Sep 17 00:00:00 2001 From: uwla Date: Fri, 1 Dec 2023 15:49:42 -0300 Subject: [PATCH 012/128] src: lib: kw_config_loader: fix not reading line if missing newline char The `kw_config_loader` module would not read the option in the last line of a file if the line is missing the newline character '\n'. While it is a good practice to always add the newline character in text files, KW should still work in cases where it is missing, perhaps due to a mistake. Indeed, `kw init` creates config files some of which do not have the newline character in the last line (such as build.config) which is evidence that mistakes may happen, but even in such scenarios we want KW to function properly. Reviewed-by: David Tadokoro Signed-off-by: uwla --- src/lib/kw_config_loader.sh | 12 ++++++- tests/unit/lib/kw_config_loader_test.sh | 43 ++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/lib/kw_config_loader.sh b/src/lib/kw_config_loader.sh index 3131afcef..5030f9c01 100644 --- a/src/lib/kw_config_loader.sh +++ b/src/lib/kw_config_loader.sh @@ -358,8 +358,18 @@ function parse_configuration() if [ ! -f "$config_path" ]; then return 22 # 22 means Invalid argument - EINVAL fi + + # The `read` command will read all the characters untill it finds a newline + # character and then write those characters onto the given variable (in this + # case, the `line` variable). If it does not find a newline `\n` character, it + # will exit with status code 1. This evaluates to false, which means the + # shellscript exits the loop. Therefore, if the last line is not empty but + # misses the newline character, the loop won't be run and the last config + # option won't be read. We handle this edge case by checking if line is not + # empty and proceeding to run the loop once more if necessary. + # # shellcheck disable=SC2162 - while read line; do + while read line || [[ -n "$line" ]]; do # Line started with # or that are blank should be ignored [[ "$line" =~ ^# || "$line" =~ ^$ ]] && continue diff --git a/tests/unit/lib/kw_config_loader_test.sh b/tests/unit/lib/kw_config_loader_test.sh index 290d5bde8..b43883c9b 100755 --- a/tests/unit/lib/kw_config_loader_test.sh +++ b/tests/unit/lib/kw_config_loader_test.sh @@ -149,6 +149,36 @@ function test_parse_configuration_standard_config() assert_configurations_helper configurations expected_configurations "$LINENO" } +function test_parse_configuration_file_without_final_newline() +{ + local config_key + local config_val + local config_ref + local config_file + + # the configuration we will test, for the build module + declare -A expected_configurations=( + [arch]='amd' + [cpu_scaling_factor]='75' + [cflags]='-Wall' + ) + config_ref='build_config' + config_file="${TMPDIR_KW_FOLDER}/build.config" + + # manually put the contents onto the file to ensure no newline at the end + (for config_key in "${!expected_configurations[@]}"; do + config_val="${expected_configurations[$config_key]}" + + # The newline character comes before the config option purposefully. This + # will put each option in a different line, but the last line won't be + # followed by the newline character, which is what we want to test. + printf '\n%s=%s' "$config_key" "$config_val" + done) > "$config_file" + + parse_configuration "$config_file" "$config_ref" + assert_configurations_helper "$config_ref" expected_configurations +} + # To test the order of config file loading, we will put a file named # kworkflow.config in each place, in order, and remove the previous one. # The order is: PWD, XDG_CONFIG_HOME, XDG_CONFIG_DIRS, KW_ETC_DIR @@ -307,7 +337,18 @@ function test_show_variables_main_correctness() ) output="$(show_variables_main | grep -E '^\s{3,}')" - while read -r line; do + + # The `read` command will read all the characters untill it finds a newline + # character and then write those characters onto the given variable (in this + # case, the `line` variable). If it does not find a newline `\n` character, it + # will exit with status code 1. This evaluates to false, which means the + # shellscript exits the loop. Therefore, if the last line is not empty but + # misses the newline character, the loop won't be run and the last config + # option won't be read. We handle this edge case by checking if line is not + # empty and proceeding to run the loop once more if necessary. + # + # shellcheck disable=SC2162 + while read -r line || [[ -n "$line" ]]; do option="$(printf '%s\n' "$line" | sed -E 's/.*\((\S*)\).*/\1/')" value=$(printf '%s\n' "$line" | sed -E 's/.*: (.*)/\1/') if [[ "${configurations[$option]}" != "$value" ]]; then From 9ac7a08dd1d21c19b1bb2517223d7e5629a31a40 Mon Sep 17 00:00:00 2001 From: uwla Date: Wed, 13 Dec 2023 15:44:39 -0300 Subject: [PATCH 013/128] setup.sh: add more short flags Add the following short flags: * -C for --skip-checks * -D for --skip-docs * -d for --docs * -f for --force * -r for --completely-remove * -t for --enable-tracing * -v for --verbose Usually short lowercase options enable some behavior. Thus, we use uppercase to sign we disable the behavior: the flag -D to disable creation of documentation as man pages, and the flag -C to disable dependencies checking. Closes #993. Reviewed-by: Rodrigo Siqueira Signed-off-by: uwla Signed-off-by: Rodrigo Siqueira --- setup.sh | 72 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/setup.sh b/setup.sh index fdc64310b..ccb4f7957 100755 --- a/setup.sh +++ b/setup.sh @@ -221,16 +221,16 @@ function usage() say 'usage: ./setup.sh option' say '' say 'Where option may be one of the following:' - say '--help | -h Display this usage message' - say "--install | -i Install $app_name" - say "--uninstall | -u Uninstall $app_name" - say '--skip-checks Skip checks (use this when packaging)' - say '--skip-docs Skip creation of man pages (use this when installing)' - say '--verbose Explain what is being done' - say '--force Never prompt' - say "--completely-remove Remove $app_name and all files under its responsibility" - say "--docs Build $app_name's documentation as HTML pages into ./build" - say "--enable-tracing Install ${app_name} with tracing enabled (use it with --install)" + say '--help | -h Display this usage message' + say "--install | -i Install $app_name" + say "--uninstall | -u Uninstall $app_name" + say '--skip-checks | -C Skip checks (use this when packaging)' + say '--skip-docs | -D Skip creation of man pages (use this when installing)' + say '--verbose | -v Explain what is being done' + say '--force | -f Never prompt' + say "--completely-remove | -r Remove $app_name and all files under its responsibility" + say "--docs | -d Build $app_name's documentation as HTML pages into ./build" + say "--enable-tracing | -t Install ${app_name} with tracing enabled (use it with --install)" } function confirm_complete_removal() @@ -562,27 +562,33 @@ function setup_global_config_file() # Options for arg; do shift - if [ "$arg" = '--verbose' ]; then - VERBOSE=1 - continue - fi - if [ "$arg" = '--force' ]; then - FORCE=1 - continue - fi - if [ "$arg" = '--skip-checks' ]; then - SKIPCHECKS=1 - continue - fi - if [[ "$arg" = '--skip-docs' ]]; then - SKIPDOCS=1 - continue - fi - if [[ "$arg" = '--enable-tracing' ]]; then - include 'tracing/tracing.sh' - ENABLE_TRACING=1 - continue - fi + case "$arg" in + --verbose | -v) + VERBOSE=1 + continue + ;; + --force | -f) + FORCE=1 + continue + ;; + # Usually short lowercase options enable some behavior. Thus, the option -C + # is uppercase to sign we disable the dependency-check behavior. + --skip-checks | -C) + SKIPCHECKS=1 + continue + ;; + # Similarly, the lowercase short option -D signs we disable the default + # behavior of generating man pages. + --skip-docs | -D) + SKIPDOCS=1 + continue + ;; + --enable-tracing | -t) + include 'tracing/tracing.sh' + ENABLE_TRACING=1 + continue + ;; + esac set -- "$@" "$arg" done @@ -599,14 +605,14 @@ case "$1" in # related to kw, e.g., '.config' file under kw controls. For this reason, we do # not want to add a short version, and the user has to be sure about this # operation. - --completely-remove) + --completely-remove | -r) confirm_complete_removal clean_legacy '-d' ;; --help | -h) usage ;; - --docs) + --docs | -d) generate_documentation ;; *) From c32fe38f1476393406ab0e8a0daf8cdc9751cf64 Mon Sep 17 00:00:00 2001 From: uwla Date: Sun, 17 Dec 2023 23:10:16 -0300 Subject: [PATCH 014/128] tests: integration: test kw version on ArchLinux, Debian and Fedora Test kw version on ArchLinux, Debian and Fedora using Podman. Also, change GitHub Unit Test Workflow to only run unit tests and ignore the integration tests. Reviewed-by: Rodrigo Siqueira Co-authored-by: Fernando Henrique Co-authored-by: Gustavo Ueti Fukunaga Signed-off-by: uwla Signed-off-by: Rodrigo Siqueira --- .github/workflows/kcov.yml | 2 +- .github/workflows/unit_tests.yml | 2 +- run_tests.sh | 34 ++++ tests/integration/kw_version_test.sh | 66 ++++++ .../podman/Containerfile_archlinux | 7 + tests/integration/podman/Containerfile_debian | 7 + tests/integration/podman/Containerfile_fedora | 7 + .../podman/clone_and_install_kw.sh | 17 ++ tests/integration/utils.sh | 190 ++++++++++++++++++ 9 files changed, 330 insertions(+), 2 deletions(-) create mode 100755 tests/integration/kw_version_test.sh create mode 100644 tests/integration/podman/Containerfile_archlinux create mode 100644 tests/integration/podman/Containerfile_debian create mode 100644 tests/integration/podman/Containerfile_fedora create mode 100755 tests/integration/podman/clone_and_install_kw.sh create mode 100755 tests/integration/utils.sh diff --git a/.github/workflows/kcov.yml b/.github/workflows/kcov.yml index 2b6b41fb8..9d2912b4d 100644 --- a/.github/workflows/kcov.yml +++ b/.github/workflows/kcov.yml @@ -37,7 +37,7 @@ jobs: run: | kcov --include-path=src,kw \ --exclude-pattern=src/bash_autocomplete.sh,src/help.sh \ - kcov_out/ ./run_tests.sh + kcov_out/ ./run_tests.sh --unit - name: Upload coverage do codecov run: | diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index b5620689b..96ab3f6ec 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -30,4 +30,4 @@ jobs: - name: Unit tests run: | - ./run_tests.sh + ./run_tests.sh --unit diff --git a/run_tests.sh b/run_tests.sh index c503febff..147a99209 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -2,6 +2,7 @@ . ./src/lib/kw_include.sh --source-only include './tests/unit/utils.sh' +include './tests/integration/utils.sh' include './src/lib/kwio.sh' function show_help() @@ -11,6 +12,8 @@ function show_help() "Example: $0 test kw_test" \ '' \ 'OPTIONS' \ + ' -i, --integration' \ + ' Limit tests to integration tests' \ ' -u, --unit' \ ' Limit tests to unit tests' \ '' \ @@ -66,16 +69,33 @@ function run_tests() local -i notfound=0 local -i fail=0 local test_failure_list='' + local test_dir + local integration_tests_setup=0 # have we setup the environment for integration tests? for current_test in "${TESTS[@]}"; do target=$(find "$TESTS_DIR" -name "${current_test}*.sh" | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') if [[ -f "$target" ]]; then + + # if we are running integration tests, we will set up the environment for + # them here. That is because all integration tests share the same setup: + # at least the container environment must be up. It is much more efficient + # to run the setup just once for all tests than to run it for every test. + # This approach also avoids code duplication in the files. + test_dir=$(dirname "${target}") + if [[ "$test_dir" =~ '/integration' && "$integration_tests_setup" == 0 ]]; then + integration_tests_setup=1 + say 'Preparing environment for integration tests...' + setup_container_environment + printf '\n' + fi + say "Running test [${current_test}]" say "$SEPARATOR" ( init_env "$target" ) + if [[ "$?" -eq 0 ]]; then success+=1 else @@ -91,6 +111,17 @@ function run_tests() notfound+=1 fi done + + # instead of tearing down the container environment after each integration test, + # we will tear it down only after all tests have ran. This optimizes significant + # amount of time for the integration tests. + if [[ "${integration_tests_setup}" == 1 ]]; then + printf '\n' # add new line after the last "OK" + say 'Tearing down environment used in integration tests...' + teardown_container_environment + printf '\n' + fi + report_results "$total" "$success" "$notfound" "$fail" "$test_failure_list" } @@ -109,6 +140,9 @@ declare TESTS_DIR=./tests if [[ "$1" == '--unit' || "$1" == '-u' ]]; then TESTS_DIR=./tests/unit shift +elif [[ "$1" == '--integration' || "$1" == '-i' ]]; then + TESTS_DIR=./tests/integration + shift fi check_files="$?" diff --git a/tests/integration/kw_version_test.sh b/tests/integration/kw_version_test.sh new file mode 100755 index 000000000..d0f08a2d8 --- /dev/null +++ b/tests/integration/kw_version_test.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +include './src/lib/kwio.sh' +include './tests/unit/utils.sh' +include './tests/integration/utils.sh' + +declare -g expected_output + +function oneTimeSetUp() +{ + local kw_git_dir + local kw_dir + local head_hash + local branch_name + local base_version + + # git directory path + kw_dir="${KWROOT_DIR}" + kw_git_dir="${kw_dir}/.git" + + # In order to check correctness of `kw --version`, we collect some information + # from the git repo: + # + # - Base version (alpha, beta, or other) + # - Branch name + # - Commit sha + # + # Because the local KW repo is copied to the container, we run the following + # commands directly on the host instead of running in the container. + head_hash=$(git --git-dir "${kw_git_dir}" rev-parse --short HEAD) + branch_name=$(git --git-dir "${kw_git_dir}" rev-parse --short --abbrev-ref HEAD) + base_version=$(head --lines 1 "${kw_dir}/src/VERSION") + + # using the gathered information, we build the expected output + expected_output=$(printf '%s\nBranch: %s\nCommit: %s' "$base_version" "$branch_name" "$head_hash") +} + +function kw_version_test_helper() +{ + local distro="$1" + local container + local output + + # collect the kw version in the container + container="kw-${distro}" + output=$(container_exec "${container}" 'kw --version') + + assertEquals "(${LINENO}): kw version failed for ${distro}" "$expected_output" "$output" +} + +function test_kw_version_on_archlinux() +{ + kw_version_test_helper 'archlinux' +} + +function test_kw_version_on_debian() +{ + kw_version_test_helper 'debian' +} + +function test_kw_version_on_fedora() +{ + kw_version_test_helper 'fedora' +} + +invoke_shunit diff --git a/tests/integration/podman/Containerfile_archlinux b/tests/integration/podman/Containerfile_archlinux new file mode 100644 index 000000000..8f9ac9073 --- /dev/null +++ b/tests/integration/podman/Containerfile_archlinux @@ -0,0 +1,7 @@ +FROM docker.io/library/archlinux + +RUN pacman -Syu --noconfirm git + +COPY ./clone_and_install_kw.sh . + +RUN bash ./clone_and_install_kw.sh diff --git a/tests/integration/podman/Containerfile_debian b/tests/integration/podman/Containerfile_debian new file mode 100644 index 000000000..e8dbfc033 --- /dev/null +++ b/tests/integration/podman/Containerfile_debian @@ -0,0 +1,7 @@ +FROM docker.io/library/debian + +RUN apt update -y && apt upgrade -y && apt install git -y + +COPY ./clone_and_install_kw.sh . + +RUN bash ./clone_and_install_kw.sh diff --git a/tests/integration/podman/Containerfile_fedora b/tests/integration/podman/Containerfile_fedora new file mode 100644 index 000000000..41f740de3 --- /dev/null +++ b/tests/integration/podman/Containerfile_fedora @@ -0,0 +1,7 @@ +FROM docker.io/library/fedora + +RUN dnf install -y git + +COPY ./clone_and_install_kw.sh . + +RUN bash ./clone_and_install_kw.sh diff --git a/tests/integration/podman/clone_and_install_kw.sh b/tests/integration/podman/clone_and_install_kw.sh new file mode 100755 index 000000000..d1d27f312 --- /dev/null +++ b/tests/integration/podman/clone_and_install_kw.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# The primary purpose of this file is to install kw's dependencies in the image +# we will built. This will save up time when installing the local copy of KW in +# the running container. +# +# We clone kw and install the unstable branch in order for the base image of the +# container to have all required dependencies. Later, the local KW repo will be +# copied to the container and installed, but the dependencies won't have to be +# installed again, which saves a lot of time. + +kw_dir='/tmp/kw' + +git clone https://github.com/kworkflow/kworkflow "${kw_dir}" +cd "$kw_dir" || exit 1 +git checkout unstable +./setup.sh --install --force --skip-docs diff --git a/tests/integration/utils.sh b/tests/integration/utils.sh new file mode 100755 index 000000000..cc6607104 --- /dev/null +++ b/tests/integration/utils.sh @@ -0,0 +1,190 @@ +#!/bin/bash + +include './src/lib/kwio.sh' + +declare -g CONTAINER_DIR # has the container files to build the container images +declare -g SAMPLES_DIR # has sample files used accross the integration tests +declare -g KWROOT_DIR # local kw dir to be copied to and installed in the containers +declare -g DISTROS # distributions we will run the integration tests + +# ensure path to directories is absolute +script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")") +CONTAINER_DIR="${script_dir}/podman" +SAMPLES_DIR="${script_dir}/samples" +KWROOT_DIR=$(realpath "${script_dir}/../..") + +# supported distros +DISTROS=( + 'archlinux' + 'debian' + 'fedora' +) + +# Builds a container image for the given distro +# +# @param $1 The OS distribution of the target container image. +# @return $? The status code of the command ran to build the image. +function build_distro_image() +{ + local distro="${1}" + local file="${CONTAINER_DIR}/Containerfile_${distro}" + + podman image build --file "$file" --tag "kw-${distro}" > /dev/null 2>&1 + + # Check if the command failed + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Error building the image for distribution ${distro}" + return "$?" + fi +} + +# Builds container images and create containers used accross the tests. +# +# @param $1 log level to print info, debug or error +function setup_container_environment() +{ + local container_img + local container_name + local distro # current distro + local distros_ok # array of distros whose setup succeed + local i # current step of the setup + local n # total number of steps + local working_directory # working directory in the container + + # initialize some values + distros_ok=() + i=0 + n=$((${#DISTROS[@]} * 2)) + working_directory='/tmp/kw' + + for distro in "${DISTROS[@]}"; do + + # Only build the image if it does not exists. That's because trying to build + # the podman image takes a second or two even if it exists and is cached. + podman image exists "kw-${distro}" + if [[ "$?" -ne 0 ]]; then + # progress message: + i=$((i + 1)) + say "[${i}/${n}] Building container image for ${distro}." + + # Build the image or fail. + build_distro_image "$distro" + if [[ "$?" -ne 0 ]]; then + complain "failed to setup container environment for distro ${distro}" + + # print we will skip creating the container image + i=$((i + 1)) + say "[${i}/${n}] Skip creating ${distro} container." + + # continue the setup for other distros. + continue + fi + else + # progress message: + i=$((i + 1)) + say "[${i}/${n}] Using cached container image for ${distro}." + fi + + # The name of the container and the container image are equal here, but it + # is useful to make a distinction that in some places we should use the image + # name and in others the container name (they are equal in value but are not + # equivalent in meaning). + container_img="kw-${distro}" + container_name="${container_img}" + + # If container exists, we tear it down and create a new one in order + # ensure KW installation reflects the latest local changes. + podman container exists "${container_name}" + if [[ "$?" -eq 0 ]]; then + teardown_single_container "${container_name}" + fi + + # progress message: + i=$((i + 1)) + say "[${i}/${n}] Creating ${distro} container." + + # containers are isolated environments designed to run a process. After the + # process ends, the container is destroyed. In order execute multiple commands + # in the container, we need to keep the container, which means the primary + # process must not terminate. Therefore, we run a never-ending command as the + # primary process, so that we can execute multiple commands (secondary + # processes) and get the output of each of them separately. + container_run \ + --workdir "${working_directory}" \ + --volume "${KWROOT_DIR}":"${working_directory}" \ + --env PATH='/root/.local/bin:/usr/bin' \ + --name "${container_name}" \ + --detach \ + "${container_img}" sleep infinity > /dev/null + + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to run the container ${container_name}" + fi + + # install kw again + container_exec "${container_name}" \ + ./setup.sh --install --force --skip-checks --skip-docs > /dev/null 2>&1 + + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to install kw in the container ${container_name}" + else + # add distro to array of distros that worked. + distros_ok+=("$distro") + fi + done + + # Update DISTRO so it only has distros whose setup succeed. + # Thus, the integration tests can run even if some distros failed to set up. + DISTROS=("${distros_ok[@]}") +} + +# destroy a single container +function teardown_single_container() +{ + local container="$1" + + podman container exists "${container}" + + if [[ "$?" -eq 0 ]]; then + # destroy the container, waiting 0 seconds to send SIGKILL + podman container rm --force --time 0 "${container}" > /dev/null 2>&1 + fi +} + +# destroy all containers used in the tests +teardown_container_environment() +{ + local distro + local i=0 # current step of tear down + local n="${#DISTROS[@]}" # total number of steps of tear down + + for distro in "${DISTROS[@]}"; do + # progress message + i=$((i + 1)) + say "[${i}/${n}] Removing ${distro} container." + + teardown_single_container "kw-${distro}" + done +} + +# run a container +function container_run() +{ + # shellcheck disable=SC2068 + podman container run $@ + + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to run the container." + fi +} + +# execute a given command in the container +function container_exec() +{ + # shellcheck disable=SC2068 + podman container exec $@ 2> /dev/null + + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to execute the command in the container." + fi +} From 333df0e566d8ae2b47971ec68f7c43b175561f4b Mon Sep 17 00:00:00 2001 From: uwla Date: Mon, 4 Dec 2023 09:05:07 -0300 Subject: [PATCH 015/128] tests: integration: add local config test We mount a directory with sample config files in the container, then `run kw config --show ` and compare the result with the expected output. Reviewed-by: Rodrigo Siqueira Co-authored-by: Fernando Henrique Co-authored-by: Gustavo Ueti Fukunaga Signed-off-by: uwla Signed-off-by: Rodrigo Siqueira --- tests/integration/config_test.sh | 79 +++++++++++++++++++ tests/integration/samples/config/build.config | 5 ++ .../integration/samples/config/deploy.config | 7 ++ .../samples/config/kworkflow.config | 10 +++ tests/integration/samples/config/mail.config | 4 + .../samples/config/notification.config | 3 + tests/integration/samples/config/vm.config | 5 ++ tests/integration/utils.sh | 14 ++++ 8 files changed, 127 insertions(+) create mode 100755 tests/integration/config_test.sh create mode 100644 tests/integration/samples/config/build.config create mode 100644 tests/integration/samples/config/deploy.config create mode 100644 tests/integration/samples/config/kworkflow.config create mode 100644 tests/integration/samples/config/mail.config create mode 100644 tests/integration/samples/config/notification.config create mode 100644 tests/integration/samples/config/vm.config diff --git a/tests/integration/config_test.sh b/tests/integration/config_test.sh new file mode 100755 index 000000000..ff5bf85b3 --- /dev/null +++ b/tests/integration/config_test.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +include './tests/unit/utils.sh' +include './tests/integration/utils.sh' + +function oneTimeSetUp() +{ + local distro + + # copy config files to the containers + for distro in "${DISTROS[@]}"; do + container_copy "kw-${distro}" "${SAMPLES_DIR}/config" '/tmp/.kw' + done +} + +# The current workaround is this: we are using specially crafted config files +# that overwrite all global options in the same order displayed by kw. +function local_config_test_helper() +{ + local config="$1" + local config_file + local container + local distro + local expected_output + + # make sure config is defined + if [[ -z "${config}" ]]; then + fail "(${LINENO}): 'config' is not defined." + fi + + # the path to the config file + config_file="${SAMPLES_DIR}/config/${config}.config" + + # the expected output is the same for all distros + expected_output=$(sort --dictionary-order "${config_file}") + + for distro in "${DISTROS[@]}"; do + container="kw-${distro}" + + # get the output inside the container + output=$(container_exec --workdir '/tmp' "${container}" "kw config --show --local ${config}") + + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}) kw failed to show local variables in ${distro}" + fi + + # remove prefix and N/A values from the output and sort them, before comparing + output=$(grep --invert-match 'N/A' <<< "${output}" | sed "s/^${config}.//" | sort --dictionary-order) + + assertEquals "(${LINENO}): kw config failed for ${distro}" "${expected_output}" "${output}" + done +} + +function test_build_config() +{ + local_config_test_helper 'build' +} + +function test_deploy_config() +{ + local_config_test_helper 'deploy' +} + +function test_mail_config() +{ + local_config_test_helper 'mail' +} + +function test_notification_config() +{ + local_config_test_helper 'notification' +} + +function test_vm_config() +{ + local_config_test_helper 'vm' +} + +invoke_shunit diff --git a/tests/integration/samples/config/build.config b/tests/integration/samples/config/build.config new file mode 100644 index 000000000..88099da83 --- /dev/null +++ b/tests/integration/samples/config/build.config @@ -0,0 +1,5 @@ +arch=arm +kernel_img_name=linux +menu_config=nconfig +doc_type=latexdocs +cpu_scaling_factor=75 diff --git a/tests/integration/samples/config/deploy.config b/tests/integration/samples/config/deploy.config new file mode 100644 index 000000000..b8c2da1c4 --- /dev/null +++ b/tests/integration/samples/config/deploy.config @@ -0,0 +1,7 @@ +kw_files_remote_path=/opt/kw +deploy_temporary_files_path=/tmp/kw +deploy_default_compression=gzip +dtb_copy_pattern=dtb* +default_deploy_target=local +reboot_after_deploy=yes +strip_modules_debug_option=no diff --git a/tests/integration/samples/config/kworkflow.config b/tests/integration/samples/config/kworkflow.config new file mode 100644 index 000000000..38a81aaef --- /dev/null +++ b/tests/integration/samples/config/kworkflow.config @@ -0,0 +1,10 @@ +ssh_user=root +ssh_ip=localhost +ssh_port=2222 +alert=y +sound_alert_command= +visual_alert_command= +disable_statistics_data_track=yes +send_opts= +checkpatch_opts= +get_maintainer_opts= diff --git a/tests/integration/samples/config/mail.config b/tests/integration/samples/config/mail.config new file mode 100644 index 000000000..0af4b6433 --- /dev/null +++ b/tests/integration/samples/config/mail.config @@ -0,0 +1,4 @@ +send_opts=1 +blocked_emails=2 +default_to_recipients=3 +default_cc_recipients=4 diff --git a/tests/integration/samples/config/notification.config b/tests/integration/samples/config/notification.config new file mode 100644 index 000000000..c161dafc9 --- /dev/null +++ b/tests/integration/samples/config/notification.config @@ -0,0 +1,3 @@ +alert=n +sound_alert_command=sound_cmd +visual_alert_command=alert_cmd diff --git a/tests/integration/samples/config/vm.config b/tests/integration/samples/config/vm.config new file mode 100644 index 000000000..8f7597011 --- /dev/null +++ b/tests/integration/samples/config/vm.config @@ -0,0 +1,5 @@ +virtualizer=qemu-system-x86_64 +mount_point=/mount +qemu_hw_options=-enable-k-d -m 4096 +qemu_net_options=-nic user,hostfwd=tcp::2222-:22 +qemu_path_image=/usr/share/qemu/virty.qcow2 diff --git a/tests/integration/utils.sh b/tests/integration/utils.sh index cc6607104..755972385 100755 --- a/tests/integration/utils.sh +++ b/tests/integration/utils.sh @@ -188,3 +188,17 @@ function container_exec() fail "(${LINENO}): Failed to execute the command in the container." fi } + +# copy local file to container +container_copy() +{ + local container="$1" + local src="$2" + local dst="$3" + + podman container cp "${src}" "${container}":"${dst}" + + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to copy host files to the container." + fi +} From 98f1aabc4173072095f33296876f21da13dd1b76 Mon Sep 17 00:00:00 2001 From: uwla Date: Tue, 28 Nov 2023 11:59:06 -0300 Subject: [PATCH 016/128] tests: integration: add basic device test that checks distro Test device info to check distribution on Archlinux, Debian and Fedora using podman. Reviewed-by: Rodrigo Siqueira Co-authored-by: Fernando Henrique Co-authored-by: Gustavo Ueti Fukunaga Signed-off-by: uwla Signed-off-by: Rodrigo Siqueira --- tests/integration/device_test.sh | 82 ++++++++++++++++++++++++++++++++ tests/integration/utils.sh | 11 +++++ 2 files changed, 93 insertions(+) create mode 100755 tests/integration/device_test.sh diff --git a/tests/integration/device_test.sh b/tests/integration/device_test.sh new file mode 100755 index 000000000..daee54d2e --- /dev/null +++ b/tests/integration/device_test.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +include './tests/unit/utils.sh' +include './tests/integration/utils.sh' +include './src/device_info.sh' + +# test if `kw device --local` in the container matches the host +function device_info_test_helper() +{ + local distro="${1}" + local container + local buffer + local filter + local filter_regex + local fs_type + local fs_size + local output + local expected_output + + # buffer with all information. + container="kw-${distro}" + buffer=$(container_exec "${container}" 'kw device --local') + + # some fields must be ignored because they surely won't match. + filter=( + 'Root filesystem' 'Size' 'Mounted on' # storage fields + 'Distribution' 'Distribution version' 'Desktop environments' # desktop fields + ) + + # add | separator to each filter item. + filter_regex=$(sed 's/ /|/g' <<< "${filter[@]}") + + # the actual perl regex. + filter_regex="(${filter_regex}):" + + # get the output, after applying filter. + output=$(printf '%s' "${buffer}" | grep --invert-match --perl-regexp "${filter_regex}") + + # get the expected output from the host machine, also filtering information. + expected_output=$(device_main --local | grep --invert-match --perl-regexp "${filter_regex}") + + # TODO: remove this block of code after issue #1000 has been solved. + # + # deviceinfo shows GPU information for Arch, but not for Debian and Fedora due + # some libraries being present in Arch by default, but not in the others. + # Therefore, if this information is not present, we must filter it out. + grep 'GPU:' <<< "${output}" > /dev/null + if [[ "$?" -ne 0 ]]; then + # we resort to SED because GREP can't filter out lines after context IF we + # use invert match. First, we tell sed to stop printing lines after matching + # the pattern GPU then delete the line containing that pattern. + expected_output=$(sed '/GPU:/q' <<< "${expected_output}" | sed '/GPU:/d') + fi + + assertEquals "(${LINENO}): kw device failed for ${distro}" "${output}" "${expected_output}" + + # check storage information + fs_type=$(container_inspect --format '{{.Driver}}' "${container}") + fs_size=$(container_inspect --format '{{.GraphDriver.Data.WorkDir}}' "${container}" | + xargs df -h | tail --lines 1 | awk '{ print $2 }') + + assert_substring_match 'Wrong filesystem type.' "${LINENO}" "${buffer}" "Root filesystem: ${fs_type}" + assert_substring_match 'Wrong filesystem size.' "${LINENO}" "${buffer}" "Size: ${fs_size}" + assert_substring_match 'Wrong mounting point.' "${LINENO}" "${buffer}" "Mounted on: /" +} + +function test_device_archlinux() +{ + device_info_test_helper 'archlinux' +} + +function test_device_debian() +{ + device_info_test_helper 'debian' +} + +function test_device_fedora() +{ + device_info_test_helper 'fedora' +} + +invoke_shunit diff --git a/tests/integration/utils.sh b/tests/integration/utils.sh index 755972385..fe944dad9 100755 --- a/tests/integration/utils.sh +++ b/tests/integration/utils.sh @@ -202,3 +202,14 @@ container_copy() fail "(${LINENO}): Failed to copy host files to the container." fi } + +# inspect the container +container_inspect() +{ + # shellcheck disable=SC2068 + podman container inspect $@ + + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to inspect the container." + fi +} From ac3db7a2940e8c26ec7c39670aa3e3e0a41aaed5 Mon Sep 17 00:00:00 2001 From: uwla Date: Wed, 13 Dec 2023 09:37:43 -0300 Subject: [PATCH 017/128] documentation: content: tests Provide documentation on integration tests, such as the dependencies required to run them. Signed-off-by: uwla Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- documentation/content/tests.rst | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/documentation/content/tests.rst b/documentation/content/tests.rst index fac0bc334..ccfacc83d 100644 --- a/documentation/content/tests.rst +++ b/documentation/content/tests.rst @@ -9,6 +9,11 @@ Kw's tests rely on `shunit2`. The `run_tests.sh` script automatically detects can have shunit2 source code in `tests/` (you can clone it from https://github.com/kward/shunit2). +In order to run the integration tests, it is necessary to install Podman and to +configure it to run in `rootless` mode. Podman is available via the default +package manager of popular distros, such as Arch, Debian, Fedora and those based +on them. + If you want to run all the tests, try:: ./run_tests.sh @@ -21,5 +26,36 @@ Or run individual tests with:: ./run_tests.sh test TESTFILE1 ... +To limit the scope of the tests, pass the flag `--unit` or `--integration` as +the first argument to any of the examples above. So, the syntax is:: + + ./run_tests.sh [scope] [command] [args] + +Where `[scope]` can be `--unit` or `--integration`. The placeholder `[command]` +can be either `list`, `test` or simply omited in order to run all tests. Here +are some examples: + + ./run_tests.sh --unit # run all unit tests + ./run_tests.sh --unit list # list all unit tests + ./run_tests.sh --unit test device # test device unit test + ./run_tests.sh --integration # run all integration tests + ./run_tests.sh --integration list # list all integration tests + ./run_tests.sh --integration test device # test device integration test + ./run_tests.sh # run all tests + ./run_tests.sh list # list all tests + ./run_tests.sh test device # run all device tests + +The integration tests can take over 10 minutes to run in the first time because +podman is building the container images to be used in the tests, which requires +installing kw's dependencies in the supported distros. After the images have +been built and cached, running the integration tests should take only a few +seconds each time. + +Then, the local kw repo is copied to the containers and installed again, which +takes very few seconds. For optimization purposes, the containers are reused +accross tests. If you add a new commit or checkout to another branch, such that +HEAD points to another commit, the containers will be destroyed and created +again in order to install the current local version of kw. + Kw is already prepared to run tests, build the documentation and check the installation in the github workflow. From 67d04a1a78ab3e7b9234c5bdb699eb71df79bf72 Mon Sep 17 00:00:00 2001 From: uwla Date: Mon, 18 Dec 2023 23:59:48 -0300 Subject: [PATCH 018/128] run_tests: allow running tests with the same basename The run_tests script used a `strip_path` function which would store the basename of all files in the global variable TESTS. When running the tests, we would use the find command to get the path of a file matching the basename of the current tests, then would check if that file exists and run the tests. The problem with this approach is that it assumes all tests have unique basename. This is no longer the case: we now have the `config_test.sh` integration test in addition to the `config_test.sh` unit test, and the same for device test. The old approach caused errors when attempting to run integration and unit tests with the same file Running `./run_tests.sh --integration test device` would work. Running `./run_tests.sh --unit test device` would work. Running `./run_tests.sh test device` would fail. To prevent this, this commit replaces the `strip_path` function with the `set_tests` function, which stores the path of the test instead of its basename. When running the tests, we use the `basename` command on the test path to print out the basename of the current test, rather than getting the path of the test from the basename of the test. Also, the new approach uses regex to match specified tests when running `./run_test.sh test `. That is because the find command cannot handle complex regex, only wildcards, so we use grep's to match multiple test files via the provided regex. Reviewed-by: Rodrigo Siqueira Signed-off-by: uwla Signed-off-by: Rodrigo Siqueira --- run_tests.sh | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/run_tests.sh b/run_tests.sh index 147a99209..0a5cd44ab 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -71,9 +71,10 @@ function run_tests() local test_failure_list='' local test_dir local integration_tests_setup=0 # have we setup the environment for integration tests? + local current_test + local target - for current_test in "${TESTS[@]}"; do - target=$(find "$TESTS_DIR" -name "${current_test}*.sh" | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') + for target in "${TESTS[@]}"; do if [[ -f "$target" ]]; then # if we are running integration tests, we will set up the environment for @@ -89,6 +90,9 @@ function run_tests() printf '\n' fi + # Format the test name to be displayed in the output. + current_test="$(basename "$test_dir")/$(basename "$target" | sed 's/.sh//')" + say "Running test [${current_test}]" say "$SEPARATOR" ( @@ -126,13 +130,12 @@ function run_tests() } declare -a TESTS -function strip_path() +function set_tests() { - local base + local file TESTS=() for file in "$@"; do - base=$(basename "${file}") - TESTS+=("${base%.*}") + TESTS+=("${file}") done } @@ -149,22 +152,31 @@ check_files="$?" #shellcheck disable=SC2086 if [[ "$#" -eq 0 ]]; then files_list=$(find "$TESTS_DIR" -name '*_test.sh' | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') + # Note: Usually we want to use double-quotes on bash variables, however, # in this case we want a set of parameters instead of a single one. - strip_path $files_list + set_tests $files_list + # Set the environment variable LANGUAGE to `en_US.UTF_8` to avoid the host # locale settings from interfering in the tests. LANGUAGE=en_US.UTF_8 run_tests elif [[ "$1" == 'list' ]]; then index=0 files_list=$(find "$TESTS_DIR" -name '*_test.sh') - strip_path $files_list + set_tests $files_list for test_name in "${TESTS[@]}"; do ((index++)) say "$index) ${test_name}" done elif [[ "$1" == 'test' ]]; then - strip_path "${@:2}" + # We use a regex to filter files so we test multiple tests matching a desirable + # pattern. For example, we can run all config-related tests by providing the + # word config. We can also run both config unit test and config integration + # test with this approach. + regex="($(sed 's/ /|/g' <<< "${@:2}"))" + + files_list=$(find "$TESTS_DIR" | grep --perl-regexp "${regex}" | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') + set_tests $files_list LANGUAGE=en_US.UTF_8 run_tests else show_help From a0f8eab75e4b2a8bebeba72181fdc2c0197c7f37 Mon Sep 17 00:00:00 2001 From: uwla Date: Wed, 20 Dec 2023 10:01:20 -0300 Subject: [PATCH 019/128] documentation: dependencies: add device-module related dependencies The device module depends on `lscpi` and `ps`, which are available via the packages `pciutils` and `procps`. Normally these dependencies will already be installed by default, but we cannot assume they are, so add them to the dependency lists. Closes #1000 Reviewed-by: Rodrigo Siqueira Signed-off-by: uwla Signed-off-by: Rodrigo Siqueira --- documentation/dependencies/arch.dependencies | 2 ++ documentation/dependencies/debian.dependencies | 2 ++ documentation/dependencies/fedora.dependencies | 2 ++ 3 files changed, 6 insertions(+) diff --git a/documentation/dependencies/arch.dependencies b/documentation/dependencies/arch.dependencies index e66eed2fb..764099802 100644 --- a/documentation/dependencies/arch.dependencies +++ b/documentation/dependencies/arch.dependencies @@ -26,3 +26,5 @@ curl perl-xml-xpath coreutils b4 +procps-ng +pciutils diff --git a/documentation/dependencies/debian.dependencies b/documentation/dependencies/debian.dependencies index dd3906cbe..de5cc6e91 100644 --- a/documentation/dependencies/debian.dependencies +++ b/documentation/dependencies/debian.dependencies @@ -28,3 +28,5 @@ curl libxml-xpath-perl coreutils b4 +procps +pciutils diff --git a/documentation/dependencies/fedora.dependencies b/documentation/dependencies/fedora.dependencies index 71becf38d..f4471ff9d 100644 --- a/documentation/dependencies/fedora.dependencies +++ b/documentation/dependencies/fedora.dependencies @@ -24,3 +24,5 @@ curl perl-XML-XPath coreutils b4 +procps +pciutils From 1ad9d7b050af6c0481cce493a493bd2795db7495 Mon Sep 17 00:00:00 2001 From: JGBSouza Date: Wed, 15 Nov 2023 20:28:55 -0300 Subject: [PATCH 020/128] src: lib: lore: Change /tmp/ to /dev/shm dir To enable parallel processing of the patches kw used the slower option, /tmp/ directory, instead of /dev/shm/ directory. In this case, to speed up the processing, change the directory to /dev/shm. Also add unit test for the create_shared_memory_dir function. Reviewed-by: David Tadokoro Signed-off-by: JGBSouza Signed-off-by: David Tadokoro --- src/lib/kwlib.sh | 18 +++++++++++++++++ src/lib/lore.sh | 3 ++- tests/unit/lib/kwlib_test.sh | 38 ++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/lib/kwlib.sh b/src/lib/kwlib.sh index 2ccb6f5f1..74d5e1c99 100644 --- a/src/lib/kwlib.sh +++ b/src/lib/kwlib.sh @@ -4,6 +4,7 @@ include "${KW_LIB_DIR}/lib/kw_db.sh" include "${KW_LIB_DIR}/lib/kw_time_and_date.sh" ENV_DIR='envs' +KW_SHARED_MEMORY_DEFAULT_DIR='/dev/shm' # Array with compression programs accepted by tar declare -ga compression_programs=('gzip' 'bzip2' 'lzip' 'lzma' 'lzop' 'zstd' @@ -126,6 +127,23 @@ function show_verbose() [[ "$flag" == 'VERBOSE' ]] && say "$cmd" } +# This function creates a temporary shared memory directory to be used by +# concurrent processes. In case the default base directory defined in the global +# variable `@KW_SHARED_MEMORY_DEFAULT_DIR` is not available, the function uses +# the default base directory of `mktemp --directory` +# +# Returns: +# Outputs the path to the shared memory directory created. +function create_shared_memory_dir() +{ + if [[ -d "$KW_SHARED_MEMORY_DEFAULT_DIR" && -w "$KW_SHARED_MEMORY_DEFAULT_DIR" ]]; then + printf '%s' "$(mktemp --tmpdir="$KW_SHARED_MEMORY_DEFAULT_DIR" --directory)" + return + fi + + printf '%s' "$(mktemp --directory)" +} + # Checks if a directory is a kernel tree root # # @DIR A directory path diff --git a/src/lib/lore.sh b/src/lib/lore.sh index e03d28b92..0c39a0f18 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -433,7 +433,8 @@ function process_patchsets() local pids local i - shared_dir_for_parallelism=$(mktemp --directory) + shared_dir_for_parallelism=$(create_shared_memory_dir) + starting_index="$PATCHSETS_PROCESSED" count=0 i=0 diff --git a/tests/unit/lib/kwlib_test.sh b/tests/unit/lib/kwlib_test.sh index 49811e8f5..813708541 100755 --- a/tests/unit/lib/kwlib_test.sh +++ b/tests/unit/lib/kwlib_test.sh @@ -95,6 +95,22 @@ function teardownGitRepository() fi } +function setupKwSharedMemoryDefaultDir() +{ + KW_SHARED_MEMORY_DEFAULT_DIR="${SHUNIT_TMPDIR}/test/tmp_dir" + mkdir --parents "$KW_SHARED_MEMORY_DEFAULT_DIR" +} + +function teardownSharedMemoryDefaultDir() +{ + is_safe_path_to_remove "$KW_SHARED_MEMORY_DEFAULT_DIR" + if [[ "$?" == 0 ]]; then + rm --recursive "$KW_SHARED_MEMORY_DEFAULT_DIR" + else + fail 'It was not possible to remove TMP_DIR in the specified directory' + fi +} + function test_is_kernel_root() { is_kernel_root "$SHUNIT_TMPDIR" @@ -965,4 +981,26 @@ function test_show_verbose() assert_equals_helper 'Expected value of command' "$LINENO" "$cmd" "$output" } +function test_check_if_create_shared_memory_dir_creates_dir_in_kw_shared_memory_default_dir() +{ + local output + + setupKwSharedMemoryDefaultDir + + output=$(create_shared_memory_dir) + assertTrue "${LINENO}: Did not create directory at ${output}" "[[ -d ${output} ]]" + assertTrue "${LINENO}: Did not create directory at KW_SHARED_MEMORY_DEFAULT_DIR" '[[ $output =~ $KW_SHARED_MEMORY_DEFAULT_DIR ]]' + + teardownSharedMemoryDefaultDir +} + +function test_check_if_create_shared_memory_dir_creates_dir_in_default_mktemp_dir() +{ + local output + + output=$(create_shared_memory_dir) + assertTrue "${LINENO}: Did not create directory at ${output}" "[[ -d ${output} ]]" + assertTrue "${LINENO}: Did not create directory at /tmp/ dir" '[[ $output =~ /tmp/ ]]' +} + invoke_shunit From bdb99c983c71065c24218c0b841c05bb73baa120 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Tue, 5 Dec 2023 18:40:00 -0300 Subject: [PATCH 021/128] tests: unit: lib: lore: Anonymize unit tests The unit tests `test_pre_process_xml_result` and `test_process_patchsets` had personal information embedded in sampled data. In this context, substitute the personal information in the samples by anonymous information based on famous musicians. Note: I took the opportunity to revise both unit tests, specially the `test_process_patchsets` one. Before, the `is_introduction_patch` and `extract_metadata_from_patch_title` functions were not mocked. Not mocking them made the unit test highly coupled with their implementation. Reviewed-by: David Tadokoro Signed-off-by: JGBSouza Signed-off-by: David Tadokoro --- tests/unit/lib/lore_test.sh | 126 ++++++++----- .../lore/pre_processed_patches_sample-1 | 12 ++ .../lore/pre_processed_patches_sample-2 | 12 ++ .../samples/lore/query_result_sample-1.xml | 43 +++++ .../unit/samples/lore/query_result_sample.xml | 168 ------------------ 5 files changed, 152 insertions(+), 209 deletions(-) create mode 100644 tests/unit/samples/lore/pre_processed_patches_sample-1 create mode 100644 tests/unit/samples/lore/pre_processed_patches_sample-2 create mode 100644 tests/unit/samples/lore/query_result_sample-1.xml delete mode 100644 tests/unit/samples/lore/query_result_sample.xml diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index 0f1beb1c4..9869a55a0 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -18,7 +18,7 @@ function oneTimeSetUp() cp "${SAMPLES_DIR}/web/reduced_lore_page_1.html" "${CACHE_LORE_DIR}/lore_page_1.html" cp "${SAMPLES_DIR}/web/reduced_lore_page_2.html" "${CACHE_LORE_DIR}/lore_page_2.html" cp "${SAMPLES_DIR}/lore_sample.config" "${SHUNIT_TMPDIR}/lore.config" - cp "${SAMPLES_DIR}/lore/query_result_sample.xml" "${SHUNIT_TMPDIR}/query_result_sample.xml" + cp --recursive "${SAMPLES_DIR}/lore/." "${SHUNIT_TMPDIR}/samples" } function setUp() @@ -510,52 +510,96 @@ function test_pre_process_xml_result() local output local expected - output=$(pre_process_xml_result "${SHUNIT_TMPDIR}/query_result_sample.xml") - expected='David Tadokoro'$'\n' - expected+='davidbtadokoro@usp.br'$'\n' - expected+='[PATCH] drm/amdkfd: Add missing tba_hi programming on aldebaran'$'\n' - expected+=' href="http://lore.kernel.org/amd-gfx/20230809212615.137674-1-davidbtadokoro@usp.br/"'$'\n' - expected+='Rodrigo Siqueira'$'\n' - expected+='rodrigo.siqueira@amd.com'$'\n' - expected+='[PATCH] Revert "drm/amd/pm: resolve reboot exception for si oland"'$'\n' - expected+=' href="http://lore.kernel.org/amd-gfx/20230809190956.435068-2-rodrigo.siqueira@amd.com/"'$'\n' - expected+='Rodrigo Siqueira'$'\n' - expected+='rodrigo.siqueira@amd.com'$'\n' - expected+='[PATCH] drm/amdgpu: don'"'"'t allow userspace to create a doorbell BO'$'\n' - expected+=' href="http://lore.kernel.org/amd-gfx/20230809190956.435068-1-rodrigo.siqueira@amd.com/"' + output=$(pre_process_xml_result "${SHUNIT_TMPDIR}/samples/query_result_sample-1.xml") + expected=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-1") assert_equals_helper 'Wrong pre-processed result' "$LINENO" "$expected" "$output" } -function test_process_patchsets() +function test_process_patchsets_single_batch() { - local pre_processed_patches + local pre_processed_patches_sample local expected - pre_processed_patches='David Tadokoro'$'\n' - pre_processed_patches+='davidbtadokoro@usp.br'$'\n' - pre_processed_patches+='[PATCH] drm/amdkfd: Add missing tba_hi programming on aldebaran'$'\n' - pre_processed_patches+=' href="http://lore.kernel.org/amd-gfx/20230809212615.137674-1-davidbtadokoro@usp.br/"'$'\n' - pre_processed_patches+='Rodrigo Siqueira'$'\n' - pre_processed_patches+='rodrigo.siqueira@amd.com'$'\n' - pre_processed_patches+='[PATCH] Revert "drm/amd/pm: resolve reboot exception for si oland"'$'\n' - pre_processed_patches+=' href="http://lore.kernel.org/amd-gfx/20230809190956.435068-2-rodrigo.siqueira@amd.com/"'$'\n' - pre_processed_patches+='Rodrigo Siqueira'$'\n' - pre_processed_patches+='rodrigo.siqueira@amd.com'$'\n' - pre_processed_patches+='[PATCH] drm/amdgpu: don'"'"'t allow userspace to create a doorbell BO'$'\n' - pre_processed_patches+=' href="http://lore.kernel.org/amd-gfx/20230809190956.435068-1-rodrigo.siqueira@amd.com/"' - - list_of_mailinglist_patches=() - process_patchsets "$pre_processed_patches" - - assert_equals_helper 'There should be only 2 patchsets in the array' "$LINENO" 2 "${#list_of_mailinglist_patches[@]}" - - expected='David TadokoroƆdavidbtadokoro@usp.brƆ1Ɔ1Ɔdrm/amdkfd: Add missing tba_hi programming on aldebaranƆ' - expected+='http://lore.kernel.org/amd-gfx/20230809212615.137674-1-davidbtadokoro@usp.br/' - assert_equals_helper 'Wrong patchset at index 0' "$LINENO" "$expected" "${list_of_mailinglist_patches[0]}" - - expected='Rodrigo SiqueiraƆrodrigo.siqueira@amd.comƆ1Ɔ1Ɔdrm/amdgpu: don'"'"'t allow userspace to create a doorbell BOƆ' - expected+='http://lore.kernel.org/amd-gfx/20230809190956.435068-1-rodrigo.siqueira@amd.com/' - assert_equals_helper 'Wrong patchset at index 1' "$LINENO" "$expected" "${list_of_mailinglist_patches[1]}" + # shellcheck disable=SC2317 + function is_introduction_patch() + { + local patch_url="$1" + [[ "$patch_url" =~ introduction ]] && return 0 + return 1 + } + + # shellcheck disable=SC2317 + function extract_metadata_from_patch_title() + { + local patch_title="${1}${SEPARATOR_CHAR}" + local patch_url="$2" + local patchset_version="X${SEPARATOR_CHAR}" + local total_patches="X${SEPARATOR_CHAR}" + + printf '%s%s%s%s' "$patchset_version" "$total_patches" "$patch_title" "$patch_url" + } + + # Clear number of patchsets processed and data structure with patchsets + reset_current_lore_fetch_session + + # Process single batch + pre_processed_patches_sample=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-1") + process_patchsets "$pre_processed_patches_sample" + + assert_equals_helper 'Wrong number of patchsets processed' "$LINENO" 2 "$PATCHSETS_PROCESSED" + + expected='Gilberto GilƆgil.gil@mpb.brƆXƆXƆ[PATCH v3] Add Palco to MPBƆhttp://lore.kernel.org/mpb/introduction' + assert_equals_helper 'Wrong processed patchset (index 0)' "$LINENO" "$expected" "${list_of_mailinglist_patches[0]}" + + expected='David BowieƆmajor.tom@rock.ukƆXƆXƆ[RFC PATCH v12] Introduce Ziggy StardustƆhttp://lore.kernel.org/rock/introduction' + assert_equals_helper 'Wrong processed patchset (index 1)' "$LINENO" "$expected" "${list_of_mailinglist_patches[1]}" +} + +function test_process_patchsets_multiple_batches() +{ + local pre_processed_patches_sample + local expected + + # shellcheck disable=SC2317 + function is_introduction_patch() + { + local patch_url="$1" + [[ "$patch_url" =~ introduction ]] && return 0 + return 1 + } + + # shellcheck disable=SC2317 + function extract_metadata_from_patch_title() + { + local patch_title="${1}${SEPARATOR_CHAR}" + local patch_url="$2" + local patchset_version="X${SEPARATOR_CHAR}" + local total_patches="X${SEPARATOR_CHAR}" + + printf '%s%s%s%s' "$patchset_version" "$total_patches" "$patch_title" "$patch_url" + } + + # Clear number of patchsets processed and data structure with patchsets + reset_current_lore_fetch_session + + # Process first batch + pre_processed_patches_sample=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-1") + process_patchsets "$pre_processed_patches_sample" + + # Process second batch + pre_processed_patches_sample=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-2") + process_patchsets "$pre_processed_patches_sample" + + assert_equals_helper 'Wrong number of patchsets processed' "$LINENO" 3 "$PATCHSETS_PROCESSED" + + expected='Gilberto GilƆgil.gil@mpb.brƆXƆXƆ[PATCH v3] Add Palco to MPBƆhttp://lore.kernel.org/mpb/introduction' + assert_equals_helper 'Wrong processed patchset (index 0)' "$LINENO" "$expected" "${list_of_mailinglist_patches[0]}" + + expected='David BowieƆmajor.tom@rock.ukƆXƆXƆ[RFC PATCH v12] Introduce Ziggy StardustƆhttp://lore.kernel.org/rock/introduction' + assert_equals_helper 'Wrong processed patchset (index 1)' "$LINENO" "$expected" "${list_of_mailinglist_patches[1]}" + + expected='Seu JorgeƆseu.jorge@samba-pop.brƆXƆXƆ[RFC] Release MĆŗsicas para Churrasco Vol.1Ɔhttp://lore.kernel.org/samba-pop/introduction' + assert_equals_helper 'Wrong processed patchset (index 2)' "$LINENO" "$expected" "${list_of_mailinglist_patches[2]}" } function test_reset_current_lore_fetch_session() diff --git a/tests/unit/samples/lore/pre_processed_patches_sample-1 b/tests/unit/samples/lore/pre_processed_patches_sample-1 new file mode 100644 index 000000000..10a33b289 --- /dev/null +++ b/tests/unit/samples/lore/pre_processed_patches_sample-1 @@ -0,0 +1,12 @@ +Gilberto Gil +gil.gil@mpb.br +[PATCH v3] Add Palco to MPB + href="http://lore.kernel.org/mpb/introduction" +Tim Maia +tim.maia@soul.br +[PATCH 3/9] tim-maia/racional: Add Bom Senso to album + href="http://lore.kernel.org/soul/sequel" +David Bowie +major.tom@rock.uk +[RFC PATCH v12] Introduce Ziggy Stardust + href="http://lore.kernel.org/rock/introduction" diff --git a/tests/unit/samples/lore/pre_processed_patches_sample-2 b/tests/unit/samples/lore/pre_processed_patches_sample-2 new file mode 100644 index 000000000..87c974c79 --- /dev/null +++ b/tests/unit/samples/lore/pre_processed_patches_sample-2 @@ -0,0 +1,12 @@ +Bob Marley +bob.marley@reggae.jm +[PATCH v2 7/10] bob-marley/survavil: Add One Drop to album + href="http://lore.kernel.org/reggae/sequel" +Charlie Brown Jr. +charlie.brown@punk.br +[PATCH 3/13] cbj/camisa10: Add Só os Loucos Sabem to album + href="http://lore.kernel.org/punk/sequel" +Seu Jorge +seu.jorge@samba-pop.br +[RFC] Release MĆŗsicas para Churrasco Vol.1 + href="http://lore.kernel.org/samba-pop/introduction" diff --git a/tests/unit/samples/lore/query_result_sample-1.xml b/tests/unit/samples/lore/query_result_sample-1.xml new file mode 100644 index 000000000..316e8a71f --- /dev/null +++ b/tests/unit/samples/lore/query_result_sample-1.xml @@ -0,0 +1,43 @@ + + + + + Gilberto Gil + gil.gil@mpb.br + + [PATCH v3] Add Palco to MPB + 2023-08-09T21:27:00Z + + urn:uuid:2f9fa3da-2057-86a4-aa20-9ad0239ff7a3 + + ... + + + + + Tim Maia + tim.maia@soul.br + + [PATCH 3/9] tim-maia/racional: Add Bom Senso to album + 2023-08-09T19:10:26Z + + urn:uuid:66fe77b1-55ad-6670-73ee-54e933cf5f63 + + + ... + + + + + David Bowie + major.tom@rock.uk + + [RFC PATCH v12] Introduce Ziggy Stardust + 2023-08-09T19:10:22Z + + urn:uuid:b09294a9-df54-a8b1-cf19-6f58c2febdd3 + + ... + + + \ No newline at end of file diff --git a/tests/unit/samples/lore/query_result_sample.xml b/tests/unit/samples/lore/query_result_sample.xml deleted file mode 100644 index fd4ef0eed..000000000 --- a/tests/unit/samples/lore/query_result_sample.xml +++ /dev/null @@ -1,168 +0,0 @@ - - - rt:8.day.ago.. AND NOT s:Re - search results - - - urn:uuid:1e2607f0-9e95-992c-5330-cac14ca56190 - 2023-08-09T22:09:53Z - - - David Tadokoro - davidbtadokoro@usp.br - - [PATCH] drm/amdkfd: Add missing tba_hi programming on aldebaran - 2023-08-09T21:27:00Z - - urn:uuid:2f9fa3da-2057-86a4-aa20-9ad0239ff7a3 - -
-
Previously asymptomatic because high 32 bits were zero.
-
-Fixes: 615222cfed20 ("drm/amdkfd: Relocate TBA/TMA to opposite side of VM hole")
-Signed-off-by: David Tadokoro <davidbtadokoro@usp.br>
----
- drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c | 1 +
- 1 file changed, 1 insertion(+)
-
-					diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c
-index 8fda16e6fee6..8ce6f5200905 100644
---- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c
-+++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c
-					
-					@@ -121,6 +121,7 @@ static int pm_map_process_aldebaran(struct packet_manager *pm,
-					 	packet->sh_mem_bases = qpd->sh_mem_bases;
- 	if (qpd->tba_addr) {
- 		packet->sq_shader_tba_lo = lower_32_bits(qpd->tba_addr >> 8);
-					+		packet->sq_shader_tba_hi = upper_32_bits(qpd->tba_addr >> 8);
-					 		packet->sq_shader_tma_lo = lower_32_bits(qpd->tma_addr >> 8);
- 		packet->sq_shader_tma_hi = upper_32_bits(qpd->tma_addr >> 8);
- 	}
--- 
-2.25.1
-
-				
-
-
-
- - - Rodrigo Siqueira - rodrigo.siqueira@amd.com - - [PATCH] Revert "drm/amd/pm: resolve reboot exception for si oland" - 2023-08-09T19:10:26Z - - urn:uuid:66fe77b1-55ad-6670-73ee-54e933cf5f63 - - -
-
This reverts commit e490d60a2f76bff636c68ce4fe34c1b6c34bbd86.
-
-This causes hangs on SI when DC is enabled.
-
-Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2755
-Signed-off-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
----
- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 29 ++++++++++++++++++++++
- 1 file changed, 29 insertions(+)
-
-					diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
-index 02e69ccff3ba..d6d9e3b1b2c0 100644
---- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
-+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
-					
-					@@ -6925,6 +6925,23 @@ static int si_dpm_enable(struct amdgpu_device *adev)
-					 	return 0;
- }
- 
-					+static int si_set_temperature_range(struct amdgpu_device *adev)
-+{
-+	int ret;
-+
-+	ret = si_thermal_enable_alert(adev, false);
-+	if (ret)
-+		return ret;
-+	ret = si_thermal_set_temperature_range(adev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
-+	if (ret)
-+		return ret;
-+	ret = si_thermal_enable_alert(adev, true);
-+	if (ret)
-+		return ret;
-+
-+	return ret;
-+}
-+
-					 static void si_dpm_disable(struct amdgpu_device *adev)
- {
- 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
-					@@ -7609,6 +7626,18 @@ static int si_dpm_process_interrupt(struct amdgpu_device *adev,
-					 
- static int si_dpm_late_init(void *handle)
- {
-					+	int ret;
-+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-+
-+	if (!adev->pm.dpm_enabled)
-+		return 0;
-+
-+	ret = si_set_temperature_range(adev);
-+	if (ret)
-+		return ret;
-+#if 0 //TODO ?
-+	si_dpm_powergate_uvd(adev, true);
-+#endif
-					 	return 0;
- }
- 
--- 
-2.41.0
-
-				
-
-
-
- - - Rodrigo Siqueira - rodrigo.siqueira@amd.com - - [PATCH] drm/amdgpu: don't allow userspace to create a doorbell BO - 2023-08-09T19:10:22Z - - urn:uuid:b09294a9-df54-a8b1-cf19-6f58c2febdd3 - -
-
We need the domains in amdgpu_drm.h for the kernel driver to manage
-the pool, but we don't want userspace using it until the code
-is ready.  So reject for now.
-
-Signed-off-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
----
- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-					diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
-index 693b1fd1191a..ca4d2d430e28 100644
---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
-+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
-					
-					@@ -289,6 +289,10 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
-					 	uint32_t handle, initial_domain;
- 	int r;
- 
-					+	/* reject DOORBELLs until userspace code to use it is available */
-+	if (args->in.domains & AMDGPU_GEM_DOMAIN_DOORBELL)
-+		return -EINVAL;
-+
-					 	/* reject invalid gem flags */
- 	if (flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- 		      AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
--- 
-2.41.0
-
-				
-
-
-
-
\ No newline at end of file From a97d37fef41f8b7c47a490a61aace58b58356071 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Fri, 24 Nov 2023 14:56:16 -0300 Subject: [PATCH 022/128] src: lib: lore: Fix duplication when listing patchsets Listing patches off any mailing list could result in duplicated patches being displayed unnecessarily. In this sense, solve the problem by checking if the patch already has been processed. Reviewed-by: David Tadokoro Signed-off-by: JGBSouza Signed-off-by: David Tadokoro --- src/lib/lore.sh | 11 +++++++-- tests/unit/lib/lore_test.sh | 23 ++++++++++++++++++ .../pre_processed_patches_sample-repeated | 24 +++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 tests/unit/samples/lore/pre_processed_patches_sample-repeated diff --git a/src/lib/lore.sh b/src/lib/lore.sh index 0c39a0f18..a0de19a6d 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -63,6 +63,10 @@ declare -g MIN_INDEX=0 # it easy to undertand. declare -ag list_of_mailinglist_patches +# This associative array stores the current processed patchsets and it is used +# to check if a given patchset was already processed. +declare -Ag processed_patchsets + # This function creates the directory used by kw for any lore related data. # # Return: @@ -317,6 +321,8 @@ function reset_current_lore_fetch_session() list_of_mailinglist_patches=() PATCHSETS_PROCESSED=0 MIN_INDEX=0 + unset processed_patchsets + declare -Ag processed_patchsets } # This function composes a query URL to a public mailing list archived @@ -443,13 +449,14 @@ function process_patchsets() if [[ "$line" =~ ^[[:space:]]href= ]]; then patch_url=$(str_get_value_under_double_quotes "$line") - if is_introduction_patch "$patch_url"; then - # Process each patch in parallel + if [[ "${processed_patchsets["$patch_url"]}" != 1 ]] && is_introduction_patch "$patch_url"; then + # Processes each patch in parallel thread_for_process_patch "$PATCHSETS_PROCESSED" "$shared_dir_for_parallelism" \ "$processed_patchset" "$patch_url" "$patch_title" & pids[i]="$!" ((i++)) ((PATCHSETS_PROCESSED++)) + processed_patchsets["$patch_url"]=1 fi processed_patchset='' diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index 9869a55a0..df4335968 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -602,6 +602,23 @@ function test_process_patchsets_multiple_batches() assert_equals_helper 'Wrong processed patchset (index 2)' "$LINENO" "$expected" "${list_of_mailinglist_patches[2]}" } +function test_process_patchsets_repeated_patches() +{ + local pre_processed_patches_sample + local expected + + # Clear number of patchsets processed and data structure with patchsets + reset_current_lore_fetch_session + + # Process list of repeated pre processed patches + pre_processed_patches_sample=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-repeated") + process_patchsets "$pre_processed_patches_sample" + assert_equals_helper 'Repeated patches should not be processed again' "$LINENO" 1 "$PATCHSETS_PROCESSED" + + expected='David BowieƆmajor.tom@rock.ukƆXƆXƆ[RFC PATCH v12] Introduce Ziggy StardustƆhttp://lore.kernel.org/rock/introduction' + assert_equals_helper 'Wrong processed patchset (index 0)' "$LINENO" "$expected" "${list_of_mailinglist_patches[0]}" +} + function test_reset_current_lore_fetch_session() { list_of_mailinglist_patches[0]=1 @@ -610,10 +627,16 @@ function test_reset_current_lore_fetch_session() PATCHSETS_PROCESSED=3 MIN_INDEX=200 + declare -Ag processed_patchsets + processed_patchsets['patch_1']=1 + processed_patchsets['patch_2']=1 + processed_patchsets['patch_3']=1 + reset_current_lore_fetch_session 2 assert_equals_helper 'Should reset `list_of_mailinglist_patches`' "$LINENO" 0 "${#list_of_mailinglist_patches[@]}" assert_equals_helper 'Should reset `PATCHSETS_PROCESSED`' "$LINENO" 0 "$PATCHSETS_PROCESSED" assert_equals_helper 'Should reset `MIN_INDEX`' "$LINENO" 0 "$MIN_INDEX" + assert_equals_helper 'Should reset `processed_patchsets`' "$LINENO" 0 "${#processed_patchsets[@]}" } function test_format_patchsets() diff --git a/tests/unit/samples/lore/pre_processed_patches_sample-repeated b/tests/unit/samples/lore/pre_processed_patches_sample-repeated new file mode 100644 index 000000000..0477ec8a9 --- /dev/null +++ b/tests/unit/samples/lore/pre_processed_patches_sample-repeated @@ -0,0 +1,24 @@ +David Bowie +major.tom@rock.uk +[RFC PATCH v12] Introduce Ziggy Stardust + href="http://lore.kernel.org/rock/introduction" +David Bowie +major.tom@rock.uk +[RFC PATCH v12] Introduce Ziggy Stardust + href="http://lore.kernel.org/rock/introduction" +David Bowie +major.tom@rock.uk +[RFC PATCH v12] Introduce Ziggy Stardust + href="http://lore.kernel.org/rock/introduction" +David Bowie +major.tom@rock.uk +[RFC PATCH v12] Introduce Ziggy Stardust + href="http://lore.kernel.org/rock/introduction" +David Bowie +major.tom@rock.uk +[RFC PATCH v12] Introduce Ziggy Stardust + href="http://lore.kernel.org/rock/introduction" +David Bowie +major.tom@rock.uk +[RFC PATCH v12] Introduce Ziggy Stardust + href="http://lore.kernel.org/rock/introduction" \ No newline at end of file From d4c7dcc9025b73642f40a7eaf8b972f12b3cdc38 Mon Sep 17 00:00:00 2001 From: JGBSouza Date: Fri, 8 Dec 2023 11:38:50 -0300 Subject: [PATCH 023/128] src: ui: patch_hub: patchset_details_and_actions: Add bookmarking info Bookmarking patches didn't show any information about where the patchset was going to be downloaded. To solve this problem, add a checkbox message when the patchset is bookmarked or removed so the user can be sure where to find it or that it was removed. Reviewed-by: David Tadokoro Signed-off-by: JGBSouza Signed-off-by: David Tadokoro --- src/ui/patch_hub/patchset_details_and_actions.sh | 13 +++++++++++++ .../patch_hub/patchset_details_and_actions_test.sh | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/ui/patch_hub/patchset_details_and_actions.sh b/src/ui/patch_hub/patchset_details_and_actions.sh index fdea347ad..aeec17d41 100644 --- a/src/ui/patch_hub/patchset_details_and_actions.sh +++ b/src/ui/patch_hub/patchset_details_and_actions.sh @@ -149,6 +149,7 @@ function handle_bookmark_action() { local -n _patchset="$1" local raw_patchset="$2" + local message_box local output local loading_pid local ret @@ -156,6 +157,7 @@ function handle_bookmark_action() output=$(download_series "${_patchset['patchset_url']}" "${lore_config['save_patches_to']}") if [[ "$?" != 0 ]]; then create_message_box 'Error' 'Could not download patchset:'$'\n'"- ${_patchset['patchset_title']}"$'\n'"[error message] ${output}" + return fi create_async_loading_screen_notification 'Bookmarking patchset'$'\n'"- ${_patchset['patchset_title']}" & @@ -166,7 +168,12 @@ function handle_bookmark_action() stop_async_loading_screen_notification "$loading_pid" if [[ "$ret" != 0 ]]; then create_message_box 'Error' 'Could not bookmark patchset'$'\n'"- ${_patchset['patchset_title']}" + return fi + + message_box='Bookmarked patchset:'$'\n'"- ${_patchset['patchset_title']}"$'\n'$'\n' + message_box+='Downloaded mbox file to:'$'\n'"$output" + create_message_box 'Success' "$message_box" } # Handler of the 'remove bookmark' action. This function removes the patchset @@ -176,14 +183,20 @@ function handle_bookmark_action() function handle_remove_bookmark_action() { local -n _patchset="$1" + local message_box delete_series_from_local_storage "${lore_config['save_patches_to']}" "${_patchset['patchset_url']}" if [[ "$?" != 0 ]]; then create_message_box 'Warning' 'Could not delete patchset .mbx file'$'\n'"- ${_patchset['patchset_title']}" + return fi remove_patchset_from_bookmark_by_url "${_patchset['patchset_url']}" if [[ "$?" != 0 ]]; then create_message_box 'Error' 'Could not unbookmark patchset'$'\n'"- ${_patchset['patchset_title']}" + return fi + + message_box='Removed bookmark from patchset:'$'\n'"- ${_patchset['patchset_title']}"$'\n'$'\n' + create_message_box 'Success' "$message_box" } diff --git a/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh b/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh index 9f25f25c0..692e1b2a6 100755 --- a/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh +++ b/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh @@ -153,6 +153,12 @@ test_handle_bookmark_action() declare -A patchset local output + # shellcheck disable=SC2317 + function create_message_box() + { + return 0 + } + # shellcheck disable=SC2317 function create_async_loading_screen_notification() { @@ -189,6 +195,12 @@ test_handle_remove_bookmark_action() local mbx_file_path local output + # shellcheck disable=SC2317 + function create_message_box() + { + return 0 + } + patchset['patchset_url']='https://lore.kernel.org/amd-gfx/20230622215735.2026220-1-Rodrigo.Siqueira@amd.com/' lore_config['save_patches_to']="$SHUNIT_TMPDIR" mbx_file_path="${lore_config['save_patches_to']}/20230622215735.2026220-1-Rodrigo.Siqueira@amd.com.mbx" From 1764e42f81e2577c313a1df654d67dc4b8f7acca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Gabriel=20Josephik?= Date: Mon, 11 Dec 2023 11:40:43 -0300 Subject: [PATCH 024/128] src: deploy: fix preparation of remote directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the temporary directory already existed, it would not be cleaned up. This could cause issues if multiples deploys were made without rebooting the target. In this context, the code now removes the temporary directory and creates it again. Co-authored-by: uwla Signed-off-by: JoĆ£o Gabriel Josephik Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/deploy.sh | 2 ++ tests/unit/deploy_test.sh | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/deploy.sh b/src/deploy.sh index 4acd66b79..46070c739 100644 --- a/src/deploy.sh +++ b/src/deploy.sh @@ -574,6 +574,8 @@ function prepare_remote_dir() cmd_manager "$flag" "$cmd" fi + # Removes temporary directory if already existent + cmd_remotely "rm --preserve-root=all --recursive --force -- ${KW_DEPLOY_TMP_FILE}" "$flag" # Create temporary folder cmd_remotely "mkdir -p $KW_DEPLOY_TMP_FILE" "$flag" } diff --git a/tests/unit/deploy_test.sh b/tests/unit/deploy_test.sh index 2efca3f0b..1864847eb 100755 --- a/tests/unit/deploy_test.sh +++ b/tests/unit/deploy_test.sh @@ -889,6 +889,7 @@ function test_prepare_remote_dir() # Test 1: Normal remote prepare declare -a expected_cmd=( "$debian_sync_files_cmd" + "${CONFIG_SSH} ${CONFIG_REMOTE} sudo \"rm --preserve-root=all --recursive --force -- ${KW_DEPLOY_TMP_FILE}\"" "$CONFIG_SSH $CONFIG_REMOTE sudo \"mkdir -p $KW_DEPLOY_TMP_FILE\"" ) @@ -901,6 +902,7 @@ function test_prepare_remote_dir() arch_sync_files_cmd="$rsync_quiet $scripts_path/$to_copy $CONFIG_REMOTE:$REMOTE_KW_DEPLOY $STD_RSYNC_FLAG --archive" declare -a expected_cmd=( "$arch_sync_files_cmd" + "${CONFIG_SSH} ${CONFIG_REMOTE} sudo \"rm --preserve-root=all --recursive --force -- ${KW_DEPLOY_TMP_FILE}\"" "$CONFIG_SSH $CONFIG_REMOTE sudo \"mkdir -p $KW_DEPLOY_TMP_FILE\"" "$CONFIG_RSYNC $KW_ETC_DIR/template_mkinitcpio.preset $CONFIG_REMOTE:$REMOTE_KW_DEPLOY $STD_RSYNC_FLAG" ) @@ -919,6 +921,7 @@ function test_prepare_remote_dir() "$UPDATE_KW_REMOTE_MSG" "$CONFIG_SSH $CONFIG_REMOTE sudo \"mkdir -p $REMOTE_KW_DEPLOY\"" "scp -q $scripts_path/$to_copy $CONFIG_REMOTE:$REMOTE_KW_DEPLOY" + "${CONFIG_SSH} ${CONFIG_REMOTE} sudo \"rm --preserve-root=all --recursive --force -- ${KW_DEPLOY_TMP_FILE}\"" "$CONFIG_SSH $CONFIG_REMOTE sudo \"mkdir -p $KW_DEPLOY_TMP_FILE\"" ) From 07d895f17f1ac097c24f7c07c0e6dd1b4fb4dd47 Mon Sep 17 00:00:00 2001 From: Xpto Lala Date: Fri, 15 Dec 2023 17:23:45 -0300 Subject: [PATCH 025/128] src: help.sh: show correct version on repo mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When running on repo-mode, KW did not show up the correct version because it was simply running `cat` on a file. This works in normal installations because the `kw` installed version is copied to a static file during the installation. In repo-mode such information is dynamic, not static. In this case, it is necessary to run other commands. Also, call `kworkflow_function` in `setup.sh` to avoid code duplication. Before, `setup.sh` would run the same commands as in `src/help.sh`. Furthermore, add a unit test for kw version on repo mode. Closes #986 Signed-off-by: uwla Co-authored-by: JoĆ£o Gabriel Josephik Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- setup.sh | 15 ++---------- src/help.sh | 38 +++++++++++++++++++++++++++-- tests/unit/help_test.sh | 53 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 15 deletions(-) diff --git a/setup.sh b/setup.sh index ccb4f7957..3ee47fbd0 100755 --- a/setup.sh +++ b/setup.sh @@ -4,6 +4,7 @@ KW_LIB_DIR='src' include "${KW_LIB_DIR}/lib/kwio.sh" include "${KW_LIB_DIR}/lib/kwlib.sh" include "${KW_LIB_DIR}/lib/kw_db.sh" +include "${KW_LIB_DIR}/help.sh" SILENT=1 VERBOSE=0 @@ -487,19 +488,7 @@ function safe_remove() function update_version() { - local head_hash - local branch_name - local base_version - - head_hash=$(git rev-parse --short HEAD) - branch_name=$(git rev-parse --short --abbrev-ref HEAD) - base_version=$(head -n 1 "$libdir/VERSION") - - cat > "$libdir/VERSION" << EOF -$base_version -Branch: $branch_name -Commit: $head_hash -EOF + kworkflow_version_from_repo > "${libdir}/VERSION" } function install_home() diff --git a/src/help.sh b/src/help.sh index 0ae1a5ad7..b3c1eed09 100644 --- a/src/help.sh +++ b/src/help.sh @@ -68,9 +68,43 @@ function kworkflow_man() exit 2 # ENOENT } +# This function is invoked in two situations: ./setup.sh and if kw is running +# from the repository. In the setup.sh script, KW_LIB_DIR is set to 'src,' and +# in the kw file, when running in the repo, this variable is set to +# "${KW_BASE_DIR}/src". In both cases we are dealing with kw repository. +# +# Return: +# Print the version information in the stdout. +function kworkflow_version_from_repo() +{ + local head_hash + local branch_name + local base_version + local git_dir + + # get version info from the git repo + git_dir=$(realpath "${KW_LIB_DIR}/../.git") + head_hash=$(git -C "${git_dir}" rev-parse --short HEAD) + branch_name=$(git -C "${git_dir}" rev-parse --short --abbrev-ref HEAD) + base_version=$(head --lines 1 "${KW_LIB_DIR}/VERSION") + + printf '%s\nBranch: %s\nCommit: %s\n' "${base_version}" "${branch_name}" "${head_hash}" +} + +# Get kw version from the VERSION file generated during the installation time, +# or get it dynamically if this command is executed directly from kw repository +# with './kw [OPTION]'. +# +# Return: +# Return kw version function kworkflow_version() { - local version_path="$KW_LIB_DIR/VERSION" + local version_path="${KW_LIB_DIR}/VERSION" + + if [[ "${KW_REPO_MODE}" == 'y' ]]; then + kworkflow_version_from_repo + return + fi - cat "$version_path" + printf '%s\n' "$(< "$version_path")" } diff --git a/tests/unit/help_test.sh b/tests/unit/help_test.sh index 8f76e292c..ddc281b1e 100755 --- a/tests/unit/help_test.sh +++ b/tests/unit/help_test.sh @@ -32,4 +32,57 @@ function test_kworkflow_man() assertEquals "($LINENO) We expected an error message." "$expect" "$output" } +function test_kworkflow_version_in_repomode() +{ + local branch_name + local head_hash + local version_name + local output + local original_path + local path_to_git_repository + local KW_REPO_MODE + local KW_LIB_DIR + + # Initialize variables. + original_path="$PWD" + version_name='omega' + branch_name='foo' + path_to_git_repository="${SHUNIT_TMPDIR}/git_repo" + KW_LIB_DIR="${path_to_git_repository}/src" + + # shellcheck disable=SC2034 + KW_REPO_MODE='y' # used to trigger repo-mode behavior + + # create the git repository + mkdir --parents "${KW_LIB_DIR}" + + # cd into the repo, so we can run git commands there. + # This is necessary because our helper `mk_fake_git` assumes the current + # working directory is the directory in which we want to run git commands. + cd "${path_to_git_repository}" || fail 'Failed to switch to git dir.' + + # print kw's version name + printf '%s\n' "${version_name}" > "${KW_LIB_DIR}/VERSION" + + # Make fake git commits from the created branch. + mk_fake_git + + # Create and switch to a new branch + git switch --quiet --create "${branch_name}" + + # Get commit hash. + head_hash=$(git rev-parse --short HEAD) + + # Get kw version. + output=$(kworkflow_version) + + # Compare results. + assert_substring_match 'Wrong version name' "(${LINENO})" "${version_name}" "${output}" + assert_substring_match 'Wrong commit' "(${LINENO})" "Commit: ${head_hash}" "${output}" + assert_substring_match 'Wrong branch' "(${LINENO})" "Branch: ${branch_name}" "${output}" + + # Go back to previous dir. + cd "$original_path" || fail 'Failed to switch back to original directory.' +} + invoke_shunit From ff706fa612462c47eab7d0c105f579bd3d3054a7 Mon Sep 17 00:00:00 2001 From: uwla Date: Fri, 5 Jan 2024 16:37:53 -0300 Subject: [PATCH 026/128] tests: unit: help: add tests for kw --version Add unit tests for kw version under normal installation. Also, the repo-mode message is now sent to stderr. That way, it can be easily ignored with a simple redirection to /dev/null. This can be useful in future integration tests which may run kw in repo-mode. Otherwise, the output would always be messed up by the repo-mode message and have to be filtered out in every test. Signed-off-by: uwla Signed-off-by: Rodrigo Siqueira Reviewed-by: Rodrigo Siqueira --- kw | 7 ++++++- tests/unit/help_test.sh | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/kw b/kw index 2b3bbd7c0..9a0693688 100755 --- a/kw +++ b/kw @@ -91,7 +91,12 @@ if [[ "${KW_REPO_MODE}" == 'y' ]]; then repo_mode_msg+=$'\t'"KW_PLUGINS_DIR=${KW_PLUGINS_DIR}"$'\n' repo_mode_msg+=$'\t'"KW_SOUND_DIR=${KW_SOUND_DIR}"$'\n'$'\n' repo_mode_msg+="${SEPARATOR}" - say "${repo_mode_msg}" + + # Message is redirected to stderr such that it can be easily ignored if needed. + # Otherwise, it could mess up the output expected by integration tests which + # are runnning kw in repo-mode and the tests would fail (we may eventually want + # such tests because in repo-mode we can execute kw without installing it). + say "${repo_mode_msg}" >&2 fi function kw() diff --git a/tests/unit/help_test.sh b/tests/unit/help_test.sh index ddc281b1e..46f8daa2b 100755 --- a/tests/unit/help_test.sh +++ b/tests/unit/help_test.sh @@ -32,6 +32,25 @@ function test_kworkflow_man() assertEquals "($LINENO) We expected an error message." "$expect" "$output" } +function test_kworkflow_version() +{ + local KW_LIB_DIR + local output + local expected_output + + # the mocked version for KW + expected_output=$(printf 'beta\nBranch: bazz\nCommit: ffddee\n') + + # this value mocks a fake location for the version file, which is the file used + # by KW to get information about the current version. + KW_LIB_DIR="${SHUNIT_TMPDIR}" + printf '%s' "${expected_output}" > "${KW_LIB_DIR}/VERSION" + + # check output + output=$(kworkflow_version) + assert_equals_helper 'Got wrong kw version.' "(${LINENO})" "${expected_output}" "${output}" +} + function test_kworkflow_version_in_repomode() { local branch_name From 3bc9eb2a0c4f6b7740167a2ee0caad6fe70fbf4e Mon Sep 17 00:00:00 2001 From: Marcelo Mendes Spessoto Junior Date: Wed, 3 Jan 2024 19:48:11 -0300 Subject: [PATCH 027/128] documentation: dependencies: Add libnotify dependency Signed-off-by: Marcelo Mendes Spessoto Junior Signed-off-by: Rodrigo Siqueira Reviewed-by: Rodrigo Siqueira --- documentation/dependencies/arch.dependencies | 1 + documentation/dependencies/debian.dependencies | 1 + documentation/dependencies/fedora.dependencies | 1 + 3 files changed, 3 insertions(+) diff --git a/documentation/dependencies/arch.dependencies b/documentation/dependencies/arch.dependencies index 764099802..efc867963 100644 --- a/documentation/dependencies/arch.dependencies +++ b/documentation/dependencies/arch.dependencies @@ -28,3 +28,4 @@ coreutils b4 procps-ng pciutils +libnotify diff --git a/documentation/dependencies/debian.dependencies b/documentation/dependencies/debian.dependencies index de5cc6e91..aa007671f 100644 --- a/documentation/dependencies/debian.dependencies +++ b/documentation/dependencies/debian.dependencies @@ -30,3 +30,4 @@ coreutils b4 procps pciutils +libnotify-bin diff --git a/documentation/dependencies/fedora.dependencies b/documentation/dependencies/fedora.dependencies index f4471ff9d..0db41fb56 100644 --- a/documentation/dependencies/fedora.dependencies +++ b/documentation/dependencies/fedora.dependencies @@ -26,3 +26,4 @@ coreutils b4 procps pciutils +libnotify From 848252264da8d22b812155b7b1f3b0008e5210c7 Mon Sep 17 00:00:00 2001 From: jppaulo Date: Thu, 11 Jan 2024 13:43:04 -0300 Subject: [PATCH 028/128] documentation: dependencies: fedora: Fix procps dependency in fedora MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In fedora distro, when installing kw with setup.sh, it is always requested to install the package procps, even when it's already installed. The problem is that the command `rpm -q procps` seems to specifically not recognize that this package is already installed. However, with `rpm -q procps-ng` (which is the same exact package) it works fine. So, change the dependency to 'procps-ng' instead of 'procps' to fix this problem. Fixes: #1010 Signed-off-by: JoĆ£o Paulo Pereira da Silva Signed-off-by: Rodrigo Siqueira Reviewed-by: Rodrigo Siqueira --- documentation/dependencies/fedora.dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/dependencies/fedora.dependencies b/documentation/dependencies/fedora.dependencies index 0db41fb56..770a68e84 100644 --- a/documentation/dependencies/fedora.dependencies +++ b/documentation/dependencies/fedora.dependencies @@ -24,6 +24,6 @@ curl perl-XML-XPath coreutils b4 -procps +procps-ng pciutils libnotify From 57f23ab7996ac96cba3353cc3555ff5a42e00038 Mon Sep 17 00:00:00 2001 From: jppaulo Date: Wed, 10 Jan 2024 19:17:32 -0300 Subject: [PATCH 029/128] src: config: Fix values with space separation in `kw config` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When manually configuring kw with `kw config`, it does not accept configurations with space separation, even with single ou double quotes put. For example, the command `kw config notification.sound_alert_command 'paplay berimbau.wav'` will result in the wrong configuration `notification.sound_alert_command=paplay` Because of that, change `kw config` to receive the value as all characters after the first space following configuration name, instead of just the first word. Fixes: #1008 Signed-off-by: JoĆ£o Paulo Pereira da Silva Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.sh b/src/config.sh index 6cae6c5da..7a8d4fe83 100644 --- a/src/config.sh +++ b/src/config.sh @@ -66,7 +66,7 @@ function config_main() target_config_file=$(printf '%s' "$parameters" | cut -d '.' -f 1) option_and_value="${parameters#*.}" option=$(printf '%s' "$option_and_value" | cut -d ' ' -f 1) - value=$(printf '%s' "$option_and_value" | cut -d ' ' -f 2) + value=$(printf '%s' "$option_and_value" | cut -d ' ' -f 2-) if [[ "${options_values['SCOPE']}" == 'global' ]]; then base_path="${KW_ETC_DIR}" From d8239a12118c12b6ca301b1f9b4cbaea165cb690 Mon Sep 17 00:00:00 2001 From: uwla Date: Thu, 11 Jan 2024 21:39:44 -0300 Subject: [PATCH 030/128] documentation: content: tests: add instructions for rootless containers Provide instructions for setting up podman to run in rootless mode. Also, fix a codeblock in `tests.rst` which was not correctly formatted and was displayed as inline instead of multiline. Signed-off-by: uwla Signed-off-by: Rodrigo Siqueira Reviewed-by: Rodrigo Siqueira --- documentation/content/tests.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/documentation/content/tests.rst b/documentation/content/tests.rst index ccfacc83d..2f7bcc7ac 100644 --- a/documentation/content/tests.rst +++ b/documentation/content/tests.rst @@ -10,9 +10,10 @@ can have shunit2 source code in `tests/` (you can clone it from https://github.com/kward/shunit2). In order to run the integration tests, it is necessary to install Podman and to -configure it to run in `rootless` mode. Podman is available via the default -package manager of popular distros, such as Arch, Debian, Fedora and those based -on them. +configure it to run in rootless mode as explained in the official documentation: +https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md. +Podman is available via the default package manager of popular distros, such as +Arch, Debian, Fedora and those based on them. If you want to run all the tests, try:: @@ -35,6 +36,8 @@ Where `[scope]` can be `--unit` or `--integration`. The placeholder `[command]` can be either `list`, `test` or simply omited in order to run all tests. Here are some examples: +.. code-block:: bash + ./run_tests.sh --unit # run all unit tests ./run_tests.sh --unit list # list all unit tests ./run_tests.sh --unit test device # test device unit test From 0a1d63671c3719222073ac999578ff5103b44925 Mon Sep 17 00:00:00 2001 From: jppaulo Date: Mon, 15 Jan 2024 20:23:46 -0300 Subject: [PATCH 031/128] documentation: tutorials: pomodoro: Update old info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are some outdated infos related to `kw pomodoro` command in kw documentation. Update these infos. Closes: #1006 Closes: #1007 Signed-off-by: JoĆ£o Paulo Pereira da Silva Reviewed-by: David Tadokoro Signed-off-by: David Tadokoro --- documentation/tutorials/pomodoro-report.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/tutorials/pomodoro-report.rst b/documentation/tutorials/pomodoro-report.rst index 48fa5c725..dff477e37 100644 --- a/documentation/tutorials/pomodoro-report.rst +++ b/documentation/tutorials/pomodoro-report.rst @@ -58,7 +58,7 @@ Notice that you can use the short version of the above command:: Now that you created this session, you can check how many minutes are left by using:: - $ kw p --list # kw p -l + $ kw p --check-timer # kw p -c Now, forget about the world and focus on your task for 30 minutes; don't worry, @@ -76,7 +76,7 @@ Notice that typing "Super weird bug" is tedious and error-prone, but don't worry, kw provides a feature to list all tags and associates them with an ID. To see all the tags that you already created, use this command:: - $ kw p -g + $ kw p --show-tags # kw p -s 1.Super weird bug In other words, you can use:: From a55f6e56b26d14f45ae4d534fa8669fe565c5369 Mon Sep 17 00:00:00 2001 From: jppaulo Date: Mon, 15 Jan 2024 21:18:22 -0300 Subject: [PATCH 032/128] src: kw_remote: Add dashes to remote commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `kw remote` commands lack a clear pattern related to double dashes (--). Notably, `kw remote add`, `kw remote remove` and `kw remote rename` do not include dashes, but `kw remote --list` does. So, to make it more clear, execute the following changes: - `kw remote add` to `kw remote --add` - `kw remote remove` to `kw remote --remove` - `kw remote rename` to `kw remote --rename` Reviewed-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: JoĆ£o Paulo Pereira da Silva Signed-off-by: Rodrigo Siqueira --- documentation/man/features/kw-remote.rst | 20 ++++++++++---------- documentation/tutorials/deploy-kernel.rst | 2 +- src/_kw | 6 +++--- src/bash_autocomplete.sh | 2 +- src/kw_remote.sh | 20 ++++++++++---------- tests/unit/kw_remote_test.sh | 6 +++--- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/documentation/man/features/kw-remote.rst b/documentation/man/features/kw-remote.rst index 10654fef5..5f9368115 100644 --- a/documentation/man/features/kw-remote.rst +++ b/documentation/man/features/kw-remote.rst @@ -7,9 +7,9 @@ kw-remote - Manage set of tracked test machines SYNOPSIS ======== | *kw remote* [-v | \--verbose] -| *kw remote* [--global] add @[:] -| *kw remote* [--global] remove -| *kw remote* [--global] rename +| *kw remote* [--global] \--add @[:] +| *kw remote* [--global] \--remove +| *kw remote* [--global] \--rename | *kw remote* [--global] \--list | *kw remote* [--global] (-s | \--set-default)= @@ -21,16 +21,16 @@ available locally at `.kw/remote.config` or globally at `~/.config/kw/remote.con OPTIONS ======= -add : +\--add : Adds a remote named for the test machine at . Notice that must follow the pattern `@[:]` where `remote` can be an IP or a name server and `:` is optional (default port is 22). -remove : +\--remove : Remove the remote named . -rename : +\--rename : Rename the remote named to . If you try a name already in use, kw will fail with a message. @@ -52,19 +52,19 @@ EXAMPLES In case you want **kw** to track a new test machine, you can use:: cd - kw remote add origin root@my-test-machine + kw remote --add origin root@my-test-machine If you do not use port 22, you can use:: - kw remote add my-x86-test-system root@my-test-machine:5555 + kw remote --add my-x86-test-system root@my-test-machine:5555 If you want to remove some remote:: - kw remote remove origin + kw remote --remove origin If you want to rename:: - kw remote rename origina arm-device + kw remote --rename origina arm-device You can also list all your available remotes via:: diff --git a/documentation/tutorials/deploy-kernel.rst b/documentation/tutorials/deploy-kernel.rst index c6565f475..c26d693cc 100644 --- a/documentation/tutorials/deploy-kernel.rst +++ b/documentation/tutorials/deploy-kernel.rst @@ -70,7 +70,7 @@ Before trying to deploy your new kernel, let's first update `kworkflow.config` and `remote.config` by making sure that you set the following options correctly:: - kw remote add my-x86-test-system root@: + kw remote --add my-x86-test-system root@: .. note:: If you don't know anything about `kworkflow.config` or `remote.config`, take diff --git a/src/_kw b/src/_kw index 4355fcb3c..a3f82b434 100644 --- a/src/_kw +++ b/src/_kw @@ -438,9 +438,9 @@ _kw_pomodoro() _kw_remote() { local -a remote_commands=( - 'add:add a named remote to kw management' - 'remove:remove an existing remote from kw management' - 'rename:rename an existing remote' + '--add:add a named remote to kw management' + '--remove:remove an existing remote from kw management' + '--rename:rename an existing remote' ) _arguments : \ diff --git a/src/bash_autocomplete.sh b/src/bash_autocomplete.sh index b85dbd4b7..2d553d8f4 100644 --- a/src/bash_autocomplete.sh +++ b/src/bash_autocomplete.sh @@ -51,7 +51,7 @@ function _kw_autocomplete() kw_options['config']='--local --global --show --help --verbose' - kw_options['remote']='add remove rename --list --global --set-default --verbose' + kw_options['remote']='--add --remove --rename --list --global --set-default --verbose' kw_options['explore']='--log --grep --all --only-header --only-source --exactly --verbose' kw_options['e']="${kw_options['explore']}" diff --git a/src/kw_remote.sh b/src/kw_remote.sh index 66e9a7531..f2ab83ca3 100644 --- a/src/kw_remote.sh +++ b/src/kw_remote.sh @@ -139,7 +139,7 @@ function add_new_remote() # We expect at exact two parameters if [[ "${#add_parameters[*]}" != 2 ]]; then - complain 'Expected: add <[user@]ip[:port]>' + complain 'Expected: --add <[user@]ip[:port]>' exit 22 # EINVAL fi @@ -236,7 +236,7 @@ function remove_remote() # We expect at exact two parameters if [[ "${#remove_parameters[*]}" != 1 ]]; then - complain 'Expected: remove ' + complain 'Expected: --remove ' exit 22 # EINVAL fi @@ -280,7 +280,7 @@ function rename_remote() # We expect at exact two parameters if [[ "${#rename_parameters[*]}" != 2 ]]; then - complain 'Expected: rename ' + complain 'Expected: --rename ' exit 22 # EINVAL fi @@ -359,15 +359,15 @@ function parse_remote_options() remote_help "$1" exit ;; - add) + --add) options_values['ADD']=1 shift ;; - remove) + --remove) options_values['REMOVE']=1 shift ;; - rename) + --rename) options_values['RENAME']=1 shift ;; @@ -411,7 +411,7 @@ function parse_remote_options() -z "${options_values['RENAME']}" && -z "${options_values['LIST']}" && -z "${options_values['DEFAULT_REMOTE']}" ]]; then options_values['ERROR']='"kw remote" should be proceeded by valid option'$'\n' - options_values['ERROR']+='Usage: kw remote (add | remove | rename | --list | --set-default) [...]' + options_values['ERROR']+='Usage: kw remote (--add | --remove | --rename | --list | --set-default) [...]' return 22 # EINVAL fi } @@ -425,9 +425,9 @@ function remote_help() fi printf '%s\n' 'kw remote:' \ ' remote - handle remote options' \ - ' remote add [--global] [--set-default] - Add new remote' \ - ' remote remove [--global] - Remove remote' \ - ' remote rename [--global] - Rename remote' \ + ' remote [--global] --add [--set-default] - Add new remote' \ + ' remote [--global] --remove - Remove remote' \ + ' remote [--global] --rename - Rename remote' \ ' remote [--global] --set-default= - Set default remote' \ ' remote [--global] --list - List remotes' \ ' remote [--global] (--verbose | -v) - be verbose' diff --git a/tests/unit/kw_remote_test.sh b/tests/unit/kw_remote_test.sh index 6aa17bef1..753529e92 100755 --- a/tests/unit/kw_remote_test.sh +++ b/tests/unit/kw_remote_test.sh @@ -465,17 +465,17 @@ function test_set_default_remote_we_already_have_the_default_remote() function test_parse_remote_options() { # Add option - parse_remote_options add origin 'root@la:3333' + parse_remote_options --add origin 'root@la:3333' assert_equals_helper 'Request add' "($LINENO)" "${options_values['ADD']}" 1 assert_equals_helper 'Remote options' "($LINENO)" "${options_values['PARAMETERS']}" 'origin root@la:3333 ' # Remove - parse_remote_options remove origin + parse_remote_options --remove origin assert_equals_helper 'Request remove' "($LINENO)" "${options_values['REMOVE']}" 1 assert_equals_helper 'Remote options' "($LINENO)" "${options_values['PARAMETERS']}" 'origin ' # Rename - parse_remote_options rename origin xpto + parse_remote_options --rename origin xpto assert_equals_helper 'Request rename' "($LINENO)" "${options_values['RENAME']}" 1 assert_equals_helper 'Remote options' "($LINENO)" "${options_values['PARAMETERS']}" 'origin xpto ' } From 999f5d346fb1ed2c266d8a5e628fd85ec66e553a Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Wed, 17 Jan 2024 17:15:31 -0300 Subject: [PATCH 033/128] src: _kw: Fix Zsh completion of `kw pomodoro` `--description` option In the Zsh completions for kw, options that depend on other options being completed to be suggested are implemented using indexed arrays. Conceptually, if 'option A' depends on 'option B' being completed to be suggested, the array that defines 'option A' will be empty until 'option B' has been completed. In the case of `kw pomodoro`, the `--description` option should only be suggested if the prompt has the `--set-timer` and `--tag` options. However, for a given shell session, the correct behavior only happens once, from which `--description` will be suggested even when the prompt has only `kw pomodoro`. The cause of this is that we do not declare a local empty array for the options that come after `--tag`, so once it has been set with `--description`, it will contain it to the remainder of the shell session. To fix this behavior declare a local empty array for the options that depend on the `--tag` at the start of the completion function for `kw pomodoro`. Reviewed-by: Rodrigo Siqueira Signed-off-by: David Tadokoro Signed-off-by: Rodrigo Siqueira --- src/_kw | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_kw b/src/_kw index a3f82b434..63387e025 100644 --- a/src/_kw +++ b/src/_kw @@ -413,6 +413,7 @@ _kw_p() { _kw_pomodoro } _kw_pomodoro() { local -a set_timer_options=() + local -a tag_options=() if ((words[(I)-t|--set-timer])); then set_timer_options=( From 1c7372c5be9273abb196c546f3002b2d0f69abdc Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Sun, 21 Jan 2024 22:16:46 -0300 Subject: [PATCH 034/128] src: lib: kwlib: Verbose mode for command substitution Added a new mode for verbose output in command substitution situations, allowing statements like foo=$(cmd_manager 'CMD_SUBSTITUTION_VERBOSE' "$cmd") for detailed output. Reviewed-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Aquila Macedo --- src/lib/kwlib.sh | 3 +++ tests/unit/lib/kwlib_test.sh | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/lib/kwlib.sh b/src/lib/kwlib.sh index 74d5e1c99..d2bbf5354 100644 --- a/src/lib/kwlib.sh +++ b/src/lib/kwlib.sh @@ -111,6 +111,9 @@ function cmd_manager() say "$command_for_eval" return 0 ;; + CMD_SUBSTITUTION_VERBOSE) + say "$command_for_eval" >&2 + ;; *) # VERBOSE say "$command_for_eval" ;; diff --git a/tests/unit/lib/kwlib_test.sh b/tests/unit/lib/kwlib_test.sh index 813708541..750e1ebff 100755 --- a/tests/unit/lib/kwlib_test.sh +++ b/tests/unit/lib/kwlib_test.sh @@ -212,6 +212,19 @@ function test_cmd_manager_say_complain_warning_highlight_cmd_success() assertTrue "($LINENO): We expected to find scripts" '[[ $ret =~ scripts ]]' } +function test_cmd_manager_cmd_substitution_with_verbose_output +{ + local cmd + local output + local verbose_output_path="${SHUNIT_TMPDIR}/verbose_output" + + cmd="printf 'Hello World!'" + output=$(cmd_manager 'CMD_SUBSTITUTION_VERBOSE' "$cmd" 2> "$verbose_output_path") + + assert_equals_helper "Should execute \`${cmd}\`" "$LINENO" 'Hello World!' "$output" + assert_equals_helper "Should output the string \`${cmd}\`' to stderr" "$LINENO" "$cmd" "$(< "$verbose_output_path")" +} + function test_cmd_manager_check_test_mode_option() { local ret From e71234d55fecdcd654b53b4069a069fc945e4984 Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Mon, 20 Nov 2023 22:44:44 -0300 Subject: [PATCH 035/128] src: lib: kw_db: Added verbose option to function select_from() This commit adds verbose mode to the select_from function in kw_db Reviewed-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Aquila Macedo --- src/kernel_config_manager.sh | 19 +++++++++++++------ src/lib/kw_db.sh | 11 ++++++++--- src/pomodoro.sh | 20 ++++++++++++++------ src/report.sh | 4 +++- tests/unit/kw_db_test.sh | 2 +- tests/unit/pomodoro_test.sh | 22 +++++++++++----------- 6 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/kernel_config_manager.sh b/src/kernel_config_manager.sh index ac06c9ddd..63b5f25a4 100644 --- a/src/kernel_config_manager.sh +++ b/src/kernel_config_manager.sh @@ -30,7 +30,7 @@ function kernel_config_manager_main() flag=${flag:-'SILENT'} if [[ -z "$*" ]]; then - list_configs + list_configs "$flag" return "$?" fi @@ -63,7 +63,7 @@ function kernel_config_manager_main() fi if [[ -n "${options_values['LIST']}" ]]; then - list_configs + list_configs "$flag" return "$?" fi @@ -126,8 +126,10 @@ function save_config_file() return 2 # ENOENT fi + [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' + # Checks if there is already an entry for that kernel config file in the database - is_on_database="$(select_from "kernel_config WHERE name IS '${config_name}'")" + is_on_database="$(select_from "kernel_config WHERE name IS '${config_name}'" '' '' '' "$flag")" if [[ -n "${is_on_database}" && "$force" != 1 ]]; then warning "Kernel config file named '${config_name}' already exists." if [[ $(ask_yN "Do you want to overwrite it?") =~ '0' ]]; then @@ -514,9 +516,12 @@ function fetch_config() # managed by kw. function list_configs() { + local flag="${1:-SILENT}" local configs - configs="$(select_from 'kernel_config' 'name AS "Name", description AS "Description", last_updated_datetime AS "Last updated"' '.mode column')" + [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' + + configs="$(select_from 'kernel_config' 'name AS \"Name\", description AS \"Description\", last_updated_datetime AS \"Last updated\"' '.mode column' '' "$flag")" if [[ -z "$configs" ]]; then say 'There are no .config files managed by kw' @@ -555,7 +560,9 @@ function basic_config_validations() exit 2 # ENOENT fi - query_output=$(select_from "kernel_config WHERE name IS '${config_name}'") + [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' + + query_output="$(select_from "kernel_config WHERE name IS '${config_name}'" '' '' '' "$flag")" if [[ -z "${query_output}" ]]; then complain "Couldn't find config in database named: ${config_name}" # Ask user what to do with hanging local .config @@ -636,7 +643,7 @@ function remove_config() local -r msg="This operation will remove ${config_name} from kw management" local ret - basic_config_validations "$config_name" "$force" 'Remove' "$msg" + basic_config_validations "$config_name" "$force" 'Remove' "$msg" "$flag" if is_safe_path_to_remove "${kernel_configs_dir}/${config_name}"; then cmd_manager "$flag" "rm ${kernel_configs_dir}/${config_name}" diff --git a/src/lib/kw_db.sh b/src/lib/kw_db.sh index 794b8fd9d..93cd2d313 100644 --- a/src/lib/kw_db.sh +++ b/src/lib/kw_db.sh @@ -179,6 +179,7 @@ function remove_from() # This function gets the values in the table of given database # +# @flag: Flag to control function output # @table: Table to select info from # @columns: Columns of the table to get # @pre_cmd: Pre command to execute @@ -195,10 +196,12 @@ function select_from() local columns="${2:-"*"}" local pre_cmd="$3" local order_by="$4" - local db="${5:-"$DB_NAME"}" - local db_folder="${6:-"$KW_DATA_DIR"}" + local flag=${5:-'SILENT'} + local db="${6:-$DB_NAME}" + local db_folder="${7:-$KW_DATA_DIR}" local db_path local query + local cmd db_path="$(join_path "$db_folder" "$db")" @@ -216,7 +219,9 @@ function select_from() if [[ -n "${order_by}" ]]; then query="SELECT $columns FROM $table ORDER BY ${order_by} ;" fi - sqlite3 -init "$KW_DB_DIR/pre_cmd.sql" -cmd "$pre_cmd" "$db_path" -batch "$query" + + cmd="sqlite3 -init ${KW_DB_DIR}/pre_cmd.sql -cmd \"${pre_cmd}\" \"${db_path}\" -batch \"${query}\"" + cmd_manager "$flag" "$cmd" } # This function takes arguments and assembles them into the correct format to diff --git a/src/pomodoro.sh b/src/pomodoro.sh index 8a5bbc2bf..2260731ee 100644 --- a/src/pomodoro.sh +++ b/src/pomodoro.sh @@ -64,6 +64,8 @@ function show_active_pomodoro_timebox() local elapsed_time local remaining_time + [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' + current_timestamp=$(get_timestamp_sec) while IFS=$'\n' read -r raw_active_timebox && [[ -n "${raw_active_timebox}" ]]; do @@ -79,16 +81,19 @@ function show_active_pomodoro_timebox() say "Started at: ${start_time} [${start_date}]" say '- Elapsed time:' "$(secs_to_arbitrarily_long_hours_mins_secs "${elapsed_time}")" say '- You still have' "$(secs_to_arbitrarily_long_hours_mins_secs "${remaining_time}")" - done <<< "$(select_from 'active_timebox' '"date","time","duration"')" + done <<< "$(select_from 'active_timebox' '"date","time","duration"' '' '' "$flag")" } # Show registered tags with number identification. function show_tags() { - local flag="$1" + local flag=${1:-'SILENT'} local tags + local cmd + + [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' - tags=$(select_from 'tag WHERE "active" IS 1' '"id" AS "ID", "name" AS "Name"' '.mode column' 'id') + tags=$(select_from 'tag WHERE "active" IS 1' '"id" AS "ID", "name" AS "Name"' '.mode column' 'id' "$flag") if [[ -z "$tags" ]]; then say 'You did not register any tag yet' return 0 @@ -103,7 +108,7 @@ function show_tags() # @tag: tag name function register_tag() { - local flag="$1" + local flag="${1:-SILENT}" local tag="$2" if ! is_tag_already_registered "$flag" "$tag"; then @@ -121,11 +126,14 @@ function register_tag() # anything. function is_tag_already_registered() { - local flag="$1" + local flag="${1:-SILENT}" local tag_name="$2" local is_tag_registered='' + local cmd + + [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' - is_tag_registered=$(select_from "tag WHERE name IS '${tag_name}'") + is_tag_registered=$(select_from "tag WHERE name IS '${tag_name}'" '' '' '' "$flag") [[ -n "${is_tag_registered}" ]] && return 0 return 1 diff --git a/src/report.sh b/src/report.sh index 24918800b..158af3b9e 100644 --- a/src/report.sh +++ b/src/report.sh @@ -132,7 +132,9 @@ function get_raw_data_from_period_of_time() flag=${flag:-'SILENT'} - raw_data=$(select_from "${table_name} WHERE date REGEXP ${regex_exp}") + [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' + + raw_data=$(select_from "${table_name} WHERE date REGEXP ${regex_exp}" '' '' '' "$flag") printf '%s' "$raw_data" } diff --git a/tests/unit/kw_db_test.sh b/tests/unit/kw_db_test.sh index ca30a10fb..20971795a 100755 --- a/tests/unit/kw_db_test.sh +++ b/tests/unit/kw_db_test.sh @@ -228,7 +228,7 @@ function test_select_from() local entries # invalid - output=$(select_from table columns '' '' 'wrong/path/invalid_db.db') + output=$(select_from table columns '' '' '' 'wrong/path/invalid_db.db') ret="$?" expected='Database does not exist' assert_equals_helper 'Invalid db, error expected' "$LINENO" "$ret" 2 diff --git a/tests/unit/pomodoro_test.sh b/tests/unit/pomodoro_test.sh index b6756c990..6eaf8c304 100755 --- a/tests/unit/pomodoro_test.sh +++ b/tests/unit/pomodoro_test.sh @@ -221,31 +221,31 @@ function test_register_tag() 'tag 2' ) - register_tag 'TEST_MODE' 'tag 1' - register_tag 'TEST_MODE' 'tag 2' + register_tag '' 'tag 1' + register_tag '' 'tag 2' output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT name FROM tag ;") compare_command_sequence '' "$LINENO" 'expected_content' "$output" # Try to register the same tag - register_tag 'TEST_MODE' 'tag 2' + register_tag '' 'tag 2' compare_command_sequence '' "$LINENO" 'expected_content' "$output" # Try to register an empty tag - register_tag 'TEST_MODE' '' + register_tag '' '' compare_command_sequence '' "$LINENO" 'expected_content' "$output" } function test_is_tag_already_registered() { - is_tag_already_registered 'TEST_MODE' 'Tag 0' + is_tag_already_registered '' 'Tag 0' assertNotEquals "$LINENO: We should not get a success" "$?" 0 - is_tag_already_registered 'TEST_MODE' '' + is_tag_already_registered '' '' assertNotEquals "$LINENO: We should not get a success" "$?" 0 sqlite3 "${KW_DATA_DIR}/kw.db" -batch "INSERT INTO tag ('name') VALUES ('Tag 0') ;" - is_tag_already_registered 'TEST_MODE' 'Tag 0' + is_tag_already_registered '' 'Tag 0' assertEquals "$LINENO: We expect to find Tag 0" "$?" 0 } @@ -261,10 +261,10 @@ function test_get_tag_name() expected='Some tag' assert_equals_helper 'Should return same value if it is not a number' "$LINENO" "$expected" "$output" - register_tag 'TEST_MODE' 'tag 1' - register_tag 'TEST_MODE' 'tag 2' - register_tag 'TEST_MODE' 'tag 3' - register_tag 'TEST_MODE' 'tag 4' + register_tag '' 'tag 1' + register_tag '' 'tag 2' + register_tag '' 'tag 3' + register_tag '' 'tag 4' for i in {1..4}; do output=$(get_tag_name "$i") From 8c0c1e719aede3bad2739bfdec27058a34faec35 Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Wed, 22 Nov 2023 22:52:33 -0300 Subject: [PATCH 036/128] src: lib: kw_db: Added verbose option to function insert_into() This commit adds verbose mode to the insert_into function in kw_db and pass the argument "$flag" to the 'statistics_manager' function in order to enable the verbose mode Reviewed-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Aquila Macedo --- src/build.sh | 4 ++-- src/deploy.sh | 16 ++++++++-------- src/lib/kw_db.sh | 7 +++++-- src/lib/kwlib.sh | 3 ++- src/pomodoro.sh | 5 +++-- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/build.sh b/src/build.sh index 78e074ca5..46050db73 100644 --- a/src/build.sh +++ b/src/build.sh @@ -142,9 +142,9 @@ function build_kernel_main() runtime=$((end - start)) if [[ "$ret" != 0 ]]; then - statistics_manager 'build' "$start" "$runtime" 'failure' + statistics_manager 'build' "$start" "$runtime" 'failure' "$flag" else - statistics_manager 'build' "$start" "$runtime" + statistics_manager 'build' "$start" "$runtime" '' "$flag" fi return "$ret" diff --git a/src/deploy.sh b/src/deploy.sh index 46070c739..481eee6a6 100644 --- a/src/deploy.sh +++ b/src/deploy.sh @@ -140,9 +140,9 @@ function deploy_main() runtime=$((end - start)) if [[ "$ret" == 0 ]]; then - statistics_manager 'list' "$start" "$runtime" + statistics_manager 'list' "$start" "$runtime" '' "$flag" else - statistics_manager 'list' "$start" "$runtime" 'failure' + statistics_manager 'list' "$start" "$runtime" 'failure' "$flag" fi exit "$?" @@ -157,9 +157,9 @@ function deploy_main() runtime=$((end - start)) if [[ "$ret" == 0 ]]; then - statistics_manager 'uninstall' "$start" "$runtime" + statistics_manager 'uninstall' "$start" "$runtime" '' "$flag" else - statistics_manager 'uninstall' "$start" "$runtime" 'failure' + statistics_manager 'uninstall' "$start" "$runtime" 'failure' "$flag" fi return "$?" @@ -253,9 +253,9 @@ function deploy_main() runtime=$((end - start)) if [[ "$ret" == 0 ]]; then - statistics_manager 'deploy' "$start" "$runtime" + statistics_manager 'deploy' "$start" "$runtime" '' "$flag" else - statistics_manager 'deploy' "$start" "$runtime" 'failure' + statistics_manager 'deploy' "$start" "$runtime" 'failure' "$flag" exit "$ret" fi else # Only module deploy @@ -266,9 +266,9 @@ function deploy_main() runtime=$((end - start)) if [[ "$ret" == 0 ]]; then - statistics_manager 'modules_deploy' "$start" "$runtime" + statistics_manager 'modules_deploy' "$start" "$runtime" '' "$flag" else - statistics_manager 'modules_deploy' "$start" "$runtime" 'failure' + statistics_manager 'modules_deploy' "$start" "$runtime" 'failure' "$flag" fi fi diff --git a/src/lib/kw_db.sh b/src/lib/kw_db.sh index 93cd2d313..a108512fc 100644 --- a/src/lib/kw_db.sh +++ b/src/lib/kw_db.sh @@ -75,8 +75,10 @@ function insert_into() local entries="$2" local values="$3" local db="${4:-"$DB_NAME"}" - local db_folder="${5:-"$KW_DATA_DIR"}" + local flag=${5:-'SILENT'} + local db_folder="${6:-$KW_DATA_DIR}" local db_path + local cmd db_path="$(join_path "$db_folder" "$db")" @@ -92,7 +94,8 @@ function insert_into() [[ -n "$entries" && ! "$entries" =~ ^\(.*\)$ ]] && entries="($entries)" - sqlite3 -init "$KW_DB_DIR/pre_cmd.sql" "$db_path" -batch "INSERT INTO $table $entries VALUES $values;" + cmd="sqlite3 -init "${KW_DB_DIR}/pre_cmd.sql" \"${db_path}\" -batch \"INSERT INTO ${table} ${entries} VALUES ${values};\"" + cmd_manager "$flag" "$cmd" } # This function updates or insert rows into table of given database, diff --git a/src/lib/kwlib.sh b/src/lib/kwlib.sh index d2bbf5354..bdebbe11c 100644 --- a/src/lib/kwlib.sh +++ b/src/lib/kwlib.sh @@ -382,6 +382,7 @@ function statistics_manager() local start_datetime_in_secs="$2" local elapsed_time_in_secs="$3" local status=${4:-'success'} + local flag=${5:-'SILENT'} local start_datetime local start_date local start_time @@ -401,7 +402,7 @@ function statistics_manager() row=$(format_values_db 5 "$label_name" "$status" "$start_date" "$start_time" "$elapsed_time_in_secs") - insert_into '"statistics_report"' "$database_columns" "$row" + insert_into '"statistics_report"' "$database_columns" "$row" '' "$flag" } # This function checks if a certain command can be run diff --git a/src/pomodoro.sh b/src/pomodoro.sh index 2260731ee..82cf854a4 100644 --- a/src/pomodoro.sh +++ b/src/pomodoro.sh @@ -112,7 +112,7 @@ function register_tag() local tag="$2" if ! is_tag_already_registered "$flag" "$tag"; then - insert_into 'tag' "('name')" "('${tag}')" + insert_into 'tag' "('name')" "('${tag}')" '' "$flag" fi } @@ -166,6 +166,7 @@ function timer_thread() # the description (if there is one) in the local database. function register_data_for_report() { + local flag=${1:-'SILENT'} local start_date local start_time local duration @@ -184,7 +185,7 @@ function register_data_for_report() # Format the data and insert it into the database formatted_data="$(format_values_db 5 "${values[@]}")" - insert_into '"pomodoro_report"' "$columns" "${formatted_data}" + insert_into '"pomodoro_report"' "$columns" "${formatted_data}" '' "$flag" } # This function checks if the time passed as argument is a valid one, i.e, is From 061f9775c78b1a4285c702be6f215ba209837857 Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Wed, 22 Nov 2023 23:54:48 -0300 Subject: [PATCH 037/128] src: lib: kw_db: Added verbose option to function replace_into() This commit adds verbose mode to the replace_into function in kw_db Reviewed-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Aquila Macedo --- src/kernel_config_manager.sh | 2 +- src/lib/kw_db.sh | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/kernel_config_manager.sh b/src/kernel_config_manager.sh index 63b5f25a4..7617c1198 100644 --- a/src/kernel_config_manager.sh +++ b/src/kernel_config_manager.sh @@ -175,7 +175,7 @@ function save_config_file() datetime=$(date '+%Y-%m-%d %H:%M:%S') values=("$config_name" "$description" "${kernel_configs_dir}/${config_name}" "$datetime") rows="$(format_values_db 4 "${values[@]}")" - replace_into '"kernel_config"' "$database_columns" "$rows" + replace_into '"kernel_config"' "$database_columns" "$rows" '' "$flag" ret="$?" if [[ "$ret" -gt 0 ]]; then diff --git a/src/lib/kw_db.sh b/src/lib/kw_db.sh index a108512fc..b1465b66a 100644 --- a/src/lib/kw_db.sh +++ b/src/lib/kw_db.sh @@ -117,8 +117,10 @@ function replace_into() local columns="$2" local rows="$3" local db="${4:-"$DB_NAME"}" - local db_folder="${5:-"$KW_DATA_DIR"}" + local flag=${5:-'SILENT'} + local db_folder="${6:-"$KW_DATA_DIR"}" local db_path + local cmd db_path="$(join_path "$db_folder" "$db")" @@ -134,7 +136,8 @@ function replace_into() [[ -n "$columns" && ! "$columns" =~ ^\(.*\)$ ]] && columns="($columns)" - sqlite3 -init "${KW_DB_DIR}/pre_cmd.sql" "${db_path}" -batch "REPLACE INTO ${table} ${columns} VALUES ${rows};" + cmd="sqlite3 -init "${KW_DB_DIR}/pre_cmd.sql" \"${db_path}\" -batch \"REPLACE INTO ${table} ${columns} VALUES ${rows};\"" + cmd_manager "$flag" "$cmd" } # This function removes every matching row from a given table. From 9c9e902ac4d4854f7dd0b68acd6ab8061c0514c5 Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Thu, 23 Nov 2023 00:01:07 -0300 Subject: [PATCH 038/128] src: lib: kw_db: Added verbose option to function remove_from() This commit adds verbose mode to the remove_from function in kw_db Reviewed-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Aquila Macedo --- src/kernel_config_manager.sh | 2 +- src/lib/kw_db.sh | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/kernel_config_manager.sh b/src/kernel_config_manager.sh index 7617c1198..cfa9a063f 100644 --- a/src/kernel_config_manager.sh +++ b/src/kernel_config_manager.sh @@ -654,7 +654,7 @@ function remove_config() fi condition_array=(['name']="${config_name}") - remove_from '"kernel_config"' 'condition_array' + remove_from '"kernel_config"' 'condition_array' '' '' "$flag" say "The ${config_name} config file was removed from kw management" } diff --git a/src/lib/kw_db.sh b/src/lib/kw_db.sh index b1465b66a..1f04a68ba 100644 --- a/src/lib/kw_db.sh +++ b/src/lib/kw_db.sh @@ -158,6 +158,7 @@ function remove_from() local -n _condition_array="$2" local db="${3:-"${DB_NAME}"}" local db_folder="${4:-"${KW_DATA_DIR}"}" + local flag=${5:-'SILENT'} local where_clause='' local db_path @@ -180,7 +181,8 @@ function remove_from() # Remove trailing ' AND ' where_clause="${where_clause::-5}" - sqlite3 -init "${KW_DB_DIR}/pre_cmd.sql" "${db_path}" -batch "DELETE FROM ${table} WHERE ${where_clause};" + cmd="sqlite3 -init "${KW_DB_DIR}/pre_cmd.sql" \"${db_path}\" -batch \"DELETE FROM ${table} WHERE ${where_clause};\"" + cmd_manager "$flag" "$cmd" } # This function gets the values in the table of given database From 41cf7f97f1ea03e089e0e3b5fba6e69271696532 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Tue, 30 Jan 2024 20:03:21 -0300 Subject: [PATCH 039/128] src: lib: dialog_ui: Remove `LC_CTYPE` override for async loading screen spinner The function `create_async_loading_screen_notification` creates a Dialog loading screen with a spinner to signal users that a delayed action is happening underneath. However, users reported environments that had problems with the characters used for the spinner while using `kw patch-hub` and running the test suite for `src/lib/dialog_ui.sh`. The problem stems from the environment variable `LC_CTYPE` (used to determine character handling rules) being overridden to account for using the spinner characters that are Unicode (multibyte). The logic behind this is sound, as the encoding aspect should be considered because these spinner characters have a length of 3 bytes. Nevertheless, not handling this matter fixes the problem for the environments mentioned above and doesn't introduce regressions for the environments that didn't face the issues. In this context, remove the override of `LC_CTYPE` and consider the spinner characters of length 1. Closes: #965 Reviewed-by: Rodrigo Siqueira Signed-off-by: David Tadokoro Signed-off-by: Rodrigo Siqueira --- src/lib/dialog_ui.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib/dialog_ui.sh b/src/lib/dialog_ui.sh index 2fd8446eb..0e6588cd5 100644 --- a/src/lib/dialog_ui.sh +++ b/src/lib/dialog_ui.sh @@ -250,12 +250,10 @@ function create_loading_screen_notification() function spin_frame() { local frame_offset="$1" - local LC_CTYPE=C local spin='⣾⣽⣻⢿┿⣟⣯⣷' - local char_width=3 frame_offset=$(((frame_offset) % ${#spin})) - printf "%s" "${spin:$frame_offset:$char_width}" + printf "%s" "${spin:$frame_offset:1}" } # Create simple async loading screen notification for delayed actions. @@ -293,7 +291,7 @@ function create_async_loading_screen_notification() # We should not use --clear because this flushes the infobox cmd+='dialog --colors' spin="$(spin_frame $frame_offset)" - frame_offset=$((frame_offset + 3)) + frame_offset=$((frame_offset + 1)) # Add Infobox screen cmd+=" --infobox $'${loading_message} ${spin}'" From 5a46b16232d781dc4e377440ba942399555686f9 Mon Sep 17 00:00:00 2001 From: jppaulo Date: Mon, 15 Jan 2024 17:16:12 -0300 Subject: [PATCH 040/128] tests: integration: Enhance text messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building images can take a long time. So, create a little warning for that when building. Also, fix first letter lowercase in "failed to setup container environment for distro ${distro}" Reviewed-by: David Tadokoro Signed-off-by: JoĆ£o Paulo Pereira da Silva Signed-off-by: David Tadokoro --- tests/integration/utils.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/utils.sh b/tests/integration/utils.sh index fe944dad9..608c013a5 100755 --- a/tests/integration/utils.sh +++ b/tests/integration/utils.sh @@ -65,12 +65,12 @@ function setup_container_environment() if [[ "$?" -ne 0 ]]; then # progress message: i=$((i + 1)) - say "[${i}/${n}] Building container image for ${distro}." + say "[${i}/${n}] Building container image for ${distro}. This might take a while..." # Build the image or fail. build_distro_image "$distro" if [[ "$?" -ne 0 ]]; then - complain "failed to setup container environment for distro ${distro}" + complain "Failed to setup container environment for distro ${distro}" # print we will skip creating the container image i=$((i + 1)) From 8e4902f62090068008ef2be914b24e38e0dfcdb6 Mon Sep 17 00:00:00 2001 From: jppaulo Date: Mon, 15 Jan 2024 18:08:33 -0300 Subject: [PATCH 041/128] tests: integration: utils: Enhance code readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some comments may be excessive (as the code is fully understandable without them) or may not follow kworkflow patterns. Additionally, there are opportunities for minor code improvements, such as variable names or line order. Refactor the code to improve readability. Reviewed-by: David Tadokoro Signed-off-by: JoĆ£o Paulo Pereira da Silva Signed-off-by: David Tadokoro --- tests/integration/utils.sh | 152 ++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 80 deletions(-) diff --git a/tests/integration/utils.sh b/tests/integration/utils.sh index 608c013a5..28bf2ec02 100755 --- a/tests/integration/utils.sh +++ b/tests/integration/utils.sh @@ -2,113 +2,104 @@ include './src/lib/kwio.sh' -declare -g CONTAINER_DIR # has the container files to build the container images -declare -g SAMPLES_DIR # has sample files used accross the integration tests -declare -g KWROOT_DIR # local kw dir to be copied to and installed in the containers -declare -g DISTROS # distributions we will run the integration tests +declare -g CONTAINER_DIR # Has the container files to build the container images +declare -g SAMPLES_DIR # Has sample files used accross the integration tests +declare -g KWROOT_DIR # Local kw dir to be copied to and installed in the containers +declare -g DISTROS # Distributions we will run the integration tests -# ensure path to directories is absolute +# Ensure path to directories is absolute script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")") CONTAINER_DIR="${script_dir}/podman" SAMPLES_DIR="${script_dir}/samples" KWROOT_DIR=$(realpath "${script_dir}/../..") -# supported distros +# Supported distros DISTROS=( 'archlinux' 'debian' 'fedora' ) -# Builds a container image for the given distro +# Build a container image for the given distro # -# @param $1 The OS distribution of the target container image. -# @return $? The status code of the command ran to build the image. +# @distro The OS distribution of the target container image. +# +# Return: +# The status code of the command ran to build the image. function build_distro_image() { - local distro="${1}" + local distro="$1" local file="${CONTAINER_DIR}/Containerfile_${distro}" podman image build --file "$file" --tag "kw-${distro}" > /dev/null 2>&1 - # Check if the command failed if [[ "$?" -ne 0 ]]; then fail "(${LINENO}): Error building the image for distribution ${distro}" return "$?" fi } -# Builds container images and create containers used accross the tests. -# -# @param $1 log level to print info, debug or error +# Build container images and create containers used accross the tests. function setup_container_environment() { - local container_img - local container_name - local distro # current distro - local distros_ok # array of distros whose setup succeed - local i # current step of the setup - local n # total number of steps local working_directory # working directory in the container + local container_name + local container_img + local current_step + local total_steps + local distros_ok # array of distros whose setup succeeded + local distro - # initialize some values distros_ok=() - i=0 - n=$((${#DISTROS[@]} * 2)) + current_step=0 + total_steps=$((${#DISTROS[@]} * 2)) working_directory='/tmp/kw' for distro in "${DISTROS[@]}"; do - # Only build the image if it does not exists. That's because trying to build + # container_img is the image name, while container_name is the name of the + # container built from the image. + container_img="kw-${distro}" + container_name="${container_img}" + + # Only build the image if it does not exist. That's because trying to build # the podman image takes a second or two even if it exists and is cached. - podman image exists "kw-${distro}" + podman image exists "${container_img}" if [[ "$?" -ne 0 ]]; then - # progress message: - i=$((i + 1)) - say "[${i}/${n}] Building container image for ${distro}. This might take a while..." + current_step=$((current_step + 1)) + say "[${current_step}/${total_steps}] Building container image for ${distro}. This might take a while..." - # Build the image or fail. build_distro_image "$distro" if [[ "$?" -ne 0 ]]; then complain "Failed to setup container environment for distro ${distro}" - # print we will skip creating the container image - i=$((i + 1)) - say "[${i}/${n}] Skip creating ${distro} container." + current_step=$((current_step + 1)) + say "[${current_step}/${total_steps}] Skip creating ${distro} container." - # continue the setup for other distros. continue fi else - # progress message: - i=$((i + 1)) - say "[${i}/${n}] Using cached container image for ${distro}." + current_step=$((current_step + 1)) + say "[${current_step}/${total_steps}] Using cached container image for ${distro}." fi - # The name of the container and the container image are equal here, but it - # is useful to make a distinction that in some places we should use the image - # name and in others the container name (they are equal in value but are not - # equivalent in meaning). - container_img="kw-${distro}" - container_name="${container_img}" - - # If container exists, we tear it down and create a new one in order + # If container exists, we tear it down and create a new one in order to # ensure KW installation reflects the latest local changes. podman container exists "${container_name}" if [[ "$?" -eq 0 ]]; then teardown_single_container "${container_name}" fi - # progress message: - i=$((i + 1)) - say "[${i}/${n}] Creating ${distro} container." - - # containers are isolated environments designed to run a process. After the - # process ends, the container is destroyed. In order execute multiple commands - # in the container, we need to keep the container, which means the primary - # process must not terminate. Therefore, we run a never-ending command as the - # primary process, so that we can execute multiple commands (secondary - # processes) and get the output of each of them separately. + current_step=$((current_step + 1)) + say "[${current_step}/${total_steps}] Creating ${distro} container." + + # Podman containers are isolated environments designed to run a single + # process. After the process ends, the container is destroyed. In order to + # execute multiple commands in the container, we need to keep the + # container alive, which means that the primary process must not terminate. + # Therefore, we run a never-ending command as the primary process, so that + # we can execute multiple commands (secondary processes) and get the output + # of each of them separately. container_run \ --workdir "${working_directory}" \ --volume "${KWROOT_DIR}":"${working_directory}" \ @@ -121,14 +112,14 @@ function setup_container_environment() fail "(${LINENO}): Failed to run the container ${container_name}" fi - # install kw again + # Container images already have kw installed. Install it again, overwriting + # the installation. container_exec "${container_name}" \ ./setup.sh --install --force --skip-checks --skip-docs > /dev/null 2>&1 if [[ "$?" -ne 0 ]]; then fail "(${LINENO}): Failed to install kw in the container ${container_name}" else - # add distro to array of distros that worked. distros_ok+=("$distro") fi done @@ -138,7 +129,23 @@ function setup_container_environment() DISTROS=("${distros_ok[@]}") } -# destroy a single container +# Destroy all containers used in the tests +function teardown_container_environment() +{ + local distro + local i=0 + local total_distros="${#DISTROS[@]}" + + for distro in "${DISTROS[@]}"; do + i=$((i + 1)) + say "[${i}/${total_distros}] Removing ${distro} container." + teardown_single_container "kw-${distro}" + done +} + +# Destroy a single container +# +# @container: Name or ID of the container function teardown_single_container() { local container="$1" @@ -146,28 +153,11 @@ function teardown_single_container() podman container exists "${container}" if [[ "$?" -eq 0 ]]; then - # destroy the container, waiting 0 seconds to send SIGKILL + # Destroy container sending SIGKILL instantly. podman container rm --force --time 0 "${container}" > /dev/null 2>&1 fi } -# destroy all containers used in the tests -teardown_container_environment() -{ - local distro - local i=0 # current step of tear down - local n="${#DISTROS[@]}" # total number of steps of tear down - - for distro in "${DISTROS[@]}"; do - # progress message - i=$((i + 1)) - say "[${i}/${n}] Removing ${distro} container." - - teardown_single_container "kw-${distro}" - done -} - -# run a container function container_run() { # shellcheck disable=SC2068 @@ -178,7 +168,6 @@ function container_run() fi } -# execute a given command in the container function container_exec() { # shellcheck disable=SC2068 @@ -189,8 +178,12 @@ function container_exec() fi } -# copy local file to container -container_copy() +# Copy files from the host to the container +# +# @container The container to copy files to. +# @src The file in the host. +# @dst The destination file or directory in the container. +function container_copy() { local container="$1" local src="$2" @@ -203,8 +196,7 @@ container_copy() fi } -# inspect the container -container_inspect() +function container_inspect() { # shellcheck disable=SC2068 podman container inspect $@ From 21d4400715a000ac57122ca66298ec1c559dddb1 Mon Sep 17 00:00:00 2001 From: jppaulo Date: Mon, 15 Jan 2024 16:31:43 -0300 Subject: [PATCH 042/128] tests: integration: Fix permission denied inside containers due to SELinux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SELinux is causing permission troubles to podman containers when the current mode is set to "enforcing". It does not allow to execute setup.sh inside the container, for example. This problem is related with how podman is built, being, currently, a quite common podman issue. Yet, it has an easy fix: add :z when mounting the volume. Helps: #1016 Reviewed-by: Rodrigo Siqueira Signed-off-by: JoĆ£o Paulo Pereira da Silva Signed-off-by: Rodrigo Siqueira --- tests/integration/utils.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/utils.sh b/tests/integration/utils.sh index 28bf2ec02..0bf75e17b 100755 --- a/tests/integration/utils.sh +++ b/tests/integration/utils.sh @@ -102,7 +102,7 @@ function setup_container_environment() # of each of them separately. container_run \ --workdir "${working_directory}" \ - --volume "${KWROOT_DIR}":"${working_directory}" \ + --volume "${KWROOT_DIR}":"${working_directory}:Z" \ --env PATH='/root/.local/bin:/usr/bin' \ --name "${container_name}" \ --detach \ From 24268646b7dc5b6dec6c573ecf561732fe5f40b4 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Wed, 7 Feb 2024 10:43:28 -0300 Subject: [PATCH 043/128] src: build: Remove redundant override of `load_build_config` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In kw, the `src/lib/kw_config_loader.sh` module takes care of configuration precedence for all the configurations, i.e., it composes configurations from the most preferred scope to the least one. Although the function `load_build_config` defined inside `src/lib/kw_config_loader.sh` takes care of this behavior for the configurations of `kw build`, this function is also defined in `src/build.sh`, doing virtually the same as the former definition. This double definition causes the one from build to override the one in the config loader (config loader is sourced first). Three problems arise from this situation: - Duplicated/redundant code. - The definition from build has a bug that outputs a warning to the user that doesn't makes sense. - It breaks the project's pattern of delegating any and all configuration loading to the `src/lib/kw_config_loader.sh` module. Probably, `load_build_config` from build was created before the inception of the config loader and we forgot to remove it after adding the module. That may be the reason why the code is duplicated and has a bug that doesn't exist in the config loader version. To address the three problems described above, remove the definition of `load_build_config` from `src/build.sh`. Fixes: #824 Thanks-to: Rodrigo Siqueira Thanks-to: AndrĆ© Gustavo Nakagomi Lopez Signed-off-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/build.sh | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/src/build.sh b/src/build.sh index 46050db73..c8221f69b 100644 --- a/src/build.sh +++ b/src/build.sh @@ -247,50 +247,6 @@ function full_cleanup() cmd_manager "$flag" "$cmd" } -# This function loads the kw build configuration files into memory, populating -# the $build_config hashtable. The files are parsed in a specific order, -# allowing higher level setting definitions to overwrite lower level ones. -function load_build_config() -{ - if [[ -v build_config && "$OVERRIDE_BUILD_CONFIG" != 1 ]]; then - unset OVERRIDE_BUILD_CONFIG - return - fi - - local -a config_dirs - local config_dirs_size - - if [[ -v XDG_CONFIG_DIRS ]]; then - IFS=: read -ra config_dirs <<< "$XDG_CONFIG_DIRS" - else - [[ -d '/etc/xdg' ]] && config_dirs=('/etc/xdg') - fi - - # Old users may not have split their configs yet - parse_configuration "$KW_ETC_DIR/$BUILD_CONFIG_FILENAME" build_config - - # XDG_CONFIG_DIRS is a colon-separated list of directories for config - # files to be searched, in order of preference. Since this function - # reads config files in a reversed order of preference, we must - # traverse it from back to top. Example: if - # XDG_CONFIG_DIRS=/etc/xdg:/home/user/myconfig:/etc/myconfig - # we will want to parse /etc/myconfig, then /home/user/myconfig, then - # /etc/xdg. - config_dirs_size="${#config_dirs[@]}" - for ((i = config_dirs_size - 1; i >= 0; i--)); do - parse_configuration "${config_dirs["$i"]}/$KWORKFLOW/$BUILD_CONFIG_FILENAME" build_config - done - - parse_configuration "${XDG_CONFIG_HOME:-"$HOME/.config"}/$KWORKFLOW/$BUILD_CONFIG_FILENAME" build_config - - if [[ -f "$PWD/$KW_DIR/$BUILD_CONFIG_FILENAME" ]]; then - parse_configuration "$PWD/$KW_DIR/$BUILD_CONFIG_FILENAME" build_config - else - # Old users may not have used kw init yet, so they wouldn't have .kw - warning "Please use kw init to update your config files" - fi -} - function parse_build_options() { local long_options='help,info,menu,doc,ccache,cpu-scaling:,warnings::,save-log-to:,llvm,clean,full-cleanup,verbose,cflags:' From addbe776fbdf08ed32576232445dbc0a1f075938 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Sat, 10 Feb 2024 07:32:14 -0700 Subject: [PATCH 044/128] src: kw_remote: Avoid destroying symbolic links in the add operation If the user tries to add the same remote name inside an env, kw will destroy the symbolic link and replace it with an actual file. Next, if the user switches between envs, they lose the previous configuration. This commit addresses this issue by adding the --follow-symlinks in the add operation, which avoids symbolic link replacement. Reviewed-by: David Tadokoro Signed-off-by: Rodrigo Siqueira Signed-off-by: David Tadokoro --- src/kw_remote.sh | 6 +++--- tests/unit/kw_remote_test.sh | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/kw_remote.sh b/src/kw_remote.sh index f2ab83ca3..788746b12 100644 --- a/src/kw_remote.sh +++ b/src/kw_remote.sh @@ -168,9 +168,9 @@ function add_new_remote() # Check if remote name already exists grep --line-regexp --quiet "^Host ${name}$" "$remote_config_file" if [[ "$?" == 0 ]]; then - sed --in-place --regexp-extended "/^Host ${name}$/{n;s/Hostname.*/Hostname ${remote_parameters['REMOTE_IP']}/}" "$remote_config_file" - sed --in-place --regexp-extended "/^Host ${name}$/{n;n;s/Port.*/Port ${remote_parameters['REMOTE_PORT']}/}" "$remote_config_file" - sed --in-place --regexp-extended "/^Host ${name}$/{n;n;n;s/User.*/User ${remote_parameters['REMOTE_USER']}/}" "$remote_config_file" + sed --in-place --follow-symlinks --regexp-extended "/^Host ${name}$/{n;s/Hostname.*/Hostname ${remote_parameters['REMOTE_IP']}/}" "$remote_config_file" + sed --in-place --follow-symlinks --regexp-extended "/^Host ${name}$/{n;n;s/Port.*/Port ${remote_parameters['REMOTE_PORT']}/}" "$remote_config_file" + sed --in-place --follow-symlinks --regexp-extended "/^Host ${name}$/{n;n;n;s/User.*/User ${remote_parameters['REMOTE_USER']}/}" "$remote_config_file" return fi diff --git a/tests/unit/kw_remote_test.sh b/tests/unit/kw_remote_test.sh index 753529e92..5ecb80d19 100755 --- a/tests/unit/kw_remote_test.sh +++ b/tests/unit/kw_remote_test.sh @@ -20,6 +20,8 @@ function setUp() mkdir -p "$KW_ETC_DIR" touch "${KW_ETC_DIR}/remote.config" + options_values['GLOBAL']='' + cd "${SHUNIT_TMPDIR}" || { fail "($LINENO): setUp(): It was not possible to move into ${SHUNIT_TMPDIR}" return @@ -674,6 +676,7 @@ function test_list_global_remotes() output=$(list_remotes) compare_command_sequence 'Should list the global remote.config if there is no local one' "$LINENO" 'expected_result' "$output" } + function test_global_option_rename_remote() { local final_result_array @@ -699,6 +702,7 @@ function test_global_option_rename_remote() mapfile -t final_result_array < "${global_remote_config_file}" compare_array_values expected_result final_result_array "$LINENO" } + function test_global_options_set_default_remote() { local final_result_array @@ -724,6 +728,7 @@ function test_global_options_set_default_remote() mapfile -t final_result_array < "${global_remote_config_file}" compare_array_values expected_result final_result_array "$LINENO" } + function test_global_option_list_remotes() { local final_result_array @@ -749,6 +754,7 @@ function test_global_option_list_remotes() mapfile -t final_result_array < "${global_remote_config_file}" compare_array_values expected_result final_result_array "$LINENO" } + function test_global_option_list_remote_invalid() { rm "${global_remote_config_file}" @@ -757,4 +763,37 @@ function test_global_option_list_remote_invalid() assertEquals "($LINENO)" "$?" 22 } +function test_ensure_add_remote_does_not_destroy_symbolic_link() +{ + local symlink="${BASE_PATH_KW}/remote.config" + local output + local base_value + + # Specific test setup + read -r -d '' base_value << 'EOF' +#kw-default=origin +Host origin + Hostname test-debian + Port 3333 + User root +EOF + printf '%s\n' "$base_value" > '.kw/remote.config' + + # Convert .kw to KW for create a symbolic link + mv "$BASE_PATH_KW" "${SHUNIT_TMPDIR}/KW" + + # Create new .kw folder + mkdir -p "$BASE_PATH_KW" + ln --symbolic "${SHUNIT_TMPDIR}/KW/remote.config" "${symlink}" + + [[ -L "$symlink" ]] + assert_equals_helper 'Symbolic link was not created' "$LINENO" 0 "$?" + + options_values['PARAMETERS']='origin root@test-deb:4444' + output=$(add_new_remote) + + [[ -L "$symlink" ]] + assert_equals_helper 'After add a new remote, link was destroyed' "$LINENO" 0 "$?" +} + invoke_shunit From 603eaca321834ccff1c95a837d3e41ea53bfd8dc Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Sat, 10 Feb 2024 08:06:04 -0700 Subject: [PATCH 045/128] src: kw_remote: Avoid destroy link when use set-default When using the --set-default option inside a kw env, it destroys the symbolic link. This commit addresses this issue by adding the --follow-symlinks parameter for the sed command. Reviewed-by: David Tadokoro Signed-off-by: Rodrigo Siqueira Signed-off-by: David Tadokoro --- src/kw_remote.sh | 4 ++-- tests/unit/kw_remote_test.sh | 42 +++++++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/kw_remote.sh b/src/kw_remote.sh index 788746b12..04712d440 100644 --- a/src/kw_remote.sh +++ b/src/kw_remote.sh @@ -205,7 +205,7 @@ function set_default_remote() grep --line-regexp --quiet "^#kw-default=.*" "$remote_config_file" # We don't have the default header yet, let's add it if [[ "$?" != 0 ]]; then - sed --in-place "1s/^/#kw-default=${default_remote}\n/" "$remote_config_file" + sed --in-place --follow-symlinks "1s/^/#kw-default=${default_remote}\n/" "$remote_config_file" return "$?" fi @@ -217,7 +217,7 @@ function set_default_remote() fi # We already have the default remote - sed --in-place --regexp-extended "s/^#kw-default=.*/#kw-default=${default_remote}/" "$remote_config_file" + sed --in-place --follow-symlinks --regexp-extended "s/^#kw-default=.*/#kw-default=${default_remote}/" "$remote_config_file" } function remove_remote() diff --git a/tests/unit/kw_remote_test.sh b/tests/unit/kw_remote_test.sh index 5ecb80d19..725ce9393 100755 --- a/tests/unit/kw_remote_test.sh +++ b/tests/unit/kw_remote_test.sh @@ -37,7 +37,7 @@ function tearDown() return } - rm -rf "$BASE_PATH_KW" + rm -rf "$SHUNIT_TMPDIR" } function test_add_new_remote_wrong_number_of_parameters() @@ -763,7 +763,7 @@ function test_global_option_list_remote_invalid() assertEquals "($LINENO)" "$?" 22 } -function test_ensure_add_remote_does_not_destroy_symbolic_link() +function setup_for_symbolic_link_test() { local symlink="${BASE_PATH_KW}/remote.config" local output @@ -776,8 +776,19 @@ Host origin Hostname test-debian Port 3333 User root +Host galactical + Hostname milky-way + Port 1234 + User hubble +Host global + Hostname planet-earth + Port 5678 + User newton EOF - printf '%s\n' "$base_value" > '.kw/remote.config' + printf '%s\n' "$base_value" > "${BASE_PATH_KW}/remote.config" + + # Remove global remote + mv "${SHUNIT_TMPDIR}/.config" "${SHUNIT_TMPDIR}/CONFIG" # Convert .kw to KW for create a symbolic link mv "$BASE_PATH_KW" "${SHUNIT_TMPDIR}/KW" @@ -785,6 +796,14 @@ EOF # Create new .kw folder mkdir -p "$BASE_PATH_KW" ln --symbolic "${SHUNIT_TMPDIR}/KW/remote.config" "${symlink}" +} + +function test_ensure_add_remote_does_not_destroy_symbolic_link() +{ + local symlink="${BASE_PATH_KW}/remote.config" + local output + + setup_for_symbolic_link_test [[ -L "$symlink" ]] assert_equals_helper 'Symbolic link was not created' "$LINENO" 0 "$?" @@ -796,4 +815,21 @@ EOF assert_equals_helper 'After add a new remote, link was destroyed' "$LINENO" 0 "$?" } +function test_ensure_set_default_remote_does_not_destroy_the_symbolic_link() +{ + local symlink="${BASE_PATH_KW}/remote.config" + local output + + setup_for_symbolic_link_test + + [[ -L "$symlink" ]] + assert_equals_helper 'Symbolic link was not created' "$LINENO" 0 "$?" + + options_values['DEFAULT_REMOTE']='galactical' + output=$(set_default_remote) + + [[ -L "$symlink" ]] + assert_equals_helper 'After set default, link was destroyed' "$LINENO" 0 "$?" +} + invoke_shunit From 825c4c4b24a9aefe1374c4ba05d5fffeeff3f5a7 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Sat, 10 Feb 2024 08:46:35 -0700 Subject: [PATCH 046/128] src: kw_remote: Ensure that link survive after remote removal When removing a remote inside an env, the symbolic link is replaced by a file, which is not the expected behavior when dealing with kw env. This commit fixes this issue by adding the --follow-symlinks parameter to the sed command inside remove_remote. Reviewed-by: David Tadokoro Signed-off-by: Rodrigo Siqueira Signed-off-by: David Tadokoro --- src/kw_remote.sh | 12 ++++++------ tests/unit/kw_remote_test.sh | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/kw_remote.sh b/src/kw_remote.sh index 04712d440..d53330c1c 100644 --- a/src/kw_remote.sh +++ b/src/kw_remote.sh @@ -249,14 +249,14 @@ function remove_remote() # Check if the target remote is the default if [[ "$?" == 0 ]]; then warning "'${target_remote}' was the default remote, please, set a new default" - sed --in-place "/^#kw-default=${target_remote}/d" "$remote_config_file" + sed --in-place --follow-symlinks "/^#kw-default=${target_remote}/d" "$remote_config_file" fi - sed --in-place --regexp-extended "/^Host ${target_remote}$/{n;/Hostname.*/d}" "$remote_config_file" - sed --in-place --regexp-extended "/^Host ${target_remote}$/{n;/Port.*/d}" "$remote_config_file" - sed --in-place --regexp-extended "/^Host ${target_remote}$/{n;/User.*/d}" "$remote_config_file" - sed --in-place --regexp-extended "/^Host ${target_remote}$/d" "$remote_config_file" - sed --in-place --regexp-extended '/^$/d' "$remote_config_file" + sed --in-place --follow-symlinks --regexp-extended "/^Host ${target_remote}$/{n;/Hostname.*/d}" "$remote_config_file" + sed --in-place --follow-symlinks --regexp-extended "/^Host ${target_remote}$/{n;/Port.*/d}" "$remote_config_file" + sed --in-place --follow-symlinks --regexp-extended "/^Host ${target_remote}$/{n;/User.*/d}" "$remote_config_file" + sed --in-place --follow-symlinks --regexp-extended "/^Host ${target_remote}$/d" "$remote_config_file" + sed --in-place --follow-symlinks --regexp-extended '/^$/d' "$remote_config_file" else complain "We could not find ${target_remote}" return 22 # EINVAL diff --git a/tests/unit/kw_remote_test.sh b/tests/unit/kw_remote_test.sh index 725ce9393..e8a337fec 100755 --- a/tests/unit/kw_remote_test.sh +++ b/tests/unit/kw_remote_test.sh @@ -832,4 +832,21 @@ function test_ensure_set_default_remote_does_not_destroy_the_symbolic_link() assert_equals_helper 'After set default, link was destroyed' "$LINENO" 0 "$?" } +function test_ensure_remove_remote_does_not_destroy_the_symbolic_link() +{ + local symlink="${BASE_PATH_KW}/remote.config" + local output + + setup_for_symbolic_link_test + + [[ -L "$symlink" ]] + assert_equals_helper 'Symbolic link was not created' "$LINENO" 0 "$?" + + options_values['PARAMETERS']='origin' + output=$(remove_remote) + + [[ -L "$symlink" ]] + assert_equals_helper 'After remove remote, link was destroyed' "$LINENO" 0 "$?" +} + invoke_shunit From dbc0b279b4397498b3f33b3d80c9f95c508d8e45 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Sat, 10 Feb 2024 08:54:59 -0700 Subject: [PATCH 047/128] src: kw_remote: Avoid destroy symbolic link when use rename If users try to rename a remote reference inside a kw env, the remote feature destroys the original link. This commit fixes this issue by adding the --follow-symlink parameter to the sed command. Reviewed-by: David Tadokoro Signed-off-by: Rodrigo Siqueira Signed-off-by: David Tadokoro --- src/kw_remote.sh | 2 +- tests/unit/kw_remote_test.sh | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/kw_remote.sh b/src/kw_remote.sh index d53330c1c..bd0963ae6 100644 --- a/src/kw_remote.sh +++ b/src/kw_remote.sh @@ -306,7 +306,7 @@ function rename_remote() # Check if remote name already exists grep --line-regexp --quiet "^Host ${old_name}$" "$remote_config_file" if [[ "$?" == 0 ]]; then - sed --in-place --regexp-extended "s/^Host $old_name/Host $new_name/" "$remote_config_file" + sed --in-place --follow-symlinks --regexp-extended "s/^Host $old_name/Host $new_name/" "$remote_config_file" # Check if the target remote was marked as a default grep --line-regexp --quiet "^#kw-default=${old_name}$" "$remote_config_file" diff --git a/tests/unit/kw_remote_test.sh b/tests/unit/kw_remote_test.sh index e8a337fec..ce823c83b 100755 --- a/tests/unit/kw_remote_test.sh +++ b/tests/unit/kw_remote_test.sh @@ -849,4 +849,21 @@ function test_ensure_remove_remote_does_not_destroy_the_symbolic_link() assert_equals_helper 'After remove remote, link was destroyed' "$LINENO" 0 "$?" } +function test_ensure_rename_remote_does_not_destroy_the_symbolic_link() +{ + local symlink="${BASE_PATH_KW}/remote.config" + local output + + setup_for_symbolic_link_test + + [[ -L "$symlink" ]] + assert_equals_helper 'Symbolic link was not created' "$LINENO" 0 "$?" + + options_values['PARAMETERS']='origin end' + output=$(rename_remote) + + [[ -L "$symlink" ]] + assert_equals_helper 'After rename remote, link was destroyed' "$LINENO" 0 "$?" +} + invoke_shunit From fa63a6c85b4e53af0e7843711872b20a733cfeb9 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Wed, 24 Jan 2024 13:33:04 -0300 Subject: [PATCH 048/128] src: ui: patch_hub: patchset_details_and_actions: Fix returning from 'Details and Actions' bug [What] With the implementation of 'Search String in Lore', the function `show_latest_patchsets_from_mailing_list` accepts an argument for additional filters to be passed in the Lore request. This argument is passed via the `screen_sequence` data structure used to pass information between the screens that compose patch-hub UI. However, because in the screen 'Details and Actions' the `screen_sequence['SHOW_SCREEN_PARAMETER']` contains data about a patchset (not an additional filter) and because this value isn't reset when returning from this screen, `show_latest_patchsets_from_mailing_list` makes an invalid request that causes the fetch to fail, when it shouldn't. In this context, make the screen 'Details and Actions' reset the value of `screen_sequence['SHOW_SCREEN_PARAMETER']` when returning and adapt other parts to not also break the 'Search String in Lore' feature. [Why] Undoubtedly, users will go back and forth between the listing of latest patchsets and a patchset details and actions, so this bug is a major flaw in patch-hub. [How] The fix goes by simply resetting the value of `screen_sequence['SHOW_SCREEN_PARAMETER']` in the function `show_patchset_details_and_actions` when the user hits the button 'Return'. However, because 'Search String in Lore' also uses this value to work, just this reset breaks this feature. So, besides the reset, we add a global variable to patch-hub UI declared in `patch_hub_core.sh` to pass additional filters instead of using `screen_sequence['SHOW_SCREEN_PARAMETER']` for this. Closes: #1028 Reviewed-by: Rodrigo Siqueira Signed-off-by: David Tadokoro Signed-off-by: Rodrigo Siqueira --- src/ui/patch_hub/latest_patchsets_from_mailing_list.sh | 4 +++- src/ui/patch_hub/patch_hub_core.sh | 3 ++- src/ui/patch_hub/patchset_details_and_actions.sh | 1 + src/ui/patch_hub/search_string_in_lore.sh | 2 +- tests/unit/ui/patch_hub/search_string_in_lore_test.sh | 8 +++++--- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ui/patch_hub/latest_patchsets_from_mailing_list.sh b/src/ui/patch_hub/latest_patchsets_from_mailing_list.sh index 6c06fee2d..67ac0cddb 100644 --- a/src/ui/patch_hub/latest_patchsets_from_mailing_list.sh +++ b/src/ui/patch_hub/latest_patchsets_from_mailing_list.sh @@ -7,7 +7,6 @@ declare -ga formatted_patchsets_list # These patchsets are ordered by their recieved time in the lore.kernel.org servers. function show_latest_patchsets_from_mailing_list() { - local additional_filters="$1" local starting_index local ending_index local box_title @@ -30,6 +29,8 @@ function show_latest_patchsets_from_mailing_list() else screen_sequence['SHOW_SCREEN']='registered_mailing_lists' fi + reset_current_lore_fetch_session + additional_filters='' return fi @@ -68,6 +69,7 @@ function show_latest_patchsets_from_mailing_list() else screen_sequence['SHOW_SCREEN']='registered_mailing_lists' fi + additional_filters='' fi ;; esac diff --git a/src/ui/patch_hub/patch_hub_core.sh b/src/ui/patch_hub/patch_hub_core.sh index 4a29505f1..fdd1223db 100644 --- a/src/ui/patch_hub/patch_hub_core.sh +++ b/src/ui/patch_hub/patch_hub_core.sh @@ -23,6 +23,7 @@ include "${KW_LIB_DIR}/ui/patch_hub/search_string_in_lore.sh" # These are references to data structures used all around the state-machine. declare -ga bookmarked_series declare -g current_mailing_list +declare -g additional_filters # This associative array is used to determine the states and topass arguments # between states. @@ -64,7 +65,7 @@ function patch_hub_main_loop() ret="$?" ;; 'latest_patchsets_from_mailing_list') - show_latest_patchsets_from_mailing_list "${screen_sequence['SHOW_SCREEN_PARAMETER']}" + show_latest_patchsets_from_mailing_list ret="$?" ;; 'bookmarked_patches') diff --git a/src/ui/patch_hub/patchset_details_and_actions.sh b/src/ui/patch_hub/patchset_details_and_actions.sh index aeec17d41..850b45a77 100644 --- a/src/ui/patch_hub/patchset_details_and_actions.sh +++ b/src/ui/patch_hub/patchset_details_and_actions.sh @@ -52,6 +52,7 @@ function show_patchset_details_and_actions() 3) # Return screen_sequence['SHOW_SCREEN']="${screen_sequence['PREVIOUS_SCREEN']}" + screen_sequence['SHOW_SCREEN_PARAMETER']='' ;; esac } diff --git a/src/ui/patch_hub/search_string_in_lore.sh b/src/ui/patch_hub/search_string_in_lore.sh index dbf02c000..06622db35 100644 --- a/src/ui/patch_hub/search_string_in_lore.sh +++ b/src/ui/patch_hub/search_string_in_lore.sh @@ -44,5 +44,5 @@ function search_string_in_lore() current_mailing_list='all' screen_sequence['SHOW_SCREEN']='latest_patchsets_from_mailing_list' - screen_sequence['SHOW_SCREEN_PARAMETER']="$(url_encode "$string")" + additional_filters="$(url_encode "$string")" } diff --git a/tests/unit/ui/patch_hub/search_string_in_lore_test.sh b/tests/unit/ui/patch_hub/search_string_in_lore_test.sh index 60575e450..9e085c974 100755 --- a/tests/unit/ui/patch_hub/search_string_in_lore_test.sh +++ b/tests/unit/ui/patch_hub/search_string_in_lore_test.sh @@ -25,6 +25,7 @@ function test_show_search_string_in_lore() { local output local expected + declare -g additional_filters='' # shellcheck disable=SC2317 function create_inputbox_screen() @@ -55,7 +56,7 @@ function test_show_search_string_in_lore() show_search_string_in_lore assert_equals_helper 'Wrong screen set' "$LINENO" 'latest_patchsets_from_mailing_list' "${screen_sequence['SHOW_SCREEN']}" - assert_equals_helper 'Wrong screen parameter' "$LINENO" 'query-string' "${screen_sequence['SHOW_SCREEN_PARAMETER']}" + assert_equals_helper 'Wrong additional filter' "$LINENO" 'query-string' "$additional_filters" assert_equals_helper 'Wrong current list' "$LINENO" 'all' "$current_mailing_list" # shellcheck disable=SC2317 @@ -75,6 +76,7 @@ function test_search_string_in_lore() { local output local expected + declare -g additional_filters='' # shellcheck disable=SC2317 function create_message_box() @@ -89,12 +91,12 @@ function test_search_string_in_lore() search_string_in_lore 'query-string' assert_equals_helper 'Wrong screen set' "$LINENO" 'latest_patchsets_from_mailing_list' "${screen_sequence['SHOW_SCREEN']}" - assert_equals_helper 'Wrong screen parameter' "$LINENO" 'query-string' "${screen_sequence['SHOW_SCREEN_PARAMETER']}" + assert_equals_helper 'Wrong screen parameter' "$LINENO" 'query-string' "$additional_filters" assert_equals_helper 'Wrong current list' "$LINENO" 'all' "$current_mailing_list" search_string_in_lore 'Robson CruzoĆ©' assert_equals_helper 'Wrong screen set' "$LINENO" 'latest_patchsets_from_mailing_list' "${screen_sequence['SHOW_SCREEN']}" - assert_equals_helper 'Wrong screen parameter' "$LINENO" 'Robson%20Cruzo%C3%A9' "${screen_sequence['SHOW_SCREEN_PARAMETER']}" + assert_equals_helper 'Wrong screen parameter' "$LINENO" 'Robson%20Cruzo%C3%A9' "$additional_filters" assert_equals_helper 'Wrong current list' "$LINENO" 'all' "$current_mailing_list" } From b58c3cd9623c63eb447067e15809c773ac5347b1 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Wed, 24 Jan 2024 12:43:38 -0300 Subject: [PATCH 049/128] src: lib: lore: Fix empty message ID bug in `get_patchset_bookmark_status` The function `get_patchset_bookmark_status` is used by patch-hub UI to determine if given patchset is already in the Lore bookmarked database. However, because the function uses `grep` to check if the patchset message ID is present in the file that represents the bookmark database, an empty message ID returns 1, which means true to being in the database. To fix this, check if the message ID passed as argument is empty and return 22 EINVAL in case it is. Note: Took the opportunity to rename the argument name from `patchset_url` to `message_id`, as it is more precise. Reviewed-by: Rodrigo Siqueira Signed-off-by: David Tadokoro Signed-off-by: Rodrigo Siqueira --- src/lib/lore.sh | 11 ++++++++--- tests/unit/lib/lore_test.sh | 3 +++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lib/lore.sh b/src/lib/lore.sh index a0de19a6d..3184b785e 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -917,18 +917,23 @@ function parse_raw_patchset_data() # This function gets the bookmark status of a patchset, 0 being not in the local # bookmarked database and 1 being in the local bookmarked database. # -# @patchset_url: The URL of the patchset that identifies the entry in the local +# @message_id: The URL of the patchset that identifies the entry in the local # bookmarked database +# +# Return: +# Returns 22 (EINVAL) function get_patchset_bookmark_status() { - local patchset_url="$1" + local message_id="$1" local count + [[ -z "$message_id" ]] && return 22 # EINVAL + if [[ ! -f "${BOOKMARKED_SERIES_PATH}" ]]; then create_lore_bookmarked_file fi - count=$(grep --count "$patchset_url" "${BOOKMARKED_SERIES_PATH}") + count=$(grep --count "$message_id" "${BOOKMARKED_SERIES_PATH}") if [[ "$count" == 0 ]]; then printf '%s' 0 else diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index df4335968..1522ec938 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -350,6 +350,9 @@ function test_get_patchset_bookmark_status() { local output + get_patchset_bookmark_status '' + assert_equals_helper 'Empty URL should return 22' "$LINENO" 22 "$?" + { printf 'entry1Ɔhttp://lore.kernel.org/amd-gfx/0138948.2424-1-lore@kernel.org/\n' printf 'entry2Ɔhttp://lore.kernel.org/linux-staging/1676464.997845-1-lore@kernel.org/\n' From 2e35da02c990dcbd66a19bdd07bb6174d388c44e Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Wed, 24 Jan 2024 19:18:42 -0300 Subject: [PATCH 050/128] src: lib: lore: Make query filter for Lore request more robust When fetching patches from Lore, patch-hub composes a query URL that contain base filters along with additional filters. The base filters basically aims to filter out any message from the given mailing list that is not a patch. However, this query filter simply filters out messages that have the string 'Re:' in the subject. In this context, make this query filter more robust by enforcing that the subject mustn't contain the string 're:', while also containing the strings 'patch' or 'rfc' (all case insensitive). The query filter is also constructed as an isolated logical expression to not conflict with potential added filters. Note: Took the opportunity to anonymize a test information. Reviewed-by: Rodrigo Siqueira Signed-off-by: David Tadokoro Signed-off-by: Rodrigo Siqueira --- src/lib/lore.sh | 7 ++----- tests/unit/lib/lore_test.sh | 8 ++++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/lib/lore.sh b/src/lib/lore.sh index 3184b785e..4187731a4 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -361,11 +361,8 @@ function compose_lore_query_url_with_verification() return 22 # EINVAL fi - # TODO: We need to use the query prefix 's:Re:' to filter out replies and match - # only real patches. Are we filtering possible patches? If no, can we filter more - # messages to obtain a lighter response file? - query_filter="?x=A&o=${min_index}&q=rt:..+AND+NOT+s:Re" - [[ -n "$additional_filters" ]] && query_filter+="+AND+${additional_filters}" + query_filter="?x=A&o=${min_index}&q=((s:patch+OR+s:rfc)+AND+NOT+s:re:)" + [[ -n "$additional_filters" ]] && query_filter+="+AND+(${additional_filters})" query_url="${LORE_URL}/${target_mailing_list}/${query_filter}" printf '%s' "$query_url" } diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index 1522ec938..11d8fbe13 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -487,22 +487,22 @@ function test_compose_lore_query_url_with_verification_valid_cases() target_mailing_list='amd-gfx' min_index='200' - expected='https://lore.kernel.org/amd-gfx/?x=A&o=200&q=rt:..+AND+NOT+s:Re' + expected='https://lore.kernel.org/amd-gfx/?x=A&o=200&q=((s:patch+OR+s:rfc)+AND+NOT+s:re:)' output=$(compose_lore_query_url_with_verification "$target_mailing_list" "$min_index") assert_equals_helper 'Valid arguments should return 0' "$LINENO" 0 "$?" assert_equals_helper 'Wrong query URL outputted' "$LINENO" "$expected" "$output" target_mailing_list='amd-gfx' min_index='-200' - expected='https://lore.kernel.org/amd-gfx/?x=A&o=-200&q=rt:..+AND+NOT+s:Re' + expected='https://lore.kernel.org/amd-gfx/?x=A&o=-200&q=((s:patch+OR+s:rfc)+AND+NOT+s:re:)' output=$(compose_lore_query_url_with_verification "$target_mailing_list" "$min_index") assert_equals_helper 'Valid arguments should return 0' "$LINENO" 0 "$?" assert_equals_helper 'Wrong query URL outputted' "$LINENO" "$expected" "$output" target_mailing_list='amd-gfx' min_index='200' - additional_filters='s:drm%2Famdgpu+AND+NOT+f:David%20Tadokoro' - expected='https://lore.kernel.org/amd-gfx/?x=A&o=200&q=rt:..+AND+NOT+s:Re+AND+s:drm%2Famdgpu+AND+NOT+f:David%20Tadokoro' + additional_filters='s:drm%2Famdgpu+AND+NOT+f:Linus%20Torvalds' + expected='https://lore.kernel.org/amd-gfx/?x=A&o=200&q=((s:patch+OR+s:rfc)+AND+NOT+s:re:)+AND+(s:drm%2Famdgpu+AND+NOT+f:Linus%20Torvalds)' output=$(compose_lore_query_url_with_verification "$target_mailing_list" "$min_index" "$additional_filters") assert_equals_helper 'Valid arguments should return 0' "$LINENO" 0 "$?" assert_equals_helper 'Wrong query URL outputted' "$LINENO" "$expected" "$output" From aa867af3e47ee91902b0fda5338b4edbd8a22b11 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Mon, 12 Feb 2024 22:24:55 -0300 Subject: [PATCH 051/128] src: kw_remote: Fix typo in short help Running `kw remote -h` outputs the short help of the `kw remote` feature. In this short help, there is a typo of the word 'remote', so fix the typo. Reviewed-by: Rodrigo Siqueira Signed-off-by: David Tadokoro Signed-off-by: Rodrigo Siqueira --- src/kw_remote.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kw_remote.sh b/src/kw_remote.sh index bd0963ae6..5f6a88dd8 100644 --- a/src/kw_remote.sh +++ b/src/kw_remote.sh @@ -428,7 +428,7 @@ function remote_help() ' remote [--global] --add [--set-default] - Add new remote' \ ' remote [--global] --remove - Remove remote' \ ' remote [--global] --rename - Rename remote' \ - ' remote [--global] --set-default= - Set default remote' \ + ' remote [--global] --set-default= - Set default remote' \ ' remote [--global] --list - List remotes' \ ' remote [--global] (--verbose | -v) - be verbose' } From 974e5a3f356348f48939df592cc3656cf9adbdac Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Sun, 11 Feb 2024 09:36:48 -0700 Subject: [PATCH 052/128] src: kw_env: Improve env list output Recently, we got some user feedback that they wish to know the env path to enable them to use other kernel custom commands. This commit addresses this issue by improving the kw env --list to also show the env path. Reviewed-by: David Tadokoro Signed-off-by: Rodrigo Siqueira Signed-off-by: David Tadokoro --- src/kw_env.sh | 34 +++++++++++++++++++++++----------- tests/unit/kw_env_test.sh | 7 +++---- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/kw_env.sh b/src/kw_env.sh index dfb59a957..6c73e1e90 100644 --- a/src/kw_env.sh +++ b/src/kw_env.sh @@ -293,6 +293,12 @@ function destroy_env() success "The \"${env_name}\" environment has been destroyed." } +function no_env_message() +{ + say 'Kw did not find any environment. You can create a new one with the --create option.' + say 'See kw env --help' +} + # This function searches for any folder inside the .kw directory and considers # it an env. # @@ -302,8 +308,7 @@ function list_env_available_envs() { local local_kw_configs="${PWD}/.kw" local current_env - local output - local ret + declare -a all_envs if [[ ! -d "$local_kw_configs" ]]; then complain 'It looks like that you did not setup kw in this repository.' @@ -311,22 +316,29 @@ function list_env_available_envs() exit 22 # EINVAL fi - output=$(ls "${local_kw_configs}/${ENV_DIR}" 2> /dev/null) - ret=$? - if [[ ret -ne 0 || -z $output ]]; then - say 'Kw did not find any environment. You can create a new one with the --create option.' - say 'See kw env --help' + if [[ ! -d "${local_kw_configs}/${ENV_DIR}" ]]; then + no_env_message + return 0 + fi + + readarray -t all_envs < <(find "${local_kw_configs}/${ENV_DIR}" -maxdepth 1 -type d -printf '%P\n' | sort --dictionary-order) + if [[ "${#all_envs[@]}" -eq 0 ]]; then + no_env_message return 0 fi if [[ -f "${local_kw_configs}/${ENV_CURRENT_FILE}" ]]; then current_env=$(< "${local_kw_configs}/${ENV_CURRENT_FILE}") - say "Current env:" - printf ' -> %s\n' "$current_env" + say 'Current env:' + printf ' -> %s: %s\n\n' "$current_env" "${KW_CACHE_DIR}/${ENV_DIR}/${current_env}" fi - say 'All kw environments set for your local folder:' - printf '%s\n' "$output" + warning 'Other kw environments:' + # For the below loop, we want to split the array + # shellcheck disable=SC2068 + for env in ${all_envs[@]}; do + printf ' * %s: %s\n' "$env" "${KW_CACHE_DIR}/${ENV_DIR}/${env}" + done } function parse_env_options() diff --git a/tests/unit/kw_env_test.sh b/tests/unit/kw_env_test.sh index f995c166a..8c3e9bcf8 100755 --- a/tests/unit/kw_env_test.sh +++ b/tests/unit/kw_env_test.sh @@ -112,13 +112,12 @@ function test_show_available_envs() create_new_env local expected=( - 'All kw environments set for your local folder:' - 'farofa' - 'tapioca' + 'Other kw environments:' + "* farofa: ${KW_CACHE_DIR}/${ENV_DIR}/farofa" + "* tapioca: ${KW_CACHE_DIR}/${ENV_DIR}/tapioca" ) output=$(list_env_available_envs) - compare_command_sequence 'Did not list all envs correctly' "$LINENO" 'expected' "$output" } From 41c0dea2195b33dab5b0dbeba42b38a757cb86ce Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Mon, 12 Feb 2024 22:07:59 -0300 Subject: [PATCH 053/128] src: _kw: Revise `kw remote` Zsh completions The Zsh completions for the `kw remote` feature are broken, because: 1. The `--list`, `--add`, `--rename`, and `remove` aren't mutually exclusive, as they should. 2. The `--add` and `--rename` options require 2 arguments, but the completions assume they don't need any and suggest other options. 3. The `--remove` option requires 1 argument, but the completions assume it doesn't need any and suggest other options. 4. The `--set-default|-s` option followed by `--add` shouldn't accept arguments, yet it does. In this sense, fix problems 1 to 3 by declaring `--add`, `--rename`, and `--remove` as completions to `_arguments` instead of `_describe`, and fix 4 by altering the completion of `--set-default|-s`, if `--add` has been completed. Also, to further improve the readability of the code, add names to the arguments of options that need them (see the option `--add`, for reference). These are not obligatory but are a way of documenting the arguments. Signed-off-by: David Tadokoro --- src/_kw | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/_kw b/src/_kw index 63387e025..2c19310e7 100644 --- a/src/_kw +++ b/src/_kw @@ -438,20 +438,26 @@ _kw_pomodoro() _kw_remote() { - local -a remote_commands=( - '--add:add a named remote to kw management' - '--remove:remove an existing remote from kw management' - '--rename:rename an existing remote' + local -a set_default=() + + set_default=( + '(-s --set-default --add --list --remove --rename)'{-s-,--set-default=}'[set existing remote as default]:remote-name: ' ) + if ((words[(I)--add])); then + set_default=( + '(-s --set-default --list --remove --rename)'{-s,--set-default}'[set remote to be added as default]' + ) + fi + _arguments : \ + '--global[use global configurations]' \ '(-v --verbose)'{-v,--verbose}'[be a little more verbose and show remote url after name]' \ - '(-s --set-default)--list[list all available remotes]' \ - '(-s --set-default --list)'{-s-,--set-default=-}'[set default remote to an existing one]: : ' \ - - if [[ "$CURRENT" -lt 3 ]]; then - _describe -t remote-commands 'remote command' remote_commands - fi + '(-s --set-default --add --remove --rename)--list[list all available remotes]' \ + '(--list --remove --rename)--add[add a named remote to kw management]:remote-name: :user-ip-port: ' \ + '(--list -s --set-default --add --remove)--rename[rename an existing remote from kw management]:old-remote-name: :new-remote-name: ' \ + '(--list -s --set-default --add --rename)--remove[remove an existing remote from kw management]:remote-name: ' \ + $set_default } _kw_r() { _kw_report } From d1556d2db233e0608541cb4929ed6caf483afa6a Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Thu, 15 Feb 2024 18:29:45 -0300 Subject: [PATCH 054/128] tests: integration: utils: fix container_exec for enhanced command execution This adjustment, including proper handling of options, container names, and the command to execute with special consideration for the '/bin/sh -c' option, promotes a more reliable and secure execution process. The commit aims to enhance the overall functionality and robustness of the container_exec function when dealing with various command scenarios. Closes: #1040 Reviewed-by: David Tadokoro Signed-off-by: Aquila Macedo Signed-off-by: David Tadokoro --- tests/integration/config_test.sh | 2 +- tests/integration/utils.sh | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/tests/integration/config_test.sh b/tests/integration/config_test.sh index ff5bf85b3..7e4597863 100755 --- a/tests/integration/config_test.sh +++ b/tests/integration/config_test.sh @@ -38,7 +38,7 @@ function local_config_test_helper() container="kw-${distro}" # get the output inside the container - output=$(container_exec --workdir '/tmp' "${container}" "kw config --show --local ${config}") + output=$(container_exec "${container}" "kw config --show --local ${config}" '--workdir=/tmp') if [[ "$?" -ne 0 ]]; then fail "(${LINENO}) kw failed to show local variables in ${distro}" diff --git a/tests/integration/utils.sh b/tests/integration/utils.sh index 0bf75e17b..da85fb009 100755 --- a/tests/integration/utils.sh +++ b/tests/integration/utils.sh @@ -114,8 +114,7 @@ function setup_container_environment() # Container images already have kw installed. Install it again, overwriting # the installation. - container_exec "${container_name}" \ - ./setup.sh --install --force --skip-checks --skip-docs > /dev/null 2>&1 + container_exec "${container_name}" './setup.sh --install --force --skip-checks --skip-docs > /dev/null 2>&1' if [[ "$?" -ne 0 ]]; then fail "(${LINENO}): Failed to install kw in the container ${container_name}" @@ -168,10 +167,25 @@ function container_run() fi } +# Execute a command within a container. +# +# @container_name The name or ID of the target container. +# @container_command The command to be executed within the container. +# @podman_exec_options Extra parameters for 'podman container exec' like +# --workdir, --env, and other supported options. function container_exec() { - # shellcheck disable=SC2068 - podman container exec $@ 2> /dev/null + local container_name="$1" + local container_command="$2" + local podman_exec_options="$3" + local cmd='podman container exec' + + if [[ -n "$podman_exec_options" ]]; then + cmd+=" ${podman_exec_options}" + fi + + cmd+=" ${container_name} /bin/sh -c '${container_command}' 2> /dev/null" + eval "$cmd" if [[ "$?" -ne 0 ]]; then fail "(${LINENO}): Failed to execute the command in the container." From 9e405552cd83fc69d39f6592c8c9eb870e00ce52 Mon Sep 17 00:00:00 2001 From: Marcelo Mendes Spessoto Junior Date: Sat, 17 Feb 2024 18:41:12 -0300 Subject: [PATCH 055/128] kw: remove kw vars Completely remove kw vars functionality as this feature has been deprecated by the kw config --show functionality. This commit does the following: * change documentation to recommend kw config --show instead of kw vars * remove kw vars documentation and base code * remove show_variables_main function used internally by kw vars and its tests Closes: #1026 Reviewed-by: David Tadokoro Signed-off-by: Marcelo Mendes Spessoto Junior Signed-off-by: David Tadokoro --- documentation/conf.py | 1 - documentation/man/features/kw-vars.rst | 14 --- documentation/man/kw.rst | 1 - documentation/tutorials/kw-env.rst | 4 +- documentation/tutorials/setup.rst | 2 +- kw | 7 -- src/_kw | 8 +- src/bash_autocomplete.sh | 2 +- src/help.sh | 1 - src/lib/kw_config_loader.sh | 108 ------------------------ tests/unit/lib/kw_config_loader_test.sh | 106 ----------------------- 11 files changed, 5 insertions(+), 249 deletions(-) delete mode 100644 documentation/man/features/kw-vars.rst diff --git a/documentation/conf.py b/documentation/conf.py index 6d9251d5f..80b29425f 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -177,7 +177,6 @@ ('man/features/kw-pomodoro', 'kw-pomodoro', 'pomodoro style time management', [author], 1), ('man/features/kw-report', 'kw-report', 'user data report support', [author], 1), ('man/features/kw-ssh', 'kw-ssh', 'ssh access', [author], 1), - ('man/features/kw-vars', 'kw-vars', 'view kw config values', [author], 1), ('man/features/kw-vm', 'kw-vm', 'commands to work with QEMU VMs', [author], 1), ('man/features/kw-self-update', 'kw-self-update', 'kw self-update mechanism', ['David Tadokoro, Everaldo Junior'], 1), ('man/features/kw-patch-hub', 'kw-patch-hub', 'UI with lore.kernel.org archives', ['David Tadokoro, Rodrigo Siqueira'], 1), diff --git a/documentation/man/features/kw-vars.rst b/documentation/man/features/kw-vars.rst deleted file mode 100644 index 8cf3b0a54..000000000 --- a/documentation/man/features/kw-vars.rst +++ /dev/null @@ -1,14 +0,0 @@ -=============================== -kw-vars - View kw config values -=============================== - -.. _vars-doc: - -SYNOPSIS -======== -*kw vars* - -DESCRIPTION -=========== -Shows configurations being used by **kw** in the current working directory. To -do that, it examines both global and local **kworkflow.config** files. diff --git a/documentation/man/kw.rst b/documentation/man/kw.rst index adbcb2ab3..0f2190505 100644 --- a/documentation/man/kw.rst +++ b/documentation/man/kw.rst @@ -93,7 +93,6 @@ the previous sections. | :ref:`kw-device` | :ref:`kw-ssh` | :ref:`kw-kernel-config-manager` - | :ref:`kw-vars` | :ref:`kw-diff` | :ref:`kw-report` | :ref:`kw-pomodoro` diff --git a/documentation/tutorials/kw-env.rst b/documentation/tutorials/kw-env.rst index 91e03cba4..5a3e159cb 100644 --- a/documentation/tutorials/kw-env.rst +++ b/documentation/tutorials/kw-env.rst @@ -63,7 +63,7 @@ Let's say that you want to switch from one config to another, you can just use:: If you want to check if everything looks correct, you can use:: - kw vars + kw config --show How to customize your bash terminal to display the current environment ---------------------------------------------------------------------- @@ -90,4 +90,4 @@ Once enabled, you need to add the following line to the .bashrc file:: .. note:: If you have modified the PS1 variable in the .bashrc file, you will need to adapt it to work correctly. You can simply call the ``kw_get_current_env_name`` function - on PS1 to display the current environment being used in kworkflow. \ No newline at end of file + on PS1 to display the current environment being used in kworkflow. diff --git a/documentation/tutorials/setup.rst b/documentation/tutorials/setup.rst index be06e279d..abefff33c 100644 --- a/documentation/tutorials/setup.rst +++ b/documentation/tutorials/setup.rst @@ -103,7 +103,7 @@ When configuring kw, you might want to start looking at theses options: After making some changes, check that kw is incorporating them with:: - kw vars + kw config --show which simply shows all the defined configuration options. diff --git a/kw b/kw index 9a0693688..6c6e5bcbd 100755 --- a/kw +++ b/kw @@ -161,13 +161,6 @@ function kw() kw_ssh_main "$@" ) ;; - vars) - ( - include "${KW_LIB_DIR}/lib/kw_config_loader.sh" - - show_variables_main "$@" - ) - ;; codestyle | c) ( include "${KW_LIB_DIR}/codestyle.sh" diff --git a/src/_kw b/src/_kw index 2c19310e7..e5079cedb 100644 --- a/src/_kw +++ b/src/_kw @@ -43,7 +43,6 @@ _kw() 'self-update:kw self-update mechanism' 'ssh:SSH support' 'patch-hub: Open UI with lore.kernel.org archives' - 'vars:Show variables' 'version:Show kw version' ) @@ -406,7 +405,7 @@ _kw_man() _values 'kw commands' \ 'backup' 'build' 'codestyle' 'config' 'debug' 'deploy' 'device' 'diff' 'drm' 'env' \ 'explore' 'init' 'mail' 'maintainers' 'pomodoro' 'remote' 'report' 'self-update' 'ssh' \ - 'patch-hub' 'vars' + 'patch-hub' } _kw_p() { _kw_pomodoro } @@ -506,11 +505,6 @@ _kw_patch-hub() _nothing } -_kw_vars() -{ - _nothing -} - _kw_version() { _nothing diff --git a/src/bash_autocomplete.sh b/src/bash_autocomplete.sh index 2d553d8f4..4fb435e81 100644 --- a/src/bash_autocomplete.sh +++ b/src/bash_autocomplete.sh @@ -13,7 +13,7 @@ function _kw_autocomplete() current_command="${COMP_WORDS[$COMP_CWORD]}" previous_command="${COMP_WORDS[$comp_curr - 1]}" - kw_options['kw']='init build deploy bd diff ssh vars codestyle self-update + kw_options['kw']='init build deploy bd diff ssh codestyle self-update maintainers kernel-config-manager config remote explore pomodoro report device backup debug mail env patch-hub clear-cache drm vm version man help' diff --git a/src/help.sh b/src/help.sh index b3c1eed09..22fb97ef3 100644 --- a/src/help.sh +++ b/src/help.sh @@ -16,7 +16,6 @@ function kworkflow_help() ' bd - Build and install kernel image/modules' \ ' diff,df - Diff files' \ ' ssh,s - SSH support' \ - ' vars - Show kw variables' \ ' codestyle,c - Apply checkpatch on directory or file' \ ' self-update,u - kw self-update mechanism' \ ' maintainers,m - Get maintainers and mailing list' \ diff --git a/src/lib/kw_config_loader.sh b/src/lib/kw_config_loader.sh index 5030f9c01..7a4ddb614 100644 --- a/src/lib/kw_config_loader.sh +++ b/src/lib/kw_config_loader.sh @@ -56,103 +56,6 @@ declare -gA lore_config_local # Default target option from kworkflow.config declare -gA deploy_target_opt=(['local']=2 ['remote']=3) -# This function is used to show the current set up used by kworkflow. -function show_variables_main() -{ - local test_mode=0 - local has_local_config='No' - - load_all_config - - if [[ "$1" =~ ^-h|^--help ]]; then - vars_help "$@" - exit 0 - fi - - # TODO: Drop [[ -f "$PWD/$CONFIG_FILENAME" ]] in the future - if [[ -f "${PWD}/${KW_DIR}/${CONFIG_FILENAME}" || -f "${PWD}/${CONFIG_FILENAME}" ]]; then - has_local_config='Yes' - fi - - if [[ "$1" == 'TEST_MODE' ]]; then - test_mode=1 - fi - - local -Ar ssh=( - [ssh_user]='SSH user' - [ssh_ip]='SSH address' - [ssh_port]='SSH port' - [ssh_configfile]='SSH configuration file' - [hostname]='Hostname of the target in the SSH configuration file' - ) - - local -Ar misc=( - [disable_statistics_data_track]='Disable tracking of statistical data' - [gui_on]='Command to activate GUI' - [gui_off]='Command to deactivate GUI' - [checkpatch_opts]='Options to be used in the checkpatch script' - [get_maintainer_opts]='Options to be used in the get_maintainer script' - ) - - local -Ar group_descriptions=( - [build]='Kernel build options' - [deploy]='Kernel deploy options' - [mail]='Send-email options' - [ssh]='SSH options' - [vm]='VM options' - [notification]='Notification options' - [misc]='Miscellaneous options' - [lore]='Upstream patches from Lore options' - ) - - groups=( - 'deploy' - 'mail' - 'ssh' - 'vm' - 'notification' - 'misc' - 'build' - 'lore' - ) - - say 'kw configuration variables:' - printf '%s\n' " Local config file: $has_local_config" - - for group in "${groups[@]}"; do - local -n descriptions="$group" - case "$group" in - 'build') - show_build_variables "$@" - continue - ;; - 'deploy') - show_deploy_variables "$@" - continue - ;; - 'mail') - show_mail_variables "$@" - continue - ;; - 'notification') - show_notification_variables "$@" - continue - ;; - 'vm') - show_vm_variables "$@" - continue - ;; - 'lore') - show_lore_variables "$@" - continue - ;; - esac - - printf '%s\n' " ${group_descriptions["$group"]}:" - print_array configurations descriptions "$test_mode" - done -} - # This is a helper function that prints the option description followed by the # option value. # @@ -505,14 +408,3 @@ load_all_config() load_lore_config load_vm_config } - -function vars_help() -{ - if [[ "$1" == --help ]]; then - include "$KW_LIB_DIR/help.sh" - kworkflow_man 'vars' - return - fi - printf '%s\n' 'kw vars:' \ - ' vars - Show current variable values being used by kw.' -} diff --git a/tests/unit/lib/kw_config_loader_test.sh b/tests/unit/lib/kw_config_loader_test.sh index b43883c9b..d7153edaf 100755 --- a/tests/unit/lib/kw_config_loader_test.sh +++ b/tests/unit/lib/kw_config_loader_test.sh @@ -253,112 +253,6 @@ function get_all_assigned_options_to_string_helper() printf '%s' "$output" } -function test_show_variables_main_completeness() -{ - local -A shown_options - local -A possible_options - local output - local output_vm - local output_mail - local output_build - local output_deploy - local output_notification - - configurations=() - - # get all assigned options, including commented ones - # remove #'s and ='s to get option names - output=$(get_all_assigned_options_to_string_helper "$KW_CONFIG_TEMPLATE") - output_build="$(get_all_assigned_options_to_string_helper "$KW_BUILD_CONFIG_SAMPLE")" - output_deploy="$(get_all_assigned_options_to_string_helper "$KW_DEPLOY_CONFIG_SAMPLE")" - output_vm="$(get_all_assigned_options_to_string_helper "$KW_VM_CONFIG_SAMPLE")" - output_mail="$(get_all_assigned_options_to_string_helper "$KW_MAIL_CONFIG_SAMPLE")" - output_notification="$(get_all_assigned_options_to_string_helper "$KW_NOTIFICATION_CONFIG_SAMPLE")" - - output+=" $output_build $output_deploy $output_vm $output_mail $output_notification" - for option in $output; do - possible_options["$option"]=1 - done - - cp "$KW_CONFIG_SAMPLE" "$TMPDIR_KW_FOLDER" - cp "$KW_BUILD_CONFIG_SAMPLE" "$TMPDIR_KW_FOLDER" - cp "$KW_VM_CONFIG_SAMPLE" "$TMPDIR_KW_FOLDER" - cp "$KW_MAIL_CONFIG_SAMPLE" "$TMPDIR_KW_FOLDER" - cp "$KW_NOTIFICATION_CONFIG_SAMPLE" "$TMPDIR_KW_FOLDER" - cp "${SAMPLES_DIR}/deploy_all_options.config" "${TMPDIR_KW_FOLDER}/deploy.config" - - load_all_config - - output="$(show_variables_main 'TEST_MODE' | grep -E '^ ')" - output="$(printf '%s\n' "$output" | sed 's/.*(\(\S*\)).*/\1/')" - - for option in $output; do - shown_options["$option"]=1 - done - - assert_configurations_helper possible_options shown_options "$LINENO" -} - -function test_show_variables_main_correctness() -{ - local output - local option - local value - local message - - # show_variables_main will load the config file, and for this test we want to - # avoid this behaviour. For this reason, we are deleting the .kw folder - rm -rf .kw - - declare -gA configurations=( - [ssh_ip]=1 - [ssh_port]=2 - [mount_point]='/home/lala' - [menu_config]=4 - [virtualizer]='libvirt' - [qemu_hw_options]=6 - [qemu_net_options]=7 - [qemu_path_image]='/home/xpto/p/virty.qcow2' - [alert]='n' - [sound_alert_command]='paplay SOUNDPATH/bell.wav' - [visual_alert_command]='notify-send lala' - [default_deploy_target]=vm - [reboot_after_deploy]='no' - [deploy_temporary_files_path]='/tmp/kw' - [dtb_copy_pattern]='broadcom/*.dtb' - [strip_modules_debug_option]='yes' - [deploy_default_compression]='lzop' - [kw_files_remote_path]='/opt/kw' - [send_opts]='--annotate --cover-letter --no-chain-reply-to --thread' - [blocked_emails]='test@email.com' - [disable_statistics_data_track]=14 - [gui_on]=15 - [gui_off]=16 - ) - - output="$(show_variables_main | grep -E '^\s{3,}')" - - # The `read` command will read all the characters untill it finds a newline - # character and then write those characters onto the given variable (in this - # case, the `line` variable). If it does not find a newline `\n` character, it - # will exit with status code 1. This evaluates to false, which means the - # shellscript exits the loop. Therefore, if the last line is not empty but - # misses the newline character, the loop won't be run and the last config - # option won't be read. We handle this edge case by checking if line is not - # empty and proceeding to run the loop once more if necessary. - # - # shellcheck disable=SC2162 - while read -r line || [[ -n "$line" ]]; do - option="$(printf '%s\n' "$line" | sed -E 's/.*\((\S*)\).*/\1/')" - value=$(printf '%s\n' "$line" | sed -E 's/.*: (.*)/\1/') - if [[ "${configurations[$option]}" != "$value" ]]; then - message="Value of option $option should be " - message+="${configurations["$option"]} but is $value" - fail "($LINENO): $message" - fi - done <<< "$output" -} - function test_load_configuration() { local msg='We will stop supporting kworkflow.config in the kernel root directory in favor of using a .kw/ directory.' From 1dde3ceb2c714c708f4671b1a65986410c032be1 Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Tue, 27 Feb 2024 16:05:47 -0300 Subject: [PATCH 056/128] tests: integration: device_test: exclude 'Distribution base' field This commit exclude 'Distribution base' field from filtering due to the clear indication that it won't yield a match during processing. Closes: #1048 Reviewed-by: Rodrigo Siqueira Signed-off-by: Aquila Macedo Signed-off-by: Rodrigo Siqueira --- tests/integration/device_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/device_test.sh b/tests/integration/device_test.sh index daee54d2e..3a859d944 100755 --- a/tests/integration/device_test.sh +++ b/tests/integration/device_test.sh @@ -23,8 +23,8 @@ function device_info_test_helper() # some fields must be ignored because they surely won't match. filter=( - 'Root filesystem' 'Size' 'Mounted on' # storage fields - 'Distribution' 'Distribution version' 'Desktop environments' # desktop fields + 'Root filesystem' 'Size' 'Mounted on' # storage fields + 'Distribution' 'Distribution base' 'Distribution version' 'Desktop environments' # desktop fields ) # add | separator to each filter item. From 2a63eb1f1918d22c949070a5e7be73a2a8058fab Mon Sep 17 00:00:00 2001 From: aqu1la Date: Tue, 20 Feb 2024 16:14:20 -0300 Subject: [PATCH 057/128] .github: workflows: integration_tests: integration tests workflow This commit creates a workflow in GitHub Actions for integration tests Reviewed-by: Rodrigo Siqueira Signed-off-by: Aquila Macedo Signed-off-by: Rodrigo Siqueira --- .github/workflows/integration_tests.yml | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/integration_tests.yml diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml new file mode 100644 index 000000000..990ffa62e --- /dev/null +++ b/.github/workflows/integration_tests.yml @@ -0,0 +1,36 @@ +name: Integration tests +on: + [push, pull_request] + +jobs: + initialize-repository: + runs-on: ubuntu-latest + defaults: + run: + shell: bash + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 1 + + integration-tests: + needs: initialize-repository + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 1 + + - name: Update the system + run: sudo apt update -y + + - name: Install dependencies + run: | + sudo apt install -y shunit2 podman + + - name: Integration tests + run: ./run_tests.sh --integration From 9b1ea6f93331c09c79f9f1862e114297c8f422ac Mon Sep 17 00:00:00 2001 From: sahil-sagwekar2652 Date: Thu, 28 Mar 2024 22:56:32 +0530 Subject: [PATCH 058/128] github: workflows: *.yml: update the checkout action version GitHub actions using Node.js 16 are being deprecated. This also comes up as a warning in the workflow run logs. This commit updates the checkout actions version to v4 which uses Node.js 20 Reviewed-by: Rodrigo Siqueira Signed-off-by: Sahil Sagwekar Signed-off-by: Rodrigo Siqueira --- .github/workflows/integration_tests.yml | 4 ++-- .github/workflows/kcov.yml | 2 +- .github/workflows/shellcheck_reviewdog.yml | 2 +- .github/workflows/shfmt.yml | 2 +- .github/workflows/test_setup_and_docs.yml | 2 +- .github/workflows/unit_tests.yml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 990ffa62e..29ed436db 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 1 @@ -21,7 +21,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 1 diff --git a/.github/workflows/kcov.yml b/.github/workflows/kcov.yml index 9d2912b4d..5ca313ce8 100644 --- a/.github/workflows/kcov.yml +++ b/.github/workflows/kcov.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 3 diff --git a/.github/workflows/shellcheck_reviewdog.yml b/.github/workflows/shellcheck_reviewdog.yml index 528d2360a..6629e9f49 100644 --- a/.github/workflows/shellcheck_reviewdog.yml +++ b/.github/workflows/shellcheck_reviewdog.yml @@ -6,7 +6,7 @@ jobs: name: runner / shellcheck runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: shellcheck uses: reviewdog/action-shellcheck@v1 with: diff --git a/.github/workflows/shfmt.yml b/.github/workflows/shfmt.yml index 10dda5224..7022c28c3 100644 --- a/.github/workflows/shfmt.yml +++ b/.github/workflows/shfmt.yml @@ -5,7 +5,7 @@ jobs: sh-checker: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Run the sh-checker uses: luizm/action-sh-checker@v0.3.0 env: diff --git a/.github/workflows/test_setup_and_docs.yml b/.github/workflows/test_setup_and_docs.yml index c4ed379d4..7ae18f206 100644 --- a/.github/workflows/test_setup_and_docs.yml +++ b/.github/workflows/test_setup_and_docs.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # This is here just because git-email cannot be installed in the # Github CI otherwise. diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 96ab3f6ec..c9dc41266 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 3 From 9a8f3199399c4606f2294f9a2cb81aaec3b55a96 Mon Sep 17 00:00:00 2001 From: sahil-sagwekar2652 Date: Mon, 1 Apr 2024 21:00:34 +0530 Subject: [PATCH 059/128] documentation: man: features: kw-remote: Fix `-s` option The `-s` option doesn't accept "=" or between it and the value, unlike its long form `--set-default`. This commit fixes the documentation to reflect the above points. Reviewed-by: David Tadokoro Signed-off-by: Sahil Sagwekar Signed-off-by: David Tadokoro --- documentation/man/features/kw-remote.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/documentation/man/features/kw-remote.rst b/documentation/man/features/kw-remote.rst index 5f9368115..9b855bdfd 100644 --- a/documentation/man/features/kw-remote.rst +++ b/documentation/man/features/kw-remote.rst @@ -11,7 +11,7 @@ SYNOPSIS | *kw remote* [--global] \--remove | *kw remote* [--global] \--rename | *kw remote* [--global] \--list -| *kw remote* [--global] (-s | \--set-default)= +| *kw remote* [--global] -s | \--set-default= DESCRIPTION =========== @@ -40,7 +40,7 @@ OPTIONS \--global: Force use global config file instead of the local one. -\-s=, \--set-default=: +\-s, \--set-default=: Set default remote to remote named . \-v, \--verbose: @@ -73,4 +73,3 @@ You can also list all your available remotes via:: If you want to set the default remote:: kw remote --set-default=new-default-remote - From 1ac2c617e8a1397957e3328746d0673b3a303247 Mon Sep 17 00:00:00 2001 From: sahil-sagwekar2652 Date: Tue, 2 Apr 2024 21:21:48 +0530 Subject: [PATCH 060/128] src: report: fix the error messages for no data If the kw report is called without any arguments or with --all flag and the statistics and pomodoro data is not present then ideally we should get two separate errors. But the option_value['ERROR'] value is getting overwritten. So we get two lines displaying the no data for pomodoro error. This commit adds an if clause for this condition and modifies the tests accordingly. Reviewed-by: David Tadokoro Signed-off-by: Sahil Sagwekar Signed-off-by: David Tadokoro --- src/report.sh | 21 ++++++--------------- tests/unit/report_test.sh | 14 ++------------ 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/src/report.sh b/src/report.sh index 158af3b9e..4906065df 100644 --- a/src/report.sh +++ b/src/report.sh @@ -146,8 +146,7 @@ function get_raw_data_from_period_of_time() # associative array in their respective command. # # Return: -# In case there is no statistics raw data to process, returns 2 (ENOENT) and -# sets an error message in 'options_values['ERROR']'. +# In case there is no statistics raw data to process, returns 2 (ENOENT). function process_and_format_statistics_raw_data() { local flag="$1" @@ -159,10 +158,7 @@ function process_and_format_statistics_raw_data() flag=${flag:-'SILENT'} - if [[ -z "${statistics_raw_data}" ]]; then - options_values['ERROR']="kw doesn't have any statistics of the target period: ${target_period}" - return 2 # ENOENT - fi + [[ -z "${statistics_raw_data}" ]] && return 2 # ENOENT for command in "${!statistics[@]}"; do values=$(printf '%s\n' "${statistics_raw_data}" | grep "|${command}|" | cut -d '|' -f6) @@ -194,8 +190,7 @@ function process_and_format_statistics_raw_data() # including an all tag summary. # # Return: -# In case there is no statistics raw data to process, returns 2 (ENOENT) and -# sets an error message in 'options_values['ERROR']'. +# In case there is no statistics raw data to process, returns 2 (ENOENT). function process_and_format_pomodoro_raw_data() { local flag="$1" @@ -216,10 +211,7 @@ function process_and_format_pomodoro_raw_data() flag=${flag:-'SILENT'} - if [[ -z "${pomodoro_raw_data}" ]]; then - options_values['ERROR']="kw doesn't have any Pomodoro data of the target period: ${target_period}" - return 2 # ENOENT - fi + [[ -z "${pomodoro_raw_data}" ]] && return 2 # ENOENT while read -r entry; do tag=$(printf '%s' "$entry" | cut -d '|' -f3) @@ -287,9 +279,8 @@ function show_report() done printf '\n' elif [[ -n "${options_values['STATISTICS']}" ]]; then - warning "${options_values['ERROR']}" + warning "kw doesn't have any statistics of the target period: ${target_period}" fi - if [[ -n "${options_values['POMODORO']}" && -n "${pomodoro_raw_data}" ]]; then say "# Pomodoro Report: ${target_period}" printf '%s\n\n' "${pomodoro_metadata['ALL_TAGS']}" @@ -299,7 +290,7 @@ function show_report() printf '%s\n%s\n' '- Sessions:' "${pomodoro_sessions["$tag"]}" done elif [[ -n "${options_values['POMODORO']}" ]]; then - warning "${options_values['ERROR']}" + warning "kw doesn't have any Pomodoro data of the target period: ${target_period}" fi } diff --git a/tests/unit/report_test.sh b/tests/unit/report_test.sh index 6a3d57cd8..821a981c4 100755 --- a/tests/unit/report_test.sh +++ b/tests/unit/report_test.sh @@ -323,14 +323,10 @@ function test_get_raw_data_from_period_of_time() function test_process_and_format_statistics_raw_data_without_data() { - local expected - target_period='1998/04/17' statistics_raw_data='' process_and_format_statistics_raw_data assert_equals_helper 'Should result in an error code' "$LINENO" 2 "$?" - expected="kw doesn't have any statistics of the target period: ${target_period}" - assert_equals_helper 'Should result in an error message' "$LINENO" "$expected" "${options_values['ERROR']}" } function test_process_and_format_statistics_raw_data_with_data() @@ -388,14 +384,10 @@ function test_process_and_format_statistics_raw_data_with_data() function test_process_and_format_pomodoro_raw_data_without_data() { - local expected - target_period='day 1998/04/17' pomodoro_raw_data='' process_and_format_pomodoro_raw_data assert_equals_helper 'Should result in an error code' "$LINENO" 2 "$?" - expected="kw doesn't have any Pomodoro data of the target period: ${target_period}" - assert_equals_helper 'Should result in an error message' "$LINENO" "$expected" "${options_values['ERROR']}" } function test_process_and_format_pomodoro_raw_data_with_data() @@ -451,18 +443,16 @@ function test_show_report() # Error message for statistics options_values['STATISTICS']=1 statistics_raw_data='' - options_values['ERROR']='Some error message' output=$(show_report) - expected='Some error message' + expected="kw doesn't have any statistics of the target period: ${target_period}" assert_equals_helper 'No statistics should result in error message' "$LINENO" "$expected" "$output" # Error message for Pomodoro options_values['STATISTICS']='' options_values['POMODORO']=1 pomodoro_raw_data='' - options_values['ERROR']='Another error message' output=$(show_report) - expected='Another error message' + expected="kw doesn't have any Pomodoro data of the target period: ${target_period}" assert_equals_helper 'No Pomodoro data should result in error message' "$LINENO" "$expected" "$output" # Expect output for statistics From 358bafaffb0d57329537631966b0237ac3c2b24e Mon Sep 17 00:00:00 2001 From: uwla Date: Wed, 3 Apr 2024 14:45:17 -0300 Subject: [PATCH 061/128] run_tests.sh: add command to clear test caches The command clear-cache clears test cached, either integration or unit, or both. Currently, this new option only clears cached container images used in integration tests, but in the future it could clear unit tests cache if we need to do so. Fixes #1017 Signed-off-by: uwla Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- documentation/content/tests.rst | 11 +- run_tests.sh | 24 ++++- tests/integration/utils.sh | 184 +++++++++++++++++++++++++++++++- 3 files changed, 209 insertions(+), 10 deletions(-) diff --git a/documentation/content/tests.rst b/documentation/content/tests.rst index 2f7bcc7ac..08a81bfd5 100644 --- a/documentation/content/tests.rst +++ b/documentation/content/tests.rst @@ -1,5 +1,5 @@ =============== - About Tests +About Tests =============== .. _tests: @@ -25,7 +25,7 @@ List all available test files:: Or run individual tests with:: - ./run_tests.sh test TESTFILE1 ... + ./run_tests.sh test TEST_FILE_1 ... To limit the scope of the tests, pass the flag `--unit` or `--integration` as the first argument to any of the examples above. So, the syntax is:: @@ -33,7 +33,7 @@ the first argument to any of the examples above. So, the syntax is:: ./run_tests.sh [scope] [command] [args] Where `[scope]` can be `--unit` or `--integration`. The placeholder `[command]` -can be either `list`, `test` or simply omited in order to run all tests. Here +can be either `list`, `test` or simply omitted in order to run all tests. Here are some examples: .. code-block:: bash @@ -41,12 +41,15 @@ are some examples: ./run_tests.sh --unit # run all unit tests ./run_tests.sh --unit list # list all unit tests ./run_tests.sh --unit test device # test device unit test + ./run_tests.sh --unit clear-cache # clear unit tests cache ./run_tests.sh --integration # run all integration tests ./run_tests.sh --integration list # list all integration tests ./run_tests.sh --integration test device # test device integration test + ./run_tests.sh --integration clear-cache # clear integration tests cache ./run_tests.sh # run all tests ./run_tests.sh list # list all tests ./run_tests.sh test device # run all device tests + ./run_tests.sh clear-cache # clear all cache The integration tests can take over 10 minutes to run in the first time because podman is building the container images to be used in the tests, which requires @@ -56,7 +59,7 @@ seconds each time. Then, the local kw repo is copied to the containers and installed again, which takes very few seconds. For optimization purposes, the containers are reused -accross tests. If you add a new commit or checkout to another branch, such that +across tests. If you add a new commit or checkout to another branch, such that HEAD points to another commit, the containers will be destroyed and created again in order to install the current local version of kw. diff --git a/run_tests.sh b/run_tests.sh index 0a5cd44ab..9020398ce 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -18,6 +18,7 @@ function show_help() ' Limit tests to unit tests' \ '' \ 'COMMANDS' \ + ' clear-cache - clears tests cache' \ ' help - displays this help message' \ ' list - lists all test files under tests/' \ ' test - runs the given test' @@ -121,14 +122,25 @@ function run_tests() # amount of time for the integration tests. if [[ "${integration_tests_setup}" == 1 ]]; then printf '\n' # add new line after the last "OK" - say 'Tearing down environment used in integration tests...' - teardown_container_environment + say 'Tearing down containers used in integration tests...' + teardown_containers printf '\n' fi report_results "$total" "$success" "$notfound" "$fail" "$test_failure_list" } +function clear_unit_tests_cache() +{ + say 'Unit tests: nothing cached to clear.' +} + +function clear_integration_tests_cache() +{ + say 'Integration tests: cleaning cache...' + teardown_container_environment "$@" +} + declare -a TESTS function set_tests() { @@ -139,12 +151,16 @@ function set_tests() done } +declare TESTS_UNIT=1 +declare TESTS_INTEGRATION=1 declare TESTS_DIR=./tests if [[ "$1" == '--unit' || "$1" == '-u' ]]; then TESTS_DIR=./tests/unit + TESTS_INTEGRATION=0 shift elif [[ "$1" == '--integration' || "$1" == '-i' ]]; then TESTS_DIR=./tests/integration + TESTS_UNIT=0 shift fi @@ -178,6 +194,10 @@ elif [[ "$1" == 'test' ]]; then files_list=$(find "$TESTS_DIR" | grep --perl-regexp "${regex}" | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') set_tests $files_list LANGUAGE=en_US.UTF_8 run_tests +elif [[ "$1" == 'clear-cache' ]]; then + shift + [[ "${TESTS_UNIT}" == 1 ]] && clear_unit_tests_cache "$@" + [[ "${TESTS_INTEGRATION}" == 1 ]] && clear_integration_tests_cache "$@" else show_help fi diff --git a/tests/integration/utils.sh b/tests/integration/utils.sh index da85fb009..368e20f3a 100755 --- a/tests/integration/utils.sh +++ b/tests/integration/utils.sh @@ -2,6 +2,7 @@ include './src/lib/kwio.sh' +declare -gr CONTAINER_BASE_IMAGE='docker.io/library' declare -g CONTAINER_DIR # Has the container files to build the container images declare -g SAMPLES_DIR # Has sample files used accross the integration tests declare -g KWROOT_DIR # Local kw dir to be copied to and installed in the containers @@ -64,14 +65,14 @@ function setup_container_environment() # Only build the image if it does not exist. That's because trying to build # the podman image takes a second or two even if it exists and is cached. - podman image exists "${container_img}" + image_exists "${container_img}" if [[ "$?" -ne 0 ]]; then current_step=$((current_step + 1)) say "[${current_step}/${total_steps}] Building container image for ${distro}. This might take a while..." build_distro_image "$distro" if [[ "$?" -ne 0 ]]; then - complain "Failed to setup container environment for distro ${distro}" + complain "Failed to setup container for distro ${distro}" current_step=$((current_step + 1)) say "[${current_step}/${total_steps}] Skip creating ${distro} container." @@ -129,7 +130,7 @@ function setup_container_environment() } # Destroy all containers used in the tests -function teardown_container_environment() +function teardown_containers() { local distro local i=0 @@ -144,7 +145,7 @@ function teardown_container_environment() # Destroy a single container # -# @container: Name or ID of the container +# @container Name or ID of the container function teardown_single_container() { local container="$1" @@ -157,6 +158,177 @@ function teardown_single_container() fi } +# Completely remove the container environment: the containers and the images +# +# @flag Optional. Currently, only accepts '-f' or '--force' to force removal of cached images. +function teardown_container_environment() +{ + local flag="$1" + local container_name + local distro + local img + local img_layer_list + local dangling_img + local dangling_img_layer_list + + for distro in "${DISTROS[@]}"; do + container_name="kw-${distro}" + podman container exists "${container_name}" + if [[ "$?" -eq 0 ]]; then + say "Removing podman container kw-${distro}." + teardown_single_container "${container_name}" + fi + + img="kw-${distro}" + image_exists "${img}" + if [[ "$?" -eq 0 ]]; then + say "Removing podman ${img} image." + + # Get this image layers, so we can safely remove its children dangling images. + img_layer_list=$(image_inspect -f '{{.RootFS.Layers}}' "${img}" | tr -d '[]') + + # Remove possible dangling images + while read -r dangling_img; do + # We check if the image exist because it could happen that in the + # previous iteration the father dangling image was deleted, causing the + # child dangling image to be deleted as well. + image_exists "${dangling_img}" + if [[ "$?" -ne 0 ]]; then + continue + fi + + # We check if the dangling image have layers which are exact prefixes of + # the current image we are trying to delete. + dangling_img_layer_list=$(image_inspect -f '{{.RootFS.Layers}}' "${dangling_img}" | tr -d '[]') + grep --perl-regexp "^${dangling_img_layer_list}" <<< "${img_layer_list}" > /dev/null + + # Delete the dangling image if that is the case. + if [[ "$?" -eq 0 ]]; then + # Dangling images are always force-removed. + image_rm --force "${dangling_img}" + fi + done <<< "$(image_ls --all --quiet --filter 'intermediate=true')" + + # Remove main image. + image_rm --force "${img}" + if [[ "$?" -ne 0 ]]; then + complain "Failed to remove ${img} image." + fi + fi + + # Remove the base image for the distro. + img="${CONTAINER_BASE_IMAGE}/${distro}" + image_exists "${img}" + if [[ "$?" -eq 0 ]]; then + say "Removing podman ${img} image." + + if [[ -n "$flag" ]]; then + image_rm "$flag" "$img" + else + image_rm "$img" + fi + fi + done +} + +# Check if the given image exists. +# +# @image The image name or id. +function image_exists() +{ + podman image exists "$1" +} + +# Remove the given images. +# +# @flags Optional flags to be passed to podman. +# If it is '-f' or '--force', then it should be the ONLY flag. +# @images Image names or ids. +function image_rm() +{ + local force_remove=0 + local img + + if [[ "$1" == "-f" || "$1" == "--force" ]]; then + force_remove=1 + shift + fi + + if [[ "$#" -lt 1 ]]; then + complain "(${LINENO}): no image provided to be removed." + return 1 + fi + + # shellcheck disable=SC2068 + podman image rm $@ > /dev/null 2>&1 + + # command succeed. + if [[ "$?" -eq 0 ]]; then + return 0 + fi + + # comman failed and we should not force-attempt it. + if [[ "$force_remove" == 0 ]]; then + complain "(${LINENO}): kw failed to execute \`podman image rm ${*}\`. Consider using --force flag." + return 1 + fi + + # We try it again, this time forcing the removal of the images. + # WARNING: If the first argument is '-f', we suppose all the other ones are the image names. + while [[ "$#" -gt 0 ]]; do + img="$1" + shift + + # Make sure the image exists. + podman image exists "$img" + if [[ "$?" -ne 0 ]]; then + complain "(${LINENO}) provided image '${img}' does not exist." + continue + fi + + # Force remove all containers that depend on that image, one by one. + (podman container ls --all --quiet --filter ancestor="$img" | + xargs -n1 podman container rm --force --time 0) > /dev/null 2>&1 + + # Force remove the image now. + podman image rm --force "$img" > /dev/null 2>&1 + done +} + +# List the given images. +# +# @options Options to be passed to podman. +# @images Image names or ids. +function image_ls() +{ + if [[ "$#" -le 1 ]]; then + complain "(${LINENO}): no image provided to be listed." + return 1 + fi + + # shellcheck disable=SC2068 + podman image ls $@ + + if [[ "$?" -ne 0 ]]; then + complain "(${LINENO}): kw failed to execute \`podman image ls ${*}\`." + fi +} + +# Inspect the given images. +# +# @options Options to be passed to podman. +# @images Image names or ids. +function image_inspect() +{ + # shellcheck disable=SC2068 + podman image inspect $@ + + if [[ "$?" -ne 0 ]]; then + complain "(${LINENO}): kw failed to execute \`podman image inspect ${*}\`." + fi +} + +# run a container function container_run() { # shellcheck disable=SC2068 @@ -210,6 +382,10 @@ function container_copy() fi } +# Inspect the given containers. +# +# @options Options to be passed to podman. +# @images Container names or ids. function container_inspect() { # shellcheck disable=SC2068 From ce41fae0e45af1395beffd6e1ef02f6792d3f497 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Thu, 7 Mar 2024 08:52:22 -0300 Subject: [PATCH 062/128] src: lib: lore: Obtain patch metadata more robustly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `kw patch-hub` feature depends heavily on correctly attaining a patch metadata. This includes the patch version, the total number of patches in its series, and its title stripped from the patch tag (strings in the fashion of `[PATCH vX YY/ZZ]`, and the like). However, the version and the patch tag are obtained by parsing the patch title in not the most reliable way. The case is worst when getting the total number of patches in the series, as this triggers chained network requests that can range around one hundred in extreme cases, resulting in unsatisfactory (and unpredictable) performance. To make the attainment of patch metadata more robust, do the following: 1. Extract methods to get each type of metadata (this was all mixed inside the function `extract_metadata_from_patch_title`); 2. Consider more cases when parsing the title for metadata; 3. Remove any network logic when obtaining the total number of patches. Note: This commit also adds a function to get the number/index of the patch in the series metadata, which is not being used by `kw patch-hub` at the moment but will be in future commits. Helps: #911 Signed-off-by: David Tadokoro Co-authored-by: AndrĆ© Gustavo Co-authored-by: Guilherme Moreno Signed-off-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/lib/lore.sh | 241 +++++++++++++++++++------- tests/unit/lib/lore_test.sh | 335 ++++++++++++++++++++++++++++++++++-- 2 files changed, 495 insertions(+), 81 deletions(-) diff --git a/src/lib/lore.sh b/src/lib/lore.sh index 4187731a4..ef274e112 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -160,57 +160,187 @@ function is_introduction_patch() return 1 } -# Verify if the target URL is accessible or not. +# This function extracts the patch metadata of a lore message title. A patch +# metadata is a string surrounded by square brackets that contains the word +# "PATCH" and/or "RFC". # -# @url Target url +# For example, considering `@message_title` equal to +# '[V3 Patch 3/7] some/subsys: Do foo', +# the outputted patch metadata will be '[V3 Patch 3/7]'. +# +# @message_title: Message title of a lore message. +# +# Return: If the function finds a patch metadata as a substring of `@message_title`, +# outputs the patch metadata, otherwise, output an empty string. +function get_patch_metadata() +{ + local message_title="$1" + local patch_metadata + + if [[ "$message_title" =~ \[[^\]]*([Rr][Ff][Cc]|[Pp][Aa][Tt][Cc][Hh])[^\[]*\] ]]; then + patch_metadata="${BASH_REMATCH[0]}" + fi + + printf '%s' "$patch_metadata" +} + +# This function extracts the version number of a patch from a patch metadata. +# The version number is the integer that follows the letters 'v' and 'V'. +# +# For example, considering `@patch_metadata` equal to +# '[rfc patch v4]', +# the outputted version will be '4'. +# +# @patch_metadata: Patch metadata of lore message. # # Return: -# If the URL is accessible, return 0. Otherwise, return 22. -function is_the_link_valid() +# If `@patch_metadata` is non-empty, output the version and return 0. Otherwise, +# return 2 (ENOENT) and output 'X', meaning 'undefined'. +function get_patch_version() { - local url="$1" - local curl_cmd='curl --insecure --silent --fail --silent --head' - local raw_curl_output - local url_status_code + local patch_metadata="$1" + local version='' - [[ -z "$url" ]] && return 22 # EINVAL + if [[ -z "$patch_metadata" ]]; then + printf 'X' + return 2 # ENOENT + fi - curl_cmd+=" $url" - raw_curl_output=$(eval "$curl_cmd") + # Grab pattern 'v' or 'V' from patch metadata + if [[ "$patch_metadata" =~ [v|V]+[[:space:]]*[[:digit:]]+ ]]; then + version="${BASH_REMATCH[0]}" + # Grab number from string + [[ "$version" =~ [[:digit:]]+ ]] && version="${BASH_REMATCH[0]}" + fi + # Versions 1 don't have pattern 'v' nor 'V' in the patch metadata + [[ -z "$version" ]] && version=1 - url_status_code=$(printf '%s' "$raw_curl_output" | grep --extended-regexp '^HTTP' | cut -d ' ' -f2) - [[ "$url_status_code" == 200 ]] && return 0 - return 22 # EINVAL + printf '%s' "$version" } -# Lore URL has a pattern that looks like this: +# This function extracts the pattern `/` with an arbitrary count +# of spaces between the digits and the foward slash. +# +# @patch_metadata: Patch metadata of lore message. # -# https://lore.kernel.org/[LIST]/[MESSAGE-ID]-[PATCH NUMBER]-[AUTHOR EMAIL]/T/#u +# Return: +# Outputs the matched `/` pattern, returning 0 in any case. +function get_number_slash_number_pattern() +{ + local patch_metadata="$1" + local number_slash_number_pattern='' + + if [[ "$patch_metadata" =~ [[:digit:]]+[[:space:]]*/[[:space:]]*[[:digit:]]+ ]]; then + number_slash_number_pattern="${BASH_REMATCH[0]}" + fi + + printf '%s' "$number_slash_number_pattern" +} + +# This function extracts the patch number in the series from a patch metadata. +# The patch number in the series is the index of the patch in the series that +# composes a patchset. # -# With this idea in mind, this function checks for '-[PATCH NUMBER]-' in the -# URL. Based on that, it increments the PATCH Number by one until we reach an -# invalid URL and figure out the total of patches in the series. +# For example, considering `@patch_metadata` equal to +# '[PATCH 09/21]', +# the outputted number in series will be '9'. # -# @url Target url +# @patch_metadata: Patch metadata of lore message. # # Return: -# Return the total of patches. -function total_patches_in_the_series() +# If `@patch_metadata` is non-empty, output the number in the series and return 0. +# Otherwise, return 2 (ENOENT) and output 'X', meaning 'undefined'. +function get_patch_number_in_series() { - local url="$1" - local total=0 - local link_ref=1 - local ret + local patch_metadata="$1" + local number_slash_number_pattern='' + local number_in_series='' - url=$(replace_http_by_https "$url") + if [[ -z "$patch_metadata" ]]; then + printf 'X' + return 2 # ENOENT + fi - until ! is_the_link_valid "$url"; do - ((total++)) - ((link_ref++)) - url="${url/-[0-9]*-/-$link_ref-}" - done + number_slash_number_pattern=$(get_number_slash_number_pattern "$patch_metadata") + # Grab number from start of string + [[ "$number_slash_number_pattern" =~ ^[[:digit:]]+ ]] && number_in_series="${BASH_REMATCH[0]}" + + # Remove leading zeroes + if [[ "$number_in_series" =~ ^0+$ ]]; then + number_in_series=0 + else + number_in_series=$(printf '%s' "$number_in_series" | sed 's/^0*//') + fi - printf '%d' "$total" + # Patchsets with one patch don't have pattern '/' in the patch metadata + [[ -z "$number_in_series" ]] && number_in_series=1 + + printf '%s' "$number_in_series" +} + +# This function extracts the total number of patches in the series from a patch +# tag. +# +# For example, considering `@patch_metadata` equal to +# '[v12 patch 0/320]', +# the outputted total in series will be '320'. +# +# @patch_metadata: Patch metadata of lore message. +# +# Return: +# If `@patch_metadata` is non-empty, output the total in the series and return 0. +# Otherwise, return 2 (ENOENT) and output 'X', meaning 'undefined'. +function get_patch_total_in_series() +{ + local patch_metadata="$1" + local number_slash_number_pattern='' + local total_in_series='' + + if [[ -z "$patch_metadata" ]]; then + printf 'X' + return 2 # ENOENT + fi + + number_slash_number_pattern=$(get_number_slash_number_pattern "$patch_metadata") + # Grab number from end of string + [[ "$number_slash_number_pattern" =~ [[:digit:]]+$ ]] && total_in_series="${BASH_REMATCH[0]}" + + # Patchsets with one patch don't have pattern '/' in the patch metadata + [[ -z "$total_in_series" ]] && total_in_series=1 + + printf '%s' "$total_in_series" +} + +# This function removes a patch metadata substring from a message title. +# +# For example, considering `@message_title` equal to +# '[additional tag][RFC/PATCH v23 12/57] some/subsys: Do bar', +# and `@patch_metadata` equal to +# '[RFC/PATCH v23 12/57]', +# the outputted stripped title will be +# '[additional tag] some/subsys: Do bar'. +# +# @message_title: Message title of lore message. +# @patch_metadata: Patch metadata of lore message. +# +# Return: +# If `@message_title` and `@patch_metadata` are non-empty, output `@message_title` +# stripped of `@patch_metadata` (assuming it is a substring). Otherwise, output an +# empty string. +function remove_patch_metadata_from_message_title() +{ + local message_title="$1" + local patch_metadata="$2" + + # This conditional prevents `sed` 'previous regular expression' error + if [[ -n "$patch_metadata" && -n "$message_title" ]]; then + # Escape chars '[', ']', and '/' from patch metadata + patch_metadata=$(printf '%s' "$patch_metadata" | sed 's/\[/\\\[/g' | sed 's/\]/\\\]/g' | sed 's/\//\\\//g') + message_title=$(printf '%s' "$message_title" | sed "s/${patch_metadata}//") + message_title=$(str_strip "$message_title") + fi + + printf '%s' "$message_title" } # Usually, the Linux kernel patch title has a lot of helpful information, and @@ -219,7 +349,8 @@ function total_patches_in_the_series() # # Patch version, Total of patches, Patch title, URL # -# @patch_title Raw patch title to be parsed +# @message_title: Raw patch title to be parsed. +# @message_id: Message title of patch to be parsed. # # Return: Return a string with patch version, total patches, and patch title # separated by SEPARATOR_CHAR. @@ -232,36 +363,18 @@ function total_patches_in_the_series() # version, this is not so straightforward. function extract_metadata_from_patch_title() { - local patch_title="$1" - local url="$2" - local patch_prefix - local patch_version="1${SEPARATOR_CHAR}" - local total_patches="X${SEPARATOR_CHAR}" - local patch_title="${patch_title}" - - patch_prefix=$(printf '%s' "$patch_title" | grep --only-matching --perl-regexp '^\[(RFC|PATCH).*\]') - if [[ "$?" == 0 ]]; then - # Patch version - patch_version=$(printf '%s' "$patch_prefix" | grep --only-matching --perl-regexp '[v|V]+\d+' | grep --only-matching --perl-regexp '\d+') - [[ "$?" != 0 ]] && patch_version=1 - patch_version+="${SEPARATOR_CHAR}" - - # How many patches - total_patches=$(total_patches_in_the_series "$url") - if [[ "$total_patches" == 0 ]]; then - total_patches=$(printf '%s' "$patch_prefix" | grep --only-matching --perl-regexp "\d+/\d+" | grep --only-matching --perl-regexp "\d+$") - [[ "$?" != 0 ]] && total_patches=1 - fi - total_patches+="${SEPARATOR_CHAR}" - - # Get patch title - patch_title=$(printf '%s' "$patch_title" | cut -d ']' -f2) - patch_title=$(str_strip "$patch_title") - fi - - patch_title+="${SEPARATOR_CHAR}" - - printf '%s%s%s%s' "$patch_version" "$total_patches" "$patch_title" "$url" + local message_title="$1" + local message_id="$2" + local patch_metadata + local version + local total_in_series + + patch_metadata="$(get_patch_metadata "$message_title")" + version="$(get_patch_version "$patch_metadata")${SEPARATOR_CHAR}" + total_in_series="$(get_patch_total_in_series "$patch_metadata")${SEPARATOR_CHAR}" + message_title="$(remove_patch_metadata_from_message_title "$message_title" "$patch_metadata")${SEPARATOR_CHAR}" + + printf '%s%s%s%s' "$version" "$total_in_series" "$message_title" "$message_id" } # This function was tailored to run in a subshell because we want to run this diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index 11d8fbe13..803955f24 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -94,28 +94,329 @@ function test_is_introduction_patch() assertEquals "($LINENO)" "$?" 1 } -function test_is_the_link_valid() +function test_get_patch_metadata() { - is_the_link_valid '' - assertEquals "($LINENO)" "$?" 22 + local message_title + local expected + local output - # shellcheck disable=SC2317 - function curl() - { - printf 'HTTP/1.1 200 OK' - } + message_title='some/subsys: Do foo' + expected='' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed without patch metadata' "$LINENO" "$expected" "$output" + + message_title='[PATCH] some/subsys: Do foo' + expected='[PATCH]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with the word "PATCH" in upper case' "$LINENO" "$expected" "$output" + + message_title='[patch] some/subsys: Do foo' + expected='[patch]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with the word "PATCH" in lower case' "$LINENO" "$expected" "$output" + + message_title='[Patch] some/subsys: Do foo' + expected='[Patch]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with the word "PATCH" with starting upper case' "$LINENO" "$expected" "$output" + + message_title='[pAtcH] some/subsys: Do foo' + expected='[pAtcH]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with the word "PATCH" with random case' "$LINENO" "$expected" "$output" + + message_title='[RFC] some/subsys: Do foo' + expected='[RFC]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with the word "RFC" in upper case' "$LINENO" "$expected" "$output" + + message_title='[rfc] some/subsys: Do foo' + expected='[rfc]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with the word "RFC" in lower case' "$LINENO" "$expected" "$output" + + message_title='[Rfc] some/subsys: Do foo' + expected='[Rfc]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with the word "RFC" with starting upper case' "$LINENO" "$expected" "$output" + + message_title='[rfC] some/subsys: Do foo' + expected='[rfC]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with the word "RFC" with random case' "$LINENO" "$expected" "$output" + + message_title='[RFC PATCH] some/subsys: Do foo' + expected='[RFC PATCH]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with with tag mixing "PATCH" and "RFC" (case 1)' "$LINENO" "$expected" "$output" + + message_title='[PATCH RFC] some/subsys: Do foo' + expected='[PATCH RFC]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with with tag mixing "PATCH" and "RFC" (case 2)' "$LINENO" "$expected" "$output" + + message_title='[addtional tag][PATCH] some/subsys: Do foo' + expected='[PATCH]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with two tags' "$LINENO" "$expected" "$output" + + message_title='[addtional tag 1][PATCH] some/subsys: Do [addtional tag 2] foo' + expected='[PATCH]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with more than one tag' "$LINENO" "$expected" "$output" + + message_title='[PATCH] some/subsys: Do foo in array[0] element' + expected='[PATCH]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with braces in subject' "$LINENO" "$expected" "$output" + + message_title='[PATCH] !@#$%^&*()_-+={}\|/.,:;`~"'"'"'' + expected='[PATCH]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with special characters' "$LINENO" "$expected" "$output" + + message_title='[v2 PATCH] some/subsys: Do foo' + expected='[v2 PATCH]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with version in tag' "$LINENO" "$expected" "$output" + + message_title='[PATCH 4/13] some/subsys: Do foo' + expected='[PATCH 4/13]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with numbering in tag' "$LINENO" "$expected" "$output" + + message_title='[PATCH] revert "patch"' + expected='[PATCH]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with word "patch" in subject' "$LINENO" "$expected" "$output" + + message_title='[PATCH][GSoC patch] some/subsys: Do foo' + expected='[PATCH]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with following tag with word "patch"' "$LINENO" "$expected" "$output" + + message_title='[v13 PATCH 2/3] some/subsys: Do foo' + expected='[v13 PATCH 2/3]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with version and numbering in tag' "$LINENO" "$expected" "$output" + + message_title='[PATCH bpf-next 4.3] some/subsys: Do foo' + expected='[PATCH bpf-next 4.3]' + output=$(get_patch_metadata "$message_title") + assert_equals_helper 'Failed with arbitrary string in tag' "$LINENO" "$expected" "$output" +} - is_the_link_valid 'something' - assertEquals "($LINENO)" "$?" 0 +function test_get_patch_version() +{ + local patch_metadata + local output - # shellcheck disable=SC2317 - function curl() - { - return 6 - } + patch_metadata='' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Empty patch metadata should return 2 ENOENT' "$LINENO" 2 "$?" + assert_equals_helper 'Empty patch metadata should output "X" as version' "$LINENO" 'X' "$output" + + patch_metadata='[PATCH]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag "[PATCH]"' "$LINENO" 1 "$output" + + patch_metadata='[RFC PATCH]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag "[RFC PATCH]"' "$LINENO" 1 "$output" + + patch_metadata='[PATCH AUTOSEL]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary string' "$LINENO" 1 "$output" + + patch_metadata='[PATCH 2718]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary integer' "$LINENO" 1 "$output" + + patch_metadata='[281.828 PATCH]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary float' "$LINENO" 1 "$output" + + patch_metadata='[PATCH 12/13]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with numbering' "$LINENO" 1 "$output" + + patch_metadata='[PATCH v4321]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with version (v)' "$LINENO" 4321 "$output" + + patch_metadata='[PATCH V1234]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with version (V)' "$LINENO" 1234 "$output" + + patch_metadata='[PATCH stringV1234string]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with version without space as border' "$LINENO" 1234 "$output" + + patch_metadata='[PATCH V18 56/78]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with version and numbering' "$LINENO" 18 "$output" + + patch_metadata='[Very voice PATCH v1389 Vertical]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with version strings starting with v/V' "$LINENO" 1389 "$output" + + patch_metadata='[PATCH v 1234]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with version (v) with space separating number and letter' "$LINENO" 1234 "$output" + + patch_metadata='[PATCH V 1234]' + output=$(get_patch_version "$patch_metadata") + assert_equals_helper 'Failed for tag with version (V) with space separating number and letter' "$LINENO" 1234 "$output" +} + +function test_get_patch_number_in_series() +{ + local patch_metadata + local expected + + patch_metadata='' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Empty patch metadata should return 2 ENOENT' "$LINENO" 2 "$?" + assert_equals_helper 'Empty patch metadata should output "X" as number in the series' "$LINENO" 'X' "$output" + + patch_metadata='[PATCH]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag "[PATCH]"' "$LINENO" 1 "$output" + + patch_metadata='[RFC PATCH]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag "[RFC PATCH]"' "$LINENO" 1 "$output" + + patch_metadata='[PATCH AUTOSEL]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary string' "$LINENO" 1 "$output" + + patch_metadata='[PATCH 2718]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary integer' "$LINENO" 1 "$output" + + patch_metadata='[281.828 PATCH]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary float' "$LINENO" 1 "$output" + + patch_metadata='[PATCH v4321]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with version' "$LINENO" 1 "$output" + + patch_metadata='[PATCH 00/13]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag of cover letter' "$LINENO" 0 "$output" + + patch_metadata='[PATCH 1/2]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag of first patch' "$LINENO" 1 "$output" + + patch_metadata='[PATCH 0424/2002]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag of arbitrary patch' "$LINENO" 424 "$output" + + patch_metadata='[v32 PATCH 0424/2002]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with numbering and version' "$LINENO" 424 "$output" + + patch_metadata='[PATCH 123 / 345]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with one space between numbers and foward-slash' "$LINENO" 123 "$output" + + patch_metadata='[PATCH 123 / 345]' + output=$(get_patch_number_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary number of spaces between numbers and foward-slash' "$LINENO" 123 "$output" +} + +function test_get_patch_total_in_series() +{ + local patch_metadata + local expected + + patch_metadata='' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Empty patch metadata should return 2 ENOENT' "$LINENO" 2 "$?" + assert_equals_helper 'Empty patch metadata should output "X" as total in series' "$LINENO" 'X' "$output" + + patch_metadata='[PATCH]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag "[PATCH]"' "$LINENO" 1 "$output" + + patch_metadata='[RFC PATCH]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag "[RFC PATCH]"' "$LINENO" 1 "$output" + + patch_metadata='[PATCH AUTOSEL]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary string' "$LINENO" 1 "$output" + + patch_metadata='[PATCH 2718]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary integer' "$LINENO" 1 "$output" + + patch_metadata='[281.828 PATCH]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary float' "$LINENO" 1 "$output" + + patch_metadata='[PATCH v4321]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with version' "$LINENO" 1 "$output" + + patch_metadata='[PATCH 00/13]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag of cover letter' "$LINENO" 13 "$output" + + patch_metadata='[PATCH 1/2]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag of first patch' "$LINENO" 2 "$output" + + patch_metadata='[PATCH 0424/2002]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag of arbitrary patch' "$LINENO" 2002 "$output" + + patch_metadata='[v32 PATCH 0424/2002]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with numbering and version' "$LINENO" 2002 "$output" + + patch_metadata='[PATCH 123 / 345]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with one space between numbers and foward-slash' "$LINENO" 345 "$output" + + patch_metadata='[PATCH 123 / 345]' + output=$(get_patch_total_in_series "$patch_metadata") + assert_equals_helper 'Failed for tag with arbitrary number of spaces between numbers and foward-slash' "$LINENO" 345 "$output" +} + +function test_remove_patch_metadata_from_message_title() +{ + local message_title + local expected + local output - is_the_link_valid 'something' - assertEquals "($LINENO)" "$?" 22 + message_title='some/subsys: Do foo' + expected='some/subsys: Do foo' + output=$(remove_patch_metadata_from_message_title "$message_title" '') + assert_equals_helper 'Failed for inexistent patch metadata' "$LINENO" "$expected" "$output" + + message_title='[PATCH] some/subsys: Do foo' + expected='some/subsys: Do foo' + output=$(remove_patch_metadata_from_message_title "$message_title" '[PATCH]') + assert_equals_helper 'Failed for simple patch metadata' "$LINENO" "$expected" "$output" + + message_title='[RFC PATCH v12 23/23] some/subsys: Do foo' + expected='some/subsys: Do foo' + output=$(remove_patch_metadata_from_message_title "$message_title" '[RFC PATCH v12 23/23]') + assert_equals_helper 'Failed for complex patch metadata' "$LINENO" "$expected" "$output" + + message_title='[cocci][PATCH][net-dev] some/subsys: Do foo' + expected='[cocci][net-dev] some/subsys: Do foo' + output=$(remove_patch_metadata_from_message_title "$message_title" '[PATCH]') + assert_equals_helper 'Failed for complex patch metadata' "$LINENO" "$expected" "$output" + + message_title='[RFC/PATCH 00/23] some/subsys: Do foo' + expected='some/subsys: Do foo' + output=$(remove_patch_metadata_from_message_title "$message_title" '[RFC/PATCH 00/23]') + assert_equals_helper 'Failed for complex patch metadata' "$LINENO" "$expected" "$output" } function test_process_name() From e6393803925e578e79954c1b5f993b21b5c6e122 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Thu, 7 Mar 2024 09:17:41 -0300 Subject: [PATCH 063/128] src: lib: lore: Overhaul processing of representative patches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [What] Revise the logic in processing representative patches for listing patchsets. When listing patchsets (a set of related patches designed to form a more significant change), a patch is elected to represent it (either a cover letter or the actual first patch in the series), and is called the representative. [Why] Correctly defining a patch as a representative or not is vital for the `kw patch-hub` feature. Having false negatives (representative patches that are "invisible" to the feature) shouldn't happen and also impact the performance, as deeper fetches for data are needed for the same number of patchsets. Currently, in some lists like git, `kw patch-hub` sometimes misses 80% of the time, which is unacceptable. [How] The heuristics to determine a patch as representative is flawed because it solely depends on the pattern of message IDs. A consistent pattern doesn't seem to exist across the many lists that can be reliably used to determine this information (actually, message ID patterns aren't even consistent in the same list). At the moment, from fetching an Atom feed with a list of patches to having a list of representative patches sorted from the newest to the oldest is done by: 1. Pre-processing the Atom feed to obtain only the needed attributes of each patch; 2. Traversing the pre-processed list of patches once and deciding if a patch is representative based on its message ID. We chang step 1 to include more attributes and replace step 2 with two steps to overhaul this processing and make it more robust and reliable. After pre-processing the Atom feed, we traverse the list of patches, marking everyone in a hashtable and storing their processed versions on an array. Then, we traverse the list of patches again, but their processed versions, and use a combination of heuristics based on the patch metadata and its relation with its in-reply-to message (if it has one). These heuristics are inspired by the source code of the b4 project, which can be found at https://github.com/mricon/b4. Note: Many files had to be updated due to ripple effects in the change of variable names, and the like. Also, much of the size of this commit is due to testing code and mocked samples for them. Closes: #900 Signed-off-by: David Tadokoro Co-authored-by: AndrĆ© Gustavo Co-authored-by: Guilherme Moreno Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/lib/lore.sh | 481 +++++++++-------- .../latest_patchsets_from_mailing_list.sh | 4 +- src/ui/patch_hub/patch_hub_core.sh | 2 +- .../patch_hub/patchset_details_and_actions.sh | 41 +- tests/unit/lib/lore_test.sh | 484 ++++++++++-------- .../lore/pre_processed_patches_sample-1 | 11 +- .../lore/pre_processed_patches_sample-2 | 11 +- .../samples/lore/query_result_sample-1.xml | 4 +- .../samples/lore/query_result_sample-2.xml | 43 ++ .../unit/ui/patch_hub/patch_hub_core_test.sh | 6 +- .../patchset_details_and_actions_test.sh | 16 +- 11 files changed, 604 insertions(+), 499 deletions(-) create mode 100644 tests/unit/samples/lore/query_result_sample-2.xml diff --git a/src/lib/lore.sh b/src/lib/lore.sh index ef274e112..236c4b289 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -34,9 +34,30 @@ declare -gA available_lore_mailing_lists # Special character used for separate data. declare -gr SEPARATOR_CHAR='Ɔ' -# Number of patchsets processed current lore fetch session. -# Also, the size of `list_of_mailinglist_patches`. -declare -g PATCHSETS_PROCESSED=0 +# Indexed array of patches that represent patchsets ordered from the latest to +# the earliest. A patchset is a set of individual patches sent together to form +# a broader change and its first message in the series is elected to be the +# representative. An element of the array is a sequence of message's attributes +# separated by `SEPARATOR_CHAR` in the following order: +# message ID, message title, author name, author email, version, number in series, +# total in series, updated, and in reply to (optional). +declare -ag representative_patches + +# Associative array with metadata of every patch that was processed during a +# fetch session of patchsets. This information is used to determine representative +# patches (see function `processed_representative_patches`). An element's general +# format is: +# individual_patches_metadata['message_id']=',' +declare -Ag individual_patches_metadata + +# Associative array used to check if a given representative patch was already +# processed. Each element is a boolean where a non-empty value is true and an +# empty one is false. +declare -Ag processed_representative_patches + +# Total number of processed representative patches in current fetch session. Also, +# the size of the indexed array `representative_patches`. +declare -g REPRESENTATIVE_PATCHES_PROCESSED=0 # Any query to the lore servers is paginated and the maximum number of individual # messages returned is 200. This variable represents this value. @@ -52,21 +73,6 @@ declare -gr LORE_PAGE_SIZE=200 # in the response (neither the message of index 0 exists). declare -g MIN_INDEX=0 -# This is a global array that kw uses to store the list of new patches from a -# target mailing list. After kw parses the data from lore, we will have a list -# that follows this pattern: -# -# Author, email, version, total patches, patch title, link -# -# Note: To separate those elements, we use the variable SEPARATOR_CHAR, which -# can be a ',' but by default, we use 'Ɔ'. We used ',' in the example for make -# it easy to undertand. -declare -ag list_of_mailinglist_patches - -# This associative array stores the current processed patchsets and it is used -# to check if a given patchset was already processed. -declare -Ag processed_patchsets - # This function creates the directory used by kw for any lore related data. # # Return: @@ -139,27 +145,6 @@ function retrieve_available_mailing_lists() done } -# This function parser the message-id link for trying to find if the target -# patch is the first one from the series (in the case of a patchset, the first -# patch is the cover-letter) or not. This is useful for identifying cover -# letters or patches from a sequence. -# -# @message_id_link String with the message id link -# -# Return -# If it is the first patch, return 0; otherwise, return 1. -function is_introduction_patch() -{ - local message_id_link="$1" - local sequence - - sequence=$(grep --only-matching --perl-regexp '\-[0-9]+\-' <<< "$message_id_link") - sequence=$(printf '%s' "$sequence" | tr -d '-') - - [[ "$sequence" == 1 ]] && return 0 - return 1 -} - # This function extracts the patch metadata of a lore message title. A patch # metadata is a string surrounded by square brackets that contains the word # "PATCH" and/or "RFC". @@ -343,61 +328,6 @@ function remove_patch_metadata_from_message_title() printf '%s' "$message_title" } -# Usually, the Linux kernel patch title has a lot of helpful information, and -# this function is responsible for extracting patch information from the patch -# title. This function extracts: -# -# Patch version, Total of patches, Patch title, URL -# -# @message_title: Raw patch title to be parsed. -# @message_id: Message title of patch to be parsed. -# -# Return: Return a string with patch version, total patches, and patch title -# separated by SEPARATOR_CHAR. -# -# FIXME: In this function, we collect metadata from the patch title; this is -# useful but fragile since we rely on developers following the right approach. -# Ideally, we should use this approach as a last resource to collect the -# information; we should always favor the lore API. For sure, we can get the -# total patches by parsing "-NUMBER-" in the message-id, but for the patch -# version, this is not so straightforward. -function extract_metadata_from_patch_title() -{ - local message_title="$1" - local message_id="$2" - local patch_metadata - local version - local total_in_series - - patch_metadata="$(get_patch_metadata "$message_title")" - version="$(get_patch_version "$patch_metadata")${SEPARATOR_CHAR}" - total_in_series="$(get_patch_total_in_series "$patch_metadata")${SEPARATOR_CHAR}" - message_title="$(remove_patch_metadata_from_message_title "$message_title" "$patch_metadata")${SEPARATOR_CHAR}" - - printf '%s%s%s%s' "$version" "$total_in_series" "$message_title" "$message_id" -} - -# This function was tailored to run in a subshell because we want to run this -# sort of data processing in parallel to avoid blocking users for a long time. -# -# @id: Id used to retrieve the data processed by this function -# @base_dir: Where this function will save the data -# @processed_line: Pre-filled data -# @message_id_link: Message id to be composed in the final result -# @title: Patch title -function thread_for_process_patch() -{ - local id="$1" - local base_dir="$2" - local processed_line="$3" - local message_id_link="$4" - local title="$5" - - processed_line+=$(extract_metadata_from_patch_title "$title" "$message_id_link") - - printf '%s' "${processed_line}" > "${base_dir}/${id}" -} - # Some people set their names like "Second name, First name", this extra comma # is not ideal when dealing with emails. This function converts names as # "Second name, First name" to "First name Second name" @@ -424,18 +354,22 @@ function process_name() printf '%s' "${full_name[1]} ${full_name[0]}" } -# This function resets all data structures that represent the current lore -# fetch session. A lore fetch session is constituted by an array with the -# latest patchsets of a lore public mailing list ordered, the number of patchsets -# processed (the size of the array), and the minimum exclusive index of the -# response (see `MIN_INDEX` declaration). +# This function resets all data structures that constitute the current fetch +# session. Five elements define a fetch session: +# 1. List of representative patches ordered from latest to earliest; +# 2. Table with the metadata of all individual patches processed; +# 3. Table with all representative patches processed; +# 4. Total number of representative patches processed; +# 5. Earliest page processed. function reset_current_lore_fetch_session() { - list_of_mailinglist_patches=() - PATCHSETS_PROCESSED=0 + representative_patches=() + unset individual_patches_metadata + declare -Ag individual_patches_metadata + unset processed_representative_patches + declare -Ag processed_representative_patches + REPRESENTATIVE_PATCHES_PROCESSED=0 MIN_INDEX=0 - unset processed_patchsets - declare -Ag processed_patchsets } # This function composes a query URL to a public mailing list archived @@ -480,126 +414,194 @@ function compose_lore_query_url_with_verification() printf '%s' "$query_url" } -# This function pre-processes an XML file containing a list of patches, extracting -# just the metadata needed to process an XML element representing a patch. The `xpath` -# command is used to capture the desired fields for each patch. A simplified example -# of an XML element representing a patch is: +# This function pre-processes a raw XML containing a list of patches. The `xpath` +# command is used to capture the desired fields for each patch. A simplified +# example of an XML element that represents a patch is (the thr:in-reply-to field +# is optional): # # -# David Tadokoro -# davidbtadokoro@usp.br +# John Smith +# john@smith.com # -# [PATCH] drm/amdkfd: Fix memory allocation +# [PATCH] dir/subdir: Fix bug xpto # 2023-08-09T21:27:00Z -# +# +# # # # The pre-processed version of this example element would be: -# David Tadokoro -# davidbtadokoro@usp.br -# [PATCH] drm/amdkfd: Fix memory allocation -# href="http://lore.kernel.org/amd-gfx/20230809212615.137674-1-davidbtadokoro@usp.br/" +# John Smith +# john@smith.com +# [PATCH] dir/subdir: Fix bug xpto +# 2023-08-09T21:27:00Z +# href="http://lore.kernel.org/list/0xc0ffee-4-john@smith.com/" +# href="http://lore.kernel.org/list/0xc0ffee-0-john@smith.com/" # -# @xml_file_path: Path to XML file +# @raw_xml: String with raw XML. # # Return: # The status code is the same as the `xpath` command and the pre-processed XML file # is outputted to the standard output -function pre_process_xml_result() +function pre_process_raw_xml() { - local xml_file_path="$1" + local raw_xml="$1" local xpath_query - local raw_xml + local xpath_output local -r NAME_EXP='//entry/author/name/text()' local -r EMAIL_EXP='//entry/author/email/text()' local -r TITLE_EXP='//entry/title/text()' + local -r UPDATED_EXP='//entry/updated/text()' local -r LINK_EXP='//entry/link/@href' + local -r IN_REPLY_TO_EXP='//entry/thr:in-reply-to/@href' - raw_xml=$(< "$xml_file_path") - xpath_query="${NAME_EXP}|${EMAIL_EXP}|${TITLE_EXP}|${LINK_EXP}" - printf '%s' "$raw_xml" | xpath -q -e "$xpath_query" + xpath_query="${NAME_EXP}|${EMAIL_EXP}|${TITLE_EXP}|${UPDATED_EXP}|${LINK_EXP}|${IN_REPLY_TO_EXP}" + xpath_output=$(printf '%s' "$raw_xml" | xpath -q -e "$xpath_query" | sed 's/^[ \t]*//') + + printf '%s\n ' "$xpath_output" } -# This function converts a list of patches into a list of patchsets stored -# in the `list_of_mailinglist_patches` array. A patchset differs from a -# single patch, because the first includes all patches in a series of patches -# which can have different version. For each multipart patchset, the first patch -# is either a cover letter or a actual patch and is the representative of the -# patchset. This patch metadata is the one stored in `list_of_mailinglist_patches`. +# This function processes a list of individual patches from an Atom feed into an +# indexed array that is passed as reference. All patches that are processed in +# this function are marked in the `individual_patches_metadata` global hastable. +# The order of patches in the resulting `@_individual_patches` array is the same +# order as in the Atom feed. # -# @pre_processed_patches: String containing a list of pre-processed patches -# TODO: -# - The function `is_introduction_patch` basically filters which patch is a -# representative of the patchset by the message-ID. Some valid representatives -# are wrongly filtered out, because of what the function considers a message-ID -# from a representative. -# - The function `extract_metadata_from_patch_title` called by `thread_for_process_patch` -# counts the cover letter as a patch which results in patchsets with cover letters -# having one more patch than in reality. -function process_patchsets() +# @raw_xml: String with Atom feed containing the list of individual patches. +# @_individual_patches: Indexed array reference to store processed patches. +function process_individual_patches() { - local pre_processed_patches="$1" - local shared_dir_for_parallelism - local processed_patchset - local starting_index - local patch_title - local patch_url - local count - local line - local pids - local i - - shared_dir_for_parallelism=$(create_shared_memory_dir) - - starting_index="$PATCHSETS_PROCESSED" - count=0 - i=0 - - while IFS= read -r line; do - if [[ "$line" =~ ^[[:space:]]href= ]]; then - patch_url=$(str_get_value_under_double_quotes "$line") - - if [[ "${processed_patchsets["$patch_url"]}" != 1 ]] && is_introduction_patch "$patch_url"; then - # Processes each patch in parallel - thread_for_process_patch "$PATCHSETS_PROCESSED" "$shared_dir_for_parallelism" \ - "$processed_patchset" "$patch_url" "$patch_title" & - pids[i]="$!" + local raw_xml="$1" + local -n _individual_patches="$2" + local pre_processed_patches + local message_id='' + local message_title='' + local author_name='' + local author_email='' + local version='' + local number_in_series='' + local total_in_series='' + local updated='' + local in_reply_to='' + local patch_metadata='' + local patch_attribute_number=0 + local i=0 + + pre_processed_patches=$(pre_process_raw_xml "$raw_xml") + + while IFS=$'\n' read -r line; do + if [[ "$patch_attribute_number" == 5 ]]; then + patch_attribute_number=0 + + patch_metadata=$(get_patch_metadata "$message_title") + version=$(get_patch_version "$patch_metadata") + number_in_series=$(get_patch_number_in_series "$patch_metadata") + total_in_series=$(get_patch_total_in_series "$patch_metadata") + message_title=$(remove_patch_metadata_from_message_title "$message_title" "$patch_metadata") + + # Mark individual patch as processed and store metadata + individual_patches_metadata["$message_id"]="${version},${number_in_series}" + + _individual_patches["$i"]="${message_id}${SEPARATOR_CHAR}${message_title}${SEPARATOR_CHAR}" + _individual_patches["$i"]+="${author_name}${SEPARATOR_CHAR}${author_email}${SEPARATOR_CHAR}" + _individual_patches["$i"]+="${version}${SEPARATOR_CHAR}${number_in_series}${SEPARATOR_CHAR}" + _individual_patches["$i"]+="${total_in_series}${SEPARATOR_CHAR}${updated}${SEPARATOR_CHAR}" + + # In case the patch has a 'In-Reply-To' field, `line` contains this value, + # so process it and read next line of pre processed. + if [[ "$line" =~ ^href= ]]; then + in_reply_to=$(str_get_value_under_double_quotes "$line") + _individual_patches["$i"]+="$in_reply_to" ((i++)) - ((PATCHSETS_PROCESSED++)) - processed_patchsets["$patch_url"]=1 + continue fi - processed_patchset='' - count=0 - continue + ((i++)) fi - # Based on the way that we build our xpath expression, we can rely on this sequence: - # Name, Email, Title, Link - # Since we have a dedicated function to extract title metadata, we want to - # save the title in a separated variable for later processing. - case "$count" in - 0) # NAME - processed_patchset="$(process_name "$line")${SEPARATOR_CHAR}" + case "$patch_attribute_number" in + 0) # Author's name + author_name=$(process_name "$line") + ;; + 1) # Author's email + author_email="$line" + ;; + 2) # Message title + message_title="$line" ;; - 1) # EMAIL - processed_patchset+="${line}${SEPARATOR_CHAR}" + 3) # Updated + updated="$line" + updated=$(printf '%s' "$updated" | sed 's/-/\//g' | sed 's/T/ /') + updated="${updated:0:-4}" ;; - 2) # TITLE - patch_title="$line" + 4) # Message-ID + message_id=$(str_get_value_under_double_quotes "$line") ;; esac - ((count++)) + ((patch_attribute_number++)) done <<< "$pre_processed_patches" +} - # Wait for specific PID to avoid interfering in other functionalities. - for pid in "${pids[@]}"; do - wait "$pid" - done +# This function processes representative patches (i.e. the first message in a +# patchset) from a list of processed individual patches. The patches determined +# as representatives are stored (in the same order as the argument +# `@_individual_patches_array`) in the global indexed array +# `representative_patches`. It uses `processed_representative_patches`, a global +# hastable, to not duplicate representative patches. Subsequent calls of this +# function append patches to `representative_patches` instead of resetting it +# (this is done with the function `reset_current_lore_fetch_session`) +# +# @_individual_patches_array: Indexed array reference with processed list of +# individual patches. +function process_representative_patches() +{ + local -n _individual_patches_array="$1" + local message_id + local in_reply_to_message_id + local -a patch_metadata + local -a in_reply_to_metadata + local is_representative_patch + + for patch in "${_individual_patches_array[@]}"; do + is_representative_patch='' + unset patch_dict + declare -A patch_dict + + read_patch_into_dict "$patch" 'patch_dict' + + # To avoid duplication, check if patch has been processed as representative + message_id="${patch_dict['message_id']}" + [[ -n "${processed_representative_patches["$message_id"]}" ]] && continue + + # Assume that patch number 0 is always the representative as the cover letter + if [[ "${patch_dict['number_in_series']}" == 0 ]]; then + is_representative_patch=1 + # Assume that, when there is no patch number 0, number 1 is the representative + elif [[ "${patch_dict['number_in_series']}" == 1 ]]; then + # Assume that patch number 1 without 'In-Reply-To' means no number 0 + if [[ "${patch_dict['total_in_series']}" == 1 || + -z "${patch_dict['in_reply_to']}" ]]; then + is_representative_patch=1 + else + patch_metadata=() + in_reply_to_metadata=() + in_reply_to_message_id="${patch_dict['in_reply_to']}" + IFS=',' read -ra patch_metadata <<< "${individual_patches_metadata["$message_id"]}" + IFS=',' read -ra in_reply_to_metadata <<< "${individual_patches_metadata["$in_reply_to_message_id"]}" + + # Assume that, if 'In-Reply-To' is not patch number 0 from the same + # version, number 1 is the representative + if [[ "${patch_metadata[0]}" != "${in_reply_to_metadata[0]}" || "${in_reply_to_metadata[1]}" != 0 ]]; then + is_representative_patch=1 + fi + fi + fi - for i in $(seq "$starting_index" "$((PATCHSETS_PROCESSED - 1))"); do - list_of_mailinglist_patches["$i"]=$(< "${shared_dir_for_parallelism}/${i}") + if [[ -n "$is_representative_patch" ]]; then + representative_patches["$REPRESENTATIVE_PATCHES_PROCESSED"]="$patch" + ((REPRESENTATIVE_PATCHES_PROCESSED++)) + processed_representative_patches["${patch_dict['message_id']}"]=1 + fi done } @@ -611,19 +613,15 @@ function process_patchsets() # 2. Make a request to the URL built in step 1 to obtain a list of patches ordered # by the recieved time on the lore.kernel.org servers. # 3. Process the list of patches to a list of patchsets stored in the -# `list_of_mailinglist_patches` array. +# `representative_patches` array. # -# In case the number of patchsets in `list_of_mailinglist_patches` is less than +# In case the number of patchsets in `representative_patches` is less than # `page` times `patchsets_per_page`, update `MIN_INDEX` and repeat steps 1 to 3. # # This function considers the totality of ordered patchsets in chunks of the same # size named pages. The `page` argument indicates until which page of the latest # patchsets should the fetch occur. # -# Each entry in `list_of_mailinglist_patches` has the following patchset metadata -# separated by `SEPARATOR_CHAR`: -# author name, author email, patchset version, number of patches, patch title, message-ID -# # @target_mailing_list: A string name that matches the mailing list name # registered to lore # @page: Positive integer that represents until what page of latest patchsets the fetch @@ -642,10 +640,6 @@ function fetch_latest_patchsets_from() local patchsets_per_page="$3" local additional_filters="$4" local flag="$5" - local raw_xml - local lore_query_url - local xml_result_file_name - local pre_processed_patches local xml_result_file_name local lore_query_url local raw_xml @@ -654,7 +648,7 @@ function fetch_latest_patchsets_from() flag=${flag:-'SILENT'} xml_result_file_name="${target_mailing_list}-patches.xml" - while [[ "$PATCHSETS_PROCESSED" -lt "$((page * patchsets_per_page))" ]]; do + while [[ "$REPRESENTATIVE_PATCHES_PROCESSED" -lt "$((page * patchsets_per_page))" ]]; do # Building URL for querying lore servers for a xml file with patches. lore_query_url=$(compose_lore_query_url_with_verification "$target_mailing_list" "$MIN_INDEX" "$additional_filters") ret="$?" @@ -679,25 +673,23 @@ function fetch_latest_patchsets_from() break fi - # Processing patches into patchsets that will be stored in `list_of_mailinglist_patches`. - pre_processed_patches=$(pre_process_xml_result "${CACHE_LORE_DIR}/${xml_result_file_name}") - # TODO: Is passing `pre_processed_patches` (huge string) as argument a possible bottleneck? - process_patchsets "$pre_processed_patches" + process_individual_patches "$raw_xml" 'individual_patches' + process_representative_patches 'individual_patches' # Update minimum exclusive index. MIN_INDEX=$((MIN_INDEX + LORE_PAGE_SIZE)) done } -# This function formats a range of patchsets metadata from `list_of_mailinglist_patches` +# This function formats a range of patchsets metadata from `representative_patches` # into an array reference passed as argument. The format of the metadata follows the # pattern: # # V | # | # # @_formatted_patchsets_list: Array reference to output formatted range of patchsets metadata -# @starting_index: Starting index of range from `list_of_mailinglist_patches` -# @ending_index: Ending index of range `list_of_mailinglist_patches` +# @starting_index: Starting index of range from `representative_patches` +# @ending_index: Ending index of range `representative_patches` function format_patchsets() { local -n _formatted_patchsets_list="$1" @@ -706,15 +698,15 @@ function format_patchsets() declare -A patchset for i in $(seq "$starting_index" "$ending_index"); do - parse_raw_patchset_data "${list_of_mailinglist_patches["$i"]}" 'patchset' - _formatted_patchsets_list["$i"]=$(printf 'V%-2s |#%-3s|' "${patchset['patchset_version']}" "${patchset['total_patches']}") - _formatted_patchsets_list["$i"]+=$(printf ' %-100s' "${patchset['patchset_title']}") + read_patch_into_dict "${representative_patches["$i"]}" 'patchset' + _formatted_patchsets_list["$i"]=$(printf 'V%-2s |#%-3s| ' "${patchset['version']}" "${patchset['total_in_series']}") + _formatted_patchsets_list["$i"]+=$(printf ' %-100s' "${patchset['message_title']}") done } -# This function outputs the starting index in the `list_of_mailinglist_patches` array of a given -# page, i.e., if the patchsets of the page 2 are from `list_of_mailinglist_patches[30]` until -# `list_of_mailinglist_patches[59]`, this function outputs '30'. +# This function outputs the starting index in the `representative_patches` array of a given +# page, i.e., if the patchsets of the page 2 are from `representative_patches[30]` until +# `representative_patches[59]`, this function outputs '30'. # # @page: Number of the target page. # @patchsets_per_page: Number of patchsets per page @@ -725,16 +717,16 @@ function get_page_starting_index() local starting_index starting_index=$(((page - 1) * patchsets_per_page)) - # Avoid an starting index greater than the max index of `list_of_mailinglist_patches` - if [[ "$starting_index" -gt "$((${#list_of_mailinglist_patches[@]} - 1))" ]]; then - starting_index=$((${#list_of_mailinglist_patches[@]} - 1)) + # Avoid an starting index greater than the max index of `representative_patches` + if [[ "$starting_index" -gt "$((${#representative_patches[@]} - 1))" ]]; then + starting_index=$((${#representative_patches[@]} - 1)) fi printf '%s' "$starting_index" } -# This function outputs the ending index in the `list_of_mailinglist_patches` array of a given -# page, i.e., if the patchsets of the page 2 are from `list_of_mailinglist_patches[30]` until -# `list_of_mailinglist_patches[59]`, this function outputs '59'. +# This function outputs the ending index in the `representative_patches` array of a given +# page, i.e., if the patchsets of the page 2 are from `representative_patches[30]` until +# `representative_patches[59]`, this function outputs '59'. # # @page: Number of the target page # @patchsets_per_page: Number of patchsets per page @@ -745,9 +737,9 @@ function get_page_ending_index() local ending_index ending_index=$(((page * patchsets_per_page) - 1)) - # Avoid an ending index greater than the max index of `list_of_mailinglist_patches` - if [[ "$ending_index" -gt "$((${#list_of_mailinglist_patches[@]} - 1))" ]]; then - ending_index=$((${#list_of_mailinglist_patches[@]} - 1)) + # Avoid an ending index greater than the max index of `representative_patches` + if [[ "$ending_index" -gt "$((${#representative_patches[@]} - 1))" ]]; then + ending_index=$((${#representative_patches[@]} - 1)) fi printf '%s' "$ending_index" } @@ -872,7 +864,7 @@ function create_lore_bookmarked_file() # Note that the function assumes that the `@raw_patchset` passed as argument contains the # necessary attributes and is correctly formatted, leaving this responsability to the caller. # -# @raw_patchset: Raw data of patchset in the same format as list_of_mailinglist_patches +# @raw_patchset: Raw data of patchset in the same format as representative_patches # to be added to the local bookmarked database # @download_dir_path: The directory where the patchset .mbx was saved function add_patchset_to_bookmarked_database() @@ -953,8 +945,6 @@ function get_bookmarked_series() declare -A series local index=0 local timestamp - local patch_title - local patch_author local tmp_data if [[ ! -f "${BOOKMARKED_SERIES_PATH}" ]]; then @@ -964,8 +954,8 @@ function get_bookmarked_series() _bookmarked_series=() while IFS='' read -r raw_patchset; do - parse_raw_patchset_data "${raw_patchset}" 'series' - tmp_data=$(printf ' %s | %-70s | %s' "${series['timestamp']}" "${series['patchset_title']}" "${series['patchset_author']}") + read_patch_into_dict "${raw_patchset}" 'series' + tmp_data=$(printf ' %s | %-70s | %s' "${series['timestamp']}" "${series['message_title']}" "${series['author_name']}") _bookmarked_series["$index"]="${tmp_data}" ((index++)) done < "${BOOKMARKED_SERIES_PATH}" @@ -996,32 +986,37 @@ function get_bookmarked_series_by_index() printf '%s' "${target_patch}" } -# This function parses raw data that represents a patchset instance into -# an associative array passed as reference. This function assumes that the +# This function parses raw data that represents a patch instance into an +# associative array passed as reference. This function assumes that the # raw data has attributes in the following order: -# patchset_author, author_email, patchset_version, total_patches, patchset_title, -# patchset_url, download_dir_path, timestamp. +# message ID, message title, author name, author email, version, +# patch number in series, total in series, updated time, in reply to (optional), +# download directory path (bookmark exclusive), and timestamp (bookmark exclusive) # # Note that the function doesn't verifies if the attributes are non-empty or -# valid (i.e. represent a valid patchset instance), passing the responsability to +# valid (i.e. represent a valid patch instance), passing the responsability to # the caller. # -# @raw_patchset: Raw data of patchset in the same format as list_of_mailinglist_patches -function parse_raw_patchset_data() +# @raw_patch: Raw data of patch in the same format as in `representative_patches` +# @_dict: Associative array reference to store parsed patch. +function read_patch_into_dict() { - local raw_patchset="$1" - local -n _patchset="$2" + local raw_patch="$1" + local -n _dict="$2" local columns - IFS="${SEPARATOR_CHAR}" read -ra columns <<< "${raw_patchset}" - _patchset['patchset_author']="${columns[0]}" - _patchset['author_email']="${columns[1]}" - _patchset['patchset_version']="${columns[2]}" - _patchset['total_patches']="${columns[3]}" - _patchset['patchset_title']="${columns[4]}" - _patchset['patchset_url']="${columns[5]}" - _patchset['download_dir_path']="${columns[6]}" - _patchset['timestamp']="${columns[7]}" + IFS="${SEPARATOR_CHAR}" read -ra columns <<< "$raw_patch" + _dict['message_id']="${columns[0]}" + _dict['message_title']="${columns[1]}" + _dict['author_name']="${columns[2]}" + _dict['author_email']="${columns[3]}" + _dict['version']="${columns[4]}" + _dict['number_in_series']="${columns[5]}" + _dict['total_in_series']="${columns[6]}" + _dict['updated']="${columns[7]}" + _dict['in_reply_to']="${columns[8]}" + _dict['download_dir_path']="${columns[9]}" + _dict['timestamp']="${columns[10]}" } # This function gets the bookmark status of a patchset, 0 being not in the local diff --git a/src/ui/patch_hub/latest_patchsets_from_mailing_list.sh b/src/ui/patch_hub/latest_patchsets_from_mailing_list.sh index 67ac0cddb..d8799f0ea 100644 --- a/src/ui/patch_hub/latest_patchsets_from_mailing_list.sh +++ b/src/ui/patch_hub/latest_patchsets_from_mailing_list.sh @@ -17,7 +17,7 @@ function show_latest_patchsets_from_mailing_list() create_async_loading_screen_notification "Loading patchsets from ${current_mailing_list} list" & loading_pid="$!" - # Query patches from mailing list, this info will be saved at `list_of_mailinglist_patches[@]`. + # Query patches from mailing list, this info will be saved at `representative_patches[@]`. fetch_latest_patchsets_from "$current_mailing_list" "$PAGE" "${lore_config['patchsets_per_page']}" "$additional_filters" ret="$?" stop_async_loading_screen_notification "$loading_pid" @@ -49,7 +49,7 @@ function show_latest_patchsets_from_mailing_list() case "$ret" in 0) # OK screen_sequence['PREVIOUS_SCREEN']='latest_patchsets_from_mailing_list' - screen_sequence['SHOW_SCREEN_PARAMETER']=${list_of_mailinglist_patches["$menu_return_string"]} + screen_sequence['SHOW_SCREEN_PARAMETER']=${representative_patches["$menu_return_string"]} screen_sequence['SHOW_SCREEN']='patchset_details_and_actions' ;; 1) # Next diff --git a/src/ui/patch_hub/patch_hub_core.sh b/src/ui/patch_hub/patch_hub_core.sh index fdd1223db..a3706bc6a 100644 --- a/src/ui/patch_hub/patch_hub_core.sh +++ b/src/ui/patch_hub/patch_hub_core.sh @@ -218,7 +218,7 @@ function list_patches() case "${screen_sequence['SHOW_SCREEN']}" in 'latest_patchsets_from_mailing_list') screen_sequence['PREVIOUS_SCREEN']='latest_patchsets_from_mailing_list' - screen_sequence['SHOW_SCREEN_PARAMETER']=${list_of_mailinglist_patches["$menu_return_string"]} + screen_sequence['SHOW_SCREEN_PARAMETER']=${representative_patches["$menu_return_string"]} ;; 'bookmarked_patches') screen_sequence['PREVIOUS_SCREEN']='bookmarked_patches' diff --git a/src/ui/patch_hub/patchset_details_and_actions.sh b/src/ui/patch_hub/patchset_details_and_actions.sh index 850b45a77..4af404fc7 100644 --- a/src/ui/patch_hub/patchset_details_and_actions.sh +++ b/src/ui/patch_hub/patchset_details_and_actions.sh @@ -14,15 +14,14 @@ function show_patchset_details_and_actions() local patch_metadata local message_box - parse_raw_patchset_data "${raw_patchset}" 'patchset' - patch_metadata=$(prettify_string 'Series:' "${patchset['patchset_title']}") - patch_metadata+=$(prettify_string 'Author:' "${patchset['patchset_author']}") - patch_metadata+=$(prettify_string 'Version:' "${patchset['patchset_version']}") - patch_metadata+=$(prettify_string 'Patches:' "${patchset['total_patches']}") + read_patch_into_dict "$raw_patchset" 'patchset' + patch_metadata=$(prettify_string 'Series:' "${patchset['message_title']}") + patch_metadata+=$(prettify_string 'Author:' "${patchset['author_name']}") + patch_metadata+=$(prettify_string 'Version:' "${patchset['version']}") + patch_metadata+=$(prettify_string 'Patches:' "${patchset['total_in_series']}") message_box="$patch_metadata" - # actions_starting_status[0]=$(get_patchset_download_status "${patchset['patchset_url']}" "${lore_config['save_patches_to']}") - actions_starting_status[1]=$(get_patchset_bookmark_status "${patchset['patchset_url']}") + actions_starting_status[1]=$(get_patchset_bookmark_status "${patchset['message_id']}") create_simple_checklist 'Patchset details and actions' "$message_box" 'actions_list' 'actions_starting_status' 1 ret="$?" @@ -114,16 +113,16 @@ function handle_download_action() return fi - create_async_loading_screen_notification 'Downloading patchset'$'\n'"${_patchset['patchset_title']}" & + create_async_loading_screen_notification 'Downloading patchset'$'\n'"${_patchset['message_title']}" & loading_pid="$!" - output=$(download_series "${_patchset['patchset_url']}" "$download_dir_path") + output=$(download_series "${_patchset['message_id']}" "$download_dir_path") ret="$?" stop_async_loading_screen_notification "$loading_pid" if [[ "$ret" != 0 ]]; then - create_message_box 'Error' 'Could not download patchset:'$'\n'"${_patchset['patchset_title']}"$'\n'"[error message] ${output}" + create_message_box 'Error' 'Could not download patchset:'$'\n'"${_patchset['message_title']}"$'\n'"[error message] ${output}" else - message_box='Downloaded patchset:'$'\n'"- ${_patchset['patchset_title']}"$'\n'$'\n' + message_box='Downloaded patchset:'$'\n'"- ${_patchset['message_title']}"$'\n'$'\n' message_box+='Filepath:'$'\n'"$output" create_message_box 'Success' "$message_box" fi @@ -155,24 +154,24 @@ function handle_bookmark_action() local loading_pid local ret - output=$(download_series "${_patchset['patchset_url']}" "${lore_config['save_patches_to']}") + output=$(download_series "${_patchset['message_id']}" "${lore_config['save_patches_to']}") if [[ "$?" != 0 ]]; then - create_message_box 'Error' 'Could not download patchset:'$'\n'"- ${_patchset['patchset_title']}"$'\n'"[error message] ${output}" + create_message_box 'Error' 'Could not download patchset:'$'\n'"- ${_patchset['message_title']}"$'\n'"[error message] ${output}" return fi - create_async_loading_screen_notification 'Bookmarking patchset'$'\n'"- ${_patchset['patchset_title']}" & + create_async_loading_screen_notification 'Bookmarking patchset'$'\n'"- ${_patchset['message_title']}" & loading_pid="$!" add_patchset_to_bookmarked_database "${raw_patchset}" "${lore_config['save_patches_to']}" ret="$?" stop_async_loading_screen_notification "$loading_pid" if [[ "$ret" != 0 ]]; then - create_message_box 'Error' 'Could not bookmark patchset'$'\n'"- ${_patchset['patchset_title']}" + create_message_box 'Error' 'Could not bookmark patchset'$'\n'"- ${_patchset['message_title']}" return fi - message_box='Bookmarked patchset:'$'\n'"- ${_patchset['patchset_title']}"$'\n'$'\n' + message_box='Bookmarked patchset:'$'\n'"- ${_patchset['message_title']}"$'\n'$'\n' message_box+='Downloaded mbox file to:'$'\n'"$output" create_message_box 'Success' "$message_box" } @@ -186,18 +185,18 @@ function handle_remove_bookmark_action() local -n _patchset="$1" local message_box - delete_series_from_local_storage "${lore_config['save_patches_to']}" "${_patchset['patchset_url']}" + delete_series_from_local_storage "${lore_config['save_patches_to']}" "${_patchset['message_id']}" if [[ "$?" != 0 ]]; then - create_message_box 'Warning' 'Could not delete patchset .mbx file'$'\n'"- ${_patchset['patchset_title']}" + create_message_box 'Warning' 'Could not delete patchset .mbx file'$'\n'"- ${_patchset['message_title']}" return fi - remove_patchset_from_bookmark_by_url "${_patchset['patchset_url']}" + remove_patchset_from_bookmark_by_url "${_patchset['message_id']}" if [[ "$?" != 0 ]]; then - create_message_box 'Error' 'Could not unbookmark patchset'$'\n'"- ${_patchset['patchset_title']}" + create_message_box 'Error' 'Could not unbookmark patchset'$'\n'"- ${_patchset['message_title']}" return fi - message_box='Removed bookmark from patchset:'$'\n'"- ${_patchset['patchset_title']}"$'\n'$'\n' + message_box='Removed bookmark from patchset:'$'\n'"- ${_patchset['message_title']}"$'\n'$'\n' create_message_box 'Success' "$message_box" } diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index 803955f24..fd4075eb7 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -75,25 +75,6 @@ function test_retrieve_available_mailing_lists() done } -function test_is_introduction_patch() -{ - local output - local sample_url - - sample_url='https://lore.kernel.org/amd-gfx/20221228163102.468-7-mario.limonciello@amd.com/T/#u' - is_introduction_patch "$sample_url" - assertEquals "($LINENO)" "$?" 1 - - sample_url='https://lore.kernel.org/amd-gfx/20221214202141.1721178-1-aurabindo.pillai@amd.com/T/#u' - is_introduction_patch "$sample_url" - assertEquals "($LINENO)" "$?" 0 - - # Invalid url - sample_url='https://lore.kernel.org/linux-media/1ae68c9f-726a-3307-65e6-e699be1fc7b9@xs4all.nl/T/#u' - is_introduction_patch "$sample_url" - assertEquals "($LINENO)" "$?" 1 -} - function test_get_patch_metadata() { local message_title @@ -436,76 +417,6 @@ function test_process_name() assertEquals "($LINENO)" "$output" "$expected" } -function test_extract_metadata_from_patch_title_with_all_metadata() -{ - local output - local sample_name - local sample_url - local expected - - # shellcheck disable=SC2317 - function total_patches_in_the_series() - { - printf '0' - } - - sample_url='https://lore.kernel.org/dri-devel/20221230153554.105856-2-robert.foss@linaro.org/T/#u' - expected="4${SEPARATOR_CHAR}11${SEPARATOR_CHAR}" - expected+='dt-bindings: display: msm: Add qcom, sm8350-dpu binding' - expected+="${SEPARATOR_CHAR}${sample_url}" - - sample_name='[PATCH v4 01/11] dt-bindings: display: msm: Add qcom, sm8350-dpu binding' - - output=$(extract_metadata_from_patch_title "$sample_name" "$sample_url") - assertEquals "($LINENO)" "$output" "$expected" -} - -function test_extract_metadata_from_patch_title_single_patch() -{ - local output - local sample_name - local sample_url - local expected - - # shellcheck disable=SC2317 - function total_patches_in_the_series() - { - printf '0' - } - - expected="1${SEPARATOR_CHAR}1${SEPARATOR_CHAR}" - expected+='drm/vc4: drop all currently held locks if deadlock happens' - expected+="${SEPARATOR_CHAR}" - - sample_name='[PATCH] drm/vc4: drop all currently held locks if deadlock happens' - output=$(extract_metadata_from_patch_title "$sample_name") - - assertEquals "($LINENO)" "$output" "$expected" -} - -function test_extract_metadata_from_patch_title_rfc() -{ - local output - local sample_name - local sample_url - local expected - - # shellcheck disable=SC2317 - function total_patches_in_the_series() - { - printf '0' - } - - expected="1${SEPARATOR_CHAR}20${SEPARATOR_CHAR}" - expected+='Initial Xe driver submission' - expected+="${SEPARATOR_CHAR}" - - sample_name='[RFC PATCH 00/20] Initial Xe driver submission' - output=$(extract_metadata_from_patch_title "$sample_name") - - assertEquals "($LINENO)" "$output" "$expected" -} - function test_delete_series_from_local_storage() { local download_dir_path="${SHUNIT_TMPDIR}/some/dir" @@ -612,9 +523,9 @@ function test_get_bookmarked_series() local output { - printf 'AUTHOR1%s %s %s %sTITLE1%s %s %sDATE1\n' "$char" "$char" "$char" "$char" "$char" "$char" "$char" - printf 'AUTHOR2%s %s %s %sTITLE2%s %s %sDATE2\n' "$char" "$char" "$char" "$char" "$char" "$char" "$char" - printf 'AUTHOR3%s %s %s %sTITLE3%s %s %sDATE3\n' "$char" "$char" "$char" "$char" "$char" "$char" "$char" + printf '%sTITLE1%sAUTHOR1%s%s%s%s%s%s%s%sDATE1\n' "$char" "$char" "$char" "$char" "$char" "$char" "$char" "$char" "$char" "$char" + printf '%sTITLE2%sAUTHOR2%s%s%s%s%s%s%s%sDATE2\n' "$char" "$char" "$char" "$char" "$char" "$char" "$char" "$char" "$char" "$char" + printf '%sTITLE3%sAUTHOR3%s%s%s%s%s%s%s%sDATE3\n' "$char" "$char" "$char" "$char" "$char" "$char" "$char" "$char" "$char" "$char" } >> "${BOOKMARKED_SERIES_PATH}" get_bookmarked_series bookmarked_series @@ -809,162 +720,309 @@ function test_compose_lore_query_url_with_verification_valid_cases() assert_equals_helper 'Wrong query URL outputted' "$LINENO" "$expected" "$output" } -function test_pre_process_xml_result() +function test_pre_process_raw_xml() { + local raw_xml local output local expected - output=$(pre_process_xml_result "${SHUNIT_TMPDIR}/samples/query_result_sample-1.xml") + raw_xml=$(< "${SHUNIT_TMPDIR}/samples/query_result_sample-1.xml") + output=$(pre_process_raw_xml "$raw_xml") expected=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-1") - assert_equals_helper 'Wrong pre-processed result' "$LINENO" "$expected" "$output" + assert_equals_helper 'Wrong pre-processed result for sample 1' "$LINENO" "$expected" "$output" + + raw_xml=$(< "${SHUNIT_TMPDIR}/samples/query_result_sample-2.xml") + output=$(pre_process_raw_xml "$raw_xml") + expected=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-2") + assert_equals_helper 'Wrong pre-processed result for sample 2' "$LINENO" "$expected" "$output" } -function test_process_patchsets_single_batch() +function test_process_individual_patches() { - local pre_processed_patches_sample + local -a individual_patches + declare -A individual_patches_metadata + local raw_xml local expected - # shellcheck disable=SC2317 - function is_introduction_patch() - { - local patch_url="$1" - [[ "$patch_url" =~ introduction ]] && return 0 - return 1 - } - - # shellcheck disable=SC2317 - function extract_metadata_from_patch_title() - { - local patch_title="${1}${SEPARATOR_CHAR}" - local patch_url="$2" - local patchset_version="X${SEPARATOR_CHAR}" - local total_patches="X${SEPARATOR_CHAR}" - - printf '%s%s%s%s' "$patchset_version" "$total_patches" "$patch_title" "$patch_url" - } - - # Clear number of patchsets processed and data structure with patchsets - reset_current_lore_fetch_session - - # Process single batch - pre_processed_patches_sample=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-1") - process_patchsets "$pre_processed_patches_sample" - - assert_equals_helper 'Wrong number of patchsets processed' "$LINENO" 2 "$PATCHSETS_PROCESSED" - - expected='Gilberto GilƆgil.gil@mpb.brƆXƆXƆ[PATCH v3] Add Palco to MPBƆhttp://lore.kernel.org/mpb/introduction' - assert_equals_helper 'Wrong processed patchset (index 0)' "$LINENO" "$expected" "${list_of_mailinglist_patches[0]}" + # Process first batch + raw_xml=$(< "${SAMPLES_DIR}/lore/query_result_sample-1.xml") + process_individual_patches "$raw_xml" 'individual_patches' + + # Check the list of processed individual patches + assert_equals_helper 'Should have processed 3 individual patches' "$LINENO" 3 "${#individual_patches[@]}" + expected='http://lore.kernel.org/mpb/introductionƆAdd Palco to MPBƆGilberto GilƆgil.gil@mpb.brƆ3Ɔ1Ɔ1Ɔ2023/08/09 21:27Ɔ' + assert_equals_helper 'Wrong processing of patch 0' "$LINENO" "$expected" "${individual_patches[0]}" + expected='http://lore.kernel.org/soul/sequelƆtim-maia/racional: Add Bom Senso to albumƆTim MaiaƆtim.maia@soul.brƆ1Ɔ3Ɔ9Ɔ2023/08/09 19:10Ɔhttp://lore.kernel.org/soul/introduction' + assert_equals_helper 'Wrong processing of patch 1' "$LINENO" "$expected" "${individual_patches[1]}" + expected='http://lore.kernel.org/rock/introductionƆIntroduce Ziggy StardustƆDavid BowieƆmajor.tom@rock.ukƆ12Ɔ1Ɔ1Ɔ2023/08/09 19:10Ɔ' + assert_equals_helper 'Wrong processing of patch 2' "$LINENO" "$expected" "${individual_patches[2]}" + + # Check the metadata of the processed patches + assert_equals_helper 'Should have 3 patches metadata' "$LINENO" 3 "${#individual_patches_metadata[@]}" + expected='3,1' + assert_equals_helper 'Wrong metadata of patch 0' "$LINENO" "$expected" "${individual_patches_metadata['http://lore.kernel.org/mpb/introduction']}" + expected='1,3' + assert_equals_helper 'Wrong metadata of patch 1' "$LINENO" "$expected" "${individual_patches_metadata['http://lore.kernel.org/soul/sequel']}" + expected='12,1' + assert_equals_helper 'Wrong metadata of patch 2' "$LINENO" "$expected" "${individual_patches_metadata['http://lore.kernel.org/rock/introduction']}" - expected='David BowieƆmajor.tom@rock.ukƆXƆXƆ[RFC PATCH v12] Introduce Ziggy StardustƆhttp://lore.kernel.org/rock/introduction' - assert_equals_helper 'Wrong processed patchset (index 1)' "$LINENO" "$expected" "${list_of_mailinglist_patches[1]}" + # Process second batch + raw_xml=$(< "${SAMPLES_DIR}/lore/query_result_sample-2.xml") + process_individual_patches "$raw_xml" 'individual_patches' + + # Check the list of processed individual patches + assert_equals_helper 'Should have processed 3 individual patches' "$LINENO" 3 "${#individual_patches[@]}" + expected='http://lore.kernel.org/reggae/sequelƆbob-marley/survavil: Add One Drop to albumƆBob MarleyƆbob.marley@reggae.jmƆ2Ɔ7Ɔ10Ɔ2023/08/09 21:27Ɔ' + assert_equals_helper 'Wrong processing of patch 0' "$LINENO" "$expected" "${individual_patches[0]}" + expected='http://lore.kernel.org/punk/sequelƆcbj/camisa10: Add Só os Loucos Sabem to albumƆCharlie Brown Jr.Ɔcharlie.brown@punk.brƆ1Ɔ3Ɔ13Ɔ2023/08/09 19:10Ɔ' + assert_equals_helper 'Wrong processing of patch 1' "$LINENO" "$expected" "${individual_patches[1]}" + expected='http://lore.kernel.org/samba-pop/introductionƆRelease MĆŗsicas para Churrasco Vol.1ƆSeu JorgeƆseu.jorge@samba-pop.brƆ1Ɔ1Ɔ1Ɔ2023/08/09 19:10Ɔhttp://lore.kernel.org/samba-pop/request' + assert_equals_helper 'Wrong processing of patch 2' "$LINENO" "$expected" "${individual_patches[2]}" + + # Check the metadata of the processed patches + assert_equals_helper 'Should have 6 patches metadata' "$LINENO" 6 "${#individual_patches_metadata[@]}" + expected='3,1' + assert_equals_helper 'Wrong metadata of patch 0' "$LINENO" "$expected" "${individual_patches_metadata['http://lore.kernel.org/mpb/introduction']}" + expected='1,3' + assert_equals_helper 'Wrong metadata of patch 1' "$LINENO" "$expected" "${individual_patches_metadata['http://lore.kernel.org/soul/sequel']}" + expected='12,1' + assert_equals_helper 'Wrong metadata of patch 2' "$LINENO" "$expected" "${individual_patches_metadata['http://lore.kernel.org/rock/introduction']}" + expected='2,7' + assert_equals_helper 'Wrong metadata of patch 3' "$LINENO" "$expected" "${individual_patches_metadata['http://lore.kernel.org/reggae/sequel']}" + expected='1,3' + assert_equals_helper 'Wrong metadata of patch 4' "$LINENO" "$expected" "${individual_patches_metadata['http://lore.kernel.org/punk/sequel']}" + expected='1,1' + assert_equals_helper 'Wrong metadata of patch 5' "$LINENO" "$expected" "${individual_patches_metadata['http://lore.kernel.org/samba-pop/introduction']}" } -function test_process_patchsets_multiple_batches() +function test_process_representative_patches_general_case() { - local pre_processed_patches_sample - local expected - - # shellcheck disable=SC2317 - function is_introduction_patch() - { - local patch_url="$1" - [[ "$patch_url" =~ introduction ]] && return 0 - return 1 - } - - # shellcheck disable=SC2317 - function extract_metadata_from_patch_title() - { - local patch_title="${1}${SEPARATOR_CHAR}" - local patch_url="$2" - local patchset_version="X${SEPARATOR_CHAR}" - local total_patches="X${SEPARATOR_CHAR}" - - printf '%s%s%s%s' "$patchset_version" "$total_patches" "$patch_title" "$patch_url" - } - - # Clear number of patchsets processed and data structure with patchsets - reset_current_lore_fetch_session - - # Process first batch - pre_processed_patches_sample=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-1") - process_patchsets "$pre_processed_patches_sample" + declare -a representative_patches=() + declare -A individual_patches_metadata=() + declare -A processed_representative_patches=() + declare REPRESENTATIVE_PATCHES_PROCESSED=0 + + local -a individual_patches + local patch1='id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ2Ɔ0Ɔ3Ɔupdated1Ɔ' + local patch2='id2Ɔtitle2Ɔauthor2Ɔemail2Ɔ13Ɔ1Ɔ230Ɔupdated2Ɔ' + local patch3='id3Ɔtitle3Ɔauthor3Ɔemail3Ɔ2Ɔ3Ɔ3Ɔupdated3Ɔid1' + local patch4='id4Ɔtitle4Ɔauthor4Ɔemail4Ɔ2Ɔ1Ɔ3Ɔupdated4Ɔid1' + + individual_patches=( + "$patch1" + "$patch2" + "$patch3" + "$patch4" + ) + individual_patches_metadata=( + ['id1']='2,0' + ['id2']='13,1' + ['id3']='2,3' + ['id4']='2,1' + ) - # Process second batch - pre_processed_patches_sample=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-2") - process_patchsets "$pre_processed_patches_sample" + process_representative_patches 'individual_patches' - assert_equals_helper 'Wrong number of patchsets processed' "$LINENO" 3 "$PATCHSETS_PROCESSED" + assert_equals_helper 'Wrong size of `representative_patches` array' "$LINENO" 2 "${#representative_patches[@]}" + assert_equals_helper 'Wrong size of `processed_representative_patches` hashtable' "$LINENO" 2 "${#processed_representative_patches[@]}" + assert_equals_helper 'Wrong value of `REPRESENTATIVE_PATCHES_PROCESSED`' "$LINENO" 2 "$REPRESENTATIVE_PATCHES_PROCESSED" + assert_equals_helper 'Wrong representative patch 0' "$LINENO" "$patch1" "${representative_patches[0]}" + assert_equals_helper 'Wrong representative patch 1' "$LINENO" "$patch2" "${representative_patches[1]}" + assert_equals_helper 'Representative patch 0 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id1']}" + assert_equals_helper 'Representative patch 1 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id2']}" +} - expected='Gilberto GilƆgil.gil@mpb.brƆXƆXƆ[PATCH v3] Add Palco to MPBƆhttp://lore.kernel.org/mpb/introduction' - assert_equals_helper 'Wrong processed patchset (index 0)' "$LINENO" "$expected" "${list_of_mailinglist_patches[0]}" +function test_process_representative_patches_subsequent_calls() +{ + declare -a representative_patches=() + declare -A individual_patches_metadata=() + declare -A processed_representative_patches=() + declare REPRESENTATIVE_PATCHES_PROCESSED=0 + + local -a individual_patches + local patch1='id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ2Ɔ0Ɔ3Ɔupdated1Ɔ' + local patch2='id2Ɔtitle2Ɔauthor2Ɔemail2Ɔ13Ɔ1Ɔ230Ɔupdated2Ɔ' + local patch3='id3Ɔtitle3Ɔauthor3Ɔemail3Ɔ2Ɔ3Ɔ3Ɔupdated3Ɔid1' + local patch4='id4Ɔtitle4Ɔauthor4Ɔemail4Ɔ2Ɔ1Ɔ3Ɔupdated4Ɔid1' + local patch5='id5Ɔtitle5Ɔauthor5Ɔemail5Ɔ32Ɔ4Ɔ6Ɔupdated5Ɔ' + local patch6='id6Ɔtitle6Ɔauthor6Ɔemail6Ɔ4Ɔ2Ɔ14Ɔupdated6Ɔ' + local patch7='id7Ɔtitle7Ɔauthor7Ɔemail7Ɔ1Ɔ0Ɔ5Ɔupdated7Ɔ' + local patch8='id8Ɔtitle8Ɔauthor8Ɔemail8Ɔ1Ɔ1Ɔ5Ɔupdated8Ɔid7' + + individual_patches=( + "$patch1" + "$patch2" + "$patch3" + "$patch4" + ) + individual_patches_metadata=( + ['id1']='2,0' + ['id2']='13,1' + ['id3']='2,3' + ['id4']='2,1' + ) - expected='David BowieƆmajor.tom@rock.ukƆXƆXƆ[RFC PATCH v12] Introduce Ziggy StardustƆhttp://lore.kernel.org/rock/introduction' - assert_equals_helper 'Wrong processed patchset (index 1)' "$LINENO" "$expected" "${list_of_mailinglist_patches[1]}" + # First call + process_representative_patches 'individual_patches' - expected='Seu JorgeƆseu.jorge@samba-pop.brƆXƆXƆ[RFC] Release MĆŗsicas para Churrasco Vol.1Ɔhttp://lore.kernel.org/samba-pop/introduction' - assert_equals_helper 'Wrong processed patchset (index 2)' "$LINENO" "$expected" "${list_of_mailinglist_patches[2]}" + # Update data structs + individual_patches=( + "$patch5" + "$patch6" + "$patch7" + "$patch8" + ) + individual_patches_metadata['id5']='32,4' + individual_patches_metadata['id6']='4,2' + individual_patches_metadata['id7']='1,0' + individual_patches_metadata['id8']='1,1' + + # Second call + process_representative_patches 'individual_patches' + + assert_equals_helper 'Wrong size of `representative_patches` array' "$LINENO" 3 "${#representative_patches[@]}" + assert_equals_helper 'Wrong size of `processed_representative_patches` hashtable' "$LINENO" 3 "${#processed_representative_patches[@]}" + assert_equals_helper 'Wrong value of `REPRESENTATIVE_PATCHES_PROCESSED`' "$LINENO" 3 "$REPRESENTATIVE_PATCHES_PROCESSED" + assert_equals_helper 'Wrong representative patch 0' "$LINENO" "$patch1" "${representative_patches[0]}" + assert_equals_helper 'Wrong representative patch 1' "$LINENO" "$patch2" "${representative_patches[1]}" + assert_equals_helper 'Wrong representative patch 2' "$LINENO" "$patch7" "${representative_patches[2]}" + assert_equals_helper 'Representative patch 0 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id1']}" + assert_equals_helper 'Representative patch 1 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id2']}" + assert_equals_helper 'Representative patch 2 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id7']}" } -function test_process_patchsets_repeated_patches() +function test_process_representative_patches_duplicated_patches() { - local pre_processed_patches_sample - local expected + declare -a representative_patches=() + declare -A individual_patches_metadata=() + declare -A processed_representative_patches=() + declare REPRESENTATIVE_PATCHES_PROCESSED=0 + + local -a individual_patches + local patch1='id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ2Ɔ0Ɔ3Ɔupdated1Ɔ' + local patch2='id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ2Ɔ0Ɔ3Ɔupdated1Ɔ' + local patch3='id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ2Ɔ0Ɔ3Ɔupdated1Ɔ' + local patch4='id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ2Ɔ0Ɔ3Ɔupdated1Ɔ' + + individual_patches=( + "$patch1" + "$patch2" + "$patch3" + "$patch4" + ) + individual_patches_metadata=( + ['id1']='2,0' + ) - # Clear number of patchsets processed and data structure with patchsets - reset_current_lore_fetch_session + process_representative_patches 'individual_patches' - # Process list of repeated pre processed patches - pre_processed_patches_sample=$(< "${SHUNIT_TMPDIR}/samples/pre_processed_patches_sample-repeated") - process_patchsets "$pre_processed_patches_sample" - assert_equals_helper 'Repeated patches should not be processed again' "$LINENO" 1 "$PATCHSETS_PROCESSED" + assert_equals_helper 'Wrong size of `representative_patches` array' "$LINENO" 1 "${#representative_patches[@]}" + assert_equals_helper 'Wrong size of `processed_representative_patches` hashtable' "$LINENO" 1 "${#processed_representative_patches[@]}" + assert_equals_helper 'Wrong value of `REPRESENTATIVE_PATCHES_PROCESSED`' "$LINENO" 1 "$REPRESENTATIVE_PATCHES_PROCESSED" + assert_equals_helper 'Wrong representative patch 0' "$LINENO" "$patch1" "${representative_patches[0]}" + assert_equals_helper 'Representative patch 0 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id1']}" +} - expected='David BowieƆmajor.tom@rock.ukƆXƆXƆ[RFC PATCH v12] Introduce Ziggy StardustƆhttp://lore.kernel.org/rock/introduction' - assert_equals_helper 'Wrong processed patchset (index 0)' "$LINENO" "$expected" "${list_of_mailinglist_patches[0]}" +function test_read_patch_into_dict() +{ + local patch + declare -A patch_dict + + patch='id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ2Ɔ0Ɔ3Ɔupdated1Ɔ' + read_patch_into_dict "$patch" 'patch_dict' + assert_equals_helper 'Wrong value of messsage ID' "$LINENO" 'id1' "${patch_dict['message_id']}" + assert_equals_helper 'Wrong value of message title' "$LINENO" 'title1' "${patch_dict['message_title']}" + assert_equals_helper 'Wrong value of author name' "$LINENO" 'author1' "${patch_dict['author_name']}" + assert_equals_helper 'Wrong value of author email' "$LINENO" 'email1' "${patch_dict['author_email']}" + assert_equals_helper 'Wrong value of version' "$LINENO" 2 "${patch_dict['version']}" + assert_equals_helper 'Wrong value of number in series' "$LINENO" 0 "${patch_dict['number_in_series']}" + assert_equals_helper 'Wrong value of total in series' "$LINENO" 3 "${patch_dict['total_in_series']}" + assert_equals_helper 'Wrong value of updated' "$LINENO" 'updated1' "${patch_dict['updated']}" + assert_equals_helper 'Wrong value of in reply to' "$LINENO" '' "${patch_dict['in_reply_to']}" + assert_equals_helper 'Wrong value of download dir path' "$LINENO" '' "${patch_dict['download_dir_path']}" + assert_equals_helper 'Wrong value of timestamp' "$LINENO" '' "${patch_dict['timestamp']}" + + patch='id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ2Ɔ0Ɔ3Ɔupdated1ƆidX' + read_patch_into_dict "$patch" 'patch_dict' + assert_equals_helper 'Wrong value of messsage ID' "$LINENO" 'id1' "${patch_dict['message_id']}" + assert_equals_helper 'Wrong value of message title' "$LINENO" 'title1' "${patch_dict['message_title']}" + assert_equals_helper 'Wrong value of author name' "$LINENO" 'author1' "${patch_dict['author_name']}" + assert_equals_helper 'Wrong value of author email' "$LINENO" 'email1' "${patch_dict['author_email']}" + assert_equals_helper 'Wrong value of version' "$LINENO" 2 "${patch_dict['version']}" + assert_equals_helper 'Wrong value of number in series' "$LINENO" 0 "${patch_dict['number_in_series']}" + assert_equals_helper 'Wrong value of total in series' "$LINENO" 3 "${patch_dict['total_in_series']}" + assert_equals_helper 'Wrong value of updated' "$LINENO" 'updated1' "${patch_dict['updated']}" + assert_equals_helper 'Wrong value of in reply to' "$LINENO" 'idX' "${patch_dict['in_reply_to']}" + assert_equals_helper 'Wrong value of download dir path' "$LINENO" '' "${patch_dict['download_dir_path']}" + assert_equals_helper 'Wrong value of timestamp' "$LINENO" '' "${patch_dict['timestamp']}" + + patch='id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ2Ɔ0Ɔ3Ɔupdated1ƆidXƆpath1Ɔtimestamp1' + read_patch_into_dict "$patch" 'patch_dict' + assert_equals_helper 'Wrong value of messsage ID' "$LINENO" 'id1' "${patch_dict['message_id']}" + assert_equals_helper 'Wrong value of message title' "$LINENO" 'title1' "${patch_dict['message_title']}" + assert_equals_helper 'Wrong value of author name' "$LINENO" 'author1' "${patch_dict['author_name']}" + assert_equals_helper 'Wrong value of author email' "$LINENO" 'email1' "${patch_dict['author_email']}" + assert_equals_helper 'Wrong value of version' "$LINENO" 2 "${patch_dict['version']}" + assert_equals_helper 'Wrong value of number in series' "$LINENO" 0 "${patch_dict['number_in_series']}" + assert_equals_helper 'Wrong value of total in series' "$LINENO" 3 "${patch_dict['total_in_series']}" + assert_equals_helper 'Wrong value of updated' "$LINENO" 'updated1' "${patch_dict['updated']}" + assert_equals_helper 'Wrong value of in reply to' "$LINENO" 'idX' "${patch_dict['in_reply_to']}" + assert_equals_helper 'Wrong value of download dir path' "$LINENO" 'path1' "${patch_dict['download_dir_path']}" + assert_equals_helper 'Wrong value of timestamp' "$LINENO" 'timestamp1' "${patch_dict['timestamp']}" } function test_reset_current_lore_fetch_session() { - list_of_mailinglist_patches[0]=1 - list_of_mailinglist_patches[1]=1 - list_of_mailinglist_patches[2]=1 - PATCHSETS_PROCESSED=3 - MIN_INDEX=200 - declare -Ag processed_patchsets - processed_patchsets['patch_1']=1 - processed_patchsets['patch_2']=1 - processed_patchsets['patch_3']=1 + representative_patches[0]=1 + representative_patches[1]=1 + representative_patches[2]=1 + declare -Ag individual_patches_metadata + individual_patches_metadata['patch_1a']=1 + individual_patches_metadata['patch_1b']=1 + individual_patches_metadata['patch_1c']=1 + individual_patches_metadata['patch_2']=1 + individual_patches_metadata['patch_3a']=1 + individual_patches_metadata['patch_3b']=1 + individual_patches_metadata['patch_3c']=1 + individual_patches_metadata['patch_3d']=1 + declare -Ag processed_representative_patches + processed_representative_patches['patch_1']=1 + processed_representative_patches['patch_2']=1 + processed_representative_patches['patch_3']=1 + REPRESENTATIVE_PATCHES_PROCESSED=3 + MIN_INDEX=200 - reset_current_lore_fetch_session 2 - assert_equals_helper 'Should reset `list_of_mailinglist_patches`' "$LINENO" 0 "${#list_of_mailinglist_patches[@]}" - assert_equals_helper 'Should reset `PATCHSETS_PROCESSED`' "$LINENO" 0 "$PATCHSETS_PROCESSED" + reset_current_lore_fetch_session + assert_equals_helper 'Should reset `representative_patches`' "$LINENO" 0 "${#representative_patches[@]}" + assert_equals_helper 'Should reset `REPRESENTATIVE_PATCHES_PROCESSED`' "$LINENO" 0 "$REPRESENTATIVE_PATCHES_PROCESSED" assert_equals_helper 'Should reset `MIN_INDEX`' "$LINENO" 0 "$MIN_INDEX" - assert_equals_helper 'Should reset `processed_patchsets`' "$LINENO" 0 "${#processed_patchsets[@]}" + assert_equals_helper 'Should reset `processed_representative_patches`' "$LINENO" 0 "${#processed_representative_patches[@]}" } function test_format_patchsets() { local -a formatted_patchsets_list + local output - list_of_mailinglist_patches[0]='Jay CornwallƆjay.cornwall@amd.comƆ1Ɔ1Ɔdrm/amdkfd: Add missing tba_hi programming on aldebaranƆ' - list_of_mailinglist_patches[0]+='http://lore.kernel.org/amd-gfx/20230809212615.137674-1-jay.cornwall@amd.com/' - list_of_mailinglist_patches[1]='Alex DeucherƆalexander.deucher@amd.comƆ1Ɔ10Ɔdrm/amdgpu: don'"'"'t allow userspace to create a doorbell BOƆ' - list_of_mailinglist_patches[1]+='http://lore.kernel.org/amd-gfx/20230809190956.435068-1-alexander.deucher@amd.com/' - list_of_mailinglist_patches[2]='Juca PiramaƆjuca.pirama@jp.comƆ3Ɔ1Ɔdrm/amdgpu: improve everythingƆ' - list_of_mailinglist_patches[2]+='http://lore.kernel.org/amd-gfx/15230802663656.432068-1-juca.pirama@jp.com/' - formatted_patchsets_list[0]=1 + representative_patches[0]='message-id0Ɔtitle0Ɔauthor0Ɔemail0Ɔ2Ɔ1Ɔ6Ɔupdated0Ɔin-reply-to0Ɔdir0Ɔtimestamp0' + representative_patches[1]='message-id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ1Ɔ0Ɔ3Ɔupdated1Ɔin-reply-to1Ɔdir1Ɔtimestamp1' + representative_patches[2]='message-id2Ɔtitle2Ɔauthor2Ɔemail2Ɔ16Ɔ1Ɔ8Ɔupdated2Ɔin-reply-to2Ɔdir2Ɔtimestamp2' + formatted_patchsets_list[0]='Vold |#old | titleold' format_patchsets 'formatted_patchsets_list' 1 2 assert_equals_helper 'Wrong number of patchsets formatted' "$LINENO" 3 "${#formatted_patchsets_list[@]}" - expected='V1 |#10 | drm/amdgpu: don'"'"'t allow userspace to create a doorbell BO' - [[ "${formatted_patchsets_list[1]}" =~ $expected ]] # to account for trailing whitespace - assert_equals_helper 'Wrong formatted patchset' "$LINENO" 0 "$?" + expected='Vold |#old | titleold' + assert_equals_helper 'Should not overwrite out-of-range entry' "$LINENO" "$expected" "${formatted_patchsets_list[0]}" + + expected='V1 |#3 | title1' + output=$(printf '%s' "${formatted_patchsets_list[1]}" | sed 's/ *$//') # trim trailing whitespace + assert_equals_helper 'Wrong formatted patchset 1' "$LINENO" "$expected" "$output" - expected='V3 |#1 | drm/amdgpu: improve everything' - [[ "${formatted_patchsets_list[2]}" =~ $expected ]] # to account for trailing whitespace - assert_equals_helper 'Wrong formatted patchset' "$LINENO" 0 "$?" + expected='V16 |#8 | title2' + output=$(printf '%s' "${formatted_patchsets_list[2]}" | sed 's/ *$//') # trim trailing whitespace + assert_equals_helper 'Wrong formatted patchset 2' "$LINENO" "$expected" "$output" } function test_get_page_starting_index() @@ -973,11 +1031,11 @@ function test_get_page_starting_index() local patchsets_per_page local output - # Mocking `list_of_mailinglist_patches` with 199 patchsets - unset list_of_mailinglist_patches - declare -gA list_of_mailinglist_patches + # Mocking `representative_patches` with 199 patchsets + unset representative_patches + declare -gA representative_patches for i in $(seq 0 199); do - list_of_mailinglist_patches["$i"]=1 + representative_patches["$i"]=1 done page=5 @@ -997,11 +1055,11 @@ function test_get_page_ending_index() local patchsets_per_page local output - # Mocking `list_of_mailinglist_patches` with 199 patchsets - unset list_of_mailinglist_patches - declare -gA list_of_mailinglist_patches + # Mocking `representative_patches` with 199 patchsets + unset representative_patches + declare -gA representative_patches for i in $(seq 0 199); do - list_of_mailinglist_patches["$i"]=1 + representative_patches["$i"]=1 done page=3 diff --git a/tests/unit/samples/lore/pre_processed_patches_sample-1 b/tests/unit/samples/lore/pre_processed_patches_sample-1 index 10a33b289..0a4047c79 100644 --- a/tests/unit/samples/lore/pre_processed_patches_sample-1 +++ b/tests/unit/samples/lore/pre_processed_patches_sample-1 @@ -1,12 +1,17 @@ Gilberto Gil gil.gil@mpb.br [PATCH v3] Add Palco to MPB - href="http://lore.kernel.org/mpb/introduction" +2023-08-09T21:27:00Z +href="http://lore.kernel.org/mpb/introduction" Tim Maia tim.maia@soul.br [PATCH 3/9] tim-maia/racional: Add Bom Senso to album - href="http://lore.kernel.org/soul/sequel" +2023-08-09T19:10:26Z +href="http://lore.kernel.org/soul/sequel" +href="http://lore.kernel.org/soul/introduction" David Bowie major.tom@rock.uk [RFC PATCH v12] Introduce Ziggy Stardust - href="http://lore.kernel.org/rock/introduction" +2023-08-09T19:10:22Z +href="http://lore.kernel.org/rock/introduction" + \ No newline at end of file diff --git a/tests/unit/samples/lore/pre_processed_patches_sample-2 b/tests/unit/samples/lore/pre_processed_patches_sample-2 index 87c974c79..ad013809c 100644 --- a/tests/unit/samples/lore/pre_processed_patches_sample-2 +++ b/tests/unit/samples/lore/pre_processed_patches_sample-2 @@ -1,12 +1,17 @@ Bob Marley bob.marley@reggae.jm [PATCH v2 7/10] bob-marley/survavil: Add One Drop to album - href="http://lore.kernel.org/reggae/sequel" +2023-08-09T21:27:00Z +href="http://lore.kernel.org/reggae/sequel" Charlie Brown Jr. charlie.brown@punk.br [PATCH 3/13] cbj/camisa10: Add Só os Loucos Sabem to album - href="http://lore.kernel.org/punk/sequel" +2023-08-09T19:10:26Z +href="http://lore.kernel.org/punk/sequel" Seu Jorge seu.jorge@samba-pop.br [RFC] Release MĆŗsicas para Churrasco Vol.1 - href="http://lore.kernel.org/samba-pop/introduction" +2023-08-09T19:10:22Z +href="http://lore.kernel.org/samba-pop/introduction" +href="http://lore.kernel.org/samba-pop/request" + \ No newline at end of file diff --git a/tests/unit/samples/lore/query_result_sample-1.xml b/tests/unit/samples/lore/query_result_sample-1.xml index 316e8a71f..59d014664 100644 --- a/tests/unit/samples/lore/query_result_sample-1.xml +++ b/tests/unit/samples/lore/query_result_sample-1.xml @@ -1,4 +1,4 @@ - + @@ -22,7 +22,7 @@ 2023-08-09T19:10:26Z urn:uuid:66fe77b1-55ad-6670-73ee-54e933cf5f63 - + ... diff --git a/tests/unit/samples/lore/query_result_sample-2.xml b/tests/unit/samples/lore/query_result_sample-2.xml new file mode 100644 index 000000000..abe1363e2 --- /dev/null +++ b/tests/unit/samples/lore/query_result_sample-2.xml @@ -0,0 +1,43 @@ + + + + + Bob Marley + bob.marley@reggae.jm + + [PATCH v2 7/10] bob-marley/survavil: Add One Drop to album + 2023-08-09T21:27:00Z + + urn:uuid:2f9fa3da-2057-86a4-aa20-9ad0239ff7a3 + + ... + + + + + Charlie Brown Jr. + charlie.brown@punk.br + + [PATCH 3/13] cbj/camisa10: Add Só os Loucos Sabem to album + 2023-08-09T19:10:26Z + + urn:uuid:66fe77b1-55ad-6670-73ee-54e933cf5f63 + + ... + + + + + Seu Jorge + seu.jorge@samba-pop.br + + [RFC] Release MĆŗsicas para Churrasco Vol.1 + 2023-08-09T19:10:22Z + + urn:uuid:b09294a9-df54-a8b1-cf19-6f58c2febdd3 + + + ... + + + \ No newline at end of file diff --git a/tests/unit/ui/patch_hub/patch_hub_core_test.sh b/tests/unit/ui/patch_hub/patch_hub_core_test.sh index 5c2fb9785..af168e39a 100755 --- a/tests/unit/ui/patch_hub/patch_hub_core_test.sh +++ b/tests/unit/ui/patch_hub/patch_hub_core_test.sh @@ -52,7 +52,7 @@ function test_show_dashboard() function test_list_patches_with_patches() { local -a patchsets_metadata_array - declare -ag list_of_mailinglist_patches + declare -ag representative_patches # shellcheck disable=SC2317 function create_menu_options() @@ -66,14 +66,14 @@ function test_list_patches_with_patches() 'more_patches_metadata' ) - list_of_mailinglist_patches=( + representative_patches=( 'some_patch_raw_data' 'some_other_patch_raw_data' 'more_patches_raw_data' ) screen_sequence['SHOW_SCREEN']='latest_patchsets_from_mailing_list' - list_patches 'Message test' list_of_mailinglist_patches '' + list_patches 'Message test' representative_patches '' assert_equals_helper 'Wrong screen set' "$LINENO" 'patchset_details_and_actions' "${screen_sequence['SHOW_SCREEN']}" assert_equals_helper 'Wrong screen parameter' "$LINENO" 'more_patches_raw_data' "${screen_sequence['SHOW_SCREEN_PARAMETER']}" diff --git a/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh b/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh index 692e1b2a6..0ee5c9d2c 100755 --- a/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh +++ b/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh @@ -35,13 +35,13 @@ function tearDown() function test_show_patchset_details_and_actions() { - local raw_patchset='Juca PiramaƆjucapirama@xpto.comƆV1Ɔ255ƆDC Patches November 19, 2022Ɔhttp://anotherthing.la' + local raw_patchset='message_idƆmessage: titleƆJuca PiramaƆjuca@pirama.foo.barƆ4Ɔ8Ɔ42Ɔ2024/02/14 21:32Ɔin_reply_to_message_id' local output local expected_result='Patchset details and actions' - expected_result+=' \Zb\Z6Series:\ZnDC Patches November 19, 2022\n' - expected_result+='\Zb\Z6Author:\ZnJuca Pirama\n\Zb\Z6Version:\ZnV1\n' - expected_result+='\Zb\Z6Patches:\Zn255\n' + expected_result+=' \Zb\Z6Series:\Znmessage: title\n' + expected_result+='\Zb\Z6Author:\ZnJuca Pirama\n\Zb\Z6Version:\Zn4\n' + expected_result+='\Zb\Z6Patches:\Zn42\n' expected_result+=' Download to specific directory Bookmark' # shellcheck disable=SC2317 @@ -201,18 +201,18 @@ test_handle_remove_bookmark_action() return 0 } - patchset['patchset_url']='https://lore.kernel.org/amd-gfx/20230622215735.2026220-1-Rodrigo.Siqueira@amd.com/' + patchset['message_id']='message-id' lore_config['save_patches_to']="$SHUNIT_TMPDIR" - mbx_file_path="${lore_config['save_patches_to']}/20230622215735.2026220-1-Rodrigo.Siqueira@amd.com.mbx" + mbx_file_path="${lore_config['save_patches_to']}/message-id.mbx" touch "$mbx_file_path" - printf 'https://lore.kernel.org/list/message-ID/' >> "$BOOKMARKED_SERIES_PATH" + printf '%s' "${patchset['message_id']}" >> "$BOOKMARKED_SERIES_PATH" handle_remove_bookmark_action 'patchset' [[ ! -f "$mbx_file_path" ]] assert_equals_helper 'Should have removed the .mbx file' "$LINENO" 0 "$?" output=$(< "$BOOKMARKED_SERIES_PATH") # shellcheck disable=SC2076 - [[ ! "$output" =~ "${patchset['patchset_url']}" ]] + [[ ! "$output" =~ "${patchset['message_id']}" ]] assert_equals_helper 'Should have removed patchset entry from database' "$LINENO" 0 "$?" } From 9c4a5dd41405c4892ded5e8f6e0e07cc0860827f Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Tue, 20 Feb 2024 14:33:52 -0300 Subject: [PATCH 064/128] src: lib: lore: Handle patch not yet processed when electing representative When electing representative patches in the `kw patch-hub` feature, which is vital to correctly listing patchsets, there is a border case that is not consider: when the possible representative patch has a in-reply-to message that has not yet been processed. In this case, the logic always determine that the patch is representative, which isn't true every time. To mitigate this, make a request for the raw version of the in-reply-to message that hasn't been processed, extract the necessary information, and determine if the original patch is representive as before. This implementation adds a network requisition that can incur in the same problem `kw patch-hub` had of many chained requisitions. However, as the number of requests is predictable (one per patch, in the extreme case), when we add parallelization to the processing, this will be solved. Signed-off-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/lib/lore.sh | 63 ++++++++++++++++----- tests/unit/lib/lore_test.sh | 110 ++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 15 deletions(-) diff --git a/src/lib/lore.sh b/src/lib/lore.sh index 236c4b289..a303b26e1 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -542,6 +542,30 @@ function process_individual_patches() done <<< "$pre_processed_patches" } +# This function makes the lore request to get the raw contents of a lore +# message. +# +# @message_id: Message-ID of desired lore message. +# @flag: Flag to control function output. +# +# Returns: +# - Output: Response from requisiton to raw lore message. +function get_raw_lore_message() +{ + local message_id="$1" + local flag="${2:-SILENT}" + local raw_message_url + + if [[ "$message_id" =~ /$ ]]; then + raw_message_url=$(replace_http_by_https "${message_id}raw") + else + raw_message_url=$(replace_http_by_https "${message_id}/raw") + fi + + # TODO: Add cache functionality + cmd_manager "$flag" "curl --silent '${raw_message_url}'" +} + # This function processes representative patches (i.e. the first message in a # patchset) from a list of processed individual patches. The patches determined # as representatives are stored (in the same order as the argument @@ -556,11 +580,13 @@ function process_individual_patches() function process_representative_patches() { local -n _individual_patches_array="$1" + local is_representative_patch local message_id local in_reply_to_message_id local -a patch_metadata local -a in_reply_to_metadata - local is_representative_patch + local in_reply_to_title + local in_reply_to_patch_metadata for patch in "${_individual_patches_array[@]}"; do is_representative_patch='' @@ -572,29 +598,36 @@ function process_representative_patches() # To avoid duplication, check if patch has been processed as representative message_id="${patch_dict['message_id']}" [[ -n "${processed_representative_patches["$message_id"]}" ]] && continue + in_reply_to_message_id="${patch_dict['in_reply_to']}" # Assume that patch number 0 is always the representative as the cover letter if [[ "${patch_dict['number_in_series']}" == 0 ]]; then is_representative_patch=1 # Assume that, when there is no patch number 0, number 1 is the representative + # if it is a root of a thread + elif [[ "${patch_dict['number_in_series']}" == 1 && -z "$in_reply_to_message_id" ]]; then + is_representative_patch=1 + # Assume that, if 'In-Reply-To' is not patch number 0 from the same version, + # number 1 is the representative elif [[ "${patch_dict['number_in_series']}" == 1 ]]; then - # Assume that patch number 1 without 'In-Reply-To' means no number 0 - if [[ "${patch_dict['total_in_series']}" == 1 || - -z "${patch_dict['in_reply_to']}" ]]; then - is_representative_patch=1 - else - patch_metadata=() - in_reply_to_metadata=() - in_reply_to_message_id="${patch_dict['in_reply_to']}" - IFS=',' read -ra patch_metadata <<< "${individual_patches_metadata["$message_id"]}" - IFS=',' read -ra in_reply_to_metadata <<< "${individual_patches_metadata["$in_reply_to_message_id"]}" + patch_metadata=() + in_reply_to_metadata=() + IFS=',' read -ra patch_metadata <<< "${individual_patches_metadata["$message_id"]}" - # Assume that, if 'In-Reply-To' is not patch number 0 from the same - # version, number 1 is the representative - if [[ "${patch_metadata[0]}" != "${in_reply_to_metadata[0]}" || "${in_reply_to_metadata[1]}" != 0 ]]; then - is_representative_patch=1 + if [[ -n "${individual_patches_metadata["$in_reply_to_message_id"]}" ]]; then + IFS=',' read -ra in_reply_to_metadata <<< "${individual_patches_metadata["$in_reply_to_message_id"]}" + else + in_reply_to_title=$(get_raw_lore_message "$message_id" | grep --perl-regexp '^Subject:' | sed 's/^Subject: //') + in_reply_to_patch_metadata=$(get_patch_metadata "$in_reply_to_title") + if [[ -n "$in_reply_to_patch_metadata" ]]; then + in_reply_to_metadata[0]=$(get_patch_version "$in_reply_to_patch_metadata") + in_reply_to_metadata[1]=$(get_patch_number_in_series "$in_reply_to_patch_metadata") fi fi + + if [[ "${patch_metadata[0]}" != "${in_reply_to_metadata[0]}" || "${in_reply_to_metadata[1]}" != 0 ]]; then + is_representative_patch=1 + fi fi if [[ -n "$is_representative_patch" ]]; then diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index fd4075eb7..7030bf95e 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -832,6 +832,18 @@ function test_process_representative_patches_general_case() assert_equals_helper 'Representative patch 1 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id2']}" } +function test_get_raw_lore_message() +{ + local expected="curl --silent 'https://domain/list/message-id/raw'" + local output + + output=$(get_raw_lore_message 'http://domain/list/message-id/' 'TEST-MODE') + assert_equals_helper 'Wrong command issued' "$LINENO" "$expected" "$output" + + output=$(get_raw_lore_message 'http://domain/list/message-id' 'TEST-MODE') + assert_equals_helper 'Wrong command issued' "$LINENO" "$expected" "$output" +} + function test_process_representative_patches_subsequent_calls() { declare -a representative_patches=() @@ -923,6 +935,104 @@ function test_process_representative_patches_duplicated_patches() assert_equals_helper 'Representative patch 0 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id1']}" } +function test_process_representative_patches_in_reply_to_not_processed() +{ + declare -a representative_patches=() + declare -A individual_patches_metadata=() + declare -A processed_representative_patches=() + declare REPRESENTATIVE_PATCHES_PROCESSED=0 + + local -a individual_patches + local patch1='id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ2Ɔ1Ɔ3Ɔupdated1Ɔid-not-processed' + + individual_patches=( + "$patch1" + ) + individual_patches_metadata=( + ['id1']='2,1' + ) + + # Case 1: In reply isn't a patch + # shellcheck disable=SC2317 + function get_raw_lore_message() + { + printf 'Subject: Some discussion' + } + process_representative_patches 'individual_patches' + + assert_equals_helper 'Wrong size of `representative_patches` array' "$LINENO" 1 "${#representative_patches[@]}" + assert_equals_helper 'Wrong size of `processed_representative_patches` hashtable' "$LINENO" 1 "${#processed_representative_patches[@]}" + assert_equals_helper 'Wrong value of `REPRESENTATIVE_PATCHES_PROCESSED`' "$LINENO" 1 "$REPRESENTATIVE_PATCHES_PROCESSED" + assert_equals_helper 'Wrong representative patch 0' "$LINENO" "$patch1" "${representative_patches[0]}" + assert_equals_helper 'Representative patch 0 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id1']}" + + # Case 2: In reply is patch from same patchset, but not cover letter + # shellcheck disable=SC2317 + function get_raw_lore_message() + { + printf 'Subject: [PATCH v2 2/3] Some title' + } + representative_patches=() + processed_representative_patches=() + REPRESENTATIVE_PATCHES_PROCESSED=0 + process_representative_patches 'individual_patches' + + assert_equals_helper 'Wrong size of `representative_patches` array' "$LINENO" 1 "${#representative_patches[@]}" + assert_equals_helper 'Wrong size of `processed_representative_patches` hashtable' "$LINENO" 1 "${#processed_representative_patches[@]}" + assert_equals_helper 'Wrong value of `REPRESENTATIVE_PATCHES_PROCESSED`' "$LINENO" 1 "$REPRESENTATIVE_PATCHES_PROCESSED" + assert_equals_helper 'Wrong representative patch 0' "$LINENO" "$patch1" "${representative_patches[0]}" + assert_equals_helper 'Representative patch 0 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id1']}" + + # Case 3: In reply is patch from same patchset and cover letter + # shellcheck disable=SC2317 + function get_raw_lore_message() + { + printf 'Subject: [PATCH v2 0/3] Some title' + } + representative_patches=() + processed_representative_patches=() + REPRESENTATIVE_PATCHES_PROCESSED=0 + process_representative_patches 'individual_patches' + + assert_equals_helper 'Wrong size of `representative_patches` array' "$LINENO" 0 "${#representative_patches[@]}" + assert_equals_helper 'Wrong size of `processed_representative_patches` hashtable' "$LINENO" 0 "${#processed_representative_patches[@]}" + assert_equals_helper 'Wrong value of `REPRESENTATIVE_PATCHES_PROCESSED`' "$LINENO" 0 "$REPRESENTATIVE_PATCHES_PROCESSED" + + # Case 4: In reply isn't patch from same patchset and isn't cover letter + # shellcheck disable=SC2317 + function get_raw_lore_message() + { + printf 'Subject: [PATCH 0/3] Some title' + } + representative_patches=() + processed_representative_patches=() + REPRESENTATIVE_PATCHES_PROCESSED=0 + process_representative_patches 'individual_patches' + + assert_equals_helper 'Wrong size of `representative_patches` array' "$LINENO" 1 "${#representative_patches[@]}" + assert_equals_helper 'Wrong size of `processed_representative_patches` hashtable' "$LINENO" 1 "${#processed_representative_patches[@]}" + assert_equals_helper 'Wrong value of `REPRESENTATIVE_PATCHES_PROCESSED`' "$LINENO" 1 "$REPRESENTATIVE_PATCHES_PROCESSED" + assert_equals_helper 'Wrong representative patch 0' "$LINENO" "$patch1" "${representative_patches[0]}" + assert_equals_helper 'Representative patch 0 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id1']}" + + # Case 5: In reply isn't patch from same patchset, but is cover letter + # shellcheck disable=SC2317 + function get_raw_lore_message() + { + printf 'Subject: [PATCH 0/3] Some title' + } + representative_patches=() + processed_representative_patches=() + REPRESENTATIVE_PATCHES_PROCESSED=0 + process_representative_patches 'individual_patches' + + assert_equals_helper 'Wrong size of `representative_patches` array' "$LINENO" 1 "${#representative_patches[@]}" + assert_equals_helper 'Wrong size of `processed_representative_patches` hashtable' "$LINENO" 1 "${#processed_representative_patches[@]}" + assert_equals_helper 'Wrong value of `REPRESENTATIVE_PATCHES_PROCESSED`' "$LINENO" 1 "$REPRESENTATIVE_PATCHES_PROCESSED" + assert_equals_helper 'Wrong representative patch 0' "$LINENO" "$patch1" "${representative_patches[0]}" + assert_equals_helper 'Representative patch 0 should be marked in hashtable' "$LINENO" 1 "${processed_representative_patches['id1']}" +} + function test_read_patch_into_dict() { local patch From e342a3e7dd1ff0befa1785d74ba7d4a858544841 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Thu, 7 Mar 2024 12:26:46 -0300 Subject: [PATCH 065/128] src: lib: lore: Parallelize `process_individual_patches` The processing of patches for listing patchsets has two major stages after fetching the Atom feed with the patches and pre processing it. The first major stage consists in traversing the pre processed list of patches sequentially, processing each one of them individually, and marking everyone in a hashtable. This stage is represented by the `process_individual_patches`. As we can leverage parallel computing in this case, parallelize the function by issuing a dedicated thread for handling each patch. This takes care of much of the processing done in `process_individual_patches` resulting in a gain of performance. Helps: #911 Signed-off-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/lib/lore.sh | 100 ++++++++++++++++++++++++++---------- tests/unit/lib/lore_test.sh | 53 +++++++++++++++++++ 2 files changed, 125 insertions(+), 28 deletions(-) diff --git a/src/lib/lore.sh b/src/lib/lore.sh index a303b26e1..74da1d7c4 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -460,6 +460,55 @@ function pre_process_raw_xml() printf '%s\n ' "$xpath_output" } +# This function is used to process individual patches in parallel. As a worker +# it composes a string representing a processed entry of a patch, and stores it +# in a file inside the `@{shared_dir_for_parallelism}/`. A +# metadata file `@{shared_dir_for_parallelism}/-metadata` to store +# the message ID, version, and number in the series of the patch. +# +# @message_id: Patch message ID. +# @message_title: Subject of the message. +# @author_name: Name of the author of the message. +# @author_email: Email of the author of the message. +# @updated: Received time of message on Lore server. +# @in_reply_to: Value of field with possible In-Reply-To. +# @i: Index of patch to be processed. +# @shared_dir_for_parallelism: Path to directory where the parallel processing +# results will be stored. +function thread_for_process_individual_patch() +{ + local message_id="$1" + local message_title="$2" + local author_name="$3" + local author_email="$4" + local updated="$5" + local in_reply_to="$6" + local i="$7" + local shared_dir_for_parallelism="$8" + local version='' + local number_in_series='' + local total_in_series='' + local patch_metadata='' + local processed_patch='' + + patch_metadata=$(get_patch_metadata "$message_title") + version=$(get_patch_version "$patch_metadata") + number_in_series=$(get_patch_number_in_series "$patch_metadata") + total_in_series=$(get_patch_total_in_series "$patch_metadata") + message_title=$(remove_patch_metadata_from_message_title "$message_title" "$patch_metadata") + + processed_patch="${message_id}${SEPARATOR_CHAR}${message_title}${SEPARATOR_CHAR}" + processed_patch+="${author_name}${SEPARATOR_CHAR}${author_email}${SEPARATOR_CHAR}" + processed_patch+="${version}${SEPARATOR_CHAR}${number_in_series}${SEPARATOR_CHAR}" + processed_patch+="${total_in_series}${SEPARATOR_CHAR}${updated}${SEPARATOR_CHAR}" + if [[ "$in_reply_to" =~ ^href= ]]; then + processed_patch+=$(str_get_value_under_double_quotes "$in_reply_to") + fi + + printf '%s' "$processed_patch" > "${shared_dir_for_parallelism}/${i}" + printf '%s,%s,%s' "$message_id" "$version" "$number_in_series" > "${shared_dir_for_parallelism}/${i}-metadata" +} + # This function processes a list of individual patches from an Atom feed into an # indexed array that is passed as reference. All patches that are processed in # this function are marked in the `individual_patches_metadata` global hastable. @@ -473,49 +522,31 @@ function process_individual_patches() local raw_xml="$1" local -n _individual_patches="$2" local pre_processed_patches + local shared_dir_for_parallelism='' local message_id='' local message_title='' local author_name='' local author_email='' - local version='' - local number_in_series='' - local total_in_series='' - local updated='' - local in_reply_to='' - local patch_metadata='' local patch_attribute_number=0 local i=0 + local -a pids + local -a patch_metadata pre_processed_patches=$(pre_process_raw_xml "$raw_xml") + shared_dir_for_parallelism=$(create_shared_memory_dir) while IFS=$'\n' read -r line; do if [[ "$patch_attribute_number" == 5 ]]; then - patch_attribute_number=0 - - patch_metadata=$(get_patch_metadata "$message_title") - version=$(get_patch_version "$patch_metadata") - number_in_series=$(get_patch_number_in_series "$patch_metadata") - total_in_series=$(get_patch_total_in_series "$patch_metadata") - message_title=$(remove_patch_metadata_from_message_title "$message_title" "$patch_metadata") + thread_for_process_individual_patch "$message_id" "$message_title" "$author_name" \ + "$author_email" "$updated" "$line" "$i" "$shared_dir_for_parallelism" & + pids["$i"]="$!" - # Mark individual patch as processed and store metadata - individual_patches_metadata["$message_id"]="${version},${number_in_series}" - - _individual_patches["$i"]="${message_id}${SEPARATOR_CHAR}${message_title}${SEPARATOR_CHAR}" - _individual_patches["$i"]+="${author_name}${SEPARATOR_CHAR}${author_email}${SEPARATOR_CHAR}" - _individual_patches["$i"]+="${version}${SEPARATOR_CHAR}${number_in_series}${SEPARATOR_CHAR}" - _individual_patches["$i"]+="${total_in_series}${SEPARATOR_CHAR}${updated}${SEPARATOR_CHAR}" + patch_attribute_number=0 + ((i++)) # In case the patch has a 'In-Reply-To' field, `line` contains this value, # so process it and read next line of pre processed. - if [[ "$line" =~ ^href= ]]; then - in_reply_to=$(str_get_value_under_double_quotes "$line") - _individual_patches["$i"]+="$in_reply_to" - ((i++)) - continue - fi - - ((i++)) + [[ "$line" =~ ^href= ]] && continue fi case "$patch_attribute_number" in @@ -540,6 +571,19 @@ function process_individual_patches() ((patch_attribute_number++)) done <<< "$pre_processed_patches" + + # Wait for specific PID to avoid interfering in other functionalities. + for pid in "${pids[@]}"; do + wait "$pid" + done + + for j in $(seq 0 "$((i - 1))"); do + _individual_patches["$j"]=$(< "${shared_dir_for_parallelism}/${j}") + # Mark individual patch as processed and store metadata + patch_metadata=() + IFS=',' read -ra patch_metadata <<< "$(< "${shared_dir_for_parallelism}/${j}-metadata")" + individual_patches_metadata["${patch_metadata[0]}"]=$(printf '%s,%s' "${patch_metadata[1]}" "${patch_metadata[2]}") + done } # This function makes the lore request to get the raw contents of a lore diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index 7030bf95e..ca534a597 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -737,6 +737,59 @@ function test_pre_process_raw_xml() assert_equals_helper 'Wrong pre-processed result for sample 2' "$LINENO" "$expected" "$output" } +function test_thread_for_process_individual_patch() +{ + local shared_dir_path="${SHUNIT_TMPDIR}/shared_dir" + local message_id1='http://lore.kernel.org/foo/bar' + local message_title1='[PATCH] some/subsys: Fix bug' + local author_name1='Foo Bar' + local author_email1='foo@bar.com' + local updated1='2023/03/01 12:05' + local line1='next-patch' + local message_id2='http://lore.kernel.org/xpto/abc' + local message_title2='[v3 RFC PATCH 12/13] subsys/net: Revert previous patch' + local author_name2='Xpto Abc' + local author_email2='xpto@abc.jp' + local updated2='2023/12/01 12:30' + local line2='href="http://lore.kernel.org/abc/xpto"' + local expected + + mkdir "$shared_dir_path" + + thread_for_process_individual_patch "$message_id1" "$message_title1" "$author_name1" \ + "$author_email1" "$updated1" "$line1" 0 "$shared_dir_path" & + thread_for_process_individual_patch "$message_id2" "$message_title2" "$author_name2" \ + "$author_email2" "$updated2" "$line2" 1 "$shared_dir_path" + + [[ -f "${shared_dir_path}/0" ]] + # shellcheck disable=SC2319 + assert_equals_helper 'Did not generate entry for processed patch' "$LINENO" 0 "$?" + expected='http://lore.kernel.org/foo/barƆsome/subsys: Fix bugƆFoo BarƆfoo@bar.comƆ' + expected+='1Ɔ1Ɔ1Ɔ2023/03/01 12:05Ɔ' + assert_equals_helper 'Wrong processed patch' "$LINENO" "$expected" "$(< "${shared_dir_path}/0")" + + [[ -f "${shared_dir_path}/0-metadata" ]] + # shellcheck disable=SC2319 + assert_equals_helper 'Did not generate metadata entry for processed patch' "$LINENO" 0 "$?" + expected='http://lore.kernel.org/foo/bar,1,1' + assert_equals_helper 'Wrong processed patch metadata' "$LINENO" "$expected" "$(< "${shared_dir_path}/0-metadata")" + + [[ -f "${shared_dir_path}/1" ]] + # shellcheck disable=SC2319 + assert_equals_helper 'Did not generate entry for processed patch' "$LINENO" 0 "$?" + expected='http://lore.kernel.org/xpto/abcƆsubsys/net: Revert previous patchƆXpto AbcƆxpto@abc.jpƆ' + expected+='3Ɔ12Ɔ13Ɔ2023/12/01 12:30Ɔhttp://lore.kernel.org/abc/xpto' + assert_equals_helper 'Wrong processed patch' "$LINENO" "$expected" "$(< "${shared_dir_path}/1")" + + [[ -f "${shared_dir_path}/1-metadata" ]] + # shellcheck disable=SC2319 + assert_equals_helper 'Did not generate metadata entry for processed patch' "$LINENO" 0 "$?" + expected='http://lore.kernel.org/xpto/abc,3,12' + assert_equals_helper 'Wrong processed patch metadata' "$LINENO" "$expected" "$(< "${shared_dir_path}/1-metadata")" + + rm -rf "$shared_dir_path" +} + function test_process_individual_patches() { local -a individual_patches From 1d6a52ffb3ba977d1491bf54f755277dae814583 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Mon, 4 Mar 2024 13:02:38 -0300 Subject: [PATCH 066/128] src: lib: lore: Parallelize `process_representative_patches` The processing of patches for listing patchsets has two major stages after fetching the Atom feed with the patches and pre processing it. The second major stage consists in traversing the processed list of patches sequentially and determining if they are or not representative. This stage is represented by the `process_representative_patches`. As we can leverage parallel computing in this case, parallelize the function by issuing a dedicated thread for handling each patch. This takes care of much of the processing done in `process_representative_patches` resulting in a gain of performance, specially because it solves the problem of possible many chained network requests. Helps: #911 Signed-off-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/lib/lore.sh | 125 +++++++++++++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 45 deletions(-) diff --git a/src/lib/lore.sh b/src/lib/lore.sh index 74da1d7c4..1a18f03e9 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -610,6 +610,65 @@ function get_raw_lore_message() cmd_manager "$flag" "curl --silent '${raw_message_url}'" } +function thread_for_process_representative_patch() +{ + local patch="$1" + local i="$2" + local shared_dir_for_parallelism="$3" + local is_representative_patch + local message_id + local in_reply_to_message_id + local -a patch_metadata + local -a in_reply_to_metadata + local in_reply_to_title + local in_reply_to_patch_metadata + + unset patch_dict + declare -A patch_dict + + read_patch_into_dict "$patch" 'patch_dict' + + # Get patch and In-Reply-To message IDs + message_id="${patch_dict['message_id']}" + in_reply_to_message_id="${patch_dict['in_reply_to']}" + + is_representative_patch='' + + # Assume that patch number 0 is always the representative as the cover letter + if [[ "${patch_dict['number_in_series']}" == 0 ]]; then + is_representative_patch=1 + # Assume that, when there is no patch number 0, number 1 is the representative + # if it is a root of a thread + elif [[ "${patch_dict['number_in_series']}" == 1 && -z "$in_reply_to_message_id" ]]; then + is_representative_patch=1 + # Assume that, if 'In-Reply-To' is not patch number 0 from the same version, + # number 1 is the representative + elif [[ "${patch_dict['number_in_series']}" == 1 ]]; then + patch_metadata=() + in_reply_to_metadata=() + IFS=',' read -ra patch_metadata <<< "${individual_patches_metadata["$message_id"]}" + + if [[ -n "${individual_patches_metadata["$in_reply_to_message_id"]}" ]]; then + IFS=',' read -ra in_reply_to_metadata <<< "${individual_patches_metadata["$in_reply_to_message_id"]}" + else + in_reply_to_title=$(get_raw_lore_message "$message_id" | grep --perl-regexp '^Subject:' | sed 's/^Subject: //') + in_reply_to_patch_metadata=$(get_patch_metadata "$in_reply_to_title") + if [[ -n "$in_reply_to_patch_metadata" ]]; then + in_reply_to_metadata[0]=$(get_patch_version "$in_reply_to_patch_metadata") + in_reply_to_metadata[1]=$(get_patch_number_in_series "$in_reply_to_patch_metadata") + fi + fi + + if [[ "${patch_metadata[0]}" != "${in_reply_to_metadata[0]}" || "${in_reply_to_metadata[1]}" != 0 ]]; then + is_representative_patch=1 + fi + fi + + if [[ -n "$is_representative_patch" ]]; then + printf '%s' "$patch" > "${shared_dir_for_parallelism}/${i}" + fi +} + # This function processes representative patches (i.e. the first message in a # patchset) from a list of processed individual patches. The patches determined # as representatives are stored (in the same order as the argument @@ -624,60 +683,36 @@ function get_raw_lore_message() function process_representative_patches() { local -n _individual_patches_array="$1" - local is_representative_patch + local patch local message_id - local in_reply_to_message_id - local -a patch_metadata - local -a in_reply_to_metadata - local in_reply_to_title - local in_reply_to_patch_metadata + local shared_dir_for_parallelism + local -a pids + local i=0 - for patch in "${_individual_patches_array[@]}"; do - is_representative_patch='' - unset patch_dict - declare -A patch_dict + shared_dir_for_parallelism=$(create_shared_memory_dir) - read_patch_into_dict "$patch" 'patch_dict' + for patch in "${_individual_patches_array[@]}"; do + thread_for_process_representative_patch "$patch" "$i" "$shared_dir_for_parallelism" & + pids["$i"]="$!" + ((i++)) + done - # To avoid duplication, check if patch has been processed as representative - message_id="${patch_dict['message_id']}" - [[ -n "${processed_representative_patches["$message_id"]}" ]] && continue - in_reply_to_message_id="${patch_dict['in_reply_to']}" + # Wait for specific PID to avoid interfering in other functionalities. + for pid in "${pids[@]}"; do + wait "$pid" + done - # Assume that patch number 0 is always the representative as the cover letter - if [[ "${patch_dict['number_in_series']}" == 0 ]]; then - is_representative_patch=1 - # Assume that, when there is no patch number 0, number 1 is the representative - # if it is a root of a thread - elif [[ "${patch_dict['number_in_series']}" == 1 && -z "$in_reply_to_message_id" ]]; then - is_representative_patch=1 - # Assume that, if 'In-Reply-To' is not patch number 0 from the same version, - # number 1 is the representative - elif [[ "${patch_dict['number_in_series']}" == 1 ]]; then - patch_metadata=() - in_reply_to_metadata=() - IFS=',' read -ra patch_metadata <<< "${individual_patches_metadata["$message_id"]}" - - if [[ -n "${individual_patches_metadata["$in_reply_to_message_id"]}" ]]; then - IFS=',' read -ra in_reply_to_metadata <<< "${individual_patches_metadata["$in_reply_to_message_id"]}" - else - in_reply_to_title=$(get_raw_lore_message "$message_id" | grep --perl-regexp '^Subject:' | sed 's/^Subject: //') - in_reply_to_patch_metadata=$(get_patch_metadata "$in_reply_to_title") - if [[ -n "$in_reply_to_patch_metadata" ]]; then - in_reply_to_metadata[0]=$(get_patch_version "$in_reply_to_patch_metadata") - in_reply_to_metadata[1]=$(get_patch_number_in_series "$in_reply_to_patch_metadata") - fi - fi + for i in $(seq 0 "$((i - 1))"); do + if [[ -f "${shared_dir_for_parallelism}/${i}" ]]; then + patch=$(< "${shared_dir_for_parallelism}/${i}") + message_id=$(printf '%s' "$patch" | awk -F "$SEPARATOR_CHAR" '{print $1}') - if [[ "${patch_metadata[0]}" != "${in_reply_to_metadata[0]}" || "${in_reply_to_metadata[1]}" != 0 ]]; then - is_representative_patch=1 - fi - fi + # Avoid duplications + [[ -n "${processed_representative_patches["$message_id"]}" ]] && continue - if [[ -n "$is_representative_patch" ]]; then representative_patches["$REPRESENTATIVE_PATCHES_PROCESSED"]="$patch" ((REPRESENTATIVE_PATCHES_PROCESSED++)) - processed_representative_patches["${patch_dict['message_id']}"]=1 + processed_representative_patches["$message_id"]=1 fi done } From a0c59f732a6283b85d5d787d6c9037e29f977774 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Wed, 24 Jan 2024 19:45:23 -0300 Subject: [PATCH 067/128] src: lib: lore: Revise display of patchset information When viewing both latest patchsets from a mailing list and the bookmarked patchsets, the display of each item in the listing can be improved. First, the message title has no size limit and overflows the screen breaking the formatting of Dialog for long titles. Also, as the the received time in Lore servers of the patch and the author name are available, we can display these infos for the latest patchsets. In this context, make the display of the patchset message title limited to 60 chars, and display the received time and author name infos in the listing of latest patchsets from a given mailing list. Signed-off-by: David Tadokoro Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/lib/lore.sh | 12 ++++-------- tests/unit/lib/lore_test.sh | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/lib/lore.sh b/src/lib/lore.sh index 1a18f03e9..14bc93788 100644 --- a/src/lib/lore.sh +++ b/src/lib/lore.sh @@ -797,7 +797,7 @@ function fetch_latest_patchsets_from() # into an array reference passed as argument. The format of the metadata follows the # pattern: # -# V | # | +# V | # | | | # # @_formatted_patchsets_list: Array reference to output formatted range of patchsets metadata # @starting_index: Starting index of range from `representative_patches` @@ -812,7 +812,7 @@ function format_patchsets() for i in $(seq "$starting_index" "$ending_index"); do read_patch_into_dict "${representative_patches["$i"]}" 'patchset' _formatted_patchsets_list["$i"]=$(printf 'V%-2s |#%-3s| ' "${patchset['version']}" "${patchset['total_in_series']}") - _formatted_patchsets_list["$i"]+=$(printf ' %-100s' "${patchset['message_title']}") + _formatted_patchsets_list["$i"]+=$(printf '%-60.60s | %s | %-30.30s' "${patchset['message_title']}" "${patchset['updated']:0:-6}" "${patchset['author_name']}") done } @@ -1048,16 +1048,12 @@ function remove_series_from_bookmark_by_index() # # @_bookmarked_series: An array reference to be populated with all the bookmarked # series. -# -# TODO: -# - Better decide which information will be shown in the bookmarked patches screen function get_bookmarked_series() { local -n _bookmarked_series="$1" declare -A series local index=0 local timestamp - local tmp_data if [[ ! -f "${BOOKMARKED_SERIES_PATH}" ]]; then return 2 # ENOENT @@ -1067,8 +1063,8 @@ function get_bookmarked_series() while IFS='' read -r raw_patchset; do read_patch_into_dict "${raw_patchset}" 'series' - tmp_data=$(printf ' %s | %-70s | %s' "${series['timestamp']}" "${series['message_title']}" "${series['author_name']}") - _bookmarked_series["$index"]="${tmp_data}" + _bookmarked_series["$index"]=$(printf ' %s | %-60.60s ' "${series['timestamp']}" "${series['message_title']}") + _bookmarked_series["$index"]+=$(printf '| %s' "${series['author_name']}") ((index++)) done < "${BOOKMARKED_SERIES_PATH}" } diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index ca534a597..d72949475 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -530,11 +530,11 @@ function test_get_bookmarked_series() get_bookmarked_series bookmarked_series - expected=' DATE1 | TITLE1 | AUTHOR1' + expected=' DATE1 | TITLE1 | AUTHOR1' assertEquals "($LINENO)" "$expected" "${bookmarked_series[0]}" - expected=' DATE2 | TITLE2 | AUTHOR2' + expected=' DATE2 | TITLE2 | AUTHOR2' assertEquals "($LINENO)" "$expected" "${bookmarked_series[1]}" - expected=' DATE3 | TITLE3 | AUTHOR3' + expected=' DATE3 | TITLE3 | AUTHOR3' assertEquals "($LINENO)" "$expected" "${bookmarked_series[2]}" } @@ -1168,22 +1168,22 @@ function test_format_patchsets() local -a formatted_patchsets_list local output - representative_patches[0]='message-id0Ɔtitle0Ɔauthor0Ɔemail0Ɔ2Ɔ1Ɔ6Ɔupdated0Ɔin-reply-to0Ɔdir0Ɔtimestamp0' - representative_patches[1]='message-id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ1Ɔ0Ɔ3Ɔupdated1Ɔin-reply-to1Ɔdir1Ɔtimestamp1' - representative_patches[2]='message-id2Ɔtitle2Ɔauthor2Ɔemail2Ɔ16Ɔ1Ɔ8Ɔupdated2Ɔin-reply-to2Ɔdir2Ɔtimestamp2' - formatted_patchsets_list[0]='Vold |#old | titleold' + representative_patches[0]='message-id0Ɔtitle0Ɔauthor0Ɔemail0Ɔ2Ɔ1Ɔ6Ɔupdated0 11:34Ɔin-reply-to0Ɔdir0Ɔtimestamp0' + representative_patches[1]='message-id1Ɔtitle1Ɔauthor1Ɔemail1Ɔ1Ɔ0Ɔ3Ɔupdated1 12:23Ɔin-reply-to1Ɔdir1Ɔtimestamp1' + representative_patches[2]='message-id2Ɔtitle2Ɔauthor2Ɔemail2Ɔ16Ɔ1Ɔ8Ɔupdated2 21:50Ɔin-reply-to2Ɔdir2Ɔtimestamp2' + formatted_patchsets_list[0]='Vold |#old | titleold | updatedold | authorold' format_patchsets 'formatted_patchsets_list' 1 2 assert_equals_helper 'Wrong number of patchsets formatted' "$LINENO" 3 "${#formatted_patchsets_list[@]}" - expected='Vold |#old | titleold' + expected='Vold |#old | titleold | updatedold | authorold' assert_equals_helper 'Should not overwrite out-of-range entry' "$LINENO" "$expected" "${formatted_patchsets_list[0]}" - expected='V1 |#3 | title1' + expected='V1 |#3 | title1 | updated1 | author1' output=$(printf '%s' "${formatted_patchsets_list[1]}" | sed 's/ *$//') # trim trailing whitespace assert_equals_helper 'Wrong formatted patchset 1' "$LINENO" "$expected" "$output" - expected='V16 |#8 | title2' + expected='V16 |#8 | title2 | updated2 | author2' output=$(printf '%s' "${formatted_patchsets_list[2]}" | sed 's/ *$//') # trim trailing whitespace assert_equals_helper 'Wrong formatted patchset 2' "$LINENO" "$expected" "$output" } From 68a2b3a07078e94d46cc423feaf1a495f017543b Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Thu, 1 Feb 2024 09:58:08 -0700 Subject: [PATCH 068/128] src: remote: Improve ssh handling in case of failure As part of the kernel workflow, it is common for a developer to have multiple hard disks with different distros for checking the kernel behavior in those scenarios. When the developer swaps the disk but the IP is still the same for the target machine, it is expected to hit the remote host identification issue. This commit alleviates this problem by detecting and taking action based on this type of failure. Reviewed-by: David Tadokoro Signed-off-by: Rodrigo Siqueira Signed-off-by: David Tadokoro --- src/kw_ssh.sh | 9 +- src/lib/remote.sh | 188 +++++++++++++++++++++++++++++----- tests/unit/deploy_test.sh | 4 +- tests/unit/kw_ssh_test.sh | 6 +- tests/unit/lib/remote_test.sh | 43 ++++++++ 5 files changed, 214 insertions(+), 36 deletions(-) diff --git a/src/kw_ssh.sh b/src/kw_ssh.sh index c09e993b4..5d0591fb1 100644 --- a/src/kw_ssh.sh +++ b/src/kw_ssh.sh @@ -25,6 +25,7 @@ function kw_ssh_main() local remote_file_host local ssh_compose='ssh' local transfer_type='' + local ret parser_ssh_options "$@" if [[ "$?" -gt 0 ]]; then @@ -49,9 +50,11 @@ function kw_ssh_main() flag=${flag:-'SILENT'} is_ssh_connection_configured "$flag" - if [[ "$?" != 0 ]]; then - ssh_connection_failure_message - exit 101 # ENETUNREACH + ret="$?" + if [[ "$ret" != 0 ]]; then + [[ "$ret" == 125 ]] && return 125 # User canceled the operation + [[ "$ret" == 101 ]] && return 101 # Network is unreachable + [[ "$ret" != 0 ]] && ssh_connection_failure_message && return 101 # ENETUNREACH fi if [[ -n "$cmd" ]]; then diff --git a/src/lib/remote.sh b/src/lib/remote.sh index 027d6b477..83968dd32 100644 --- a/src/lib/remote.sh +++ b/src/lib/remote.sh @@ -15,6 +15,24 @@ REMOTE_KW_DEPLOY='/root/kw_deploy' declare -gA remote_parameters +# This function checks if connecting to the host machine via ssh is possible. +# It is helpful to invoke this function before performing any meaningful +# operation that depends on the ssh connection. +# +# @flag: How to display a command, the default value is +# 'SILENT'. For more options see `src/lib/kwlib.sh` function `cmd_manager` +# @remote: IP or domain name. +# @port: TCP Port. Default value is 22. +# @user: User in the host machine. Default value is "root" +# @remote_file: Path to the remote file +# @remote_file_host: Hostname in the ssh file +# +# Returns: +# In case of success, this function returns 0, otherwise, it can return: +# 2 - It did not find the remote_file +# 101 - Network is not reachable +# 125 - The operation was canceled +# 255 - Unknown error function is_ssh_connection_configured() { local flag=${1:-'SILENT'} @@ -23,7 +41,8 @@ function is_ssh_connection_configured() local user=${4:-${remote_parameters['REMOTE_USER']}} local remote_file=${5:-${remote_parameters[REMOTE_FILE]}} local remote_file_host=${5:-${remote_parameters[REMOTE_FILE_HOST]}} - local ssh_cmd='ssh -q -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5' + local ssh_cmd='ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5' + local ret if [[ -z "$remote" && -z "$port" && -z "$user" ]]; then if [[ -n "${remote_file}" ]]; then @@ -39,7 +58,138 @@ function is_ssh_connection_configured() ssh_cmd+=' exit' - cmd_manager "$flag" "$ssh_cmd" + output=$(cmd_manager "$flag" "$ssh_cmd" 2>&1) + if [[ "$?" == 255 ]]; then + ssh_error_handling "$output" + # The remove host identification issue + if [[ "$?" == 111 ]]; then + remove_key_from_kwown_hosts "$flag" "$ssh_cmd" + ret="$?" + + # User canceled the manual update + [[ "$ret" == 125 ]] && return 125 + # Some other unknown error occurred + [[ "$ret" != 0 ]] && return 101 # ENETUNREACH + + # Retry the ssh command + cmd_manager "$flag" "$ssh_cmd" + [[ "$?" != 0 ]] && return 101 # ENETUNREACH + return 0 + fi + + return 255 + fi + + [[ "$flag" == 'TEST_MODE' ]] && printf '%s\n' "$output" + + return 0 +} + +# This function is responsible for handling specific ssh errors. Unfortunately, +# when the SSH command fails, it always returns 255, which does not provide a +# fine-grained way to deal with particular issues. To workaround this +# limitation, this function parses the error message. +# +# @error_message: String with the error message from the ssh command +# +# Return: +# 0 - If does not find anything +# 111 - If remote host identification has changed +function ssh_error_handling() +{ + local error_message="$1" + local remote_host_change_message='.*WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED.*' + + # Case 1: Remote host identification change, return 111 + grep --line-regexp --quiet "$remote_host_change_message" <<< "$error_message" + if [[ "$?" == 0 ]]; then + return 111 # ECONNREFUSED + fi + + return 0 +} + +# Remove current host from the known_hosts file. +# +# @flag: How to display a command, the default value is +# "HIGHLIGHT_CMD". For more options see `src/lib/kwlib.sh` function `cmd_manager`. +# @ssh_cmd: The ssh command that failed to execute. +# +# Returns: +# 0 - If everything is ok +# 125 - if the user cancel the operation or the result code from ssh-keygen +# command. +function remove_key_from_kwown_hosts() +{ + local flag=${1:-'SILENT'} + local ssh_cmd="$2" + local remove_key_cmd='ssh-keygen -q -f' + + #shellcheck disable=SC2119 + extract_remote_info_from_config_file + + remove_key_cmd+=" '${HOME}/.ssh/known_hosts' -R '[${remote_parameters['REMOTE_IP']}]:${remote_parameters['REMOTE_PORT']}'" + + warning 'kw was not able to ssh into:' + warning " Host: ${remote_parameters['REMOTE_IP']}" + warning " Port: ${remote_parameters['REMOTE_PORT']}" + warning " User: ${remote_parameters['REMOTE_USER']}" + warning 'Due to a remote host identification issue.' + if [[ $(ask_yN 'Do you want kw to remove the current host from the known_hosts file?') =~ '0' ]]; then + say ' No problem, the operation has been canceled.' + say ' You can try to manually check the kw issue by using the below command:' + say " ${ssh_cmd}" + return 125 # ECANCELED + fi + + cmd_manager "$flag" "$remove_key_cmd" +} + +# This function converts part of the information in the ssh file into the +# remote_parameters array. +# +# @remote_file_host: Hostname in the ssh file +# @remote_file: Path to the remote file +function extract_remote_info_from_config_file() +{ + local remote_file_host=${1:-${remote_parameters['REMOTE_FILE_HOST']}} + local remote_file=${2:-${remote_parameters['REMOTE_FILE']}} + local trimmed_remote_file + local line_number + local remote + local line + local port + local user + + # Getting the line number of the target host + line_number=$(grep --line-number "^Host ${remote_file_host}\$" "$remote_file" | cut --delimiter=':' -f1) + ((line_number++)) + # Trimming remote file from target host line upward + trimmed_remote_file=$(tail --lines "+${line_number}" "${remote_file}") + # Getting the line number of next host from target host, if it exists + line_number=$(printf '%s' "$trimmed_remote_file" | grep --line-number --max-count=1 '^Host' | cut --delimiter=':' -f1) + # In case next host exists, trim remote file again from next host line downward + if [[ -n "$line_number" ]]; then + ((line_number--)) + trimmed_remote_file=$(printf '%s' "$trimmed_remote_file" | head --lines "$line_number") + fi + + # Here, we are matching lines with Hostname/Port/User occurrences that happen between the target + # host line and the next host line (if it exists) in the remote config file and only have leading + # spaces (excludes commented lines). We then cut the resulting string to get only the value of + # the Hostname/Port/User line. + line=$(printf '%s' "$trimmed_remote_file" | grep --max-count=1 '^[[:blank:]]*Hostname') + remote=$(printf '%s' "$line" | rev | cut --delimiter=' ' -f1 | rev) + + line=$(printf '%s' "$trimmed_remote_file" | grep --max-count=1 '^[[:blank:]]*Port') + port=$(printf '%s' "$line" | rev | cut --delimiter=' ' -f1 | rev) + + line=$(printf '%s' "$trimmed_remote_file" | grep --max-count=1 '^[[:blank:]]*User') + user=$(printf '%s' "$line" | rev | cut --delimiter=' ' -f1 | rev) + + remote_parameters['REMOTE_IP']="$remote" + remote_parameters['REMOTE_PORT']="$port" + remote_parameters['REMOTE_USER']="$user" } function ssh_connection_failure_message() @@ -57,29 +207,11 @@ function ssh_connection_failure_message() # and user from the config file. if [[ -z "$remote" && -z "$port" && -z "$user" ]]; then if [[ -n "${remote_parameters['REMOTE_FILE']}" ]]; then - # Getting the line number of the target host - line_number=$(grep --line-number "^Host ${remote_file_host}\$" "$remote_file" | cut --delimiter=':' -f1) - ((line_number++)) - # Trimming remote file from target host line upward - trimmed_remote_file=$(tail --lines "+${line_number}" "${remote_file}") - # Getting the line number of next host from target host, if it exists - line_number=$(printf '%s' "$trimmed_remote_file" | grep --line-number --max-count=1 '^Host' | cut --delimiter=':' -f1) - # In case next host exists, trim remote file again from next host line downward - if [[ -n "$line_number" ]]; then - ((line_number--)) - trimmed_remote_file=$(printf '%s' "$trimmed_remote_file" | head --lines "$line_number") - fi - - # Here, we are matching lines with Hostname/Port/User occurrences that happen between the target - # host line and the next host line (if it exists) in the remote config file and only have leading - # spaces (excludes commented lines). We then cut the resulting string to get only the value of - # the Hostname/Port/User line. - line=$(printf '%s' "$trimmed_remote_file" | grep --max-count=1 '^[[:blank:]]*Hostname') - remote=$(printf '%s' "$line" | rev | cut --delimiter=' ' -f1 | rev) - line=$(printf '%s' "$trimmed_remote_file" | grep --max-count=1 '^[[:blank:]]*Port') - port=$(printf '%s' "$line" | rev | cut --delimiter=' ' -f1 | rev) - line=$(printf '%s' "$trimmed_remote_file" | grep --max-count=1 '^[[:blank:]]*User') - user=$(printf '%s' "$line" | rev | cut --delimiter=' ' -f1 | rev) + #shellcheck disable=SC2119 + extract_remote_info_from_config_file + remote="${remote_parameters['REMOTE_IP']}" + user="${remote_parameters['REMOTE_USER']}" + port="${remote_parameters['REMOTE_PORT']}" else complain 'Could not find remote config file.' complain 'Suggestion: check if there is a remote.config or try using' @@ -89,9 +221,9 @@ function ssh_connection_failure_message() fi complain 'We could not reach the remote machine by using:' - complain " IP: $remote" - complain " User: $user" - complain " Port: $port" + complain " IP: ${remote}" + complain " User: ${user}" + complain " Port: ${port}" complain 'Please ensure that the above info is correct.' complain 'Suggestion: Check if your remote machine permits root login via ssh' complain 'or check if your public key is in the remote machine.' diff --git a/tests/unit/deploy_test.sh b/tests/unit/deploy_test.sh index 1864847eb..41c3e5a9e 100755 --- a/tests/unit/deploy_test.sh +++ b/tests/unit/deploy_test.sh @@ -219,9 +219,9 @@ function test_setup_remote_ssh_with_passwordless() '-> Trying to set up passwordless access' '' # Extra line due to \n in the say message 'ssh-copy-id root@127.0.0.1' - 'ssh -q -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5 -p 3333 root@127.0.0.1 exit' + 'ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5 -p 3333 root@127.0.0.1 exit' 'ssh-copy-id juca@127.0.0.1' - 'ssh -q -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5 -p 3333 juca@127.0.0.1 exit' + 'ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5 -p 3333 juca@127.0.0.1 exit' ) remote_parameters['REMOTE_USER']='juca' diff --git a/tests/unit/kw_ssh_test.sh b/tests/unit/kw_ssh_test.sh index bcd3d7469..f125689f2 100755 --- a/tests/unit/kw_ssh_test.sh +++ b/tests/unit/kw_ssh_test.sh @@ -92,7 +92,7 @@ function test_kw_ssh_main_no_parameter() local output declare -a expected_cmd=( - "ssh -q -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5 -F ${SHUNIT_TMPDIR}/.kw/remote.config origin exit" + "ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5 -F ${SHUNIT_TMPDIR}/.kw/remote.config origin exit" "ssh -F ${SHUNIT_TMPDIR}/.kw/remote.config origin" ) @@ -106,7 +106,7 @@ function test_kw_ssh_main_command() local output declare -a expected_cmd=( - "ssh -q -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5 -F ${SHUNIT_TMPDIR}/.kw/remote.config origin exit" + "ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5 -F ${SHUNIT_TMPDIR}/.kw/remote.config origin exit" "ssh -F ${SHUNIT_TMPDIR}/.kw/remote.config origin pwd" ) @@ -129,7 +129,7 @@ function test_kw_ssh_main_script() '[[ $ret =~ "$msg" ]]' declare -a expected_cmd=( - "ssh -q -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5 -F ${SHUNIT_TMPDIR}/.kw/remote.config origin exit" + "ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=5 -F ${SHUNIT_TMPDIR}/.kw/remote.config origin exit" "ssh -F ${SHUNIT_TMPDIR}/.kw/remote.config origin \"bash -s\" -- < $TEST_PATH/dmesg" ) diff --git a/tests/unit/lib/remote_test.sh b/tests/unit/lib/remote_test.sh index 4c7afc349..daead56e4 100755 --- a/tests/unit/lib/remote_test.sh +++ b/tests/unit/lib/remote_test.sh @@ -47,6 +47,7 @@ function oneTimeSetUp() export INVALID_ARG='Invalid arguments' export NO_SUCH_FILE='No such file' export SSH_OK='ssh -p 3333 127.0.0.1' + export HOME='/home/SOMETHING' rm -rf "$FAKE_KW" mk_fake_remote "$FAKE_KW" "$modules_path" @@ -458,6 +459,48 @@ function test_remote2host() assert_equals_helper 'Default user' "$LINENO" "$expected_cmd_str" "$output" } +function test_extract_remote_info_from_config_file() +{ + remote_parameters['REMOTE_FILE']="${TEST_PATH}/.kw/remote.config" + remote_parameters['REMOTE_FILE_HOST']='steamos' + + extract_remote_info_from_config_file + assert_equals_helper 'Remote did not match' "$LINENO" 'steamdeck' "${remote_parameters['REMOTE_IP']}" + assert_equals_helper 'Port did not match' "$LINENO" 8888 "${remote_parameters['REMOTE_PORT']}" + assert_equals_helper 'User did not match' "$LINENO" 'jozzi' "${remote_parameters['REMOTE_USER']}" +} + +function test_remove_key_from_kwown_hosts_by_user_request() +{ + local expected_cmd="ssh-keygen -q -f '${HOME}/.ssh/known_hosts' -R '[steamdeck]:8888'" + + remote_parameters['REMOTE_FILE']="${TEST_PATH}/.kw/remote.config" + remote_parameters['REMOTE_FILE_HOST']='steamos' + + output=$(remove_key_from_kwown_hosts 'TEST_MODE' 'something' <<< 'Y' | tail -1) + assert_equals_helper 'Remove identification command is wrong' "$LINENO" "$expected_cmd" "$output" +} + +function test_remove_key_from_kwown_hosts_by_user_request_cancel_operation() +{ + local output + + remote_parameters['REMOTE_FILE']="${TEST_PATH}/.kw/remote.config" + remote_parameters['REMOTE_FILE_HOST']='steamos' + + output=$(remove_key_from_kwown_hosts 'TEST_MODE' 'something' <<< 'N') + assert_equals_helper 'User canceled the operation' "$LINENO" 125 "$?" +} + +function test_ssh_error_handling() +{ + ssh_error_handling 'This is not a valid error' + assert_equals_helper 'This is not a valid error' "$LINENO" 0 "$?" + + ssh_error_handling 'WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED' + assert_equals_helper 'Remote host change' "$LINENO" 111 "$?" +} + function test_which_distro() { local cmd='cat /etc/os-release' From 15d40bdb4b9c48ebc38ca109c9070677747a9668 Mon Sep 17 00:00:00 2001 From: JGBSouza Date: Thu, 21 Mar 2024 11:03:48 -0300 Subject: [PATCH 069/128] src: lib: kw_db: Update database handling functions for WHERE clauses The original databases function had some limitations, as that the select function couldn't handle a where clause to select an specific data and the where clause used in the remove function could only handle equality comparassions. In this sense, add a function that generate where clause with multiple relational operations and update the `select_from` and `remove_from` functions to use this new implementation. Reviewed-by: David Tadokoro Signed-off-by: JGBSouza Signed-off-by: David Tadokoro --- src/kernel_config_manager.sh | 13 +- src/lib/kw_db.sh | 73 +++++-- src/pomodoro.sh | 12 +- src/report.sh | 2 +- tests/unit/kernel_config_manager_test.sh | 20 +- tests/unit/kw_db_test.sh | 248 ++++++++++++++++++----- tests/unit/samples/db_files/init.sql | 1 + 7 files changed, 285 insertions(+), 84 deletions(-) diff --git a/src/kernel_config_manager.sh b/src/kernel_config_manager.sh index cfa9a063f..d9e656a33 100644 --- a/src/kernel_config_manager.sh +++ b/src/kernel_config_manager.sh @@ -114,6 +114,7 @@ function save_config_file() local rows local cmd local ret + declare -A condition_array # Get env's kernel source tree if [[ -n "${options_values['ENV_PATH_KBUILD_OUTPUT_FLAG']}" ]]; then @@ -129,7 +130,8 @@ function save_config_file() [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' # Checks if there is already an entry for that kernel config file in the database - is_on_database="$(select_from "kernel_config WHERE name IS '${config_name}'" '' '' '' "$flag")" + condition_array=(['name']="${config_name}") + is_on_database="$(select_from 'kernel_config' '' '' 'condition_array' '' "$flag")" if [[ -n "${is_on_database}" && "$force" != 1 ]]; then warning "Kernel config file named '${config_name}' already exists." if [[ $(ask_yN "Do you want to overwrite it?") =~ '0' ]]; then @@ -521,7 +523,7 @@ function list_configs() [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' - configs="$(select_from 'kernel_config' 'name AS \"Name\", description AS \"Description\", last_updated_datetime AS \"Last updated\"' '.mode column' '' "$flag")" + configs="$(select_from 'kernel_config' 'name AS \"Name\", description AS \"Description\", last_updated_datetime AS \"Last updated\"' '.mode column' '' '' "$flag")" if [[ -z "$configs" ]]; then say 'There are no .config files managed by kw' @@ -554,6 +556,7 @@ function basic_config_validations() local flag="${5:-SILENT}" local query_output local -r kernel_configs_dir="${KW_DATA_DIR}/configs" + declare -A condition_array if [[ ! -f "${kernel_configs_dir}/${config_name}" ]]; then complain "Couldn't find config file named: ${config_name}" @@ -562,7 +565,9 @@ function basic_config_validations() [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' - query_output="$(select_from "kernel_config WHERE name IS '${config_name}'" '' '' '' "$flag")" + condition_array=(['name']="${config_name}") + query_output="$(select_from 'kernel_config' '' '' 'condition_array' '' "$flag")" + if [[ -z "${query_output}" ]]; then complain "Couldn't find config in database named: ${config_name}" # Ask user what to do with hanging local .config @@ -654,7 +659,7 @@ function remove_config() fi condition_array=(['name']="${config_name}") - remove_from '"kernel_config"' 'condition_array' '' '' "$flag" + remove_from 'kernel_config' 'condition_array' '' '' "$flag" say "The ${config_name} config file was removed from kw management" } diff --git a/src/lib/kw_db.sh b/src/lib/kw_db.sh index 1f04a68ba..2a287aa3a 100644 --- a/src/lib/kw_db.sh +++ b/src/lib/kw_db.sh @@ -155,7 +155,7 @@ function replace_into() function remove_from() { local table="$1" - local -n _condition_array="$2" + local _condition_array="$2" local db="${3:-"${DB_NAME}"}" local db_folder="${4:-"${KW_DATA_DIR}"}" local flag=${5:-'SILENT'} @@ -169,29 +169,28 @@ function remove_from() return 2 fi - if [[ -z "$table" || -z "${!_condition_array[*]}" ]]; then + if [[ -z "$table" || -z "$_condition_array" ]]; then complain 'Empty table or condition array.' return 22 # EINVAL fi - for column in "${!_condition_array[@]}"; do - where_clause+="$column='${_condition_array["${column}"]}'" - where_clause+=' AND ' - done - # Remove trailing ' AND ' - where_clause="${where_clause::-5}" + where_clause="$(generate_where_clause "$_condition_array")" + query="DELETE FROM ${table} ${where_clause} ;" - cmd="sqlite3 -init "${KW_DB_DIR}/pre_cmd.sql" \"${db_path}\" -batch \"DELETE FROM ${table} WHERE ${where_clause};\"" + cmd="sqlite3 -init "${KW_DB_DIR}/pre_cmd.sql" \"${db_path}\" -batch \"${query}\"" cmd_manager "$flag" "$cmd" } # This function gets the values in the table of given database +# with the given conditions. # -# @flag: Flag to control function output # @table: Table to select info from # @columns: Columns of the table to get # @pre_cmd: Pre command to execute +# @_condition_array: An array reference of condition pairs. In case there is no +# WHERE clause, an empty value must be passed # @order_by: List of attributes to use for ordering +# @flag: Flag to control function output # @db: Name of the database file # @db_folder: Path to the folder that contains @db # @@ -203,13 +202,14 @@ function select_from() local table="$1" local columns="${2:-"*"}" local pre_cmd="$3" - local order_by="$4" - local flag=${5:-'SILENT'} - local db="${6:-$DB_NAME}" - local db_folder="${7:-$KW_DATA_DIR}" + local _condition_array="$4" + local order_by=${5:-''} + local flag=${6:-'SILENT'} + local db="${7:-"$DB_NAME"}" + local db_folder="${8:-"$KW_DATA_DIR"}" + local where_clause local db_path local query - local cmd db_path="$(join_path "$db_folder" "$db")" @@ -223,15 +223,52 @@ function select_from() return 22 # EINVAL fi - query="SELECT $columns FROM $table ;" + if [[ -n "$_condition_array" ]]; then + where_clause="$(generate_where_clause "$_condition_array")" + fi + + query="SELECT ${columns} FROM ${table} ${where_clause} ;" + if [[ -n "${order_by}" ]]; then - query="SELECT $columns FROM $table ORDER BY ${order_by} ;" + query="${query::-2} ORDER BY ${order_by} ;" fi - cmd="sqlite3 -init ${KW_DB_DIR}/pre_cmd.sql -cmd \"${pre_cmd}\" \"${db_path}\" -batch \"${query}\"" + cmd="sqlite3 -init "${KW_DB_DIR}/pre_cmd.sql" -cmd \"${pre_cmd}\" \"${db_path}\" -batch \"${query}\"" cmd_manager "$flag" "$cmd" } +# This function receives a condition_array and then generate +# the infos that will be used by the WHERE clause to specify +# the data we want. +# +# @condition_array_ref: The condition array reference containing the conditions +# +# Returns: +# A string containing the generated clause +function generate_where_clause() +{ + local -n condition_array_ref="$1" + local clause + local relational_op='=' + local attribute + local where_clause="WHERE " + local value + + for clause in "${!condition_array_ref[@]}"; do + attribute="$(cut --delimiter=',' --fields=1 <<< "$clause")" + value="${condition_array_ref["${clause}"]}" + + if [[ "$clause" =~ "," ]]; then + relational_op=$(cut --delimiter=',' --fields=2 <<< "$clause") + fi + + where_clause+="${attribute}${relational_op}'${value}'" + where_clause+=' AND ' + done + + printf '%s' "${where_clause::-5}" # Remove trailing ' AND ' +} + # This function takes arguments and assembles them into the correct format to # be used as values in SQL commands. For example, if we want to format two sets # of three values - the first set being 'a1', 'a2', and 'a3' and the second being diff --git a/src/pomodoro.sh b/src/pomodoro.sh index 82cf854a4..419975e0b 100644 --- a/src/pomodoro.sh +++ b/src/pomodoro.sh @@ -81,7 +81,7 @@ function show_active_pomodoro_timebox() say "Started at: ${start_time} [${start_date}]" say '- Elapsed time:' "$(secs_to_arbitrarily_long_hours_mins_secs "${elapsed_time}")" say '- You still have' "$(secs_to_arbitrarily_long_hours_mins_secs "${remaining_time}")" - done <<< "$(select_from 'active_timebox' '"date","time","duration"' '' '' "$flag")" + done <<< "$(select_from 'active_timebox' '"date","time","duration"' '' '' '' "$flag")" } # Show registered tags with number identification. @@ -90,10 +90,12 @@ function show_tags() local flag=${1:-'SILENT'} local tags local cmd + declare -A condition_array [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' - tags=$(select_from 'tag WHERE "active" IS 1' '"id" AS "ID", "name" AS "Name"' '.mode column' 'id' "$flag") + condition_array=(['active']='1') + tags=$(select_from 'tag' '"id" AS "ID", "name" AS "Name"' '.mode column' 'condition_array' 'id' "$flag") if [[ -z "$tags" ]]; then say 'You did not register any tag yet' return 0 @@ -133,7 +135,7 @@ function is_tag_already_registered() [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' - is_tag_registered=$(select_from "tag WHERE name IS '${tag_name}'" '' '' '' "$flag") + is_tag_registered=$(select_from "tag WHERE name IS '${tag_name}'" '' '' '' '' "$flag") [[ -n "${is_tag_registered}" ]] && return 0 return 1 @@ -245,6 +247,7 @@ function get_tag_name() { local value="$1" local tag + declare -A condition_array # Basic check [[ -z "$value" ]] && return 22 # EINVAL @@ -254,7 +257,8 @@ function get_tag_name() return 0 fi - tag=$(select_from "tag WHERE id IS ${value}" 'name') + condition_array=(['id']="$value") + tag=$(select_from 'tag' 'name' '' 'condition_array') if [[ -z "$tag" ]]; then options_values['ERROR']="There is no tag with ID: ${value}" return 22 # EINVAL diff --git a/src/report.sh b/src/report.sh index 4906065df..9aef38c20 100644 --- a/src/report.sh +++ b/src/report.sh @@ -134,7 +134,7 @@ function get_raw_data_from_period_of_time() [[ "$flag" == 'VERBOSE' ]] && flag='CMD_SUBSTITUTION_VERBOSE' - raw_data=$(select_from "${table_name} WHERE date REGEXP ${regex_exp}" '' '' '' "$flag") + raw_data=$(select_from "${table_name} WHERE date REGEXP ${regex_exp}" '' '' '' '' "$flag") printf '%s' "$raw_data" } diff --git a/tests/unit/kernel_config_manager_test.sh b/tests/unit/kernel_config_manager_test.sh index 89f76fae5..ee5c3e800 100755 --- a/tests/unit/kernel_config_manager_test.sh +++ b/tests/unit/kernel_config_manager_test.sh @@ -125,15 +125,18 @@ function test_save_config_file_check_directories_creation() function test_save_config_file_check_saved_config() { local output + declare -A condition_array save_config_file "$NO_FORCE" "$NAME_1" "$DESCRIPTION_1" > /dev/null assertTrue "${LINENO}: Failed to find .config file for ${NAME_1}" '[[ -f ${dot_configs_dir}/${NAME_1} ]]' - output=$(select_from "kernel_config WHERE name IS '${NAME_1}'" 'name') + condition_array=(['name']="${NAME_1}") + output=$(select_from 'kernel_config' 'name' '' 'condition_array') assert_equals_helper "Failed to find db entry for ${NAME_1}" "$LINENO" "$NAME_1" "$output" save_config_file "$NO_FORCE" "$NAME_2" > /dev/null assertTrue "${LINENO}: Failed to find .config file for ${NAME_2}" '[[ -f ${dot_configs_dir}/${NAME_2} ]]' - output=$(select_from "kernel_config WHERE name IS '${NAME_2}'" 'name') + condition_array=(['name']="${NAME_2}") + output=$(select_from 'kernel_config' 'name' '' 'condition_array') assert_equals_helper "Failed to find db entry for ${NAME_2}" "$LINENO" "$NAME_2" "$output" output=$(cat "${dot_configs_dir}/${NAME_2}") @@ -143,13 +146,16 @@ function test_save_config_file_check_saved_config() function test_save_config_file_check_description() { local output + declare -A condition_array save_config_file "$NO_FORCE" "$NAME_1" "$DESCRIPTION_1" > /dev/null - output=$(select_from "kernel_config WHERE name IS '${NAME_1}'" 'description') + condition_array=(['name']="${NAME_1}") + output=$(select_from 'kernel_config' 'description' '' 'condition_array') assert_equals_helper "The description content for ${NAME_1} does not match" "$LINENO" "$DESCRIPTION_1" "$output" save_config_file "$NO_FORCE" "$NAME_2" "$DESCRIPTION_2" > /dev/null - output=$(select_from "kernel_config WHERE name IS '${NAME_2}'" 'description') + condition_array=(['name']="${NAME_2}") + output=$(select_from 'kernel_config' 'description' '' 'condition_array') assert_equals_helper "The description content for ${NAME_2} does not match" "$LINENO" "$DESCRIPTION_2" "$output" } @@ -286,21 +292,21 @@ function test_remove_config() # Case 1: We should have two files output=$(find "${dot_configs_dir}" -mindepth 1 -type f | wc -l) assert_equals_helper "We expected 2 files but got ${output}" "$LINENO" 2 "$output" - output=$(select_from 'kernel_config' 'count(*)') + output=$(select_from 'kernel_config' 'count(*)' '' '') assert_equals_helper "We expected 2 entries in the db but got ${output}" "$LINENO" 2 "$output" # Case 2: Remove one config file remove_config "$NAME_1" 1 > /dev/null 2>&1 output=$(find "${dot_configs_dir}" -mindepth 1 -type f | wc -l) assert_equals_helper "We expected 1 file but got ${output}" "$LINENO" 1 "$output" - output=$(select_from 'kernel_config' 'count(*)') + output=$(select_from 'kernel_config' 'count(*)' '' '') assert_equals_helper "We expected 1 entry in the db but got ${output}" "$LINENO" 1 "$output" # Case 3: Remove all config files remove_config "$NAME_2" 1 > /dev/null 2>&1 output=$(find "${dot_configs_dir}" -mindepth 1 -type f | wc -l) assert_equals_helper "We expected no files but got ${output}" "$LINENO" 0 "$output" - output=$(select_from 'kernel_config' 'count(*)') + output=$(select_from 'kernel_config' 'count(*)' '' '') assert_equals_helper "We expected no entry in the db but got ${output}" "$LINENO" 0 "$output" } diff --git a/tests/unit/kw_db_test.sh b/tests/unit/kw_db_test.sh index 20971795a..3362e1672 100755 --- a/tests/unit/kw_db_test.sh +++ b/tests/unit/kw_db_test.sh @@ -37,7 +37,7 @@ function test_execute_sql_script() ret="$?" expected="Creating database: $KW_DATA_DIR/kw.db" assert_equals_helper 'No errors expected' "$LINENO" "$ret" 0 - assert_equals_helper 'DB file does not exist, should warn' "$LINENO" "$output" "$expected" + assert_equals_helper 'DB file does not exist, should warn' "$LINENO" "$expected" "$output" assertTrue "($LINENO) DB file should be created" '[[ -f "$KW_DATA_DIR/kw.db" ]]' @@ -72,37 +72,37 @@ function test_format_values_db() ret="$?" expected='No arguments given' assert_equals_helper 'Invalid db, error expected' "$LINENO" "$ret" 22 - assert_equals_helper 'Expected error msg' "$LINENO" "$output" "$expected" + assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" output=$(format_values_db 3 'first' 'second' 'third') ret="$?" expected="('first','second','third')" assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" output=$(format_values_db 2 "some_func('lala xpto')" "somefunc2('lala xpto')") ret="$?" expected="(some_func('lala xpto'),somefunc2('lala xpto'))" assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" output=$(format_values_db 2 'first 1' 'second 1' 'first 2' 'second 2') ret="$?" expected="('first 1','second 1'),('first 2','second 2')" assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" output=$(format_values_db 1 "some 'quotes'") ret="$?" expected="('some ''quotes''')" assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" output=$(format_values_db 2 'first' 'NULL') ret="$?" expected="('first',NULL)" assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" } function test_execute_command_db() @@ -116,25 +116,25 @@ function test_execute_command_db() ret="$?" expected='Database does not exist' assert_equals_helper 'Invalid db, error expected.' "$LINENO" "$ret" 2 - assert_equals_helper 'Expected error msg.' "$LINENO" "$output" "$expected" + assert_equals_helper 'Expected error msg.' "$LINENO" "$expected" "$output" output=$(execute_command_db 'SELECT * FROM tags;') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT * FROM tags;') assert_equals_helper 'No error expected.' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output.' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output.' "$LINENO" "$expected" "$output" output=$(execute_command_db 'SELECT * FROM not_a_table;' 2>&1) ret="$?" expected='no such table: not_a_table' assert_equals_helper 'Invalid table.' "$LINENO" "$ret" 1 - assert_substring_match 'Wrong output.' "($LINENO)" "$output" "$expected" + assert_substring_match 'Wrong output.' "($LINENO)" "$expected" "$output" output=$(execute_command_db 'SELEC * FROM tags;' 2>&1) ret="$?" expected='near "SELEC": syntax error' assert_equals_helper 'Invalid table.' "$LINENO" "$ret" 1 - assert_substring_match 'Wrong output.' "($LINENO)" "$output" "$expected" + assert_substring_match 'Wrong output.' "($LINENO)" "$expected" "$output" entries="$(concatenate_with_commas name start_date)" @@ -142,7 +142,7 @@ function test_execute_command_db() ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT name,start_date FROM statistics;') assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Testing with concatenate_with_commas' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing with concatenate_with_commas' "$LINENO" "$expected" "$output" } function test_insert_into() @@ -158,19 +158,19 @@ function test_insert_into() ret="$?" expected='Database does not exist' assert_equals_helper 'Invalid db, error expected' "$LINENO" "$ret" 2 - assert_equals_helper 'Expected error msg' "$LINENO" "$output" "$expected" + assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" output=$(insert_into '' entries values) ret="$?" expected='Empty table or values.' assert_equals_helper 'Empty table, error expected' "$LINENO" "$ret" 22 - assert_equals_helper 'Expected error msg' "$LINENO" "$output" "$expected" + assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" output=$(insert_into table entries '') ret="$?" expected='Empty table or values.' assert_equals_helper 'Empty values, error expected' "$LINENO" "$ret" 22 - assert_equals_helper 'Expected error msg' "$LINENO" "$output" "$expected" + assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" # valid insert_into 'tags' '(tag)' "('new tag')" @@ -178,28 +178,28 @@ function test_insert_into() output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT tag FROM tags WHERE id = 5;') expected='new tag' assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" insert_into 'tags' '' "('6','other tag')" ret="$?" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT tag FROM tags WHERE id = 6;') expected='other tag' assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" insert_into 'tags' 'tag' "('yet another tag')" ret="$?" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT tag FROM tags WHERE id = 7;') expected='yet another tag' assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" insert_into 'pomodoro' '("tag_id","start_date","start_time","duration","description")' "(4,date('now'),time('now'),600,'some description')" ret="$?" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "description" FROM pomodoro WHERE "tag_id" = 4;') expected='some description' assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" entries=$(concatenate_with_commas '"tag_id"' '"start_date"' '"start_time"' '"duration"' '"description"') values=$(format_values_db 5 '5' "date('now')" "time('now','+10 minutes')" '650' 'some description 2') @@ -208,7 +208,7 @@ function test_insert_into() output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "description" FROM pomodoro WHERE "tag_id" = 5;') expected='some description 2' assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Testing with format functions' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing with format functions' "$LINENO" "$expected" "$output" entries=$(concatenate_with_commas id tag) values=$(format_values_db 2 8 'tag 8' 9 'tag 9') @@ -217,7 +217,7 @@ function test_insert_into() output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT tag FROM tags WHERE id >= 8;') expected=$'tag 8\ntag 9' assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Testing with format functions' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing with format functions' "$LINENO" "$expected" "$output" } function test_select_from() @@ -226,39 +226,84 @@ function test_select_from() local expected local ret local entries + declare -A condition_array # invalid - output=$(select_from table columns '' '' '' 'wrong/path/invalid_db.db') + output=$(select_from table columns '' '' '' '' 'wrong/path/invalid_db.db') ret="$?" expected='Database does not exist' assert_equals_helper 'Invalid db, error expected' "$LINENO" "$ret" 2 - assert_equals_helper 'Expected error msg' "$LINENO" "$output" "$expected" + assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" - output=$(select_from '' entries) + output=$(select_from '' "$entries" '' '') ret="$?" expected='Empty table.' assert_equals_helper 'Empty table, error expected' "$LINENO" "$ret" 22 - assert_equals_helper 'Expected error msg' "$LINENO" "$output" "$expected" + assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" # valid - output=$(select_from 'tags' 'tag') + output=$(select_from 'pomodoro' "$entries" '' '') ret="$?" - expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT tag FROM tags;') + expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT * FROM "pomodoro" ;') assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" - output=$(select_from 'tags') + entries=$(concatenate_with_commas '"start_date"' '"start_time"' '"description"') + condition_array=(['start_time']='2021-11-18') + output=$(select_from 'pomodoro' "$entries" '' 'condition_array') ret="$?" - expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT * FROM tags;') + expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time = '2021-11-18' ;') assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" - entries=$(concatenate_with_commas '"start_date"' '"start_time"' '"description"') - output=$(select_from 'pomodoro' "$entries") + condition_array=(['start_time,=']='2021-11-18') + output=$(select_from 'pomodoro' "$entries" '' 'condition_array') + ret="$?" + expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time = '2021-11-18' ;') + assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + condition_array=(['start_time,<']='2021-11-18') + output=$(select_from 'pomodoro' "$entries" '' 'condition_array') + ret="$?" + expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time < '2021-11-18' ;') + assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + condition_array=(['start_time,<=']='2021-11-18') + output=$(select_from 'pomodoro' "$entries" '' 'condition_array') + ret="$?" + expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time <= '2021-11-18' ;') + assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + condition_array=(['start_time,>']='2021-11-18') + output=$(select_from 'pomodoro' "$entries" '' 'condition_array') + ret="$?" + expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time > '2021-11-18' ;') + assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + condition_array=(['start_time,>=']='2021-11-18') + output=$(select_from 'pomodoro' "$entries" '' 'condition_array') + ret="$?" + expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time >= '2021-11-18' ;') + assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + condition_array=(['start_time,!=']='2021-11-18') + output=$(select_from 'pomodoro' "$entries" '' 'condition_array') ret="$?" - expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro";') + expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time != '2021-11-18' ;') assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + condition_array=(['start_time,<>']='2021-11-18') + output=$(select_from 'pomodoro' "$entries" '' 'condition_array') + ret="$?" + expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time <> '2021-11-18' ;') + assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" } test_replace_into() @@ -287,7 +332,7 @@ test_replace_into() assert_equals_helper 'Wrong error message' "$LINENO" "$expected" "$output" # valid operation with non-existent row - replace_into 'fake_table' '("name","attribute1","attribute2")' "('someName','someAtt1','someAtt2')" + replace_into 'fake_table' '("name","attribute1","attribute2","rank")' "('someName','someAtt1','someAtt2','2')" ret="$?" output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT 'f'.'name' FROM 'fake_table' AS 'f' WHERE 'f'.'name'='someName' ;") expected='someName' @@ -295,7 +340,7 @@ test_replace_into() assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" # valid operation with existent row - replace_into 'fake_table' '("name","attribute1","attribute2")' "('someName','anotherAtt1','anotherAtt2')" + replace_into 'fake_table' '("name","attribute1","attribute2","rank")' "('someName','anotherAtt1','anotherAtt2','2')" ret="$?" assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT count(*) FROM 'fake_table' AS 'f' WHERE 'f'.'name'='someName' ;") @@ -315,27 +360,27 @@ function test_remove_from() local ret # invalid operations - output=$(remove_from 'table' 'condition_array' 'wrong/path/invalid_db.db') + output=$(remove_from 'table' '' 'wrong/path/invalid_db.db') ret="$?" expected='Database does not exist' assert_equals_helper 'Invalid db, error expected' "$LINENO" 2 "$ret" assert_equals_helper 'Wrong error message' "$LINENO" "$expected" "$output" - output=$(remove_from '' 'condition_array') + output=$(remove_from '' '') ret="$?" expected='Empty table or condition array.' assert_equals_helper 'Empty table, error expected' "$LINENO" 22 "$ret" assert_equals_helper 'Wrong error message' "$LINENO" "$expected" "$output" - output=$(remove_from table 'condition_array') + output=$(remove_from table '') ret="$?" expected='Empty table or condition array.' assert_equals_helper 'Empty condition array expected' "$LINENO" 22 "$ret" assert_equals_helper 'Wrong error message' "$LINENO" "$expected" "$output" # remove one row using one unique attribute - columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2') - values=$(format_values_db 3 'name1' 'att1' 'att2') + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + values=$(format_values_db 4 'name1' 'att1' 'att2' '0') insert_into 'fake_table' "$columns" "$values" condition_array=(['name']='name1') remove_from 'fake_table' 'condition_array' @@ -344,8 +389,8 @@ function test_remove_from() assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" # remove one row using one unique attribute and some non-unique - columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2') - values=$(format_values_db 3 'name1' 'att1' 'att2') + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + values=$(format_values_db 4 'name1' 'att1' 'att2' '0') insert_into 'fake_table' "$columns" "$values" condition_array=(['name']='name1' ['attribute1']='att1' ['attribute2']='att2') remove_from 'fake_table' 'condition_array' @@ -354,8 +399,8 @@ function test_remove_from() assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" # remove one row using non-unique attributes - columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2') - values=$(format_values_db 3 'name1' 'att1' 'att2' 'name2' 'att1' 'ATT2') + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + values=$(format_values_db 4 'name1' 'att1' 'att2' '0' 'name2' 'att1' 'ATT2' '0') insert_into 'fake_table' "$columns" "$values" condition_array=(['attribute1']='att1' ['attribute2']='att2') remove_from 'fake_table' 'condition_array' @@ -367,15 +412,118 @@ function test_remove_from() assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" # remove two rows using non-unique attribute - columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2') - values=$(format_values_db 3 'name1' 'att1' 'att2') + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + values=$(format_values_db 4 'name1' 'att1' 'att2' '0') insert_into 'fake_table' "$columns" "$values" condition_array=(['attribute1']='att1') remove_from 'fake_table' 'condition_array' - output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT * FROM 'fake_table' WHERE attribute1='att1' ;") + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT name,attribute1,attribute2,rank FROM 'fake_table' WHERE attribute1='att1' ;") expected='' assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" - output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT * FROM 'fake_table' ;") + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT name,attribute1,attribute2,rank FROM 'fake_table' ;") + + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + values=$(format_values_db 4 \ + 'name1' 'att1.3' 'att2.3' '0' \ + 'name2' 'att1.3' 'att2.3' '1' \ + 'name3' 'att1.3' 'att2.3' '2') + insert_into 'fake_table' "$columns" "$values" + condition_array=(['rank,<']='1') + remove_from 'fake_table' 'condition_array' + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT name,attribute1,attribute2,rank FROM 'fake_table' WHERE attribute1='att1.3' ;") + expected=$'name2|att1.3|att2.3|1\n' + expected+='name3|att1.3|att2.3|2' + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + values=$(format_values_db 4 \ + 'name4' 'att1.4' 'att2.4' '0' \ + 'name5' 'att1.4' 'att2.4' '1' \ + 'name6' 'att1.4' 'att2.4' '2') + insert_into 'fake_table' "$columns" "$values" + condition_array=(['rank,>']='1') + remove_from 'fake_table' 'condition_array' + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT name,attribute1,attribute2,rank FROM 'fake_table' WHERE attribute1='att1.4' ;") + expected=$'name4|att1.4|att2.4|0\n' + expected+='name5|att1.4|att2.4|1' + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + values=$(format_values_db 4 \ + 'name7' 'att1.5' 'att2.5' '0' \ + 'name8' 'att1.5' 'att2.5' '1' \ + 'name9' 'att1.5' 'att2.5' '2') + insert_into 'fake_table' "$columns" "$values" + condition_array=(['rank,<=']='1') + remove_from 'fake_table' 'condition_array' + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT name,attribute1,attribute2,rank FROM 'fake_table' WHERE attribute1='att1.5' ;") + expected='name9|att1.5|att2.5|2' + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + values=$(format_values_db 4 \ + 'name10' 'att1.6' 'att2.6' '0' \ + 'name11' 'att1.6' 'att2.6' '1' \ + 'name12' 'att1.6' 'att2.6' '2') + insert_into 'fake_table' "$columns" "$values" + condition_array=(['rank,>=']='1') + remove_from 'fake_table' 'condition_array' + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT name,attribute1,attribute2,rank FROM 'fake_table' WHERE attribute1='att1.6' ;") + expected='name10|att1.6|att2.6|0' + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + values=$(format_values_db 4 \ + 'name13' 'att7.1' 'att7.2' '0' \ + 'name14' 'att7.1' 'att7.2' '1' \ + 'name15' 'att7.1' 'att7.2' '2') + insert_into 'fake_table' "$columns" "$values" + condition_array=(['rank,!=']='1') + remove_from 'fake_table' 'condition_array' + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT name,attribute1,attribute2,rank FROM 'fake_table' WHERE attribute1='att7.1' ;") + expected='name14|att7.1|att7.2|1' + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + values=$(format_values_db 4 \ + 'name16' 'att8.1' 'att8.2' '0' \ + 'name17' 'att8.1' 'att8.2' '1' \ + 'name18' 'att8.1' 'att8.2' '2') + insert_into 'fake_table' "$columns" "$values" + condition_array=(['rank,<>']='1') + remove_from 'fake_table' 'condition_array' + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT name,attribute1,attribute2,rank FROM 'fake_table' WHERE attribute1='att8.1' ;") + expected='name17|att8.1|att8.2|1' + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" +} + +function test_generate_where_clause() +{ + declare -A condition_array + local output + local expected + local ret + + condition_array=(['attribute']='value') + expected="WHERE attribute='value'" + output="$(generate_where_clause 'condition_array')" + ret="$?" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected no error' "$LINENO" 0 "$ret" + + condition_array=(['attribute,<']='value') + expected="WHERE attribute<'value'" + output="$(generate_where_clause 'condition_array')" + ret="$?" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected no error' "$LINENO" 0 "$ret" + + condition_array=(['attribute,<=']='value') + expected="WHERE attribute<='value'" + output="$(generate_where_clause 'condition_array')" + ret="$?" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected no error' "$LINENO" 0 "$ret" } invoke_shunit diff --git a/tests/unit/samples/db_files/init.sql b/tests/unit/samples/db_files/init.sql index 6a5f4ca59..13438ea3e 100644 --- a/tests/unit/samples/db_files/init.sql +++ b/tests/unit/samples/db_files/init.sql @@ -24,5 +24,6 @@ CREATE TABLE IF NOT EXISTS "fake_table" ( "name" TEXT NOT NULL UNIQUE, "attribute1" TEXT, "attribute2" TEXT, + "rank" INTEGER NOT NULL, PRIMARY KEY("id") ); From 3c11d233a373d7deefcd5ec5082d75c04c47bff3 Mon Sep 17 00:00:00 2001 From: JGBSouza Date: Thu, 4 Apr 2024 22:09:16 -0300 Subject: [PATCH 070/128] src: lib: kw_db: Add update_into function The database functions had no implementation for when we needed to update one or multiples attributes of an entry in the database without replacing it. In this case, add a new function update_into to make it possible. Reviewed-by: David Tadokoro Signed-off-by: JGBSouza Signed-off-by: David Tadokoro --- src/lib/kw_db.sh | 78 ++++++++++++++++++++++++++++++ tests/unit/kw_db_test.sh | 101 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) diff --git a/src/lib/kw_db.sh b/src/lib/kw_db.sh index 2a287aa3a..9624c99e8 100644 --- a/src/lib/kw_db.sh +++ b/src/lib/kw_db.sh @@ -237,6 +237,61 @@ function select_from() cmd_manager "$flag" "$cmd" } +# This function updates the set of values in the table of given database +# with the given conditions. +# +# @table: Table to select info from +# @_updates_array: An array reference of updates pairs that will be updated +# in the db +# @pre_cmd: Pre command to execute +# @_condition_array: An array reference of condition pairs specifing the data +# that will be updated +# @flag: Flag to control function output +# @db: Name of the database file +# @db_folder: Path to the folder that contains @db +# +# Return: +# 2 if db doesn't exist; 22 if table is empty +# 0 if succesful; non-zero otherwise +function update_into() +{ + local table="$1" + local _updates_array="$2" + local pre_cmd="$3" + local _condition_array="$4" + local flag=${5:-'SILENT'} + local db="${6:-"$DB_NAME"}" + local db_folder="${7:-"$KW_DATA_DIR"}" + local where_clause='' + local db_path + local query + + db_path="$(join_path "$db_folder" "$db")" + + if [[ ! -f "$db_path" ]]; then + complain 'Database does not exist' + return 2 + fi + + if [[ -z "$table" ]]; then + complain 'Empty table.' + return 22 # EINVAL + fi + + if [[ -z "$_condition_array" || -z "$_updates_array" ]]; then + complain 'Empty condition or updates array.' + return 22 #EINVAL + fi + + where_clause="$(generate_where_clause "$_condition_array")" + set_clause="$(generate_set_clause "$_updates_array")" + + query="UPDATE ${table} SET ${set_clause} ${where_clause} ;" + + cmd="sqlite3 -init "${KW_DB_DIR}/pre_cmd.sql" -cmd \"${pre_cmd}\" \"${db_path}\" -batch \"${query}\"" + cmd_manager "$flag" "$cmd" +} + # This function receives a condition_array and then generate # the infos that will be used by the WHERE clause to specify # the data we want. @@ -269,6 +324,29 @@ function generate_where_clause() printf '%s' "${where_clause::-5}" # Remove trailing ' AND ' } +# This function receives a updates_array and then generates the infos that +# will be used by the SET clause to update the data fields we want. +# +# @updates_array_ref: The updates array reference containing the conditions updates +# +# Returns: +# A string containing the generated clause +function generate_set_clause() +{ + local -n updates_array_ref="$1" + local attribute + local set_clause + local value + + for attribute in "${!updates_array_ref[@]}"; do + value="${updates_array_ref["${attribute}"]}" + set_clause+="${attribute} = '${value}'" + set_clause+=', ' + done + + printf '%s' "${set_clause::-2}" # Remove trailing ', ' +} + # This function takes arguments and assembles them into the correct format to # be used as values in SQL commands. For example, if we want to format two sets # of three values - the first set being 'a1', 'a2', and 'a3' and the second being diff --git a/tests/unit/kw_db_test.sh b/tests/unit/kw_db_test.sh index 3362e1672..096e54605 100755 --- a/tests/unit/kw_db_test.sh +++ b/tests/unit/kw_db_test.sh @@ -497,6 +497,85 @@ function test_remove_from() assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" } +function test_update_into() +{ + local columnns + local values + declare -A condition_array + declare -A updates_array + local output + local expected + local ret + + # invalid operations + output=$(update_into 'table' 'updates_array' '' '' '' 'wrong/path/invalid_db.db') + ret="$?" + expected='Database does not exist' + assert_equals_helper 'Invalid db, error expected' "$LINENO" 2 "$ret" + assert_equals_helper 'Wrong error message' "$LINENO" "$expected" "$output" + + output=$(update_into '' 'updates_array' '' '') + ret="$?" + expected='Empty table.' + assert_equals_helper 'Empty table, error expected' "$LINENO" 22 "$ret" + assert_equals_helper 'Wrong error message' "$LINENO" "$expected" "$output" + + output=$(update_into table 'update_array' '' '') + ret="$?" + expected='Empty condition or updates array.' + assert_equals_helper 'Empty condition array expected' "$LINENO" 22 "$ret" + assert_equals_helper 'Wrong error message' "$LINENO" "$expected" "$output" + + columns=$(concatenate_with_commas 'name' 'attribute1' 'attribute2' 'rank') + + values=$(format_values_db 4 \ + 'name19' 'att1' 'att2' '10' \ + 'name20' 'att1' 'att2' '11' \ + 'name21' 'att1' 'att2' '2' \ + 'name22' 'att1' 'att2' '2') + insert_into 'fake_table' "$columns" "$values" + + # update one row using one unique attribute + condition_array=(['name']='name19') + updates_array=(['attribute1']='att1.1') + update_into 'fake_table' 'updates_array' '' 'condition_array' + ret="$?" + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT attribute1 FROM 'fake_table' WHERE name='name19' ;") + expected='att1.1' + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected no error' "$LINENO" 0 "$ret" + + # update multiple rows using one unique attribute + condition_array=(['name']='name19') + updates_array=(['attribute1']='att1.2' ['attribute2']='att2.2' ['rank']='10') + update_into 'fake_table' 'updates_array' '' 'condition_array' + ret="$?" + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT attribute1, attribute2, rank FROM 'fake_table' WHERE name='name19' ;") + expected='att1.2|att2.2|10' + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected no error' "$LINENO" 0 "$ret" + + # update one row using non unique attribute + condition_array=(['rank']='2') + updates_array=(['attribute1']='att1.3') + update_into 'fake_table' 'updates_array' '' 'condition_array' + ret="$?" + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT attribute1 FROM 'fake_table' WHERE rank='2' ;") + expected=$'att1.3\natt1.3' + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected no error' "$LINENO" 0 "$ret" + + # update multiple rows using non unique attribute + condition_array=(['rank,>=']='10') + updates_array=(['attribute1']='att1.4' ['attribute2']='att2.4' ['rank']='3') + update_into 'fake_table' 'updates_array' '' 'condition_array' + ret="$?" + output=$(sqlite3 "${KW_DATA_DIR}/kw.db" -batch "SELECT name,attribute1,attribute2,rank FROM 'fake_table' WHERE rank='3' ;") + expected=$'name19|att1.4|att2.4|3\nname20|att1.4|att2.4|3' + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected no error' "$LINENO" 0 "$ret" +} + function test_generate_where_clause() { declare -A condition_array @@ -526,4 +605,26 @@ function test_generate_where_clause() assert_equals_helper 'Expected no error' "$LINENO" 0 "$ret" } +function test_generate_set_clause() +{ + declare -A condition_array + local output + local expected + local ret + + condition_array=(['attribute']='value') + expected="attribute = 'value'" + output="$(generate_set_clause 'condition_array')" + ret="$?" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected no error' "$LINENO" 0 "$ret" + + condition_array=(['attribute1']='value1' ['attribute2']='value2' ['attribute3']='value3') + expected="attribute1 = 'value1', attribute3 = 'value3', attribute2 = 'value2'" + output="$(generate_set_clause 'condition_array')" + ret="$?" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected no error' "$LINENO" 0 "$ret" +} + invoke_shunit From fbf753568d52760a77239874ee7089ef6a6b1677 Mon Sep 17 00:00:00 2001 From: OJarrisonn Date: Thu, 18 Apr 2024 10:55:10 -0300 Subject: [PATCH 071/128] kw: fix unneeded variable redefinition The variable `KW_SOUND_DIR` was being setted to `'/usr/share/sounds/kw'` twice Reviewed-by: Rodrigo Siqueira Co-authored-by: Lais Nuto Signed-off-by: OJarrisonn (Jorge Harrisonn) Signed-off-by: Rodrigo Siqueira --- kw | 1 - 1 file changed, 1 deletion(-) diff --git a/kw b/kw index 6c6e5bcbd..700cd9356 100755 --- a/kw +++ b/kw @@ -24,7 +24,6 @@ if [[ -f "$KW_SYSTEM_WIDE_INSTALLATION" ]]; then KW_LIB_DIR='/usr/share/kw' KW_SOUND_DIR='/usr/share/sounds/kw' KW_DOC_DIR='/usr/share/doc/kw/html/' - KW_SOUND_DIR='/usr/share/sounds/kw' KW_ETC_DIR='/etc/kw' else KW_LIB_DIR="${KW_LIB_DIR:-"${HOME}/.local/lib"}/${KWORKFLOW}" From 93ac913b3ff9ca0a7bc6ad8a9ff40127ac9d0a47 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Fri, 19 Apr 2024 13:39:09 -0600 Subject: [PATCH 072/128] tests: unit: lib: lore_test: Replace TEST-MODE with TEST_MODE The unit test test_get_raw_lore_message hangs because it needs an internet connection, which is not expected for a unit test. This error happened because of a typo in the unit test flag, which originally used TEST-MODE instead of TEST_MODE. This commit addresses this issue by using the correct flag. Reviewed-by: David Tadokoro Fixes: 9c4a5dd ("src: lib: lore: Handle patch not yet processed when electing representative") Signed-off-by: Rodrigo Siqueira Signed-off-by: David Tadokoro --- tests/unit/lib/lore_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index d72949475..bf0a70eeb 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -890,10 +890,10 @@ function test_get_raw_lore_message() local expected="curl --silent 'https://domain/list/message-id/raw'" local output - output=$(get_raw_lore_message 'http://domain/list/message-id/' 'TEST-MODE') + output=$(get_raw_lore_message 'http://domain/list/message-id/' 'TEST_MODE') assert_equals_helper 'Wrong command issued' "$LINENO" "$expected" "$output" - output=$(get_raw_lore_message 'http://domain/list/message-id' 'TEST-MODE') + output=$(get_raw_lore_message 'http://domain/list/message-id' 'TEST_MODE') assert_equals_helper 'Wrong command issued' "$LINENO" "$expected" "$output" } From fab60d3856b3443f0a984d16c88df624f08ba25e Mon Sep 17 00:00:00 2001 From: uwla Date: Fri, 26 Apr 2024 11:24:39 -0300 Subject: [PATCH 073/128] tests: run_tests: Refactor tests main script The test/run_tests.sh script is the entrypoint to both the unit tests and integration tests suites. In this sense, refactor this important file by: - Moving global variable declarations to top of the file - Replacing `if/elif/else` blocks with `case` statement - Extracting long blocks of code to their own functions Reviewed-by: David Tadokoro Signed-off-by: uwla Signed-off-by: David Tadokoro --- run_tests.sh | 113 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 35 deletions(-) diff --git a/run_tests.sh b/run_tests.sh index 9020398ce..7e32cf0a4 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -5,6 +5,11 @@ include './tests/unit/utils.sh' include './tests/integration/utils.sh' include './src/lib/kwio.sh' +declare -a TESTS +declare TESTS_DIR +declare TESTS_UNIT=1 +declare TESTS_INTEGRATION=1 + function show_help() { printf '%s\n' "Usage: $0 [--flags] [help] [list] [test ...]" \ @@ -141,7 +146,6 @@ function clear_integration_tests_cache() teardown_container_environment "$@" } -declare -a TESTS function set_tests() { local file @@ -151,53 +155,92 @@ function set_tests() done } -declare TESTS_UNIT=1 -declare TESTS_INTEGRATION=1 -declare TESTS_DIR=./tests -if [[ "$1" == '--unit' || "$1" == '-u' ]]; then - TESTS_DIR=./tests/unit - TESTS_INTEGRATION=0 - shift -elif [[ "$1" == '--integration' || "$1" == '-i' ]]; then - TESTS_DIR=./tests/integration - TESTS_UNIT=0 - shift -fi - -check_files="$?" -#shellcheck disable=SC2086 -if [[ "$#" -eq 0 ]]; then +function list_tests() +{ + local index + local files_list + + index=0 + files_list=$(find "$TESTS_DIR" -name '*_test.sh') + + # shellcheck disable=SC2086 + set_tests $files_list + + for test_name in "${TESTS[@]}"; do + ((index++)) + say "$index) ${test_name}" + done +} + +function run_all_tests() +{ + local files_list + files_list=$(find "$TESTS_DIR" -name '*_test.sh' | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') # Note: Usually we want to use double-quotes on bash variables, however, # in this case we want a set of parameters instead of a single one. + # shellcheck disable=SC2086 set_tests $files_list # Set the environment variable LANGUAGE to `en_US.UTF_8` to avoid the host # locale settings from interfering in the tests. LANGUAGE=en_US.UTF_8 run_tests -elif [[ "$1" == 'list' ]]; then - index=0 - files_list=$(find "$TESTS_DIR" -name '*_test.sh') - set_tests $files_list - for test_name in "${TESTS[@]}"; do - ((index++)) - say "$index) ${test_name}" - done -elif [[ "$1" == 'test' ]]; then +} + +function run_user_provided_tests() +{ + local regex + local files_list + # We use a regex to filter files so we test multiple tests matching a desirable # pattern. For example, we can run all config-related tests by providing the # word config. We can also run both config unit test and config integration # test with this approach. - regex="($(sed 's/ /|/g' <<< "${@:2}"))" - + regex="($(sed 's/ /|/g' <<< "${@}"))" files_list=$(find "$TESTS_DIR" | grep --perl-regexp "${regex}" | grep --extended-regexp --invert-match 'samples/.*|/shunit2/') + + # shellcheck disable=SC2086 set_tests $files_list + LANGUAGE=en_US.UTF_8 run_tests -elif [[ "$1" == 'clear-cache' ]]; then - shift - [[ "${TESTS_UNIT}" == 1 ]] && clear_unit_tests_cache "$@" - [[ "${TESTS_INTEGRATION}" == 1 ]] && clear_integration_tests_cache "$@" -else - show_help -fi +} + +# parse flag +case "$1" in + --unit | -u) + TESTS_DIR='./tests/unit' + TESTS_INTEGRATION=0 + shift + ;; + --integration | -i) + TESTS_DIR='./tests/integration' + TESTS_UNIT=0 + shift + ;; + *) + TESTS_DIR='./tests' + ;; +esac + +action=${1:-all} +shift + +case "$action" in + all) + run_all_tests + ;; + list) + list_tests + ;; + test) + run_user_provided_tests "$@" + ;; + clear-cache) + [[ "$TESTS_UNIT" -eq 1 ]] && clear_unit_tests_cache "$@" + [[ "$TESTS_INTEGRATION" -eq 1 ]] && clear_integration_tests_cache "$@" + ;; + *) + show_help + ;; +esac From d7c1304c3376043eccf9f17b635cafcdf494658c Mon Sep 17 00:00:00 2001 From: uwla Date: Fri, 26 Apr 2024 11:34:18 -0300 Subject: [PATCH 074/128] tests: integration: utils: Extract podman commands to functions The integration tests suite uses utility functions defined at tests/integration/utils.sh. These functions usually run explicit podman commands. So, to refactor this utility file, extract podman commands to functions. Reviewed-by: David Tadokoro Signed-off-by: uwla Signed-off-by: David Tadokoro --- tests/integration/utils.sh | 56 +++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/tests/integration/utils.sh b/tests/integration/utils.sh index 368e20f3a..ae0e8c989 100755 --- a/tests/integration/utils.sh +++ b/tests/integration/utils.sh @@ -32,7 +32,7 @@ function build_distro_image() local distro="$1" local file="${CONTAINER_DIR}/Containerfile_${distro}" - podman image build --file "$file" --tag "kw-${distro}" > /dev/null 2>&1 + image_build --file "$file" --tag "kw-${distro}" if [[ "$?" -ne 0 ]]; then fail "(${LINENO}): Error building the image for distribution ${distro}" @@ -57,7 +57,6 @@ function setup_container_environment() working_directory='/tmp/kw' for distro in "${DISTROS[@]}"; do - # container_img is the image name, while container_name is the name of the # container built from the image. container_img="kw-${distro}" @@ -86,7 +85,7 @@ function setup_container_environment() # If container exists, we tear it down and create a new one in order to # ensure KW installation reflects the latest local changes. - podman container exists "${container_name}" + container_exists "${container_name}" if [[ "$?" -eq 0 ]]; then teardown_single_container "${container_name}" fi @@ -129,7 +128,7 @@ function setup_container_environment() DISTROS=("${distros_ok[@]}") } -# Destroy all containers used in the tests +# Destroy all containers used in the tests. function teardown_containers() { local distro @@ -145,12 +144,12 @@ function teardown_containers() # Destroy a single container # -# @container Name or ID of the container +# @container Container name or id. function teardown_single_container() { local container="$1" - podman container exists "${container}" + container_exists "${container}" if [[ "$?" -eq 0 ]]; then # Destroy container sending SIGKILL instantly. @@ -328,7 +327,44 @@ function image_inspect() fi } -# run a container +# Build a container image. +# +# @args Arguments to be passed to podman. +function image_build() +{ + # shellcheck disable=SC2068 + podman image build $@ > /dev/null 2>&1 + + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to build the image." + fi +} + +# Check existence of given container. +# +# @container The container name or id. +function container_exists() +{ + podman container exists "$1" +} + +# Remove the given containers. +# +# @options Options to be passed to podman if any. +# @containers Container names or ids. +function container_rm() +{ + # shellcheck disable=SC2068 + podman container rm $@ > /dev/null 2>&1 + + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to remove containers." + fi +} + +# Run a container. +# +# @args Arguments to be passed to podman. function container_run() { # shellcheck disable=SC2068 @@ -364,7 +400,7 @@ function container_exec() fi } -# Copy files from the host to the container +# Copy files from the host to the container. # # @container The container to copy files to. # @src The file in the host. @@ -384,8 +420,8 @@ function container_copy() # Inspect the given containers. # -# @options Options to be passed to podman. -# @images Container names or ids. +# @options Options to be passed to podman. +# @containers Container names or ids. function container_inspect() { # shellcheck disable=SC2068 From 2c4d00bbc1fffdf8dd588c9a75b7807b5fbfdc6a Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Sun, 28 Apr 2024 13:59:14 -0300 Subject: [PATCH 075/128] tests: unit: lib: lore_test: Fix race condition in `test_thread_for_process_individual_patch` [What] In the test function `test_thread_for_process_individual_patch` there is a race condition in the subsequent lines thread_for_process_individual_patch [...] "$shared_dir_path" & thread_for_process_individual_patch [...] "$shared_dir_path" In the lines above, we launch two executions of `thread_for_process_individual_patch`, one in the background (the first one) and one to be executed in the main thread. The reasoning is that we are testing the parallel aspect of the function, so we launch two parallel threads of execution. The problem is that the main thread finishes the second execution of `thread_for_process_individual_patch` and starts making assertions on the first execution of the function. This means that if the first execution gets scheduled in a way that the main thread gets to the assertions first, the test will fail, making these test cases flaky. [How to reproduce race condition] To reproduce the case in which the test fails, change the first execution of `thread_for_process_individual_patch` to (sleep 5 && thread_for_process_individual_patch [...]) & run the specific tests with `./run_tests.sh --unit test lib/lore_test`, and see the fail. [The fix] Add a `wait` command to force the main thread to wait for the first execution to end before making assertions about it. Reviewed-by: Rodrigo Siqueira Signed-off-by: David Tadokoro Signed-off-by: Rodrigo Siqueira --- tests/unit/lib/lore_test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index bf0a70eeb..2d20f91c1 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -760,6 +760,7 @@ function test_thread_for_process_individual_patch() "$author_email1" "$updated1" "$line1" 0 "$shared_dir_path" & thread_for_process_individual_patch "$message_id2" "$message_title2" "$author_name2" \ "$author_email2" "$updated2" "$line2" 1 "$shared_dir_path" + wait [[ -f "${shared_dir_path}/0" ]] # shellcheck disable=SC2319 From 48cecf15485d2e7be176855754380d9303358daa Mon Sep 17 00:00:00 2001 From: auyer Date: Sat, 27 Apr 2024 17:13:38 -0300 Subject: [PATCH 076/128] tests: unit: fix reverse argument order of assert_equals_helper in docs and test cases The `assert_equals_helper` fuction definition has the arguments number 3 and number 4 defined as 'expected' and 'actual', repectively. This is the same for popular libraries, like golang testify/Assert. However the documentation stated the opposite order and there are missuses of the function in some test cases. Fixed most tests that used the different order: config_test, deploy_test, kw_db_test, kw_env_test and mail_test. Helps: #1091 Reviewed-by: David Tadokoro Signed-off-by: auyer Signed-off-by: David Tadokoro --- documentation/content/codingstyle.rst | 4 +- tests/unit/config_test.sh | 6 +- tests/unit/deploy_test.sh | 20 +-- tests/unit/kw_db_test.sh | 74 ++++----- tests/unit/kw_env_test.sh | 6 +- tests/unit/mail_test.sh | 222 +++++++++++++------------- 6 files changed, 166 insertions(+), 166 deletions(-) diff --git a/documentation/content/codingstyle.rst b/documentation/content/codingstyle.rst index a63180791..4240cb55b 100644 --- a/documentation/content/codingstyle.rst +++ b/documentation/content/codingstyle.rst @@ -244,11 +244,11 @@ a developer. We also encourage using the ``assert_equals_helper`` helper function, which provides a wrapper capable of spitting a useful error message in case the assertion fails. Ideally, one should do either:: - assert_equals_helper "$error_message" "($LINENO)" "$output" "$expected_output" + assert_equals_helper "$error_message" "($LINENO)" "$expected_output" "$output" or:: - assertEquals "($LINENO)" "$output" "$expected_output" + assertEquals "($LINENO)" "$expected_output" "$output" Help functions -------------- diff --git a/tests/unit/config_test.sh b/tests/unit/config_test.sh index ac6b62387..bc6250311 100755 --- a/tests/unit/config_test.sh +++ b/tests/unit/config_test.sh @@ -108,11 +108,11 @@ function test_set_config_value_changing_default_value() set_config_value 'use_llvm' 'lala' "${KW_CONFIG_BASE_PATH}/build.config" output=$(grep 'use_llvm' "${KW_CONFIG_BASE_PATH}/build.config") - assert_equals_helper 'Change llvm' "($LINENO)" "$output" 'use_llvm=lala' + assert_equals_helper 'Change llvm' "($LINENO)" 'use_llvm=lala' "$output" set_config_value 'menu_config' 'menuconfig' "${KW_CONFIG_BASE_PATH}/build.config" output=$(grep 'menu_config' "${KW_CONFIG_BASE_PATH}/build.config") - assert_equals_helper 'Change llvm' "($LINENO)" "$output" 'menu_config=menuconfig' + assert_equals_helper 'Change llvm' "($LINENO)" 'menu_config=menuconfig' "$output" } function test_set_config_value_with_dot_in_the_value() @@ -133,7 +133,7 @@ function test_set_config_with_a_path_as_value() set_config_value 'qemu_path_image' '/DATA/QEMU_VMS/virty.qcow2' "${KW_CONFIG_BASE_PATH}/vm.config" output=$(grep 'qemu_path_image' "${KW_CONFIG_BASE_PATH}/vm.config") - assert_equals_helper 'Change llvm' "($LINENO)" "$output" 'qemu_path_image=/DATA/QEMU_VMS/virty.qcow2' + assert_equals_helper 'Change llvm' "($LINENO)" 'qemu_path_image=/DATA/QEMU_VMS/virty.qcow2' "$output" } function test_set_config_with_verbose_mode() diff --git a/tests/unit/deploy_test.sh b/tests/unit/deploy_test.sh index 41c3e5a9e..bc726b629 100755 --- a/tests/unit/deploy_test.sh +++ b/tests/unit/deploy_test.sh @@ -730,8 +730,8 @@ function test_parse_deploy_options() declare -gA options_values parse_deploy_options --remote 'user@127.0.2.1:8888' assert_equals_helper 'Could not set deploy REMOTE_USER' "($LINENO)" 'user' "${remote_parameters['REMOTE_USER']}" - assert_equals_helper 'Could not set deploy REMOTE' "($LINENO)" "${remote_parameters['REMOTE_IP']}" '127.0.2.1' - assert_equals_helper 'Could not set deploy REMOTE_PORT' "($LINENO)" "${remote_parameters['REMOTE_PORT']}" '8888' + assert_equals_helper 'Could not set deploy REMOTE' "($LINENO)" '127.0.2.1' "${remote_parameters['REMOTE_IP']}" + assert_equals_helper 'Could not set deploy REMOTE_PORT' "($LINENO)" '8888' "${remote_parameters['REMOTE_PORT']}" unset options_values declare -gA options_values @@ -945,8 +945,8 @@ function test_collect_target_info_for_deploy() # LOCAL alias collect_deploy_info='collect_deploy_info_other_mock' collect_target_info_for_deploy 2 'TEST_MODE' - assert_equals_helper 'Check bootloader' "($LINENO)" "${target_deploy_info[bootloader]}" 'LILO' - assert_equals_helper 'Check distro' "($LINENO)" "${target_deploy_info[distro]}" 'fedora' + assert_equals_helper 'Check bootloader' "($LINENO)" 'LILO' "${target_deploy_info[bootloader]}" + assert_equals_helper 'Check distro' "($LINENO)" 'fedora' "${target_deploy_info[distro]}" # REMOTE function cmd_remotely() @@ -955,8 +955,8 @@ function test_collect_target_info_for_deploy() printf '[bootloader]=syslinux [distro]=chrome' } collect_target_info_for_deploy 3 'TEST_MODE' - assert_equals_helper 'Check bootloader' "($LINENO)" "${target_deploy_info[bootloader]}" 'syslinux' - assert_equals_helper 'Check distro' "($LINENO)" "${target_deploy_info[distro]}" 'chrome' + assert_equals_helper 'Check bootloader' "($LINENO)" 'syslinux' "${target_deploy_info[bootloader]}" + assert_equals_helper 'Check distro' "($LINENO)" 'chrome' "${target_deploy_info[distro]}" } function test_get_kernel_binary_name_outside_env() @@ -971,11 +971,11 @@ function test_get_kernel_binary_name_outside_env() build_config['arch']='arm64' output=$(get_kernel_binary_name) - assert_equals_helper 'Expected Image for ARM' "($LINENO)" "$output" 'Image' + assert_equals_helper 'Expected Image for ARM' "($LINENO)" 'Image' "$output" build_config['arch']='x86_64' output=$(get_kernel_binary_name) - assert_equals_helper 'Expected bzImage for x86' "($LINENO)" "$output" 'bzImage' + assert_equals_helper 'Expected bzImage for x86' "($LINENO)" 'bzImage' "$output" cd "$original" || { fail "($LINENO) It was not possible to move back from temp directory" @@ -991,11 +991,11 @@ function test_get_kernel_binary_name_inside_env() build_config['arch']='arm64' output=$(get_kernel_binary_name) - assert_equals_helper 'Expected Image for ARM' "($LINENO)" "$output" 'Image' + assert_equals_helper 'Expected Image for ARM' "($LINENO)" 'Image' "$output" build_config['arch']='x86_64' output=$(get_kernel_binary_name) - assert_equals_helper 'Expected bzImage for x86' "($LINENO)" "$output" 'bzImage' + assert_equals_helper 'Expected bzImage for x86' "($LINENO)" 'bzImage' "$output" } function test_get_kernel_binary_name_invalid_operation() diff --git a/tests/unit/kw_db_test.sh b/tests/unit/kw_db_test.sh index 096e54605..a941fa48c 100755 --- a/tests/unit/kw_db_test.sh +++ b/tests/unit/kw_db_test.sh @@ -31,12 +31,12 @@ function test_execute_sql_script() output=$(execute_sql_script 'wrong/path/invalid_script.sql') ret="$?" - assert_equals_helper 'Invalid script, error expected' "$LINENO" "$ret" 2 + assert_equals_helper 'Invalid script, error expected' "$LINENO" 2 "$ret" output=$(execute_sql_script "$DB_FILES/init.sql") ret="$?" expected="Creating database: $KW_DATA_DIR/kw.db" - assert_equals_helper 'No errors expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No errors expected' "$LINENO" 0 "$ret" assert_equals_helper 'DB file does not exist, should warn' "$LINENO" "$expected" "$output" assertTrue "($LINENO) DB file should be created" '[[ -f "$KW_DATA_DIR/kw.db" ]]' @@ -49,17 +49,17 @@ function test_execute_sql_script() execute_sql_script "$DB_FILES/insert.sql" ret="$?" - assert_equals_helper 'No errors expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No errors expected' "$LINENO" 0 "$ret" # counting the number rows in each table output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT count(id) FROM tags;') - assert_equals_helper 'Expected 4 tags' "$LINENO" "$output" 4 + assert_equals_helper 'Expected 4 tags' "$LINENO" 4 "$output" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT count(rowid) FROM pomodoro;') - assert_equals_helper 'Expected 5 pomodoro entries' "$LINENO" "$output" 5 + assert_equals_helper 'Expected 5 pomodoro entries' "$LINENO" 5 "$output" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT count(rowid) FROM statistics;') - assert_equals_helper 'Expected 4 statistic entries' "$LINENO" "$output" 4 + assert_equals_helper 'Expected 4 statistic entries' "$LINENO" 4 "$output" } function test_format_values_db() @@ -71,37 +71,37 @@ function test_format_values_db() output=$(format_values_db 0) ret="$?" expected='No arguments given' - assert_equals_helper 'Invalid db, error expected' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid db, error expected' "$LINENO" 22 "$ret" assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" output=$(format_values_db 3 'first' 'second' 'third') ret="$?" expected="('first','second','third')" - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" output=$(format_values_db 2 "some_func('lala xpto')" "somefunc2('lala xpto')") ret="$?" expected="(some_func('lala xpto'),somefunc2('lala xpto'))" - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" output=$(format_values_db 2 'first 1' 'second 1' 'first 2' 'second 2') ret="$?" expected="('first 1','second 1'),('first 2','second 2')" - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" output=$(format_values_db 1 "some 'quotes'") ret="$?" expected="('some ''quotes''')" - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" output=$(format_values_db 2 'first' 'NULL') ret="$?" expected="('first',NULL)" - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" } @@ -115,25 +115,25 @@ function test_execute_command_db() output=$(execute_command_db 'some cmd' 'wrong/path/invalid_db.db') ret="$?" expected='Database does not exist' - assert_equals_helper 'Invalid db, error expected.' "$LINENO" "$ret" 2 + assert_equals_helper 'Invalid db, error expected.' "$LINENO" 2 "$ret" assert_equals_helper 'Expected error msg.' "$LINENO" "$expected" "$output" output=$(execute_command_db 'SELECT * FROM tags;') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT * FROM tags;') - assert_equals_helper 'No error expected.' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected.' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output.' "$LINENO" "$expected" "$output" output=$(execute_command_db 'SELECT * FROM not_a_table;' 2>&1) ret="$?" expected='no such table: not_a_table' - assert_equals_helper 'Invalid table.' "$LINENO" "$ret" 1 + assert_equals_helper 'Invalid table.' "$LINENO" 1 "$ret" assert_substring_match 'Wrong output.' "($LINENO)" "$expected" "$output" output=$(execute_command_db 'SELEC * FROM tags;' 2>&1) ret="$?" expected='near "SELEC": syntax error' - assert_equals_helper 'Invalid table.' "$LINENO" "$ret" 1 + assert_equals_helper 'Invalid table.' "$LINENO" 1 "$ret" assert_substring_match 'Wrong output.' "($LINENO)" "$expected" "$output" entries="$(concatenate_with_commas name start_date)" @@ -141,7 +141,7 @@ function test_execute_command_db() output=$(execute_command_db "SELECT $entries FROM statistics;") ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT name,start_date FROM statistics;') - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Testing with concatenate_with_commas' "$LINENO" "$expected" "$output" } @@ -157,19 +157,19 @@ function test_insert_into() output=$(insert_into table entries values 'wrong/path/invalid_db.db') ret="$?" expected='Database does not exist' - assert_equals_helper 'Invalid db, error expected' "$LINENO" "$ret" 2 + assert_equals_helper 'Invalid db, error expected' "$LINENO" 2 "$ret" assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" output=$(insert_into '' entries values) ret="$?" expected='Empty table or values.' - assert_equals_helper 'Empty table, error expected' "$LINENO" "$ret" 22 + assert_equals_helper 'Empty table, error expected' "$LINENO" 22 "$ret" assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" output=$(insert_into table entries '') ret="$?" expected='Empty table or values.' - assert_equals_helper 'Empty values, error expected' "$LINENO" "$ret" 22 + assert_equals_helper 'Empty values, error expected' "$LINENO" 22 "$ret" assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" # valid @@ -177,28 +177,28 @@ function test_insert_into() ret="$?" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT tag FROM tags WHERE id = 5;') expected='new tag' - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" insert_into 'tags' '' "('6','other tag')" ret="$?" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT tag FROM tags WHERE id = 6;') expected='other tag' - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" insert_into 'tags' 'tag' "('yet another tag')" ret="$?" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT tag FROM tags WHERE id = 7;') expected='yet another tag' - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" insert_into 'pomodoro' '("tag_id","start_date","start_time","duration","description")' "(4,date('now'),time('now'),600,'some description')" ret="$?" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "description" FROM pomodoro WHERE "tag_id" = 4;') expected='some description' - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" entries=$(concatenate_with_commas '"tag_id"' '"start_date"' '"start_time"' '"duration"' '"description"') @@ -207,7 +207,7 @@ function test_insert_into() ret="$?" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "description" FROM pomodoro WHERE "tag_id" = 5;') expected='some description 2' - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Testing with format functions' "$LINENO" "$expected" "$output" entries=$(concatenate_with_commas id tag) @@ -216,7 +216,7 @@ function test_insert_into() ret="$?" output=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT tag FROM tags WHERE id >= 8;') expected=$'tag 8\ntag 9' - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Testing with format functions' "$LINENO" "$expected" "$output" } @@ -232,20 +232,20 @@ function test_select_from() output=$(select_from table columns '' '' '' '' 'wrong/path/invalid_db.db') ret="$?" expected='Database does not exist' - assert_equals_helper 'Invalid db, error expected' "$LINENO" "$ret" 2 + assert_equals_helper 'Invalid db, error expected' "$LINENO" 2 "$ret" assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" output=$(select_from '' "$entries" '' '') ret="$?" expected='Empty table.' - assert_equals_helper 'Empty table, error expected' "$LINENO" "$ret" 22 + assert_equals_helper 'Empty table, error expected' "$LINENO" 22 "$ret" assert_equals_helper 'Expected error msg' "$LINENO" "$expected" "$output" # valid output=$(select_from 'pomodoro' "$entries" '' '') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT * FROM "pomodoro" ;') - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" entries=$(concatenate_with_commas '"start_date"' '"start_time"' '"description"') @@ -253,56 +253,56 @@ function test_select_from() output=$(select_from 'pomodoro' "$entries" '' 'condition_array') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time = '2021-11-18' ;') - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" condition_array=(['start_time,=']='2021-11-18') output=$(select_from 'pomodoro' "$entries" '' 'condition_array') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time = '2021-11-18' ;') - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" condition_array=(['start_time,<']='2021-11-18') output=$(select_from 'pomodoro' "$entries" '' 'condition_array') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time < '2021-11-18' ;') - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" condition_array=(['start_time,<=']='2021-11-18') output=$(select_from 'pomodoro' "$entries" '' 'condition_array') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time <= '2021-11-18' ;') - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" condition_array=(['start_time,>']='2021-11-18') output=$(select_from 'pomodoro' "$entries" '' 'condition_array') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time > '2021-11-18' ;') - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" condition_array=(['start_time,>=']='2021-11-18') output=$(select_from 'pomodoro' "$entries" '' 'condition_array') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time >= '2021-11-18' ;') - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" condition_array=(['start_time,!=']='2021-11-18') output=$(select_from 'pomodoro' "$entries" '' 'condition_array') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time != '2021-11-18' ;') - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" condition_array=(['start_time,<>']='2021-11-18') output=$(select_from 'pomodoro' "$entries" '' 'condition_array') ret="$?" expected=$(sqlite3 "$KW_DATA_DIR/kw.db" -batch 'SELECT "start_date","start_time","description" FROM "pomodoro" WHERE start_time <> '2021-11-18' ;') - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" } diff --git a/tests/unit/kw_env_test.sh b/tests/unit/kw_env_test.sh index 8c3e9bcf8..f70d9e5e9 100755 --- a/tests/unit/kw_env_test.sh +++ b/tests/unit/kw_env_test.sh @@ -202,7 +202,7 @@ function test_validate_env_before_switch_invalid_case_with_config() # In this case we don't care about the user output for the test, for this # reason, move to dev/null validate_env_before_switch > /dev/null - assert_equals_helper 'It should not allow switch to a new env due to .config file.' "$LINENO" "$?" 22 + assert_equals_helper 'It should not allow switch to a new env due to .config file.' "$LINENO" 22 "$?" } function test_validate_env_before_switch_invalid_case_with_object_file() @@ -217,7 +217,7 @@ function test_validate_env_before_switch_invalid_case_with_object_file() # In this case we don't care about the user output for the test, for this # reason, move to dev/null validate_env_before_switch > /dev/null - assert_equals_helper 'It should not allow switch to a new env due to object files.' "$LINENO" "$?" 22 + assert_equals_helper 'It should not allow switch to a new env due to object files.' "$LINENO" 22 "$?" } function test_validate_env_before_switch_no_config_and_no_object_files() @@ -226,7 +226,7 @@ function test_validate_env_before_switch_no_config_and_no_object_files() mv '.config' 'config' validate_env_before_switch > /dev/null - assert_equals_helper 'It should allow switch to a new env.' "$LINENO" "$?" 0 + assert_equals_helper 'It should allow switch to a new env.' "$LINENO" 0 "$?" } function test_parse_env_options() diff --git a/tests/unit/mail_test.sh b/tests/unit/mail_test.sh index 5e115e551..d822ae1eb 100755 --- a/tests/unit/mail_test.sh +++ b/tests/unit/mail_test.sh @@ -61,32 +61,32 @@ function test_validate_encryption() # invalid values validate_encryption 'xpto' &> /dev/null ret="$?" - assert_equals_helper 'Expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Expected an error' "$LINENO" 22 "$ret" validate_encryption 'rsa' &> /dev/null ret="$?" - assert_equals_helper 'Expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Expected an error' "$LINENO" 22 "$ret" validate_encryption 'tlss' &> /dev/null ret="$?" - assert_equals_helper 'Expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Expected an error' "$LINENO" 22 "$ret" validate_encryption 'ssll' &> /dev/null ret="$?" - assert_equals_helper 'Expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Expected an error' "$LINENO" 22 "$ret" validate_encryption &> /dev/null ret="$?" - assert_equals_helper 'Expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Expected an error' "$LINENO" 22 "$ret" # valid values validate_encryption 'ssl' ret="$?" - assert_equals_helper 'Expected no error for ssl' "$LINENO" "$ret" 0 + assert_equals_helper 'Expected no error for ssl' "$LINENO" 0 "$ret" validate_encryption 'tls' ret="$?" - assert_equals_helper 'Expected no error for tls' "$LINENO" "$ret" 0 + assert_equals_helper 'Expected no error for tls' "$LINENO" 0 "$ret" } function test_validate_email() @@ -99,23 +99,23 @@ function test_validate_email() output="$(validate_email 'invalid email')" ret="$?" expected='Invalid email: invalid email' - assert_equals_helper 'Invalid email was passed' "$LINENO" "$output" "$expected" - assert_equals_helper 'Expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid email was passed' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected an error' "$LINENO" 22 "$ret" output="$(validate_email 'lalala')" ret="$?" expected='Invalid email: lalala' - assert_equals_helper 'Invalid email was passed' "$LINENO" "$output" "$expected" - assert_equals_helper 'Expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid email was passed' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected an error' "$LINENO" 22 "$ret" # valid values validate_email 'test@email.com' ret="$?" - assert_equals_helper 'Expected a success' "$LINENO" "$ret" 0 + assert_equals_helper 'Expected a success' "$LINENO" 0 "$ret" validate_email 'test123@serious.gov' ret="$?" - assert_equals_helper 'Expected a success' "$LINENO" "$ret" 0 + assert_equals_helper 'Expected a success' "$LINENO" 0 "$ret" } function test_find_commit_references() @@ -131,11 +131,11 @@ function test_find_commit_references() find_commit_references ret="$?" - assert_equals_helper 'No arguments given' "$LINENO" "$ret" 22 + assert_equals_helper 'No arguments given' "$LINENO" 22 "$ret" find_commit_references @^ ret="$?" - assert_equals_helper 'Outside git repo should return 125' "$LINENO" "$ret" 125 + assert_equals_helper 'Outside git repo should return 125' "$LINENO" 125 "$ret" cd "$FAKE_GIT" || { ret="$?" @@ -145,22 +145,22 @@ function test_find_commit_references() output="$(find_commit_references invalid_ref)" ret="$?" - assert_equals_helper 'Invalid ref should not work' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid ref should not work' "$LINENO" 22 "$ret" assertTrue "($LINENO) Invalid ref should be empty" '[[ -z "$output" ]]' output="$(find_commit_references '@^..@')" ret="$?" - assert_equals_helper '@^..@ should be a valid reference' "$LINENO" "$ret" 0 + assert_equals_helper '@^..@ should be a valid reference' "$LINENO" 0 "$ret" assertTrue "($LINENO) @^..@ should generate a reference" '[[ -n "$output" ]]' output="$(find_commit_references @)" ret="$?" - assert_equals_helper '@ should be a valid reference' "$LINENO" "$ret" 0 + assert_equals_helper '@ should be a valid reference' "$LINENO" 0 "$ret" assertTrue "($LINENO) @ should generate a reference" '[[ -n "$output" ]]' output="$(find_commit_references some args @ around)" ret="$?" - assert_equals_helper '@ should be a valid reference' "$LINENO" "$ret" 0 + assert_equals_helper '@ should be a valid reference' "$LINENO" 0 "$ret" assertTrue "($LINENO) @ should generate a reference" '[[ -n "$output" ]]' cd "$ORIGINAL_DIR" || { @@ -180,28 +180,28 @@ function test_validate_email_list() output="$(validate_email_list 'invalid email')" ret="$?" expected='The given recipient: invalid email does not contain a valid e-mail.' - assert_equals_helper 'Invalid email was passed' "$LINENO" "$output" "$expected" - assert_equals_helper 'Expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid email was passed' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected an error' "$LINENO" 22 "$ret" output="$(validate_email_list 'lalala')" ret="$?" expected='The given recipient: lalala does not contain a valid e-mail.' - assert_equals_helper 'Invalid email was passed' "$LINENO" "$output" "$expected" - assert_equals_helper 'Expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid email was passed' "$LINENO" "$expected" "$output" + assert_equals_helper 'Expected an error' "$LINENO" 22 "$ret" output="$(validate_email_list 'name1@lala.com,name2@lala.xpto,LastName, FirstName ,test123@serious.gov')" ret="$?" expected='The given recipient: LastName does not contain a valid e-mail.' - assert_equals_helper 'Expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Expected an error' "$LINENO" 22 "$ret" # valid values validate_email_list 'test@email.com' ret="$?" - assert_equals_helper 'Expected a success' "$LINENO" "$ret" 0 + assert_equals_helper 'Expected a success' "$LINENO" 0 "$ret" validate_email_list 'name1@lala.com,name2@lala.xpto,name3 second ,test123@serious.gov' ret="$?" - assert_equals_helper 'Expected a success' "$LINENO" "$ret" 0 + assert_equals_helper 'Expected a success' "$LINENO" 0 "$ret" } function test_reposition_commit_count_arg() @@ -211,19 +211,19 @@ function test_reposition_commit_count_arg() output="$(reposition_commit_count_arg --any --amount --of --args)" expected=' "--any" "--amount" "--of" "--args"' - assert_equals_helper 'Should not change arguments' "$LINENO" "$output" "$expected" + assert_equals_helper 'Should not change arguments' "$LINENO" "$expected" "$output" output="$(reposition_commit_count_arg --arg='some options, lala')" expected=' "--arg=some options, lala"' - assert_equals_helper 'Should correctly quote arguments' "$LINENO" "$output" "$expected" + assert_equals_helper 'Should correctly quote arguments' "$LINENO" "$expected" "$output" output="$(reposition_commit_count_arg -375)" expected=' -- -375' - assert_equals_helper 'Should place count argument at the end' "$LINENO" "$output" "$expected" + assert_equals_helper 'Should place count argument at the end' "$LINENO" "$expected" "$output" output="$(reposition_commit_count_arg --arg='some options, lala' -375)" expected=' "--arg=some options, lala" -- -375' - assert_equals_helper 'Should handle multiple arguments' "$LINENO" "$output" "$expected" + assert_equals_helper 'Should handle multiple arguments' "$LINENO" "$expected" "$output" } function test_remove_blocked_recipients() @@ -268,151 +268,151 @@ function test_mail_parser() # Invalid options parse_mail_options '-t' '--smtpuser' ret="$?" - assert_equals_helper 'Option without argument' "$LINENO" "$ret" 22 + assert_equals_helper 'Option without argument' "$LINENO" 22 "$ret" output=$(parse_mail_options '--name' 'Xpto') ret="$?" - assert_equals_helper 'Option without --setup' "$LINENO" "$ret" 95 + assert_equals_helper 'Option without --setup' "$LINENO" 95 "$ret" parse_mail_options '--smtpLalaXpto' 'lala xpto' ret="$?" - assert_equals_helper 'Invalid option passed' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid option passed' "$LINENO" 22 "$ret" parse_mail_options '--wrongOption' 'lala xpto' ret="$?" - assert_equals_helper 'Invalid option passed' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid option passed' "$LINENO" 22 "$ret" # valid options parse_mail_options some -- extra -1 args HEAD^ expected='some extra args HEAD^ -1' - assert_equals_helper 'Set passthrough options' "$LINENO" "${options_values['PASS_OPTION_TO_SEND_EMAIL']}" "$expected" - assert_equals_helper 'Set passthrough options' "$LINENO" "${options_values['COMMIT_RANGE']}" '-1 HEAD^' + assert_equals_helper 'Set passthrough options' "$LINENO" "$expected" "${options_values['PASS_OPTION_TO_SEND_EMAIL']}" + assert_equals_helper 'Set passthrough options' "$LINENO" '-1 HEAD^' "${options_values['COMMIT_RANGE']}" parse_mail_options -- --subject-prefix="PATCH i-g-t" HEAD^ expected="'--subject-prefix=PATCH i-g-t' HEAD^" - assert_equals_helper 'Set passthrough options with space' "$LINENO" "${options_values['PASS_OPTION_TO_SEND_EMAIL']}" "$expected" + assert_equals_helper 'Set passthrough options with space' "$LINENO" "$expected" "${options_values['PASS_OPTION_TO_SEND_EMAIL']}" parse_mail_options -375 expected='-375' - assert_equals_helper 'Set commit count option' "$LINENO" "${options_values['PASS_OPTION_TO_SEND_EMAIL']}" "$expected" - assert_equals_helper 'Set commit count option' "$LINENO" "${options_values['COMMIT_RANGE']}" "$expected " + assert_equals_helper 'Set commit count option' "$LINENO" "$expected" "${options_values['PASS_OPTION_TO_SEND_EMAIL']}" + assert_equals_helper 'Set commit count option' "$LINENO" "$expected " "${options_values['COMMIT_RANGE']}" parse_mail_options -v3 expected='-v3' - assert_equals_helper 'Set version option' "$LINENO" "${options_values['PATCH_VERSION']}" "$expected" + assert_equals_helper 'Set version option' "$LINENO" "$expected" "${options_values['PATCH_VERSION']}" expected='-v3 @^' - assert_equals_helper 'Set version option' "$LINENO" "${options_values['PASS_OPTION_TO_SEND_EMAIL']}" "$expected" - assert_equals_helper 'Set version option' "$LINENO" "${options_values['COMMIT_RANGE']}" '@^' + assert_equals_helper 'Set version option' "$LINENO" "$expected" "${options_values['PASS_OPTION_TO_SEND_EMAIL']}" + assert_equals_helper 'Set version option' "$LINENO" '@^' "${options_values['COMMIT_RANGE']}" parse_mail_options '--send' - assert_equals_helper 'Set send flag' "$LINENO" "${options_values['SEND']}" 1 + assert_equals_helper 'Set send flag' "$LINENO" 1 "${options_values['SEND']}" parse_mail_options '--verbose' - assert_equals_helper 'Set verbose option' "$LINENO" "${options_values['VERBOSE']}" 1 + assert_equals_helper 'Set verbose option' "$LINENO" 1 "${options_values['VERBOSE']}" parse_mail_options '--private' expected='--suppress-cc=all' - assert_equals_helper 'Set private flag' "$LINENO" "${options_values['PRIVATE']}" "$expected" + assert_equals_helper 'Set private flag' "$LINENO" "$expected" "${options_values['PRIVATE']}" parse_mail_options '--rfc' expected='--rfc' - assert_equals_helper 'Set rfc flag' "$LINENO" "${options_values['RFC']}" "$expected" + assert_equals_helper 'Set rfc flag' "$LINENO" "$expected" "${options_values['RFC']}" parse_mail_options '--to=some@mail.com' expected='some@mail.com' - assert_equals_helper 'Set to flag' "$LINENO" "${options_values['TO']}" "$expected" + assert_equals_helper 'Set to flag' "$LINENO" "$expected" "${options_values['TO']}" parse_mail_options '--cc=some@mail.com' expected='some@mail.com' - assert_equals_helper 'Set cc flag' "$LINENO" "${options_values['CC']}" "$expected" + assert_equals_helper 'Set cc flag' "$LINENO" "$expected" "${options_values['CC']}" parse_mail_options '--simulate' expected='--dry-run' - assert_equals_helper 'Set simulate flag' "$LINENO" "${options_values['SIMULATE']}" "$expected" + assert_equals_helper 'Set simulate flag' "$LINENO" "$expected" "${options_values['SIMULATE']}" parse_mail_options '--to=name1@lala.com,name2@lala.xpto,name3 second ' expected='name1@lala.com,name2@lala.xpto,name3 second ' - assert_equals_helper 'Set to flag' "$LINENO" "${options_values['TO']}" "$expected" + assert_equals_helper 'Set to flag' "$LINENO" "$expected" "${options_values['TO']}" parse_mail_options '--setup' expected=1 - assert_equals_helper 'Set setup flag' "$LINENO" "${options_values['SETUP']}" "$expected" + assert_equals_helper 'Set setup flag' "$LINENO" "$expected" "${options_values['SETUP']}" parse_mail_options '--force' expected=1 - assert_equals_helper 'Set force flag' "$LINENO" "${options_values['FORCE']}" "$expected" + assert_equals_helper 'Set force flag' "$LINENO" "$expected" "${options_values['FORCE']}" parse_mail_options '--verify' expected_result=1 - assert_equals_helper 'Set verify flag' "$LINENO" "${options_values['VERIFY']}" "$expected_result" + assert_equals_helper 'Set verify flag' "$LINENO" "$expected_result" "${options_values['VERIFY']}" parse_mail_options '--template' expected_result=':' - assert_equals_helper 'Template without options' "$LINENO" "${options_values['TEMPLATE']}" "$expected_result" + assert_equals_helper 'Template without options' "$LINENO" "$expected_result" "${options_values['TEMPLATE']}" parse_mail_options '--template=test' expected_result=':test' - assert_equals_helper 'Set template flag' "$LINENO" "${options_values['TEMPLATE']}" "$expected_result" + assert_equals_helper 'Set template flag' "$LINENO" "$expected_result" "${options_values['TEMPLATE']}" parse_mail_options '--template= Test ' expected_result=':test' - assert_equals_helper 'Set template flag, case and spaces' "$LINENO" "${options_values['TEMPLATE']}" "$expected_result" + assert_equals_helper 'Set template flag, case and spaces' "$LINENO" "$expected_result" "${options_values['TEMPLATE']}" parse_mail_options '--interactive' expected_result='parser' - assert_equals_helper 'Set interactive flag' "$LINENO" "${options_values['INTERACTIVE']}" "$expected_result" + assert_equals_helper 'Set interactive flag' "$LINENO" "$expected_result" "${options_values['INTERACTIVE']}" parse_mail_options '--no-interactive' expected_result=1 - assert_equals_helper 'Set no-interactive flag' "$LINENO" "${options_values['NO_INTERACTIVE']}" "$expected_result" + assert_equals_helper 'Set no-interactive flag' "$LINENO" "$expected_result" "${options_values['NO_INTERACTIVE']}" expected='' - assert_equals_helper 'Unset local or global flag' "$LINENO" "${options_values['CMD_SCOPE']}" "$expected" + assert_equals_helper 'Unset local or global flag' "$LINENO" "$expected" "${options_values['CMD_SCOPE']}" expected='local' - assert_equals_helper 'Unset local or global flag' "$LINENO" "${options_values['SCOPE']}" "$expected" + assert_equals_helper 'Unset local or global flag' "$LINENO" "$expected" "${options_values['SCOPE']}" parse_mail_options '--local' - assert_equals_helper 'Set local flag' "$LINENO" "${options_values['SCOPE']}" "$expected" - assert_equals_helper 'Set local flag' "$LINENO" "${options_values['CMD_SCOPE']}" "$expected" + assert_equals_helper 'Set local flag' "$LINENO" "$expected" "${options_values['SCOPE']}" + assert_equals_helper 'Set local flag' "$LINENO" "$expected" "${options_values['CMD_SCOPE']}" parse_mail_options '--global' expected='global' - assert_equals_helper 'Set global flag' "$LINENO" "${options_values['SCOPE']}" "$expected" - assert_equals_helper 'Set global flag' "$LINENO" "${options_values['CMD_SCOPE']}" "$expected" + assert_equals_helper 'Set global flag' "$LINENO" "$expected" "${options_values['SCOPE']}" + assert_equals_helper 'Set global flag' "$LINENO" "$expected" "${options_values['CMD_SCOPE']}" parse_mail_options '-t' '--name' 'Xpto Lala' expected='Xpto Lala' - assert_equals_helper 'Set name' "$LINENO" "${options_values['user.name']}" "$expected" + assert_equals_helper 'Set name' "$LINENO" "$expected" "${options_values['user.name']}" parse_mail_options '-t' '--email' 'test@email.com' expected='test@email.com' - assert_equals_helper 'Set email' "$LINENO" "${options_values['user.email']}" "$expected" + assert_equals_helper 'Set email' "$LINENO" "$expected" "${options_values['user.email']}" parse_mail_options '-t' '--smtpuser' 'test@email.com' expected='test@email.com' - assert_equals_helper 'Set smtp user' "$LINENO" "${options_values['sendemail.smtpuser']}" "$expected" + assert_equals_helper 'Set smtp user' "$LINENO" "$expected" "${options_values['sendemail.smtpuser']}" parse_mail_options '-t' '--smtpencryption' 'tls' expected='tls' - assert_equals_helper 'Set smtp encryption to tls' "$LINENO" "${options_values['sendemail.smtpencryption']}" "$expected" + assert_equals_helper 'Set smtp encryption to tls' "$LINENO" "$expected" "${options_values['sendemail.smtpencryption']}" parse_mail_options '-t' '--smtpencryption' 'ssl' expected='ssl' - assert_equals_helper 'Set smtp encryption to ssl' "$LINENO" "${options_values['sendemail.smtpencryption']}" "$expected" + assert_equals_helper 'Set smtp encryption to ssl' "$LINENO" "$expected" "${options_values['sendemail.smtpencryption']}" parse_mail_options '-t' '--smtpserver' 'test.email.com' expected='test.email.com' - assert_equals_helper 'Set smtp server' "$LINENO" "${options_values['sendemail.smtpserver']}" "$expected" + assert_equals_helper 'Set smtp server' "$LINENO" "$expected" "${options_values['sendemail.smtpserver']}" parse_mail_options '-t' '--smtpserverport' '123' expected='123' - assert_equals_helper 'Set smtp serverport' "$LINENO" "${options_values['sendemail.smtpserverport']}" "$expected" + assert_equals_helper 'Set smtp serverport' "$LINENO" "$expected" "${options_values['sendemail.smtpserverport']}" parse_mail_options '-t' '--smtppass' 'verySafePass' expected='verySafePass' - assert_equals_helper 'Set smtp pass' "$LINENO" "${options_values['sendemail.smtppass']}" "$expected" + assert_equals_helper 'Set smtp pass' "$LINENO" "$expected" "${options_values['sendemail.smtppass']}" cd "$ORIGINAL_DIR" || { ret="$?" @@ -438,75 +438,75 @@ function test_mail_send() output=$(mail_send 'TEST_MODE') expected='git send-email @^' - assert_equals_helper 'Testing send without options' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing send without options' "$LINENO" "$expected" "$output" parse_mail_options '--to=mail@test.com' output=$(mail_send 'TEST_MODE') expected='git send-email --to="mail@test.com" @^' - assert_equals_helper 'Testing send with to option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing send with to option' "$LINENO" "$expected" "$output" parse_mail_options '--to=name1@lala.com,name2@lala.xpto,name3 second ,test123@serious.gov' output=$(mail_send 'TEST_MODE') expected='git send-email --to="name1@lala.com,name2@lala.xpto,name3 second ,test123@serious.gov" @^' - assert_equals_helper 'Testing send with to option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing send with to option' "$LINENO" "$expected" "$output" parse_mail_options '--cc=mail@test.com' output=$(mail_send 'TEST_MODE') expected='git send-email --cc="mail@test.com" @^' - assert_equals_helper 'Testing send with c option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing send with c option' "$LINENO" "$expected" "$output" parse_mail_options '--cc=name1@lala.com,name2@lala.xpto,name3 second ,test123@serious.gov' output=$(mail_send 'TEST_MODE') expected='git send-email --cc="name1@lala.com,name2@lala.xpto,name3 second ,test123@serious.gov" @^' - assert_equals_helper 'Testing send with cc option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing send with cc option' "$LINENO" "$expected" "$output" parse_mail_options '--simulate' output=$(mail_send 'TEST_MODE') expected='git send-email --dry-run @^' - assert_equals_helper 'Testing send with simulate option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing send with simulate option' "$LINENO" "$expected" "$output" parse_mail_options '--private' output=$(mail_send 'TEST_MODE') expected="git send-email --suppress-cc=all @^" - assert_equals_helper 'Testing send with to option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing send with to option' "$LINENO" "$expected" "$output" parse_mail_options '--rfc' output=$(mail_send 'TEST_MODE') expected="git send-email --rfc @^" - assert_equals_helper 'Testing send with rfc option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing send with rfc option' "$LINENO" "$expected" "$output" parse_mail_options '--to=mail@test.com' 'HEAD~' output=$(mail_send 'TEST_MODE') expected='git send-email --to="mail@test.com" HEAD~' - assert_equals_helper 'Testing send with patch option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing send with patch option' "$LINENO" "$expected" "$output" parse_mail_options '--to=mail@test.com' -13 -v2 extra_args -- --other_arg output=$(mail_send 'TEST_MODE') expected='git send-email --to="mail@test.com" extra_args --other_arg -13 -v2' - assert_equals_helper 'Testing no options option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing no options option' "$LINENO" "$expected" "$output" parse_mail_options '--to=mail@test.com' parse_configuration "$KW_MAIL_CONFIG_SAMPLE" mail_config output=$(mail_send 'TEST_MODE') expected='git send-email --to="mail@test.com" --annotate --no-chain-reply-to --thread @^' - assert_equals_helper 'Testing default option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing default option' "$LINENO" "$expected" "$output" parse_mail_options '--to=mail@test.com' '@^^' parse_configuration "$KW_CONFIG_SAMPLE" output=$(mail_send 'TEST_MODE') expected='git send-email --to="mail@test.com" --annotate --cover-letter --no-chain-reply-to --thread @^^' - assert_equals_helper 'Testing default option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing default option' "$LINENO" "$expected" "$output" cd "$ORIGINAL_DIR" || { ret="$?" @@ -536,19 +536,19 @@ function test_get_configs() output=${set_confs['local_user.name']} expected='Xpto Lala' - assert_equals_helper 'Checking local name' "$LINENO" "$output" "$expected" + assert_equals_helper 'Checking local name' "$LINENO" "$expected" "$output" output=${set_confs['local_user.email']} expected='test@email.com' - assert_equals_helper 'Checking local email' "$LINENO" "$output" "$expected" + assert_equals_helper 'Checking local email' "$LINENO" "$expected" "$output" output=${set_confs['local_sendemail.smtppass']} expected='********' - assert_equals_helper 'Checking local smtppass' "$LINENO" "$output" "$expected" + assert_equals_helper 'Checking local smtppass' "$LINENO" "$expected" "$output" output=${set_confs['local_sendemail.smtpuser']} expected='' - assert_equals_helper 'Checking local smtpuser' "$LINENO" "$output" "$expected" + assert_equals_helper 'Checking local smtpuser' "$LINENO" "$expected" "$output" git config --local --unset sendemail.smtpuser @@ -608,8 +608,8 @@ function test_config_values() expected['local']='Xpto Lala' expected['loaded']='Loaded Name' - assert_equals_helper 'Checking local name' "$LINENO" "${output['local']}" "${expected['local']}" - assert_equals_helper 'Checking loaded name' "$LINENO" "${output['loaded']}" "${expected['loaded']}" + assert_equals_helper 'Checking local name' "$LINENO" "${expected['local']}" "${output['local']}" + assert_equals_helper 'Checking loaded name' "$LINENO" "${expected['loaded']}" "${output['loaded']}" cd "$ORIGINAL_DIR" || { ret="$?" @@ -630,11 +630,11 @@ function test_add_config() # test default values output=$(add_config 'test.opt' '' '' 'TEST_MODE') expected="git config --global test.opt 'value'" - assert_equals_helper 'Testing serverport option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing serverport option' "$LINENO" "$expected" "$output" output=$(add_config 'test.option' 'test_value' 'local' 'TEST_MODE') expected="git config --local test.option 'test_value'" - assert_equals_helper 'Testing serverport option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing serverport option' "$LINENO" "$expected" "$output" } function test_mail_setup() @@ -675,17 +675,17 @@ function test_mail_setup() output=$(mail_setup 'TEST_MODE') expected="git config -- user.name 'Xpto Lala'" - assert_equals_helper 'Testing config with same value' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing config with same value' "$LINENO" "$expected" "$output" parse_mail_options '-t' '--name' 'Lala Xpto' output=$(printf 'n\n' | mail_setup 'TEST_MODE' | tail -n 1) expected='No configuration options were set.' - assert_equals_helper 'Operation should be skipped' "$LINENO" "$output" "$expected" + assert_equals_helper 'Operation should be skipped' "$LINENO" "$expected" "$output" output=$(printf 'y\n' | mail_setup 'TEST_MODE' | tail -n 1) expected="git config -- user.name 'Lala Xpto'" - assert_equals_helper 'Testing confirmation' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing confirmation' "$LINENO" "$expected" "$output" unset options_values declare -gA options_values @@ -694,14 +694,14 @@ function test_mail_setup() output=$(mail_setup 'TEST_MODE') expected="git config --local sendemail.smtpserverport '123'" - assert_equals_helper 'Testing serverport option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing serverport option' "$LINENO" "$expected" "$output" options_values['sendemail.smtpserverport']='' options_values['user.name']='Xpto Lala' output=$(mail_setup 'TEST_MODE') expected="git config --local user.name 'Xpto Lala'" - assert_equals_helper 'Testing config with same value' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing config with same value' "$LINENO" "$expected" "$output" unset options_values declare -gA options_values @@ -710,7 +710,7 @@ function test_mail_setup() output=$(mail_setup 'TEST_MODE') expected="git config --local sendemail.smtpuser 'username'" - assert_equals_helper 'Testing smtpuser option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing smtpuser option' "$LINENO" "$expected" "$output" unset options_values declare -gA options_values @@ -720,7 +720,7 @@ function test_mail_setup() output=$(mail_setup 'TEST_MODE') expected="git config --global sendemail.smtppass 'verySafePass'" - assert_equals_helper 'Testing global option' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing global option' "$LINENO" "$expected" "$output" cd "$SHUNIT_TMPDIR" || { ret="$?" @@ -736,7 +736,7 @@ function test_mail_setup() output=$(mail_setup 'TEST_MODE') expected="git config --global sendemail.smtppass 'verySafePass'" - assert_equals_helper 'Testing global option outside git' "$LINENO" "$output" "$expected" + assert_equals_helper 'Testing global option outside git' "$LINENO" "$expected" "$output" cd "$ORIGINAL_DIR" || { ret="$?" @@ -798,13 +798,13 @@ function test_interactive_prompt() # the way bash handles variables and subshells # TODO: fix these tests # expected='value1' - # assert_equals_helper 'Testing test1 value' "$LINENO" "${options_values['test1']}" "$expected" + # assert_equals_helper 'Testing test1 value' "$LINENO" "$expected" "${options_values['test1']}" # expected='value2' - # assert_equals_helper 'Testing test2 value' "$LINENO" "${options_values['test2']}" "$expected" + # assert_equals_helper 'Testing test2 value' "$LINENO" "$expected" "${options_values['test2']}" # expected='Lala Xpto' - # assert_equals_helper 'Testing user.name value' "$LINENO" "${options_values['user.name']}" "$expected" + # assert_equals_helper 'Testing user.name value' "$LINENO" "$expected" "${options_values['user.name']}" cd "$ORIGINAL_DIR" || { ret="$?" @@ -877,24 +877,24 @@ function test_load_template() output=$(load_template 'invalid' &> /dev/null) ret="$?" expected=22 - assert_equals_helper 'Invalid template' "$LINENO" "$ret" "$expected" + assert_equals_helper 'Invalid template' "$LINENO" "$expected" "$ret" load_template 'test1' expected='smtp.test1.com' - assert_equals_helper 'Load template 1' "$LINENO" "${options_values['sendemail.smtpserver']}" "$expected" + assert_equals_helper 'Load template 1' "$LINENO" "$expected" "${options_values['sendemail.smtpserver']}" tearDown setUp load_template 'test2' expected='smtp.test2.com' - assert_equals_helper 'Load template 2' "$LINENO" "${options_values['sendemail.smtpserver']}" "$expected" + assert_equals_helper 'Load template 2' "$LINENO" "$expected" "${options_values['sendemail.smtpserver']}" parse_mail_options -t --smtpserver 'user.given.server' load_template 'test2' expected='user.given.server' - assert_equals_helper 'Load template 2 should not overwrite user given values' "$LINENO" "${options_values['sendemail.smtpserver']}" "$expected" + assert_equals_helper 'Load template 2 should not overwrite user given values' "$LINENO" "$expected" "${options_values['sendemail.smtpserver']}" } function test_template_setup() @@ -920,20 +920,20 @@ function test_template_setup() template_setup expected='smtp.test1.com' - assert_equals_helper 'Load template 1' "$LINENO" "${options_values['sendemail.smtpserver']}" "$expected" + assert_equals_helper 'Load template 1' "$LINENO" "$expected" "${options_values['sendemail.smtpserver']}" options_values['TEMPLATE']=':test2' options_values['sendemail.smtpserver']='' template_setup expected='smtp.test2.com' - assert_equals_helper 'Load template 2' "$LINENO" "${options_values['sendemail.smtpserver']}" "$expected" + assert_equals_helper 'Load template 2' "$LINENO" "$expected" "${options_values['sendemail.smtpserver']}" parse_mail_options --smtpserver 'user.input' --template='test2' template_setup expected='user.input' - assert_equals_helper 'Load template 2' "$LINENO" "${options_values['sendemail.smtpserver']}" "$expected" + assert_equals_helper 'Load template 2' "$LINENO" "$expected" "${options_values['sendemail.smtpserver']}" } # This test can only be done on a local scope, as we have no control over the @@ -1005,7 +1005,7 @@ function test_mail_verify() output=$(mail_verify | head -1) expected='It looks like you are ready to send patches as:' - assert_equals_helper 'Expected successful verification' "$LINENO" "$output" "$expected" + assert_equals_helper 'Expected successful verification' "$LINENO" "$expected" "$output" unset options_values unset set_confs From 71d60ebc661f3602126b63bb5fe9dbf28a9b4fc9 Mon Sep 17 00:00:00 2001 From: Caio Dantas Date: Tue, 30 Apr 2024 14:38:30 -0300 Subject: [PATCH 077/128] documentation: content: codingstyle Add documentation to single quotes use Add documentation section about the use of single quotes instead of double quotes whenever there is no shell expansion in the value Signed-off-by: Caio Dantas Co-authored-by: Gustavo Fukunaga Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- documentation/content/codingstyle.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/documentation/content/codingstyle.rst b/documentation/content/codingstyle.rst index 4240cb55b..19ac2aa63 100644 --- a/documentation/content/codingstyle.rst +++ b/documentation/content/codingstyle.rst @@ -280,6 +280,18 @@ it stays consistent across multiple platforms. If you need to add extra lines while generating a string you can use the ``$'\n'`` literal to add a new line character or other special characters. +Single quotes instead double quotes +----------------------------------- + +Whenever you have a variable that stands for a string that doesn’t contain +shell expansions, use single quotes instead of double quotes. For example:: + + var='literal-value' #Single quotes + +or:: + + path="${HOME}/path/to/file" #Double quotes + String concatenation -------------------- From 47a04c41015125546103de7931d1f5dae40b3746 Mon Sep 17 00:00:00 2001 From: Gustavo Ueti Fukunaga Date: Sat, 4 May 2024 18:27:47 -0300 Subject: [PATCH 078/128] src: Fix codestyle for double quotes Fix files in /src dir that used double quotes instead of single quotes when there is no bash expansions. Signed-off-by: Gustavo Ueti Fukunaga Co-authored-by: Caio Dantas Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/backup.sh | 2 +- src/debug.sh | 2 +- src/deploy.sh | 2 +- src/explore.sh | 26 +++++++++++++------------- src/kernel_config_manager.sh | 4 ++-- src/lib/dialog_ui.sh | 2 +- src/lib/kw_config_loader.sh | 22 +++++++++++----------- src/lib/kw_db.sh | 2 +- src/lib/kw_time_and_date.sh | 2 +- src/mail.sh | 2 +- 10 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/backup.sh b/src/backup.sh index 97bb18836..9f0474870 100644 --- a/src/backup.sh +++ b/src/backup.sh @@ -134,7 +134,7 @@ function restore_config() complain "It looks like that the file $config_file differs from the backup version." cmd="diff -u --color=always ${KW_DATA_DIR}/configs/configs/${config_file} ${file}" cmd_manager "$flag" "$cmd" - if [[ $(ask_yN 'Do you want to replace it and its metadata?') =~ "0" ]]; then + if [[ $(ask_yN 'Do you want to replace it and its metadata?') =~ '0' ]]; then continue fi fi diff --git a/src/debug.sh b/src/debug.sh index cb5e596e2..019d2fe5d 100644 --- a/src/debug.sh +++ b/src/debug.sh @@ -854,7 +854,7 @@ function convert_event_syntax_to_sys_path_hash() if [[ "$specific_event" =~ .*'['.*']'.* ]]; then specific_filter=${specific_event%]*} specific_filter=${specific_filter##*[} - specific_event=$(cut -d "[" -f1 <<< "$specific_event") + specific_event=$(cut -d '[' -f1 <<< "$specific_event") fi hash_key="${EVENT_BASE_PATH}/${root_event}/${specific_event}" diff --git a/src/deploy.sh b/src/deploy.sh index 481eee6a6..98d3407c5 100644 --- a/src/deploy.sh +++ b/src/deploy.sh @@ -547,7 +547,7 @@ function prepare_remote_dir() distro_info=$(which_distro "$remote" "$port" "$user") distro=$(detect_distro '/' "$distro_info") - if [[ $distro =~ "none" ]]; then + if [[ "$distro" =~ 'none' ]]; then complain "Unfortunately, there's no support for '$distro_info'" exit 95 # ENOTSUP fi diff --git a/src/explore.sh b/src/explore.sh index 36002c0e8..c1f88f604 100644 --- a/src/explore.sh +++ b/src/explore.sh @@ -34,9 +34,9 @@ function explore_main() [[ -n "${options_values['VERBOSE']}" ]] && flag='VERBOSE' - if [[ "${options_values['SCOPE']}" == "HEADER" ]]; then + if [[ "${options_values['SCOPE']}" == 'HEADER' ]]; then path="${path}/*.h" - elif [[ "${options_values['SCOPE']}" == "SOURCE" ]]; then + elif [[ "${options_values['SCOPE']}" == 'SOURCE' ]]; then path="${path}/*.c" fi @@ -80,7 +80,7 @@ function parse_explore_options() local options if [[ "$#" -eq 0 ]]; then - options_values['ERROR']="Expected string or parameter. See man for detail." + options_values['ERROR']='Expected string or parameter. See man for detail.' return 22 # EINVAL fi @@ -105,7 +105,7 @@ function parse_explore_options() case "$1" in --log | -l) if [[ -n "${options_values['TYPE']}" && "${options_values['TYPE']}" -ne 1 ]]; then - options_values['ERROR']="Invalid arguments: Multiple search type!" + options_values['ERROR']='Invalid arguments: Multiple search type!' return 22 # EINVAL fi @@ -114,7 +114,7 @@ function parse_explore_options() ;; --grep | -g) if [[ -n "${options_values['TYPE']}" && "${options_values['TYPE']}" -ne 2 ]]; then - options_values['ERROR']="Invalid arguments: Multiple search type!" + options_values['ERROR']='Invalid arguments: Multiple search type!' return 22 # EINVAL fi @@ -123,7 +123,7 @@ function parse_explore_options() ;; --all | -a) if [[ -n "${options_values['TYPE']}" && "${options_values['TYPE']}" -ne 3 ]]; then - options_values['ERROR']="Invalid arguments: Multiple search type!" + options_values['ERROR']='Invalid arguments: Multiple search type!' return 22 # EINVAL fi @@ -132,24 +132,24 @@ function parse_explore_options() ;; --only-header | -H) if [[ -n "${options_values['SCOPE']}" ]]; then - if [[ "${options_values['SCOPE']}" != "HEADER" ]]; then - options_values['ERROR']="Invalid arguments: Multiple search scope!" + if [[ "${options_values['SCOPE']}" != 'HEADER' ]]; then + options_values['ERROR']='Invalid arguments: Multiple search scope!' return 22 # EINVAL fi fi - options_values['SCOPE']="HEADER" + options_values['SCOPE']='HEADER' shift ;; --only-source | -c) if [[ -n "${options_values['SCOPE']}" ]]; then - if [[ "${options_values['SCOPE']}" != "SOURCE" ]]; then - options_values['ERROR']="Invalid arguments: Multiple search scope!" + if [[ "${options_values['SCOPE']}" != 'SOURCE' ]]; then + options_values['ERROR']='Invalid arguments: Multiple search scope!' return 22 # EINVAL fi fi - options_values['SCOPE']="SOURCE" + options_values['SCOPE']='SOURCE' shift ;; --exactly) @@ -173,7 +173,7 @@ function parse_explore_options() elif [[ -z "${options_values['PATH']}" ]]; then options_values['PATH']="$1" else - options_values['ERROR']="Too many parameters" + options_values['ERROR']='Too many parameters' return 22 # EINVAL fi shift diff --git a/src/kernel_config_manager.sh b/src/kernel_config_manager.sh index d9e656a33..ffd4a214c 100644 --- a/src/kernel_config_manager.sh +++ b/src/kernel_config_manager.sh @@ -425,7 +425,7 @@ function fetch_config() cmd_manager "$flag" "$cmd" if [[ -f "${config_base_path}/${output}" ]]; then - if [[ -z "$force" && $(ask_yN "Do you want to overwrite ${output} in your current directory?") =~ "0" ]]; then + if [[ -z "$force" && "$(ask_yN "Do you want to overwrite ${output} in your current directory?")" =~ '0' ]]; then warning 'Operation aborted' return 125 #ECANCELED fi @@ -480,7 +480,7 @@ function fetch_config() ;; esac - printf "%s" "$mods" > "${KW_CACHE_DIR}/lsmod" + printf '%s' "$mods" > "${KW_CACHE_DIR}/lsmod" cmd="make localmodconfig LSMOD=${KW_CACHE_DIR}/lsmod${output_kbuild_flag}" diff --git a/src/lib/dialog_ui.sh b/src/lib/dialog_ui.sh index 0e6588cd5..5c54cc2e3 100644 --- a/src/lib/dialog_ui.sh +++ b/src/lib/dialog_ui.sh @@ -253,7 +253,7 @@ function spin_frame() local spin='⣾⣽⣻⢿┿⣟⣯⣷' frame_offset=$(((frame_offset) % ${#spin})) - printf "%s" "${spin:$frame_offset:1}" + printf '%s' "${spin:$frame_offset:1}" } # Create simple async loading screen notification for delayed actions. diff --git a/src/lib/kw_config_loader.sh b/src/lib/kw_config_loader.sh index 7a4ddb614..21b7371f8 100644 --- a/src/lib/kw_config_loader.sh +++ b/src/lib/kw_config_loader.sh @@ -107,8 +107,8 @@ function show_build_variables() [cflags]='Specify compilation flags' ) - printf '%s\n' " Kernel build options:" - local -n descriptions="build" + printf '%s\n' ' Kernel build options:' + local -n descriptions='build' print_array build_config build } @@ -139,8 +139,8 @@ function show_deploy_variables() [strip_modules_debug_option]='Modules will be stripped after they are installed which will reduce the initramfs size' ) - printf '%s\n' " Kernel deploy options:" - local -n descriptions="deploy" + printf '%s\n' ' Kernel deploy options:' + local -n descriptions='deploy' print_array deploy_config deploy } @@ -165,8 +165,8 @@ function show_mail_variables() [default_cc_recipients]='E-mail addresses to always be included as CC: recipients' ) - printf '%s\n' " kw mail options:" - local -n descriptions="mail" + printf '%s\n' ' kw mail options:' + local -n descriptions='mail' print_array mail_config mail } @@ -192,8 +192,8 @@ function show_vm_variables() [mount_point]='VM mount point' ) - printf '%s\n' " Kernel vm options:" - local -n descriptions="vm" + printf '%s\n' ' Kernel vm options:' + local -n descriptions='vm' print_array vm_config vm } @@ -217,8 +217,8 @@ function show_notification_variables() [visual_alert_command]='Command for visual notification' ) - printf '%s\n' " Kernel notification options:" - local -n descriptions="notification" + printf '%s\n' ' Kernel notification options:' + local -n descriptions='notification' print_array notification_config notification } @@ -241,7 +241,7 @@ function show_lore_variables() [lists]='List that you want to follow' ) - printf '%s\n' " Kernel upstream Lore options:" + printf '%s\n' ' Kernel upstream Lore options:' local -n descriptions='lore' print_array lore_config lore diff --git a/src/lib/kw_db.sh b/src/lib/kw_db.sh index 9624c99e8..3a2a7f73e 100644 --- a/src/lib/kw_db.sh +++ b/src/lib/kw_db.sh @@ -313,7 +313,7 @@ function generate_where_clause() attribute="$(cut --delimiter=',' --fields=1 <<< "$clause")" value="${condition_array_ref["${clause}"]}" - if [[ "$clause" =~ "," ]]; then + if [[ "$clause" =~ ',' ]]; then relational_op=$(cut --delimiter=',' --fields=2 <<< "$clause") fi diff --git a/src/lib/kw_time_and_date.sh b/src/lib/kw_time_and_date.sh index 3babe2001..f6715712b 100644 --- a/src/lib/kw_time_and_date.sh +++ b/src/lib/kw_time_and_date.sh @@ -18,7 +18,7 @@ function sec_to_format() local value="$1" local format="$2" - value=${value:-"0"} + value=${value:-'0'} format=${format:-'+%H:%M:%S'} date -d@"$value" -u "$format" diff --git a/src/mail.sh b/src/mail.sh index f4a69814e..8f9d19aac 100644 --- a/src/mail.sh +++ b/src/mail.sh @@ -1103,7 +1103,7 @@ function parse_mail_options() fi # TODO: find a better way to handle spaces inside pass_option_to_send_email for i in "$@"; do - if [[ "${i}" =~ " " ]]; then + if [[ "${i}" =~ ' ' ]]; then pass_option_to_send_email+=" ${i@Q}" else pass_option_to_send_email+=" ${i}" From c2a23887eae4796c9ac78de500616802f68a948a Mon Sep 17 00:00:00 2001 From: Marcelo Mendes Spessoto Junior Date: Fri, 19 Apr 2024 22:57:10 -0300 Subject: [PATCH 079/128] kw: replace every "#!/bin/bash" shebang with "#!/usr/bin/env bash" The usual "#!/bin/bash" may not work for some linux distributions. Replace it with "#!/usr/bin/env bash" kworkflow, being a bash-written project, requires the use of shebangs to define the interpreter environment where kw is run. Nowadays, the scripts contain the shebang "#!/bin/bash", which works normally for most of the distros. There are, however, some exceptions, such as NixOS, where there is no /bin/bash (bash is located in /nix/store). Using workflow on these types of distros may not be smooth, since the user is required to run kw commands preceded by bash or manually modify the code. Closes: #1089 Reviewed-by: Rodrigo Siqueira Signed-off-by: Marcelo Mendes Spessoto Junior Signed-off-by: Rodrigo Siqueira --- database/migrate_legacy_data_20220101.sh | 2 +- documentation/content/codingstyle.rst | 6 ++++++ kw | 2 +- run_tests.sh | 2 +- scripts/kwreview.sh | 2 +- setup.sh | 2 +- tests/integration/config_test.sh | 2 +- tests/integration/device_test.sh | 2 +- tests/integration/kw_version_test.sh | 2 +- tests/integration/podman/clone_and_install_kw.sh | 2 +- tests/integration/utils.sh | 2 +- tests/unit/backup_test.sh | 2 +- tests/unit/build_test.sh | 2 +- tests/unit/codestyle_test.sh | 2 +- tests/unit/config_test.sh | 2 +- tests/unit/debug_test.sh | 2 +- tests/unit/deploy_test.sh | 2 +- tests/unit/device_test.sh | 2 +- tests/unit/diff_test.sh | 2 +- tests/unit/drm_plugin_test.sh | 2 +- tests/unit/explore_test.sh | 2 +- tests/unit/help_test.sh | 2 +- tests/unit/init_test.sh | 2 +- tests/unit/kernel_config_manager_test.sh | 2 +- tests/unit/kw_dash.sh | 2 +- tests/unit/kw_db_test.sh | 2 +- tests/unit/kw_env_test.sh | 2 +- tests/unit/kw_remote_test.sh | 2 +- tests/unit/kw_ssh_test.sh | 2 +- tests/unit/kw_test.sh | 2 +- tests/unit/lib/dialog_ui_test.sh | 2 +- tests/unit/lib/kw_config_loader_test.sh | 2 +- tests/unit/lib/kw_include_test.sh | 2 +- tests/unit/lib/kw_string_test.sh | 2 +- tests/unit/lib/kw_time_and_date_test.sh | 2 +- tests/unit/lib/kwio_test.sh | 2 +- tests/unit/lib/kwlib_test.sh | 2 +- tests/unit/lib/lore_test.sh | 2 +- tests/unit/lib/remote_test.sh | 2 +- tests/unit/lib/signal_manager_test.sh | 2 +- tests/unit/lib/statistics_test.sh | 2 +- tests/unit/lib/web_test.sh | 2 +- tests/unit/mail_test.sh | 2 +- tests/unit/maintainers_test.sh | 2 +- tests/unit/patch_hub_test.sh | 2 +- tests/unit/permissions_test.sh | 2 +- tests/unit/plugins/kernel_install/arch_test.sh | 2 +- tests/unit/plugins/kernel_install/bootloader_utils_test.sh | 2 +- tests/unit/plugins/kernel_install/debian_test.sh | 2 +- tests/unit/plugins/kernel_install/fedora_test.sh | 2 +- tests/unit/plugins/kernel_install/grub_test.sh | 2 +- tests/unit/plugins/kernel_install/rpi_test.sh | 2 +- tests/unit/plugins/kernel_install/utils_test.sh | 2 +- tests/unit/plugins/kw_mail/to_cc_cmd_test.sh | 2 +- tests/unit/pomodoro_test.sh | 2 +- tests/unit/report_test.sh | 2 +- tests/unit/samples/tracing/kw_main_file_mock | 2 +- tests/unit/scripts/profiler_test.sh | 2 +- tests/unit/self_update_test.sh | 2 +- tests/unit/tracing/tracing_test.sh | 4 ++-- .../ui/patch_hub/latest_patchsets_from_mailing_list_test.sh | 2 +- tests/unit/ui/patch_hub/lore_mailing_lists_test.sh | 2 +- tests/unit/ui/patch_hub/patch_hub_core_test.sh | 2 +- .../unit/ui/patch_hub/patchset_details_and_actions_test.sh | 2 +- tests/unit/ui/patch_hub/search_string_in_lore_test.sh | 2 +- tests/unit/ui/patch_hub/settings_test.sh | 2 +- tests/unit/utils.sh | 2 +- tests/unit/vm_test.sh | 2 +- 68 files changed, 74 insertions(+), 68 deletions(-) diff --git a/database/migrate_legacy_data_20220101.sh b/database/migrate_legacy_data_20220101.sh index 906db1709..8de785997 100755 --- a/database/migrate_legacy_data_20220101.sh +++ b/database/migrate_legacy_data_20220101.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This file handles the migration of legacy user data, from the old directories and files # storage, to the new database model diff --git a/documentation/content/codingstyle.rst b/documentation/content/codingstyle.rst index 19ac2aa63..b6257d237 100644 --- a/documentation/content/codingstyle.rst +++ b/documentation/content/codingstyle.rst @@ -329,6 +329,12 @@ Good:: rsync --verbose --recursive dir1 dir2 +Declaring shebangs +------------------ + +Avoid using "#!/bin/bash" when writing new bash files. This usual shebang may not work for +some linux distributions that don't follow FHS, such as NixOS. Use "#!/usr/bin/env bash" instead. + Conclusion ---------- diff --git a/kw b/kw index 700cd9356..41b295151 100755 --- a/kw +++ b/kw @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash KWORKFLOW=${KWORKFLOW:-'kw'} diff --git a/run_tests.sh b/run_tests.sh index 7e32cf0a4..24de362a4 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash . ./src/lib/kw_include.sh --source-only include './tests/unit/utils.sh' diff --git a/scripts/kwreview.sh b/scripts/kwreview.sh index 2095f55b5..9af883134 100755 --- a/scripts/kwreview.sh +++ b/scripts/kwreview.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash declare -gA opt declare -ga analysed_files diff --git a/setup.sh b/setup.sh index 3ee47fbd0..34938b513 100755 --- a/setup.sh +++ b/setup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash KW_LIB_DIR='src' . 'src/lib/kw_include.sh' --source-only include "${KW_LIB_DIR}/lib/kwio.sh" diff --git a/tests/integration/config_test.sh b/tests/integration/config_test.sh index 7e4597863..d6551e34a 100755 --- a/tests/integration/config_test.sh +++ b/tests/integration/config_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' include './tests/integration/utils.sh' diff --git a/tests/integration/device_test.sh b/tests/integration/device_test.sh index 3a859d944..4694b247c 100755 --- a/tests/integration/device_test.sh +++ b/tests/integration/device_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' include './tests/integration/utils.sh' diff --git a/tests/integration/kw_version_test.sh b/tests/integration/kw_version_test.sh index d0f08a2d8..10379c656 100755 --- a/tests/integration/kw_version_test.sh +++ b/tests/integration/kw_version_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/lib/kwio.sh' include './tests/unit/utils.sh' diff --git a/tests/integration/podman/clone_and_install_kw.sh b/tests/integration/podman/clone_and_install_kw.sh index d1d27f312..d721c1a27 100755 --- a/tests/integration/podman/clone_and_install_kw.sh +++ b/tests/integration/podman/clone_and_install_kw.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # The primary purpose of this file is to install kw's dependencies in the image # we will built. This will save up time when installing the local copy of KW in diff --git a/tests/integration/utils.sh b/tests/integration/utils.sh index ae0e8c989..178fa3520 100755 --- a/tests/integration/utils.sh +++ b/tests/integration/utils.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/lib/kwio.sh' diff --git a/tests/unit/backup_test.sh b/tests/unit/backup_test.sh index 3cb832b36..e2b5337eb 100755 --- a/tests/unit/backup_test.sh +++ b/tests/unit/backup_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/backup.sh' include './src/lib/kwlib.sh' diff --git a/tests/unit/build_test.sh b/tests/unit/build_test.sh index b735aba13..1c5473461 100755 --- a/tests/unit/build_test.sh +++ b/tests/unit/build_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/build.sh' > /dev/null include './tests/unit/utils.sh' diff --git a/tests/unit/codestyle_test.sh b/tests/unit/codestyle_test.sh index 2b9c377e2..dffa3760c 100755 --- a/tests/unit/codestyle_test.sh +++ b/tests/unit/codestyle_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/codestyle.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/config_test.sh b/tests/unit/config_test.sh index bc6250311..ca4b2922a 100755 --- a/tests/unit/config_test.sh +++ b/tests/unit/config_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/config.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/debug_test.sh b/tests/unit/debug_test.sh index 67ad786b6..f2dca859e 100755 --- a/tests/unit/debug_test.sh +++ b/tests/unit/debug_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/debug.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/deploy_test.sh b/tests/unit/deploy_test.sh index bc726b629..3a3e905d1 100755 --- a/tests/unit/deploy_test.sh +++ b/tests/unit/deploy_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/deploy.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/device_test.sh b/tests/unit/device_test.sh index 64850987f..331003e98 100755 --- a/tests/unit/device_test.sh +++ b/tests/unit/device_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/device_info.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/diff_test.sh b/tests/unit/diff_test.sh index cf4c4dee6..729bbc3b2 100755 --- a/tests/unit/diff_test.sh +++ b/tests/unit/diff_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/diff.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/drm_plugin_test.sh b/tests/unit/drm_plugin_test.sh index 44b327c2f..1bc583fbe 100755 --- a/tests/unit/drm_plugin_test.sh +++ b/tests/unit/drm_plugin_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/plugins/subsystems/drm/drm.sh' include './src/lib/kwlib.sh' diff --git a/tests/unit/explore_test.sh b/tests/unit/explore_test.sh index 5596e35c9..298fdf574 100755 --- a/tests/unit/explore_test.sh +++ b/tests/unit/explore_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' include './src/explore.sh' diff --git a/tests/unit/help_test.sh b/tests/unit/help_test.sh index 46f8daa2b..04e30f55e 100755 --- a/tests/unit/help_test.sh +++ b/tests/unit/help_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' include './src/help.sh' diff --git a/tests/unit/init_test.sh b/tests/unit/init_test.sh index 4957be5d5..6d96a9300 100755 --- a/tests/unit/init_test.sh +++ b/tests/unit/init_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/init.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/kernel_config_manager_test.sh b/tests/unit/kernel_config_manager_test.sh index ee5c3e800..a52ea2011 100755 --- a/tests/unit/kernel_config_manager_test.sh +++ b/tests/unit/kernel_config_manager_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/kernel_config_manager.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/kw_dash.sh b/tests/unit/kw_dash.sh index 647f5a503..0f52ad692 100755 --- a/tests/unit/kw_dash.sh +++ b/tests/unit/kw_dash.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' diff --git a/tests/unit/kw_db_test.sh b/tests/unit/kw_db_test.sh index a941fa48c..880f9662b 100755 --- a/tests/unit/kw_db_test.sh +++ b/tests/unit/kw_db_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' include './src/lib/kw_db.sh' diff --git a/tests/unit/kw_env_test.sh b/tests/unit/kw_env_test.sh index f70d9e5e9..9f23b0ce3 100755 --- a/tests/unit/kw_env_test.sh +++ b/tests/unit/kw_env_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/kw_env.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/kw_remote_test.sh b/tests/unit/kw_remote_test.sh index ce823c83b..b7088a27a 100755 --- a/tests/unit/kw_remote_test.sh +++ b/tests/unit/kw_remote_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/kw_remote.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/kw_ssh_test.sh b/tests/unit/kw_ssh_test.sh index f125689f2..dc8bf1884 100755 --- a/tests/unit/kw_ssh_test.sh +++ b/tests/unit/kw_ssh_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/kw_ssh.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/kw_test.sh b/tests/unit/kw_test.sh index f6d692283..462eab87f 100755 --- a/tests/unit/kw_test.sh +++ b/tests/unit/kw_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' unset -v KW_LIB_DIR # to be able to test the developer mode diff --git a/tests/unit/lib/dialog_ui_test.sh b/tests/unit/lib/dialog_ui_test.sh index 5450af320..991dee926 100755 --- a/tests/unit/lib/dialog_ui_test.sh +++ b/tests/unit/lib/dialog_ui_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # include './src/lib/dialog_ui.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/lib/kw_config_loader_test.sh b/tests/unit/lib/kw_config_loader_test.sh index d7153edaf..9db669a71 100755 --- a/tests/unit/lib/kw_config_loader_test.sh +++ b/tests/unit/lib/kw_config_loader_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' include './src/lib/kw_config_loader.sh' diff --git a/tests/unit/lib/kw_include_test.sh b/tests/unit/lib/kw_include_test.sh index 964a70473..41cff4565 100755 --- a/tests/unit/lib/kw_include_test.sh +++ b/tests/unit/lib/kw_include_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' diff --git a/tests/unit/lib/kw_string_test.sh b/tests/unit/lib/kw_string_test.sh index d9fcd80af..8640b0c20 100755 --- a/tests/unit/lib/kw_string_test.sh +++ b/tests/unit/lib/kw_string_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/lib/kw_string.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/lib/kw_time_and_date_test.sh b/tests/unit/lib/kw_time_and_date_test.sh index c883f1588..5ea88e318 100755 --- a/tests/unit/lib/kw_time_and_date_test.sh +++ b/tests/unit/lib/kw_time_and_date_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/lib/kw_time_and_date.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/lib/kwio_test.sh b/tests/unit/lib/kwio_test.sh index f1b082acb..2334ab13f 100755 --- a/tests/unit/lib/kwio_test.sh +++ b/tests/unit/lib/kwio_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' include './src/lib/kwio.sh' diff --git a/tests/unit/lib/kwlib_test.sh b/tests/unit/lib/kwlib_test.sh index 750e1ebff..f0e3bcf08 100755 --- a/tests/unit/lib/kwlib_test.sh +++ b/tests/unit/lib/kwlib_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/maintainers.sh' include './src/lib/kwlib.sh' diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index 2d20f91c1..1725a9eb7 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/lib/lore.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/lib/remote_test.sh b/tests/unit/lib/remote_test.sh index daead56e4..e89d113ee 100755 --- a/tests/unit/lib/remote_test.sh +++ b/tests/unit/lib/remote_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/lib/remote.sh' include './src/lib/kwlib.sh' diff --git a/tests/unit/lib/signal_manager_test.sh b/tests/unit/lib/signal_manager_test.sh index f6b54725e..0e836d01a 100755 --- a/tests/unit/lib/signal_manager_test.sh +++ b/tests/unit/lib/signal_manager_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/lib/signal_manager.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/lib/statistics_test.sh b/tests/unit/lib/statistics_test.sh index f16660a47..3a483f7a6 100755 --- a/tests/unit/lib/statistics_test.sh +++ b/tests/unit/lib/statistics_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/lib/statistics.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/lib/web_test.sh b/tests/unit/lib/web_test.sh index f48421a21..ba74de608 100755 --- a/tests/unit/lib/web_test.sh +++ b/tests/unit/lib/web_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/lib/web.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/mail_test.sh b/tests/unit/mail_test.sh index d822ae1eb..a65f548fc 100755 --- a/tests/unit/mail_test.sh +++ b/tests/unit/mail_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/mail.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/maintainers_test.sh b/tests/unit/maintainers_test.sh index 4a1b19dec..0f04c8427 100755 --- a/tests/unit/maintainers_test.sh +++ b/tests/unit/maintainers_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/maintainers.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/patch_hub_test.sh b/tests/unit/patch_hub_test.sh index 1353ed0b9..cbcecf93b 100755 --- a/tests/unit/patch_hub_test.sh +++ b/tests/unit/patch_hub_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/patch_hub.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/permissions_test.sh b/tests/unit/permissions_test.sh index 5eb4adf49..6bc7f0970 100755 --- a/tests/unit/permissions_test.sh +++ b/tests/unit/permissions_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' diff --git a/tests/unit/plugins/kernel_install/arch_test.sh b/tests/unit/plugins/kernel_install/arch_test.sh index 887de86a0..8b942c3c5 100755 --- a/tests/unit/plugins/kernel_install/arch_test.sh +++ b/tests/unit/plugins/kernel_install/arch_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/plugins/kernel_install/utils.sh' include './src/plugins/kernel_install/arch.sh' diff --git a/tests/unit/plugins/kernel_install/bootloader_utils_test.sh b/tests/unit/plugins/kernel_install/bootloader_utils_test.sh index d2ce7db4b..80f9b50e5 100755 --- a/tests/unit/plugins/kernel_install/bootloader_utils_test.sh +++ b/tests/unit/plugins/kernel_install/bootloader_utils_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/plugins/kernel_install/bootloader_utils.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/plugins/kernel_install/debian_test.sh b/tests/unit/plugins/kernel_install/debian_test.sh index 66f80036f..a69c8848b 100755 --- a/tests/unit/plugins/kernel_install/debian_test.sh +++ b/tests/unit/plugins/kernel_install/debian_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/plugins/kernel_install/utils.sh' include './src/plugins/kernel_install/debian.sh' diff --git a/tests/unit/plugins/kernel_install/fedora_test.sh b/tests/unit/plugins/kernel_install/fedora_test.sh index 0a235b682..f306d9172 100755 --- a/tests/unit/plugins/kernel_install/fedora_test.sh +++ b/tests/unit/plugins/kernel_install/fedora_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/plugins/kernel_install/utils.sh' include './src/plugins/kernel_install/fedora.sh' diff --git a/tests/unit/plugins/kernel_install/grub_test.sh b/tests/unit/plugins/kernel_install/grub_test.sh index a3e68497b..770631b49 100755 --- a/tests/unit/plugins/kernel_install/grub_test.sh +++ b/tests/unit/plugins/kernel_install/grub_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/plugins/kernel_install/utils.sh' include './src/plugins/kernel_install/grub.sh' diff --git a/tests/unit/plugins/kernel_install/rpi_test.sh b/tests/unit/plugins/kernel_install/rpi_test.sh index 67ccd161f..2c4afb459 100755 --- a/tests/unit/plugins/kernel_install/rpi_test.sh +++ b/tests/unit/plugins/kernel_install/rpi_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/plugins/kernel_install/utils.sh' include './src/plugins/kernel_install/rpi_bootloader.sh' diff --git a/tests/unit/plugins/kernel_install/utils_test.sh b/tests/unit/plugins/kernel_install/utils_test.sh index 8c30a7807..473d9066b 100755 --- a/tests/unit/plugins/kernel_install/utils_test.sh +++ b/tests/unit/plugins/kernel_install/utils_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # We load utils in the oneTimeSetUp() to ensure we can replace some kw functions include './tests/unit/utils.sh' diff --git a/tests/unit/plugins/kw_mail/to_cc_cmd_test.sh b/tests/unit/plugins/kw_mail/to_cc_cmd_test.sh index c636a10ec..4e8798a0f 100755 --- a/tests/unit/plugins/kw_mail/to_cc_cmd_test.sh +++ b/tests/unit/plugins/kw_mail/to_cc_cmd_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' diff --git a/tests/unit/pomodoro_test.sh b/tests/unit/pomodoro_test.sh index 6eaf8c304..00b57e19e 100755 --- a/tests/unit/pomodoro_test.sh +++ b/tests/unit/pomodoro_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/pomodoro.sh' include './src/lib/kw_db.sh' diff --git a/tests/unit/report_test.sh b/tests/unit/report_test.sh index 821a981c4..483fc79ce 100755 --- a/tests/unit/report_test.sh +++ b/tests/unit/report_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/report.sh' include './src/lib/kw_db.sh' diff --git a/tests/unit/samples/tracing/kw_main_file_mock b/tests/unit/samples/tracing/kw_main_file_mock index 44b598d79..afab1787d 100644 --- a/tests/unit/samples/tracing/kw_main_file_mock +++ b/tests/unit/samples/tracing/kw_main_file_mock @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This is a mock to test the injection of tracing code into kw main file diff --git a/tests/unit/scripts/profiler_test.sh b/tests/unit/scripts/profiler_test.sh index c4a61cd21..7d89d9dc6 100755 --- a/tests/unit/scripts/profiler_test.sh +++ b/tests/unit/scripts/profiler_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './scripts/profiler.sh' > '/dev/null' 2>&1 include './tests/unit/utils.sh' diff --git a/tests/unit/self_update_test.sh b/tests/unit/self_update_test.sh index a6e9dcd21..062e3f84f 100755 --- a/tests/unit/self_update_test.sh +++ b/tests/unit/self_update_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/self_update.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/tracing/tracing_test.sh b/tests/unit/tracing/tracing_test.sh index d89f056ef..5dd647cc3 100755 --- a/tests/unit/tracing/tracing_test.sh +++ b/tests/unit/tracing/tracing_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tracing/tracing.sh' include './tests/unit/utils.sh' @@ -45,7 +45,7 @@ function test_sync_main_kw_file_with_tracing() output=$(< "${bin}/${kw_path}") expected=$( cat << 'EOF' -#!/bin/bash +#!/usr/bin/env bash # This is a mock to test the injection of tracing code into kw main file diff --git a/tests/unit/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh b/tests/unit/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh index ee86553eb..ad7caed54 100755 --- a/tests/unit/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh +++ b/tests/unit/ui/patch_hub/latest_patchsets_from_mailing_list_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/ui/patch_hub/latest_patchsets_from_mailing_list.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/ui/patch_hub/lore_mailing_lists_test.sh b/tests/unit/ui/patch_hub/lore_mailing_lists_test.sh index bf915b479..91a4f0c9f 100755 --- a/tests/unit/ui/patch_hub/lore_mailing_lists_test.sh +++ b/tests/unit/ui/patch_hub/lore_mailing_lists_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/ui/patch_hub/lore_mailing_lists.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/ui/patch_hub/patch_hub_core_test.sh b/tests/unit/ui/patch_hub/patch_hub_core_test.sh index af168e39a..6146cfb75 100755 --- a/tests/unit/ui/patch_hub/patch_hub_core_test.sh +++ b/tests/unit/ui/patch_hub/patch_hub_core_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/ui/patch_hub/patch_hub_core.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh b/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh index 0ee5c9d2c..0a10a148d 100755 --- a/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh +++ b/tests/unit/ui/patch_hub/patchset_details_and_actions_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/ui/patch_hub/patchset_details_and_actions.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/ui/patch_hub/search_string_in_lore_test.sh b/tests/unit/ui/patch_hub/search_string_in_lore_test.sh index 9e085c974..2e943df1a 100755 --- a/tests/unit/ui/patch_hub/search_string_in_lore_test.sh +++ b/tests/unit/ui/patch_hub/search_string_in_lore_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/ui/patch_hub/search_string_in_lore.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/ui/patch_hub/settings_test.sh b/tests/unit/ui/patch_hub/settings_test.sh index f00a999e2..e14a6012a 100755 --- a/tests/unit/ui/patch_hub/settings_test.sh +++ b/tests/unit/ui/patch_hub/settings_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './src/ui/patch_hub/settings.sh' include './tests/unit/utils.sh' diff --git a/tests/unit/utils.sh b/tests/unit/utils.sh index 1ed27750c..19bc52671 100755 --- a/tests/unit/utils.sh +++ b/tests/unit/utils.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash REPO_ROOT_PATH="$PWD" TEST_DIR="$PWD/tests/unit" diff --git a/tests/unit/vm_test.sh b/tests/unit/vm_test.sh index 6ab43c39f..643b5bfe6 100755 --- a/tests/unit/vm_test.sh +++ b/tests/unit/vm_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash include './tests/unit/utils.sh' include './src/lib/kw_config_loader.sh' From dc1ce626627cdd29f0dd3543520398997aac4383 Mon Sep 17 00:00:00 2001 From: Bruno Rocha Levi Date: Thu, 9 May 2024 20:29:44 -0300 Subject: [PATCH 080/128] add errno error codes to returns that lack them Some of the return statements don't have a comment at the end saying what was the errno error code. In this sense, add the error codes to most of these return statements to enforce the coding style. Reviewed-by: David Tadokoro Signed-off-by: Bruno Rocha Levi Co-developed-by: Lucas Antonio Pataluch dos Santos Signed-off-by: David Tadokoro --- database/migrate_legacy_data_20220101.sh | 10 +++++----- kw | 2 +- run_tests.sh | 2 +- setup.sh | 2 +- src/debug.sh | 6 +++--- src/kernel_config_manager.sh | 2 +- src/kw_remote.sh | 2 +- src/kw_ssh.sh | 4 ++-- src/lib/dialog_ui.sh | 2 +- src/lib/kw_string.sh | 4 ++-- src/lib/kwlib.sh | 6 +++--- src/lib/remote.sh | 2 +- src/lib/web.sh | 2 +- src/mail.sh | 2 +- src/maintainers.sh | 8 ++++---- src/pomodoro.sh | 2 +- src/report.sh | 2 +- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/database/migrate_legacy_data_20220101.sh b/database/migrate_legacy_data_20220101.sh index 8de785997..3082fe063 100755 --- a/database/migrate_legacy_data_20220101.sh +++ b/database/migrate_legacy_data_20220101.sh @@ -99,7 +99,7 @@ function migrate_statistics() cmd_manager 'SILENT' "mv ${datadir}/statistics ${datadir}/legacy_statistics" if [[ "$?" != 0 ]]; then complain "Couldn't rename ${datadir}/statistics ${datadir}/legacy_statistics" - return 1 #EPERM + return 1 # EPERM fi } @@ -161,7 +161,7 @@ function migrate_pomodoro() cmd_manager 'SILENT' "mv ${datadir}/pomodoro ${datadir}/legacy_pomodoro" if [[ "$?" != 0 ]]; then complain "Couldn't rename ${datadir}/pomodoro ${datadir}/legacy_pomodoro" - return 1 #EPERM + return 1 # EPERM fi } @@ -216,20 +216,20 @@ function migrate_kernel_configs() cmd_manager 'SILENT' "cp -r ${configs_dir}/. ${datadir}/configs" if [[ "$?" != 0 ]]; then complain "Couldn't copy kernel config files from ${configs_dir} to ${datadir}/configs" - return 1 #EPERM + return 1 # EPERM fi # mark migrated directories to avoid duplicated data cmd_manager 'SILENT' "mv ${datadir}/configs/configs ${datadir}/configs/legacy_configs" if [[ "$?" != 0 ]]; then complain "Couldn't rename ${datadir}/configs/configs to ${datadir}/configs/legacy_configs" - return 1 #EPERM + return 1 # EPERM fi cmd_manager 'SILENT' "mv ${datadir}/configs/metadata ${datadir}/configs/legacy_metadata" if [[ "$?" != 0 ]]; then complain "Couldn't rename ${datadir}/configs/metadata to ${datadir}/configs/legacy_metadata" - return 1 #EPERM + return 1 # EPERM fi } diff --git a/kw b/kw index 41b295151..aac10cc4e 100755 --- a/kw +++ b/kw @@ -321,7 +321,7 @@ function kw() complain 'Invalid option' kworkflow_help - return 1 + return 1 # EPERM ) ;; esac diff --git a/run_tests.sh b/run_tests.sh index 24de362a4..ffde2af78 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -64,7 +64,7 @@ function report_results() done fi - return 1 + return 1 # EPERM fi } diff --git a/setup.sh b/setup.sh index 34938b513..39910328a 100755 --- a/setup.sh +++ b/setup.sh @@ -544,7 +544,7 @@ function setup_global_config_file() fi else warning "setup could not find $config_file_template" - return 2 + return 2 # ENOENT fi } diff --git a/src/debug.sh b/src/debug.sh index 019d2fe5d..7e473aa04 100644 --- a/src/debug.sh +++ b/src/debug.sh @@ -48,7 +48,7 @@ function debug_main() if [[ "$?" -gt 0 ]]; then complain "Invalid option: ${options_values['ERROR']}" debug_help - return 22 + return 22 # EINVAL fi test_mode="${options_values['TEST_MODE']}" @@ -961,7 +961,7 @@ function parser_debug_options() populate_remote_info "$2" if [[ "$?" == 22 ]]; then options_values['ERROR']="$option" - return 22 + return 22 # EINVAL fi options_values['TARGET']="$REMOTE_TARGET" shift 2 @@ -1029,7 +1029,7 @@ function parser_debug_options() ;; *) options_values['ERROR']="$1" - return 22 + return 22 # EINVAL ;; esac done diff --git a/src/kernel_config_manager.sh b/src/kernel_config_manager.sh index ffd4a214c..c6423c004 100644 --- a/src/kernel_config_manager.sh +++ b/src/kernel_config_manager.sh @@ -245,7 +245,7 @@ function get_config_from_proc() case "$target" in 1) # VM # We do not support this option with VM - return 95 + return 95 # ENOTSUP ;; 2) # LOCAL # Try to find /proc/config, if we cannot find, attempt to load the module diff --git a/src/kw_remote.sh b/src/kw_remote.sh index 5f6a88dd8..98a98ffb1 100644 --- a/src/kw_remote.sh +++ b/src/kw_remote.sh @@ -406,7 +406,7 @@ function parse_remote_options() return 22 # EINVAL elif [[ "${options_values['DEFAULT_REMOTE']}" == 1 ]]; then options_values['ERROR']='Expected a string values after --set-default=' - return 22 + return 22 # EINVAL elif [[ -z "${options_values['ADD']}" && -z "${options_values['REMOVE']}" && -z "${options_values['RENAME']}" && -z "${options_values['LIST']}" && -z "${options_values['DEFAULT_REMOTE']}" ]]; then diff --git a/src/kw_ssh.sh b/src/kw_ssh.sh index 5d0591fb1..f446ba2fe 100644 --- a/src/kw_ssh.sh +++ b/src/kw_ssh.sh @@ -316,7 +316,7 @@ function parser_ssh_options() populate_remote_info "$2" if [[ "$?" == 22 ]]; then options_values['ERROR']="$option" - return 22 + return 22 # EINVAL fi shift 2 ;; @@ -357,7 +357,7 @@ function parser_ssh_options() ;; *) options_values['ERROR']="$1" - return 22 + return 22 # EINVAL ;; esac done diff --git a/src/lib/dialog_ui.sh b/src/lib/dialog_ui.sh index 5c54cc2e3..9932c0688 100644 --- a/src/lib/dialog_ui.sh +++ b/src/lib/dialog_ui.sh @@ -931,7 +931,7 @@ function prettify_string() local variable_to_concatenate="$2" if [[ -z "$fixed_text" || -z "$variable_to_concatenate" ]]; then - return 22 + return 22 # EINVAL fi printf '\Zb\Z6%s\Zn%s\\n' "$fixed_text" "$variable_to_concatenate" diff --git a/src/lib/kw_string.sh b/src/lib/kw_string.sh index 73d406a01..853f29ed0 100644 --- a/src/lib/kw_string.sh +++ b/src/lib/kw_string.sh @@ -29,7 +29,7 @@ function str_is_a_number() value=$(str_strip "$value") [[ "$value" =~ ^[-]?[0-9]+$ ]] && return 0 - return 1 + return 1 # EPERM } # Calculate the length of a string @@ -206,7 +206,7 @@ function str_has_special_characters() local str="$*" [[ "$str" == *['!'@#\$%^\&*\(\)+]* ]] && return 0 - return 1 + return 1 # EPERM } # Get value under double-quotes. This function only returns the first match if diff --git a/src/lib/kwlib.sh b/src/lib/kwlib.sh index bdebbe11c..f67ccc6d4 100644 --- a/src/lib/kwlib.sh +++ b/src/lib/kwlib.sh @@ -169,7 +169,7 @@ function is_kernel_root() -d "${DIR}/scripts" ]]; then return 0 fi - return 1 + return 1 # EPERM } # Finds the root of the linux kernel repo containing the given file @@ -268,7 +268,7 @@ function is_a_patch() local file_content if [[ ! -f "$FILE_PATH" ]]; then - return 1 + return 1 # EPERM fi file_content=$(< "$FILE_PATH") @@ -284,7 +284,7 @@ function is_a_patch() for expected_str in "${PATCH_EXPECTED_STRINGS[@]}"; do if [[ ! "$file_content" =~ $expected_str ]]; then - return 1 + return 1 # EPERM fi done diff --git a/src/lib/remote.sh b/src/lib/remote.sh index 83968dd32..7bf7137d1 100644 --- a/src/lib/remote.sh +++ b/src/lib/remote.sh @@ -67,7 +67,7 @@ function is_ssh_connection_configured() ret="$?" # User canceled the manual update - [[ "$ret" == 125 ]] && return 125 + [[ "$ret" == 125 ]] && return 125 # ECANCELED # Some other unknown error occurred [[ "$ret" != 0 ]] && return 101 # ENETUNREACH diff --git a/src/lib/web.sh b/src/lib/web.sh index f10788520..bde41f70a 100644 --- a/src/lib/web.sh +++ b/src/lib/web.sh @@ -74,7 +74,7 @@ function is_html_file() grep --silent '\(\|\)' "$file_path" [[ "$?" == 0 ]] && return 0 - return 1 + return 1 # EPERM } # This function recieves a string and converts it to contain only characters that diff --git a/src/mail.sh b/src/mail.sh index 8f9d19aac..8680e8f83 100644 --- a/src/mail.sh +++ b/src/mail.sh @@ -600,7 +600,7 @@ function mail_verify() if [[ "${#missing_conf}" -gt 0 ]]; then complain 'Missing configurations required for send-email:' printf ' %s\n' "${missing_conf[@]}" - return 22 + return 22 # EINVAL fi success 'It looks like you are ready to send patches as:' diff --git a/src/maintainers.sh b/src/maintainers.sh index 319a5fd30..c69f03354 100644 --- a/src/maintainers.sh +++ b/src/maintainers.sh @@ -59,7 +59,7 @@ function maintainers_main() # Check if is a valid path if [[ ! -d "$FILE_OR_DIR" && ! -f "$FILE_OR_DIR" ]]; then complain 'Invalid path' - return 1 + return 1 # EPERM fi FILE_OR_DIR="$(realpath "${FILE_OR_DIR}")" @@ -68,7 +68,7 @@ function maintainers_main() if ! is_a_patch "$FILE_OR_DIR"; then if [[ -n "$update_patch" ]]; then complain 'Option --update-patch was passed but given path is not a patch.' - return 1 + return 1 # EPERM fi is_file_a_patch=false script_options="${script_options} -f" @@ -85,7 +85,7 @@ function maintainers_main() # Check if kernel root was found. if [[ -z "$kernel_root" ]]; then complain 'Neither the given path nor the working path is in a kernel tree.' - return 1 + return 1 # EPERM fi # If file is not a patch and outside a kernel tree, it must be an user's @@ -93,7 +93,7 @@ function maintainers_main() # because it is most likely a user's mistake. So better let the user know. if ! "$is_file_a_patch" && ! "$is_file_inside_kernel_tree"; then complain 'The given file is not a patch and is outside a kernel tree.' - return 1 + return 1 # EPERM fi cmd_manager "$flag" "cd ${kernel_root}" diff --git a/src/pomodoro.sh b/src/pomodoro.sh index 419975e0b..94898d3fb 100644 --- a/src/pomodoro.sh +++ b/src/pomodoro.sh @@ -138,7 +138,7 @@ function is_tag_already_registered() is_tag_registered=$(select_from "tag WHERE name IS '${tag_name}'" '' '' '' '' "$flag") [[ -n "${is_tag_registered}" ]] && return 0 - return 1 + return 1 # EPERM } # This is the thread function that will be used to notify when the Pomodoro diff --git a/src/report.sh b/src/report.sh index 9aef38c20..24414d1ac 100644 --- a/src/report.sh +++ b/src/report.sh @@ -448,7 +448,7 @@ function parse_report_options() if [[ "$reference_count" -gt 1 ]]; then complain 'Please, only use a single time reference' - return 22 + return 22 # EINVAL elif [[ "$reference_count" == 0 ]]; then # If no option, set day as a default options_values['DAY']=$(get_today_info '+%Y/%m/%d') From 518a1737889b0ec70e49d1c238ba60fcc6d67bc5 Mon Sep 17 00:00:00 2001 From: Marcelo Mendes Spessoto Junior Date: Mon, 13 May 2024 08:56:45 -0300 Subject: [PATCH 081/128] initial Jenkinsfile Signed-off-by: Marcelo Mendes Spessoto Junior --- Jenkinsfile | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..9a7827fc8 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,24 @@ +pipeline { + agent any + stages { + + stage('Build'){ + steps{ + sh ''' + apt update -y + apt install -y kcov shunit2 bc sqlite3 bsdmainutils libxml-xpath-perl + ./run_tests.sh prepare + mkdir kcov_out/ + git config --global user.email "kw@kworkflow.net" + git config --global user.name "Kworkflow" + ./run_tests.sh + kcov --include-path=src,kw \ + --exclude-pattern=src/bash_autocomplete.sh,src/help.sh \ + kcov_out/ ./run_tests.sh + ''' + cobertura autoUpdateHealth: false, autoUpdateStability: false, coberturaReportFile: 'kcov_out/', conditionalCoverageTargets: '70, 0, 0', failUnhealthy: false, failUnstable: false, lineCoverageTargets: '80, 0, 0', maxNumberOfBuilds: 0, methodCoverageTargets: '80, 0, 0', onlyStable: false, sourceEncoding: 'ASCII', zoomCoverageChart: false + } + } + + } +} From 8fa6366bf3200d9ac7e2dda891f4c6a460eca23f Mon Sep 17 00:00:00 2001 From: Gabriel Schwartz Date: Mon, 6 May 2024 18:18:30 -0300 Subject: [PATCH 082/128] documentation: man: update man pages to use correct config files Most man pages still mentioned a root level kworkflow.config file as the only source of user-adjustable settings. This commit replaces outdated references to kworkflow.config with the specific .kw/.config format currently used by kw config and also recommends the use of kw config to adjust these options. In doing so, this commit also removes the list of adjustable options from the main kw.rst man page, as these were outdated, are now mostly command-specific and could cause confusion in new users. Further changes are needed to redistribute these explanations (when needed) to more adequate locations. Reviewed-by: Rodrigo Siqueira Signed-off-by: Gabriel Schwartz Signed-off-by: Rodrigo Siqueira --- documentation/man/features/kw-build.rst | 13 ++- documentation/man/features/kw-codestyle.rst | 5 +- documentation/man/features/kw-deploy.rst | 26 +++-- documentation/man/features/kw-drm.rst | 9 +- documentation/man/features/kw-init.rst | 20 ++-- .../man/features/kw-kernel-config-manager.rst | 5 +- documentation/man/features/kw-mail.rst | 6 +- documentation/man/features/kw-maintainers.rst | 5 +- documentation/man/features/kw-ssh.rst | 5 +- documentation/man/features/kw-vm.rst | 6 +- documentation/man/kw.rst | 108 +----------------- 11 files changed, 61 insertions(+), 147 deletions(-) diff --git a/documentation/man/features/kw-build.rst b/documentation/man/features/kw-build.rst index 8fd82b455..3acd3136c 100644 --- a/documentation/man/features/kw-build.rst +++ b/documentation/man/features/kw-build.rst @@ -40,7 +40,7 @@ OPTIONS -n, \--menu: The menu option invokes the kernel menuconfig. Notice that the default menu - config can be changed in the **kworkflow.config** file by setting a different + config can be changed in the **build.config** file by setting a different option in *menu_config*. If the user is working in a *cross-compile* environment, it is recommended to use this option to avoid messing with the config file manually. @@ -48,7 +48,7 @@ OPTIONS -d, \--doc: The doc option provides a mechanism for building the kernel-doc; by default, it will build htmldocs. Users can change the default documentation output by - changing the parameter *doc_type* in the **kworkflow.config** file. + changing the parameter *doc_type* in the **build.config** file. -S, \--cpu-scaling: The cpu-scaling option lets the user set whichever CPU usage they want from @@ -61,12 +61,12 @@ OPTIONS -w, \--warnings (1 | 2 | 3 | 12 | 13 | 23 | 123): This can be used to enable compilation warnings accordingly. You can set the - default log level via `build.config` file under the option `warning_level`. + default log level via **build.config** file under the option `warning_level`. Please check the kernel's ``make help`` for more info. -s, \--save-log-to=path: This option will save the full compilation log with the enabled warnings to - the specified path. You can set the default log path in the `build.config` + the specified path. You can set the default log path in the **build.config** file via `log_path` option. \--llvm: @@ -104,8 +104,9 @@ OPTIONS EXAMPLES ======== -For these examples, we suppose the fields in your **kworkflow.config** file are -already configured. +For these examples, we assume that the relevant fields in your configuration +files (located by default in **.kw/**) have already been setup. We recommend +the use of ``kw config`` for managing your local and global configurations. For building and installing a new module version based on the current kernel version, you can use:: diff --git a/documentation/man/features/kw-codestyle.rst b/documentation/man/features/kw-codestyle.rst index 02d3cfab5..c6b9cd985 100644 --- a/documentation/man/features/kw-codestyle.rst +++ b/documentation/man/features/kw-codestyle.rst @@ -29,8 +29,9 @@ OPTIONS EXAMPLES ======== -For these examples, we suppose the fields in your **kworkflow.config** file are -already configured. +For these examples, we assume that the relevant fields in your configuration +files (located by default in **.kw/**) have already been setup. We recommend +the use of ``kw config`` for managing your local and global configurations. For checking the code style:: diff --git a/documentation/man/features/kw-deploy.rst b/documentation/man/features/kw-deploy.rst index 096f84f0a..116cda646 100644 --- a/documentation/man/features/kw-deploy.rst +++ b/documentation/man/features/kw-deploy.rst @@ -31,22 +31,23 @@ executed: You can specify the deploy target via command line by using the flag ``--remote :`` (e.g., ``--remote 172.16.254.1:22``); however, if -you do this frequently you will probably prefer to add this information to your -local **kworkflow.config**. See the example below:: +you plan on deploying to the same remote frequently can benefit from using the +``kw remote`` feature to save the SSH information in a configuration file +used by kw, for example:: - default_deploy_target=remote - ssh_user=root - ssh_ip=172.16.254.1 - ssh_port=22 + kw remote --add origin root@172.16.254.1 + +For more information, check ``kw remote --help`` If you want to install a new kernel version in your host machine, you can use the flag ``--local``; you will need to use your root password. -Another typical operation when deploying a new kernel to a test machine, it is -the reboot after the update. You can explicitly say it for **kw** by adding the -flag ``--reboot``, add this to the **kworkflow.config** with:: +Another typical operation when deploying a new kernel to a test machine is +rebooting after the update. You can add the ``--reboot`` flag to a command to +explicitly make **kw** reboot the machine afterwards, or you can set this to +always happen by modifying ``reboot_after_deploy`` flag in **deploy.config** with:: - reboot_after_deploy=yes + kw config deploy.reboot_after_deploy yes This can be used with conjunction the :ref:`build` command by invoking ``kw bd``. @@ -117,8 +118,9 @@ OPTIONS EXAMPLES ======== -For these examples, we suppose the fields in your **kworkflow.config** file are -already configured. +For these examples, we assume that the relevant fields in your configuration +files (located by default in **.kw/**) have already been setup. We recommend +the use of ``kw config`` for managing your local and global configurations. First, if you are working in a specific kernel module, and if you want to install your recent changes in your local machine you can use:: diff --git a/documentation/man/features/kw-drm.rst b/documentation/man/features/kw-drm.rst index 3368d269a..ac16eaf3d 100644 --- a/documentation/man/features/kw-drm.rst +++ b/documentation/man/features/kw-drm.rst @@ -26,8 +26,8 @@ OPTIONS \--local, \--remote [:]: This option specifies the target device for the drm action, it can be a remote or local machine. If these options are not explicitly passed via - command line, **kw** going to take the target set in the variable - *default_deploy_target* (**kworkflow.config**) for identifying the target. + command line, **kw** is going to take the target set in the variable + *default_deploy_target* (**deploy.config**) for identifying the target. It is important to highlight that the drm feature **does not support VM**. -lm, \--load-module=[:,...][;:...]: @@ -68,8 +68,9 @@ OPTIONS EXAMPLES ======== -For these examples, we suppose the fields in your **kworkflow.config** file are -already configured. +For these examples, we assume that the relevant fields in your configuration +files (located by default in **.kw/**) have already been setup. We recommend +the use of ``kw config`` for managing your local and global configurations. If you are working with DRM drivers, you can take advantage of load and unload commands combined with GUI control commands. For example:: diff --git a/documentation/man/features/kw-init.rst b/documentation/man/features/kw-init.rst index 8d85b095a..4b6770133 100644 --- a/documentation/man/features/kw-init.rst +++ b/documentation/man/features/kw-init.rst @@ -11,9 +11,9 @@ SYNOPSIS DESCRIPTION =========== -This command creates a **.kw** folder containing a **kworkflow.config** file in +This command creates a **.kw** folder containing default configuration files in the current kernel directory. The primary reason for running ``kw init`` is to -pick up a freshly created config file. +pick up freshly created config files. OPTIONS ======= @@ -25,7 +25,7 @@ OPTIONS creating the local config file. \--arch : - Set the variable `arch` from the newly created **kworkflow.config** file. + Set the variable `arch` from the newly created **build.config** file. Before actually changing it, this option checks if ** is a valid architecture found in the **arch** folder from the kernel directory. @@ -34,7 +34,7 @@ OPTIONS and **, respectively. \--target : - Set the variable `default_deploy_target` from **kworkflow.config** to + Set the variable `default_deploy_target` from **deploy.config** to **, which can be local or remote. \--verbose: @@ -45,17 +45,19 @@ EXAMPLES For these examples, we suppose that the kernel directory is your current directory. -For initializing a **kworkflow.config** with `arch` set to arm, use:: +For initializing a **build.config** with `arch` set to arm, use:: kw init --arch arm -To initialize **kworkflow.config** with `arch` set to x86, `ssh_user` set to -john, `ssh_ip` set to localhost, and `ssh_port` set to 2222, run:: +To initialize **build.config** with `arch` set to x86 and a **kworkflow.config** +with `ssh_user` set to john, `ssh_ip` set to localhost, and `ssh_port` +set to 2222, run:: kw init --arch x86 --remote john@localhost:2222 -For initializing a **kworkflow.config** with `arch` set to arm64, `target` set to -remote, `ssh_user` mary, `ssh_ip` localhost, and `ssh_port` 1234, run:: +For initializing a **build.config** with `arch` set to arm64, a **deploy.config** +with `target` set to remote and a **kworkflow.config** with `ssh_user` mary, +`ssh_ip` localhost, and `ssh_port` 1234, run:: kw init --arch arm64 --remote mary@localhost:1234 --target remote diff --git a/documentation/man/features/kw-kernel-config-manager.rst b/documentation/man/features/kw-kernel-config-manager.rst index 0c4a13595..404da4e75 100644 --- a/documentation/man/features/kw-kernel-config-manager.rst +++ b/documentation/man/features/kw-kernel-config-manager.rst @@ -62,8 +62,9 @@ OPTIONS EXAMPLES ======== -In the following examples, we assume your **kworkflow.config** file is already -properly configured. +For these examples, we assume that the relevant fields in your configuration +files (located by default in **.kw/**) have already been setup. We recommend +the use of ``kw config`` for managing your local and global configurations. In case you want **kw** to save your current **.config** file, you can use:: diff --git a/documentation/man/features/kw-mail.rst b/documentation/man/features/kw-mail.rst index 62f3429ad..c4fb3a633 100644 --- a/documentation/man/features/kw-mail.rst +++ b/documentation/man/features/kw-mail.rst @@ -29,12 +29,12 @@ the union of the recipients of each patch as the recipients of the cover-letter. .. note:: You can block certain e-mail addresses from being automatically added to the recipients list of the patches using the *blocked_emails* option in the - *kworkflow.config* file. + **mail.config** file. .. note:: You can add To\: and CC\: recipients to be included by default using the *default_to_recipients* and *default_cc_recipients* configurations, respectively, - in the *mail.config* file. + in the **mail.config** file. .. note:: Any option recognized by ``git send-email`` can be passed directly to it if @@ -53,7 +53,7 @@ OPTIONS .. note:: You can change the default arguments used to send emails in the - *kworkflow.config* file. + **mail.config** file. \--to=',...': Specify the recipients that will receive the patch via e-mail. The diff --git a/documentation/man/features/kw-maintainers.rst b/documentation/man/features/kw-maintainers.rst index e44347bf7..59017a86e 100644 --- a/documentation/man/features/kw-maintainers.rst +++ b/documentation/man/features/kw-maintainers.rst @@ -36,8 +36,9 @@ OPTIONS EXAMPLES ======== -For these examples, we suppose the fields in your **kworkflow.config** file are -already configured. +For these examples, we assume that the relevant fields in your configuration +files (located by default in **.kw/**) have already been setup. We recommend +the use of ``kw config`` for managing your local and global configurations. If you want to check the maintainers:: diff --git a/documentation/man/features/kw-ssh.rst b/documentation/man/features/kw-ssh.rst index 7ca708fac..4a76f3d36 100644 --- a/documentation/man/features/kw-ssh.rst +++ b/documentation/man/features/kw-ssh.rst @@ -51,8 +51,9 @@ OPTIONS EXAMPLES ======== -For these examples, we suppose the fields in your **kworkflow.config** file are -already configured. +For these examples, we assume that the relevant fields in your configuration +files (located by default in **.kw/**) have already been setup. We recommend +the use of ``kw config`` for managing your local and global configurations. After you start your VM you can ssh into it with:: diff --git a/documentation/man/features/kw-vm.rst b/documentation/man/features/kw-vm.rst index fb78e9dd9..8b866bdd9 100644 --- a/documentation/man/features/kw-vm.rst +++ b/documentation/man/features/kw-vm.rst @@ -21,7 +21,7 @@ OPTIONS ======= -m, \--mount: This mounts the QEMU image in a specific directory, based on the data available - in the **kworkflow.config** file. Notice that the configuration file has the + in the **vm.config** file. Notice that the configuration file has the information about the source image and destination mount point. .. note:: @@ -29,10 +29,10 @@ OPTIONS -n, \--umount: This unmounts the previously mounted QEMU image, based on the parameters - available in the **kworkflow.config** file. + available in the **vm.config** file. -u, \--up: - This starts the QEMU VM based on parameters in the **kworkflow.config** file. + This starts the QEMU VM based on parameters in the **vm.config** file. \--alert=(s | v | (sv | vs) | n): Defines the alert behaviour upon the command completion. diff --git a/documentation/man/kw.rst b/documentation/man/kw.rst index 0f2190505..fca6e7608 100644 --- a/documentation/man/kw.rst +++ b/documentation/man/kw.rst @@ -19,8 +19,8 @@ DESCRIPTION =========== **kw** mission is: reduce the overhead related with infrastructure project setup in projects that have a similar workflow to the Linux Kernel. It can (and -should) be customized by editing the **kworkflow.config** file, as discussed in -section `ABOUT kworflow.config`_. +should) be customized by editing its various configuration files (preferably +through the **kw config** command). COMMANDS ======== @@ -88,6 +88,7 @@ This section describes a tool available in **kw** to help developers keep track of configuration files and other features provided by **kw** that do not fit in the previous sections. + | :ref:`kw-config` | :ref:`kw-backup` | :ref:`kw-init` | :ref:`kw-device` @@ -111,108 +112,11 @@ version, \--version, -v ~~~~~~~~~~~~~~~~~~~~~~~ Show kworkflow version. -ABOUT kworflow.config -===================== -.. _`ABOUT kworkflow.config`: - -**kw** reads its configuration from two files: the global -*/etc/kworkflow.config* file and the local **kworkflow.config** file -present at the current working directory. The global **kworkflow.config** is a -part of the **kw** code and provides the overall behavior for **kw**. Local -**kworkflow.config** settings override global ones; you may have one -**kworkflow.config** per project. In this section, we describe the possible -fields you can specify in the configuration files. - -ssh_user= ---------------- -Sets the user to be used by ssh. By default **kw** uses ``root``. - -ssh_ip= ------------ -Sets the IP address to be used by ssh. By default **kw** uses ``localhost``. - -ssh_port= ---------------- -Sets the ssh port. By default **kw** uses ``2222``. - -ssh_configfile= --------------------------------- -Provides an optional SSH configuration file to be used by ssh. For more details -see ``man ssh_config``. - -hostname= -------------------- -Sets the hostname to be used when an SSH configuration file is provided. - -arch= -------------------- -Allows you to specify the default architecture used by **kw**. By default, -**kw** uses ``x86_64``. - -kernel_img_name= ------------------------------------ -Use this option as a way to indicate to kw the kernel image name. This is the -file present in the directory ``arch/*/boot/``; keep in mind that the kernel -image name might change based on the user config file or target architecture. - -cross_compile= --------------------------------------------- -Kw supports cross compile setup, use this option to indicate the target -toolchain. - -menu_config= -------------------------- -Default kernel menu used by **kw**, the default is ``nconfig``. - -alert=[vs | s | v | n] ----------------------- -Default alert options, you have: - -1. v: enables visual notification. - -2. s: enables sound notification. - -3. vs or sv: enables both. - -4. n (or any other option): disables notifications. - -sound_alert_command= ------------------------------ -Command to run for sound completion alert. By default, **kw** uses -``paplay INSTALLPATH/sounds/complete.wav &`` - -visual_alert_command= ------------------------------- -Command to run for visual completion alert. By default, **kw** uses -``notify-send -i checkbox -t 10000 "kw" "Command: \\"$COMMAND\\" completed!"`` - -.. note:: - You may use the *COMMAND* variable, which will be replaced by the kw command - whose conclusion the user wished to be alerted of. - -default_deploy_target ---------------------- -By default, **kw** deploys in the *remote*; however, you can change this -behavior with this variable. The available options are: *local* and *remote*. - -reboot_remote_by_default ------------------------- -Reboot machine after the deploy finishes. - -gui_on= ----------------- -This option is disabled by default, if enabled, it requires a command that -instructs kw to turn on the GUI. - -gui_off= ------------------ -This option is disabled by default, if enabled, it requires a command that -instructs kw to turn off the GUI. - EXAMPLES ======== -For these examples, we suppose the fields in your **kworkflow.config** file is -already configured. +For these examples, we assume that the relevant fields in your configuration +files (located by default in **.kw/**) have already been setup. We recommend +the use of ``kw config`` for managing your local and global configurations. First, if you are working in a specific kernel module, and if you want to install your recent changes in your local machine you can use:: From 328449c949d5a7e71baa4bdec4ca326ebcbc77c1 Mon Sep 17 00:00:00 2001 From: Lincoln Yuji Date: Wed, 1 May 2024 17:18:34 -0300 Subject: [PATCH 083/128] src: maintainers: Handle multi line MODULE_AUTHOR for --authors The previous implementation of print_files_authors only captured and printed authors found in a single line of a MODULE_AUTHOR macro statement. This new modified version allows 'kw m --authors' to also catch and print authors on multiline statements. Closes: #69 Co-authored-by: Luiza Soezima Co-authored-by: Sabrina Araujo Signed-off-by: Lincoln Yuji Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/maintainers.sh | 17 ++++++++-- tests/unit/maintainers_test.sh | 3 +- .../multiline_authors_test.c | 32 +++++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 tests/unit/samples/print_file_author_test_dir/multiline_authors_test.c diff --git a/src/maintainers.sh b/src/maintainers.sh index c69f03354..a7e745c76 100644 --- a/src/maintainers.sh +++ b/src/maintainers.sh @@ -160,9 +160,20 @@ function print_files_authors() local printed_authors_separator=false for file in "${files[@]}"; do - authors=$(grep --only-matching --extended-regexp 'MODULE_AUTHOR *\(.*\)' "$file" | - sed --regexp-extended 's/(MODULE_AUTHOR *\( *\"|\" *\))//g' | - sed --expression ':a' --expression 'N' --expression '$!ba' --expression 's/\n/, /g') + # Match everything inside the parenthesis of `MODULE_AUTHOR ()`, with arbitrary white spaces + # before `(`, while handling multi-line cases. The `\K` escape sequence resets the grep's match, + # that is, it excludes `MODULE_AUTHOR *\(` from the final result + authors=$(grep --null-data --perl-regexp --only-matching 'MODULE_AUTHOR\s*\(\K[^)]*' "$file" | tr --delete '\0') + + # Trim contents from first grep deleting `\n` and `\` with any adjacent white spaces, + # and substitute leading white spaces to a single one. + authors=$(sed --expression 's/\\n//g' --expression 's/\s*\\\s*//g' --expression 's/^\s*/ /g' <<< "$authors") + authors=$(tr --delete '\n' <<< "$authors") + + # Finally, delete string quotes by substituting them to commas to separate the authors, removing + # remaining blank characters at the end of the output. + authors=$(sed --expression 's/\"\s*\"/, /g' --expression 's/\s*\"//g' --expression 's/\s*$//g' <<< "$authors") + if [[ -n "$authors" ]]; then if [[ "$printed_authors_separator" = false ]]; then say "$SEPARATOR" diff --git a/tests/unit/maintainers_test.sh b/tests/unit/maintainers_test.sh index 0f04c8427..888672a1a 100755 --- a/tests/unit/maintainers_test.sh +++ b/tests/unit/maintainers_test.sh @@ -11,7 +11,8 @@ include './tests/unit/utils.sh' CORRECT_DIR_MSG="========================================================= MODULE AUTHORS: code1.c: John Doe , Caesar Doe , Michael Doe -code2.c: Bob Hilson " +code2.c: Bob Hilson +multiline_authors_test.c: Martha Elsa , Verena Bert , Gabi Katinka , Leonie Hildebert " CORRECT_FILE_MSG="========================================================= MODULE AUTHORS: code1.c: John Doe , Caesar Doe , Michael Doe " diff --git a/tests/unit/samples/print_file_author_test_dir/multiline_authors_test.c b/tests/unit/samples/print_file_author_test_dir/multiline_authors_test.c new file mode 100644 index 000000000..4a62100bb --- /dev/null +++ b/tests/unit/samples/print_file_author_test_dir/multiline_authors_test.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * codestyle.c + * + * Copyright (C) 2024 Martha Elsa + * + * This file is used to test the print_files_authors function + * at src/maintainers.sh. + * + */ + +#include + +void ordinary_dummy_function(void) +{ + puts("Just a function..."); +} + +int main(int argc, char *args[]) +{ + int i; + printf("%d\n", argc); + for (i = 0; i < argc; ++i) + printf("%s ", args[i]); + return 0; +} + +MODULE_AUTHOR ( "Martha Elsa " \ + "Verena Bert " ) +ORDINARY_MACRO ( "Does something..." ) +MODULE_AUTHOR ( "Gabi Katinka \n" + "Leonie Hildebert " ) \ No newline at end of file From 1f050b5696bfd4e9aa0b48cf7a6056bf1d44a111 Mon Sep 17 00:00:00 2001 From: sahil-sagwekar2652 Date: Mon, 1 Apr 2024 22:13:24 +0530 Subject: [PATCH 084/128] src: explore: add --show-context flag The idea was to expand kw explore to show extra context after matching a string. This has been achieved by adding a new -C | --show-context flag which accepts an integer argument. The default value for this arg will be 3. The functionality is implemented by using native features of grep and git grep commands, to avoid adding new dependencies. tests: unit: explore_test: Added test cases for --show-context src: bash_autocomplete: Updated bash completions for kw explore src: _kw: updated zsh completions for kw explore documentation: man: features: kw-explore: updated man page and added examples for kw explore Closes: #1052 Signed-off-by: Sahil Sagwekar Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- documentation/man/features/kw-explore.rst | 20 +++++- src/_kw | 1 + src/bash_autocomplete.sh | 2 +- src/explore.sh | 49 +++++++++---- tests/unit/explore_test.sh | 87 +++++++++++++++++++++-- 5 files changed, 139 insertions(+), 20 deletions(-) diff --git a/documentation/man/features/kw-explore.rst b/documentation/man/features/kw-explore.rst index 5138c3bce..0f5a28aa6 100644 --- a/documentation/man/features/kw-explore.rst +++ b/documentation/man/features/kw-explore.rst @@ -7,7 +7,7 @@ kw-explore - Explore folder SYNOPSIS ======== *kw* (*e* | *explore*) [(-l | \--log) | (-g | \--grep) | (-a | \--all) | \--verbose] - [(-c | \--only-source) | (-H | \--only-header)] + [(-c | \--only-source) | (-H | \--only-header)] [(-C[] | \--show-context[=])] [-p] [ | ] DESCRIPTION @@ -45,5 +45,23 @@ OPTIONS -H | \--only-header: With this option, it is possible to show only the results from the header. +-C[] | \--show-context[=]: + Show lines of additional context above and below the matched line. + If is not specified, the default value of 3 will be used. + \--verbose: Verbose mode allows the user to see the commands executed under the hood. + +EXAMPLES +======== +To show matched line with context using long-form flag:: + + kw explore --show-context=5 search_string + +To show matched line with context using short flag:: + + kw explore -C5 search_string + +Search through all tracked and untracked files, default value of 3 will be used for context:: + + kw explore -C --all search_string diff --git a/src/_kw b/src/_kw index e5079cedb..c6caf4420 100644 --- a/src/_kw +++ b/src/_kw @@ -282,6 +282,7 @@ _kw_explore() '(-a --all -l --log -g --grep)'{-a,--all}'[search for all matches in files under or not git management]' \ '(-c --only-source -H --only-header)'{-c,--only-source}'[show only results from the source]' \ '(-H --only-header -c --only-source)'{-H,--only-header}'[show only results from the header]' \ + '(-C --show-context)'{-C-,--show-context=-}'[set the context value]' \ '1: : ' \ '2: :_files' } diff --git a/src/bash_autocomplete.sh b/src/bash_autocomplete.sh index 4fb435e81..1159b8ccd 100644 --- a/src/bash_autocomplete.sh +++ b/src/bash_autocomplete.sh @@ -53,7 +53,7 @@ function _kw_autocomplete() kw_options['remote']='--add --remove --rename --list --global --set-default --verbose' - kw_options['explore']='--log --grep --all --only-header --only-source --exactly --verbose' + kw_options['explore']='--log --grep --all --only-header --only-source --exactly --show-context --verbose' kw_options['e']="${kw_options['explore']}" kw_options['pomodoro']='--set-timer --check-timer --show-tags --tag --description --help --verbose' diff --git a/src/explore.sh b/src/explore.sh index c1f88f604..c69c2d751 100644 --- a/src/explore.sh +++ b/src/explore.sh @@ -15,6 +15,7 @@ function explore_main() local flag local search local path + local context local ret if [[ "$1" =~ -h|--help ]]; then @@ -31,6 +32,7 @@ function explore_main() flag="${options_values['TEST_MODE']:-'SILENT'}" search="${options_values['SEARCH']}" path="${options_values['PATH']:-'.'}" + context="${options_values['CONTEXT']:-0}" [[ -n "${options_values['VERBOSE']}" ]] && flag='VERBOSE' @@ -48,19 +50,19 @@ function explore_main() if [[ "${options_values['TYPE']}" -eq 2 ]]; then # Use GNU GREP - explore_files_gnu_grep "$search" "$path" "$flag" + explore_files_gnu_grep "$search" "$path" "$context" "$flag" return fi if [[ "${options_values['TYPE']}" -eq 3 ]]; then # Search in directories controlled or not by git - explore_all_files_git "$search" "$path" "$flag" + explore_all_files_git "$search" "$path" "$context" "$flag" return fi if [[ -z "${options_values['TYPE']}" ]]; then # Search in files under git control - explore_files_under_git "$search" "$path" "$flag" + explore_files_under_git "$search" "$path" "$context" "$flag" return fi } @@ -75,8 +77,8 @@ function explore_main() # This function also set options_values function parse_explore_options() { - local long_options='log,grep,all,only-header,only-source,exactly,verbose' - local short_options='l,g,a,H,c' + local long_options='log,grep,all,only-header,only-source,exactly,verbose,show-context::' + local short_options='l,g,a,H,c,C::' local options if [[ "$#" -eq 0 ]]; then @@ -97,6 +99,7 @@ function parse_explore_options() options_values['TYPE']='' options_values['SCOPE']='' options_values['EXACTLY']='' + options_values['CONTEXT']='' options_values['VERBOSE']='' eval "set -- $options" @@ -158,6 +161,24 @@ function parse_explore_options() ;; --verbose) options_values['VERBOSE']=1 + shift + ;; + --show-context | -C) + if [[ -n "${options_values['CONTEXT']}" ]]; then + options_values['ERROR']='Invalid arguments: Multiple context values!' + return 22 # EINVAL + fi + + if [[ ! "$2" ]]; then + options_values['CONTEXT']=3 + elif [[ ! "$2" =~ ^[0-9]+$ ]]; then + options_values['ERROR']='Context value must be a non-negative integer!' + return 22 # EINVAL + else + options_values['CONTEXT']="$2" + shift + fi + shift ;; --) # End of options, beginning of arguments @@ -196,7 +217,7 @@ function explore_git_log() flag=${flag:-'SILENT'} - cmd_manager "$flag" "git log --grep='$search_string' $path" + cmd_manager "$flag" "git log --grep='${search_string}' ${path}" } # This function searches string in files under git control. @@ -209,11 +230,12 @@ function explore_files_under_git() { local regex="$1" local path="$2" - local flag="$3" + local context="$3" + local flag="$4" flag=${flag:-'SILENT'} - cmd_manager "$flag" "git grep -e '$regex' -nI $path" + cmd_manager "$flag" "git grep --context ${context} -e '${regex}' --line-number -I ${path}" } # This function uses git grep tool to search string in files under or not git @@ -228,11 +250,12 @@ function explore_all_files_git() { local regex="$1" local path="$2" - local flag="$3" + local context="$3" + local flag="$4" flag=${flag:-'SILENT'} - cmd_manager "$flag" "git grep --no-index -e '$regex' -nI $path" + cmd_manager "$flag" "git grep --no-index --context ${context} -e '${regex}' --line-number -I ${path}" } # This function allows the use of gnu grep utility to manages the search for @@ -246,11 +269,12 @@ function explore_files_gnu_grep() { local regex="$1" local path="$2" - local flag="$3" + local context="$3" + local flag="$4" flag=${flag:-'SILENT'} - cmd_manager "$flag" "grep --color -nrI $path -e '$regex'" + cmd_manager "$flag" "grep --color --line-number --recursive -I ${path} --context ${context} -e '${regex}'" } function explore_help() @@ -267,5 +291,6 @@ function explore_help() ' explore,e --all,-a - Search for all match under or not of git management' \ ' explore,e --only-source,-c - Search for all in source files' \ ' explore,e --only-header,-H - Search for all in header files' \ + ' explore,e --show-context[=],-C[] - Print lines of output context (default: 3)' \ ' explore,e --verbose - Show a detailed output' } diff --git a/tests/unit/explore_test.sh b/tests/unit/explore_test.sh index 298fdf574..1f3555ec9 100755 --- a/tests/unit/explore_test.sh +++ b/tests/unit/explore_test.sh @@ -67,9 +67,14 @@ function test_explore_files_under_git_repo() assertEquals "($LINENO)" "$MSG_OUT" "$output" output=$(explore_main 'GNU grep' '.' 'TEST_MODE') - expected_result="git grep -e 'GNU grep' -nI ." + expected_result="git grep --context 0 -e 'GNU grep' --line-number -I ." assertEquals "($LINENO)" "$expected_result" "$output" + # Test for non zero context value + output=$(explore_main --show-context=5 'GNU grep' '.' 'TEST_MODE') + expected_result="git grep --context 5 -e 'GNU grep' --line-number -I ." + assertEquals "(${LINENO})" "$expected_result" "$output" + # Test if search only in files under git control cp "$current_path/tests/unit/samples/grep_check.c" ./ MSG_OUT='GNU grep' @@ -82,13 +87,13 @@ function test_explore_files_under_git_repo() # Test only-source and only-header MSG_OUT='3' - output=$(explore_main 'camelCase' | wc -l) + output=$(explore_main 'camelCase' | wc --lines) assertEquals "($LINENO)" "$MSG_OUT" "$output" MSG_OUT='2' - output=$(explore_main -c 'camelCase' | wc -l) + output=$(explore_main -c 'camelCase' | wc --lines) assertEquals "($LINENO)" "$MSG_OUT" "$output" MSG_OUT='1' - output=$(explore_main -H 'camelCase' | wc -l) + output=$(explore_main -H 'camelCase' | wc --lines) assertEquals "($LINENO)" "$MSG_OUT" "$output" cd "$current_path" || { @@ -133,7 +138,11 @@ function test_explore_grep() assertEquals "($LINENO)" '.git' "$output" output=$(explore_main --grep 'GNU grep' '.' 'TEST_MODE') - expected_result="grep --color -nrI . -e 'GNU grep'" + expected_result="grep --color --line-number --recursive -I . --context 0 -e 'GNU grep'" + assertEquals "(${LINENO})" "$expected_result" "$output" + + output=$(explore_main --grep --show-context=5 'GNU grep' '.' 'TEST_MODE') + expected_result="grep --color --line-number --recursive -I . --context 5 -e 'GNU grep'" assertEquals "($LINENO)" "$expected_result" "$output" cd "$current_path" || { @@ -153,7 +162,11 @@ function test_explore_git() } output=$(explore_main --all 'GNU grep' '.' 'TEST_MODE') - expected_result="git grep --no-index -e 'GNU grep' -nI ." + expected_result="git grep --no-index --context 0 -e 'GNU grep' --line-number -I ." + assertEquals "(${LINENO})" "$expected_result" "$output" + + output=$(explore_main --all --show-context=5 'GNU grep' '.' 'TEST_MODE') + expected_result="git grep --no-index --context 5 -e 'GNU grep' --line-number -I ." assertEquals "($LINENO)" "$expected_result" "$output" # Test if the search ignores files in .git @@ -172,6 +185,47 @@ function test_explore_git() } } +function test_explore_context() +{ + local -r current_path="$PWD" + local expected_context='3' + local expected_match='avoid' + local msg_out='7' + + cd "$SHUNIT_TMPDIR" || { + fail "(${LINENO}) It was not possible to move to temporary directory" + return + } + + # Check the number of output lines + output=$(explore_main --show-context=3 'avoid' codestyle_error.c | wc --lines) + assertEquals "(${LINENO})" "$msg_out" "$output" + + output=$(explore_main --show-context="$expected_context" "$expected_match" codestyle_error.c) + + # Check if the expected match and context lines are present in the output + assert_substring_match 'Expected match not found!' "${LINENO}" "${expected_match}" "$output" + + # Check context lines below the match + for ((i = 1; i <= expected_context; i++)); do + CONTEXT_LINE=$((i + 4)) # Assuming match is on line 4 + CONTEXT_LINE_CONTENT=$(printf '%s' "$output" | head -n "${CONTEXT_LINE}" | tail --lines 1) + assert_line_match "Context line ${CONTEXT_LINE} below match" "$CONTEXT_LINE_CONTENT" "$output" + done + + # Check context lines above the match + for ((i = 1; i <= expected_context; i++)); do + CONTEXT_LINE=$((4 - i)) # Assuming match is on line 4 + CONTEXT_LINE_CONTENT=$(printf '%s' "$output" | head -n ${CONTEXT_LINE} | tail -n 1) + assert_line_match "Context line ${CONTEXT_LINE} above match" "$CONTEXT_LINE_CONTENT" "$output" + done + + cd "$current_path" || { + fail "(${LINENO}) It was not possible to move back from temp directory" + return + } +} + function test_parse_explore_options() { # Expected behaviour @@ -236,6 +290,20 @@ function test_parse_explore_options() assertEquals "($LINENO)" '0' "$ret" assertEquals "($LINENO)" 'HEADER' "${options_values['SCOPE']}" + unset options_values + declare -gA options_values + parse_explore_options -C + ret="$?" + assertEquals "(${LINENO})" '0' "$ret" + assertEquals "(${LINENO})" '3' "${options_values['CONTEXT']}" + + unset options_values + declare -gA options_values + parse_explore_options --show-context=5 + ret="$?" + assertEquals "(${LINENO})" '0' "$ret" + assertEquals "(${LINENO})" '5' "${options_values['CONTEXT']}" + # Others parse_explore_options --logljkl ret="$?" @@ -266,6 +334,13 @@ function test_parse_explore_options() assertEquals "($LINENO)" '22' "$ret" assertEquals "($LINENO)" 'Invalid arguments: Multiple search type!' "${options_values['ERROR']}" + unset options_values + declare -gA options_values + parse_explore_options --show-context=invalid + ret="$?" + assertEquals "($LINENO)" '22' "$ret" + assertEquals "($LINENO)" 'Context value must be a non-negative integer!' "${options_values['ERROR']}" + parse_explore_options main ret="$?" assertEquals "($LINENO)" '0' "$ret" From 0ef682cf6d53106f3ce2a23e42299f361f6e95bc Mon Sep 17 00:00:00 2001 From: Fernando Yang Date: Thu, 9 May 2024 13:59:05 -0300 Subject: [PATCH 085/128] src: plugins: kernel_install: utils: clean shellcheck warning SC2294 Substitute @ to * to explicitly join the elements on spaces. Reviewed-by: David Tadokoro Signed-off-by: Fernando Yang Signed-off-by: Eduardo Figueredo Signed-off-by: David Tadokoro --- src/plugins/kernel_install/utils.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/kernel_install/utils.sh b/src/plugins/kernel_install/utils.sh index adcff66e9..f773d872c 100644 --- a/src/plugins/kernel_install/utils.sh +++ b/src/plugins/kernel_install/utils.sh @@ -40,7 +40,7 @@ function cmd_manager() ;; esac - eval "$@" + eval "$*" } function command_exists() From 597e5672f75b998d3c17cd35df373361cd1f8701 Mon Sep 17 00:00:00 2001 From: Fernando Yang Date: Wed, 8 May 2024 10:09:15 -0300 Subject: [PATCH 086/128] src: plugins: kernel_install: utils: clean coding style violations Replace short options with long options, which are more readable. Replace echo with printf, which is more consistent across multiple platforms than echo. Note: The maintainance of cat instead of using Bash redirects (which is the correct way considering the project coding style) is because redirects don't support glob expansions, so using it instead of cat would actually make the code more complex, and, possibly, less performatic in the end. Reviewed-by: David Tadokoro Signed-off-by: Fernando Yang Signed-off-by: Eduardo Figueredo Signed-off-by: David Tadokoro --- src/plugins/kernel_install/utils.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/kernel_install/utils.sh b/src/plugins/kernel_install/utils.sh index f773d872c..c59e06254 100644 --- a/src/plugins/kernel_install/utils.sh +++ b/src/plugins/kernel_install/utils.sh @@ -197,7 +197,8 @@ function collect_deploy_info() bootloader="[bootloader]=$bootloader" # Get distro - distro=$(cat /etc/*-release | grep -w 'ID\(_LIKE\)\?' | cut -d = -f 2 | xargs echo) + distro=$(cat /etc/*-release | grep --word-regexp 'ID\(_LIKE\)\?' | cut --delimiter = --fields 2 | xargs printf '%s ') + distro="${distro::-1}" distro="[distro]='$distro'" # Build associative array data From e1107bf61e9fff5ae52243ec2d0dc07386a1ea6c Mon Sep 17 00:00:00 2001 From: Felipe Anibal Date: Tue, 14 May 2024 14:38:08 -0300 Subject: [PATCH 087/128] src: plugins: subsystems: drm: update code style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update code style to match kw patterns. Signed-off-by: Felipe Anibal Signed-off-by: OtĆ”vio Silva Reviewed-off-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- src/plugins/subsystems/drm/drm.sh | 66 +++++++++++++++---------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/plugins/subsystems/drm/drm.sh b/src/plugins/subsystems/drm/drm.sh index bf4c9c9f1..68c003e07 100644 --- a/src/plugins/subsystems/drm/drm.sh +++ b/src/plugins/subsystems/drm/drm.sh @@ -1,6 +1,6 @@ -. "${KW_LIB_DIR}/lib/kw_config_loader.sh" --source-only -. "${KW_LIB_DIR}/lib/remote.sh" --source-only -. "${KW_LIB_DIR}/lib/kwlib.sh" --source-only +include "${KW_LIB_DIR}/lib/kw_config_loader.sh" +include "${KW_LIB_DIR}/lib/remote.sh" +include "${KW_LIB_DIR}/lib/kwlib.sh" declare -gr UNLOAD='UNLOAD' declare -gA options_values @@ -26,9 +26,9 @@ function drm_main() parse_drm_options "$@" if [[ "$?" -gt 0 ]]; then - complain "Invalid option: ${options_values['ERROR']} $target $gui_on $gui_off ${remote_parameters['REMOTE_IP']} ${remote_parameters['REMOTE_PORT']}" + complain "Invalid option: ${options_values['ERROR']} ${target} ${gui_on} ${gui_off} ${remote_parameters['REMOTE_IP']} ${remote_parameters['REMOTE_PORT']}" drm_help - return 22 + return 22 # EINVAL fi target="${options_values['TARGET']}" @@ -56,7 +56,7 @@ function drm_main() if [[ -n "$load_module" ]]; then module_control 'LOAD' "$target" "$remote" "$load_module" "$flag" if [[ "$?" != 0 ]]; then - return 22 + return 22 # EINVAL fi fi @@ -100,7 +100,7 @@ function module_control() local unformatted_remote="$3" local parameters="$4" local flag="$5" - local module_cmd="" + local module_cmd='' local remote local port @@ -109,12 +109,12 @@ function module_control() module_cmd=$(convert_module_info "$operation" "$parameters") if [[ "$?" != 0 ]]; then complain 'Wrong parameter in --[un]load-module=' - return 22 + return 22 # EINVAL fi case "$target" in 2) # LOCAL - cmd_manager "$flag" "sudo bash -c \"$module_cmd\"" + cmd_manager "$flag" "sudo bash -c \"${module_cmd}\"" ;; 3) # REMOTE remote=$(get_based_on_delimiter "$unformatted_remote" ':' 1) @@ -138,10 +138,10 @@ function convert_module_info() local unload="$1" shift local raw_modules_str="$*" - local parameters_str="" - local final_command="" - local remove_flag="" - local module_str="" + local parameters_str='' + local final_command='' + local remove_flag='' + local module_str='' local first_time=1 if [[ "$unload" == "$UNLOAD" ]]; then @@ -154,21 +154,21 @@ function convert_module_info() # Target event. e.g.: amdgpu_dm or amdgpu for module in "${modules[@]}"; do parameters_str='' - module_str="modprobe $remove_flag $module" + module_str="modprobe ${remove_flag} ${module}" if [[ "$module" =~ .*':'.* ]]; then - module_str="modprobe $remove_flag " - module_str+=$(cut -d ':' -f1 <<< "$module") + module_str="modprobe ${remove_flag} " + module_str+=$(cut --delimiter=':' --fields=1 <<< "$module") if [[ "$unload" != "$UNLOAD" ]]; then # Capture module parameters - specific_parameters_str=$(cut -d ':' -f2 <<< "$module") + specific_parameters_str=$(cut --delimiter=':' --fields=2 <<< "$module") IFS=',' read -r -a parameters_array <<< "$specific_parameters_str" for specific_parameter in "${parameters_array[@]}"; do parameters_str+="$specific_parameter " done - module_str+=" $parameters_str" + module_str+=" ${parameters_str}" fi fi @@ -177,7 +177,7 @@ function convert_module_info() first_time=0 continue fi - final_command+=" && $module_str" + final_command+=" && ${module_str}" done if [[ -z "$final_command" ]]; then @@ -264,26 +264,26 @@ function get_available_connectors() case "$target" in 2) # LOCAL TARGET - cards_raw_list=$(find "$SYSFS_CLASS_DRM" -name 'card*' | sort -d) + cards_raw_list=$(find "$SYSFS_CLASS_DRM" -name 'card*' | sort --dictionary-order) if [[ -f "$SYSFS_CLASS_DRM" ]]; then ret="$?" - complain "We cannot access $SYSFS_CLASS_DRM" + complain "We cannot access ${SYSFS_CLASS_DRM}" return "$ret" # ENOENT fi target_label='local' ;; 3) # REMOTE TARGET - find_conn_cmd="find $SYSFS_CLASS_DRM -name 'card*'" + find_conn_cmd="find ${SYSFS_CLASS_DRM} -name 'card*'" - cards_raw_list=$(cmd_remotely "$find_conn_cmd" "$flag" | sort -d) + cards_raw_list=$(cmd_remotely "$find_conn_cmd" "$flag" | sort --dictionary-order) target_label='remote' ;; esac while read -r card; do card=$(basename "$card") - key=$(printf '%s\n' "$card" | grep card | cut -d- -f1) - value=$(printf '%s\n' "$card" | grep card | cut -d- -f2) + key=$(printf '%s\n' "$card" | grep card | cut --delimiter='-' --fields=1) + value=$(printf '%s\n' "$card" | grep card | cut --delimiter='-' --fields=2) [[ "$key" == "$value" ]] && continue if [[ -n "$key" && -n "$value" ]]; then @@ -292,18 +292,18 @@ function get_available_connectors() cards["$key"]="$value" continue fi - cards["$key"]="$list_of_values,$value" + cards["$key"]="${list_of_values},${value}" fi done <<< "$cards_raw_list" for card in "${!cards[@]}"; do connectors="${cards[$card]}" - printf '%s\n' "[$target_label] ${card^} supports:" + printf '%s\n' "[${target_label}] ${card^} supports:" IFS=',' read -r -a connectors <<< "${cards[$card]}" for conn in "${connectors[@]}"; do - printf '%s\n' " $conn" + printf '%s\n' " ${conn}" done done @@ -324,13 +324,13 @@ function get_supported_mode_per_connector() flag=${flag:-'SILENT'} - cmd="for f in $SYSFS_CLASS_DRM/*/modes;"' do c=$(< $f) && [[ ! -z $c ]] && printf "%s\n" "$f:" "$c" ""; done' + cmd="for f in ${SYSFS_CLASS_DRM}/*/modes;"' do c=$(< $f) && [[ ! -z $c ]] && printf "%s\n" "$f:" "$c" ""; done' case "$target" in 2) # LOCAL TARGET if [[ -f "$SYSFS_CLASS_DRM" ]]; then ret="$?" - complain "We cannot access $SYSFS_CLASS_DRM" + complain "We cannot access ${SYSFS_CLASS_DRM}" return "$ret" # ENOENT fi modes=$(eval "$cmd") @@ -395,14 +395,14 @@ function parse_drm_options() options_values['TARGET']="$LOCAL_TARGET" fi - eval "set -- $options" + eval "set -- ${options}" while [[ "$#" -gt 0 ]]; do case "$1" in --remote) populate_remote_info "$2" if [[ "$?" == 22 ]]; then options_values['ERROR']="$option" - return 22 + return 22 # EINVAL fi options_values['TARGET']="$REMOTE_TARGET" shift 2 @@ -471,7 +471,7 @@ function parse_drm_options() function drm_help() { if [[ "$1" =~ --help ]]; then - include "$KW_LIB_DIR/help.sh" + include "${KW_LIB_DIR}/help.sh" kworkflow_man 'drm' return fi From 3f68a797884be7636cc8561db30d5f6a235898bb Mon Sep 17 00:00:00 2001 From: Felipe Anibal Date: Mon, 20 May 2024 15:37:43 -0300 Subject: [PATCH 088/128] src: plugins: subsystems: drm: check enabled connector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make "kw drm --conn-available" more informative, marking enabled connectors with an '*'. Do this by checking the "/sys/class/drm//enabled" file. Closes #1096 documentation: update kw drm --conn-available option description tests: update tests for kw drm --conn-available Signed-off-by: Felipe Anibal Signed-off-by: OtĆ”vio Silva Reviewed-off-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira --- documentation/man/features/kw-drm.rst | 3 ++- src/plugins/subsystems/drm/drm.sh | 21 +++++++++++++------ tests/unit/drm_plugin_test.sh | 30 +++++++++++++++------------ 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/documentation/man/features/kw-drm.rst b/documentation/man/features/kw-drm.rst index ac16eaf3d..4916c10e6 100644 --- a/documentation/man/features/kw-drm.rst +++ b/documentation/man/features/kw-drm.rst @@ -56,7 +56,8 @@ OPTIONS a specific command in the **kworkflow.config** file with the specific command. \--conn-available: - Show all connectors available in the target machine. + Show all connectors available in the target machine. The ones marked with '*' + are enabled. \--modes: Show all available modes per card. diff --git a/src/plugins/subsystems/drm/drm.sh b/src/plugins/subsystems/drm/drm.sh index 68c003e07..ed9bf83eb 100644 --- a/src/plugins/subsystems/drm/drm.sh +++ b/src/plugins/subsystems/drm/drm.sh @@ -258,13 +258,17 @@ function get_available_connectors() local remote local port local find_conn_cmd + local connector_enabled declare -A cards flag=${flag:-'SILENT'} + # command to find all cards and for each of them append if it is enabled or not + find_conn_cmd="find ${SYSFS_CLASS_DRM} -name 'card*-*' -exec printf '%s,' {} \; -exec cat {}/enabled \; -exec printf '\n' \;" + case "$target" in 2) # LOCAL TARGET - cards_raw_list=$(find "$SYSFS_CLASS_DRM" -name 'card*' | sort --dictionary-order) + cards_raw_list=$(cmd_manager 'SILENT' "$find_conn_cmd" | sort --dictionary-order) if [[ -f "$SYSFS_CLASS_DRM" ]]; then ret="$?" complain "We cannot access ${SYSFS_CLASS_DRM}" @@ -273,21 +277,26 @@ function get_available_connectors() target_label='local' ;; 3) # REMOTE TARGET - find_conn_cmd="find ${SYSFS_CLASS_DRM} -name 'card*'" - cards_raw_list=$(cmd_remotely "$find_conn_cmd" "$flag" | sort --dictionary-order) target_label='remote' ;; esac - while read -r card; do - card=$(basename "$card") + while read -r card_info; do + card_path=$(printf '%s' "$card_info" | cut --delimiter=',' --fields=1) + connector_enabled=$(printf '%s' "$card_info" | cut --delimiter=',' --fields=2) + card=$(basename "$card_path") key=$(printf '%s\n' "$card" | grep card | cut --delimiter='-' --fields=1) - value=$(printf '%s\n' "$card" | grep card | cut --delimiter='-' --fields=2) + value=$(printf '%s\n' "$card" | grep card | cut --delimiter='-' --fields=2-) [[ "$key" == "$value" ]] && continue if [[ -n "$key" && -n "$value" ]]; then list_of_values="${cards[$key]}" + + if [[ "$connector_enabled" == 'enabled' ]]; then + value="${value} *" + fi + if [[ -z "$list_of_values" ]]; then cards["$key"]="$value" continue diff --git a/tests/unit/drm_plugin_test.sh b/tests/unit/drm_plugin_test.sh index 1bc583fbe..4ae5241cb 100755 --- a/tests/unit/drm_plugin_test.sh +++ b/tests/unit/drm_plugin_test.sh @@ -63,10 +63,13 @@ function mk_fake_sys_class_drm() for dir in "${fake_dirs[@]}"; do mkdir -p "${FAKE_DRM_SYSFS}/${dir}" + printf disabled > "${FAKE_DRM_SYSFS}/${dir}/enabled" done touch "${FAKE_DRM_SYSFS}/version" touch "${FAKE_DRM_SYSFS}/card0-DP-3/modes" + printf enabled > "${FAKE_DRM_SYSFS}/card0-DVI-D-1/enabled" + printf enabled > "${FAKE_DRM_SYSFS}/card1-HDMI-A-2/enabled" cat << END >> "${FAKE_DRM_SYSFS}/card0-DP-3/modes" 1920x2160 @@ -259,16 +262,16 @@ function test_get_available_connectors_local() declare -a expected_output=( '[local] Card1 supports:' - 'DP' - 'DP' - 'DP' - 'HDMI' + 'DP-4' + 'DP-5' + 'DP-6' + 'HDMI-A-2 *' '[local] Card0 supports:' - 'DP' - 'DP' - 'DP' - 'DVI' - 'HDMI' + 'DP-1' + 'DP-2' + 'DP-3' + 'DVI-D-1 *' + 'HDMI-A-1' ) # Local @@ -276,6 +279,7 @@ function test_get_available_connectors_local() compare_command_sequence '' "$LINENO" 'expected_output' "$output" } +# shellcheck disable=SC2317 # Disable shellchek warning about unreachable commands in this function function test_get_available_connectors_remote() { local output @@ -284,16 +288,16 @@ function test_get_available_connectors_remote() output=$( function cmd_remotely() { - printf '/sys/class/drm/card0-%s-1\n' 'DP' - printf '/sys/class/drm/card0-%s-1\n' 'eDP' + printf '/sys/class/drm/card0-%s,enabled\n' 'DP-1' + printf '/sys/class/drm/card0-%s,disabled\n' 'eDP-1' } get_available_connectors '3' '' 'TEST_MODE' ) declare -a expected_output=( '[remote] Card0 supports:' - 'DP' - 'eDP' + 'DP-1 *' + 'eDP-1' ) compare_command_sequence '' "$LINENO" 'expected_output' "$output" } From 07136e35f76aede5b2147579d1ebdc7da5e8aa59 Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Fri, 24 May 2024 12:35:13 -0300 Subject: [PATCH 089/128] setup: refactor check_dependencies function This commit refactors the check_dependencies function by extracting missing package detection into get_missing_packages, package installation into install_packages, updating check_dependencies to use these new functions, and adding function documentation. Reviewed-by: David Tadokoro Signed-off-by: Aquila Macedo Signed-off-by: David Tadokoro --- setup.sh | 104 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 29 deletions(-) diff --git a/setup.sh b/setup.sh index 39910328a..111010a51 100755 --- a/setup.sh +++ b/setup.sh @@ -51,39 +51,91 @@ declare -r CONFIGS_PATH='configs' declare -r DOCS_VIRTUAL_ENV='docs_virtual_env' -function check_dependencies() +# This function identifies the missing packages required by the distribution. +# +# @distro: The distribution name (arch, debian, fedora, etc.) +# @deps_file: The path to the dependencies file for the distribution. +# +# Returns: +# Outputs a space-separated string with the missing packages. +function get_missing_packages() { - local package_list='' - local cmd='' - local distro - local ret - - distro=$(detect_distro '/') + local distro="$1" + local deps_file="$2" + local package_list + local installed if [[ "$distro" =~ 'arch' ]]; then while IFS='' read -r package; do - installed=$(pacman -Ql "$package" &> /dev/null) - [[ "$?" != 0 ]] && package_list="$package $package_list" - done < "$DOCUMENTATION/dependencies/arch.dependencies" - cmd="pacman -Sy --noconfirm ${package_list}" + pacman -Ql "$package" &> /dev/null + [[ "$?" != 0 ]] && package_list="${package} ${package_list}" + done < "$deps_file" elif [[ "$distro" =~ 'debian' ]]; then while IFS='' read -r package; do installed=$(dpkg-query -W --showformat='${Status}\n' "$package" 2> /dev/null | grep -c 'ok installed') - [[ "$installed" -eq 0 ]] && package_list="$package $package_list" - done < "$DOCUMENTATION/dependencies/debian.dependencies" - cmd="apt install -y $package_list" + [[ "$installed" -eq 0 ]] && package_list="${package} ${package_list}" + done < "$deps_file" elif [[ "$distro" =~ 'fedora' ]]; then while IFS='' read -r package; do - installed=$(rpm -q "$package" &> /dev/null) - [[ "$?" -ne 0 ]] && package_list="$package $package_list" - done < "$DOCUMENTATION/dependencies/fedora.dependencies" - cmd="dnf install -y $package_list" + rpm -q "$package" &> /dev/null + [[ "$?" -ne 0 ]] && package_list="${package} ${package_list}" + done < "$deps_file" + fi + + printf '%s\n' "$package_list" +} + +# This function installs the given packages. +# +# @cmd: The installation command with the packages to be installed. +# +# Returns: +# The return status of the installation command. +function install_packages() +{ + local cmd="$1" + + if [[ "$EUID" -eq 0 ]]; then + eval "$cmd" else - warning 'Unfortunately, we do not have official support for your distro (yet)' - warning 'Please, try to find the following packages:' - warning "$(cat "$DOCUMENTATION/dependencies/arch.dependencies")" - return 0 + eval "sudo ${cmd}" fi +} + +# This function checks and installs the necessary dependencies for the current +# distribution. +# +# Returns: +# Returns 0 if all dependencies are already installed or installation is +# successful. +function check_dependencies() +{ + local package_list + local cmd + local distro + local ret + + distro=$(detect_distro '/') + + package_list=$(get_missing_packages "$distro" "${DOCUMENTATION}/dependencies/${distro}.dependencies") + + case "$distro" in + arch*) + cmd="pacman -Sy --noconfirm ${package_list}" + ;; + debian*) + cmd="apt install -y ${package_list}" + ;; + fedora*) + cmd="dnf install -y ${package_list}" + ;; + *) + warning 'Unfortunately, we do not have official support for your distro (yet)' + warning 'Please, try to find the following packages:' + warning "$(cat "${DOCUMENTATION}/dependencies/arch.dependencies")" + return 0 + ;; + esac if [[ -n "$package_list" ]]; then if [[ "$FORCE" == 0 ]]; then @@ -93,12 +145,7 @@ function check_dependencies() fi fi - # Install system packages - if [[ "$EUID" -eq 0 ]]; then - eval "$cmd" - else - eval "sudo $cmd" - fi + install_packages "$cmd" ret="$?" # Installation failed... @@ -106,7 +153,6 @@ function check_dependencies() complain '[ERROR] Dependencies installation has failed. Aborting kw installation...' exit "$ret" fi - fi } From eca6482da2356713c6434f08c6e746736a7e754a Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Tue, 7 May 2024 20:06:10 -0300 Subject: [PATCH 090/128] setup: introduce option to install kernel build dependencies This update simplifies the process of installing necessary kernel build dependencies, tailored to the distribution, by adding a new option `--install-kernel-dev-deps`, which install all the dependencies necessaries for this process. Reviewed-by: David Tadokoro Signed-off-by: Aquila Macedo Signed-off-by: David Tadokoro --- .../kernel_build/arch.dependencies | 17 +++ .../kernel_build/debian.dependencies | 20 ++++ .../kernel_build/fedora.dependencies | 12 ++ setup.sh | 105 ++++++++++++++++-- 4 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 documentation/dependencies/kernel_build/arch.dependencies create mode 100644 documentation/dependencies/kernel_build/debian.dependencies create mode 100644 documentation/dependencies/kernel_build/fedora.dependencies diff --git a/documentation/dependencies/kernel_build/arch.dependencies b/documentation/dependencies/kernel_build/arch.dependencies new file mode 100644 index 000000000..9bbd5ff01 --- /dev/null +++ b/documentation/dependencies/kernel_build/arch.dependencies @@ -0,0 +1,17 @@ +make +base-devel +linux-headers +bison +flex +openssl +ncurses +pahole +xmlto +kmod +inetutils +bc +libelf +cpio +perl +tar +xz diff --git a/documentation/dependencies/kernel_build/debian.dependencies b/documentation/dependencies/kernel_build/debian.dependencies new file mode 100644 index 000000000..5389331a8 --- /dev/null +++ b/documentation/dependencies/kernel_build/debian.dependencies @@ -0,0 +1,20 @@ +libncurses-dev +gawk +flex +bison +openssl +libssl-dev +dkms +libelf-dev +libudev-dev +libpci-dev +libiberty-dev +autoconf +llvm +exuberant-ctags +build-essential +xmlto +kmod +dwarves +clang +lld diff --git a/documentation/dependencies/kernel_build/fedora.dependencies b/documentation/dependencies/kernel_build/fedora.dependencies new file mode 100644 index 000000000..4b93e530d --- /dev/null +++ b/documentation/dependencies/kernel_build/fedora.dependencies @@ -0,0 +1,12 @@ +qt3-devel +libXi-devel +diffutils +gcc-c++ +ncurses-devel +bison +flex +openssl-devel +elfutils-libelf-devel +openssl +dwarves +llvm diff --git a/setup.sh b/setup.sh index 111010a51..641831016 100755 --- a/setup.sh +++ b/setup.sh @@ -156,6 +156,87 @@ function check_dependencies() fi } +# This function checks and installs kernel build dependencies, i.e., +# dependencies that are necessary to build a Linux kernel. It supports three +# Linux distributions: Debian, Arch Linux, and Fedora. +# +# @distro: Detect the current distribution. +# +# Returns: +# Returns 0 if all necessary dependencies are already installed or installation +# is successful. and returns 22 (EINVAL), in case `@distro` is an unsupported +# OS type. The function can also exit the execution with 125 (ECANCELED) in case +# the user opts to abort the installation. +function check_and_install_kernel_build_dependencies() +{ + local distro="$1" + local kernel_build_deps_file + local package_list + local cmd + + kernel_build_deps_file="${DOCUMENTATION}/dependencies/kernel_build/${distro}.dependencies" + + package_list=$(get_missing_packages "$distro" "$kernel_build_deps_file") + + case "$distro" in + arch*) + cmd="pacman -Sy --noconfirm ${package_list}" + ;; + debian*) + cmd="apt install -y ${package_list}" + ;; + fedora*) + cmd="dnf install -y ${package_list}" + ;; + *) + complain "Unsupported OS type: ${distro}" + return 22 # EINVAL + ;; + esac + + if [[ -z "$package_list" ]]; then + warning 'All necessary kernel build dependencies are already installed.' + return 0 + fi + + if [[ -n "$package_list" ]]; then + if [[ "$FORCE" == 0 ]]; then + if [[ $(ask_yN "The following packages are required to build the kernel: ${package_list}"$'\nMay we install them?') =~ '0' ]]; then + complain 'Aborting installation. Kernel build dependencies not installed.' + exit 125 # ECANCELED + fi + fi + + install_packages "$cmd" + + # Installation failed... + if [[ "$?" -ne 0 ]]; then + complain '[ERROR] Dependencies installation to build the kernel has failed. Aborting installation...' + exit "$?" + fi + fi +} + +# This function initiates the process to ensure kernel build dependencies are +# installed. +function install_kernel_dev_deps() +{ + local distro + local ret + + distro=$(detect_distro '/') + + # Check if distro is equal to 'none' + if [[ "$distro" == 'none' ]]; then + complain 'Support for this distro is not available yet.' + exit 22 # EINVAL + fi + + # Use check_and_install_kernel_build_dependencies() to handle dependency + # installation + check_and_install_kernel_build_dependencies "$distro" +} + function generate_documentation() { local ret @@ -268,16 +349,17 @@ function usage() say 'usage: ./setup.sh option' say '' say 'Where option may be one of the following:' - say '--help | -h Display this usage message' - say "--install | -i Install $app_name" - say "--uninstall | -u Uninstall $app_name" - say '--skip-checks | -C Skip checks (use this when packaging)' - say '--skip-docs | -D Skip creation of man pages (use this when installing)' - say '--verbose | -v Explain what is being done' - say '--force | -f Never prompt' - say "--completely-remove | -r Remove $app_name and all files under its responsibility" - say "--docs | -d Build $app_name's documentation as HTML pages into ./build" - say "--enable-tracing | -t Install ${app_name} with tracing enabled (use it with --install)" + say '--help | -h Display this usage message' + say "--install | -i Install $app_name" + say '--install-kernel-dev-deps | -k Installs all necessary dependencies to build the kernel according to your distribution' + say "--uninstall | -u Uninstall $app_name" + say '--skip-checks | -C Skip checks (use this when packaging)' + say '--skip-docs | -D Skip creation of man pages (use this when installing)' + say '--verbose | -v Explain what is being done' + say '--force | -f Never prompt' + say "--completely-remove | -r Remove $app_name and all files under its responsibility" + say "--docs | -d Build $app_name's documentation as HTML pages into ./build" + say "--enable-tracing | -t Install ${app_name} with tracing enabled (use it with --install)" } function confirm_complete_removal() @@ -650,6 +732,9 @@ case "$1" in --docs | -d) generate_documentation ;; + --install-kernel-dev-deps | -k) + install_kernel_dev_deps + ;; *) complain 'Invalid number of arguments' usage From 336f36caefd86a50f76c019ef6e88313f08c19b9 Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Mon, 13 May 2024 23:04:00 -0300 Subject: [PATCH 091/128] setup: introduce full-installation option This commit introduces the --full-installation option, which combines the functionality of --install and --install-kernel-dev-deps. The new option installs the kworkflow and all necessary kernel development dependencies in sequence. Reviewed-by: David Tadokoro Signed-off-by: Aquila Macedo Signed-off-by: David Tadokoro --- setup.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/setup.sh b/setup.sh index 641831016..6f0d972ef 100755 --- a/setup.sh +++ b/setup.sh @@ -352,6 +352,7 @@ function usage() say '--help | -h Display this usage message' say "--install | -i Install $app_name" say '--install-kernel-dev-deps | -k Installs all necessary dependencies to build the kernel according to your distribution' + say "--full-installation | -F Install $app_name and its kernel development dependencies" say "--uninstall | -u Uninstall $app_name" say '--skip-checks | -C Skip checks (use this when packaging)' say '--skip-docs | -D Skip creation of man pages (use this when installing)' @@ -644,6 +645,14 @@ function install_home() warning '-> For a better experience with kw, please, open a new terminal.' } +function full_installation() +{ + say 'Starting kw installation...' + install_home + say 'Installing kernel dependencies for build...' + install_kernel_dev_deps +} + function setup_bashrc_to_show_current_kw_env() { local config_file_template="${etcdir}/kw_prompt_current_env_name.sh" @@ -735,6 +744,9 @@ case "$1" in --install-kernel-dev-deps | -k) install_kernel_dev_deps ;; + --full-installation | -F) + full_installation + ;; *) complain 'Invalid number of arguments' usage From 8042ce4c81c3a023edacf218ac70fd9450c5c4d0 Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Mon, 13 May 2024 23:06:44 -0300 Subject: [PATCH 092/128] setup: clean string concatenation on usage message Updates the usage messages to properly interpolate the ${app_name} variable. Reviewed-by: David Tadokoro Signed-off-by: Aquila Macedo Signed-off-by: David Tadokoro --- setup.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.sh b/setup.sh index 6f0d972ef..16561fdca 100755 --- a/setup.sh +++ b/setup.sh @@ -350,16 +350,16 @@ function usage() say '' say 'Where option may be one of the following:' say '--help | -h Display this usage message' - say "--install | -i Install $app_name" + say "--install | -i Install ${app_name}" say '--install-kernel-dev-deps | -k Installs all necessary dependencies to build the kernel according to your distribution' - say "--full-installation | -F Install $app_name and its kernel development dependencies" - say "--uninstall | -u Uninstall $app_name" + say "--full-installation | -F Install ${app_name} and its kernel development dependencies" + say "--uninstall | -u Uninstall ${app_name}" say '--skip-checks | -C Skip checks (use this when packaging)' say '--skip-docs | -D Skip creation of man pages (use this when installing)' say '--verbose | -v Explain what is being done' say '--force | -f Never prompt' - say "--completely-remove | -r Remove $app_name and all files under its responsibility" - say "--docs | -d Build $app_name's documentation as HTML pages into ./build" + say "--completely-remove | -r Remove ${app_name} and all files under its responsibility" + say "--docs | -d Build ${app_name}'s documentation as HTML pages into ./build" say "--enable-tracing | -t Install ${app_name} with tracing enabled (use it with --install)" } From 2882bf5309e25a2782f30011fc68f785dc77599a Mon Sep 17 00:00:00 2001 From: Bruna Bispo Date: Thu, 23 May 2024 08:41:06 -0300 Subject: [PATCH 093/128] tests: fix reverse argument order of assert_equals_helper and assertEquals Continue fix the reverse argument order of 'assert_equals_helper' and 'assertEquals' that began in the commit 48cecf15. Closes: #1091 Reviewed-by: David Tadokoro Signed-off-by: Bruna Bispo Signed-off-by: David Tadokoro --- tests/integration/device_test.sh | 2 +- tests/unit/backup_test.sh | 10 +-- tests/unit/build_test.sh | 4 +- tests/unit/config_test.sh | 36 ++++----- tests/unit/debug_test.sh | 74 +++++++++--------- tests/unit/diff_test.sh | 4 +- tests/unit/drm_plugin_test.sh | 2 +- tests/unit/help_test.sh | 2 +- tests/unit/kw_env_test.sh | 32 ++++---- tests/unit/kw_remote_test.sh | 52 ++++++------- tests/unit/kw_test.sh | 2 +- tests/unit/lib/dialog_ui_test.sh | 22 +++--- tests/unit/lib/kw_config_loader_test.sh | 14 ++-- tests/unit/lib/kw_include_test.sh | 4 +- tests/unit/lib/kw_string_test.sh | 24 +++--- tests/unit/lib/kw_time_and_date_test.sh | 44 +++++------ tests/unit/lib/kwlib_test.sh | 76 +++++++++---------- tests/unit/lib/lore_test.sh | 10 +-- tests/unit/lib/statistics_test.sh | 14 ++-- tests/unit/lib/web_test.sh | 18 ++--- tests/unit/mail_test.sh | 4 +- tests/unit/maintainers_test.sh | 22 +++--- .../unit/plugins/kernel_install/arch_test.sh | 2 +- .../unit/plugins/kernel_install/utils_test.sh | 30 ++++---- tests/unit/plugins/kw_mail/to_cc_cmd_test.sh | 4 +- tests/unit/pomodoro_test.sh | 44 +++++------ tests/unit/report_test.sh | 26 +++---- .../unit/ui/patch_hub/patch_hub_core_test.sh | 8 +- 28 files changed, 295 insertions(+), 291 deletions(-) diff --git a/tests/integration/device_test.sh b/tests/integration/device_test.sh index 4694b247c..92dd134cf 100755 --- a/tests/integration/device_test.sh +++ b/tests/integration/device_test.sh @@ -52,7 +52,7 @@ function device_info_test_helper() expected_output=$(sed '/GPU:/q' <<< "${expected_output}" | sed '/GPU:/d') fi - assertEquals "(${LINENO}): kw device failed for ${distro}" "${output}" "${expected_output}" + assertEquals "(${LINENO}): kw device failed for ${distro}" "${expected_output}" "${output}" # check storage information fs_type=$(container_inspect --format '{{.Driver}}' "${container}") diff --git a/tests/unit/backup_test.sh b/tests/unit/backup_test.sh index e2b5337eb..15cba66ef 100755 --- a/tests/unit/backup_test.sh +++ b/tests/unit/backup_test.sh @@ -32,7 +32,7 @@ function test_create_backup() done) output=$(create_backup /randomly/random/path) - assertEquals "$LINENO" "$output" 'We could not find the path' + assertEquals "$LINENO" 'We could not find the path' "$output" output=$(create_backup "$SHUNIT_TMPDIR" 'SILENT') filepath=$(str_remove_prefix "$output" 'Backup successfully created at ') @@ -47,7 +47,7 @@ function test_restore_backup() local output output=$(restore_backup "$SHUNIT_TMPDIR"/random/path/backup.tar.gz) - assertEquals "($LINENO)" "$output" 'We could not find this file' + assertEquals "($LINENO)" 'We could not find this file' "$output" output=$(restore_backup tests/unit/samples/kw-backup-2021-08-07_23-42-51.tar.gz) assertTrue "($LINENO) Not all files were extracted" \ @@ -83,17 +83,17 @@ function test_restore_config() config_2_last_line=$(tail -n 1 "$KW_DATA_DIR/configs/configs/config-2") output=$(printf '%s\n' 'n' | restore_config) - assertEquals "$LINENO" "$(printf '%s\n' "$output" | head -n 1)" 'It looks like that the file config-2 differs from the backup version.' + assertEquals "$LINENO" 'It looks like that the file config-2 differs from the backup version.' "$(printf '%s\n' "$output" | head -n 1)" # Since we answered no above, we expect config-2 to remain the same assert_equals_helper "config-2 should've reamined the same" "$LINENO" "$config_2_last_line" "$(tail -n 1 "$KW_DATA_DIR/configs/configs/config-2")" output=$(printf '%s\n' 'y' | restore_config) - assertEquals "$LINENO" "$(printf '%s\n' "$output" | head -n 1)" 'It looks like that the file config-2 differs from the backup version.' + assertEquals "$LINENO" 'It looks like that the file config-2 differs from the backup version.' "$(printf '%s\n' "$output" | head -n 1)" # Now config-2 should be changed, as we said yes above config_2_last_line=$(tail -n 1 "$KW_DATA_DIR/configs/configs/config-2") - assertEquals "$LINENO" "$config_2_last_line" '# This line is different' + assertEquals "$LINENO" '# This line is different' "$config_2_last_line" } function test_restore_data_from_dir() diff --git a/tests/unit/build_test.sh b/tests/unit/build_test.sh index 1c5473461..bde08f68e 100755 --- a/tests/unit/build_test.sh +++ b/tests/unit/build_test.sh @@ -307,7 +307,7 @@ function test_kernel_build_invalid_flag() output=$(build_kernel_main 'TEST_MODE' --notvalid 2> /dev/null) ret="$?" - assertEquals "($LINENO)" "$ret" 22 + assertEquals "($LINENO)" 22 "$ret" } function test_kernel_build_outside_kernel_repository() @@ -322,7 +322,7 @@ function test_kernel_build_outside_kernel_repository() output=$(build_kernel_main 'TEST_MODE') ret="$?" - assert_equals_helper 'We expected an error' "($LINENO)" "$ret" 125 + assert_equals_helper 'We expected an error' "($LINENO)" 125 "$ret" cd "$FAKE_KERNEL" || { fail "($LINENO) It was not possible to move into temporary directory" diff --git a/tests/unit/config_test.sh b/tests/unit/config_test.sh index ca4b2922a..9a3c1a61e 100755 --- a/tests/unit/config_test.sh +++ b/tests/unit/config_test.sh @@ -46,29 +46,29 @@ function show_raw_configurations() function test_is_config_file_valid() { is_config_file_valid 'invalid' - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" is_config_file_valid 'builds' - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" is_config_file_valid 'kworkflows' - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" # Valid options is_config_file_valid 'kworkflow' - assertEquals "($LINENO)" "$?" 0 + assertEquals "($LINENO)" 0 "$?" is_config_file_valid 'build' - assertEquals "($LINENO)" "$?" 0 + assertEquals "($LINENO)" 0 "$?" } function test_is_a_valid_config_option_only_valid_options() { is_a_valid_config_option 'build' 'cross_compile' - assertEquals "($LINENO)" "$?" 0 + assertEquals "($LINENO)" 0 "$?" is_a_valid_config_option 'kworkflow' 'ssh_ip' - assertEquals "($LINENO)" "$?" 0 + assertEquals "($LINENO)" 0 "$?" } function test_is_a_valid_config_invalid_parameters() @@ -76,16 +76,16 @@ function test_is_a_valid_config_invalid_parameters() local output output=$(is_a_valid_config_option 'build') - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" output=$(is_a_valid_config_option 'kworkflow') - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" output=$(is_a_valid_config_option 'kworkflow' 'this_is_invalid') - assertEquals "($LINENO)" "$?" 95 + assertEquals "($LINENO)" 95 "$?" output=$(is_a_valid_config_option 'build' 'nop') - assertEquals "($LINENO)" "$?" 95 + assertEquals "($LINENO)" 95 "$?" } function test_set_config_check_if_file_still_a_link_after_change() @@ -118,13 +118,13 @@ function test_set_config_value_changing_default_value() function test_set_config_value_with_dot_in_the_value() { validate_option_parameter 'this.is valid' - assertEquals "($LINENO)" "$?" 0 + assertEquals "($LINENO)" 0 "$?" validate_option_parameter 'this.is valid.also.valid' - assertEquals "($LINENO)" "$?" 0 + assertEquals "($LINENO)" 0 "$?" validate_option_parameter 'this is.not.valid' - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_set_config_with_a_path_as_value() @@ -151,10 +151,10 @@ function test_set_config_with_verbose_mode() function test_check_if_target_config_exist() { check_if_target_config_exist 'vm' 'vm.config' - assertEquals "($LINENO)" "$?" 0 + assertEquals "($LINENO)" 0 "$?" check_if_target_config_exist 'vm' 'la.config' - assertEquals "($LINENO)" "$?" 2 + assertEquals "($LINENO)" 2 "$?" } function test_parse_config_options() @@ -292,9 +292,9 @@ function test_show_configurations_invalid_target() local output output=$(show_configurations invalid_target) - assertEquals "($LINENO)" "$output" 'Invalid config target: invalid_target' + assertEquals "($LINENO)" 'Invalid config target: invalid_target' "$output" show_configurations invalid_target > /dev/null 2>&1 - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } invoke_shunit diff --git a/tests/unit/debug_test.sh b/tests/unit/debug_test.sh index f2dca859e..681de8584 100755 --- a/tests/unit/debug_test.sh +++ b/tests/unit/debug_test.sh @@ -120,7 +120,7 @@ function test_process_list() raw_input='' output=$(process_list "$raw_input" 1) ret="$?" - assert_equals_helper 'Return error:' "($LINENO)" "$ret" 22 + assert_equals_helper 'Return error:' "($LINENO)" 22 "$ret" } function test_convert_event_syntax_to_sys_path_hash() @@ -223,8 +223,8 @@ function test_convert_event_syntax_to_sys_path_hash() IFS=$'\n' printf '%s\n' "${!events_hash[*]}" ) - assert_equals_helper 'Wrong syntax:' "($LINENO)" "$output" '' - assert_equals_helper 'Return error:' "($LINENO)" "$ret" 22 + assert_equals_helper 'Wrong syntax:' "($LINENO)" '' "$output" + assert_equals_helper 'Return error:' "($LINENO)" 22 "$ret" events_hash=() convert_event_syntax_to_sys_path_hash ':' @@ -233,8 +233,8 @@ function test_convert_event_syntax_to_sys_path_hash() IFS=$'\n' printf '%s\n' "${!events_hash[*]}" ) - assert_equals_helper 'Wrong syntax:' "($LINENO)" "$output" '' - assert_equals_helper 'Return error:' "($LINENO)" "$ret" 22 + assert_equals_helper 'Wrong syntax:' "($LINENO)" '' "$output" + assert_equals_helper 'Return error:' "($LINENO)" 22 "$ret" } function test_build_event_command_string() @@ -311,9 +311,9 @@ function test_parser_debug_options_remote() { # 1) Parser remote without config file. parser_debug_options --remote 'juca@localhost:33' - assert_equals_helper 'Expected localhost' "$LINENO" "${remote_parameters['REMOTE_IP']}" 'localhost' - assert_equals_helper 'Expected port 33' "$LINENO" "${remote_parameters['REMOTE_PORT']}" 33 - assert_equals_helper 'Expected user' "$LINENO" "${remote_parameters['REMOTE_USER']}" 'juca' + assert_equals_helper 'Expected localhost' "$LINENO" 'localhost' "${remote_parameters['REMOTE_IP']}" + assert_equals_helper 'Expected port 33' "$LINENO" 33 "${remote_parameters['REMOTE_PORT']}" + assert_equals_helper 'Expected user' "$LINENO" 'juca' "${remote_parameters['REMOTE_USER']}" # 2) Parser remote with config file @@ -329,16 +329,16 @@ function test_parser_debug_options_remote() # 2.1) We have a config file, with origin set as host, and user request it parser_debug_options --remote 'origin' - assert_equals_helper 'Expected origin' "$LINENO" "${remote_parameters['REMOTE_FILE_HOST']}" 'origin' + assert_equals_helper 'Expected origin' "$LINENO" 'origin' "${remote_parameters['REMOTE_FILE_HOST']}" # 2.2) We have a config file, with --remote NAME, but we don't have NAME in the # config file. parser_debug_options --remote 'debian-test-dns' - assert_equals_helper 'Expected empty' "$LINENO" "${remote_parameters['REMOTE_FILE_HOST']}" '' - assert_equals_helper 'Expected debian-test-dns' "$LINENO" "${remote_parameters['REMOTE_IP']}" 'debian-test-dns' + assert_equals_helper 'Expected empty' "$LINENO" '' "${remote_parameters['REMOTE_FILE_HOST']}" + assert_equals_helper 'Expected debian-test-dns' "$LINENO" 'debian-test-dns' "${remote_parameters['REMOTE_IP']}" parser_debug_options --remote '192.0.2.0' - assert_equals_helper 'Expected 192.0.2.0' "$LINENO" "${remote_parameters['REMOTE_IP']}" '192.0.2.0' + assert_equals_helper 'Expected 192.0.2.0' "$LINENO" '192.0.2.0' "${remote_parameters['REMOTE_IP']}" cd "$original_dir" || { fail "($LINENO) It was not possible to move back to original directory" @@ -353,62 +353,62 @@ function test_parser_debug_options() # Validate list option parser_debug_options --list - assert_equals_helper 'Expected list' "$LINENO" "${options_values['LIST']}" 1 + assert_equals_helper 'Expected list' "$LINENO" 1 "${options_values['LIST']}" parser_debug_options --list --event 'amdgpu_dm' - assert_equals_helper 'Expected amdgpu_dm' "$LINENO" "${options_values['EVENT']}" 'amdgpu_dm' + assert_equals_helper 'Expected amdgpu_dm' "$LINENO" 'amdgpu_dm' "${options_values['EVENT']}" # Validate history option parser_debug_options --history - assert_equals_helper 'Expected history' "$LINENO" "${options_values['HISTORY']}" 1 + assert_equals_helper 'Expected history' "$LINENO" 1 "${options_values['HISTORY']}" # Validate follow parser_debug_options --follow - assert_equals_helper 'Expected follow' "$LINENO" "${options_values['FOLLOW']}" 1 + assert_equals_helper 'Expected follow' "$LINENO" 1 "${options_values['FOLLOW']}" # Validate event event_str='amdgpu_dm:dc_something[x>3]' parser_debug_options --event "$event_str" - assert_equals_helper 'Expected event' "$LINENO" "${options_values['EVENT']}" "$event_str" + assert_equals_helper 'Expected event' "$LINENO" "$event_str" "${options_values['EVENT']}" # Validate disable event parser_debug_options --event "$event_str" --disable - assert_equals_helper 'Expected event' "$LINENO" "${options_values['DISABLE']}" 1 + assert_equals_helper 'Expected event' "$LINENO" 1 "${options_values['DISABLE']}" # Validate disable event parser_debug_options --event "$event_str" --cmd "$fake_cmd" - assert_equals_helper 'Expected event' "$LINENO" "${options_values['CMD']}" "$fake_cmd" + assert_equals_helper 'Expected event' "$LINENO" "$fake_cmd" "${options_values['CMD']}" # Check local option parser_debug_options --local --event "$event_str" --disable - assert_equals_helper 'Expected event' "$LINENO" "${options_values['TARGET']}" 2 + assert_equals_helper 'Expected event' "$LINENO" 2 "${options_values['TARGET']}" # Check test_mode parser_debug_options test_mode - assert_equals_helper 'Expected event' "$LINENO" "${options_values['TEST_MODE']}" 'TEST_MODE' + assert_equals_helper 'Expected event' "$LINENO" 'TEST_MODE' "${options_values['TEST_MODE']}" # Validate dmesg parser_debug_options --dmesg - assert_equals_helper 'Expected dmesg' "$LINENO" "${options_values['DMESG']}" 1 + assert_equals_helper 'Expected dmesg' "$LINENO" 1 "${options_values['DMESG']}" # Validate ftrace parser_debug_options --ftrace - assert_equals_helper 'Expected ftrace failure' "$LINENO" "$?" 22 + assert_equals_helper 'Expected ftrace failure' "$LINENO" 22 "$?" parser_debug_options --list --ftrace - assert_equals_helper 'Expected ftrace failure' "$LINENO" "$?" 22 + assert_equals_helper 'Expected ftrace failure' "$LINENO" 22 "$?" ftrace_str='something:another,thing' parser_debug_options --ftrace="$ftrace_str" - assert_equals_helper 'Expected ftrace syntax' "$LINENO" "${options_values['FTRACE']}" "$ftrace_str" + assert_equals_helper 'Expected ftrace syntax' "$LINENO" "$ftrace_str" "${options_values['FTRACE']}" ftrace_str='something:' parser_debug_options --ftrace="$ftrace_str" - assert_equals_helper 'Expected ftrace setup' "$LINENO" "${options_values['FTRACE']}" "$ftrace_str" + assert_equals_helper 'Expected ftrace setup' "$LINENO" "$ftrace_str" "${options_values['FTRACE']}" ftrace_str='something: la, llu, xpto' parser_debug_options --ftrace="$ftrace_str" - assert_equals_helper 'Expected ftrace string' "$LINENO" "${options_values['FTRACE']}" "$ftrace_str" + assert_equals_helper 'Expected ftrace string' "$LINENO" "$ftrace_str" "${options_values['FTRACE']}" } function test_build_ftrace_command_string() @@ -423,10 +423,10 @@ function test_build_ftrace_command_string() # function_graph output=$(build_ftrace_command_string 'function_graph') expected_cmd="$disable_trace && printf '%s' 'function_graph' > $current_tracer && $enable_trace" - assert_equals_helper 'Expected to enable function_graph' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected to enable function_graph' "$LINENO" "$expected_cmd" "$output" output=$(build_ftrace_command_string ' function_graph ') - assert_equals_helper 'Expected to enable function_graph' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected to enable function_graph' "$LINENO" "$expected_cmd" "$output" # function_graph: -> Should fail output=$(build_ftrace_command_string 'function_graph: ') @@ -443,7 +443,7 @@ function test_build_ftrace_command_string() expected_cmd="$disable_trace && printf '%s' 'function_graph' > $current_tracer" expected_cmd+=" && printf '%s' 'amdgpu_dm*' >> $ftracer_filter" expected_cmd+=" && $enable_trace" - assert_equals_helper 'Expected amdgpu_dm filters' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected amdgpu_dm filters' "$LINENO" "$expected_cmd" "$output" # function_graph:amdgpu_dm*,dc_*,drm_test output=$(build_ftrace_command_string 'function_graph:amdgpu_dm*,dc_*,drm_test') @@ -452,7 +452,7 @@ function test_build_ftrace_command_string() expected_cmd+=" && printf '%s' 'dc_*' >> $ftracer_filter" expected_cmd+=" && printf '%s' 'drm_test' >> $ftracer_filter" expected_cmd+=" && $enable_trace" - assert_equals_helper 'Expected to find multiple filters' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected to find multiple filters' "$LINENO" "$expected_cmd" "$output" # function_graph: amdgpu_dm*, dc_* output=$(build_ftrace_command_string 'function_graph: amdgpu_dm*, dc_*') @@ -460,7 +460,7 @@ function test_build_ftrace_command_string() expected_cmd+=" && printf '%s' 'amdgpu_dm*' >> $ftracer_filter" expected_cmd+=" && printf '%s' 'dc_*' >> $ftracer_filter" expected_cmd+=" && $enable_trace" - assert_equals_helper 'Expected to find multiple filters' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected to find multiple filters' "$LINENO" "$expected_cmd" "$output" # Empty output=$(build_ftrace_command_string '') @@ -470,7 +470,7 @@ function test_build_ftrace_command_string() # Disable output=$(build_ftrace_command_string 'function_graph:amdgpu_dm*' 1) expected_cmd="$disable_trace && printf '' > $ftracer_filter && printf 'nop' > $FTRACE_CURRENT_PATH" - assert_equals_helper 'Expected disable command' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected disable command' "$LINENO" "$expected_cmd" "$output" } function test_ftrace_debug() @@ -491,7 +491,7 @@ function test_ftrace_debug() output=$(ftrace_debug 2 'TEST_MODE' 'function_graph:amdgpu_dm*') expected_cmd="$disable_trace && printf '%s' 'function_graph' > $current_tracer" expected_cmd+=" && printf '%s' 'amdgpu_dm*' >> $ftracer_filter && $enable_trace" - assert_equals_helper 'Expected command' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected command' "$LINENO" "$expected_cmd" "$output" expected_cmd_base="$expected_cmd" @@ -502,12 +502,12 @@ function test_ftrace_debug() output=$(ftrace_debug 3 'TEST_MODE' 'function_graph:amdgpu_dm*') expected_cmd="ssh -p 3333 juca@127.0.0.1 sudo \"$expected_cmd_base\"" - assert_equals_helper 'Expected remote command' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected remote command' "$LINENO" "$expected_cmd" "$output" # Follow output=$(ftrace_debug 3 'TEST_MODE' 'function_graph:amdgpu_dm*' '' 1) expected_cmd="ssh -p 3333 juca@127.0.0.1 sudo \"$expected_cmd_base && cat $trace_pipe\"" - assert_equals_helper 'Expected follow' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected follow' "$LINENO" "$expected_cmd" "$output" # History cd "$SHUNIT_TMPDIR" || { @@ -763,7 +763,7 @@ function test_event_debug() # Failure case output=$(event_debug 3 'TEST_MODE' 'lala;:') ret="$?" - assert_equals_helper 'Invalid syntax' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid syntax' "$LINENO" 22 "$ret" # List output=$(event_debug 2 'TEST_MODE' 'amdgpu_dm' '' '' '' 1) diff --git a/tests/unit/diff_test.sh b/tests/unit/diff_test.sh index 729bbc3b2..ab9c4adcc 100755 --- a/tests/unit/diff_test.sh +++ b/tests/unit/diff_test.sh @@ -30,7 +30,7 @@ function test_diff_folders() # TODO: We need to investigate this LANG part. Ideally, we don't want it here output=$(LANG=en_US.UTF-8 diff_folders "$folder_1" "$folder_2") - assertEquals "$output" "Only in ${folder_1}: get_maintainer.pl" + assertEquals "Only in ${folder_1}: get_maintainer.pl" "$output" } function test_diff_folders_no_difference() @@ -39,7 +39,7 @@ function test_diff_folders_no_difference() local folder_2="${SAMPLES_DIR}/db_files" output=$(diff_folders "$folder_1" "$folder_2") - assertEquals "$output" "" + assertEquals "" "$output" } function test_diff_folders_invalid_path() diff --git a/tests/unit/drm_plugin_test.sh b/tests/unit/drm_plugin_test.sh index 4ae5241cb..46f496697 100755 --- a/tests/unit/drm_plugin_test.sh +++ b/tests/unit/drm_plugin_test.sh @@ -400,7 +400,7 @@ function test_convert_module_info() assertEquals "$LINENO" "$expected" "$output" output=$(convert_module_info "LOAD" "") - assertEquals "$LINENO" "$?" "22" + assertEquals "$LINENO" 22 "$?" } invoke_shunit diff --git a/tests/unit/help_test.sh b/tests/unit/help_test.sh index 04e30f55e..29ebacd5c 100755 --- a/tests/unit/help_test.sh +++ b/tests/unit/help_test.sh @@ -28,7 +28,7 @@ function test_kworkflow_man() expect="Couldn't find the man page for kw-error!" output=$(kworkflow_man 'error' 'TEST_MODE') ret="$?" - assertEquals "($LINENO) We expected an error." "$ret" 2 + assertEquals "($LINENO) We expected an error." 2 "$ret" assertEquals "($LINENO) We expected an error message." "$expect" "$output" } diff --git a/tests/unit/kw_env_test.sh b/tests/unit/kw_env_test.sh index 9f23b0ce3..901da34bf 100755 --- a/tests/unit/kw_env_test.sh +++ b/tests/unit/kw_env_test.sh @@ -44,19 +44,19 @@ function test_create_new_env_create_multiple_envs_from_current_configs() options_values['CREATE']='xpto' create_new_env - assertEquals "($LINENO) We should nota have errors" "$?" 0 + assertEquals "($LINENO) We should nota have errors" 0 "$?" options_values['CREATE']='abc' create_new_env - assertEquals "($LINENO) We should nota have errors" "$?" 0 + assertEquals "($LINENO) We should nota have errors" 0 "$?" # Other checks # 1. Do we have the env folder? new_env_name=$(find ".kw/${ENV_DIR}" -type d -name 'xpto') - assertEquals "($LINENO) We did not find the new folder name" "$new_env_name" ".kw/${ENV_DIR}/xpto" + assertEquals "($LINENO) We did not find the new folder name" ".kw/${ENV_DIR}/xpto" "$new_env_name" new_env_name=$(find ".kw/${ENV_DIR}" -type d -name 'abc') - assertEquals "($LINENO) We did not find the new folder name" "$new_env_name" ".kw/${ENV_DIR}/abc" + assertEquals "($LINENO) We did not find the new folder name" ".kw/${ENV_DIR}/abc" "$new_env_name" # 2. Check for config files for config in "${config_file_list[@]}"; do @@ -74,7 +74,7 @@ function test_create_new_env_outside_of_a_repo_without_init() options_values['CREATE']='farofa' output=$(create_new_env) - assertEquals "($LINENO) We should hit a fail condition" "$?" 22 + assertEquals "($LINENO) We should hit a fail condition" 22 "$?" } function test_create_new_env_missing_config() @@ -98,7 +98,7 @@ function test_create_new_env_check_if_target_env_name_already_exists() # Try to create the same env twice output=$(create_new_env) - assertEquals "($LINENO) We should be able to create two env with the same name" "$?" 22 + assertEquals "($LINENO) We should be able to create two env with the same name" 22 "$?" } function test_show_available_envs() @@ -129,7 +129,7 @@ function test_show_available_envs_when_we_dont_kw_folder() assertTrue "${LINENO}: Something went wrong when we tried to remove .kw folder" 'rm -rf .kw' output=$(list_env_available_envs) - assertEquals "($LINENO) We should hit a fail condition" "$?" 22 + assertEquals "($LINENO) We should hit a fail condition" 22 "$?" } function test_show_available_envs_when_there_is_no_env() @@ -166,7 +166,7 @@ function test_use_target_env() real_path=$(readlink "${PWD}/.kw/build.config") expected_path="${PWD}/.kw/${ENV_DIR}/farofa/build.config" - assertEquals "($LINENO) It looks like that the env did not switch" "$real_path" "$expected_path" + assertEquals "($LINENO) It looks like that the env did not switch" "$expected_path" "$real_path" # Switch env options_values['USE']='tapioca' @@ -175,7 +175,7 @@ function test_use_target_env() real_path=$(readlink "${PWD}/.kw/build.config") expected_path="${PWD}/.kw/${ENV_DIR}/tapioca/build.config" - assertEquals "($LINENO) It looks like that the env did not switch" "$real_path" "$expected_path" + assertEquals "($LINENO) It looks like that the env did not switch" "$expected_path" "$real_path" } function test_use_target_env_invalid_env() @@ -194,7 +194,7 @@ function test_use_target_env_invalid_env() # Switch env options_values['USE']='lala' output=$(use_target_env) - assertEquals "($LINENO) Env does not exists" "$?" 22 + assertEquals "($LINENO) Env does not exists" 22 "$?" } function test_validate_env_before_switch_invalid_case_with_config() @@ -242,11 +242,11 @@ function test_parse_env_options() # Check help output=$(parse_env_options -h) - assertEquals "($LINENO)" "$?" 0 + assertEquals "($LINENO)" 0 "$?" # Check verbose output=$(parse_env_options --verbose) - assertEquals "($LINENO)" "$?" 0 + assertEquals "($LINENO)" 0 "$?" # Check create parse_env_options --create abc @@ -254,10 +254,10 @@ function test_parse_env_options() "($LINENO)" 'abc' "${options_values['CREATE']}" output=$(parse_env_options --create 'abc la') - assertEquals "($LINENO) Invalid name" "$?" 22 + assertEquals "($LINENO) Invalid name" 22 "$?" output=$(parse_env_options --create 'Weird_n@m#') - assertEquals "($LINENO) Invalid name" "$?" 22 + assertEquals "($LINENO) Invalid name" 22 "$?" # Check use option parse_env_options --use abc @@ -266,10 +266,10 @@ function test_parse_env_options() # Check use option parse_env_options --an-invalid-option - assertEquals "($LINENO) Invalid option" "$?" 22 + assertEquals "($LINENO) Invalid option" 22 "$?" parse_env_options --use - assertEquals "($LINENO) Invalid option" "$?" 22 + assertEquals "($LINENO) Invalid option" 22 "$?" } function test_exit_env_checking_files() diff --git a/tests/unit/kw_remote_test.sh b/tests/unit/kw_remote_test.sh index b7088a27a..29a3bc173 100755 --- a/tests/unit/kw_remote_test.sh +++ b/tests/unit/kw_remote_test.sh @@ -46,15 +46,15 @@ function test_add_new_remote_wrong_number_of_parameters() options_values['PARAMETERS']='' output=$(add_new_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" options_values['PARAMETERS']='xpto' output=$(add_new_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" options_values['PARAMETERS']='xpto lala uuu' output=$(add_new_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_add_new_remote_no_kw_folder() @@ -67,7 +67,7 @@ function test_add_new_remote_no_kw_folder() options_values['PARAMETERS']='origin u' output=$(add_new_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_add_new_remote_with_no_config_file() @@ -213,11 +213,11 @@ function test_remove_remote_wrong_parameters() options_values['PARAMETERS']='' output=$(remove_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" options_values['PARAMETERS']='one two' output=$(remove_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_remove_remote_only_one_entry() @@ -235,7 +235,7 @@ function test_remove_remote_only_one_entry() options_values['PARAMETERS']='origin' output=$(remove_remote) mapfile -t final_result < "${BASE_PATH_KW}/remote.config" - assertEquals "($LINENO)" "${final_result[*]}" '' + assertEquals "($LINENO)" '' "${final_result[*]}" } function test_remove_remote_try_to_remove_something_from_an_empty_file() @@ -247,7 +247,7 @@ function test_remove_remote_try_to_remove_something_from_an_empty_file() options_values['PARAMETERS']='origin' output=$(remove_remote) mapfile -t final_result < "${BASE_PATH_KW}/remote.config" - assertEquals "($LINENO)" "${final_result[*]}" '' + assertEquals "($LINENO)" '' "${final_result[*]}" } function test_remove_remote_drop_guard_between_others() @@ -316,7 +316,7 @@ function test_remove_remote_try_to_drop_something_that_does_not_exists() # Remove a remote option in the middle options_values['PARAMETERS']='uva' output=$(remove_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_rename_remote_wrong_number_of_parameters() @@ -325,15 +325,15 @@ function test_rename_remote_wrong_number_of_parameters() options_values['PARAMETERS']='' output=$(rename_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" options_values['PARAMETERS']='xpto' output=$(rename_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" options_values['PARAMETERS']='xpto la lu' output=$(rename_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_rename_remote_try_to_rename_something_that_does_not_exists() @@ -344,7 +344,7 @@ function test_rename_remote_try_to_rename_something_that_does_not_exists() options_values['PARAMETERS']='ko uva' output=$(rename_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_rename_remote_rename_to_something_that_already_exists() @@ -355,7 +355,7 @@ function test_rename_remote_rename_to_something_that_already_exists() options_values['PARAMETERS']='fedora-test arch-test' output=$(rename_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_rename_remote_change_a_valid_remote() @@ -429,7 +429,7 @@ function test_set_default_remote_try_to_set_an_invalid_remote() options_values['DEFAULT_REMOTE']='palmares' output=$(set_default_remote) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_set_default_remote_we_already_have_the_default_remote() @@ -468,18 +468,18 @@ function test_parse_remote_options() { # Add option parse_remote_options --add origin 'root@la:3333' - assert_equals_helper 'Request add' "($LINENO)" "${options_values['ADD']}" 1 - assert_equals_helper 'Remote options' "($LINENO)" "${options_values['PARAMETERS']}" 'origin root@la:3333 ' + assert_equals_helper 'Request add' "($LINENO)" 1 "${options_values['ADD']}" + assert_equals_helper 'Remote options' "($LINENO)" 'origin root@la:3333 ' "${options_values['PARAMETERS']}" # Remove parse_remote_options --remove origin - assert_equals_helper 'Request remove' "($LINENO)" "${options_values['REMOVE']}" 1 - assert_equals_helper 'Remote options' "($LINENO)" "${options_values['PARAMETERS']}" 'origin ' + assert_equals_helper 'Request remove' "($LINENO)" 1 "${options_values['REMOVE']}" + assert_equals_helper 'Remote options' "($LINENO)" 'origin ' "${options_values['PARAMETERS']}" # Rename parse_remote_options --rename origin xpto - assert_equals_helper 'Request rename' "($LINENO)" "${options_values['RENAME']}" 1 - assert_equals_helper 'Remote options' "($LINENO)" "${options_values['PARAMETERS']}" 'origin xpto ' + assert_equals_helper 'Request rename' "($LINENO)" 1 "${options_values['RENAME']}" + assert_equals_helper 'Remote options' "($LINENO)" 'origin xpto ' "${options_values['PARAMETERS']}" } function test_list_remotes() @@ -508,23 +508,23 @@ function test_list_remotes_invalid() { rm "${local_remote_config_file}" output=$(list_remotes) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" rm -rf "${BASE_PATH_KW}" rm "${global_remote_config_file}" output=$(list_remotes) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_kw_remote_without_valid_option() { # kw remote (no option nor parameter) parse_remote_options - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" # kw remote [...] (no options) parse_remote_options - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_remove_remote_that_is_prefix_of_other_remote() @@ -760,7 +760,7 @@ function test_global_option_list_remote_invalid() rm "${global_remote_config_file}" options_values['GLOBAL']='1' output=$(list_remotes) - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function setup_for_symbolic_link_test() diff --git a/tests/unit/kw_test.sh b/tests/unit/kw_test.sh index 462eab87f..8629f28fd 100755 --- a/tests/unit/kw_test.sh +++ b/tests/unit/kw_test.sh @@ -11,7 +11,7 @@ function test_validate_global_variables() VARS=(KWORKFLOW KW_LIB_DIR) for v in "${VARS[@]}"; do test -z ${!v+x} - assertEquals "Variable $v should exist." $? 1 + assertEquals "Variable ${v} should exist." 1 $? done } diff --git a/tests/unit/lib/dialog_ui_test.sh b/tests/unit/lib/dialog_ui_test.sh index 991dee926..00ee4b76c 100755 --- a/tests/unit/lib/dialog_ui_test.sh +++ b/tests/unit/lib/dialog_ui_test.sh @@ -107,7 +107,7 @@ function test_create_simple_checklist_rely_on_some_default_options() expected_cmd+=" $'Checklist 1' '' 'on' $'Checklist 2' '' 'off'" output=$(create_simple_checklist "$menu_title" "$menu_message_box" 'menu_list_string_array' 'check_statuses' '' '' '' '' '' 'TEST_MODE') - assert_equals_helper 'Expected simple checklist' "$LINENO" "${output}" "${expected_cmd}" + assert_equals_helper 'Expected simple checklist' "$LINENO" "${expected_cmd}" "${output}" } function test_create_simple_checklist_use_all_options() @@ -126,7 +126,7 @@ function test_create_simple_checklist_use_all_options() expected_cmd+=" $'Checklist 1' '' 'on' $'Checklist 2' '' 'off'" output=$(create_simple_checklist "$menu_title" "$menu_message_box" 'menu_list_string_array' 'check_statuses' 1 'Nop' '442' '244' '3' 'TEST_MODE') - assert_equals_helper 'Expected simple checklist' "$LINENO" "${output}" "${expected_cmd}" + assert_equals_helper 'Expected simple checklist' "$LINENO" "${expected_cmd}" "${output}" } function test_create_loading_screen_notification_rely_on_some_default_options() @@ -139,7 +139,7 @@ function test_create_loading_screen_notification_rely_on_some_default_options() expected_cmd+=" '8' '60'" output=$(create_loading_screen_notification "$loading_message" '' '' 'TEST_MODE') - assert_equals_helper 'Expected loading screen with some default options' "$LINENO" "${output}" "${expected_cmd}" + assert_equals_helper 'Expected loading screen with some default options' "$LINENO" "${expected_cmd}" "${output}" } function test_create_loading_screen_notification_use_all_options() @@ -152,7 +152,7 @@ function test_create_loading_screen_notification_use_all_options() expected_cmd+=" '1234' '4321'" output=$(create_loading_screen_notification "$loading_message" '1234' '4321' 'TEST_MODE') - assert_equals_helper 'Expected loading screen with some default options' "$LINENO" "${output}" "${expected_cmd}" + assert_equals_helper 'Expected loading screen with some default options' "$LINENO" "${expected_cmd}" "${output}" } function test_create_async_loading_screen_notification_rely_on_some_default_options() @@ -177,7 +177,7 @@ function test_create_async_loading_screen_notification_rely_on_some_default_opti stop_async_loading_screen_notification "$pid" output=$(< "$output_path") - assert_equals_helper 'Expected async loading screen with some default options' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected async loading screen with some default options' "$LINENO" "$expected_cmd" "$output" } function test_create_async_loading_screen_notification_use_all_options() @@ -202,7 +202,7 @@ function test_create_async_loading_screen_notification_use_all_options() stop_async_loading_screen_notification "$pid" output=$(< "$output_path") - assert_equals_helper 'Expected async loading screen with some default options' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected async loading screen with some default options' "$LINENO" "$expected_cmd" "$output" } function test_create_message_box_rely_on_some_default_options() @@ -216,7 +216,7 @@ function test_create_message_box_rely_on_some_default_options() expected_cmd+=" --msgbox $'There\'re no bookmarked patches...'" expected_cmd+=" '15' '40'" output=$(create_message_box "${box_title}" "${message_box}" '' '' 'TEST_MODE') - assert_equals_helper 'Expected message box with some default options' "$LINENO" "$output" "${expected_cmd}" + assert_equals_helper 'Expected message box with some default options' "$LINENO" "${expected_cmd}" "$output" } function test_create_message_box_use_all_options() @@ -230,7 +230,7 @@ function test_create_message_box_use_all_options() expected_cmd+=" --msgbox $'There\'re no bookmarked patches...'" expected_cmd+=" '1234' '4321'" output=$(create_message_box "${box_title}" "${message_box}" '1234' '4321' 'TEST_MODE') - assert_equals_helper 'Expected message box with all custom options' "$LINENO" "$output" "${expected_cmd}" + assert_equals_helper 'Expected message box with all custom options' "$LINENO" "${expected_cmd}" "$output" } function test_create_directory_selection_screen_rely_on_some_default_options() @@ -569,10 +569,10 @@ function test_build_dialog_command_preamble() function test_prettify_string_failures() { prettify_string - assert_equals_helper 'Expected failure' "$LINENO" "$?" 22 + assert_equals_helper 'Expected failure' "$LINENO" 22 "$?" prettify_string 'Something' - assert_equals_helper 'Expected failure' "$LINENO" "$?" 22 + assert_equals_helper 'Expected failure' "$LINENO" 22 "$?" } function test_prettify_string() @@ -581,7 +581,7 @@ function test_prettify_string() local expected_string='\Zb\Z6Series:\ZnSomething\n' output=$(prettify_string 'Series:' 'Something') - assert_equals_helper 'Expected pretty string' "$LINENO" "$output" "$expected_string" + assert_equals_helper 'Expected pretty string' "$LINENO" "$expected_string" "$output" } invoke_shunit diff --git a/tests/unit/lib/kw_config_loader_test.sh b/tests/unit/lib/kw_config_loader_test.sh index 9db669a71..0e776a39f 100755 --- a/tests/unit/lib/kw_config_loader_test.sh +++ b/tests/unit/lib/kw_config_loader_test.sh @@ -73,16 +73,16 @@ function test_parse_configuration_config_with_spaces_and_comments() parse_configuration 'kworkflow_space_comments.config' assertEquals "($LINENO): Kw failed to load a regular config file" 0 "$?" - assertEquals "($LINENO)" "${configurations['ssh_user']}" 'juca' - assertEquals "($LINENO)" "${configurations['mount_point']}" '/home/lala' - assertEquals "($LINENO)" "${configurations['virtualizer']}" 'libvirt' - assertEquals "($LINENO)" "${configurations['reboot_after_deploy']}" 'no' + assertEquals "($LINENO)" 'juca' "${configurations['ssh_user']}" + assertEquals "($LINENO)" '/home/lala' "${configurations['mount_point']}" + assertEquals "($LINENO)" 'libvirt' "${configurations['virtualizer']}" + assertEquals "($LINENO)" 'no' "${configurations['reboot_after_deploy']}" } function test_parser_configuration_failed_exit_code() { parse_configuration 'tests/unit/foobarpotato' - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } # Helper function used to compare expected config agaist the populated data. @@ -270,13 +270,13 @@ function test_load_configuration() # No to updating kworkflow.config to .kw/kworkflow.config output="$(printf '%s\n' 'n' | load_kworkflow_config)" - assertEquals "($LINENO): There should have been a warning" "$output" "$msg" + assertEquals "($LINENO): There should have been a warning" "$msg" "$output" assertTrue 'kworkflow.config was moved' '[[ -f "$PWD/$CONFIG_FILENAME" ]]' # Yes to updating kworkflow.config to .kw/kworkflow.config output="$(printf '%s\n' 'y' | load_configuration)" - assertEquals "($LINENO): There should have been a warning" "$output" "$msg" + assertEquals "($LINENO): There should have been a warning" "$msg" "$output" assertTrue '.kw was not created' '[[ -d "$PWD/$KW_DIR/" ]]' assertTrue 'kworkflow.config is not inside .kw' '[[ -f "$PWD/$KW_DIR/$CONFIG_FILENAME" ]]' diff --git a/tests/unit/lib/kw_include_test.sh b/tests/unit/lib/kw_include_test.sh index 41cff4565..78244c714 100755 --- a/tests/unit/lib/kw_include_test.sh +++ b/tests/unit/lib/kw_include_test.sh @@ -80,8 +80,8 @@ function test_include_similar_paths() test1_expected='output of test1' test2_expected='output of test2' - assertEquals "($LINENO)" "$test1_output" "$test1_expected" - assertEquals "($LINENO)" "$test2_output" "$test2_expected" + assertEquals "($LINENO)" "$test1_expected" "$test1_output" + assertEquals "($LINENO)" "$test2_expected" "$test2_output" } invoke_shunit diff --git a/tests/unit/lib/kw_string_test.sh b/tests/unit/lib/kw_string_test.sh index 8640b0c20..6462f9521 100755 --- a/tests/unit/lib/kw_string_test.sh +++ b/tests/unit/lib/kw_string_test.sh @@ -294,20 +294,20 @@ function test_concatenate_with_commas() output=$(concatenate_with_commas) ret="$?" expected='' - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Expected empty string' "$LINENO" "$output" "$expected" + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" + assert_equals_helper 'Expected empty string' "$LINENO" "$expected" "$output" output=$(concatenate_with_commas 'single') ret="$?" expected='single' - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" output=$(concatenate_with_commas 'first' 'second' 'third') ret="$?" expected='first,second,third' - assert_equals_helper 'No error expected' "$LINENO" "$ret" 0 - assert_equals_helper 'Wrong output' "$LINENO" "$output" "$expected" + assert_equals_helper 'No error expected' "$LINENO" 0 "$ret" + assert_equals_helper 'Wrong output' "$LINENO" "$expected" "$output" } function test_str_has_special_characters() @@ -317,10 +317,10 @@ function test_str_has_special_characters() local ret output=$(str_has_special_characters 'no special char here') - assert_equals_helper 'No error expected' "$LINENO" "$?" 1 + assert_equals_helper 'No error expected' "$LINENO" 1 "$?" output=$(str_has_special_characters 'We have a special char!') - assert_equals_helper 'We expected a special char here' "$LINENO" "$?" 0 + assert_equals_helper 'We expected a special char here' "$LINENO" 0 "$?" } function test_str_get_value_under_double_quotes() @@ -329,18 +329,18 @@ function test_str_get_value_under_double_quotes() local expected='value under quotes' output=$(str_get_value_under_double_quotes 'This is a "value under quotes", right?') - assert_equals_helper 'Wrong values under quotes' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong values under quotes' "$LINENO" "$expected" "$output" expected='Nothing around quotes' output=$(str_get_value_under_double_quotes '"Nothing around quotes"') - assert_equals_helper 'Wrong values under quotes' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong values under quotes' "$LINENO" "$expected" "$output" expected='Two' output=$(str_get_value_under_double_quotes '"Two" and "Nothing around quotes" and "xpto"') - assert_equals_helper 'Wrong values under quotes' "$LINENO" "$output" "$expected" + assert_equals_helper 'Wrong values under quotes' "$LINENO" "$expected" "$output" output=$(str_get_value_under_double_quotes '') - assert_equals_helper 'Empty string' "$LINENO" "$?" 22 + assert_equals_helper 'Empty string' "$LINENO" 22 "$?" } diff --git a/tests/unit/lib/kw_time_and_date_test.sh b/tests/unit/lib/kw_time_and_date_test.sh index 5ea88e318..42c87b9c2 100755 --- a/tests/unit/lib/kw_time_and_date_test.sh +++ b/tests/unit/lib/kw_time_and_date_test.sh @@ -13,16 +13,16 @@ function setUp() function test_sec_to_format() { formatted_time=$(sec_to_format "$pre_total_sec") - assertEquals "($LINENO)" "$formatted_time" "$pre_formated_sec" + assertEquals "($LINENO)" "$pre_formated_sec" "$formatted_time" formatted_time=$(sec_to_format "") - assertEquals "($LINENO)" "$formatted_time" '00:00:00' + assertEquals "($LINENO)" '00:00:00' "$formatted_time" formatted_time=$(sec_to_format "$pre_total_sec" '+%M:%S') - assertEquals "($LINENO)" "$formatted_time" '30:46' + assertEquals "($LINENO)" '30:46' "$formatted_time" formatted_time=$(sec_to_format "$pre_total_sec" '+%S') - assertEquals "($LINENO)" "$formatted_time" '46' + assertEquals "($LINENO)" '46' "$formatted_time" } function test_secs_to_arbitrarily_long_hours_mins_secs() @@ -152,14 +152,14 @@ function test_date_to_format() local formatted_date formatted_date=$(date_to_format '2020/3/1') - assert_equals_helper 'Today' "$LINENO" "$formatted_date" '2020/03/01' + assert_equals_helper 'Today' "$LINENO" '2020/03/01' "$formatted_date" formatted_date=$(date_to_format '2020/3/1' '+%Y/%m') - assert_equals_helper 'Today' "$LINENO" "$formatted_date" '2020/03' + assert_equals_helper 'Today' "$LINENO" '2020/03' "$formatted_date" formatted_date=$(date_to_format) today=$(date '+%Y/%m/%d') - assert_equals_helper 'Today' "$LINENO" "$formatted_date" "$today" + assert_equals_helper 'Today' "$LINENO" "$today" "$formatted_date" } function test_days_in_the_month() @@ -171,57 +171,57 @@ function test_days_in_the_month() local ret total_days=$(days_in_the_month 2 2021) - assert_equals_helper 'We expect 28 days' "$LINENO" "$total_days" 28 + assert_equals_helper 'We expect 28 days' "$LINENO" 28 "$total_days" total_days=$(days_in_the_month 02 2021) - assert_equals_helper 'We expect 28 days' "$LINENO" "$total_days" 28 + assert_equals_helper 'We expect 28 days' "$LINENO" 28 "$total_days" # Leap year, February has 29 days total_days=$(days_in_the_month 2 2016) - assert_equals_helper 'We expect 29 days' "$LINENO" "$total_days" 29 + assert_equals_helper 'We expect 29 days' "$LINENO" 29 "$total_days" total_days=$(days_in_the_month 2 300) - assert_equals_helper 'We expect 28 days' "$LINENO" "$total_days" 28 + assert_equals_helper 'We expect 28 days' "$LINENO" 28 "$total_days" # Leap year, February has 29 days total_days=$(days_in_the_month 2 1600) - assert_equals_helper 'We expect 29 days' "$LINENO" "$total_days" 29 + assert_equals_helper 'We expect 29 days' "$LINENO" 29 "$total_days" total_days=$(days_in_the_month 1 2016) - assert_equals_helper 'We expect 31 days' "$LINENO" "$total_days" 31 + assert_equals_helper 'We expect 31 days' "$LINENO" 31 "$total_days" total_days=$(days_in_the_month 6 2021) - assert_equals_helper 'We expect 30 days' "$LINENO" "$total_days" 30 + assert_equals_helper 'We expect 30 days' "$LINENO" 30 "$total_days" total_days=$(days_in_the_month 9 2021) - assert_equals_helper 'We expect 30 days' "$LINENO" "$total_days" 30 + assert_equals_helper 'We expect 30 days' "$LINENO" 30 "$total_days" total_days=$(days_in_the_month 09 2021) - assert_equals_helper 'We expect 30 days' "$LINENO" "$total_days" 30 + assert_equals_helper 'We expect 30 days' "$LINENO" 30 "$total_days" total_days=$(days_in_the_month 8 2021) - assert_equals_helper 'We expect 31 days' "$LINENO" "$total_days" 31 + assert_equals_helper 'We expect 31 days' "$LINENO" 31 "$total_days" # Empty year should be converted to the present year total_days=$(days_in_the_month 8) - assert_equals_helper 'Use this year' "$LINENO" "$total_days" 31 + assert_equals_helper 'Use this year' "$LINENO" 31 "$total_days" # An invalid month days_in_the_month 333 ret="$?" - assert_equals_helper 'Invalid month' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid month' "$LINENO" 22 "$ret" days_in_the_month -5 ret="$?" - assert_equals_helper 'Invalid month' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid month' "$LINENO" 22 "$ret" days_in_the_month -09 ret="$?" - assert_equals_helper 'Invalid month' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid month' "$LINENO" 22 "$ret" days_in_the_month -009 ret="$?" - assert_equals_helper 'Invalid month' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid month' "$LINENO" 22 "$ret" } function test_timebox_to_sec() diff --git a/tests/unit/lib/kwlib_test.sh b/tests/unit/lib/kwlib_test.sh index f0e3bcf08..4632817de 100755 --- a/tests/unit/lib/kwlib_test.sh +++ b/tests/unit/lib/kwlib_test.sh @@ -230,10 +230,10 @@ function test_cmd_manager_check_test_mode_option() local ret ret=$(cmd_manager 'TEST_MODE' 'pwd') - assertEquals "Expected pwd, but we got $ret" "$ret" "pwd" + assertEquals "Expected pwd, but we got ${ret}" "pwd" "$ret" ret=$(cmd_manager 'TEST_MODE' 'ls -lah') - assertEquals "Expected ls -lah, but we got $ret" "$ret" "ls -lah" + assertEquals "Expected ls -lah, but we got ${ret}" "ls -lah" "$ret" } function test_detect_distro_root_path_only() @@ -243,47 +243,47 @@ function test_detect_distro_root_path_only() root_path="${SAMPLES_DIR}/os/arch" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" root_path="${SAMPLES_DIR}/os/manjaro" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" root_path="${SAMPLES_DIR}/os/ubuntu" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'debian' + assert_equals_helper '' "$LINENO" 'debian' "$output" root_path="${SAMPLES_DIR}/os/debian" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'debian' + assert_equals_helper '' "$LINENO" 'debian' "$output" root_path="${SAMPLES_DIR}/os/raspbian" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'debian' + assert_equals_helper '' "$LINENO" 'debian' "$output" root_path="${SAMPLES_DIR}/os/fedora" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'fedora' + assert_equals_helper '' "$LINENO" 'fedora' "$output" root_path="${SAMPLES_DIR}/os/arch-linux-arm" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" root_path="${SAMPLES_DIR}/os/endeavouros" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" root_path="${SAMPLES_DIR}/os/steamos" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" root_path="${SAMPLES_DIR}/os/popos" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'debian' + assert_equals_helper '' "$LINENO" 'debian' "$output" root_path="${SAMPLES_DIR}/os/none" output=$(detect_distro "$root_path") - assert_equals_helper '' "$LINENO" "$output" 'none' + assert_equals_helper '' "$LINENO" 'none' "$output" } function test_detect_distro_str_check() @@ -292,22 +292,22 @@ function test_detect_distro_str_check() local output output=$(detect_distro '/' 'arch') - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" output=$(detect_distro '' 'debian') - assert_equals_helper '' "$LINENO" "$output" 'debian' + assert_equals_helper '' "$LINENO" 'debian' "$output" output=$(detect_distro '' 'fedora') - assert_equals_helper '' "$LINENO" "$output" 'fedora' + assert_equals_helper '' "$LINENO" 'fedora' "$output" output=$(detect_distro '' 'ubuntu') - assert_equals_helper '' "$LINENO" "$output" 'none' + assert_equals_helper '' "$LINENO" 'none' "$output" output=$(detect_distro '' 'ubuntu debian') - assert_equals_helper '' "$LINENO" "$output" 'debian' + assert_equals_helper '' "$LINENO" 'debian' "$output" output=$(detect_distro '' 'manjaro steamos lala arch') - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" } function test_detect_distro_from_raw_data() @@ -319,57 +319,57 @@ function test_detect_distro_from_raw_data() root_path="${SAMPLES_DIR}/os/arch/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" root_path="${SAMPLES_DIR}/os/manjaro/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" root_path="${SAMPLES_DIR}/os/ubuntu/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'debian' + assert_equals_helper '' "$LINENO" 'debian' "$output" root_path="${SAMPLES_DIR}/os/debian/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'debian' + assert_equals_helper '' "$LINENO" 'debian' "$output" root_path="${SAMPLES_DIR}/os/raspbian/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'debian' + assert_equals_helper '' "$LINENO" 'debian' "$output" root_path="${SAMPLES_DIR}/os/fedora/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'fedora' + assert_equals_helper '' "$LINENO" 'fedora' "$output" root_path="${SAMPLES_DIR}/os/arch-linux-arm/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" root_path="${SAMPLES_DIR}/os/endeavouros/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" root_path="${SAMPLES_DIR}/os/steamos/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'arch' + assert_equals_helper '' "$LINENO" 'arch' "$output" root_path="${SAMPLES_DIR}/os/popos/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'debian' + assert_equals_helper '' "$LINENO" 'debian' "$output" root_path="${SAMPLES_DIR}/os/none/etc/os-release" os_release_data=$(< "$root_path") output=$(detect_distro '' '' "$os_release_data") - assert_equals_helper '' "$LINENO" "$output" 'none' + assert_equals_helper '' "$LINENO" 'none' "$output" } function test_join_path() @@ -378,19 +378,19 @@ function test_join_path() local ret ret=$(join_path "/lala" "///xpto") - assertEquals "Expect /lala/xpto" "$ret" "$base" + assertEquals "Expect /lala/xpto" "$base" "$ret" ret=$(join_path "/lala" "/xpto////") - assertEquals "Expect /lala/xpto" "$ret" "$base" + assertEquals "Expect /lala/xpto" "$base" "$ret" ret=$(join_path "/lala" "////xpto////") - assertEquals "Expect /lala/xpto" "$ret" "$base" + assertEquals "Expect /lala/xpto" "$base" "$ret" ret=$(join_path "/lala" "//test///xpto////") - assertEquals "Expect /lala/test/xpto" "$ret" "/lala/test/xpto" + assertEquals "Expect /lala/test/xpto" "/lala/test/xpto" "$ret" ret=$(join_path "/lala/") - assertEquals "Expect /lala/" "$ret" "/lala/" + assertEquals "Expect /lala/" "/lala/" "$ret" } function test_find_kernel_root() @@ -401,13 +401,13 @@ function test_find_kernel_root() mkdir -p "$fake_path" kernel_path=$(find_kernel_root "$fake_path") - assertEquals "We expected to find a kernel path" "$kernel_path" "$SHUNIT_TMPDIR" + assertEquals "We expected to find a kernel path" "$SHUNIT_TMPDIR" "$kernel_path" kernel_path=$(find_kernel_root "/tmp") - assertEquals "We should not find a path" "$kernel_path" "" + assertEquals "We should not find a path" "" "$kernel_path" kernel_path=$(find_kernel_root "test/") - assertEquals "We should not find a path" "$kernel_path" "" + assertEquals "We should not find a path" "" "$kernel_path" } function test_is_a_patch() diff --git a/tests/unit/lib/lore_test.sh b/tests/unit/lib/lore_test.sh index 1725a9eb7..9ff11340c 100755 --- a/tests/unit/lib/lore_test.sh +++ b/tests/unit/lib/lore_test.sh @@ -66,12 +66,12 @@ function test_retrieve_available_mailing_lists() for index in "${!expected_lists[@]}"; do assert_equals_helper "We expected '$index' to be a valid key" "($LINENO)" \ - "${available_lore_mailing_lists["$index"]}" "${expected_lists["$index"]}" + "${expected_lists["$index"]}" "${available_lore_mailing_lists["$index"]}" done for index in "${!available_lore_mailing_lists[@]}"; do assert_equals_helper "We didn't expect '$index' to be a valid key" "($LINENO)" \ - "${available_lore_mailing_lists["$index"]}" "${expected_lists["$index"]}" + "${expected_lists["$index"]}" "${available_lore_mailing_lists["$index"]}" done } @@ -406,15 +406,15 @@ function test_process_name() local expected='First Second' output=$(process_name 'Second, First') - assertEquals "($LINENO)" "$output" "$expected" + assertEquals "($LINENO)" "$expected" "$output" output=$(process_name 'Second Third, First') expected='First Second Third' - assertEquals "($LINENO)" "$output" "$expected" + assertEquals "($LINENO)" "$expected" "$output" output=$(process_name 'First Second') expected='First Second' - assertEquals "($LINENO)" "$output" "$expected" + assertEquals "($LINENO)" "$expected" "$output" } function test_delete_series_from_local_storage() diff --git a/tests/unit/lib/statistics_test.sh b/tests/unit/lib/statistics_test.sh index 3a483f7a6..dc15c2c55 100755 --- a/tests/unit/lib/statistics_test.sh +++ b/tests/unit/lib/statistics_test.sh @@ -64,10 +64,10 @@ function test_calculate_total_of_data() function test_max_value() { max=$(max_value "0") - assertEquals "($LINENO)" "$max" "0" + assertEquals "($LINENO)" 0 "$max" max=$(max_value "") - assertEquals "($LINENO)" "$max" "0" + assertEquals "($LINENO)" 0 "$max" max=$(max_value "$pre_values") assertEquals "($LINENO)" "$pre_max" "$max" @@ -76,13 +76,13 @@ function test_max_value() function test_min_value() { min=$(min_value "0" "0") - assertEquals "($LINENO)" "$min" "0" + assertEquals "($LINENO)" 0 "$min" min=$(min_value "" "") - assertEquals "($LINENO)" "$min" "" + assertEquals "($LINENO)" "" "$min" min=$(min_value "$pre_values" "$pre_max") - assertEquals "($LINENO)" "$min" "$pre_min" + assertEquals "($LINENO)" "$pre_min" "$min" } # Note: The weekly, monthly, and yearly calculation uses `basic_data_process`. @@ -98,11 +98,11 @@ function test_basic_data_process() basic_data_process "$data" build="${shared_data["build"]}" - assertEquals "($LINENO)" "$build_output" "$build" + assertEquals "($LINENO)" "$build" "$build_output" basic_data_process "$data" deploy="${shared_data["deploy"]}" - assertEquals "($LINENO)" "$deploy_output" "$deploy" + assertEquals "($LINENO)" "$deploy" "$deploy_output" basic_data_process "$data" deploy="${shared_data["list"]}" diff --git a/tests/unit/lib/web_test.sh b/tests/unit/lib/web_test.sh index ba74de608..ceed94efe 100755 --- a/tests/unit/lib/web_test.sh +++ b/tests/unit/lib/web_test.sh @@ -37,20 +37,20 @@ function test_download() output=$(download '' '' '' 'TEST_MODE') ret="$?" expected='URL must not be empty.' - assert_equals_helper 'We expected to get an error for an empty URL' "($LINENO)" "$ret" 22 - assert_equals_helper 'We expected an error message' "($LINENO)" "$output" "$expected" + assert_equals_helper 'We expected to get an error for an empty URL' "($LINENO)" 22 "$ret" + assert_equals_helper 'We expected an error message' "($LINENO)" "$expected" "$output" output=$(download 'http://some-url.com' '' '' 'TEST_MODE') expected="curl --silent 'http://some-url.com' --output 'fake_cache/page.xml'" - assert_equals_helper 'We expected the correct curl command' "($LINENO)" "$output" "$expected" + assert_equals_helper 'We expected the correct curl command' "($LINENO)" "$expected" "$output" output=$(download 'http://some-url.com' 'some-file.html' '' 'TEST_MODE') expected="curl --silent 'http://some-url.com' --output 'fake_cache/some-file.html'" - assert_equals_helper 'We expected a custom file name' "($LINENO)" "$output" "$expected" + assert_equals_helper 'We expected a custom file name' "($LINENO)" "$expected" "$output" output=$(download 'http://some-url.com' 'some-file.html' 'alt_path' 'TEST_MODE') expected="curl --silent 'http://some-url.com' --output 'alt_path/some-file.html'" - assert_equals_helper 'We expected a custom file name and path' "($LINENO)" "$output" "$expected" + assert_equals_helper 'We expected a custom file name and path' "($LINENO)" "$expected" "$output" } function test_replace_http_by_https() @@ -59,15 +59,15 @@ function test_replace_http_by_https() local expected='https://lore.kernel.org/' output=$(replace_http_by_https 'http://lore.kernel.org/') - assert_equals_helper 'Expected https' "($LINENO)" "$output" "$expected" + assert_equals_helper 'Expected https' "($LINENO)" "$expected" "$output" output=$(replace_http_by_https 'https://lore.kernel.org/') - assert_equals_helper 'Expected https' "($LINENO)" "$output" "$expected" + assert_equals_helper 'Expected https' "($LINENO)" "$expected" "$output" expected='lore.kernel.org/' output=$(replace_http_by_https 'lore.kernel.org/') - assert_equals_helper 'No http prefix' "($LINENO)" "$?" 1 - assert_equals_helper 'Expected https' "($LINENO)" "$output" "$expected" + assert_equals_helper 'No http prefix' "($LINENO)" 1 "$?" + assert_equals_helper 'Expected https' "($LINENO)" "$expected" "$output" } function test_is_html_file_with_non_html_files() diff --git a/tests/unit/mail_test.sh b/tests/unit/mail_test.sh index a65f548fc..e16563d79 100755 --- a/tests/unit/mail_test.sh +++ b/tests/unit/mail_test.sh @@ -963,7 +963,7 @@ function test_mail_verify() output=$(mail_verify) ret="$?" - assert_equals_helper 'Failed verify expected an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Failed verify expected an error' "$LINENO" 22 "$ret" compare_command_sequence '' "$LINENO" 'expected_results' "$output" unset options_values @@ -988,7 +988,7 @@ function test_mail_verify() output=$(mail_verify) ret="$?" - assert_equals_helper 'Expected a success' "$LINENO" "$ret" 0 + assert_equals_helper 'Expected a success' "$LINENO" 0 "$ret" compare_command_sequence '' "$LINENO" 'expected_results' "$output" unset options_values diff --git a/tests/unit/maintainers_test.sh b/tests/unit/maintainers_test.sh index 888672a1a..410719e8c 100755 --- a/tests/unit/maintainers_test.sh +++ b/tests/unit/maintainers_test.sh @@ -81,13 +81,13 @@ function oneTimeTearDown() function test_print_files_authors() { local -r ret=$(print_files_authors "tests/unit/samples/print_file_author_test_dir/code1.c") - multilineAssertEquals "$ret" "$CORRECT_FILE_MSG" + multilineAssertEquals "$CORRECT_FILE_MSG" "$ret" } function test_print_files_authors_from_dir() { local -r ret=$(print_files_authors "tests/unit/samples/print_file_author_test_dir") - multilineAssertEquals "$ret" "$CORRECT_DIR_MSG" + multilineAssertEquals "$CORRECT_DIR_MSG" "$ret" } function test_maintainers_main() @@ -103,20 +103,20 @@ function test_maintainers_main() return } ret="$(maintainers_main .)" - multilineAssertEquals "$ret" "$CORRECT_TMP_MSG" + multilineAssertEquals "$CORRECT_TMP_MSG" "$ret" ret="$(maintainers_main fs)" - multilineAssertEquals "$ret" "$CORRECT_TMP_FS_MSG" + multilineAssertEquals "$CORRECT_TMP_FS_MSG" "$ret" cd fs || { fail "($LINENO) It was not possible to move to fs directory" return } ret="$(maintainers_main ..)" - multilineAssertEquals "$ret" "$CORRECT_TMP_MSG" + multilineAssertEquals "$CORRECT_TMP_MSG" "$ret" ret="$(maintainers_main .)" - multilineAssertEquals "$ret" "$CORRECT_TMP_FS_MSG" + multilineAssertEquals "$CORRECT_TMP_FS_MSG" "$ret" cd "$original_dir" || { fail "($LINENO) It was not possible to move back from temp directory" return @@ -132,28 +132,28 @@ function test_maintainers_main_patch() } ret="$(maintainers_main update_patch_test.patch)" - multilineAssertEquals "$ret" "$CORRECT_TMP_MSG" + multilineAssertEquals "$CORRECT_TMP_MSG" "$ret" # test -u cp -f update_patch_test.patch{,.bak} ret="$(maintainers_main -u update_patch_test.patch)" - multilineAssertEquals "$ret" "$CORRECT_TMP_PATCH_MSG" + multilineAssertEquals "$CORRECT_TMP_PATCH_MSG" "$ret" assertFileEquals update_patch_test{,_model}.patch cp -f update_patch_test.patch{.bak,} # test --update-patch ret="$(maintainers_main --update-patch update_patch_test.patch)" - multilineAssertEquals "$ret" "$CORRECT_TMP_PATCH_MSG" + multilineAssertEquals "$CORRECT_TMP_PATCH_MSG" "$ret" assertFileEquals update_patch_test{,_model}.patch # test for already existing maintainers ret="$(maintainers_main -u update_patch_test.patch)" - multilineAssertEquals "$ret" "$CORRECT_TMP_PATCH_ALREADY_IN_MSG" + multilineAssertEquals "$CORRECT_TMP_PATCH_ALREADY_IN_MSG" "$ret" assertFileEquals update_patch_test{,_model}.patch # test for already existing "To:" field without maintainers ret="$(maintainers_main -u update_patch_test2.patch)" - multilineAssertEquals "$ret" "$CORRECT_TMP_PATCH2_MSG" + multilineAssertEquals "$CORRECT_TMP_PATCH2_MSG" "$ret" assertFileEquals update_patch_test{,_model}2.patch cd "$original_dir" || { diff --git a/tests/unit/plugins/kernel_install/arch_test.sh b/tests/unit/plugins/kernel_install/arch_test.sh index 8b942c3c5..e9962e4cd 100755 --- a/tests/unit/plugins/kernel_install/arch_test.sh +++ b/tests/unit/plugins/kernel_install/arch_test.sh @@ -128,7 +128,7 @@ function test_generate_arch_temporary_root_file_system_remote_and_not_supported( generate_arch_temporary_root_file_system 'TEST_MODE' "$name" 'remote' 'GRUB' )" - assertEquals "($LINENO)" "$?" 22 + assertEquals "($LINENO)" 22 "$?" } function test_generate_arch_temporary_root_file_system_remote_preferred_root_fs() diff --git a/tests/unit/plugins/kernel_install/utils_test.sh b/tests/unit/plugins/kernel_install/utils_test.sh index 473d9066b..b1df9aa88 100755 --- a/tests/unit/plugins/kernel_install/utils_test.sh +++ b/tests/unit/plugins/kernel_install/utils_test.sh @@ -455,7 +455,7 @@ function test_install_modules() local lib_modules_path_bkp="$LIB_MODULES_PATH" output=$(install_modules "$module_target" 'TEST_MODE') - assert_equals_helper 'We did not find required files' "$LINENO" "$?" 2 + assert_equals_helper 'We did not find required files' "$LINENO" 2 "$?" cd "$test_tmp_file" || { fail "($LINENO) It was not possible to move to temporary directory" @@ -532,10 +532,12 @@ function test_install_kernel_remote() mk_fake_tar_file_to_deploy "$PWD" "$KW_DEPLOY_TMP_FILE" "$name" mkdir -p "${KW_DEPLOY_TMP_FILE}/kw_pkg" touch "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" - printf 'kernel_name=%s\n' "$name" > "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" - printf 'kernel_binary_image_file=%s\n' "$kernel_image_name" >> "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" - printf 'architecture=%s\n' "$architecture" >> "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" - printf 'previous_kernel_backup=yes\n' >> "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" + { + printf 'kernel_name=%s\n' "$name" + printf 'kernel_binary_image_file=%s\n' "$kernel_image_name" + printf 'architecture=%s\n' "$architecture" + printf 'previous_kernel_backup=yes\n' + } > "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" touch "${PWD}/boot/vmlinuz-${name}" output=$(install_kernel 'debian' "$reboot" "$target" 'TEST_MODE') @@ -575,9 +577,11 @@ function test_install_kernel_local() mk_fake_tar_file_to_deploy "$PWD" "$KW_DEPLOY_TMP_FILE" mkdir -p "${KW_DEPLOY_TMP_FILE}/kw_pkg" touch "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" - printf 'kernel_name=%s\n' "$name" > "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" - printf 'kernel_binary_image_file=%s\n' "$kernel_image_name" >> "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" - printf 'architecture=%s\n' "$architecture" >> "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" + { + printf 'kernel_name=%s\n' "$name" + printf 'kernel_binary_image_file=%s\n' "$kernel_image_name" + printf 'architecture=%s\n' "$architecture" + } > "${KW_DEPLOY_TMP_FILE}/kw_pkg/kw.pkg.info" # Check standard remote kernel installation declare -a cmd_sequence=( @@ -659,19 +663,19 @@ function test_is_filesystem_writable() local expected_cmd output=$(is_filesystem_writable 'ext4' 'TEST_MODE') - assert_equals_helper 'Expected nothing' "$LINENO" "$?" 0 + assert_equals_helper 'Expected nothing' "$LINENO" 0 "$?" output=$(is_filesystem_writable 'xpto-lala' 'TEST_MODE') - assert_equals_helper 'Expected EOPNOTSUPP error' "$LINENO" "$?" 95 + assert_equals_helper 'Expected EOPNOTSUPP error' "$LINENO" 95 "$?" output=$(is_filesystem_writable 'btrfs' 'TEST_MODE') expected_cmd='btrfs property get / ro | grep "ro=false" --silent' - assert_equals_helper 'Expected btrfs property get command' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected btrfs property get command' "$LINENO" "$expected_cmd" "$output" AB_ROOTFS_PARTITION="${PWD}/kw" output=$(is_filesystem_writable 'ext4' 'TEST_MODE') expected_cmd="tune2fs -l '$AB_ROOTFS_PARTITION' | grep -q '^Filesystem features: .*read-only.*$'" - assert_equals_helper 'Expected tune2fs command' "$LINENO" "$output" "$expected_cmd" + assert_equals_helper 'Expected tune2fs command' "$LINENO" "$expected_cmd" "$output" } function test_make_root_partition_writable() @@ -686,7 +690,7 @@ function test_make_root_partition_writable() } make_root_partition_writable 'TEST_MODE' )" - assert_equals_helper 'It is writable, do nothing' "$LINENO" "$?" 0 + assert_equals_helper 'It is writable, do nothing' "$LINENO" 0 "$?" # Check ext4 AB_ROOTFS_PARTITION='/xpto/la' diff --git a/tests/unit/plugins/kw_mail/to_cc_cmd_test.sh b/tests/unit/plugins/kw_mail/to_cc_cmd_test.sh index 4e8798a0f..be2978e86 100755 --- a/tests/unit/plugins/kw_mail/to_cc_cmd_test.sh +++ b/tests/unit/plugins/kw_mail/to_cc_cmd_test.sh @@ -35,11 +35,11 @@ function test_to_cc_main() bash "$to_cc_cmd" "$FAKE_CACHE" 'to' '' ret="$?" - assert_equals_helper 'Empty patch path should return an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Empty patch path should return an error' "$LINENO" 22 "$ret" bash "$to_cc_cmd" "$FAKE_CACHE" '' 'to_list' ret="$?" - assert_equals_helper 'Empty to_cc should return an error' "$LINENO" "$ret" 22 + assert_equals_helper 'Empty to_cc should return an error' "$LINENO" 22 "$ret" output="$(bash "$to_cc_cmd" "$FAKE_CACHE" to to_list)" expected="$TO_LIST" diff --git a/tests/unit/pomodoro_test.sh b/tests/unit/pomodoro_test.sh index 00b57e19e..e142287ed 100755 --- a/tests/unit/pomodoro_test.sh +++ b/tests/unit/pomodoro_test.sh @@ -118,63 +118,63 @@ function test_parse_pomodoro() local output parse_pomodoro '-t' '10m' - assert_equals_helper 'Time parser failed (minutes)' "$LINENO" "${options_values['TIMER']}" '10m' + assert_equals_helper 'Time parser failed (minutes)' "$LINENO" '10m' "${options_values['TIMER']}" parse_pomodoro '-t' '333h' - assert_equals_helper 'Time parser failed (hour)' "$LINENO" "${options_values['TIMER']}" '333h' + assert_equals_helper 'Time parser failed (hour)' "$LINENO" '333h' "${options_values['TIMER']}" parse_pomodoro '--set-timer' '234s' - assert_equals_helper 'Time parser failed (sec)' "$LINENO" "${options_values['TIMER']}" '234s' + assert_equals_helper 'Time parser failed (sec)' "$LINENO" '234s' "${options_values['TIMER']}" output=$(parse_pomodoro '--set-timer' '23 s') - assert_equals_helper 'No space' "$LINENO" "$?" '22' + assert_equals_helper 'No space' "$LINENO" 22 "$?" output=$(parse_pomodoro '--set-timer' '234') - assert_equals_helper 'No suffix' "$LINENO" "$?" '22' + assert_equals_helper 'No suffix' "$LINENO" 22 "$?" output=$(parse_pomodoro '--set-timer' 'uum') - assert_equals_helper 'No a number' "$LINENO" "$?" '22' + assert_equals_helper 'No a number' "$LINENO" 22 "$?" parse_pomodoro '--check-timer' - assert_equals_helper 'Show current timebox' "$LINENO" "${options_values['SHOW_TIMER']}" '1' + assert_equals_helper 'Show current timebox' "$LINENO" 1 "${options_values['SHOW_TIMER']}" parse_pomodoro '--tag' 'Something is here' - assert_equals_helper 'Tag requires set timer' "$LINENO" "$?" 22 + assert_equals_helper 'Tag requires set timer' "$LINENO" 22 "$?" parse_pomodoro '--set-timer' '1234s' '--tag' 'Something is here' - assert_equals_helper 'Get tag' "$LINENO" "${options_values['TAG']}" 'Something is here' + assert_equals_helper 'Get tag' "$LINENO" 'Something is here' "${options_values['TAG']}" parse_pomodoro '--set-timer' '1234s' '--tag' ' Extra space ' - assert_equals_helper 'Handle extra space failed' "$LINENO" "${options_values['TAG']}" 'Extra space' + assert_equals_helper 'Handle extra space failed' "$LINENO" 'Extra space' "${options_values['TAG']}" str_sample='com Ƨ -u ^ xpo-la ¬ x--bl' parse_pomodoro '--set-timer' '1234s' '--tag' "$str_sample" - assert_equals_helper 'Handle diverse chars' "$LINENO" "${options_values['TAG']}" "$str_sample" + assert_equals_helper 'Handle diverse chars' "$LINENO" "$str_sample" "${options_values['TAG']}" output=$(parse_pomodoro '--description' 'lala lalala') - assert_equals_helper 'Description requires tag' "$LINENO" "$?" 22 + assert_equals_helper 'Description requires tag' "$LINENO" 22 "$?" output=$(parse_pomodoro '-g' 'Some tag' '--description' 'lala lalala') - assert_equals_helper 'Description requires set timer' "$LINENO" "$?" 22 + assert_equals_helper 'Description requires set timer' "$LINENO" 22 "$?" str_sample='This is just a simple description' parse_pomodoro '--set-timer' '1234s' '--tag' 'Some tag' '-d' "$str_sample" - assert_equals_helper 'Wrong description' "$LINENO" "${options_values['DESCRIPTION']}" "$str_sample" + assert_equals_helper 'Wrong description' "$LINENO" "$str_sample" "${options_values['DESCRIPTION']}" str_sample_spaces=' This is just a simple description ' parse_pomodoro '--set-timer' '1234s' '--tag' 'Some tag' '-d' "$str_sample_spaces" - assert_equals_helper 'Wrong description' "$LINENO" "${options_values['DESCRIPTION']}" "$str_sample" + assert_equals_helper 'Wrong description' "$LINENO" "$str_sample" "${options_values['DESCRIPTION']}" str_sample='Does --comment --lal -u -x xpto-bla and xpto--blablbal' parse_pomodoro '--set-timer' '1234s' '--tag' 'Some tag' '-d' "$str_sample" - assert_equals_helper 'Wrong description' "$LINENO" "${options_values['DESCRIPTION']}" "$str_sample" + assert_equals_helper 'Wrong description' "$LINENO" "$str_sample" "${options_values['DESCRIPTION']}" apostrophe="Let's try something with apostrophe (I'm, you're, we're)" parse_pomodoro '--set-timer' '1234s' '--tag' 'apostrophe' '--description' "$apostrophe" - assert_equals_helper 'Wrong description' "$LINENO" "${options_values['DESCRIPTION']}" "$apostrophe" + assert_equals_helper 'Wrong description' "$LINENO" "$apostrophe" "${options_values['DESCRIPTION']}" parse_pomodoro '--verbose' - assert_equals_helper 'Show a detailed output' "$LINENO" "${options_values['VERBOSE']}" '1' + assert_equals_helper 'Show a detailed output' "$LINENO" 1 "${options_values['VERBOSE']}" } function test_register_data_for_report() @@ -246,7 +246,7 @@ function test_is_tag_already_registered() sqlite3 "${KW_DATA_DIR}/kw.db" -batch "INSERT INTO tag ('name') VALUES ('Tag 0') ;" is_tag_already_registered '' 'Tag 0' - assertEquals "$LINENO: We expect to find Tag 0" "$?" 0 + assertEquals "$LINENO: We expect to find Tag 0" 0 "$?" } function test_get_tag_name() @@ -255,7 +255,7 @@ function test_get_tag_name() local expected get_tag_name '' - assert_equals_helper 'Empty string should be detected' "$LINENO" '22' "$?" + assert_equals_helper 'Empty string should be detected' "$LINENO" 22 "$?" output=$(get_tag_name 'Some tag') expected='Some tag' @@ -274,10 +274,10 @@ function test_get_tag_name() # Try to get an ID out of range get_tag_name 65 - assert_equals_helper 'Out of range' "$LINENO" '22' "$?" + assert_equals_helper 'Out of range' "$LINENO" 22 "$?" get_tag_name -2 - assert_equals_helper 'Out of range' "$LINENO" '22' "$?" + assert_equals_helper 'Out of range' "$LINENO" 22 "$?" } function test_is_valid_argument() diff --git a/tests/unit/report_test.sh b/tests/unit/report_test.sh index 483fc79ce..bd536a365 100755 --- a/tests/unit/report_test.sh +++ b/tests/unit/report_test.sh @@ -65,62 +65,62 @@ function test_parse_report_options() # Default values parse_report_options '--day' expected_result=$(get_today_info '+%Y/%m/%d') - assert_equals_helper 'Get today info' "$LINENO" "${options_values['DAY']}" "$expected_result" + assert_equals_helper 'Get today info' "$LINENO" "$expected_result" "${options_values['DAY']}" parse_report_options '--week' expected_result=$(get_days_of_week) - assert_equals_helper 'Get this week info' "$LINENO" "${options_values['WEEK']}" "$expected_result" + assert_equals_helper 'Get this week info' "$LINENO" "$expected_result" "${options_values['WEEK']}" parse_report_options '--month' expected_result=$(get_today_info '+%Y/%m') - assert_equals_helper 'Get this month info' "$LINENO" "${options_values['MONTH']}" "$expected_result" + assert_equals_helper 'Get this month info' "$LINENO" "$expected_result" "${options_values['MONTH']}" parse_report_options '--year' expected_result=$(get_today_info '+%Y') - assert_equals_helper 'Get this year info' "$LINENO" "${options_values['YEAR']}" "$expected_result" + assert_equals_helper 'Get this year info' "$LINENO" "$expected_result" "${options_values['YEAR']}" parse_report_options '--verbose' - assert_equals_helper 'Show a detailed output' "$LINENO" "${options_values['VERBOSE']}" '1' + assert_equals_helper 'Show a detailed output' "$LINENO" 1 "${options_values['VERBOSE']}" # Values with parameters ## Days ref_date='1999/03/03' parse_report_options "--day=$ref_date" expected_result=$(date_to_format "$ref_date" '+%Y/%m/%d') - assert_equals_helper "$ref_date is a valid date" "$LINENO" "${options_values['DAY']}" "$expected_result" + assert_equals_helper "$ref_date is a valid date" "$LINENO" "$expected_result" "${options_values['DAY']}" ref_date='2022/04/32' output=$(parse_report_options "--day=$ref_date" 2> /dev/null) ret="$?" - assert_equals_helper "$ref_date is an invalid date" "$LINENO" "$ret" 22 + assert_equals_helper "$ref_date is an invalid date" "$LINENO" 22 "$ret" ## Weeks ref_date='1990/04/10' parse_report_options "--week=$ref_date" expected_result=$(get_days_of_week "$ref_date") - assert_equals_helper 'We expected all days of week' "$LINENO" "${options_values['WEEK']}" "$expected_result" + assert_equals_helper 'We expected all days of week' "$LINENO" "$expected_result" "${options_values['WEEK']}" ref_date='2022/04/32' output=$(parse_report_options "--week=$ref_date" 2> /dev/null) ret="$?" - assert_equals_helper "$ref_date is invalid" "$LINENO" "$ret" 22 + assert_equals_helper "$ref_date is invalid" "$LINENO" 22 "$ret" ## Month ref_date='1990/04' parse_report_options "--month=$ref_date" expected_result=$(date_to_format "$ref_date/01" '+%Y/%m') - assert_equals_helper 'We expected 1990/04' "$LINENO" "${options_values['MONTH']}" "$expected_result" + assert_equals_helper 'We expected 1990/04' "$LINENO" "$expected_result" "${options_values['MONTH']}" ref_date='1990/30' output=$(parse_report_options "--month=$ref_date" 2> /dev/null) ret="$?" - assert_equals_helper 'Invalid date' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid date' "$LINENO" 22 "$ret" # Invalid parameter ref_date='2022/04/12' output=$(parse_report_options "--month=$ref_date --day=$ref_date" 2> /dev/null) ret="$?" - assert_equals_helper 'Invalid date' "$LINENO" "$ret" 22 + assert_equals_helper 'Invalid date' "$LINENO" 22 "$ret" } function test_statistics() @@ -558,7 +558,7 @@ function test_save_data_to() # Try to use an invalid root directory path. output=$(save_data_to '/lala/do/not') ret="$?" - assert_equals_helper 'We expect a root path to be invalid' "$LINENO" "$ret" 1 + assert_equals_helper 'We expect a root path to be invalid' "$LINENO" 1 "$ret" # Try to use an invalid folder path error. output=$(save_data_to '/tmp/folder_not_created/') diff --git a/tests/unit/ui/patch_hub/patch_hub_core_test.sh b/tests/unit/ui/patch_hub/patch_hub_core_test.sh index 6146cfb75..9dc31e4c0 100755 --- a/tests/unit/ui/patch_hub/patch_hub_core_test.sh +++ b/tests/unit/ui/patch_hub/patch_hub_core_test.sh @@ -36,7 +36,7 @@ function test_show_dashboard() } show_dashboard - assert_equals_helper 'Expected register screen' "$LINENO" "${screen_sequence['SHOW_SCREEN']}" 'registered_mailing_lists' + assert_equals_helper 'Expected register screen' "$LINENO" 'registered_mailing_lists' "${screen_sequence['SHOW_SCREEN']}" # Mock bookmarked # shellcheck disable=SC2317 @@ -46,7 +46,7 @@ function test_show_dashboard() } show_dashboard - assert_equals_helper 'Expected register screen' "$LINENO" "${screen_sequence['SHOW_SCREEN']}" 'bookmarked_patches' + assert_equals_helper 'Expected register screen' "$LINENO" 'bookmarked_patches' "${screen_sequence['SHOW_SCREEN']}" } function test_list_patches_with_patches() @@ -98,10 +98,10 @@ function test_list_patches_without_patches() target_array_list=() list_patches 'Message test' target_array_list 'show_new_patches_in_the_mailing_list' '' - assert_equals_helper 'Expected screen' "$LINENO" "${screen_sequence['SHOW_SCREEN']}" 'dashboard' + assert_equals_helper 'Expected screen' "$LINENO" 'dashboard' "${screen_sequence['SHOW_SCREEN']}" list_patches 'Message test' target_array_list 'bookmarked_patches' '' - assert_equals_helper 'Expected screen' "$LINENO" "${screen_sequence['SHOW_SCREEN']}" 'dashboard' + assert_equals_helper 'Expected screen' "$LINENO" 'dashboard' "${screen_sequence['SHOW_SCREEN']}" } invoke_shunit From 5c24d6b14322aab1a23333de4431ff3dd3498564 Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Mon, 13 May 2024 19:41:16 -0300 Subject: [PATCH 094/128] tests: integration: modify kw_version_test to run entirely in container Updated kw_version_test to run completely inside the container to ensure compatibility with different repo labels. The version check logic now dynamically determines branch name, commit hash, and base version within the container, simplifying the process and avoiding assumptions about the host repository setup. Signed-off-by: Aquila Macedo Reviewed-by: David Tadokoro Signed-off-by: David Tadokoro --- tests/integration/kw_version_test.sh | 98 ++++++++++++++++++---------- 1 file changed, 63 insertions(+), 35 deletions(-) diff --git a/tests/integration/kw_version_test.sh b/tests/integration/kw_version_test.sh index 10379c656..35f42dccc 100755 --- a/tests/integration/kw_version_test.sh +++ b/tests/integration/kw_version_test.sh @@ -4,19 +4,21 @@ include './src/lib/kwio.sh' include './tests/unit/utils.sh' include './tests/integration/utils.sh' -declare -g expected_output - -function oneTimeSetUp() +# This function gets the commit hash and base version of the specified branch, +# constructs the expected output. +# +# @container: The name of the container. +# +# Return: +# Return 0: On success. +# Return 1: If it fails to get the branch name, head commit hash, or base version. +function kw_version_check_version() { - local kw_git_dir - local kw_dir + local container="$1" local head_hash local branch_name local base_version - - # git directory path - kw_dir="${KWROOT_DIR}" - kw_git_dir="${kw_dir}/.git" + local expected_output # In order to check correctness of `kw --version`, we collect some information # from the git repo: @@ -24,43 +26,69 @@ function oneTimeSetUp() # - Base version (alpha, beta, or other) # - Branch name # - Commit sha - # - # Because the local KW repo is copied to the container, we run the following - # commands directly on the host instead of running in the container. - head_hash=$(git --git-dir "${kw_git_dir}" rev-parse --short HEAD) - branch_name=$(git --git-dir "${kw_git_dir}" rev-parse --short --abbrev-ref HEAD) - base_version=$(head --lines 1 "${kw_dir}/src/VERSION") + branch_name=$(container_exec "$container" "git rev-parse --short --abbrev-ref HEAD") + if [[ "$?" -ne 0 ]]; then + complain "Failed to get the branch name" + return 1 # EPERM + fi + + head_commit_hash=$(container_exec "$container" "git rev-parse --short ${branch_name}") + if [[ "$?" -ne 0 ]]; then + complain 'Failed to get the head commit hash' + return 1 # EPERM + fi + + base_version=$(container_exec "$container" "git show ${branch_name}:./src/VERSION | head --lines 1") + if [[ "$?" -ne 0 ]]; then + complain 'Failed to get the base version' + return 1 # EPERM + fi + + expected_output=$(printf '%s\nBranch: %s\nCommit: %s' "$base_version" "$branch_name" "$head_commit_hash") - # using the gathered information, we build the expected output - expected_output=$(printf '%s\nBranch: %s\nCommit: %s' "$base_version" "$branch_name" "$head_hash") + printf '%s\n' "$expected_output" } -function kw_version_test_helper() +# Function to test the kw version feature across different distributions inside +# containers, using the three forms of the feature: kw version, kw --version, +# and kw -v. +function test_kw_version() { - local distro="$1" local container + local distro local output + local expected_output - # collect the kw version in the container - container="kw-${distro}" - output=$(container_exec "${container}" 'kw --version') + for distro in "${DISTROS[@]}"; do + container="kw-${distro}" - assertEquals "(${LINENO}): kw version failed for ${distro}" "$expected_output" "$output" -} + # collect the expected output in the container. + expected_output=$(kw_version_check_version "$container") + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Couldn't collect expected version output from container ${container}" + fi -function test_kw_version_on_archlinux() -{ - kw_version_test_helper 'archlinux' -} + # collect the version in the container using `kw version` + output=$(container_exec "$container" 'kw version') + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to get 'kw version' for ${distro}" + fi + assert_equals_helper "'kw version' failed for ${distro}" "$LINENO" "$expected_output" "$output" -function test_kw_version_on_debian() -{ - kw_version_test_helper 'debian' -} + # collect the version in the container using `kw --version` + output=$(container_exec "$container" 'kw --version') + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to get 'kw --version' for ${distro}" + fi + assert_equals_helper "'kw --version' failed for ${distro}" "$LINENO" "$expected_output" "$output" -function test_kw_version_on_fedora() -{ - kw_version_test_helper 'fedora' + # collect the version in the container using `kw -v` + output=$(container_exec "$container" 'kw -v') + if [[ "$?" -ne 0 ]]; then + fail "(${LINENO}): Failed to get 'kw -v' for ${distro}" + fi + assert_equals_helper "'kw -v' failed for ${distro}" "$LINENO" "$expected_output" "$output" + done } invoke_shunit From 021e849e435f0a42ead0a791de1efbfdde70af3f Mon Sep 17 00:00:00 2001 From: auyer Date: Sun, 2 Jun 2024 15:19:38 -0300 Subject: [PATCH 095/128] documentation: man: features: kw-build: save-log-to option does not use '=' The doc for the kw build save-log-to option is outdated here, showing a sintax '--save-log-to=path', but the correct is '--save-log-to path'. Signed-off-by: auyer Reviewed-by: David Tadokoro Signed-off-by: David Tadokoro --- documentation/man/features/kw-build.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/man/features/kw-build.rst b/documentation/man/features/kw-build.rst index 3acd3136c..4b1ea4937 100644 --- a/documentation/man/features/kw-build.rst +++ b/documentation/man/features/kw-build.rst @@ -64,7 +64,7 @@ OPTIONS default log level via **build.config** file under the option `warning_level`. Please check the kernel's ``make help`` for more info. --s, \--save-log-to=path: +-s, \--save-log-to path: This option will save the full compilation log with the enabled warnings to the specified path. You can set the default log path in the **build.config** file via `log_path` option. @@ -142,7 +142,7 @@ using:: Sometimes we have a lot of error message that does not fit in the terminal buffer; in these cases it is helpful to save all logs in a file:: - kw b --warnings 123 --save-log-to=ALL_WARNINGS.log + kw b --warnings 123 --save-log-to ALL_WARNINGS.log If you want to use llvm:: From 65fc09ed74c331e70ff2243397f21cfeb7bdf2ad Mon Sep 17 00:00:00 2001 From: duzaao Date: Thu, 6 Jun 2024 11:42:27 -0300 Subject: [PATCH 096/128] src: lib: remote: Standardize cmd_remotely with cmd_manager cmd_manager and cmd_remotely are very similar, and they would benefit from sharing the same interface, which is not true right now. This commit just changes the flag position in the cmd_remotely command to standardize both commands. Reviewed-by: Rodrigo Siqueira Signed-off-by: duzaao Signed-off-by: Rodrigo Siqueira --- src/debug.sh | 14 +++++++------- src/deploy.sh | 22 +++++++++++----------- src/device_info.sh | 28 ++++++++++++++-------------- src/kernel_config_manager.sh | 12 ++++++------ src/lib/remote.sh | 6 +++--- src/plugins/subsystems/drm/drm.sh | 10 +++++----- tests/unit/lib/remote_test.sh | 12 ++++++------ 7 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/debug.sh b/src/debug.sh index 7e473aa04..7a8a317ca 100644 --- a/src/debug.sh +++ b/src/debug.sh @@ -208,7 +208,7 @@ function reset_debug() # TODO: We should check if the VM is up and running fi - cmd_remotely "$reset_cmd" "$flag" "$remote" "$port" "$user" + cmd_remotely "$flag" "$reset_cmd" "$remote" "$port" "$user" ;; esac } @@ -275,7 +275,7 @@ function dmesg_debug() # TODO: We should check if the VM is up and running fi - cmd_remotely "$cmd" "$flag" '' '' '' '' "$save_following_log" + cmd_remotely "$flag" "$cmd" '' '' '' '' "$save_following_log" ;; esac } @@ -387,13 +387,13 @@ function event_debug() if [[ -n "$list" ]]; then show_verbose "$flag" "$command" - list_output=$(cmd_remotely "$command" 'SILENT' "$remote" "$port" "$user") + list_output=$(cmd_remotely 'SILENT' "$command" "$remote" "$port" "$user") show_list "$list_output" "$event" ret="$?" return "$ret" fi - cmd_remotely "$command" "$flag" "$remote" "$port" "$user" '' "$save_following_log" + cmd_remotely "$flag" "$command" "$remote" "$port" "$user" '' "$save_following_log" # If we used --cmd, we need to retrieve the log if [[ -n "$user_cmd" ]]; then @@ -442,7 +442,7 @@ function ftrace_list() fi show_verbose "$flag" "$cmd_list" - raw_data=$(cmd_remotely "$cmd_list" 'SILENT' "$remote" "$port" "$user") + raw_data=$(cmd_remotely 'SILENT' "$cmd_list" "$remote" "$port" "$user") ret="$?" ;; esac @@ -531,7 +531,7 @@ function ftrace_debug() # TODO: We should check if the VM is up and running fi - cmd_remotely "$cmd_ftrace" "$flag" '' '' '' '' "$save_following_log" + cmd_remotely "$flag" "$cmd_ftrace" '' '' '' '' "$save_following_log" ret="$?" # If we used --cmd, we need to retrieve the log @@ -900,7 +900,7 @@ function stop_debug() port="${remote_parameters['REMOTE_PORT']}" user="${remote_parameters['REMOTE_USER']}" - cmd_remotely "$stop_dmesg_cmd" "$flag" "$remote" "$port" "$user" + cmd_remotely "$flag" "$stop_dmesg_cmd" "$remote" "$port" "$user" ;; esac fi diff --git a/src/deploy.sh b/src/deploy.sh index 98d3407c5..50c661d95 100644 --- a/src/deploy.sh +++ b/src/deploy.sh @@ -352,7 +352,7 @@ function prepare_distro_for_deploy() local cmd="$REMOTE_INTERACE_CMD_PREFIX" cmd+=" --deploy-setup ${flag} ${target}" - cmd_remotely "$cmd" "$flag" + cmd_remotely "$flag" "$cmd" ;; esac } @@ -389,7 +389,7 @@ function update_status_log() ;; 3) # REMOTE_TARGET cmd="${metadata_string} >> ${kw_status_path}" - cmd_remotely "$cmd" "$flag" + cmd_remotely "$flag" "$cmd" ;; esac } @@ -420,7 +420,7 @@ function check_setup_status() ret="$?" ;; 3) # REMOTE_TARGET - cmd_remotely "$cmd" "$flag" + cmd_remotely "$flag" "$cmd" ret="$?" ;; esac @@ -563,7 +563,7 @@ function prepare_remote_dir() '--archive' "$remote" "$port" "$user" 'quiet' else say '* Sending kw to the remote' - cmd_remotely "mkdir -p $REMOTE_KW_DEPLOY" "$flag" + cmd_remotely "$flag" "mkdir -p $REMOTE_KW_DEPLOY" if [[ -n ${remote_parameters['REMOTE_FILE']} && -n ${remote_parameters['REMOTE_FILE_HOST']} ]]; then cmd="scp -q -F ${remote_parameters['REMOTE_FILE']} $files_to_send ${remote_parameters['REMOTE_FILE_HOST']}:$REMOTE_KW_DEPLOY" @@ -575,9 +575,9 @@ function prepare_remote_dir() fi # Removes temporary directory if already existent - cmd_remotely "rm --preserve-root=all --recursive --force -- ${KW_DEPLOY_TMP_FILE}" "$flag" + cmd_remotely "$flag" "rm --preserve-root=all --recursive --force -- ${KW_DEPLOY_TMP_FILE}" # Create temporary folder - cmd_remotely "mkdir -p $KW_DEPLOY_TMP_FILE" "$flag" + cmd_remotely "$flag" "mkdir -p $KW_DEPLOY_TMP_FILE" } # Create the temporary folder for local deploy. @@ -663,7 +663,7 @@ function run_list_installed_kernels() local cmd="$REMOTE_INTERACE_CMD_PREFIX" cmd+=" --list-kernels $flag $single_line $all" - cmd_remotely "$cmd" "$flag" + cmd_remotely "$flag" "$cmd" ;; esac @@ -707,7 +707,7 @@ function collect_target_info_for_deploy() local cmd="$REMOTE_INTERACE_CMD_PREFIX" cmd+=" --collect-info $flag $target" - data=$(cmd_remotely "$cmd" "$flag") + data=$(cmd_remotely "$flag" "$cmd") ;; esac @@ -780,7 +780,7 @@ function run_kernel_uninstall() # line break with `\`; this may allow us to break a huge line like this. local cmd="$REMOTE_INTERACE_CMD_PREFIX" cmd+=" --uninstall-kernels '$reboot' 'remote' '$kernels_target_list' '$flag' '$force'" - cmd_remotely "$cmd" "$flag" + cmd_remotely "$flag" "$cmd" ;; esac } @@ -853,7 +853,7 @@ function modules_install() # Execute script cmd="$REMOTE_INTERACE_CMD_PREFIX --modules ${release}.kw.tar" - cmd_remotely "$cmd" "$flag" + cmd_remotely "$flag" "$cmd" ;; esac } @@ -1338,7 +1338,7 @@ function run_kernel_install() cmd="$REMOTE_INTERACE_CMD_PREFIX" cmd+=" --kernel-update $cmd_parameters" - cmd_remotely "$cmd" "$flag" "$remote" "$port" + cmd_remotely "$flag" "$cmd" "$remote" "$port" human_install_kernel_message "$?" return "$?" ;; diff --git a/src/device_info.sh b/src/device_info.sh index 4beb7781b..fb1551305 100644 --- a/src/device_info.sh +++ b/src/device_info.sh @@ -88,7 +88,7 @@ function get_ram() ;; 3) # REMOTE_TARGET show_verbose "$flag" "$cmd" - ram=$(cmd_remotely "$cmd" 'SILENT') + ram=$(cmd_remotely 'SILENT' "$cmd") ;; esac @@ -131,10 +131,10 @@ function get_cpu() ;; 3) # REMOTE_TARGET show_verbose "$flag" "$cmd_model" - cpu_model=$(cmd_remotely "$cmd_model" 'SILENT') + cpu_model=$(cmd_remotely 'SILENT' "$cmd_model") show_verbose "$flag" "$cmd_frequency" - cpu_frequency=$(cmd_remotely "$cmd_frequency" 'SILENT') + cpu_frequency=$(cmd_remotely 'SILENT' "$cmd_frequency") ;; esac @@ -193,7 +193,7 @@ function get_disk() ;; 3) # REMOTE_TARGET show_verbose "$flag" "$cmd" - info=$(cmd_remotely "$cmd" 'SILENT') + info=$(cmd_remotely 'SILENT' "$cmd") ;; esac @@ -254,7 +254,7 @@ function get_os() root_path='/' cmd="cat $(join_path "$root_path" "$os_release_path")" show_verbose "$flag" "$cmd" - raw_os_release=$(cmd_remotely "$cmd" 'SILENT') + raw_os_release=$(cmd_remotely 'SILENT' "$cmd") ;; esac @@ -313,7 +313,7 @@ function get_desktop_environment() ;; 3) # REMOTE_TARGET show_verbose "$flag" "$cmd" - desktop_env=$(cmd_remotely "$cmd" 'SILENT') + desktop_env=$(cmd_remotely 'SILENT' "$cmd") ;; esac @@ -379,11 +379,11 @@ function get_gpu() ;; 3) # REMOTE_TARGET show_verbose "$flag" "$cmd_pci_address" - pci_addresses=$(cmd_remotely "$cmd_pci_address" 'SILENT') + pci_addresses=$(cmd_remotely 'SILENT' "$cmd_pci_address") for g in $pci_addresses; do cmd="lspci -v -s ${g}" show_verbose "$flag" "$cmd" - gpu_info=$(cmd_remotely "$cmd" 'SILENT') + gpu_info=$(cmd_remotely 'SILENT' "$cmd") cmd="printf '%s\n' '${gpu_info}' | sed --quiet --regexp-extended '/Subsystem/s/\s*.*:\s+(.*)/\1/p'" show_verbose "$flag" "$cmd" @@ -444,20 +444,20 @@ function get_motherboard() ;; 3) # REMOTE_TARGET show_verbose "$flag" "$cmd_name" - mb_name=$(cmd_remotely "$cmd_name" 'SILENT') + mb_name=$(cmd_remotely 'SILENT' "$cmd_name") show_verbose "$flag" "$cmd_vendor" - mb_vendor=$(cmd_remotely "$cmd_vendor" 'SILENT') + mb_vendor=$(cmd_remotely 'SILENT' "$cmd_vendor") # Fallback if [[ -z "$mb_name" ]]; then show_verbose "$flag" "$fallback_name_cmd" - mb_name=$(cmd_remotely "$fallback_name_cmd" 'SILENT') + mb_name=$(cmd_remotely 'SILENT' "$fallback_name_cmd") fi if [[ -z "$mb_vendor" ]]; then show_verbose "$flag" "$fallback_vendor_cmd" - mb_vendor=$(cmd_remotely "$fallback_vendor_cmd" 'SILENT') + mb_vendor=$(cmd_remotely 'SILENT' "$fallback_vendor_cmd") fi ;; esac @@ -508,10 +508,10 @@ function get_chassis() 3) # REMOTE_TARGET cmd="test -f ${dmi_file_path}" show_verbose "$flag" "$cmd" - cmd_remotely "$cmd" "$flag" + cmd_remotely "$flag" "$cmd" if [[ "$?" == 0 ]]; then show_verbose "$flag" "$dmi_cmd" - chassis_type=$(cmd_remotely "$dmi_cmd" 'SILENT') + chassis_type=$(cmd_remotely 'SILENT' "$dmi_cmd") fi ;; esac diff --git a/src/kernel_config_manager.sh b/src/kernel_config_manager.sh index c6423c004..9935fdbe3 100644 --- a/src/kernel_config_manager.sh +++ b/src/kernel_config_manager.sh @@ -259,13 +259,13 @@ function get_config_from_proc() return 0 ;; 3) # REMOTE - cmd_remotely "[ -f ${PROC_CONFIG_PATH} ]" "$flag" + cmd_remotely "$flag" "[ -f ${PROC_CONFIG_PATH} ]" if [[ "$?" != 0 ]]; then - cmd_remotely "$CMD_LOAD_CONFIG_MODULE" "$flag" + cmd_remotely "$flag" "$CMD_LOAD_CONFIG_MODULE" [[ "$?" != 0 ]] && return 95 # Operation not supported fi - cmd_remotely "$CMD_GET_CONFIG" "$flag" + cmd_remotely "$flag" "$CMD_GET_CONFIG" [[ "$?" != 0 ]] && return 95 # Operation not supported remote2host "$flag" "/tmp/${output}" "$config_base_path" return 0 @@ -313,8 +313,8 @@ function get_config_from_boot() return 0 ;; 3) # REMOTE - kernel_release=$(cmd_remotely 'uname -r' "$flag") - cmd_remotely "[ -f ${root}boot/config-${kernel_release} ]" "$flag" + kernel_release=$(cmd_remotely "$flag" 'uname -r') + cmd_remotely "$flag" "[ -f ${root}boot/config-${kernel_release} ]" [[ "$?" != 0 ]] && return 95 # ENOTSUP remote2host "$flag" "${root}boot/config-${kernel_release}" "$config_base_path" @@ -476,7 +476,7 @@ function fetch_config() mods=$(cmd_manager "$flag" 'lsmod') ;; 3) # REMOTE - mods=$(cmd_remotely 'lsmod' "$flag") + mods=$(cmd_remotely "$flag" 'lsmod') ;; esac diff --git a/src/lib/remote.sh b/src/lib/remote.sh index 7bf7137d1..af9d60c03 100644 --- a/src/lib/remote.sh +++ b/src/lib/remote.sh @@ -246,8 +246,8 @@ function ssh_connection_failure_message() # If no command is specified, we finish the execution and return 22 function cmd_remotely() { - local command="$1" - local flag=${2:-'HIGHLIGHT_CMD'} + local flag=${1:-'HIGHLIGHT_CMD'} + local command="$2" local remote=${3:-${remote_parameters['REMOTE_IP']}} local port=${4:-${remote_parameters['REMOTE_PORT']}} local user=${5:-${remote_parameters['REMOTE_USER']}} @@ -371,7 +371,7 @@ function which_distro() local output cmd='cat /etc/os-release' - output=$(cmd_remotely "$cmd" "$flag" "$remote" "$port" "$user") + output=$(cmd_remotely "$flag" "$cmd" "$remote" "$port" "$user") # TODO: I think we can find a better way to test this... if [[ "$flag" =~ 'TEST_MODE' ]]; then printf '%s' "$output" diff --git a/src/plugins/subsystems/drm/drm.sh b/src/plugins/subsystems/drm/drm.sh index ed9bf83eb..6a8a430e7 100644 --- a/src/plugins/subsystems/drm/drm.sh +++ b/src/plugins/subsystems/drm/drm.sh @@ -120,7 +120,7 @@ function module_control() remote=$(get_based_on_delimiter "$unformatted_remote" ':' 1) port=$(get_based_on_delimiter "$unformatted_remote" ':' 2) - cmd_remotely "$module_cmd" "$flag" "$remote" "$port" + cmd_remotely "$flag" "$module_cmd" "$remote" "$port" ;; esac } @@ -234,8 +234,8 @@ function gui_control() cmd_manager "$flag" "$bind_control_cmd" ;; 3) # REMOTE TARGET - cmd_remotely "$gui_control_cmd" "$flag" "$remote" "$port" - cmd_remotely "$bind_control_cmd" "$flag" "$remote" "$port" '' '1' + cmd_remotely "$flag" "$gui_control_cmd" "$remote" "$port" + cmd_remotely "$flag" "$bind_control_cmd" "$remote" "$port" '' '1' ;; esac } @@ -277,7 +277,7 @@ function get_available_connectors() target_label='local' ;; 3) # REMOTE TARGET - cards_raw_list=$(cmd_remotely "$find_conn_cmd" "$flag" | sort --dictionary-order) + cards_raw_list=$(cmd_remotely "$flag" "$find_conn_cmd" | sort --dictionary-order) target_label='remote' ;; esac @@ -346,7 +346,7 @@ function get_supported_mode_per_connector() target_label='local' ;; 3) # REMOTE TARGET - modes=$(cmd_remotely "$cmd" 'SILENT' '' '' '' '1') + modes=$(cmd_remotely 'SILENT' "$cmd" '' '' '' '1') target_label='remote' ;; esac diff --git a/tests/unit/lib/remote_test.sh b/tests/unit/lib/remote_test.sh index e89d113ee..edd5cd2fd 100755 --- a/tests/unit/lib/remote_test.sh +++ b/tests/unit/lib/remote_test.sh @@ -328,7 +328,7 @@ function test_cmd_remote() remote_parameters['REMOTE_FILE_HOST']='origin' expected_command="ssh -F ${SHUNIT_TMPDIR}/remote.config origin sudo \"$command\"" - output=$(cmd_remotely "$command" "$flag") + output=$(cmd_remotely "$flag" "$command") assertEquals "($LINENO): Command did not match" "$expected_command" "$output" configurations=() @@ -340,23 +340,23 @@ function test_cmd_remote() remote_parameters['REMOTE_USER']='root' expected_command="ssh -p $port $user@$remote sudo \"$command\"" - output=$(cmd_remotely "$command" "$flag" "$remote" "$port" "$user") + output=$(cmd_remotely "$flag" "$command" "$remote" "$port" "$user") assertEquals "($LINENO):" "$expected_command" "$output" expected_command="ssh -p $port $user@localhost sudo \"$command\"" - output=$(cmd_remotely "$command" "$flag" '' "$port" "$user") + output=$(cmd_remotely "$flag" "$command" '' "$port" "$user") assertEquals "($LINENO):" "$expected_command" "$output" expected_command="ssh -p 22 $user@localhost sudo \"$command\"" - output=$(cmd_remotely "$command" "$flag" '' '' "$user") + output=$(cmd_remotely "$flag" "$command" '' '' "$user") assertEquals "($LINENO):" "$expected_command" "$output" expected_command="ssh -p 22 root@localhost sudo \"$command\"" - output=$(cmd_remotely "$command" "$flag") + output=$(cmd_remotely "$flag" "$command") assertEquals "($LINENO):" "$expected_command" "$output" expected_command="No command specified" - output=$(cmd_remotely '' "$flag") + output=$(cmd_remotely "$flag" '') assertEquals "($LINENO):" "$expected_command" "$output" } From 8ff1516977741697c574729b1e15b7daaefd0112 Mon Sep 17 00:00:00 2001 From: Aquila Macedo Date: Tue, 4 Jun 2024 18:26:25 -0300 Subject: [PATCH 097/128] .github: workflows: integration_tests: remove redundant initialize-repository job Remove the extra initialize-repository job which was checking out the repository. Closes: #1075 Reviewed-by: Rodrigo Siqueira Reviewed-by: David Tadokoro Signed-off-by: Aquila Macedo Signed-off-by: Rodrigo Siqueira --- .github/workflows/integration_tests.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 29ed436db..1a2083870 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -3,20 +3,7 @@ on: [push, pull_request] jobs: - initialize-repository: - runs-on: ubuntu-latest - defaults: - run: - shell: bash - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 1 - integration-tests: - needs: initialize-repository runs-on: ubuntu-latest steps: From cbd065e760a7db26b413daa97616d802f09c72b6 Mon Sep 17 00:00:00 2001 From: Marcelo Mendes Spessoto Junior Date: Wed, 20 Mar 2024 06:19:53 -0300 Subject: [PATCH 098/128] src: build: Add --from-sha option Add --from-sha option that builds every commit from to actual commit. Closes #666 Reviewed-by: Rodrigo Siqueira Signed-off-by: Marcelo Mendes Spessoto Junior Signed-off-by: Rodrigo Siqueira --- documentation/man/features/kw-build.rst | 13 +++ documentation/tutorials/buildlinux.rst | 9 ++ src/_kw | 24 ++--- src/bash_autocomplete.sh | 2 +- src/build.sh | 73 ++++++++++++++- tests/unit/build_test.sh | 116 ++++++++++++++++++++++++ tests/unit/lib/kw_include_test.sh | 8 +- tests/unit/utils.sh | 15 +++ 8 files changed, 241 insertions(+), 19 deletions(-) diff --git a/documentation/man/features/kw-build.rst b/documentation/man/features/kw-build.rst index 4b1ea4937..085c1e514 100644 --- a/documentation/man/features/kw-build.rst +++ b/documentation/man/features/kw-build.rst @@ -17,6 +17,7 @@ SYNOPSIS | *kw* (*b* | *build*) [(-c | \--clean)] [\--alert=(s | v | (sv | vs) | n)] | *kw* (*b* | *build*) [(-f | \--full-cleanup)] [\--alert=(s | v | (sv | vs) | n)] | *kw* (*b* | *build*) [\--cflags] +| *kw* (*b* | *build*) [\--from-sha ] | *kw* (*b* | *build*) [\--verbose] DESCRIPTION @@ -102,6 +103,10 @@ OPTIONS | **sv** or **vs** enables both. | **n** (or any other option) disables notifications (this is the default). +\--from-sha: + Build every commit after to branch head. Useful for testing if all patches in + patchset compile. + EXAMPLES ======== For these examples, we assume that the relevant fields in your configuration @@ -159,3 +164,11 @@ If you want to reset the kernel tree to its default, `all config and script outp If you want to use cflags:: kw b --cflags "-O3 -pipe -march=native" + +If you want to build every commit after HEAD~2 to HEAD:: + + kw b --from-sha HEAD~2 + +If you want to build every commit after ee3b5 to HEAD:: + + kw b --from-sha ee3b5 diff --git a/documentation/tutorials/buildlinux.rst b/documentation/tutorials/buildlinux.rst index d2932b802..57dbc13ef 100644 --- a/documentation/tutorials/buildlinux.rst +++ b/documentation/tutorials/buildlinux.rst @@ -80,3 +80,12 @@ Well, that's it. kw will automatically infer the number of job slots for compiling based on the number of cores of your machine (i.e. when running make ``-j``, ** is an integer that specifies the number of processes that will run at the same time), and compilation will begin! + +Compiling patchsets +------------------- +You may want to try compiling every patch in your patchset to test if everything is alright. +You can do this by using the "from-sha" flag:: + + kw build --from-sha SHA + +This will compile every patch after the commit with given SHA to the branch HEAD. diff --git a/src/_kw b/src/_kw index c6caf4420..94dddac0b 100644 --- a/src/_kw +++ b/src/_kw @@ -92,18 +92,18 @@ _kw_build() { _arguments : \ '(--verbose)--verbose[enable verbose mode]' \ - '(-i --info -c --clean -f --full-cleanup -n --menu -d --doc --ccache -w --warnings -S --cpu-scaling -s --save-log-to --llvm --cflags)'{-i,--info}'[display kernel release name, version and number of modules to compile]' \ - '(-c --clean -f --full-cleanup -i --info -n --menu -d --doc --ccache -w --warnings -S --cpu-scaling -s --save-log-to --llvm --cflags)'{-c,--clean}'[remove files generated by the kernel build system]' \ - '(-f --full-cleanup -c --clean -i --info -n --menu -d --doc --ccache -w --warnings -S --cpu-scaling -s --save-log-to --llvm --cflags)'{-f,--full-cleanup}'[reset the kernel tree to its default option integrated into env]' \ - '(-n --menu -i --info -c --clean -f --full-cleanup -d --doc --cflags)'{-n,--menu}'[invoke kernel menuconfig]' \ - '(-d --doc -i --info -c --clean -f --full-cleanup -n --menu --cflags)'{-d,--doc}'[build the kernel-doc]' \ - '(-i --info -c --clean -f --full-cleanup --cflags)--ccache[enable ccache during compilation tasks]' \ - '(-w --warnings -i --info -c --clean -f --full-cleanup --cflags)'{-w,--warnings}'[enable compilation warnings]:log level:(1 2 3 12 13 23 123)' \ - '(-S --cpu-scaling -i --info -c --clean -f --full-cleanup --cflags)'{-S,--cpu-scaling}'[set CPU usage]:scaling percentage: ' \ - '(-s --save-log-to -i --info -c --clean -f --full-cleanup --cflags)'{-s,--save-log-to}'[save full compilation log with the enabled warnings to the specified path]:log path:_files' \ - '(-i --info -c --clean -f --full-cleanup --cflags)--llvm[enable the usage of the LLVM toolchain]' \ - '(-i --info -c --clean -f --full-cleanup -n --menu -d --doc --ccache -w --warnings -S --cpu-scaling -s --save-log-to --llvm --cflags)--cflags[customize kernel compilation with specific flags]' - + '(-i --info -c --clean -f --full-cleanup -n --menu -d --doc --ccache -w --warnings -S --cpu-scaling -s --save-log-to --llvm --cflags --from-sha)'{-i,--info}'[display kernel release name, version and number of modules to compile]' \ + '(-c --clean -f --full-cleanup -i --info -n --menu -d --doc --ccache -w --warnings -S --cpu-scaling -s --save-log-to --llvm --cflags --from-sha)'{-c,--clean}'[remove files generated by the kernel build system]' \ + '(-f --full-cleanup -c --clean -i --info -n --menu -d --doc --ccache -w --warnings -S --cpu-scaling -s --save-log-to --llvm --cflags --from-sha)'{-f,--full-cleanup}'[reset the kernel tree to its default option integrated into env]' \ + '(-n --menu -i --info -c --clean -f --full-cleanup -d --doc --cflags --from-sha)'{-n,--menu}'[invoke kernel menuconfig]' \ + '(-d --doc -i --info -c --clean -f --full-cleanup -n --menu --cflags --from-sha)'{-d,--doc}'[build the kernel-doc]' \ + '(-i --info -c --clean -f --full-cleanup --cflags --from-sha)--ccache[enable ccache during compilation tasks]' \ + '(-w --warnings -i --info -c --clean -f --full-cleanup --cflags --from-sha)'{-w,--warnings}'[enable compilation warnings]:log level:(1 2 3 12 13 23 123)' \ + '(-S --cpu-scaling -i --info -c --clean -f --full-cleanup --cflags --from-sha)'{-S,--cpu-scaling}'[set CPU usage]:scaling percentage: ' \ + '(-s --save-log-to -i --info -c --clean -f --full-cleanup --cflags --from-sha)'{-s,--save-log-to}'[save full compilation log with the enabled warnings to the specified path]:log path:_files' \ + '(-i --info -c --clean -f --full-cleanup --cflags --from-sha)--llvm[enable the usage of the LLVM toolchain]' \ + '(-i --info -c --clean -f --full-cleanup -n --menu -d --doc --ccache -w --warnings -S --cpu-scaling -s --save-log-to --llvm --cflags --from-sha)--cflags[customize kernel compilation with specific flags]' \ + '(-i --info -c --clean -f --full-cleanup -n --menu -d --doc --ccache -w --warnings -S --cpu-scaling -s --save-log-to --llvm --cflags --from-sha)--from-sha[Compile all commits from given sha value to branch head]: :' } _kw_clear-cache() diff --git a/src/bash_autocomplete.sh b/src/bash_autocomplete.sh index 1159b8ccd..6de0327e6 100644 --- a/src/bash_autocomplete.sh +++ b/src/bash_autocomplete.sh @@ -21,7 +21,7 @@ function _kw_autocomplete() kw_options['init']='--arch --remote --target --force --template --verbose' kw_options['build']='--help --info --menu --cpu-scaling --ccache --llvm --clean - --full-cleanup --verbose --doc --warnings --save-log-to --cflags' + --full-cleanup --verbose --doc --warnings --save-log-to --cflags --from-sha' kw_options['b']="${kw_options['build']}" diff --git a/src/build.sh b/src/build.sh index c8221f69b..99759e06f 100644 --- a/src/build.sh +++ b/src/build.sh @@ -33,6 +33,9 @@ function build_kernel_main() local clean local output_kbuild_flag='' local cflags + local from_sha_arg + local sha_base + local merge_base parse_build_options "$@" @@ -59,6 +62,7 @@ function build_kernel_main() clean=${options_values['CLEAN']} full_cleanup=${options_values['FULL_CLEANUP']} cflags=${options_values['CFLAGS']} + from_sha_arg=${options_values['FROM_SHA_ARG']} [[ -n "${options_values['VERBOSE']}" ]] && flag='VERBOSE' flag=${flag:-'SILENT'} @@ -124,6 +128,41 @@ function build_kernel_main() return "$?" fi + if [[ -n "$from_sha_arg" ]]; then + # Check if there is a rebase in process. + if [[ -d .git/rebase-merge ]]; then + warning 'ERROR: Abort the repository rebase before continuing with build from sha (use "git rebase --abort")!' + return 125 # ECANCELED + elif [[ -f .git/MERGE_HEAD ]]; then + warning 'ERROR: Abort the repository merge before continuing with build from sha (use "git rebase --abort")!' + return 125 # ECANCELED + elif [[ -f .git/BISECT_LOG ]]; then + warning 'ERROR: Stop the repository bisect before continuing with build from sha (use "git bisect reset")!' + return 125 # ECANCELED + elif [[ -d .git/rebase-apply ]]; then + printf 'ERROR: Abort the repository patch apply before continuing with build from sha (use "git am --abort")!' + return 125 # ECANCELED + fi + + # Check if given SHA represents real commit + cmd_manager 'SILENT' "git cat-file -e ${from_sha_arg}^{commit} 2> /dev/null" + if [[ "$?" != 0 ]]; then + complain "ERROR: The given SHA (${from_sha_arg}) does not represent a valid commit sha." + return 22 # EINVAL + fi + + # Check if given SHA is in working tree. + sha_base=$(git rev-parse --verify "$from_sha_arg") + merge_base=$(git merge-base "$from_sha_arg" HEAD) + if [[ "$sha_base" != "$merge_base" ]]; then + complain "ERROR: Given SHA (${from_sha_arg}) is invalid. Check if it is an ancestor of the branch head." + return 22 # EINVAL + fi + + build_from_sha "$flag" "$from_sha_arg" + return "$?" + fi + command="make ${optimizations} ${llvm}ARCH=${platform_ops}${warnings}" if [[ -n "$cflags" ]]; then @@ -247,9 +286,33 @@ function full_cleanup() cmd_manager "$flag" "$cmd" } +# This functions uses iteractive 'git rebase' with '--exec' flag under the hood +# to apply a 'kw build' over each commit from SHA to branch head. +# +# @flag How to display a command, see `src/lib/kwlib.sh` function `cmd_manager`. +# @sha The SHA from the first commit to be compiled until the branch head. +# +# Return: +# 0 if successfully compiled patchset, 125 (ECANCELED) otherwise. +function build_from_sha() +{ + local flag="$1" + local sha="$2" + local cmd + + flag=${flag:-'SILENT'} + cmd="git rebase ${sha} --exec 'kw build'" + cmd_manager "$flag" "$cmd" + + if [[ "$?" != 0 ]]; then + complain "kw build failed during the compilation of a patch! Check the rebase in progress for more information." + return 125 #ECANCELED + fi +} + function parse_build_options() { - local long_options='help,info,menu,doc,ccache,cpu-scaling:,warnings::,save-log-to:,llvm,clean,full-cleanup,verbose,cflags:' + local long_options='help,info,menu,doc,ccache,cpu-scaling:,warnings::,save-log-to:,llvm,clean,full-cleanup,verbose,cflags:,from-sha:' local short_options='h,i,n,d,S:,w::,s:,c,f' local doc_type local file_name_size @@ -279,6 +342,7 @@ function parse_build_options() options_values['FULL_CLEANUP']='' options_values['VERBOSE']='' options_values['CFLAGS']="${build_config[cflags]}" + options_values['FROM_SHA_ARG']='' # Check llvm option if [[ ${options_values['USE_LLVM_TOOLCHAIN']} =~ 'yes' ]]; then @@ -362,6 +426,10 @@ function parse_build_options() options_values['LOG_PATH']="$2" shift 2 ;; + --from-sha) + options_values['FROM_SHA_ARG']="$2" + shift 2 + ;; --) shift ;; @@ -394,7 +462,8 @@ function build_help() ' build (-c | --clean) - Clean option integrated into env' \ ' build (-f | --full-cleanup) - Reset the kernel tree to its default option integrated into env' \ ' build (--cflags) - Customize kernel compilation with specific flags' \ - ' build (--verbose) - Show a detailed output' + ' build (--verbose) - Show a detailed output' \ + ' build (--from-sha ) - Build all commits from to actual commit' } # Every time build.sh is loaded its proper configuration has to be loaded as well diff --git a/tests/unit/build_test.sh b/tests/unit/build_test.sh index bde08f68e..c66671a59 100755 --- a/tests/unit/build_test.sh +++ b/tests/unit/build_test.sh @@ -861,6 +861,122 @@ function test_kernel_build_cpu_scaling_llvm_warning_sava_log_to() compare_command_sequence '' "($LINENO)" 'expected_result' "$output" } +function test_kernel_build_from_sha() +{ + local expected_result + local output + local sha='HEAD^' + + mk_fake_git + + output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) + declare -a expected_result=( + "git rebase HEAD^ --exec 'kw build'" + ) + + compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" +} + +function test_kernel_build_from_sha_nonexisting_sha() +{ + local expected_result + local output + local sha='fakesha' + + mk_fake_git + + output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) + declare -a expected_result=( + "ERROR: The given SHA (${sha}) does not represent a valid commit sha." + ) + + compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" +} + +function test_kernel_build_from_sha_sha_not_ancestor() +{ + local expected_result + local output + + mk_fake_git + mk_git_branch 'branch' + + output=$(build_kernel_main 'TEST_MODE' --from-sha branch) + declare -a expected_result=( + 'ERROR: Given SHA (branch) is invalid. Check if it is an ancestor of the branch head.' + ) + + compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" +} + +function test_kernel_build_from_sha_pending_rebase() +{ + local expected_result + local output + local sha='HEAD^' + + mk_fake_git + mkdir '.git/rebase-merge' + + output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) + declare -a expected_result=( + 'ERROR: Abort the repository rebase before continuing with build from sha (use "git rebase --abort")!' + ) + + compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" +} + +function test_kernel_build_from_sha_pending_merge() +{ + local expected_result + local output + local sha='HEAD^' + + mk_fake_git + touch '.git/MERGE_HEAD' + + output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) + declare -a expected_result=( + 'ERROR: Abort the repository merge before continuing with build from sha (use "git rebase --abort")!' + ) + + compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" +} + +function test_kernel_build_from_sha_pending_bisect() +{ + local expected_result + local output + local sha='HEAD^' + + mk_fake_git + touch '.git/BISECT_LOG' + + output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) + declare -a expected_result=( + 'ERROR: Stop the repository bisect before continuing with build from sha (use "git bisect reset")!' + ) + + compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" +} + +function test_kernel_build_from_sha_pending_apply() +{ + local expected_result + local output + local sha='HEAD^' + + mk_fake_git + mkdir '.git/rebase-apply' + + output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) + declare -a expected_result=( + 'ERROR: Abort the repository patch apply before continuing with build from sha (use "git am --abort")!' + ) + + compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" +} + function test_kernel_build_inside_an_env() { local output diff --git a/tests/unit/lib/kw_include_test.sh b/tests/unit/lib/kw_include_test.sh index 78244c714..c191db80e 100755 --- a/tests/unit/lib/kw_include_test.sh +++ b/tests/unit/lib/kw_include_test.sh @@ -16,13 +16,13 @@ function oneTimeSetUp() touch "${test_files[@]}" # the next files will be checked for name collisions - printf "%s\n" "function test1(){ printf '%s\n' 'output of test1';}" > \ - "$SHUNIT_TMPDIR/include_test_similar_path.sh" + printf "%s\n" "function test1(){ printf '%s\n' 'output of test1';}" > "\ +$SHUNIT_TMPDIR/include_test_similar_path.sh" mkdir "$SHUNIT_TMPDIR/include_test" - printf "%s\n" "function test2(){ printf '%s\n' 'output of test2';}" > \ - "$SHUNIT_TMPDIR/include_test/similar_path.sh" + printf "%s\n" "function test2(){ printf '%s\n' 'output of test2';}" > "\ +$SHUNIT_TMPDIR/include_test/similar_path.sh" } function oneTimeTearDown() diff --git a/tests/unit/utils.sh b/tests/unit/utils.sh index 19bc52671..4697f8845 100755 --- a/tests/unit/utils.sh +++ b/tests/unit/utils.sh @@ -265,6 +265,21 @@ function mk_fake_git() git commit --allow-empty -q -m 'Third commit' } +# Create a new git branch for current local repository and return to master branch afterwards. +# +# @branch_name The name of the new branch to be created. +function mk_git_branch() +{ + local branch_name="$1" + + git checkout --quiet HEAD^ + git checkout --quiet -b "$branch_name" + touch branch_file + git add branch_file + git commit --message "create_branch" --quiet + git checkout --quiet master +} + function mk_fake_kw_folder() { local target_folder="$1" From 278cfd4ca0333582238a2178e6bd13b28f1f05a5 Mon Sep 17 00:00:00 2001 From: Pedro Mariano Date: Sun, 5 May 2024 10:51:30 -0300 Subject: [PATCH 099/128] src: plugins: subsystems: drm: Add after-reboot gui option The option `kw drm` does not provide support for permanently enabling or disabling GUI. Add the option to reach this even after reboot. Reviewed-by: Rodrigo Siqueira Signed-off-by: Pedro Mariano Signed-off-by: Vinicius Lima Signed-off-by: Rodrigo Siqueira --- documentation/man/features/kw-drm.rst | 16 +++ etc/kworkflow.config | 3 + src/_kw | 12 ++- src/bash_autocomplete.sh | 4 +- src/plugins/subsystems/drm/drm.sh | 49 ++++++++- tests/unit/drm_plugin_test.sh | 133 +++++++++++++++++++++++- tests/unit/lib/kw_config_loader_test.sh | 2 + tests/unit/samples/kworkflow.config | 2 + 8 files changed, 206 insertions(+), 15 deletions(-) diff --git a/documentation/man/features/kw-drm.rst b/documentation/man/features/kw-drm.rst index 4916c10e6..4fbddaadb 100644 --- a/documentation/man/features/kw-drm.rst +++ b/documentation/man/features/kw-drm.rst @@ -55,6 +55,22 @@ OPTIONS systemctl operation but users can change this behavior by set *gui_off* with a specific command in the **kworkflow.config** file with the specific command. +\--gui-on-after-reboot: + This option sets the GUI to turn on automatically after the next reboot. By default, + it uses systemctl operation; however, users are free to add any specific + command for activating their preferred GUI in the variable *gui_on_after_reboot* + in the **kworkflow.config** file. + Note: This change will take effect only after the system is rebooted. To enable + the GUI immediately, use the --gui-on option. + +\--gui-off-after-reboot: + This option sets the GUI to turn off automatically after the next reboot. By default, + it uses systemctl operation; however, users are free to add any specific + command for deactivating their GUI in the variable *gui_off_after_reboot* + in the **kworkflow.config** file. + Note: This change will take effect only after the system is rebooted. To disable + the GUI immediately, use the --gui-off option. + \--conn-available: Show all connectors available in the target machine. The ones marked with '*' are enabled. diff --git a/etc/kworkflow.config b/etc/kworkflow.config index 779e5b395..f1437d5d2 100644 --- a/etc/kworkflow.config +++ b/etc/kworkflow.config @@ -26,5 +26,8 @@ disable_statistics_data_track=no # Set a specific command to activate the GUI #gui_on=systemctl isolate graphical.target +#gui_on_after_reboot=systemctl set-default graphical.target + # Set a specific command to deactivate the GUI #gui_off=systemctl isolate multi-user.target +#gui_off_after_reboot=systemctl set-default multi-user.target \ No newline at end of file diff --git a/src/_kw b/src/_kw index 94dddac0b..71b318fc5 100644 --- a/src/_kw +++ b/src/_kw @@ -130,11 +130,11 @@ _kw_config() local configs='( vm.virtualizer vm.mount_point vm.qemu_hw_options vm.qemu_net_options vm.qemu_path_image kworkflow.ssh_user kworkflow.ssh_ip kworkflow.ssh_port kworkflow.ssh_configfile kworkflow.hostname - kworkflow.disable_statistics_data_track kworkflow.gui_on kworkflow.gui_off kworkflow.send_opts - kworkflow.blocked_emails kworkflow.checkpatch_opts kworkflow.get_maintainer_opts - notification.alert notification.sound_alert_command notification.visual_alert_command - build.arch build.kernel_img_name build.cross_compile build.menu_config build.doc_type build.cflags - build.cpu_scaling_factor build.enable_ccache build.warning_level build.use_llvm + kworkflow.disable_statistics_data_track kworkflow.gui_on kworkflow.gui_off kworkflow.gui_on_after_reboot + kworkflow.gui_off_after_reboot kworkflow.send_opts kworkflow.blocked_emails kworkflow.checkpatch_opts + kworkflow.get_maintainer_opts notification.alert notification.sound_alert_command + notification.visual_alert_command build.arch build.kernel_img_name build.cross_compile build.menu_config + build.doc_type build.cflags build.cpu_scaling_factor build.enable_ccache build.warning_level build.use_llvm deploy.kw_files_remote_path deploy.deploy_temporary_files_path deploy.deploy_default_compression deploy.dtb_copy_pattern deploy.default_deploy_target deploy.reboot_after_deploy deploy.strip_modules_debug_option mail.send_opts mail.blocked_emails mail.default_cc_recipients @@ -257,6 +257,8 @@ _kw_drm() '(--local)--remote[specify a remote as the target machine]: :' \ '(--gui-off)--gui-on[turn-on the target GUI]' \ '(--gui-on)--gui-off[turn-off the target GUI]' \ + '(--gui-off-after-reboot)--gui-on-after-reboot[turn-on the target GUI permanently]' \ + '(--gui-on-after-reboot)--gui-off-after-reboot[turn-off the target GUI permanently]' \ '--conn-available[show all connectors available in the target machine]' \ '--modes[show all available modes per card]' } diff --git a/src/bash_autocomplete.sh b/src/bash_autocomplete.sh index 6de0327e6..b6813ddea 100644 --- a/src/bash_autocomplete.sh +++ b/src/bash_autocomplete.sh @@ -78,8 +78,8 @@ function _kw_autocomplete() kw_options['patch-hub']='--help' - kw_options['drm']='--remote --local --gui-on --gui-off --load-module - --unload-module --conn-available --modes --verbose --help' + kw_options['drm']='--remote --local --gui-on --gui-off --gui-on-after-reboot --gui-off-after-reboot + --load-module --unload-module --conn-available --modes --verbose --help' kw_options['vm']='--mount --umount --up --alert --help' diff --git a/src/plugins/subsystems/drm/drm.sh b/src/plugins/subsystems/drm/drm.sh index 6a8a430e7..91d820589 100644 --- a/src/plugins/subsystems/drm/drm.sh +++ b/src/plugins/subsystems/drm/drm.sh @@ -12,6 +12,8 @@ function drm_main() local target local gui_on local gui_off + local gui_on_after_reboot + local gui_off_after_reboot local conn_available local remote local load_module @@ -34,6 +36,8 @@ function drm_main() target="${options_values['TARGET']}" gui_on="${options_values['GUI_ON']}" gui_off="${options_values['GUI_OFF']}" + gui_on_after_reboot="${options_values['GUI_ON_AFTER_REBOOT']}" + gui_off_after_reboot="${options_values['GUI_OFF_AFTER_REBOOT']}" conn_available="${options_values['CONN_AVAILABLE']}" modes_available="${options_values['MODES_AVAILABLE']}" help_opt="${options_values['HELP']}" @@ -64,6 +68,10 @@ function drm_main() gui_control 'ON' "$target" "$remote" "$flag" elif [[ "$gui_off" == 1 ]]; then gui_control 'OFF' "$target" "$remote" "$flag" + elif [[ "$gui_on_after_reboot" == 1 ]]; then + gui_control 'ON_AFTER_REBOOT' "$target" "$remote" "$flag" + elif [[ "$gui_off_after_reboot" == 1 ]]; then + gui_control 'OFF_AFTER_REBOOT' "$target" "$remote" "$flag" fi if [[ -n "$unload_module" ]]; then @@ -208,6 +216,8 @@ function gui_control() local isolate_target local remote local port + local set_default='false' + local default_command flag=${flag:-'SILENT'} @@ -215,15 +225,34 @@ function gui_control() isolate_target='graphical.target' vt_console=1 gui_control_cmd="${configurations[gui_on]}" - else + elif [[ "$operation" == 'OFF' ]]; then isolate_target='multi-user.target' vt_console=0 gui_control_cmd="${configurations[gui_off]}" + elif [[ "$operation" == 'ON_AFTER_REBOOT' ]]; then + isolate_target='graphical.target' + vt_console=1 + gui_control_cmd="${configurations[gui_on_after_reboot]}" + set_default='true' + warning 'This option will take effect after reboot' >&2 + elif [[ "$operation" == 'OFF_AFTER_REBOOT' ]]; then + isolate_target='multi-user.target' + vt_console=0 + gui_control_cmd="${configurations[gui_off_after_reboot]}" + set_default='true' + warning 'This option will take effect after reboot' >&2 fi # If the user does not override the turn on/off command we use the default # systemctl - gui_control_cmd=${gui_control_cmd:-"systemctl isolate ${isolate_target}"} + + if [[ "$set_default" == 'true' ]]; then + default_command="systemctl set-default ${isolate_target}" + else + default_command="systemctl isolate ${isolate_target}" + fi + + gui_control_cmd=${gui_control_cmd:-"${default_command}"} bind_control_cmd='for i in /sys/class/vtconsole/*/bind; do printf "%s\n" '$vt_console' > $i; done; sleep 0.5' # is this right? case "$target" in @@ -360,8 +389,8 @@ function get_supported_mode_per_connector() function parse_drm_options() { - local long_options='remote:,local,gui-on,gui-off,load-module:,unload-module:,help,verbose' - long_options+=',conn-available,modes' + local long_options='remote:,local,gui-on,gui-off,gui-on-after-reboot,gui-off-after-reboot' + long_options+=',load-module:,unload-module:,help,verbose,conn-available,modes' local short_options='h' local raw_options="$*" local options @@ -378,6 +407,8 @@ function parse_drm_options() options_values['GUI_ON']='' options_values['GUI_OFF']='' + options_values['GUI_ON_AFTER_REBOOT']='' + options_values['GUI_OFF_AFTER_REBOOT']='' options_values['CONN_AVAILABLE']='' options_values['HELP']='' options_values['LOAD_MODULE']='' @@ -428,6 +459,14 @@ function parse_drm_options() options_values['GUI_OFF']=1 shift ;; + --gui-on-after-reboot) + options_values['GUI_ON_AFTER_REBOOT']=1 + shift + ;; + --gui-off-after-reboot) + options_values['GUI_OFF_AFTER_REBOOT']=1 + shift + ;; --load-module) #options_values['LOAD_MODULE']=$(cut -d '=' -f2- <<< "$option") if [[ "$2" =~ ^-- ]]; then @@ -489,6 +528,8 @@ function drm_help() ' drm [--local | --remote [:]] (-um|--unload-module)=[;;...]' \ ' drm [--local | --remote [:]] --gui-on' \ ' drm [--local | --remote [:]] --gui-off' \ + ' drm [--local | --remote [:]] --gui-on-after-reboot' \ + ' drm [--local | --remote [:]] --gui-off-after-reboot' \ ' drm [--local | --remote [:]] --conn-available' \ ' drm [--local | --remote [:]] --verbose' \ ' drm [--local | --remote [:]] --modes' diff --git a/tests/unit/drm_plugin_test.sh b/tests/unit/drm_plugin_test.sh index 46f496697..d76e41514 100755 --- a/tests/unit/drm_plugin_test.sh +++ b/tests/unit/drm_plugin_test.sh @@ -26,6 +26,9 @@ function setUp() # Parser default config file for the average case parse_configuration "$KW_CONFIG_SAMPLE" + + export bind_cmd='for i in /sys/class/vtconsole/*/bind; do printf "%s\n" 1 > $i; done; sleep 0.5' + export unbind_cmd='for i in /sys/class/vtconsole/*/bind; do printf "%s\n" 0 > $i; done; sleep 0.5' } function tearDown() @@ -113,6 +116,8 @@ function test_drm_parser_options() assertEquals "($LINENO)" '' "${options_values['GUI_ON']}" assertEquals "($LINENO)" '' "${options_values['GUI_OFF']}" + assertEquals "${LINENO}" '' "${options_values['GUI_ON_AFTER_REBOOT']}" + assertEquals "${LINENO}" '' "${options_values['GUI_OFF_AFTER_REBOOT']}" assertEquals "($LINENO)" '' "${options_values['CONN_AVAILABLE']}" assertEquals "($LINENO)" '' "${options_values['MODES_AVAILABLE']}" @@ -122,8 +127,14 @@ function test_drm_parser_options() parse_drm_options --gui-off assertEquals "($LINENO)" 1 "${options_values['GUI_OFF']}" + parse_drm_options --gui-on-after-reboot + assertEquals "${LINENO}" 1 "${options_values['GUI_ON_AFTER_REBOOT']}" + + parse_drm_options --gui-off-after-reboot + assertEquals "${LINENO}" 1 "${options_values['GUI_OFF_AFTER_REBOOT']}" + parse_drm_options --verbose - assertEquals "($LINENO)" 1 "${options_values['VERBOSE']}" + assertEquals "${LINENO}" 1 "${options_values['VERBOSE']}" parse_drm_options --conn-available assertEquals "($LINENO)" 1 "${options_values['CONN_AVAILABLE']}" @@ -162,8 +173,6 @@ function test_gui_control_remote() { local gui_on_cmd='systemctl isolate graphical.target' local gui_off_cmd='systemctl isolate multi-user.target' - local bind_cmd='for i in /sys/class/vtconsole/*/bind; do printf "%s\n" 1 > $i; done; sleep 0.5' - local unbind_cmd='for i in /sys/class/vtconsole/*/bind; do printf "%s\n" 0 > $i; done; sleep 0.5' local output # Remote @@ -173,7 +182,7 @@ function test_gui_control_remote() tearDown # We want to test the default cases first # REMOTE = 3 - ssh_part="ssh -p 8888 juca@127.0.0.1" + ssh_part='ssh -p 8888 juca@127.0.0.1' full_turn_on_gui_cmd="${ssh_part} sudo \"${gui_on_cmd}\"" full_bind_cmd="${ssh_part} 'sudo bash -c '\''${bind_cmd}'\'" @@ -228,16 +237,113 @@ function test_gui_control_remote() compare_command_sequence '' "$LINENO" 'expected_cmd_seq' "$output" } +function test_gui_control_on_after_reboot_local() +{ + local gui_on_after_reboot_cmd='systemctl set-default graphical.target' + local output + + # Remote + remote_parameters['REMOTE_IP']='127.0.0.1' + remote_parameters['REMOTE_PORT']='8888' + remote_parameters['REMOTE_USER']='juca' + + tearDown # We want to test the default cases first + + ssh_part='ssh -p 8888 juca@127.0.0.1' + full_turn_on_gui_after_reboot_cmd="${ssh_part} sudo \"${gui_on_after_reboot_cmd}\"" + full_bind_cmd="${ssh_part} 'sudo bash -c '\''${bind_cmd}'\'" + + declare -a expected_cmd_seq=( + "$full_turn_on_gui_after_reboot_cmd" + "$full_bind_cmd" + ) + + output=$(gui_control 'ON_AFTER_REBOOT' '3' '127.0.0.1:8888' 'TEST_MODE') + compare_command_sequence '' "${LINENO}" 'expected_cmd_seq' "${output}" + + # Test with config file + parse_configuration "$KW_CONFIG_SAMPLE" + + # Remote + remote_parameters['REMOTE_PORT']='3333' + + ssh_part="ssh -p 3333 juca@127.0.0.1" + + gui_on_after_reboot_cmd='turn on after reboot' + full_turn_on_gui_after_reboot_cmd="${ssh_part} sudo \"${gui_on_after_reboot_cmd}\"" + full_bind_cmd="${ssh_part} 'sudo bash -c '\''${bind_cmd}'\'" + + declare -a expected_cmd_seq=( + "$full_turn_on_gui_after_reboot_cmd" + "$full_bind_cmd" + ) + + output=$(gui_control 'ON_AFTER_REBOOT' '3' '' 'TEST_MODE') + compare_command_sequence '' "${LINENO}" 'expected_cmd_seq' "${output}" + +} + +function test_gui_control_off_after_reboot_local() +{ + local gui_off_after_reboot_cmd='systemctl set-default multi-user.target' + local output + + # Remote + remote_parameters['REMOTE_IP']='127.0.0.1' + remote_parameters['REMOTE_PORT']='8888' + remote_parameters['REMOTE_USER']='juca' + + tearDown # We want to test the default cases first + + ssh_part='ssh -p 8888 juca@127.0.0.1' + + full_turn_off_gui_after_reboot_cmd="${ssh_part} sudo \"${gui_off_after_reboot_cmd}\"" + full_unbind_cmd="$ssh_part 'sudo bash -c '\''${unbind_cmd}'\'" + + declare -a expected_cmd_seq=( + "$full_turn_off_gui_after_reboot_cmd" + "$full_unbind_cmd" + ) + + output=$(gui_control 'OFF_AFTER_REBOOT' '3' '127.0.0.1:8888' 'TEST_MODE') + compare_command_sequence '' "${LINENO}" 'expected_cmd_seq' "${output}" + + # Test with config file + parse_configuration "$KW_CONFIG_SAMPLE" + + # Remote + remote_parameters['REMOTE_PORT']='3333' + + ssh_part="ssh -p 3333 juca@127.0.0.1" + + gui_off_after_reboot_cmd='turn off after reboot' + full_turn_off_gui_after_reboot_cmd="${ssh_part} sudo \"${gui_off_after_reboot_cmd}\"" + full_unbind_cmd="${ssh_part} 'sudo bash -c '\''${unbind_cmd}'\'" + + declare -a expected_cmd_seq=( + "$full_turn_off_gui_after_reboot_cmd" + "$full_unbind_cmd" + ) + + output=$(gui_control 'OFF_AFTER_REBOOT' '3' '' 'TEST_MODE') + compare_command_sequence '' "${LINENO}" 'expected_cmd_seq' "${output}" + +} + function test_gui_control_local() { local gui_on_cmd='systemctl isolate graphical.target' local gui_off_cmd='systemctl isolate multi-user.target' + local gui_on_after_reboot_cmd='systemctl set-default graphical.target' + local gui_off_after_reboot_cmd='systemctl set-default multi-user.target' local bind_cmd='for i in /sys/class/vtconsole/*/bind; do printf "%s\n" 1 > $i; done; sleep 0.5' local unbind_cmd='for i in /sys/class/vtconsole/*/bind; do printf "%s\n" 0 > $i; done; sleep 0.5' local output configurations[gui_on]="$gui_on_cmd" configurations[gui_off]="$gui_off_cmd" + configurations[gui_on_after_reboot]="$gui_on_after_reboot_cmd" + configurations[gui_off_after_reboot]="$gui_off_after_reboot_cmd" declare -a expected_cmd_seq=( "sudo ${gui_on_cmd}" @@ -254,6 +360,25 @@ function test_gui_control_local() output=$(gui_control 'OFF' '2' '' 'TEST_MODE') compare_command_sequence '' "$LINENO" 'expected_cmd_seq' "$output" + + # Test GUI ON after reboot + declare -a expected_cmd_seq=( + "sudo ${gui_on_after_reboot_cmd}" + "sudo ${bind_cmd}" + ) + + output=$(gui_control 'ON_AFTER_REBOOT' '2' '' 'TEST_MODE') + compare_command_sequence '' "$LINENO" 'expected_cmd_seq' "$output" + + # Test GUI OFF after reboot + declare -a expected_cmd_seq=( + "sudo ${gui_off_after_reboot_cmd}" + "sudo ${unbind_cmd}" + ) + + output=$(gui_control 'OFF_AFTER_REBOOT' '2' '' 'TEST_MODE') + compare_command_sequence '' "$LINENO" 'expected_cmd_seq' "$output" + } function test_get_available_connectors_local() diff --git a/tests/unit/lib/kw_config_loader_test.sh b/tests/unit/lib/kw_config_loader_test.sh index 0e776a39f..13d21b6e3 100755 --- a/tests/unit/lib/kw_config_loader_test.sh +++ b/tests/unit/lib/kw_config_loader_test.sh @@ -119,6 +119,8 @@ function test_parse_configuration_check_parser_values_only_for_kworkflow_config_ [ssh_port]='3333' [gui_on]='turn on' [gui_off]='turn off' + [gui_on_after_reboot]='turn on after reboot' + [gui_off_after_reboot]='turn off after reboot' [checkpatch_opts]='--no-tree --color=always --strict' [get_maintainer_opts]='--separator , --nokeywords --nogit --nogit-fallback --norolestats' ) diff --git a/tests/unit/samples/kworkflow.config b/tests/unit/samples/kworkflow.config index 980a1fe6e..037f935b2 100644 --- a/tests/unit/samples/kworkflow.config +++ b/tests/unit/samples/kworkflow.config @@ -3,5 +3,7 @@ ssh_ip=127.0.0.1 ssh_port=3333 gui_on=turn on gui_off=turn off +gui_on_after_reboot=turn on after reboot +gui_off_after_reboot=turn off after reboot checkpatch_opts=--no-tree --color=always --strict get_maintainer_opts=--separator , --nokeywords --nogit --nogit-fallback --norolestats From defa940391552e93eec6aab02f480111ced941a9 Mon Sep 17 00:00:00 2001 From: Lincoln Yuji Date: Thu, 23 May 2024 20:25:50 -0300 Subject: [PATCH 100/128] tests: unit: maintainers_test: Add failing tests The kw 'maintainers' feature lacks tests for its multiple corner cases where it should fail. Adding such tests ensures a larger test coverage for expected behaviors of this feature, possibly preventing future accidental undesirable changes. Signed-off-by: Rodrigo Siqueira Co-authored-by: Luiza Soezima Co-authored-by: Sabrina Araujo Signed-off-by: Lincoln Yuji Reviewed-by: Rodrigo Siqueira --- tests/unit/maintainers_test.sh | 187 ++++++++++++++++++--- tests/unit/samples/cover_letter_test.patch | 21 +++ 2 files changed, 184 insertions(+), 24 deletions(-) create mode 100644 tests/unit/samples/cover_letter_test.patch diff --git a/tests/unit/maintainers_test.sh b/tests/unit/maintainers_test.sh index 410719e8c..80a9bfc13 100755 --- a/tests/unit/maintainers_test.sh +++ b/tests/unit/maintainers_test.sh @@ -44,6 +44,9 @@ Maintainers already in 'To:' field of update_patch_test.patch" FAKE_KERNEL="tests/.tmp" +# Original directory path to go back before each test function +ORIGINAL_DIR="$PWD" + function oneTimeSetUp() { # This creates tests/.tmp which should mock a kernel tree root. A .git @@ -55,8 +58,9 @@ function oneTimeSetUp() cp -f tests/unit/samples/MAINTAINERS "$FAKE_KERNEL"/MAINTAINERS cp -f tests/unit/samples/external/get_maintainer.pl "$FAKE_KERNEL"/scripts/ cp -f tests/unit/samples/update_patch_test{_model,}{,2}.patch "$FAKE_KERNEL"/ + cp --force 'tests/unit/samples/cover_letter_test.patch' "$FAKE_KERNEL" cd "$FAKE_KERNEL" || { - fail "($LINENO) It was not possible to move to temporary directory" + fail "(${LINENO}) It was not possible to move to temporary directory" return } touch fs/some_file @@ -66,7 +70,7 @@ function oneTimeSetUp() git config user.email kw@kw git commit --quiet -m "Test message" cd "$original_dir" || { - fail "($LINENO) It was not possible to move back from temp directory" + fail "(${LINENO}) It was not possible to move back from temp directory" return } @@ -78,6 +82,27 @@ function oneTimeTearDown() rm -rf "$FAKE_KERNEL" } +function setUp() +{ + # Ensure each test function starts running in ORIGINAL_DIR. + cd "$ORIGINAL_DIR" || { + fail "(${LINENO}) It was not possible to move to original dir" + return + } +} + +function tearDown() +{ + # Check if SHUNIT_TMPDIR can be safely removed and then remove it and remake it. + is_safe_path_to_remove "$SHUNIT_TMPDIR" + if [[ "$?" == 0 ]]; then + rm --recursive --force "$SHUNIT_TMPDIR" + mkdir --parents "$SHUNIT_TMPDIR" + else + fail 'It was not possible to safely remove SHUNIT tmp directory.' + fi +} + function test_print_files_authors() { local -r ret=$(print_files_authors "tests/unit/samples/print_file_author_test_dir/code1.c") @@ -93,13 +118,12 @@ function test_print_files_authors_from_dir() function test_maintainers_main() { local ret - local -r original_dir="$PWD" ret="$(maintainers_main tests/.tmp)" multilineAssertEquals "$ret" "$CORRECT_TMP_MSG" cd "$FAKE_KERNEL" || { - fail "($LINENO) It was not possible to move to temporary directory" + fail "(${LINENO}) It was not possible to move to temporary directory" return } ret="$(maintainers_main .)" @@ -109,7 +133,7 @@ function test_maintainers_main() multilineAssertEquals "$CORRECT_TMP_FS_MSG" "$ret" cd fs || { - fail "($LINENO) It was not possible to move to fs directory" + fail "(${LINENO}) It was not possible to move to fs directory" return } ret="$(maintainers_main ..)" @@ -117,49 +141,164 @@ function test_maintainers_main() ret="$(maintainers_main .)" multilineAssertEquals "$CORRECT_TMP_FS_MSG" "$ret" - cd "$original_dir" || { - fail "($LINENO) It was not possible to move back from temp directory" +} + +# This function tests expected behaviors for failure in +# parse_maintainers_options. +function test_parse_maintainers_options() +{ + local return_status + + cd "$FAKE_KERNEL" || { + fail "(${LINENO}) It was not possible to move to temporary directory" return } + + # Invalid option (typo) + unset options_values + declare -gA options_values + parse_maintainers_options --update-pacth # Messy argument + return_status="$?" + assertEquals "(${LINENO})" 22 "$return_status" + + # Invalid option (even with a correct one following it) + unset options_values + declare -gA options_values + parse_maintainers_options --update-patch --invalid-option + return_status="$?" + assertEquals "(${LINENO})" 22 "$return_status" + + # Too many arguments + unset options_values + declare -gA options_values + parse_maintainers_options --update-patch '.' 'some_file' + return_status="$?" + assertEquals "(${LINENO})" 22 "$return_status" +} + +function test_maintainers_main_update_patch_invalid_inputs() +{ + local return_status + local output_from_maintainers_main + + cd "$FAKE_KERNEL" || { + fail "(${LINENO}) It was not possible to move to temporary directory" + return + } + + output_from_maintainers_main="$(maintainers_main --update-patch 'fs/some_file')" + return_status="$?" + assertEquals "(${LINENO})" 'Option --update-patch was passed but given path is not a patch.' "$output_from_maintainers_main" + assertEquals "(${LINENO})" 1 "$return_status" + + output_from_maintainers_main="$(maintainers_main --update-patch 'cover_letter_test.patch')" + return_status="$?" + assertEquals "(${LINENO})" 'Option --update-patch was passed but given path is not a patch.' "$output_from_maintainers_main" + assertEquals "(${LINENO})" 1 "$return_status" +} + +# This function tests cases where the maintainers_main is called outside +# of a kernel tree and the given path is not in a kernel tree either. +function test_maintainers_main_no_kernel() +{ + local return_status + local output_from_maintainers_main + + # Going outside of a kernel tree + cd "$SHUNIT_TMPDIR" || { + fail "(${LINENO}) It was not possible to move to temporary directory" + return + } + mkdir 'not-a-kernel' + + # Testing with default value + output_from_maintainers_main="$(maintainers_main)" + return_status="$?" + assertEquals "(${LINENO})" 'Neither the given path nor the working path is in a kernel tree.' "$output_from_maintainers_main" + assertEquals "(${LINENO})" 1 "$return_status" + + # Testing while giving a path + output_from_maintainers_main="$(maintainers_main ./not-a-kernel)" + return_status="$?" + assertEquals "(${LINENO})" 'Neither the given path nor the working path is in a kernel tree.' "$output_from_maintainers_main" + assertEquals "(${LINENO})" 1 "$return_status" +} + +# This function tests cases where the maintainers_main is called inside +# a kernel tree, but the given path is not a patch and is outside a kernel tree. +function test_maintainers_main_path_out_of_tree() +{ + local return_status + local output_from_maintainers_main + + cd "$FAKE_KERNEL" || { + fail "(${LINENO}) It was not possible to move to temporary directory" + return + } + + output_from_maintainers_main="$(maintainers_main ..)" + return_status="$?" + assertEquals "(${LINENO})" 'The given file is not a patch and is outside a kernel tree.' "$output_from_maintainers_main" + assertEquals "(${LINENO})" 1 "$return_status" +} + +# This function tests cases where the given paths to maintainers_main are invalid +function test_maintainers_main_invalid_paths() +{ + local return_status + local output_from_maintainers_main + + cd "$FAKE_KERNEL" || { + fail "(${LINENO}) It was not possible to move to temporary directory" + return + } + + # Test for files that don't exist in current directory + output_from_maintainers_main="$(maintainers_main 'file-does-not-exist.c')" + return_status="$?" + assertEquals "(${LINENO})" 'Invalid path' "$output_from_maintainers_main" + assertEquals "(${LINENO})" 1 "$return_status" + + # Test for files that don't exist in an other existing directory + output_from_maintainers_main="$(maintainers_main "$SHUNIT_TMPDIR/not-a-file.c")" + return_status="$?" + assertEquals "(${LINENO})" 'Invalid path' "$output_from_maintainers_main" + assertEquals "(${LINENO})" 1 "$return_status" } function test_maintainers_main_patch() { - local original_dir="$PWD" + local return_status + cd "$FAKE_KERNEL" || { - fail "($LINENO) It was not possible to move to temporary directory" + fail "(${LINENO}) It was not possible to move to temporary directory" return } - ret="$(maintainers_main update_patch_test.patch)" - multilineAssertEquals "$CORRECT_TMP_MSG" "$ret" + return_status="$(maintainers_main update_patch_test.patch)" + multilineAssertEquals "$CORRECT_TMP_MSG" "$return_status" # test -u cp -f update_patch_test.patch{,.bak} - ret="$(maintainers_main -u update_patch_test.patch)" - multilineAssertEquals "$CORRECT_TMP_PATCH_MSG" "$ret" + return_status="$(maintainers_main -u update_patch_test.patch)" + multilineAssertEquals "$CORRECT_TMP_PATCH_MSG" "$return_status" assertFileEquals update_patch_test{,_model}.patch cp -f update_patch_test.patch{.bak,} # test --update-patch - ret="$(maintainers_main --update-patch update_patch_test.patch)" - multilineAssertEquals "$CORRECT_TMP_PATCH_MSG" "$ret" + return_status="$(maintainers_main --update-patch update_patch_test.patch)" + multilineAssertEquals "$CORRECT_TMP_PATCH_MSG" "$return_status" assertFileEquals update_patch_test{,_model}.patch # test for already existing maintainers - ret="$(maintainers_main -u update_patch_test.patch)" - multilineAssertEquals "$CORRECT_TMP_PATCH_ALREADY_IN_MSG" "$ret" + return_status="$(maintainers_main -u update_patch_test.patch)" + multilineAssertEquals "$CORRECT_TMP_PATCH_ALREADY_IN_MSG" "$return_status" assertFileEquals update_patch_test{,_model}.patch # test for already existing "To:" field without maintainers - ret="$(maintainers_main -u update_patch_test2.patch)" - multilineAssertEquals "$CORRECT_TMP_PATCH2_MSG" "$ret" + return_status="$(maintainers_main -u update_patch_test2.patch)" + multilineAssertEquals "$CORRECT_TMP_PATCH2_MSG" "$return_status" assertFileEquals update_patch_test{,_model}2.patch - - cd "$original_dir" || { - fail "($LINENO) It was not possible to move back from temp directory" - return - } } invoke_shunit diff --git a/tests/unit/samples/cover_letter_test.patch b/tests/unit/samples/cover_letter_test.patch new file mode 100644 index 000000000..bc7398ff2 --- /dev/null +++ b/tests/unit/samples/cover_letter_test.patch @@ -0,0 +1,21 @@ +From 2741c6a546f4e0b148f7211def92a8843b9e0972 Mon Sep 17 00:00:00 2001 +From: kw +Date: Fri, 23 May 2023 09:04:44 -0300 +Subject: [PATCH 0/2] Cover letter example + +This is an example of a cover letter for testing purposes. +There are not actual pacthes related to this file and the +following modified files do not exist. + +kw (2): + src: art3435: Add failure paths as corner cases + test: unit: art3435_test: Add failing tests + + src/art3435.c | 34 ++++++++++++++++++ + test/unit/art3435.sh | 86 ++++++++++++++++++++++++++++++++++ + + 2 files changed, 120 insertions(+) + +-- +2.34.1 + From e4e385d02f391ad8c3c06193844a2596413f4386 Mon Sep 17 00:00:00 2001 From: Lorenzo Bertin Salvador Date: Mon, 29 Apr 2024 22:20:13 -0300 Subject: [PATCH 101/128] src: plugins: kernel_install: utils: add regex support for `kw deploy --uninstall` Currently, `kw deploy --uninstall` just supports a comma-separated kernel list, but for some cases it's better to provide a regex pattern that will match the desired kernels to be uninstalled. In this sense, add support for regex arguments for the option. Note that regex arguments should be prefixed with 'regex:'. Closes: #344 Reviewed-by: David Tadokoro Signed-off-by: Lorenzo Bertin Salvador Co-authored-by: Briza Mel Dias de Sousa Signed-off-by: David Tadokoro --- documentation/man/features/kw-deploy.rst | 19 +- src/plugins/kernel_install/utils.sh | 79 +++++- tests/unit/deploy_test.sh | 8 + .../unit/plugins/kernel_install/utils_test.sh | 229 +++++++++++++++--- 4 files changed, 293 insertions(+), 42 deletions(-) diff --git a/documentation/man/features/kw-deploy.rst b/documentation/man/features/kw-deploy.rst index 116cda646..f91180a78 100644 --- a/documentation/man/features/kw-deploy.rst +++ b/documentation/man/features/kw-deploy.rst @@ -85,9 +85,10 @@ OPTIONS -s, \--ls-line: List available kernels separated by comma. --u [,...], \--uninstall [,...]: +-u ( | regex:)[,...], \--uninstall ( | regex:)[,...]: Remove a single kernel or multiple kernels; for removing - multiple kernels it is necessary to separate them with comma. + multiple kernels it is necessary to separate them with comma. A regex pattern + can also be passed as input, prefixed with 'regex:'. -f, \--force: Remove kernels even if they were not installed by kw (only valid with @@ -153,3 +154,17 @@ any other kw user. If you want to install a custom kernel from this package, you can use:: kw deploy --from-package 5.19.0-THIS-IS-AN-EXAMPLE+.kw.tar + +Below are examples of how to use `kw deploy --uninstall`: + +1) Full kernel name argument + + kw deploy --uninstall 'kernel1' + +2) Regular expression argument + + kw deploy --uninstall 'regex:kernel.*' + +3) Comma-separated list of full kernel names and regular expressions + + kw deploy --uninstall 'regex:kernel[1-3],kernel4,regex:kernel[5-6]' diff --git a/src/plugins/kernel_install/utils.sh b/src/plugins/kernel_install/utils.sh index c59e06254..25309b0fd 100644 --- a/src/plugins/kernel_install/utils.sh +++ b/src/plugins/kernel_install/utils.sh @@ -551,32 +551,89 @@ function do_uninstall() fi } +# Checks if an element is contained in a given array. +# +# @target_element: Target element to check +# @_array: Indexed array reference to target array +# +# Return: +# Returns 0 if `@target_element` is in `@_array` and 1 otherwise. +function is_in_array() +{ + local target_element="$1" + local -n _array="$2" + + for element in "${_array[@]}"; do + [[ "$element" == "$target_element" ]] && return 0 + done + return 1 +} + +# Returns an unique list of names for the available kernels. +# +# @all_kernels: List all available kernels if set, besides those managed kw +# @prefix: Base prefix for searching available kernels +# @_processsed_installed_kernels: Indexed array reference where the list will be +# stored. The indexed array will be cleared prior to the storing. +# +# Return: +# Returns array containing available kernels in `@_processed_installed_kernels`. +function process_installed_kernels() +{ + local all_kernels="$1" + local prefix="$2" + local -n _processed_installed_kernels="$3" + local kernels + + _processed_installed_kernels=() + kernels=$(list_installed_kernels 'SILENT' 1 "$all_kernels" "$prefix") + IFS=, read -r -a available_kernels <<< "$kernels" + mapfile -t _processed_installed_kernels <<< "$(printf "%s\n" "${available_kernels[@]}" | sort --unique)" +} + function kernel_uninstall() { local reboot="$1" local target="$2" - local kernel_list_string="$3" + local kernel_list_string_or_regex="$3" local flag="$4" local force="$5" local prefix="$6" local update_grub=0 + local -a all_installed_kernels + local -a kw_managed_kernels + local prefix_for_regex='regex:' + local regex_expression + declare -A kernel_names + + if [[ -z "$kernel_list_string_or_regex" ]]; then + printf '%s\n' 'Invalid argument' + exit 22 #EINVAL + fi cmd_manager "$flag" "sudo mkdir -p $REMOTE_KW_DEPLOY" cmd_manager "$flag" "sudo touch '$INSTALLED_KERNELS_PATH'" - kernel_list_string=$(printf '%s' "$kernel_list_string" | tr --delete ' ') + process_installed_kernels 1 "$prefix" 'all_installed_kernels' + process_installed_kernels '' "$prefix" 'kw_managed_kernels' - if [[ -z "$kernel_list_string" ]]; then - printf '%s\n' 'Invalid argument' - exit 22 #EINVAL - fi + IFS=', ' read -r -a kernel_names_array <<< "$kernel_list_string_or_regex" - IFS=', ' read -r -a kernel_names <<< "$kernel_list_string" - for kernel in "${kernel_names[@]}"; do - cmd="sudo grep -q '$kernel' '$INSTALLED_KERNELS_PATH'" - cmd_manager "$flag" "$cmd" + for input_string in "${kernel_names_array[@]}"; do + for installed_kernel in "${all_installed_kernels[@]}"; do + if [[ "$input_string" =~ ^$prefix_for_regex ]]; then + regex_expression=^${input_string#"$prefix_for_regex"}$ + [[ "$installed_kernel" =~ $regex_expression ]] && kernel_names["$installed_kernel"]=1 + else + [[ "$installed_kernel" == "$input_string" ]] && kernel_names["$installed_kernel"]=1 + fi + done + done + + for kernel in "${!kernel_names[@]}"; do + is_in_array "$kernel" 'kw_managed_kernels' if [[ "$?" != 0 && -z "$force" ]]; then - printf '%s\n' "$kernel not managed by kw. Use --force/-f to uninstall anyway." + printf '%s\n' "${kernel} not managed by kw. Use --force/-f to uninstall anyway." continue # EINVAL fi diff --git a/tests/unit/deploy_test.sh b/tests/unit/deploy_test.sh index 3a3e905d1..ab2e825f3 100755 --- a/tests/unit/deploy_test.sh +++ b/tests/unit/deploy_test.sh @@ -684,6 +684,14 @@ function test_kernel_uninstall() deploy_remote_cmd+=" --uninstall-kernels '1' 'remote' '$single_kernel' 'TEST_MODE' ''" run_kernel_uninstall_cmd="ssh -p 3333 juca@127.0.0.1 sudo \"$deploy_remote_cmd\"" assert_equals_helper 'Reboot option' "$LINENO" "$run_kernel_uninstall_cmd" "$output" + + # Kernel with regex + output=$(run_kernel_uninstall 3 1 "regex:(5.*-rc7)" 'TEST_MODE' '' 1) + deploy_remote_cmd="$DEPLOY_REMOTE_PREFIX" + deploy_remote_cmd+=" --uninstall-kernels '1' 'remote' 'regex:(5.*-rc7)' 'TEST_MODE' ''" + run_kernel_uninstall_cmd="ssh -p 3333 juca@127.0.0.1 sudo \"$deploy_remote_cmd\"" + assert_equals_helper 'Regex option' "$LINENO" "$run_kernel_uninstall_cmd" "$output" + } function test_cleanup() diff --git a/tests/unit/plugins/kernel_install/utils_test.sh b/tests/unit/plugins/kernel_install/utils_test.sh index b1df9aa88..7a9d09236 100755 --- a/tests/unit/plugins/kernel_install/utils_test.sh +++ b/tests/unit/plugins/kernel_install/utils_test.sh @@ -52,7 +52,7 @@ function setUp() # Creating fake installed kernels touch "$INSTALLED_KERNELS_PATH" printf '5.5.0-rc2-VKMS+' >> "$INSTALLED_KERNELS_PATH" - printf '5.6.0-rc2-AMDGPU+' >> "$INSTALLED_KERNELS_PATH" + printf '\n%s' '5.6.0-rc2-AMDGPU+' >> "$INSTALLED_KERNELS_PATH" # Replace KW_DEPLOY_TMP_FILE test_tmp_file="$SHUNIT_TMPDIR/tmp/kw" @@ -206,30 +206,154 @@ function test_reboot_machine() assert_equals_helper 'Disable reboot in a non-local machine' "$LINENO" 'sudo -E reboot' "$output" } -function test_kernel_uninstall_unmanaged() +function test_is_in_array() { + local -a array=(1 2 3 4 5) + + is_in_array 0 'array' + assert_equals_helper 'Should return 1 (not present)' "$LINENO" 1 "$?" + is_in_array 4 'array' + assert_equals_helper 'Should return 0 (present)' "$LINENO" 0 "$?" +} + +function test_process_installed_kernels() +{ + local -a processed_installed_kernels + local original_list_installed_kernels_definition + + original_list_installed_kernels_definition=$(declare -f list_installed_kernels) + # shellcheck disable=SC2317 + function list_installed_kernels() + { + local all_kernels="$3" + + if [[ -n "$all_kernels" ]]; then + printf 'kernel1,kernel2,notmanaged' + else + printf 'kernel1,kernel2' + fi + } + + processed_installed_kernels=('should' 'be' 'cleared' 'prior') + process_installed_kernels '' '' 'processed_installed_kernels' + assert_equals_helper 'Wrong number of elements' "$LINENO" 2 "${#processed_installed_kernels[@]}" + assert_equals_helper 'Wrong element 0' "$LINENO" 'kernel1' "${processed_installed_kernels[0]}" + assert_equals_helper 'Wrong element 1' "$LINENO" 'kernel2' "${processed_installed_kernels[1]}" + + processed_installed_kernels=('should' 'be' 'cleared' 'prior') + process_installed_kernels 1 '' 'processed_installed_kernels' + assert_equals_helper 'Wrong number of elements' "$LINENO" 3 "${#processed_installed_kernels[@]}" + assert_equals_helper 'Wrong element 0' "$LINENO" 'kernel1' "${processed_installed_kernels[0]}" + assert_equals_helper 'Wrong element 1' "$LINENO" 'kernel2' "${processed_installed_kernels[1]}" + assert_equals_helper 'Wrong element 2' "$LINENO" 'notmanaged' "${processed_installed_kernels[2]}" + + eval "$original_list_installed_kernels_definition" +} + +function test_kernel_uninstall_regex_one_kernel() +{ + local kernel_name='5.5.0-rc2-VKMS+' + local mkinitcpio_d_path_1="etc/mkinitcpio.d/$kernel_name.preset" + local grub_cfg_path="${TARGET_PATH}/boot/grub/grub.cfg" local output - local -a expected - local output + local boot_files + local index - expected=( - '' # TODO: Figure out why we have these extra spaces here - "sudo mkdir -p $REMOTE_KW_DEPLOY" - '' - "sudo touch '$INSTALLED_KERNELS_PATH'" - '' - "sudo grep -q 'kname' '$INSTALLED_KERNELS_PATH'" - 'kname not managed by kw. Use --force/-f to uninstall anyway.' + cd "$SHUNIT_TMPDIR" || { + fail "(${LINENO}) It was not possible to move to temporary directory" + return + } + + # Composing expected command sequence + local -a cmd_sequence=( + "sudo mkdir -p ${REMOTE_KW_DEPLOY}" + "sudo touch '${INSTALLED_KERNELS_PATH}'" + "Removing: ${kernel_name}" ) + index=${#cmd_sequence[@]} + + boot_files=$(find "${TARGET_PATH}/boot/" -name "*${kernel_name}*" | sort) + # shellcheck disable=SC2068 + for file in ${boot_files[@]}; do + cmd_sequence["$((index++))"]="Removing: ${file}" + cmd_sequence["$((index++))"]="sudo -E rm ${file}" + done + + cmd_sequence["$((index++))"]="Can't find ${TARGET_PATH}/${mkinitcpio_d_path_1}" + cmd_sequence["$((index++))"]="Can't find ${TARGET_PATH}/var/lib/initramfs-tools/${kernel_name}" + cmd_sequence["$((index++))"]="Can't find ${TARGET_PATH}/lib/modules/${kernel_name}" + cmd_sequence["$((index++))"]="sudo sed -i '/${kernel_name}/d' '$INSTALLED_KERNELS_PATH'" + cmd_sequence["$((index++))"]='run_bootloader_update_mock' + + # Check + output=$(kernel_uninstall 0 'local' 'regex:.*VKMS.*' 'TEST_MODE' '' "$SHUNIT_TMPDIR") + compare_command_sequence '' "$LINENO" 'cmd_sequence' "$output" + + cd "$TEST_ROOT_PATH" || { + fail "($LINENO) It was not possible to move back from temp directory" + return + } +} + +function test_kernel_uninstall_regex_two_kernels() +{ + local kernel_name_1='5.5.0-rc2-VKMS+' + local kernel_name_2='5.6.0-rc2-AMDGPU+' + local mkinitcpio_d_path_1="etc/mkinitcpio.d/${kernel_name_1}.preset" + local mkinitcpio_d_path_2="etc/mkinitcpio.d/${kernel_name_2}.preset" + local output + local boot_files + local index - # Test unmanaged cd "$SHUNIT_TMPDIR" || { + fail "($LINENO) It was not possible to move to temporary directory" return } - output=$(kernel_uninstall '0' 'local' 'kname') - compare_command_sequence '' "$LINENO" 'expected' "$output" + # Composing expected command sequence + local -a cmd_sequence=( + "sudo mkdir -p ${REMOTE_KW_DEPLOY}" + "sudo touch '${INSTALLED_KERNELS_PATH}'" + "Removing: ${kernel_name_1}" + ) + index=${#cmd_sequence[@]} + + boot_files=$(find "${TARGET_PATH}/boot/" -name "*${kernel_name_1}*" | sort) + # shellcheck disable=SC2068 + for file in ${boot_files[@]}; do + cmd_sequence["$((index++))"]="Removing: ${file}" + cmd_sequence["$((index++))"]="sudo -E rm ${file}" + done + + cmd_sequence["$((index++))"]="Can't find ${TARGET_PATH}/${mkinitcpio_d_path_1}" + cmd_sequence["$((index++))"]="Can't find ${TARGET_PATH}/var/lib/initramfs-tools/${kernel_name_1}" + cmd_sequence["$((index++))"]="Can't find ${TARGET_PATH}/lib/modules/${kernel_name_1}" + cmd_sequence["$((index++))"]="sudo sed -i '/${kernel_name_1}/d' '$INSTALLED_KERNELS_PATH'" + cmd_sequence["$((index++))"]="Removing: ${kernel_name_2}" + + boot_files=$(find "${TARGET_PATH}/boot/" -name "*${kernel_name_2}*" | sort) + # shellcheck disable=SC2068 + for file in ${boot_files[@]}; do + cmd_sequence["$((index++))"]="Removing: ${file}" + cmd_sequence["$((index++))"]="sudo -E rm ${file}" + done + + cmd_sequence["$((index++))"]="Can't find ${TARGET_PATH}/${mkinitcpio_d_path_2}" + cmd_sequence["$((index++))"]="Can't find ${TARGET_PATH}/var/lib/initramfs-tools/${kernel_name_2}" + cmd_sequence["$((index++))"]="Can't find ${TARGET_PATH}/lib/modules/${kernel_name_2}" + cmd_sequence["$((index++))"]="sudo sed -i '/${kernel_name_2}/d' '$INSTALLED_KERNELS_PATH'" + cmd_sequence["$((index++))"]='run_bootloader_update_mock' + + # Check + output=$(kernel_uninstall 0 'local' '5.*' 'TEST_MODE' '' "$SHUNIT_TMPDIR") + compare_command_sequence '' "$LINENO" 'cmd_sequence' "$output" + output=$(kernel_uninstall 0 'local' 'regex:5\.5.*,regex:5\.6.*' 'TEST_MODE' '' "$SHUNIT_TMPDIR") + compare_command_sequence '' "$LINENO" 'cmd_sequence' "$output" + output=$(kernel_uninstall 0 'local' 'regex:5\.5.*,regex:5\.6.*' 'TEST_MODE' '' "$SHUNIT_TMPDIR") + compare_command_sequence '' "$LINENO" 'cmd_sequence' "$output" + output=$(kernel_uninstall 0 'local' 'regex:5\.5.*,5.6.0-rc2-AMDGPU+' 'TEST_MODE' '' "$SHUNIT_TMPDIR") + compare_command_sequence '' "$LINENO" 'cmd_sequence' "$output" cd "$TEST_ROOT_PATH" || { fail "($LINENO) It was not possible to move back from temp directory" @@ -237,32 +361,80 @@ function test_kernel_uninstall_unmanaged() } } +function test_kernel_uninstall_unmanaged() +{ + local target='5.5.0-rc2-NOTMANAGED' + local modules_lib_path="${TARGET_PATH}/lib/modules/${target}" + local initramfs_tools_var_path="${TARGET_PATH}/var/lib/initramfs-tools/${target}" + local mkinitcpio_d_path="${TARGET_PATH}/etc/mkinitcpio.d/${target}.preset" + local output + + # Notice that we are only testing the force feature, we did not create fake + # files, as a result we can't find files. + local -a cmd_sequence=( + "sudo mkdir -p ${REMOTE_KW_DEPLOY}" + "sudo touch '${INSTALLED_KERNELS_PATH}'" + "${target} not managed by kw. Use --force/-f to uninstall anyway." + ) + + mkdir -p "${TARGET_PATH}/boot" + printf '%s\n' "menuentry 'Arch Linux, with Linux 5.5.0-rc2-NOTMANAGED'" >> "${TARGET_PATH}/boot/grub/grub.cfg" + touch "${TARGET_PATH}/boot/vmlinuz-5.5.0-rc2-NOTMANAGED" + output=$(kernel_uninstall 0 'local' '5.5.0-rc2-NOTMANAGED' 'TEST_MODE' '' "$TARGET_PATH") + compare_command_sequence '' "$LINENO" 'cmd_sequence' "$output" + + rm "${TARGET_PATH}/boot/vmlinuz-5.5.0-rc2-NOTMANAGED" +} + function test_kernel_force_uninstall_unmanaged() { - local target='xpto' + local target='5.5.0-rc2-NOTMANAGED' + local grub_cfg_path="${TARGET_PATH}/boot/grub/grub.cfg" + local boot_path="${TARGET_PATH}/boot/vmlinuz-${target}" local modules_lib_path="${TARGET_PATH}/lib/modules/${target}" - local initramfs_tools_var_path="${TARGET_PATH}/var/lib/initramfs-tools/$target" + local initramfs_tools_var_path="${TARGET_PATH}/var/lib/initramfs-tools/${target}" local mkinitcpio_d_path="${TARGET_PATH}/etc/mkinitcpio.d/${target}.preset" local output # Notice that we are only testing the force feature, we did not create fake # files, as a result we can't find files. local -a cmd_sequence=( - "sudo mkdir -p $REMOTE_KW_DEPLOY" - "sudo touch '$INSTALLED_KERNELS_PATH'" - "sudo grep -q 'xpto' '$INSTALLED_KERNELS_PATH'" - "Removing: $target" - "Can't find $mkinitcpio_d_path" - "Can't find $initramfs_tools_var_path" - "Can't find $modules_lib_path" - "sudo sed -i '/xpto/d' '$INSTALLED_KERNELS_PATH'" + "sudo mkdir -p ${REMOTE_KW_DEPLOY}" + "sudo touch '${INSTALLED_KERNELS_PATH}'" + "Removing: ${target}" + "Removing: ${boot_path}" + "sudo -E rm ${boot_path}" + "Removing: ${mkinitcpio_d_path}" + "sudo -E rm ${mkinitcpio_d_path}" + "Removing: ${initramfs_tools_var_path}" + "sudo -E rm ${initramfs_tools_var_path}" + "Removing: ${modules_lib_path}" + "sudo -E rm -rf ${modules_lib_path}" + "sudo sed -i '/${target}/d' '${INSTALLED_KERNELS_PATH}'" 'run_bootloader_update_mock' ) mkdir -p "${TARGET_PATH}/boot" - - output=$(kernel_uninstall 0 'local' 'xpto' 'TEST_MODE' 1 "$TARGET_PATH") + mkdir -p "${TARGET_PATH}/lib/modules/" + mkdir -p "${TARGET_PATH}/var/lib/initramfs-tools" + mkdir -p "${TARGET_PATH}/etc/mkinitcpio.d" + + tmp_grub_cfg="${TARGET_PATH}/tmp/grub.cfg" + cp "$grub_cfg_path" "$tmp_grub_cfg" + printf '%s' "menuentry 'Arch Linux, with Linux 5.5.0-rc2-NOTMANAGED'" >> "$grub_cfg_path" + touch "$boot_path" + touch "$mkinitcpio_d_path" + touch "$initramfs_tools_var_path" + mkdir -p "$modules_lib_path" + + output=$(kernel_uninstall 0 'local' '5.5.0-rc2-NOTMANAGED' 'TEST_MODE' 1 "$TARGET_PATH") compare_command_sequence '' "$LINENO" 'cmd_sequence' "$output" + + cp "$tmp_grub_cfg" "$grub_cfg_path" + rm "$boot_path" + rm "$mkinitcpio_d_path" + rm "$initramfs_tools_var_path" + rm -rf "$modules_lib_path" } function test_remove_managed_kernel_local() @@ -293,7 +465,6 @@ function test_remove_managed_kernel_local() local -a cmd_sequence=( "sudo mkdir -p $REMOTE_KW_DEPLOY" "sudo touch '$INSTALLED_KERNELS_PATH'" - "sudo grep -q '$kernel_name' '$INSTALLED_KERNELS_PATH'" "Removing: $kernel_name" ) @@ -323,7 +494,7 @@ function test_remove_managed_kernel_local() done # Check - output=$(kernel_uninstall 0 'local' '5.5.0-rc2-VKMS+' 'TEST_MODE' '' "$SHUNIT_TMPDIR/") + output=$(kernel_uninstall 0 'local' '5.5.0-rc2-VKMS+' 'TEST_MODE' 1 "$SHUNIT_TMPDIR/") compare_command_sequence '' "$LINENO" 'cmd_sequence' "$output" } From 6a3a8f8214ed646db25a7159c16b15490f4749e3 Mon Sep 17 00:00:00 2001 From: Marcelo Mendes Spessoto Junior Date: Fri, 14 Jun 2024 20:03:22 -0300 Subject: [PATCH 102/128] tests: unit: build_test: improve from_sha tests The unit tests for from_sha feature compare output and result by using the compare_command_sequence function. Replace them with assertEquals, which is more appropriate for one-line output pairs. Reviewed-by: Rodrigo Siqueira Signed-off-by: Marcelo Mendes Spessoto Junior Signed-off-by: Rodrigo Siqueira --- tests/unit/build_test.sh | 42 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/tests/unit/build_test.sh b/tests/unit/build_test.sh index c66671a59..19e83d014 100755 --- a/tests/unit/build_test.sh +++ b/tests/unit/build_test.sh @@ -870,11 +870,9 @@ function test_kernel_build_from_sha() mk_fake_git output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) - declare -a expected_result=( - "git rebase HEAD^ --exec 'kw build'" - ) + expected_result="git rebase HEAD^ --exec 'kw build'" - compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" + assertEquals "(${LINENO})" "$expected_result" "$output" } function test_kernel_build_from_sha_nonexisting_sha() @@ -886,11 +884,9 @@ function test_kernel_build_from_sha_nonexisting_sha() mk_fake_git output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) - declare -a expected_result=( - "ERROR: The given SHA (${sha}) does not represent a valid commit sha." - ) + expected_result="ERROR: The given SHA (${sha}) does not represent a valid commit sha." - compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" + assertEquals "(${LINENO})" "$expected_result" "$output" } function test_kernel_build_from_sha_sha_not_ancestor() @@ -902,11 +898,9 @@ function test_kernel_build_from_sha_sha_not_ancestor() mk_git_branch 'branch' output=$(build_kernel_main 'TEST_MODE' --from-sha branch) - declare -a expected_result=( - 'ERROR: Given SHA (branch) is invalid. Check if it is an ancestor of the branch head.' - ) + expected_result='ERROR: Given SHA (branch) is invalid. Check if it is an ancestor of the branch head.' - compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" + assertEquals "(${LINENO})" "$expected_result" "$output" } function test_kernel_build_from_sha_pending_rebase() @@ -919,11 +913,9 @@ function test_kernel_build_from_sha_pending_rebase() mkdir '.git/rebase-merge' output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) - declare -a expected_result=( - 'ERROR: Abort the repository rebase before continuing with build from sha (use "git rebase --abort")!' - ) + expected_result='ERROR: Abort the repository rebase before continuing with build from sha (use "git rebase --abort")!' - compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" + assertEquals "(${LINENO})" "$expected_result" "$output" } function test_kernel_build_from_sha_pending_merge() @@ -936,11 +928,9 @@ function test_kernel_build_from_sha_pending_merge() touch '.git/MERGE_HEAD' output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) - declare -a expected_result=( - 'ERROR: Abort the repository merge before continuing with build from sha (use "git rebase --abort")!' - ) + expected_result='ERROR: Abort the repository merge before continuing with build from sha (use "git rebase --abort")!' - compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" + assertEquals "(${LINENO})" "$expected_result" "$output" } function test_kernel_build_from_sha_pending_bisect() @@ -953,11 +943,9 @@ function test_kernel_build_from_sha_pending_bisect() touch '.git/BISECT_LOG' output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) - declare -a expected_result=( - 'ERROR: Stop the repository bisect before continuing with build from sha (use "git bisect reset")!' - ) + expected_result='ERROR: Stop the repository bisect before continuing with build from sha (use "git bisect reset")!' - compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" + assertEquals "(${LINENO})" "$expected_result" "$output" } function test_kernel_build_from_sha_pending_apply() @@ -970,11 +958,9 @@ function test_kernel_build_from_sha_pending_apply() mkdir '.git/rebase-apply' output=$(build_kernel_main 'TEST_MODE' --from-sha ${sha}) - declare -a expected_result=( - 'ERROR: Abort the repository patch apply before continuing with build from sha (use "git am --abort")!' - ) + expected_result='ERROR: Abort the repository patch apply before continuing with build from sha (use "git am --abort")!' - compare_command_sequence '' "(${LINENO})" 'expected_result' "$output" + assertEquals "(${LINENO})" "$expected_result" "$output" } function test_kernel_build_inside_an_env() From 36309b83d8fdfdb98fc49c2b896189e590a4de95 Mon Sep 17 00:00:00 2001 From: Lincoln Yuji Date: Fri, 14 Jun 2024 14:12:46 -0300 Subject: [PATCH 103/128] setup: Support Zsh completions for setups with ZDOTDIR paths Some users may like to follow the XDG Base Directory specification, and Zsh partially supports it as it allows the user to define environmental variables, such as ZDOTDIR, to override the default locations of dot files. With this commit, when there is no ~/.zshrc the setup script will now check if user has the ZDOTDIR directory defined and then if there is a .zshrc file inside. If it does, then the kw native Zsh completions necessary configs will be added to this file. Reviewed-by: David Tadokoro Signed-off-by: Lincoln Yuji Signed-off-by: David Tadokoro --- setup.sh | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/setup.sh b/setup.sh index 16561fdca..595416861 100755 --- a/setup.sh +++ b/setup.sh @@ -292,14 +292,14 @@ function remove_kw_from_PATH_variable() function update_path() { - local shellrc=${1:-'.bashrc'} + local shellrc="$1" IFS=':' read -ra ALL_PATHS <<< "$PATH" for path in "${ALL_PATHS[@]}"; do [[ "$path" -ef "$binpath" ]] && return done - safe_append "PATH=${HOME}/.local/bin:\$PATH # kw" "${HOME}/${shellrc}" + safe_append "PATH=${HOME}/.local/bin:\$PATH # kw" "$shellrc" } function update_current_bash() @@ -547,9 +547,9 @@ function synchronize_files() if command_exists 'bash'; then # Add tabcompletion to bashrc - if [[ -f "$HOME/.bashrc" || -L "$HOME/.bashrc" ]]; then + if [[ -f "${HOME}/.bashrc" || -L "${HOME}/.bashrc" ]]; then append_bashcompletion - update_path + update_path "${HOME}/.bashrc" else warning 'Unable to find a .bashrc file.' fi @@ -558,9 +558,14 @@ function synchronize_files() if command_exists 'zsh'; then # Add tabcompletion to zshrc if [[ -f "${HOME}/.zshrc" || -L "${HOME}/.zshrc" ]]; then - remove_legacy_zshcompletion - append_zshcompletion - update_path '.zshrc' + remove_legacy_zshcompletion "${HOME}/.zshrc" + append_zshcompletion "${HOME}/.zshrc" + update_path "${HOME}/.zshrc" + # Check for alternative path for .zshrc + elif [[ -d "$ZDOTDIR" && -f "${ZDOTDIR}/.zshrc" ]]; then + remove_legacy_zshcompletion "${ZDOTDIR}/.zshrc" + append_zshcompletion "${ZDOTDIR}/.zshrc" + update_path "${ZDOTDIR}/.zshrc" else warning 'Unable to find a .zshrc file.' fi @@ -586,16 +591,20 @@ function append_bashcompletion() function remove_legacy_zshcompletion() { - safe_remove '# Enable bash completion for zsh' "${HOME}/.zshrc" - safe_remove 'autoload bashcompinit && bashcompinit' "${HOME}/.zshrc" - safe_remove "source ${libdir}/${BASH_AUTOCOMPLETE}.sh" "${HOME}/.zshrc" + local zshrc_path="$1" + + safe_remove '# Enable bash completion for zsh' "${zshrc_path}" + safe_remove 'autoload bashcompinit && bashcompinit' "${zshrc_path}" + safe_remove "source ${libdir}/${BASH_AUTOCOMPLETE}.sh" "${zshrc_path}" } function append_zshcompletion() { - safe_append "# ${app_name}" "${HOME}/.zshrc" - safe_append "export fpath=(${libdir} \$fpath)" "${HOME}/.zshrc" - safe_append 'autoload compinit && compinit -i' "${HOME}/.zshrc" + local zshrc_path="$1" + + safe_append "# ${app_name}" "${zshrc_path}" + safe_append "export fpath=(${libdir} \$fpath)" "${zshrc_path}" + safe_append 'autoload compinit && compinit -i' "${zshrc_path}" } function safe_append() From 37cad041370700a612d50e86c6b9af8065c814c2 Mon Sep 17 00:00:00 2001 From: Fernando Yang Date: Thu, 6 Jun 2024 11:07:29 -0300 Subject: [PATCH 104/128] src: plugins: subsystems: drm: Correct shellcheck warning Correction to the SC2319 shellcheck warning about the possibility of overwriting the output value. To avoid this, the output value has been stored in a variable outside the if. Reviewed-by: David Tadokoro Signed-off-by: Fernando Yang Signed-off-by: David Tadokoro --- src/plugins/subsystems/drm/drm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/subsystems/drm/drm.sh b/src/plugins/subsystems/drm/drm.sh index 91d820589..3dda470b2 100644 --- a/src/plugins/subsystems/drm/drm.sh +++ b/src/plugins/subsystems/drm/drm.sh @@ -298,8 +298,8 @@ function get_available_connectors() case "$target" in 2) # LOCAL TARGET cards_raw_list=$(cmd_manager 'SILENT' "$find_conn_cmd" | sort --dictionary-order) + ret="$?" if [[ -f "$SYSFS_CLASS_DRM" ]]; then - ret="$?" complain "We cannot access ${SYSFS_CLASS_DRM}" return "$ret" # ENOENT fi From 0211c639ac684bb533357d5c2a1c6a0d4b82f005 Mon Sep 17 00:00:00 2001 From: Fernando Yang Date: Thu, 6 Jun 2024 11:22:05 -0300 Subject: [PATCH 105/128] src: plugins: subsystems: drm: show help when running kw drm without options When running kw drm without options, it will show now the list of available options, providing more user-friendly experience. Reviewed-by: David Tadokoro Signed-off-by: Fernando Yang Signed-off-by: David Tadokoro --- src/plugins/subsystems/drm/drm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/subsystems/drm/drm.sh b/src/plugins/subsystems/drm/drm.sh index 3dda470b2..604a29935 100644 --- a/src/plugins/subsystems/drm/drm.sh +++ b/src/plugins/subsystems/drm/drm.sh @@ -21,7 +21,7 @@ function drm_main() local test_mode local flag - if [[ "$*" =~ -h|--help ]]; then + if [[ "$*" =~ -h|--help || "$#" == 0 ]]; then drm_help "$*" exit 0 fi From 8ff5960c15ca472336bdc85cbec6889d6e72d68f Mon Sep 17 00:00:00 2001 From: Fernando Yang Date: Thu, 6 Jun 2024 11:29:00 -0300 Subject: [PATCH 106/128] src: plugins: subsystems: drm: Remove support for short options lm and rm Remove the short options -lm and -um, which don't work. Reviewed-by: David Tadokoro Signed-off-by: Fernando Yang Signed-off-by: David Tadokoro --- documentation/man/features/kw-drm.rst | 4 ++-- src/plugins/subsystems/drm/drm.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/man/features/kw-drm.rst b/documentation/man/features/kw-drm.rst index 4fbddaadb..5a46e088c 100644 --- a/documentation/man/features/kw-drm.rst +++ b/documentation/man/features/kw-drm.rst @@ -30,7 +30,7 @@ OPTIONS *default_deploy_target* (**deploy.config**) for identifying the target. It is important to highlight that the drm feature **does not support VM**. --lm, \--load-module=[:,...][;:...]: +\--load-module=[:,...][;:...]: Allow user to specify one or more modules to be load with or without parameters. If you want to indicate more than one module, you have to separate them using ';'. Additionally, if users wish to provide specific @@ -39,7 +39,7 @@ OPTIONS will make sure that the target module will be load first and after that trigger the GUI. --um=[;;...], \--unload-module=[;;...]: +\--unload-module=[;;...]: This option allows users to unload one or more DRM drivers. Users can provide a single module to be unloaded or a list separated by ';'. This command first disables the user interface and, after that, unloads the module. diff --git a/src/plugins/subsystems/drm/drm.sh b/src/plugins/subsystems/drm/drm.sh index 604a29935..68eb94d52 100644 --- a/src/plugins/subsystems/drm/drm.sh +++ b/src/plugins/subsystems/drm/drm.sh @@ -524,8 +524,8 @@ function drm_help() return fi printf '%s\n' 'Usage: kw drm [options]:' \ - ' drm [--local | --remote [:]] (-lm|--load-module)=[:,][;:...][;...]' \ - ' drm [--local | --remote [:]] (-um|--unload-module)=[;;...]' \ + ' drm [--local | --remote [:]] --load-module=[:,][;:...][;...]' \ + ' drm [--local | --remote [:]] --unload-module=[;;...]' \ ' drm [--local | --remote [:]] --gui-on' \ ' drm [--local | --remote [:]] --gui-off' \ ' drm [--local | --remote [:]] --gui-on-after-reboot' \ From a27a0cacf95a900729e5e9c865f872889ab49dbf Mon Sep 17 00:00:00 2001 From: Fernando Yang Date: Thu, 6 Jun 2024 11:47:17 -0300 Subject: [PATCH 107/128] src: plugins: subsystems: drm: add returns to [un]load_module functions Add the return of success message, indicating the module was effectively loaded/unloaded. Add error return in load_module and unload_module if the module hasn`t been unloaded successfully. Closes: #1002 Reviewed-by: David Tadokoro Signed-off-by: Fernando Yang Signed-off-by: David Tadokoro --- src/plugins/subsystems/drm/drm.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/subsystems/drm/drm.sh b/src/plugins/subsystems/drm/drm.sh index 68eb94d52..c7ca38530 100644 --- a/src/plugins/subsystems/drm/drm.sh +++ b/src/plugins/subsystems/drm/drm.sh @@ -60,8 +60,10 @@ function drm_main() if [[ -n "$load_module" ]]; then module_control 'LOAD' "$target" "$remote" "$load_module" "$flag" if [[ "$?" != 0 ]]; then + complain "Failure to load module ${load_module}" return 22 # EINVAL fi + success "Successfully loaded module ${load_module}" fi if [[ "$gui_on" == 1 ]]; then @@ -78,6 +80,11 @@ function drm_main() # For unload DRM drivers, we need to make sure that we turn off user GUI [[ "$gui_off" != 1 ]] && gui_control 'OFF' "$target" "$remote" module_control 'UNLOAD' "$target" "$remote" "$unload_module" "$flag" + if [[ "$?" != 0 ]]; then + complain "Failure to unload module ${unload_module}" + return 22 # EINVAL + fi + success "Successfully unloaded module ${unload_module}" fi if [[ "$conn_available" == 1 ]]; then From 7896c4ba44a662acea977abb22b8b02bbaf59e62 Mon Sep 17 00:00:00 2001 From: Thiago Duvanel Date: Tue, 28 May 2024 13:41:58 -0300 Subject: [PATCH 108/128] src: pomodoro: add `--repeat-previous` option to pomodoro Add the `--repeat-previous` option for `kw pomodoro`, which allows the user to repeat the last Pomodoro session without typing it all over again. Closes: #1009 Reviewed-by: David Tadokoro Signed-off-by: Thiago Duvanel Ferreira Signed-off-by: David Tadokoro --- documentation/man/features/kw-pomodoro.rst | 9 +++ src/_kw | 7 +- src/bash_autocomplete.sh | 2 +- src/pomodoro.sh | 89 +++++++++++++++++++++- tests/unit/pomodoro_test.sh | 50 ++++++++++++ 5 files changed, 152 insertions(+), 5 deletions(-) diff --git a/documentation/man/features/kw-pomodoro.rst b/documentation/man/features/kw-pomodoro.rst index 74ed33ec6..e534274e4 100644 --- a/documentation/man/features/kw-pomodoro.rst +++ b/documentation/man/features/kw-pomodoro.rst @@ -9,6 +9,7 @@ SYNOPSIS | *kw* (*p* | *pomodoro*) (-t | \--set-timer)