From 41204702bbd35fc0344f4bf4c159e03a061efc9d Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 5 Dec 2023 13:41:44 +0100 Subject: [PATCH] Squashed 'tests/lib/external/snapd-testing-tools/' content from commit 43533bd git-subtree-dir: tests/lib/external/snapd-testing-tools git-subtree-split: 43533bdd976fda6ede0e538467c2aa42954dc96d --- .github/labeler.yml | 6 + .github/workflows/labeler.yaml | 12 + .github/workflows/tests.yaml | 124 ++++ CODE_OF_CONDUCT.md | 76 ++ COPYING | 674 ++++++++++++++++++ README.md | 74 ++ remote/remote.exec | 88 +++ remote/remote.pull | 61 ++ remote/remote.push | 61 ++ remote/remote.refresh | 322 +++++++++ remote/remote.retry | 59 ++ remote/remote.setup | 100 +++ remote/remote.wait-for | 307 ++++++++ setup.sh | 11 + spread.yaml | 75 ++ tests/check-test-format/task.yaml | 42 ++ tests/check-test-format/tasks/task1.yaml | 9 + tests/check-test-format/tasks/task2.yaml | 9 + tests/check-test-format/tasks/task3.yaml | 7 + tests/check-test-format/tasks/task4.yaml | 8 + tests/check-test-format/tasks/task5.yaml | 10 + tests/check-test-format/tasks/task6.yaml | 6 + ...borted-and-failed-execute-and-restore.json | 443 ++++++++++++ ...aborted-and-failed-execute-and-restore.log | 82 +++ tests/log-analyzer/data/all-aborted.json | 215 ++++++ tests/log-analyzer/data/all-aborted.log | 40 ++ tests/log-analyzer/data/all-failed.json | 613 ++++++++++++++++ tests/log-analyzer/data/all-failed.log | 138 ++++ .../data/all-success-failed-restore.json | 453 ++++++++++++ .../data/all-success-failed-restore.log | 74 ++ tests/log-analyzer/data/all-success.json | 400 +++++++++++ tests/log-analyzer/data/all-success.log | 57 ++ .../data/failed-prepare-and-restore.json | 513 +++++++++++++ .../data/failed-prepare-and-restore.log | 91 +++ .../data/failed-prepare-project.json | 315 ++++++++ .../data/failed-prepare-project.log | 50 ++ .../data/failed-prepare-suite.json | 327 +++++++++ .../data/failed-prepare-suite.log | 50 ++ .../data/failed-prepare-task.json | 607 ++++++++++++++++ .../log-analyzer/data/failed-prepare-task.log | 94 +++ .../data/with-aborted-and-failed-restore.json | 285 ++++++++ .../data/with-aborted-and-failed-restore.log | 50 ++ .../with-failed-and-failed-restore-suite.json | 493 +++++++++++++ .../with-failed-and-failed-restore-suite.log | 79 ++ tests/log-analyzer/spread.yaml | 35 + tests/log-analyzer/task.yaml | 243 +++++++ tests/log-analyzer/tests/test-1/task.yaml | 10 + tests/log-analyzer/tests/test-2/task.yaml | 10 + tests/log-analyzer/tests/test-3/task.yaml | 10 + tests/log-analyzer/tests/test-4/task.yaml | 10 + tests/log-analyzer/tests/test-5/task.yaml | 10 + tests/log-parser/all-aborted.log.spread | 46 ++ tests/log-parser/all-successful.log.spread | 112 +++ tests/log-parser/task.yaml | 106 +++ tests/log-parser/with-all-results.log.spread | 163 +++++ .../with-failed-and-aborted.log.spread | 265 +++++++ .../with-failed-project-restore.log.spread | 146 ++++ ...ith-failed-repeated-and-aborted.log.spread | 154 ++++ .../with-failed-repeated.log.spread | 154 ++++ .../with-failed-suite-restore.log.spread | 146 ++++ tests/log-parser/with-failed.log.spread | 216 ++++++ .../with-results-in-detail.log.spread | 149 ++++ tests/not/task.yaml | 6 + tests/os.paths/task.yaml | 41 ++ tests/os.query/task.yaml | 171 +++++ tests/quiet/task.yaml | 9 + tests/remote.exec/task.yaml | 40 ++ tests/remote.pull/task.yaml | 33 + tests/remote.push/task.yaml | 33 + tests/remote.refresh/task.yaml | 56 ++ tests/remote.retry/task.yaml | 43 ++ tests/remote.setup/task.yaml | 54 ++ tests/remote.wait-for/task.yaml | 83 +++ tests/repack-kernel/task.yaml | 47 ++ tests/retry/task.yaml | 26 + tests/snaps.cleanup/task.yaml | 69 ++ tests/snaps.name/task.yaml | 25 + tests/spread-manager/checks/task1/task.yaml | 13 + tests/spread-manager/checks/task2/task.yaml | 15 + tests/spread-manager/checks/task3/task.yaml | 15 + tests/spread-manager/checks/task4/task.yaml | 15 + tests/spread-manager/checks/task5/.empty | 0 tests/spread-manager/spread.yaml | 12 + tests/spread-manager/task.yaml | 92 +++ tests/spread-shellcheck/task.yaml | 44 ++ tests/spread-shellcheck/tasks/task1 | 13 + tests/spread-shellcheck/tasks/task2 | 13 + tests/spread-shellcheck/tasks/task3 | 13 + tests/spread-shellcheck/tasks/task4 | 13 + tests/tests.backup/task.yaml | 59 ++ tests/tests.cleanup/task.yaml | 77 ++ tests/tests.pkgs/task.yaml | 48 ++ tests/tests.systemd/task.yaml | 64 ++ tools/not | 6 + tools/os.paths | 64 ++ tools/os.query | 286 ++++++++ tools/quiet | 32 + tools/repack-kernel | 230 ++++++ tools/retry | 157 ++++ tools/snaps.cleanup | 94 +++ tools/snaps.name | 77 ++ tools/tests.backup | 69 ++ tools/tests.cleanup | 97 +++ tools/tests.pkgs | 163 +++++ tools/tests.pkgs.apt.sh | 65 ++ tools/tests.pkgs.dnf-yum.sh | 75 ++ tools/tests.pkgs.pacman.sh | 71 ++ tools/tests.pkgs.zypper.sh | 66 ++ tools/tests.systemd | 177 +++++ utils/check-test-format | 149 ++++ utils/log-analyzer | 330 +++++++++ utils/log-parser | 590 +++++++++++++++ utils/spread-manager | 167 +++++ utils/spread-shellcheck | 413 +++++++++++ utils/spreadJ | 119 ++++ 115 files changed, 14334 insertions(+) create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/labeler.yaml create mode 100644 .github/workflows/tests.yaml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 COPYING create mode 100644 README.md create mode 100755 remote/remote.exec create mode 100755 remote/remote.pull create mode 100755 remote/remote.push create mode 100755 remote/remote.refresh create mode 100755 remote/remote.retry create mode 100755 remote/remote.setup create mode 100755 remote/remote.wait-for create mode 100755 setup.sh create mode 100644 spread.yaml create mode 100644 tests/check-test-format/task.yaml create mode 100644 tests/check-test-format/tasks/task1.yaml create mode 100644 tests/check-test-format/tasks/task2.yaml create mode 100644 tests/check-test-format/tasks/task3.yaml create mode 100644 tests/check-test-format/tasks/task4.yaml create mode 100644 tests/check-test-format/tasks/task5.yaml create mode 100644 tests/check-test-format/tasks/task6.yaml create mode 100644 tests/log-analyzer/data/aborted-and-failed-execute-and-restore.json create mode 100644 tests/log-analyzer/data/aborted-and-failed-execute-and-restore.log create mode 100644 tests/log-analyzer/data/all-aborted.json create mode 100644 tests/log-analyzer/data/all-aborted.log create mode 100644 tests/log-analyzer/data/all-failed.json create mode 100644 tests/log-analyzer/data/all-failed.log create mode 100644 tests/log-analyzer/data/all-success-failed-restore.json create mode 100644 tests/log-analyzer/data/all-success-failed-restore.log create mode 100644 tests/log-analyzer/data/all-success.json create mode 100644 tests/log-analyzer/data/all-success.log create mode 100644 tests/log-analyzer/data/failed-prepare-and-restore.json create mode 100644 tests/log-analyzer/data/failed-prepare-and-restore.log create mode 100644 tests/log-analyzer/data/failed-prepare-project.json create mode 100644 tests/log-analyzer/data/failed-prepare-project.log create mode 100644 tests/log-analyzer/data/failed-prepare-suite.json create mode 100644 tests/log-analyzer/data/failed-prepare-suite.log create mode 100644 tests/log-analyzer/data/failed-prepare-task.json create mode 100644 tests/log-analyzer/data/failed-prepare-task.log create mode 100644 tests/log-analyzer/data/with-aborted-and-failed-restore.json create mode 100644 tests/log-analyzer/data/with-aborted-and-failed-restore.log create mode 100644 tests/log-analyzer/data/with-failed-and-failed-restore-suite.json create mode 100644 tests/log-analyzer/data/with-failed-and-failed-restore-suite.log create mode 100644 tests/log-analyzer/spread.yaml create mode 100644 tests/log-analyzer/task.yaml create mode 100644 tests/log-analyzer/tests/test-1/task.yaml create mode 100644 tests/log-analyzer/tests/test-2/task.yaml create mode 100644 tests/log-analyzer/tests/test-3/task.yaml create mode 100644 tests/log-analyzer/tests/test-4/task.yaml create mode 100644 tests/log-analyzer/tests/test-5/task.yaml create mode 100644 tests/log-parser/all-aborted.log.spread create mode 100644 tests/log-parser/all-successful.log.spread create mode 100644 tests/log-parser/task.yaml create mode 100644 tests/log-parser/with-all-results.log.spread create mode 100644 tests/log-parser/with-failed-and-aborted.log.spread create mode 100644 tests/log-parser/with-failed-project-restore.log.spread create mode 100644 tests/log-parser/with-failed-repeated-and-aborted.log.spread create mode 100644 tests/log-parser/with-failed-repeated.log.spread create mode 100644 tests/log-parser/with-failed-suite-restore.log.spread create mode 100644 tests/log-parser/with-failed.log.spread create mode 100644 tests/log-parser/with-results-in-detail.log.spread create mode 100644 tests/not/task.yaml create mode 100644 tests/os.paths/task.yaml create mode 100644 tests/os.query/task.yaml create mode 100644 tests/quiet/task.yaml create mode 100644 tests/remote.exec/task.yaml create mode 100644 tests/remote.pull/task.yaml create mode 100644 tests/remote.push/task.yaml create mode 100644 tests/remote.refresh/task.yaml create mode 100644 tests/remote.retry/task.yaml create mode 100644 tests/remote.setup/task.yaml create mode 100644 tests/remote.wait-for/task.yaml create mode 100644 tests/repack-kernel/task.yaml create mode 100644 tests/retry/task.yaml create mode 100644 tests/snaps.cleanup/task.yaml create mode 100644 tests/snaps.name/task.yaml create mode 100644 tests/spread-manager/checks/task1/task.yaml create mode 100644 tests/spread-manager/checks/task2/task.yaml create mode 100644 tests/spread-manager/checks/task3/task.yaml create mode 100644 tests/spread-manager/checks/task4/task.yaml create mode 100644 tests/spread-manager/checks/task5/.empty create mode 100644 tests/spread-manager/spread.yaml create mode 100644 tests/spread-manager/task.yaml create mode 100644 tests/spread-shellcheck/task.yaml create mode 100644 tests/spread-shellcheck/tasks/task1 create mode 100644 tests/spread-shellcheck/tasks/task2 create mode 100644 tests/spread-shellcheck/tasks/task3 create mode 100644 tests/spread-shellcheck/tasks/task4 create mode 100644 tests/tests.backup/task.yaml create mode 100644 tests/tests.cleanup/task.yaml create mode 100644 tests/tests.pkgs/task.yaml create mode 100644 tests/tests.systemd/task.yaml create mode 100755 tools/not create mode 100755 tools/os.paths create mode 100755 tools/os.query create mode 100755 tools/quiet create mode 100755 tools/repack-kernel create mode 100755 tools/retry create mode 100755 tools/snaps.cleanup create mode 100755 tools/snaps.name create mode 100755 tools/tests.backup create mode 100755 tools/tests.cleanup create mode 100755 tools/tests.pkgs create mode 100644 tools/tests.pkgs.apt.sh create mode 100644 tools/tests.pkgs.dnf-yum.sh create mode 100644 tools/tests.pkgs.pacman.sh create mode 100644 tools/tests.pkgs.zypper.sh create mode 100755 tools/tests.systemd create mode 100755 utils/check-test-format create mode 100755 utils/log-analyzer create mode 100755 utils/log-parser create mode 100755 utils/spread-manager create mode 100755 utils/spread-shellcheck create mode 100755 utils/spreadJ diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000..1f1b04b5 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,6 @@ +# Add 'needs tests' label to either any change on remote, tools or utils dir +needs tests: + - remote/**/* + - tools/**/* + - utils/**/* + diff --git a/.github/workflows/labeler.yaml b/.github/workflows/labeler.yaml new file mode 100644 index 00000000..bd41c8eb --- /dev/null +++ b/.github/workflows/labeler.yaml @@ -0,0 +1,12 @@ +name: "Pull Request Labeler" +on: + - pull_request_target + +jobs: + triage: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v4 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + sync-labels: false diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 00000000..a0935ef9 --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,124 @@ +name: Jobs +on: + pull_request: + branches: + - main + push: + branches: + - main + +jobs: + unit-tests: + runs-on: ubuntu-20.04 + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Run shellCheck for tools + run: | + # Run shellcheck from the snap which most likely is newer than what the distro provides + sudo apt-get remove --purge shellcheck + sudo snap install shellcheck + find tools utils remote -type f -exec sh -c "head -n 1 {} | egrep -a 'bin/bash|bin/sh' >/dev/null" \; -print -exec shellcheck {} \; + + # Run shellcheck from the distro + sudo snap remove shellcheck + sudo apt-get install -y shellcheck + find tools utils remote -type f -exec sh -c "head -n 1 {} | egrep -a 'bin/bash|bin/sh' >/dev/null" \; -print -exec shellcheck {} \; + + - name: Run codespell tool + run: | + sudo apt install python3-pip + pip3 install codespell + codespell + + test: + needs: [unit-tests] + runs-on: self-hosted + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Get previous attempt + id: get-previous-attempt + run: | + echo "previous_attempt=$(( ${{ github.run_attempt }} - 1 ))" >> $GITHUB_OUTPUT + shell: bash + + - name: Get previous cache + uses: actions/cache@v3 + with: + path: "${{ github.workspace }}/.test-results" + key: "${{ github.job }}-results-${{ github.run_id }}-${{ steps.get-previous-attempt.outputs.previous_attempt }}" + + - name: Prepare test results env and vars + id: prepare-test-results-env + run: | + # Create test results directories and save vars + TEST_RESULTS_DIR="${{ github.workspace }}/.test-results" + echo "TEST_RESULTS_DIR=$TEST_RESULTS_DIR" >> $GITHUB_ENV + + # Save the var with the failed tests file + echo "FAILED_TESTS_FILE=$TEST_RESULTS_DIR/failed-tests" >> $GITHUB_ENV + + # Make sure the test results dirs are created + # This step has to be after the cache is restored + mkdir -p "$TEST_RESULTS_DIR" + + - name: Check failed tests to run + if: "!contains(github.event.pull_request.labels.*.name, 'Run all')" + run: | + # Save previous failed test results in FAILED_TESTS env var + FAILED_TESTS="" + if [ -f "$FAILED_TESTS_FILE" ]; then + echo "Failed tests file found" + FAILED_TESTS="$(cat $FAILED_TESTS_FILE)" + if [ -n "$FAILED_TESTS" ]; then + echo "Failed tests to run: $FAILED_TESTS" + echo "FAILED_TESTS=$FAILED_TESTS" >> $GITHUB_ENV + fi + fi + + - name: Run test + run: | + RUN_TESTS="google:tests/ google-nested:tests/" + if [ -n "$FAILED_TESTS" ]; then + RUN_TESTS="$FAILED_TESTS" + fi + + (set -o pipefail; spread $RUN_TESTS | tee spread.log) + + - name: Discard spread workers + if: always() + run: | + shopt -s nullglob; + for r in .spread-reuse.*.yaml; do + spread -discard -reuse-pid="$(echo "$r" | grep -o -E '[0-9]+')"; + done + + - name: analyze spread test results + if: always() + run: | + if [ -f spread.log ]; then + echo "Running spread log parser" + ./utils/log-parser spread.log --output spread-results.json + + echo "Determining which tests were executed" + RUN_TESTS="google:tests/ google-nested:tests/" + if [ -n "$FAILED_TESTS" ]; then + RUN_TESTS="$FAILED_TESTS" + fi + + echo "Running spread log analyzer" + ./utils/log-analyzer list-reexecute-tasks "$RUN_TESTS" spread-results.json > "$FAILED_TESTS_FILE" + else + echo "No spread log found, saving empty list of failed tests" + touch "$FAILED_TESTS_FILE" + fi + + - name: save spread test results to cache + if: always() + uses: actions/cache/save@v3 + with: + path: "${{ github.workspace }}/.test-results" + key: "${{ github.job }}-results-${{ github.run_id }}-${{ github.run_attempt }}" diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..eae850e8 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at snap-advocacy@canonical.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 00000000..9f213f0e --- /dev/null +++ b/README.md @@ -0,0 +1,74 @@ +[![Snapcraft](https://avatars2.githubusercontent.com/u/19532717?s=200)](https://snapcraft.io) + +# Welcome to snapd-testing-tools + +This is the code repository for **snapd-testing-tools**, the set of tools +used by snapd for testing porpuses. + +The tools in this project are designed and tested independently, making them easy +to be imported and used by any project. + +## Get involved + +This is an [open source](COPYING) project and we warmly welcome community +contributions, suggestions, and constructive feedback. If you're interested in +contributing, please take a look at our [Code of Conduct](CODE_OF_CONDUCT.md) +first. + +- to report an issue, please file [a bug + report](https://bugs.launchpad.net/snappy/+filebug) on our [Launchpad issue +tracker](https://bugs.launchpad.net/snappy/) +- for suggestions and constructive feedback, create a post on the [Snapcraft + forum](https://forum.snapcraft.io/c/snapd) + +## Get in touch + +We're friendly! We have a community forum at +[https://forum.snapcraft.io](https://forum.snapcraft.io) where we discuss +feature plans, development news, issues, updates and troubleshooting. You can +chat in realtime with the snapd team and our wider community on the +[#snappy](https://web.libera.chat?channel=#snappy) IRC channel on +[libera chat](https://libera.chat/). + +For news and updates, follow us on [Twitter](https://twitter.com/snapcraftio) +and on [Facebook](https://www.facebook.com/snapcraftio). + +## Adding new tools + +The tools included in this project are intended to be reused by other projects. + +Tools are supported in all the systems included in spread.yaml file. + +Read the following considerations before adding new tools: + + - Each tool needs to be accompanied by at least 1 spread test in `tests//` + - At least 1 spread test needs to be included in the tests directory for each tool + - If the tool is a shell script, it needs to first pass a [ShellCheck](https://github.com/koalaman/shellcheck) assessment + - All tools need to be as generic as possible + - Each tool must also provide a command line interface (CLI), including _help_ output + +## Adding new utils + +The utils included in this project are intended to be reused by other projects. + +Utils are used as a complement for spread tests executions. Those are not intended to be used by spread tests. +For example utils are used on github action workflows to analyze tests code and outputs. + +Utils are supported in ubuntu-18.04 and higher. + +Read the following considerations before adding new utils: + + - Each util needs to be accompanied by at least 1 spread test in `tests//` + - At least 1 spread test needs to be included in the tests directory for each util + - If the util is a shell script, it needs to first pass a [ShellCheck](https://github.com/koalaman/shellcheck) assessment + - All utils need to be as generic as possible + - Each util must also provide a command line interface (CLI), including _help_ output + + +## Project status + +| Service | Status | +|-----|:---| +| [Github Actions](https://github.com/actions/) | ![Build Status][actions-image] | + +[actions-image]: https://github.com/snapcore/snapd-testing-tools/actions diff --git a/remote/remote.exec b/remote/remote.exec new file mode 100755 index 00000000..b9d7fbf9 --- /dev/null +++ b/remote/remote.exec @@ -0,0 +1,88 @@ +#!/bin/bash -e + +show_help() { + echo "usage: remote.exec [--user ] [--pass ] " + echo "" + echo "Available options:" + echo " -h --help show this help message." + echo "" +} + +_load_config() { + local CFG_FILE + CFG_FILE="$(remote.setup get-config-path)" + if [ ! -f "$CFG_FILE" ]; then + echo "remote.exec: config file \"$CFG_FILE\" not found, please run remote.setup command first" + return 1 + fi + # shellcheck disable=SC1090 + . "$CFG_FILE" +} + +_get_pass() { + local SSH_PASS + if [ -n "$TESTS_REMOTE_PASS" ]; then + echo "sshpass -p $TESTS_REMOTE_PASS" + fi +} + +_get_cert() { + if [ -n "$TESTS_REMOTE_PASS" ]; then + return + elif [ -n "$TESTS_REMOTE_CERT" ]; then + echo "-i $TESTS_REMOTE_CERT" + fi +} + +remote_exec() { + local user pass + local timeout=10 + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit + ;; + --user) + user="$2" + shift 2 + ;; + --pass) + pass="$2" + shift 2 + ;; + --timeout) + timeout="$2" + shift 2 + ;; + -*) + echo "remote.exec: unknown option $1" >&2 + exit 1 + ;; + *) + break + ;; + esac + done + + _load_config + if [ -n "$user" ]; then + TESTS_REMOTE_USER="$user" + fi + if [ -n "$pass" ]; then + TESTS_REMOTE_PASS="$pass" + fi + + local SSH_PASS SSH_CERT + SSH_PASS="$(_get_pass)" + SSH_CERT="$(_get_cert)" + + # shellcheck disable=SC2153,SC2086 + $SSH_PASS ssh $SSH_CERT -p "$TESTS_REMOTE_PORT" -o LogLevel=ERROR -o ServerAliveInterval=10 -o ConnectTimeout="$timeout" -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$TESTS_REMOTE_USER"@"$TESTS_REMOTE_HOST" "$@" +} + +main() { + remote_exec "$@" +} + +main "$@" diff --git a/remote/remote.pull b/remote/remote.pull new file mode 100755 index 00000000..e9ec088a --- /dev/null +++ b/remote/remote.pull @@ -0,0 +1,61 @@ +#!/bin/bash -e + +show_help() { + echo "usage: remote.pull [LOCAL_PATH]" + echo "" + echo "Available options:" + echo " -h --help show this help message." + echo "" +} + +_load_config() { + local CFG_FILE + CFG_FILE="$(remote.setup get-config-path)" + if [ ! -f "$CFG_FILE" ]; then + echo "remote.pull: config file \"$CFG_FILE\" not found, please run remote.setup command first" + return 1 + fi + # shellcheck disable=SC1090 + . "$CFG_FILE" +} + +_get_pass() { + if [ -n "$TESTS_REMOTE_PASS" ]; then + echo "sshpass -p $TESTS_REMOTE_PASS" + fi +} + +_get_cert() { + if [ -n "$TESTS_REMOTE_PASS" ]; then + return + elif [ -n "$TESTS_REMOTE_CERT" ]; then + echo "-i $TESTS_REMOTE_CERT" + fi +} + +remote_pull() { + local REMOTE_PATH="$1" + local LOCAL_PATH="${2:-.}" + if [ -z "$REMOTE_PATH" ]; then + echo "remote.pull: remote path is required" + fi + + local SSH_PASS SSH_CERT + SSH_PASS="$(_get_pass)" + SSH_CERT="$(_get_cert)" + + # shellcheck disable=SC2153,SC2086 + $SSH_PASS scp $SSH_CERT -P "$TESTS_REMOTE_PORT" -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$TESTS_REMOTE_USER"@"$TESTS_REMOTE_HOST":"$REMOTE_PATH" "$LOCAL_PATH" +} + +main() { + if [ $# -eq 0 ] || [ "$1" == '-h' ] || [ "$1" == '--help' ]; then + show_help + exit 0 + fi + + _load_config + remote_pull "$@" +} + +main "$@" diff --git a/remote/remote.push b/remote/remote.push new file mode 100755 index 00000000..095be0c5 --- /dev/null +++ b/remote/remote.push @@ -0,0 +1,61 @@ +#!/bin/bash -e + +show_help() { + echo "usage: remote.push [REMOTE_PATH]" + echo "" + echo "Available options:" + echo " -h --help show this help message." + echo "" +} + +_load_config() { + local CFG_FILE + CFG_FILE="$(remote.setup get-config-path)" + if [ ! -f "$CFG_FILE" ]; then + echo "remote.push: config file \"$CFG_FILE\" not found, please run remote.setup command first" + return 1 + fi + # shellcheck disable=SC1090 + . "$CFG_FILE" +} + +_get_pass() { + if [ -n "$TESTS_REMOTE_PASS" ]; then + echo "sshpass -p $TESTS_REMOTE_PASS" + fi +} + +_get_cert() { + if [ -n "$TESTS_REMOTE_PASS" ]; then + return + elif [ -n "$TESTS_REMOTE_CERT" ]; then + echo "-i $TESTS_REMOTE_CERT" + fi +} + +remote_push() { + local LOCAL_PATH="$1" + local REMOTE_PATH="${2:-}" + if [ -z "$LOCAL_PATH" ]; then + echo "remote.push: local path is required" + fi + + local SSH_PASS SSH_CERT + SSH_PASS="$(_get_pass)" + SSH_CERT="$(_get_cert)" + + # shellcheck disable=SC2153,SC2086 + $SSH_PASS scp $SSH_CERT -P "$TESTS_REMOTE_PORT" -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$LOCAL_PATH" "$TESTS_REMOTE_USER"@"$TESTS_REMOTE_HOST":"$REMOTE_PATH" +} + +main() { + if [ $# -eq 0 ] || [ "$1" == '-h' ] || [ "$1" == '--help' ]; then + show_help + exit 0 + fi + + _load_config + remote_push "$@" +} + +main "$@" diff --git a/remote/remote.refresh b/remote/remote.refresh new file mode 100755 index 00000000..67278d42 --- /dev/null +++ b/remote/remote.refresh @@ -0,0 +1,322 @@ +#!/bin/bash -e + +show_help() { + echo "usage: remote.refresh snap [--channel CHANNEL] " + echo "usage: remote.refresh full [--channel CHANNEL]" + echo "usage: remote.refresh disable-refreshes" + echo "" + echo "SNAPNAME: allowed options are: kernel, core, base, gadget, snapd or the snap name" + echo "" + echo "Available options:" + echo " -h --help show this help message." + echo "" +} + +check_refresh_after_reboot() { + local refresh_channel=$1 + local snap=$2 + + echo "remote.refresh: checking snap \"$snap\" refresh after reboot" + remote.wait-for reboot + remote.wait-for snap-command + remote.retry -n 10 --wait 2 "snap info $snap | grep -q -E \"tracking: +(latest/${refresh_channel}|${refresh_channel})\"" + echo "remote.refresh: snap \"$snap\" refreshed correctly" +} + +check_refresh() { + local refresh_channel=$1 + local snap=$2 + + echo "remote.refresh: checking snap \"$snap\" refresh with no reboot" + remote.wait-for ssh -n 60 --wait 2 + remote.wait-for snap-command + remote.retry -n 10 --wait 2 "snap info $snap | grep -q -E \"tracking: +(latest/${refresh_channel}|${refresh_channel})\"" + echo "remote.refresh: snap \"$snap\" refreshed correctly" +} + +check_waiting_for_reboot() { + remote.exec "sudo journalctl -n 30" | grep -q "Waiting for system reboot" +} + +check_ready_to_refresh() { + remote.wait-for ssh + if check_waiting_for_reboot; then + echo "remote.refresh: waiting for system reboot" + remote.wait-for reboot + fi + remote.wait-for refresh +} + +do_refresh() { + local snap_name=$1 + local refresh_channel=$2 + + echo "remote.refresh: triggering refresh for snap \"$snap_name\" on channel \"$refresh_channel\"" + output=$(remote.exec "sudo snap refresh --channel ${refresh_channel} $snap_name 2>&1" || echo "snapd is about to reboot the system") + if echo "$output" | grep -E "(no updates available|cannot refresh \"$snap_name\"|is not installed)"; then + echo "remote.refresh: snap \"$snap_name\" has no updates available" + elif echo "$output" | grep -E "snapd is about to reboot the system"; then + remote.exec --timeout 3 "sudo reboot" || true + check_refresh_after_reboot "$refresh_channel" "$snap_name" + else + check_refresh "$refresh_channel" "$snap_name" + fi +} + +process_refresh() { + local snap_name=$1 + local refresh_channel=$2 + + if [ -z "$refresh_channel" ]; then + # Tracking is retrieved from snap info command because in old versions of + # snapd the tracking is not included in the snap list output + refresh_channel="$(remote.exec "snap info $snap_name" | grep -E '^tracking:' | awk '{ print $2 }')" + fi + + echo "remote.refresh: Refreshing $snap_name snap from $refresh_channel channel" + do_refresh "$snap_name" "$refresh_channel" +} + +refresh_fundamental() { + snap_name=$1 + regex=$2 + refresh_channel=$3 + + echo "remote.refresh: starting $snap_name refresh process" + snap_name="$(remote.exec "snap list" | grep -E "$regex" | awk '{ print $1 }')" + if [ -z "$snap_name" ]; then + echo "remote.refresh: no $snap_name snap to update" + return + fi + + if [ "$(echo "$snap_name" | wc -l)" -gt 1 ]; then + echo "remote.refresh: there is more than 1 $snap_name snap to update, skipping" + return 0 + fi + process_refresh "$snap_name" "$refresh_channel" +} + +refresh_kernel() { + local refresh_channel=$1 + local snap_name regex + + snap_name='kernel' + regex='(kernel$|kernel,)' + refresh_fundamental "$snap_name" "$regex" "$refresh_channel" +} + +refresh_gadget() { + local refresh_channel=$1 + local snap_name regex + + snap_name='gadget' + regex='(gadget$|gadget,)' + refresh_fundamental "$snap_name" "$regex" "$refresh_channel" +} + +refresh_snapd() { + local refresh_channel=$1 + local snap_name regex + + snap_name='snapd' + regex='^snapd.*(snapd$|snapd,)' + refresh_fundamental "$snap_name" "$regex" "$refresh_channel" +} + +refresh_core() { + local refresh_channel=$1 + local snap_name regex + + snap_name='core' + regex='^core.*(core$|core,)' + refresh_fundamental "$snap_name" "$regex" "$refresh_channel" +} + +refresh_core_base() { + local refresh_channel=$1 + local snap_name regex + + snap_name='core base' + regex='^core.* (base$|base,)' + refresh_fundamental "$snap_name" "$regex" "$refresh_channel" +} + +refresh_snap() { + local snapname=$1 + local refresh_channel=$2 + + if [ -z "$snapname" ]; then + echo "remote.refresh: snap name to refresh is not specified" + return 1 + fi + + if ! remote.exec "snap list $snapname"; then + echo "remote.refresh: no $snapname snap to update" + return 0 + fi + + snap_line="$(remote.exec "snap list $snapname" | tail -1)" + process_refresh "$snap_line" "$refresh_channel" +} + +refresh_all() { + # Run update and make "|| true" to continue when the connection is closed by remote host or not any snap to update + remote.exec "sudo snap refresh" || true + remote.wait-for ssh +} + + +get_boot_id() { + remote.exec "cat /proc/sys/kernel/random/boot_id" +} + +prevent_autorefresh() { + remote.wait-for ssh + state_path="$(remote.exec 'find /writable -name state.json 2>/dev/null' || true)" + if [ -z "$state_path" ]; then + echo "remote.refresh: state file not found in writable" + state_path="$(remote.exec 'find / -name state.json 2>/dev/null' || true)" + fi + if [ -z "$state_path" ]; then + echo "remote.refresh: state.json file not found" + exit 1 + fi + + remote.exec "sudo cp $state_path /tmp/state.json" + remote.exec "sudo chmod 644 /tmp/state.json" + remote.pull /tmp/state.json state.json + echo "remote.refresh: state file retrieved" + + jq ".data[\"last-refresh\"] = \"$(date +%Y-%m-%dT%H:%M:%S%:z)\"" state.json > state.json.new + echo "remote.refresh: state file just updated" + + remote.push state.json.new /tmp/state.json.new + remote.exec "sudo cp /tmp/state.json.new $state_path" + remote.exec "sudo chmod 600 $state_path" + echo "remote.refresh: updated state file restored" + rm -f state.json state.json.new +} + +disable_refreshes() { + if ! command -v jq &>/dev/null; then + snap install --devmode jq + fi + + echo "remote.refresh: modifying state to make it look like the last refresh just happened" + remote.exec "sudo systemctl stop snapd.socket snapd.service" + prevent_autorefresh + remote.exec "sudo systemctl start snapd.socket snapd.service" + + echo "remote.refresh: minimizing risk of hitting refresh schedule" + remote.exec "sudo snap set core refresh.schedule=00:00-23:59" + remote.exec "sudo snap refresh --time --abs-time" | grep -Eq "last: 2[0-9]{3}" + +} + +full_refresh() { + echo "remote.refresh: starting full refresh" + + check_ready_to_refresh + disable_refreshes + + check_ready_to_refresh + refresh_core + + check_ready_to_refresh + refresh_core_base + + check_ready_to_refresh + refresh_snapd + + check_ready_to_refresh + refresh_kernel + + check_ready_to_refresh + refresh_all + + check_ready_to_refresh +} + +snap_refresh() { + local channel snapname + + while [ $# -gt 0 ]; do + case "$1" in + --channel) + channel=$2 + shift 2 + ;; + *) + snapname=$1 + shift + ;; + esac + done + + if [ -z "$snapname" ]; then + echo "remote.refresh: snap name to refresh is not specified" + return 1 + fi + + case "$snapname" in + core) + refresh_core "$channel" + ;; + base) + refresh_core_base "$channel" + ;; + snapd) + refresh_snapd "$channel" + ;; + kernel) + refresh_kernel "$channel" + ;; + gadget) + refresh_gadget "$channel" + ;; + *) + refresh_snap "$snapname" "$channel" + ;; + esac +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit + fi + + local action + case "$1" in + -h|--help) + show_help + exit + ;; + full) + action=full_refresh + shift + ;; + snap) + action=snap_refresh + shift + ;; + disable-refreshes) + action=disable_refreshes + shift + ;; + *) + echo "remote.refresh: unsupported parameter $1" >&2 + exit 1 + ;; + esac + + if [ -z "$(declare -f "$action")" ]; then + echo "remote.refresh: no such command: $action" + show_help + exit 1 + fi + + "$action" "$@" +} + +main "$@" diff --git a/remote/remote.retry b/remote/remote.retry new file mode 100755 index 00000000..bfe72f28 --- /dev/null +++ b/remote/remote.retry @@ -0,0 +1,59 @@ +#!/bin/bash -e + +show_help() { + echo "usage: remote.retry [--wait WAIT] [-n|--attempts ATTEMPTS] " + echo "" + echo "Available options:" + echo " -h --help show this help message." + echo "" +} + +remote_retry(){ + local attempts=$1 + local wait=$2 + local cmd=$3 + + while ! remote.exec "$cmd"; do + attempts=$(( attempts - 1 )) + if [ $attempts -le 0 ]; then + echo "remote.retry: timed out retrying command" + return 1 + fi + sleep "$wait" + done +} + +main() { + local wait attempts cmd + wait=1 + attempts=30 + + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit + ;; + --wait) + wait=$2 + shift 2 + ;; + --attempts|-n) + attempts=$2 + shift 2 + ;; + *) + break + ;; + esac + done + + if [ $# -eq 0 ]; then + echo "remote.retry: command to retry not specified" + return 1 + fi + + remote_retry "$attempts" "$wait" "$@" +} + +main "$@" diff --git a/remote/remote.setup b/remote/remote.setup new file mode 100755 index 00000000..35e0ea69 --- /dev/null +++ b/remote/remote.setup @@ -0,0 +1,100 @@ +#!/bin/bash -e + +CFG_FILE="${REMOTE_CFG_FILE:-$(pwd)/remote.setup.cfg}" + +show_help() { + echo "usage: remote.setup config --host --port --user [--pass ] [--cert ]" + echo "usage: remote.setup get-config-path" + echo "" + echo "Available options:" + echo " -h --help show this help message." + echo "" +} + +get_config_path() { + echo "$CFG_FILE" +} + +config() { + local host port user pass cert + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit + ;; + --host) + host="$2" + shift 2 + ;; + --port) + port="$2" + shift 2 + ;; + --user) + user="$2" + shift 2 + ;; + --pass) + pass="$2" + shift 2 + ;; + --cert) + cert="$2" + shift 2 + ;; + *) + echo "tests.remote: unknown option $1" >&2 + exit 1 + ;; + esac + done + + if [ -z "$host" ] || [ -z "$port" ] || [ -z "$user" ]; then + echo "remote.setup: host, port and user values are required" + exit 1 + fi + if [ -n "$pass" ] && [ -z "$(command -v sshpass)" ]; then + echo "remote.setup: sshpass tool is required when password is configured" + fi + if [ -n "$cert" ] && ! [ -f "$cert" ]; then + echo "remote.setup: certificate is set but file does not exist" + exit 1 + fi + + rm -f "$CFG_FILE" + echo "export TESTS_REMOTE_HOST=$host" > "$CFG_FILE" + # shellcheck disable=SC2129 + echo "export TESTS_REMOTE_PORT=$port" >> "$CFG_FILE" + echo "export TESTS_REMOTE_USER=$user" >> "$CFG_FILE" + echo "export TESTS_REMOTE_PASS=$pass" >> "$CFG_FILE" + echo "export TESTS_REMOTE_CERT=$cert" >> "$CFG_FILE" +} + +main() { + local subcommand="$1" + local action= + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit 0 + ;; + *) + action=$(echo "$subcommand" | tr '-' '_') + shift + break + ;; + esac + done + + if [ -z "$(declare -f "$action")" ]; then + echo "remote.setup: no such command: $subcommand" + show_help + exit 1 + fi + + "$action" "$@" +} + +main "$@" diff --git a/remote/remote.wait-for b/remote/remote.wait-for new file mode 100755 index 00000000..b692e5fb --- /dev/null +++ b/remote/remote.wait-for @@ -0,0 +1,307 @@ +#!/bin/bash -e + +# The default values have been selected trying to match with most of +# the wait times in the tests and also trying to follow common sense. +DEFAULT_WAIT_FOR_SSH_ATTEMPTS=800 +DEFAULT_WAIT_FOR_SSH_WAIT=1 +DEFAULT_WAIT_FOR_NO_SSH_ATTEMPTS=200 +DEFAULT_WAIT_FOR_NO_SSH_WAIT=1 +DEFAULT_WAIT_FOR_SNAP_COMMAND_ATTEMPTS=200 +DEFAULT_WAIT_FOR_SNAP_COMMAND_WAIT=1 +DEFAULT_WAIT_FOR_DEV_INIT_ATTEMPTS=60 +DEFAULT_WAIT_FOR_DEV_INIT_WAIT=1 +DEFAULT_WAIT_FOR_REBOOT_ATTEMPTS=120 +DEFAULT_WAIT_FOR_REBOOT_WAIT=5 + +show_help() { + echo "usage: remote.wait-for ssh [--wait WAIT] [-n|--attempts ATTEMPTS]" + echo " remote.wait-for no-ssh [--wait WAIT] [-n|--attempts ATTEMPTS]" + echo " remote.wait-for snap-command [--wait WAIT] [-n|--attempts ATTEMPTS]" + echo " remote.wait-for reboot [--wait WAIT] [-n|--attempts ATTEMPTS]" + echo " remote.wait-for device-initialized [--wait WAIT] [-n|--attempts ATTEMPTS]" + echo " remote.wait-for refresh [--wait WAIT] [-n|--attempts ATTEMPTS]" + echo "" + echo "Available options:" + echo " -h --help show this help message." + echo "" +} + +wait_for_ssh() { + local attempts=${1:-$DEFAULT_WAIT_FOR_SSH_ATTEMPTS} + local wait=${2:-$DEFAULT_WAIT_FOR_SSH_WAIT} + echo "remote.wait-for: waiting for ssh connection" + + until remote.exec "true" &>/dev/null; do + echo -n '.' + attempts=$(( attempts - 1 )) + if [ $attempts -le 0 ]; then + echo "" + echo "remote.wait-for: timed out waiting for ssh connection to succeed" + return 1 + fi + sleep "$wait" + done + echo "" + echo "remote.wait-for: ssh connection stablished" +} + +wait_for_no_ssh() { + local attempts=${1:-$DEFAULT_WAIT_FOR_NO_SSH_ATTEMPTS} + local wait=${2:-$DEFAULT_WAIT_FOR_NO_SSH_WAIT} + + echo "remote.wait-for: waiting for no ssh connection" + + while remote.exec "true" &>/dev/null; do + echo -n '.' + attempts=$(( attempts - 1 )) + if [ $attempts -le 0 ]; then + echo "" + echo "remote.wait-for: timed out waiting for ssh connection to fail" + return 1 + fi + sleep "$wait" + done + echo "" + echo "remote.wait-for: ssh connection lost" +} + + +wait_for_snap_command() { + local attempts=${1:-$DEFAULT_WAIT_FOR_SNAP_COMMAND_ATTEMPTS} + local wait=${2:-$DEFAULT_WAIT_FOR_SNAP_COMMAND_WAIT} + + echo "remote.wait-for: waiting for snap command" + + while ! remote.exec "command -v snap" &>/dev/null; do + echo -n '.' + attempts=$(( attempts - 1 )) + if [ $attempts -le 0 ]; then + echo "" + echo "remote.wait-for: timed out waiting for snap command to succeed" + return 1 + fi + sleep "$wait" + done + echo "" + echo "remote.wait-for: snap command ready" +} + +get_boot_id() { + remote.exec "cat /proc/sys/kernel/random/boot_id" +} + +wait_for_reconnect_ssh() { + echo "remote.wait-for: waiting for ssh is recoonected" + wait_for_no_ssh "$DEFAULT_WAIT_FOR_NO_SSH_ATTEMPTS" "$DEFAULT_WAIT_FOR_NO_SSH_WAIT" + wait_for_ssh "$DEFAULT_WAIT_FOR_SSH_ATTEMPTS" "$DEFAULT_WAIT_FOR_SSH_WAIT" +} + +wait_for_reboot() { + local attempts=${1:-$DEFAULT_WAIT_FOR_REBOOT_ATTEMPTS} + local wait=${2:-$DEFAULT_WAIT_FOR_REBOOT_WAIT} + local initial_boot_id=$3 + local last_boot_id + + echo "remote.wait-for: waiting for reboot" + + if [ -z "$initial_boot_id" ]; then + echo "remote.wait-for: initial boot id not set" + wait_for_reconnect_ssh + return + fi + + while [ "$attempts" -ge 0 ]; do + echo -n '.' + attempts=$(( attempts - 1 )) + # The get_boot_id could fail because the connection is broken due to the reboot + last_boot_id="$(get_boot_id)" || true + # The boot_id is a GUID, i.e. 450d12a1-9811-464e-8c9e-cec1c60e8684 + if [[ "$last_boot_id" =~ .*-.*-.*-.*-.* ]] && [ "$last_boot_id" != "$initial_boot_id" ]; then + break + fi + sleep "$wait" + done + + echo "" + if [ "$last_boot_id" != "$initial_boot_id" ]; then + echo "remote.wait-for: reboot completed" + else + echo "remote.wait-for: boot id did not change" + return 1 + fi + +} + +wait_for_device_initialized() { + local attempts=${1:-$DEFAULT_WAIT_FOR_DEV_INIT_ATTEMPTS} + local wait=${2:-$DEFAULT_WAIT_FOR_DEV_INIT_WAIT} + + echo "remote.wait-for: waiting for device initialized" + + while ! remote.exec "snap changes" | grep -Eq "Done.*Initialize device"; do + echo -n '.' + attempts=$(( attempts - 1 )) + if [ $attempts -le 0 ]; then + echo "" + echo "remote.wait-for: timed out waiting for device to be fully initialized. Aborting!" + return 1 + fi + sleep "$wait" + done + echo "" + echo "remote.wait-for: device initialized" +} + +wait_for_refresh_reboot() { + echo "remote.wait-for: waiting for refresh reboot" + + local change_id=${1:-} + local boot_id=${2:-} + if [ -z "$change_id" ] || [ -z "$boot_id" ]; then + echo "remote.wait-for: either change_id or boot_id not provided" + return 1 + fi + + wait_for_ssh "$DEFAULT_WAIT_FOR_SSH_ATTEMPTS" "$DEFAULT_WAIT_FOR_SSH_WAIT" + for _ in $(seq 5); do + # The refresh is being executed + if remote.exec "snap changes" | grep -Eq "$change_id.*Doing.*(Auto-refresh|Refresh)"; then + # The systems is waiting for reboot + if remote.exec "sudo journalctl -u snapd -n 30" | grep -q "Waiting for system reboot"; then + echo "remote.wait-for: waiting for system reboot" + remote.exec "sudo reboot" || true + wait_for_no_ssh "$DEFAULT_WAIT_FOR_NO_SSH_ATTEMPTS" "$DEFAULT_WAIT_FOR_NO_SSH_WAIT" + break + fi + echo "remote.wait-for: either auto-refresh or refresh in progress" + fi + + # when the refresh has finished and no reboot needed, the function returns + if remote.exec "snap changes" | grep -Eq "$change_id.*Done.*(Auto-refresh|Refresh)"; then + echo "remote.wait-for: refresh completed, reboot not required" + return + fi + + if remote.exec "snap changes" | grep -Eq "$change_id.*Error.*(Auto-refresh|Refresh)"; then + echo "remote.wait-for: refresh finished with error" + return 1 + fi + + echo "remote.wait-for: system reboot not detected" + sleep 1 + done + wait_for_ssh "$DEFAULT_WAIT_FOR_SSH_ATTEMPTS" "$DEFAULT_WAIT_FOR_SSH_WAIT" + if [ "$(remote.exec "cat /proc/sys/kernel/random/boot_id")" == "$boot_id" ]; then + echo "remote.wait-for: boot id did not change" + return 1 + else + echo "remote.wait-for: boot id changed, refresh completed with reboot" + fi +} + +wait_for_refresh(){ + echo "remote.wait-for: waiting for either auto-refresh or refresh" + + change_line="$(remote.exec 'snap changes' | grep -E 'Doing.*(Auto-refresh|Refresh)' || true)" + if [ -n "$change_line" ]; then + echo "remote.wait-for: refresh in progress" + change_id="$(echo "$change_line" | awk '{ print $1 }')" + boot_id="$(remote.exec "cat /proc/sys/kernel/random/boot_id")" + + for _ in $(seq 20); do + if wait_for_refresh_reboot "$change_id" "$boot_id"; then + break + fi + done + echo "" + + changes="$(remote.exec 'snap changes')" + if echo "$changes" | grep -Eq "$change_id.*Doing.*(Auto-refresh|Refresh)"; then + echo "remote.wait-for: still doing refresh, exiting" + elif echo "$changes" | grep -Eq "$change_id.*Error.*(Auto-refresh|Refresh)"; then + echo "remote.wait-for: refresh failed" + elif echo "$changes" | grep -Eq "$change_id.*Done.*(Auto-refresh|Refresh)"; then + echo "remote.wait-for: refresh completed" + else + echo "remote.wait-for: refresh results unknown" + echo "$changes" + return 1 + fi + else + echo "remote.wait-for: no refresh in progress" + fi +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit + fi + + local action wait attempts others + case "$1" in + -h|--help) + show_help + exit + ;; + ssh) + action=wait_for_ssh + shift + ;; + no-ssh) + action=wait_for_no_ssh + shift + ;; + snap-command) + action=wait_for_snap_command + shift + ;; + reboot) + action=wait_for_reboot + shift + ;; + device-initialized) + action=wait_for_device_initialized + shift + ;; + refresh) + action=wait_for_refresh + shift + ;; + *) + echo "remote.wait-for: unsupported parameter $1" >&2 + exit 1 + ;; + esac + + if [ -z "$(declare -f "$action")" ]; then + echo "remote.wait-for: no such command: $action" + show_help + exit 1 + fi + + while [ $# -gt 0 ]; do + case "$1" in + --wait) + wait=$2 + shift 2 + ;; + --attempts|-n) + attempts=$2 + shift 2 + ;; + *) + if [ -z "$others" ]; then + others=$1 + else + others="$others $1" + fi + shift + ;; + esac + done + + "$action" "$attempts" "$wait" "$others" +} + +main "$@" diff --git a/setup.sh b/setup.sh new file mode 100755 index 00000000..6c25175f --- /dev/null +++ b/setup.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# This script is used to setup the path and other environment variables needed +# to run the tools when the tools aren't used as part of a spread test. +# The steps are: +# 1. source the file: `. /setup.sh` +# 2. run any tool: `retry true` + +PROJECT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +export PATH=$PATH:$PROJECT_DIR/tools:$PROJECT_DIR/utils:$PROJECT_DIR/remote diff --git a/spread.yaml b/spread.yaml new file mode 100644 index 00000000..a93da707 --- /dev/null +++ b/spread.yaml @@ -0,0 +1,75 @@ +project: snapd-testing-tools + +environment: + PROJECT_PATH: /root/snapd-testing-tools + PATH: $PATH:$PROJECT_PATH/tools:$PROJECT_PATH/utils:$PROJECT_PATH/remote + +backends: + google: + key: '$(HOST: echo "$SPREAD_GOOGLE_KEY")' + location: snapd-spread/us-east1-b + halt-timeout: 2h + systems: + - ubuntu-14.04-64: + - ubuntu-16.04-64: + - ubuntu-18.04-32: + - ubuntu-18.04-64: + - ubuntu-20.04-64: + - ubuntu-22.04-64: + - ubuntu-23.04-64: + - ubuntu-23.10-64: + - debian-11-64: + - debian-12-64: + - debian-sid-64: + - fedora-37-64: + - fedora-38-64: + - arch-linux-64: + - amazon-linux-2-64: + storage: preserve-size + - centos-7-64: + storage: preserve-size + - centos-8-64: + storage: preserve-size + - centos-9-64: + storage: preserve-size + - opensuse-15.4-64: + - opensuse-15.5-64: + - opensuse-tumbleweed-64: + + google-nested: + type: google + key: '$(HOST: echo "$SPREAD_GOOGLE_KEY")' + location: snapd-spread/us-east1-b + plan: n2-standard-2 + halt-timeout: 2h + cpu-family: "Intel Cascade Lake" + systems: + - ubuntu-20.04-64: + image: ubuntu-2004-64-virt-enabled + storage: 20G + workers: 1 + +path: /root/snapd-testing-tools + +kill-timeout: 10m +warn-timeout: 3m + +prepare: | + echo "Prepare snapd-testing-tools project" + +restore: | + echo "Restore snapd-testing-tools project" + rm -rf "$PROJECT_PATH" + +suites: + tests/: + summary: Main test suite for snapd-testing-tools + prepare: | + echo "Preparing snapd-testing-tools main suite" + # Create users for the tests + useradd -m tools-user-1 + echo tools-user-1:tools-user-1 | sudo chpasswd + useradd -m tools-user-2 + echo tools-user-2:tools-user-2 | sudo chpasswd + restore: | + echo "Restoring snapd-testing-tools main suite" diff --git a/tests/check-test-format/task.yaml b/tests/check-test-format/task.yaml new file mode 100644 index 00000000..2d82dcc4 --- /dev/null +++ b/tests/check-test-format/task.yaml @@ -0,0 +1,42 @@ +summary: smoke test for the spread checker tool + +backends: [google] + +systems: [ ubuntu-20.04-64 ] + +prepare: | + apt install -y python3-yamlordereddictloader + +restore: | + apt remove -y python3-yamlordereddictloader + +execute: | + check-test-format -h | MATCH "usage: check-test-format" + + # Check failing tasks with order not desired + check-test-format --tests "$PWD/tasks/task1.yaml" 2>&1 | MATCH "Keys 'execute' and 'prepare' do not follow the desired order" + + check-test-format --tests "$PWD/tasks/task2.yaml" 2>&1 | MATCH "Keys 'execute' and 'restore' do not follow the desired order" + + check-test-format --tests "$PWD/tasks/task3.yaml" 2>&1 | MATCH "Keys 'systems' and 'backends' do not follow the desired order" + check-test-format --tests "$PWD/tasks/task3.yaml" 2>&1 | MATCH "Key 'execute' is mandatory" + + # Check passing a file with more than 1 error + check-test-format --tests "$PWD/tasks/task4.yaml" 2>&1 | MATCH "Keys 'environment' and 'systems' do not follow the desired order" + check-test-format --tests "$PWD/tasks/task4.yaml" 2>&1 | MATCH "Key 'details' is mandatory" + + # Check passing a file with a non supported section + check-test-format --tests "$PWD/tasks/task5.yaml" 2>&1 | MATCH "key 'unsupported' is not among the supported keys" + + # Check passing more than 1 file to the tool + check-test-format --tests "$PWD/tasks/task4.yaml" "$PWD/tasks/task5.yaml" 2>&1 | MATCH "Key 'details' is mandatory" + check-test-format --tests "$PWD/tasks/task4.yaml" "$PWD/tasks/task5.yaml" 2>&1 | MATCH "key 'unsupported' is not among the supported keys" + + # Check passing a file with a non supported format + # Check passing a dir + cp "$PWD/tasks/task6.yaml" "$PWD/tasks/task.yaml" + echo "newtext" >> "$PWD/tasks/task.yaml" + check-test-format --tests "$PWD/tasks/task.yaml" 2>&1 | MATCH "Invalid task format, checks failed for task" + check-test-format --dir "$PWD/tasks/" 2>&1 | MATCH "Invalid task format, checks failed for task" + check-test-format --dir "$PWD/tasks/" 2>&1 | NOMATCH "Key 'execute' is mandatory" + rm "$PWD/tasks/task.yaml" diff --git a/tests/check-test-format/tasks/task1.yaml b/tests/check-test-format/tasks/task1.yaml new file mode 100644 index 00000000..90ecfe6c --- /dev/null +++ b/tests/check-test-format/tasks/task1.yaml @@ -0,0 +1,9 @@ +summary: this is the summary + +details: details + +execute: | + echo "execute" + +prepare: | + echo "prepare" diff --git a/tests/check-test-format/tasks/task2.yaml b/tests/check-test-format/tasks/task2.yaml new file mode 100644 index 00000000..9e02ee75 --- /dev/null +++ b/tests/check-test-format/tasks/task2.yaml @@ -0,0 +1,9 @@ +summary: this is the summary + +details: details + +execute: | + echo "execute" + +restore: | + echo "restore" diff --git a/tests/check-test-format/tasks/task3.yaml b/tests/check-test-format/tasks/task3.yaml new file mode 100644 index 00000000..55989a17 --- /dev/null +++ b/tests/check-test-format/tasks/task3.yaml @@ -0,0 +1,7 @@ +summary: this is the summary + +details: details + +systems: [ ubuntu-20.04-64 ] + +backends: [ google ] diff --git a/tests/check-test-format/tasks/task4.yaml b/tests/check-test-format/tasks/task4.yaml new file mode 100644 index 00000000..c712c79f --- /dev/null +++ b/tests/check-test-format/tasks/task4.yaml @@ -0,0 +1,8 @@ +summary: this is the summary + +environment: + TEST: 1 + +systems: [ ubuntu-20.04-64 ] + + diff --git a/tests/check-test-format/tasks/task5.yaml b/tests/check-test-format/tasks/task5.yaml new file mode 100644 index 00000000..ff45b068 --- /dev/null +++ b/tests/check-test-format/tasks/task5.yaml @@ -0,0 +1,10 @@ +summary: this is the summary + +details: details + +unsupported: not supported + +systems: [ ubuntu-20.04-64 ] + +execute: | + echo "execute" diff --git a/tests/check-test-format/tasks/task6.yaml b/tests/check-test-format/tasks/task6.yaml new file mode 100644 index 00000000..e42a4092 --- /dev/null +++ b/tests/check-test-format/tasks/task6.yaml @@ -0,0 +1,6 @@ +summary: this is the summary + +details: details + +execute: | + echo "execute" diff --git a/tests/log-analyzer/data/aborted-and-failed-execute-and-restore.json b/tests/log-analyzer/data/aborted-and-failed-execute-and-restore.json new file mode 100644 index 00000000..258d7bd2 --- /dev/null +++ b/tests/log-analyzer/data/aborted-and-failed-execute-and-restore.json @@ -0,0 +1,443 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "18:37:06", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:37:06", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:37:15", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242137-942824) to boot at 34.75.199.115..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:37:20", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242137-942720) to boot at 34.75.71.82..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:37:57", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242137-942720)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:37:57", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242137-942720)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:37:58", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242137-942720) at 34.75.71.82." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:37:58", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242137-942720)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:02", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:38:02", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242137-942824)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:38:02", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242137-942824)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:02", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:03", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:38:04", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242137-942824) at 34.75.199.115." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:38:04", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242137-942824)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:04", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:04", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:05", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:05", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "18:38:06", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-22.04-64:tests/test-2", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:06", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:06", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "18:38:06", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-22.04-64:tests/test-2", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo restore\n", + "restore\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:06", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:07", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:07", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:07", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:38:07", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242137-942720)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:08", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:08", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:09", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:09", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:10", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:10", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:11", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:11", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:12", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:12", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:13", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:13", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:14", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "18:38:14", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-20.04-64:tests/test-2", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:14", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "18:38:15", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-20.04-64:tests/test-2", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo restore\n", + "restore\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:15", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:38:15", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:38:16", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242137-942824)..." + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:38:16", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "5", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:38:16", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "3", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:38:16", + "result_type": "Failed", + "level": "tasks", + "stage": null, + "number": "2", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:tests/test-2\n", + " - google:ubuntu-22.04-64:tests/test-2\n" + ] + } + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:38:16", + "result_type": "Failed", + "level": "task", + "stage": "restore", + "number": "2", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:tests/test-2\n", + " - google:ubuntu-22.04-64:tests/test-2\n" + ] + } + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/aborted-and-failed-execute-and-restore.log b/tests/log-analyzer/data/aborted-and-failed-execute-and-restore.log new file mode 100644 index 00000000..93f003e6 --- /dev/null +++ b/tests/log-analyzer/data/aborted-and-failed-execute-and-restore.log @@ -0,0 +1,82 @@ +2022-05-24 18:37:06 Project content is packed for delivery (9.71KB). +2022-05-24 18:37:06 Sequence of jobs produced with -seed=1653428226 +2022-05-24 18:37:06 If killed, discard servers with: spread -reuse-pid=101245 -discard +2022-05-24 18:37:06 Allocating google:ubuntu-22.04-64... +2022-05-24 18:37:06 Allocating google:ubuntu-20.04-64... +2022-05-24 18:37:15 Waiting for google:ubuntu-20.04-64 (may242137-942824) to boot at 34.75.199.115... +2022-05-24 18:37:20 Waiting for google:ubuntu-22.04-64 (may242137-942720) to boot at 34.75.71.82... +2022-05-24 18:37:57 Allocated google:ubuntu-22.04-64 (may242137-942720). +2022-05-24 18:37:57 Connecting to google:ubuntu-22.04-64 (may242137-942720)... +2022-05-24 18:37:58 Connected to google:ubuntu-22.04-64 (may242137-942720) at 34.75.71.82. +2022-05-24 18:37:58 Sending project content to google:ubuntu-22.04-64 (may242137-942720)... +2022-05-24 18:38:02 Preparing google:ubuntu-22.04-64 (may242137-942720)... +2022-05-24 18:38:02 Allocated google:ubuntu-20.04-64 (may242137-942824). +2022-05-24 18:38:02 Connecting to google:ubuntu-20.04-64 (may242137-942824)... +2022-05-24 18:38:02 Preparing google:ubuntu-22.04-64:tests/ (may242137-942720)... +2022-05-24 18:38:03 Preparing google:ubuntu-22.04-64:tests/test-4 (may242137-942720)... +2022-05-24 18:38:04 Connected to google:ubuntu-20.04-64 (may242137-942824) at 34.75.199.115. +2022-05-24 18:38:04 Sending project content to google:ubuntu-20.04-64 (may242137-942824)... +2022-05-24 18:38:04 Executing google:ubuntu-22.04-64:tests/test-4 (may242137-942720) (1/10)... +2022-05-24 18:38:04 Restoring google:ubuntu-22.04-64:tests/test-4 (may242137-942720)... +2022-05-24 18:38:05 Preparing google:ubuntu-22.04-64:tests/test-2 (may242137-942720)... +2022-05-24 18:38:05 Executing google:ubuntu-22.04-64:tests/test-2 (may242137-942720) (2/10)... +2022-05-24 18:38:06 Error executing google:ubuntu-22.04-64:tests/test-2 (may242137-942720) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 18:38:06 Restoring google:ubuntu-22.04-64:tests/test-2 (may242137-942720)... +2022-05-24 18:38:06 Preparing google:ubuntu-20.04-64 (may242137-942824)... +2022-05-24 18:38:06 Error restoring google:ubuntu-22.04-64:tests/test-2 (may242137-942720) : +----- ++ echo restore +restore ++ exit 1 +----- +. +2022-05-24 18:38:06 Restoring google:ubuntu-22.04-64:tests/ (may242137-942720)... +2022-05-24 18:38:07 Preparing google:ubuntu-20.04-64:tests/ (may242137-942824)... +2022-05-24 18:38:07 Restoring google:ubuntu-22.04-64 (may242137-942720)... +2022-05-24 18:38:07 Preparing google:ubuntu-20.04-64:tests/test-5 (may242137-942824)... +2022-05-24 18:38:07 Discarding google:ubuntu-22.04-64 (may242137-942720)... +2022-05-24 18:38:08 Executing google:ubuntu-20.04-64:tests/test-5 (may242137-942824) (3/10)... +2022-05-24 18:38:08 Restoring google:ubuntu-20.04-64:tests/test-5 (may242137-942824)... +2022-05-24 18:38:09 Preparing google:ubuntu-20.04-64:tests/test-3 (may242137-942824)... +2022-05-24 18:38:09 Executing google:ubuntu-20.04-64:tests/test-3 (may242137-942824) (4/10)... +2022-05-24 18:38:10 Restoring google:ubuntu-20.04-64:tests/test-3 (may242137-942824)... +2022-05-24 18:38:10 Preparing google:ubuntu-20.04-64:tests/test-1 (may242137-942824)... +2022-05-24 18:38:11 Executing google:ubuntu-20.04-64:tests/test-1 (may242137-942824) (5/10)... +2022-05-24 18:38:11 Restoring google:ubuntu-20.04-64:tests/test-1 (may242137-942824)... +2022-05-24 18:38:12 Preparing google:ubuntu-20.04-64:tests/test-4 (may242137-942824)... +2022-05-24 18:38:12 Executing google:ubuntu-20.04-64:tests/test-4 (may242137-942824) (6/10)... +2022-05-24 18:38:13 Restoring google:ubuntu-20.04-64:tests/test-4 (may242137-942824)... +2022-05-24 18:38:13 Preparing google:ubuntu-20.04-64:tests/test-2 (may242137-942824)... +2022-05-24 18:38:14 Executing google:ubuntu-20.04-64:tests/test-2 (may242137-942824) (7/10)... +2022-05-24 18:38:14 Error executing google:ubuntu-20.04-64:tests/test-2 (may242137-942824) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 18:38:14 Restoring google:ubuntu-20.04-64:tests/test-2 (may242137-942824)... +2022-05-24 18:38:15 Error restoring google:ubuntu-20.04-64:tests/test-2 (may242137-942824) : +----- ++ echo restore +restore ++ exit 1 +----- +. +2022-05-24 18:38:15 Restoring google:ubuntu-20.04-64:tests/ (may242137-942824)... +2022-05-24 18:38:15 Restoring google:ubuntu-20.04-64 (may242137-942824)... +2022-05-24 18:38:16 Discarding google:ubuntu-20.04-64 (may242137-942824)... +2022-05-24 18:38:16 Successful tasks: 5 +2022-05-24 18:38:16 Aborted tasks: 3 +2022-05-24 18:38:16 Failed tasks: 2 + - google:ubuntu-20.04-64:tests/test-2 + - google:ubuntu-22.04-64:tests/test-2 +2022-05-24 18:38:16 Failed task restore: 2 + - google:ubuntu-20.04-64:tests/test-2 + - google:ubuntu-22.04-64:tests/test-2 diff --git a/tests/log-analyzer/data/all-aborted.json b/tests/log-analyzer/data/all-aborted.json new file mode 100644 index 00000000..6e2424bf --- /dev/null +++ b/tests/log-analyzer/data/all-aborted.json @@ -0,0 +1,215 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "18:06:40", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:06:40", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:06:49", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242106-435572) to boot at 34.148.101.55..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:06:50", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242106-435744) to boot at 34.148.4.171..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:07:30", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242106-435572)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:07:30", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242106-435572)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:07:32", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242106-435572) at 34.148.101.55." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:07:32", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242106-435572)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:07:36", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "18:07:37", + "info_type": "Error", + "verb": "preparing", + "task": "google:ubuntu-22.04-64", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo 'Prepare log-analyzer-reexec project'\n", + "Prepare log-analyzer-reexec project\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:07:37", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:07:37", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242106-435572)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:07:41", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242106-435744)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:07:41", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242106-435744)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:07:42", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242106-435744) at 34.148.4.171." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:07:42", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242106-435744)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:07:46", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "18:07:47", + "info_type": "Error", + "verb": "preparing", + "task": "google:ubuntu-20.04-64", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo 'Prepare log-analyzer-reexec project'\n", + "Prepare log-analyzer-reexec project\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:07:47", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:07:47", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242106-435744)..." + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:07:48", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "0", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:07:48", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "10", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:07:48", + "result_type": "Failed", + "level": "project", + "stage": "prepare", + "number": "2", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:project\n", + " - google:ubuntu-22.04-64:project\n" + ] + } + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/all-aborted.log b/tests/log-analyzer/data/all-aborted.log new file mode 100644 index 00000000..aa284e92 --- /dev/null +++ b/tests/log-analyzer/data/all-aborted.log @@ -0,0 +1,40 @@ +2022-05-24 18:06:40 Project content is packed for delivery (5.27KB). +2022-05-24 18:06:40 Sequence of jobs produced with -seed=1653426400 +2022-05-24 18:06:40 If killed, discard servers with: spread -reuse-pid=98654 -discard +2022-05-24 18:06:40 Allocating google:ubuntu-22.04-64... +2022-05-24 18:06:40 Allocating google:ubuntu-20.04-64... +2022-05-24 18:06:49 Waiting for google:ubuntu-22.04-64 (may242106-435572) to boot at 34.148.101.55... +2022-05-24 18:06:50 Waiting for google:ubuntu-20.04-64 (may242106-435744) to boot at 34.148.4.171... +2022-05-24 18:07:30 Allocated google:ubuntu-22.04-64 (may242106-435572). +2022-05-24 18:07:30 Connecting to google:ubuntu-22.04-64 (may242106-435572)... +2022-05-24 18:07:32 Connected to google:ubuntu-22.04-64 (may242106-435572) at 34.148.101.55. +2022-05-24 18:07:32 Sending project content to google:ubuntu-22.04-64 (may242106-435572)... +2022-05-24 18:07:36 Preparing google:ubuntu-22.04-64 (may242106-435572)... +2022-05-24 18:07:37 Error preparing google:ubuntu-22.04-64 (may242106-435572) : +----- ++ echo 'Prepare log-analyzer-reexec project' +Prepare log-analyzer-reexec project ++ exit 1 +----- +. +2022-05-24 18:07:37 Restoring google:ubuntu-22.04-64 (may242106-435572)... +2022-05-24 18:07:37 Discarding google:ubuntu-22.04-64 (may242106-435572)... +2022-05-24 18:07:41 Allocated google:ubuntu-20.04-64 (may242106-435744). +2022-05-24 18:07:41 Connecting to google:ubuntu-20.04-64 (may242106-435744)... +2022-05-24 18:07:42 Connected to google:ubuntu-20.04-64 (may242106-435744) at 34.148.4.171. +2022-05-24 18:07:42 Sending project content to google:ubuntu-20.04-64 (may242106-435744)... +2022-05-24 18:07:46 Preparing google:ubuntu-20.04-64 (may242106-435744)... +2022-05-24 18:07:47 Error preparing google:ubuntu-20.04-64 (may242106-435744) : +----- ++ echo 'Prepare log-analyzer-reexec project' +Prepare log-analyzer-reexec project ++ exit 1 +----- +. +2022-05-24 18:07:47 Restoring google:ubuntu-20.04-64 (may242106-435744)... +2022-05-24 18:07:47 Discarding google:ubuntu-20.04-64 (may242106-435744)... +2022-05-24 18:07:48 Successful tasks: 0 +2022-05-24 18:07:48 Aborted tasks: 10 +2022-05-24 18:07:48 Failed project prepare: 2 + - google:ubuntu-20.04-64:project + - google:ubuntu-22.04-64:project diff --git a/tests/log-analyzer/data/all-failed.json b/tests/log-analyzer/data/all-failed.json new file mode 100644 index 00000000..dea8ba7a --- /dev/null +++ b/tests/log-analyzer/data/all-failed.json @@ -0,0 +1,613 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "17:52:29", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:52:29", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:52:39", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242052-202754) to boot at 34.139.205.254..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:52:43", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242052-202652) to boot at 104.196.209.131..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:53:24", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242052-202652)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:53:24", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242052-202652)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:53:25", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242052-202754)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:53:25", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242052-202754)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:53:26", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242052-202652) at 104.196.209.131." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:53:26", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242052-202652)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:53:26", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242052-202754) at 34.139.205.254." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:53:26", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242052-202754)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:28", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:29", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:29", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:29", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:30", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:30", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:30", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:53:31", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-22.04-64:tests/test-3", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:31", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:31", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:53:31", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-20.04-64:tests/test-5", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:31", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:31", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:32", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:32", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:32", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:53:33", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-20.04-64:tests/test-2", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:33", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:53:33", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-22.04-64:tests/test-4", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:33", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:33", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:33", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:34", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:34", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:53:34", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-20.04-64:tests/test-3", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:34", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:53:35", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-22.04-64:tests/test-2", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:35", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:35", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:35", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:35", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:53:36", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-20.04-64:tests/test-4", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:36", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:36", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:36", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:53:36", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-22.04-64:tests/test-1", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:36", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:37", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:37", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:53:37", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-20.04-64:tests/test-1", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:37", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:38", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:38", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:38", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:53:38", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-22.04-64:tests/test-5", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:38", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:53:39", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242052-202754)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:39", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:53:40", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:53:41", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242052-202652)..." + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:53:42", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "0", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:53:42", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "0", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:53:42", + "result_type": "Failed", + "level": "tasks", + "stage": null, + "number": "10", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:tests/test-1\n", + " - google:ubuntu-20.04-64:tests/test-2\n", + " - google:ubuntu-20.04-64:tests/test-3\n", + " - google:ubuntu-20.04-64:tests/test-4\n", + " - google:ubuntu-20.04-64:tests/test-5\n", + " - google:ubuntu-22.04-64:tests/test-1\n", + " - google:ubuntu-22.04-64:tests/test-2\n", + " - google:ubuntu-22.04-64:tests/test-3\n", + " - google:ubuntu-22.04-64:tests/test-4\n", + " - google:ubuntu-22.04-64:tests/test-5\n" + ] + } + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/all-failed.log b/tests/log-analyzer/data/all-failed.log new file mode 100644 index 00000000..1003f4d6 --- /dev/null +++ b/tests/log-analyzer/data/all-failed.log @@ -0,0 +1,138 @@ +2022-05-24 17:52:29 Project content is packed for delivery (2.87KB). +2022-05-24 17:52:29 Sequence of jobs produced with -seed=1653425549 +2022-05-24 17:52:29 If killed, discard servers with: spread -reuse-pid=97426 -discard +2022-05-24 17:52:29 Allocating google:ubuntu-22.04-64... +2022-05-24 17:52:29 Allocating google:ubuntu-20.04-64... +2022-05-24 17:52:39 Waiting for google:ubuntu-20.04-64 (may242052-202754) to boot at 34.139.205.254... +2022-05-24 17:52:43 Waiting for google:ubuntu-22.04-64 (may242052-202652) to boot at 104.196.209.131... +2022-05-24 17:53:24 Allocated google:ubuntu-22.04-64 (may242052-202652). +2022-05-24 17:53:24 Connecting to google:ubuntu-22.04-64 (may242052-202652)... +2022-05-24 17:53:25 Allocated google:ubuntu-20.04-64 (may242052-202754). +2022-05-24 17:53:25 Connecting to google:ubuntu-20.04-64 (may242052-202754)... +2022-05-24 17:53:26 Connected to google:ubuntu-22.04-64 (may242052-202652) at 104.196.209.131. +2022-05-24 17:53:26 Sending project content to google:ubuntu-22.04-64 (may242052-202652)... +2022-05-24 17:53:26 Connected to google:ubuntu-20.04-64 (may242052-202754) at 34.139.205.254. +2022-05-24 17:53:26 Sending project content to google:ubuntu-20.04-64 (may242052-202754)... +2022-05-24 17:53:28 Preparing google:ubuntu-22.04-64 (may242052-202652)... +2022-05-24 17:53:29 Preparing google:ubuntu-22.04-64:tests/ (may242052-202652)... +2022-05-24 17:53:29 Preparing google:ubuntu-20.04-64 (may242052-202754)... +2022-05-24 17:53:29 Preparing google:ubuntu-22.04-64:tests/test-3 (may242052-202652)... +2022-05-24 17:53:30 Preparing google:ubuntu-20.04-64:tests/ (may242052-202754)... +2022-05-24 17:53:30 Executing google:ubuntu-22.04-64:tests/test-3 (may242052-202652) (1/10)... +2022-05-24 17:53:30 Preparing google:ubuntu-20.04-64:tests/test-5 (may242052-202754)... +2022-05-24 17:53:31 Error executing google:ubuntu-22.04-64:tests/test-3 (may242052-202652) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:53:31 Restoring google:ubuntu-22.04-64:tests/test-3 (may242052-202652)... +2022-05-24 17:53:31 Executing google:ubuntu-20.04-64:tests/test-5 (may242052-202754) (2/10)... +2022-05-24 17:53:31 Error executing google:ubuntu-20.04-64:tests/test-5 (may242052-202754) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:53:31 Restoring google:ubuntu-20.04-64:tests/test-5 (may242052-202754)... +2022-05-24 17:53:31 Preparing google:ubuntu-22.04-64:tests/test-4 (may242052-202652)... +2022-05-24 17:53:32 Preparing google:ubuntu-20.04-64:tests/test-2 (may242052-202754)... +2022-05-24 17:53:32 Executing google:ubuntu-20.04-64:tests/test-2 (may242052-202754) (3/10)... +2022-05-24 17:53:32 Executing google:ubuntu-22.04-64:tests/test-4 (may242052-202652) (4/10)... +2022-05-24 17:53:33 Error executing google:ubuntu-20.04-64:tests/test-2 (may242052-202754) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:53:33 Restoring google:ubuntu-20.04-64:tests/test-2 (may242052-202754)... +2022-05-24 17:53:33 Error executing google:ubuntu-22.04-64:tests/test-4 (may242052-202652) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:53:33 Restoring google:ubuntu-22.04-64:tests/test-4 (may242052-202652)... +2022-05-24 17:53:33 Preparing google:ubuntu-20.04-64:tests/test-3 (may242052-202754)... +2022-05-24 17:53:33 Preparing google:ubuntu-22.04-64:tests/test-2 (may242052-202652)... +2022-05-24 17:53:34 Executing google:ubuntu-20.04-64:tests/test-3 (may242052-202754) (5/10)... +2022-05-24 17:53:34 Executing google:ubuntu-22.04-64:tests/test-2 (may242052-202652) (6/10)... +2022-05-24 17:53:34 Error executing google:ubuntu-20.04-64:tests/test-3 (may242052-202754) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:53:34 Restoring google:ubuntu-20.04-64:tests/test-3 (may242052-202754)... +2022-05-24 17:53:35 Error executing google:ubuntu-22.04-64:tests/test-2 (may242052-202652) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:53:35 Restoring google:ubuntu-22.04-64:tests/test-2 (may242052-202652)... +2022-05-24 17:53:35 Preparing google:ubuntu-20.04-64:tests/test-4 (may242052-202754)... +2022-05-24 17:53:35 Executing google:ubuntu-20.04-64:tests/test-4 (may242052-202754) (7/10)... +2022-05-24 17:53:35 Preparing google:ubuntu-22.04-64:tests/test-1 (may242052-202652)... +2022-05-24 17:53:36 Error executing google:ubuntu-20.04-64:tests/test-4 (may242052-202754) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:53:36 Restoring google:ubuntu-20.04-64:tests/test-4 (may242052-202754)... +2022-05-24 17:53:36 Executing google:ubuntu-22.04-64:tests/test-1 (may242052-202652) (8/10)... +2022-05-24 17:53:36 Preparing google:ubuntu-20.04-64:tests/test-1 (may242052-202754)... +2022-05-24 17:53:36 Error executing google:ubuntu-22.04-64:tests/test-1 (may242052-202652) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:53:36 Restoring google:ubuntu-22.04-64:tests/test-1 (may242052-202652)... +2022-05-24 17:53:37 Executing google:ubuntu-20.04-64:tests/test-1 (may242052-202754) (9/10)... +2022-05-24 17:53:37 Preparing google:ubuntu-22.04-64:tests/test-5 (may242052-202652)... +2022-05-24 17:53:37 Error executing google:ubuntu-20.04-64:tests/test-1 (may242052-202754) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:53:37 Restoring google:ubuntu-20.04-64:tests/test-1 (may242052-202754)... +2022-05-24 17:53:38 Restoring google:ubuntu-20.04-64:tests/ (may242052-202754)... +2022-05-24 17:53:38 Executing google:ubuntu-22.04-64:tests/test-5 (may242052-202652) (10/10)... +2022-05-24 17:53:38 Restoring google:ubuntu-20.04-64 (may242052-202754)... +2022-05-24 17:53:38 Error executing google:ubuntu-22.04-64:tests/test-5 (may242052-202652) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:53:38 Restoring google:ubuntu-22.04-64:tests/test-5 (may242052-202652)... +2022-05-24 17:53:39 Discarding google:ubuntu-20.04-64 (may242052-202754)... +2022-05-24 17:53:39 Restoring google:ubuntu-22.04-64:tests/ (may242052-202652)... +2022-05-24 17:53:40 Restoring google:ubuntu-22.04-64 (may242052-202652)... +2022-05-24 17:53:41 Discarding google:ubuntu-22.04-64 (may242052-202652)... +2022-05-24 17:53:42 Successful tasks: 0 +2022-05-24 17:53:42 Aborted tasks: 0 +2022-05-24 17:53:42 Failed tasks: 10 + - google:ubuntu-20.04-64:tests/test-1 + - google:ubuntu-20.04-64:tests/test-2 + - google:ubuntu-20.04-64:tests/test-3 + - google:ubuntu-20.04-64:tests/test-4 + - google:ubuntu-20.04-64:tests/test-5 + - google:ubuntu-22.04-64:tests/test-1 + - google:ubuntu-22.04-64:tests/test-2 + - google:ubuntu-22.04-64:tests/test-3 + - google:ubuntu-22.04-64:tests/test-4 + - google:ubuntu-22.04-64:tests/test-5 diff --git a/tests/log-analyzer/data/all-success-failed-restore.json b/tests/log-analyzer/data/all-success-failed-restore.json new file mode 100644 index 00000000..48bd65cb --- /dev/null +++ b/tests/log-analyzer/data/all-success-failed-restore.json @@ -0,0 +1,453 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "17:42:58", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:42:58", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:07", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242043-312411) to boot at 34.148.59.204..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:07", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242043-312500) to boot at 34.138.215.109..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:43", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242043-312411)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:43", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242043-312411)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:45", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242043-312411) at 34.148.59.204." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:45", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242043-312411)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:50", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:50", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:51", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:52", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:52", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:53", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:54", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:55", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:55", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:56", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:56", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:57", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:58", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:58", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:59", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:00", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:00", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:01", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:02", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:44:02", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-22.04-64", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo 'Restore snapd-testing-tools project'\n", + "Restore snapd-testing-tools project\n", + "/bin/bash: line 26: PROJECT_PATH: unbound variable\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:02", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242043-312411)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:04", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242043-312500)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:04", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242043-312500)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:05", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242043-312500) at 34.138.215.109." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:05", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242043-312500)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:08", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:08", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:09", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:09", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:10", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:10", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:11", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:11", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:12", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:13", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:13", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:14", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:14", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:15", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:15", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:16", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:16", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:17", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:17", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:44:18", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-20.04-64", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo 'Restore snapd-testing-tools project'\n", + "Restore snapd-testing-tools project\n", + "/bin/bash: line 26: PROJECT_PATH: unbound variable\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:18", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242043-312500)..." + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:44:19", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "10", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:44:19", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "0", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:44:19", + "result_type": "Failed", + "level": "project", + "stage": "restore", + "number": "2", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:project\n", + " - google:ubuntu-22.04-64:project\n" + ] + } + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/all-success-failed-restore.log b/tests/log-analyzer/data/all-success-failed-restore.log new file mode 100644 index 00000000..a777c9ff --- /dev/null +++ b/tests/log-analyzer/data/all-success-failed-restore.log @@ -0,0 +1,74 @@ +2022-05-24 17:42:58 Project content is packed for delivery (1.30KB). +2022-05-24 17:42:58 Sequence of jobs produced with -seed=1653424978 +2022-05-24 17:42:58 If killed, discard servers with: spread -reuse-pid=96667 -discard +2022-05-24 17:42:58 Allocating google:ubuntu-22.04-64... +2022-05-24 17:42:58 Allocating google:ubuntu-20.04-64... +2022-05-24 17:43:07 Waiting for google:ubuntu-22.04-64 (may242043-312411) to boot at 34.148.59.204... +2022-05-24 17:43:07 Waiting for google:ubuntu-20.04-64 (may242043-312500) to boot at 34.138.215.109... +2022-05-24 17:43:43 Allocated google:ubuntu-22.04-64 (may242043-312411). +2022-05-24 17:43:43 Connecting to google:ubuntu-22.04-64 (may242043-312411)... +2022-05-24 17:43:45 Connected to google:ubuntu-22.04-64 (may242043-312411) at 34.148.59.204. +2022-05-24 17:43:45 Sending project content to google:ubuntu-22.04-64 (may242043-312411)... +2022-05-24 17:43:50 Preparing google:ubuntu-22.04-64 (may242043-312411)... +2022-05-24 17:43:50 Preparing google:ubuntu-22.04-64:tests/ (may242043-312411)... +2022-05-24 17:43:51 Preparing google:ubuntu-22.04-64:tests/test-3 (may242043-312411)... +2022-05-24 17:43:52 Executing google:ubuntu-22.04-64:tests/test-3 (may242043-312411) (1/10)... +2022-05-24 17:43:52 Restoring google:ubuntu-22.04-64:tests/test-3 (may242043-312411)... +2022-05-24 17:43:53 Preparing google:ubuntu-22.04-64:tests/test-2 (may242043-312411)... +2022-05-24 17:43:54 Executing google:ubuntu-22.04-64:tests/test-2 (may242043-312411) (2/10)... +2022-05-24 17:43:55 Restoring google:ubuntu-22.04-64:tests/test-2 (may242043-312411)... +2022-05-24 17:43:55 Preparing google:ubuntu-22.04-64:tests/test-4 (may242043-312411)... +2022-05-24 17:43:56 Executing google:ubuntu-22.04-64:tests/test-4 (may242043-312411) (3/10)... +2022-05-24 17:43:56 Restoring google:ubuntu-22.04-64:tests/test-4 (may242043-312411)... +2022-05-24 17:43:57 Preparing google:ubuntu-22.04-64:tests/test-1 (may242043-312411)... +2022-05-24 17:43:58 Executing google:ubuntu-22.04-64:tests/test-1 (may242043-312411) (4/10)... +2022-05-24 17:43:58 Restoring google:ubuntu-22.04-64:tests/test-1 (may242043-312411)... +2022-05-24 17:43:59 Preparing google:ubuntu-22.04-64:tests/test-5 (may242043-312411)... +2022-05-24 17:44:00 Executing google:ubuntu-22.04-64:tests/test-5 (may242043-312411) (5/10)... +2022-05-24 17:44:00 Restoring google:ubuntu-22.04-64:tests/test-5 (may242043-312411)... +2022-05-24 17:44:01 Restoring google:ubuntu-22.04-64:tests/ (may242043-312411)... +2022-05-24 17:44:02 Restoring google:ubuntu-22.04-64 (may242043-312411)... +2022-05-24 17:44:02 Error restoring google:ubuntu-22.04-64 (may242043-312411) : +----- ++ echo 'Restore snapd-testing-tools project' +Restore snapd-testing-tools project +/bin/bash: line 26: PROJECT_PATH: unbound variable +----- +. +2022-05-24 17:44:02 Discarding google:ubuntu-22.04-64 (may242043-312411)... +2022-05-24 17:44:04 Allocated google:ubuntu-20.04-64 (may242043-312500). +2022-05-24 17:44:04 Connecting to google:ubuntu-20.04-64 (may242043-312500)... +2022-05-24 17:44:05 Connected to google:ubuntu-20.04-64 (may242043-312500) at 34.138.215.109. +2022-05-24 17:44:05 Sending project content to google:ubuntu-20.04-64 (may242043-312500)... +2022-05-24 17:44:08 Preparing google:ubuntu-20.04-64 (may242043-312500)... +2022-05-24 17:44:08 Preparing google:ubuntu-20.04-64:tests/ (may242043-312500)... +2022-05-24 17:44:09 Preparing google:ubuntu-20.04-64:tests/test-3 (may242043-312500)... +2022-05-24 17:44:09 Executing google:ubuntu-20.04-64:tests/test-3 (may242043-312500) (6/10)... +2022-05-24 17:44:10 Restoring google:ubuntu-20.04-64:tests/test-3 (may242043-312500)... +2022-05-24 17:44:10 Preparing google:ubuntu-20.04-64:tests/test-1 (may242043-312500)... +2022-05-24 17:44:11 Executing google:ubuntu-20.04-64:tests/test-1 (may242043-312500) (7/10)... +2022-05-24 17:44:11 Restoring google:ubuntu-20.04-64:tests/test-1 (may242043-312500)... +2022-05-24 17:44:12 Preparing google:ubuntu-20.04-64:tests/test-4 (may242043-312500)... +2022-05-24 17:44:13 Executing google:ubuntu-20.04-64:tests/test-4 (may242043-312500) (8/10)... +2022-05-24 17:44:13 Restoring google:ubuntu-20.04-64:tests/test-4 (may242043-312500)... +2022-05-24 17:44:14 Preparing google:ubuntu-20.04-64:tests/test-2 (may242043-312500)... +2022-05-24 17:44:14 Executing google:ubuntu-20.04-64:tests/test-2 (may242043-312500) (9/10)... +2022-05-24 17:44:15 Restoring google:ubuntu-20.04-64:tests/test-2 (may242043-312500)... +2022-05-24 17:44:15 Preparing google:ubuntu-20.04-64:tests/test-5 (may242043-312500)... +2022-05-24 17:44:16 Executing google:ubuntu-20.04-64:tests/test-5 (may242043-312500) (10/10)... +2022-05-24 17:44:16 Restoring google:ubuntu-20.04-64:tests/test-5 (may242043-312500)... +2022-05-24 17:44:17 Restoring google:ubuntu-20.04-64:tests/ (may242043-312500)... +2022-05-24 17:44:17 Restoring google:ubuntu-20.04-64 (may242043-312500)... +2022-05-24 17:44:18 Error restoring google:ubuntu-20.04-64 (may242043-312500) : +----- ++ echo 'Restore snapd-testing-tools project' +Restore snapd-testing-tools project +/bin/bash: line 26: PROJECT_PATH: unbound variable +----- +. +2022-05-24 17:44:18 Discarding google:ubuntu-20.04-64 (may242043-312500)... +2022-05-24 17:44:19 Successful tasks: 10 +2022-05-24 17:44:19 Aborted tasks: 0 +2022-05-24 17:44:19 Failed project restore: 2 + - google:ubuntu-20.04-64:project + - google:ubuntu-22.04-64:project diff --git a/tests/log-analyzer/data/all-success.json b/tests/log-analyzer/data/all-success.json new file mode 100644 index 00000000..962875f4 --- /dev/null +++ b/tests/log-analyzer/data/all-success.json @@ -0,0 +1,400 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "17:45:05", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:45:05", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:45:14", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242045-878680) to boot at 35.237.221.225..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:45:15", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242045-878764) to boot at 34.148.94.157..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:46:00", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242045-878680)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:46:00", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242045-878680)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:46:02", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242045-878680) at 35.237.221.225." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:46:02", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242045-878680)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:06", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:06", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:07", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:08", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:08", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:09", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:09", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:10", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:10", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:11", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:46:11", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242045-878764)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:46:11", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242045-878764)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:11", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:12", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:46:12", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242045-878764) at 34.148.94.157." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:46:12", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242045-878764)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:12", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:13", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:13", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:14", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:14", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:15", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:15", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:15", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:46:16", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242045-878680)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:16", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:17", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:17", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:18", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:19", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:19", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:20", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:20", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:21", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:22", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:22", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:23", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:24", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:24", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:25", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:25", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:26", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:46:27", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:46:27", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242045-878764)..." + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:46:28", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "10", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:46:28", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "0", + "detail": null + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/all-success.log b/tests/log-analyzer/data/all-success.log new file mode 100644 index 00000000..6fb71415 --- /dev/null +++ b/tests/log-analyzer/data/all-success.log @@ -0,0 +1,57 @@ +2022-05-24 17:45:05 Project content is packed for delivery (2.04KB). +2022-05-24 17:45:05 Sequence of jobs produced with -seed=1653425105 +2022-05-24 17:45:05 If killed, discard servers with: spread -reuse-pid=96844 -discard +2022-05-24 17:45:05 Allocating google:ubuntu-22.04-64... +2022-05-24 17:45:05 Allocating google:ubuntu-20.04-64... +2022-05-24 17:45:14 Waiting for google:ubuntu-22.04-64 (may242045-878680) to boot at 35.237.221.225... +2022-05-24 17:45:15 Waiting for google:ubuntu-20.04-64 (may242045-878764) to boot at 34.148.94.157... +2022-05-24 17:46:00 Allocated google:ubuntu-22.04-64 (may242045-878680). +2022-05-24 17:46:00 Connecting to google:ubuntu-22.04-64 (may242045-878680)... +2022-05-24 17:46:02 Connected to google:ubuntu-22.04-64 (may242045-878680) at 35.237.221.225. +2022-05-24 17:46:02 Sending project content to google:ubuntu-22.04-64 (may242045-878680)... +2022-05-24 17:46:06 Preparing google:ubuntu-22.04-64 (may242045-878680)... +2022-05-24 17:46:06 Preparing google:ubuntu-22.04-64:tests/ (may242045-878680)... +2022-05-24 17:46:07 Preparing google:ubuntu-22.04-64:tests/test-1 (may242045-878680)... +2022-05-24 17:46:08 Executing google:ubuntu-22.04-64:tests/test-1 (may242045-878680) (1/10)... +2022-05-24 17:46:08 Restoring google:ubuntu-22.04-64:tests/test-1 (may242045-878680)... +2022-05-24 17:46:09 Preparing google:ubuntu-22.04-64:tests/test-4 (may242045-878680)... +2022-05-24 17:46:09 Executing google:ubuntu-22.04-64:tests/test-4 (may242045-878680) (2/10)... +2022-05-24 17:46:10 Restoring google:ubuntu-22.04-64:tests/test-4 (may242045-878680)... +2022-05-24 17:46:10 Preparing google:ubuntu-22.04-64:tests/test-3 (may242045-878680)... +2022-05-24 17:46:11 Executing google:ubuntu-22.04-64:tests/test-3 (may242045-878680) (3/10)... +2022-05-24 17:46:11 Allocated google:ubuntu-20.04-64 (may242045-878764). +2022-05-24 17:46:11 Connecting to google:ubuntu-20.04-64 (may242045-878764)... +2022-05-24 17:46:11 Restoring google:ubuntu-22.04-64:tests/test-3 (may242045-878680)... +2022-05-24 17:46:12 Preparing google:ubuntu-22.04-64:tests/test-2 (may242045-878680)... +2022-05-24 17:46:12 Connected to google:ubuntu-20.04-64 (may242045-878764) at 34.148.94.157. +2022-05-24 17:46:12 Sending project content to google:ubuntu-20.04-64 (may242045-878764)... +2022-05-24 17:46:12 Executing google:ubuntu-22.04-64:tests/test-2 (may242045-878680) (4/10)... +2022-05-24 17:46:13 Restoring google:ubuntu-22.04-64:tests/test-2 (may242045-878680)... +2022-05-24 17:46:13 Preparing google:ubuntu-22.04-64:tests/test-5 (may242045-878680)... +2022-05-24 17:46:14 Executing google:ubuntu-22.04-64:tests/test-5 (may242045-878680) (5/10)... +2022-05-24 17:46:14 Restoring google:ubuntu-22.04-64:tests/test-5 (may242045-878680)... +2022-05-24 17:46:15 Restoring google:ubuntu-22.04-64:tests/ (may242045-878680)... +2022-05-24 17:46:15 Preparing google:ubuntu-20.04-64 (may242045-878764)... +2022-05-24 17:46:15 Restoring google:ubuntu-22.04-64 (may242045-878680)... +2022-05-24 17:46:16 Discarding google:ubuntu-22.04-64 (may242045-878680)... +2022-05-24 17:46:16 Preparing google:ubuntu-20.04-64:tests/ (may242045-878764)... +2022-05-24 17:46:17 Preparing google:ubuntu-20.04-64:tests/test-2 (may242045-878764)... +2022-05-24 17:46:17 Executing google:ubuntu-20.04-64:tests/test-2 (may242045-878764) (6/10)... +2022-05-24 17:46:18 Restoring google:ubuntu-20.04-64:tests/test-2 (may242045-878764)... +2022-05-24 17:46:19 Preparing google:ubuntu-20.04-64:tests/test-1 (may242045-878764)... +2022-05-24 17:46:19 Executing google:ubuntu-20.04-64:tests/test-1 (may242045-878764) (7/10)... +2022-05-24 17:46:20 Restoring google:ubuntu-20.04-64:tests/test-1 (may242045-878764)... +2022-05-24 17:46:20 Preparing google:ubuntu-20.04-64:tests/test-5 (may242045-878764)... +2022-05-24 17:46:21 Executing google:ubuntu-20.04-64:tests/test-5 (may242045-878764) (8/10)... +2022-05-24 17:46:22 Restoring google:ubuntu-20.04-64:tests/test-5 (may242045-878764)... +2022-05-24 17:46:22 Preparing google:ubuntu-20.04-64:tests/test-4 (may242045-878764)... +2022-05-24 17:46:23 Executing google:ubuntu-20.04-64:tests/test-4 (may242045-878764) (9/10)... +2022-05-24 17:46:24 Restoring google:ubuntu-20.04-64:tests/test-4 (may242045-878764)... +2022-05-24 17:46:24 Preparing google:ubuntu-20.04-64:tests/test-3 (may242045-878764)... +2022-05-24 17:46:25 Executing google:ubuntu-20.04-64:tests/test-3 (may242045-878764) (10/10)... +2022-05-24 17:46:25 Restoring google:ubuntu-20.04-64:tests/test-3 (may242045-878764)... +2022-05-24 17:46:26 Restoring google:ubuntu-20.04-64:tests/ (may242045-878764)... +2022-05-24 17:46:27 Restoring google:ubuntu-20.04-64 (may242045-878764)... +2022-05-24 17:46:27 Discarding google:ubuntu-20.04-64 (may242045-878764)... +2022-05-24 17:46:28 Successful tasks: 10 +2022-05-24 17:46:28 Aborted tasks: 0 diff --git a/tests/log-analyzer/data/failed-prepare-and-restore.json b/tests/log-analyzer/data/failed-prepare-and-restore.json new file mode 100644 index 00000000..57fba41b --- /dev/null +++ b/tests/log-analyzer/data/failed-prepare-and-restore.json @@ -0,0 +1,513 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "17:56:26", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:56:26", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:56:26", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:56:36", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242056-644336) to boot at 35.185.37.159..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:56:41", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242056-644230) to boot at 34.75.94.174..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:56:42", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242056-644428) to boot at 34.138.43.204..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:17", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242056-644230)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:17", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242056-644230)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:19", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242056-644230) at 34.75.94.174." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:19", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242056-644230)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:22", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242056-644336)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:22", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242056-644336)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:23", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:24", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242056-644428)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:24", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242056-644428)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:24", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242056-644336) at 35.185.37.159." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:24", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242056-644336)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:24", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:25", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:25", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242056-644428) at 34.138.43.204." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:25", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242056-644428)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:26", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:26", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:27", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:27", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:27", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:28", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:57:28", + "info_type": "Error", + "verb": "preparing", + "task": "google:ubuntu-22.04-64:tests/test-1", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo prepare\n", + "prepare\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:28", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:28", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:28", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:57:28", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-22.04-64:tests/test-1", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo restore\n", + "restore\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:28", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:29", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:29", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:29", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:29", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:29", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:29", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242056-644230)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:30", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:30", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:30", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:30", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:31", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:31", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:57:31", + "info_type": "Error", + "verb": "preparing", + "task": "google:ubuntu-20.04-64:tests/test-1", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo prepare\n", + "prepare\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:31", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:32", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:57:32", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-20.04-64:tests/test-1", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo restore\n", + "restore\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:32", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:32", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:33", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:33", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:57:33", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:34", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242056-644336)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:57:34", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242056-644428)..." + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:57:34", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "5", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:57:34", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "5", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:57:34", + "result_type": "Failed", + "level": "task", + "stage": "prepare", + "number": "2", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:tests/test-1\n", + " - google:ubuntu-22.04-64:tests/test-1\n" + ] + } + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:57:34", + "result_type": "Failed", + "level": "task", + "stage": "restore", + "number": "2", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:tests/test-1\n", + " - google:ubuntu-22.04-64:tests/test-1\n" + ] + } + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/failed-prepare-and-restore.log b/tests/log-analyzer/data/failed-prepare-and-restore.log new file mode 100644 index 00000000..59283cfe --- /dev/null +++ b/tests/log-analyzer/data/failed-prepare-and-restore.log @@ -0,0 +1,91 @@ +2022-05-24 17:56:26 Project content is packed for delivery (3.41KB). +2022-05-24 17:56:26 Sequence of jobs produced with -seed=1653425786 +2022-05-24 17:56:26 If killed, discard servers with: spread -reuse-pid=97780 -discard +2022-05-24 17:56:26 Allocating google:ubuntu-22.04-64... +2022-05-24 17:56:26 Allocating google:ubuntu-20.04-64... +2022-05-24 17:56:26 Allocating google:ubuntu-20.04-64... +2022-05-24 17:56:36 Waiting for google:ubuntu-20.04-64 (may242056-644336) to boot at 35.185.37.159... +2022-05-24 17:56:41 Waiting for google:ubuntu-22.04-64 (may242056-644230) to boot at 34.75.94.174... +2022-05-24 17:56:42 Waiting for google:ubuntu-20.04-64 (may242056-644428) to boot at 34.138.43.204... +2022-05-24 17:57:17 Allocated google:ubuntu-22.04-64 (may242056-644230). +2022-05-24 17:57:17 Connecting to google:ubuntu-22.04-64 (may242056-644230)... +2022-05-24 17:57:19 Connected to google:ubuntu-22.04-64 (may242056-644230) at 34.75.94.174. +2022-05-24 17:57:19 Sending project content to google:ubuntu-22.04-64 (may242056-644230)... +2022-05-24 17:57:22 Allocated google:ubuntu-20.04-64 (may242056-644336). +2022-05-24 17:57:22 Connecting to google:ubuntu-20.04-64 (may242056-644336)... +2022-05-24 17:57:23 Preparing google:ubuntu-22.04-64 (may242056-644230)... +2022-05-24 17:57:24 Allocated google:ubuntu-20.04-64 (may242056-644428). +2022-05-24 17:57:24 Connecting to google:ubuntu-20.04-64 (may242056-644428)... +2022-05-24 17:57:24 Connected to google:ubuntu-20.04-64 (may242056-644336) at 35.185.37.159. +2022-05-24 17:57:24 Sending project content to google:ubuntu-20.04-64 (may242056-644336)... +2022-05-24 17:57:24 Preparing google:ubuntu-22.04-64:tests/ (may242056-644230)... +2022-05-24 17:57:25 Preparing google:ubuntu-22.04-64:tests/test-4 (may242056-644230)... +2022-05-24 17:57:25 Connected to google:ubuntu-20.04-64 (may242056-644428) at 34.138.43.204. +2022-05-24 17:57:25 Sending project content to google:ubuntu-20.04-64 (may242056-644428)... +2022-05-24 17:57:26 Executing google:ubuntu-22.04-64:tests/test-4 (may242056-644230) (1/10)... +2022-05-24 17:57:26 Restoring google:ubuntu-22.04-64:tests/test-4 (may242056-644230)... +2022-05-24 17:57:27 Preparing google:ubuntu-22.04-64:tests/test-1 (may242056-644230)... +2022-05-24 17:57:27 Preparing google:ubuntu-20.04-64 (may242056-644428)... +2022-05-24 17:57:27 Preparing google:ubuntu-20.04-64 (may242056-644336)... +2022-05-24 17:57:28 Preparing google:ubuntu-20.04-64:tests/ (may242056-644428)... +2022-05-24 17:57:28 Error preparing google:ubuntu-22.04-64:tests/test-1 (may242056-644230) : +----- ++ echo prepare +prepare ++ exit 1 +----- +. +2022-05-24 17:57:28 Restoring google:ubuntu-22.04-64:tests/test-1 (may242056-644230)... +2022-05-24 17:57:28 Preparing google:ubuntu-20.04-64:tests/ (may242056-644336)... +2022-05-24 17:57:28 Preparing google:ubuntu-20.04-64:tests/test-2 (may242056-644428)... +2022-05-24 17:57:28 Error restoring google:ubuntu-22.04-64:tests/test-1 (may242056-644230) : +----- ++ echo restore +restore ++ exit 1 +----- +. +2022-05-24 17:57:28 Restoring google:ubuntu-22.04-64:tests/ (may242056-644230)... +2022-05-24 17:57:29 Executing google:ubuntu-20.04-64:tests/test-2 (may242056-644428) (3/10)... +2022-05-24 17:57:29 Preparing google:ubuntu-20.04-64:tests/test-4 (may242056-644336)... +2022-05-24 17:57:29 Restoring google:ubuntu-22.04-64 (may242056-644230)... +2022-05-24 17:57:29 Restoring google:ubuntu-20.04-64:tests/test-2 (may242056-644428)... +2022-05-24 17:57:29 Executing google:ubuntu-20.04-64:tests/test-4 (may242056-644336) (4/10)... +2022-05-24 17:57:29 Discarding google:ubuntu-22.04-64 (may242056-644230)... +2022-05-24 17:57:30 Preparing google:ubuntu-20.04-64:tests/test-5 (may242056-644428)... +2022-05-24 17:57:30 Restoring google:ubuntu-20.04-64:tests/test-4 (may242056-644336)... +2022-05-24 17:57:30 Executing google:ubuntu-20.04-64:tests/test-5 (may242056-644428) (5/10)... +2022-05-24 17:57:30 Preparing google:ubuntu-20.04-64:tests/test-1 (may242056-644336)... +2022-05-24 17:57:31 Restoring google:ubuntu-20.04-64:tests/test-5 (may242056-644428)... +2022-05-24 17:57:31 Preparing google:ubuntu-20.04-64:tests/test-3 (may242056-644428)... +2022-05-24 17:57:31 Error preparing google:ubuntu-20.04-64:tests/test-1 (may242056-644336) : +----- ++ echo prepare +prepare ++ exit 1 +----- +. +2022-05-24 17:57:31 Restoring google:ubuntu-20.04-64:tests/test-1 (may242056-644336)... +2022-05-24 17:57:32 Executing google:ubuntu-20.04-64:tests/test-3 (may242056-644428) (6/10)... +2022-05-24 17:57:32 Error restoring google:ubuntu-20.04-64:tests/test-1 (may242056-644336) : +----- ++ echo restore +restore ++ exit 1 +----- +. +2022-05-24 17:57:32 Restoring google:ubuntu-20.04-64:tests/ (may242056-644336)... +2022-05-24 17:57:32 Restoring google:ubuntu-20.04-64:tests/test-3 (may242056-644428)... +2022-05-24 17:57:33 Restoring google:ubuntu-20.04-64 (may242056-644336)... +2022-05-24 17:57:33 Restoring google:ubuntu-20.04-64:tests/ (may242056-644428)... +2022-05-24 17:57:33 Restoring google:ubuntu-20.04-64 (may242056-644428)... +2022-05-24 17:57:34 Discarding google:ubuntu-20.04-64 (may242056-644336)... +2022-05-24 17:57:34 Discarding google:ubuntu-20.04-64 (may242056-644428)... +2022-05-24 17:57:34 Successful tasks: 5 +2022-05-24 17:57:34 Aborted tasks: 5 +2022-05-24 17:57:34 Failed task prepare: 2 + - google:ubuntu-20.04-64:tests/test-1 + - google:ubuntu-22.04-64:tests/test-1 +2022-05-24 17:57:34 Failed task restore: 2 + - google:ubuntu-20.04-64:tests/test-1 + - google:ubuntu-22.04-64:tests/test-1 diff --git a/tests/log-analyzer/data/failed-prepare-project.json b/tests/log-analyzer/data/failed-prepare-project.json new file mode 100644 index 00000000..3a443963 --- /dev/null +++ b/tests/log-analyzer/data/failed-prepare-project.json @@ -0,0 +1,315 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "18:04:51", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:04:51", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:00", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242104-523536) to boot at 34.148.146.189..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:05", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242104-523644) to boot at 35.185.103.64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:42", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242104-523536)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:42", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242104-523536)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:43", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242104-523536) at 34.148.146.189." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:43", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242104-523536)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:47", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:48", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:48", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:49", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:49", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:50", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:50", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:50", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:51", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:52", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:52", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:53", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:53", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:54", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:54", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:55", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:55", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:56", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:05:56", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:57", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242104-523644)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:57", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242104-523644)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:57", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242104-523536)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:58", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242104-523644) at 35.185.103.64." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:05:58", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242104-523644)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:06:01", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "18:06:01", + "info_type": "Error", + "verb": "preparing", + "task": "google:ubuntu-20.04-64", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo 'Prepare log-analyzer-reexec project'\n", + "Prepare log-analyzer-reexec project\n", + "+ '[' ubuntu-20.04-64 = ubuntu-20.04-64 ']'\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:06:01", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:06:02", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242104-523644)..." + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:06:02", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "5", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:06:02", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "5", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:06:02", + "result_type": "Failed", + "level": "project", + "stage": "prepare", + "number": "1", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:project\n" + ] + } + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/failed-prepare-project.log b/tests/log-analyzer/data/failed-prepare-project.log new file mode 100644 index 00000000..f17d7483 --- /dev/null +++ b/tests/log-analyzer/data/failed-prepare-project.log @@ -0,0 +1,50 @@ +2022-05-24 18:04:51 Project content is packed for delivery (4.90KB). +2022-05-24 18:04:51 Sequence of jobs produced with -seed=1653426291 +2022-05-24 18:04:51 If killed, discard servers with: spread -reuse-pid=98482 -discard +2022-05-24 18:04:51 Allocating google:ubuntu-22.04-64... +2022-05-24 18:04:51 Allocating google:ubuntu-20.04-64... +2022-05-24 18:05:00 Waiting for google:ubuntu-22.04-64 (may242104-523536) to boot at 34.148.146.189... +2022-05-24 18:05:05 Waiting for google:ubuntu-20.04-64 (may242104-523644) to boot at 35.185.103.64... +2022-05-24 18:05:42 Allocated google:ubuntu-22.04-64 (may242104-523536). +2022-05-24 18:05:42 Connecting to google:ubuntu-22.04-64 (may242104-523536)... +2022-05-24 18:05:43 Connected to google:ubuntu-22.04-64 (may242104-523536) at 34.148.146.189. +2022-05-24 18:05:43 Sending project content to google:ubuntu-22.04-64 (may242104-523536)... +2022-05-24 18:05:47 Preparing google:ubuntu-22.04-64 (may242104-523536)... +2022-05-24 18:05:48 Preparing google:ubuntu-22.04-64:tests/ (may242104-523536)... +2022-05-24 18:05:48 Preparing google:ubuntu-22.04-64:tests/test-2 (may242104-523536)... +2022-05-24 18:05:49 Executing google:ubuntu-22.04-64:tests/test-2 (may242104-523536) (1/10)... +2022-05-24 18:05:49 Restoring google:ubuntu-22.04-64:tests/test-2 (may242104-523536)... +2022-05-24 18:05:50 Preparing google:ubuntu-22.04-64:tests/test-5 (may242104-523536)... +2022-05-24 18:05:50 Executing google:ubuntu-22.04-64:tests/test-5 (may242104-523536) (2/10)... +2022-05-24 18:05:50 Restoring google:ubuntu-22.04-64:tests/test-5 (may242104-523536)... +2022-05-24 18:05:51 Preparing google:ubuntu-22.04-64:tests/test-1 (may242104-523536)... +2022-05-24 18:05:52 Executing google:ubuntu-22.04-64:tests/test-1 (may242104-523536) (3/10)... +2022-05-24 18:05:52 Restoring google:ubuntu-22.04-64:tests/test-1 (may242104-523536)... +2022-05-24 18:05:53 Preparing google:ubuntu-22.04-64:tests/test-4 (may242104-523536)... +2022-05-24 18:05:53 Executing google:ubuntu-22.04-64:tests/test-4 (may242104-523536) (4/10)... +2022-05-24 18:05:54 Restoring google:ubuntu-22.04-64:tests/test-4 (may242104-523536)... +2022-05-24 18:05:54 Preparing google:ubuntu-22.04-64:tests/test-3 (may242104-523536)... +2022-05-24 18:05:55 Executing google:ubuntu-22.04-64:tests/test-3 (may242104-523536) (5/10)... +2022-05-24 18:05:55 Restoring google:ubuntu-22.04-64:tests/test-3 (may242104-523536)... +2022-05-24 18:05:56 Restoring google:ubuntu-22.04-64:tests/ (may242104-523536)... +2022-05-24 18:05:56 Restoring google:ubuntu-22.04-64 (may242104-523536)... +2022-05-24 18:05:57 Allocated google:ubuntu-20.04-64 (may242104-523644). +2022-05-24 18:05:57 Connecting to google:ubuntu-20.04-64 (may242104-523644)... +2022-05-24 18:05:57 Discarding google:ubuntu-22.04-64 (may242104-523536)... +2022-05-24 18:05:58 Connected to google:ubuntu-20.04-64 (may242104-523644) at 35.185.103.64. +2022-05-24 18:05:58 Sending project content to google:ubuntu-20.04-64 (may242104-523644)... +2022-05-24 18:06:01 Preparing google:ubuntu-20.04-64 (may242104-523644)... +2022-05-24 18:06:01 Error preparing google:ubuntu-20.04-64 (may242104-523644) : +----- ++ echo 'Prepare log-analyzer-reexec project' +Prepare log-analyzer-reexec project ++ '[' ubuntu-20.04-64 = ubuntu-20.04-64 ']' ++ exit 1 +----- +. +2022-05-24 18:06:01 Restoring google:ubuntu-20.04-64 (may242104-523644)... +2022-05-24 18:06:02 Discarding google:ubuntu-20.04-64 (may242104-523644)... +2022-05-24 18:06:02 Successful tasks: 5 +2022-05-24 18:06:02 Aborted tasks: 5 +2022-05-24 18:06:02 Failed project prepare: 1 + - google:ubuntu-20.04-64:project diff --git a/tests/log-analyzer/data/failed-prepare-suite.json b/tests/log-analyzer/data/failed-prepare-suite.json new file mode 100644 index 00000000..27bab6cd --- /dev/null +++ b/tests/log-analyzer/data/failed-prepare-suite.json @@ -0,0 +1,327 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "18:02:09", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:02:09", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:02:17", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242102-500954) to boot at 34.138.163.49..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:02:18", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242102-501054) to boot at 35.227.118.17..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:03:04", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242102-500954)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:03:04", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242102-500954)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:03:05", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242102-500954) at 34.138.163.49." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:03:05", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242102-500954)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:03:09", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242102-501054)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:03:09", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242102-501054)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:09", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:03:11", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242102-501054) at 35.227.118.17." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:03:11", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242102-501054)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:11", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:11", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:12", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:12", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:13", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:13", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:14", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:14", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:14", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "18:03:14", + "info_type": "Error", + "verb": "preparing", + "task": "google:ubuntu-20.04-64:tests/", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ '[' ubuntu-20.04-64 = ubuntu-20.04-64 ']'\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:14", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:15", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:15", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:03:15", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242102-501054)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:15", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:16", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:17", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:17", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:18", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:19", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:20", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:20", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:21", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "18:03:22", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "18:03:22", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242102-500954)..." + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:03:23", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "5", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:03:23", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "5", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "18:03:23", + "result_type": "Failed", + "level": "suite", + "stage": "prepare", + "number": "1", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:tests/\n" + ] + } + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/failed-prepare-suite.log b/tests/log-analyzer/data/failed-prepare-suite.log new file mode 100644 index 00000000..e61c0893 --- /dev/null +++ b/tests/log-analyzer/data/failed-prepare-suite.log @@ -0,0 +1,50 @@ +2022-05-24 18:02:09 Project content is packed for delivery (4.54KB). +2022-05-24 18:02:09 Sequence of jobs produced with -seed=1653426129 +2022-05-24 18:02:09 If killed, discard servers with: spread -reuse-pid=98221 -discard +2022-05-24 18:02:09 Allocating google:ubuntu-22.04-64... +2022-05-24 18:02:09 Allocating google:ubuntu-20.04-64... +2022-05-24 18:02:17 Waiting for google:ubuntu-22.04-64 (may242102-500954) to boot at 34.138.163.49... +2022-05-24 18:02:18 Waiting for google:ubuntu-20.04-64 (may242102-501054) to boot at 35.227.118.17... +2022-05-24 18:03:04 Allocated google:ubuntu-22.04-64 (may242102-500954). +2022-05-24 18:03:04 Connecting to google:ubuntu-22.04-64 (may242102-500954)... +2022-05-24 18:03:05 Connected to google:ubuntu-22.04-64 (may242102-500954) at 34.138.163.49. +2022-05-24 18:03:05 Sending project content to google:ubuntu-22.04-64 (may242102-500954)... +2022-05-24 18:03:09 Allocated google:ubuntu-20.04-64 (may242102-501054). +2022-05-24 18:03:09 Connecting to google:ubuntu-20.04-64 (may242102-501054)... +2022-05-24 18:03:09 Preparing google:ubuntu-22.04-64 (may242102-500954)... +2022-05-24 18:03:11 Connected to google:ubuntu-20.04-64 (may242102-501054) at 35.227.118.17. +2022-05-24 18:03:11 Sending project content to google:ubuntu-20.04-64 (may242102-501054)... +2022-05-24 18:03:11 Preparing google:ubuntu-22.04-64:tests/ (may242102-500954)... +2022-05-24 18:03:11 Preparing google:ubuntu-22.04-64:tests/test-3 (may242102-500954)... +2022-05-24 18:03:12 Executing google:ubuntu-22.04-64:tests/test-3 (may242102-500954) (1/10)... +2022-05-24 18:03:12 Restoring google:ubuntu-22.04-64:tests/test-3 (may242102-500954)... +2022-05-24 18:03:13 Preparing google:ubuntu-22.04-64:tests/test-5 (may242102-500954)... +2022-05-24 18:03:13 Preparing google:ubuntu-20.04-64 (may242102-501054)... +2022-05-24 18:03:14 Executing google:ubuntu-22.04-64:tests/test-5 (may242102-500954) (2/10)... +2022-05-24 18:03:14 Preparing google:ubuntu-20.04-64:tests/ (may242102-501054)... +2022-05-24 18:03:14 Restoring google:ubuntu-22.04-64:tests/test-5 (may242102-500954)... +2022-05-24 18:03:14 Error preparing google:ubuntu-20.04-64:tests/ (may242102-501054) : +----- ++ '[' ubuntu-20.04-64 = ubuntu-20.04-64 ']' ++ exit 1 +----- +. +2022-05-24 18:03:14 Restoring google:ubuntu-20.04-64:tests/ (may242102-501054)... +2022-05-24 18:03:15 Restoring google:ubuntu-20.04-64 (may242102-501054)... +2022-05-24 18:03:15 Preparing google:ubuntu-22.04-64:tests/test-1 (may242102-500954)... +2022-05-24 18:03:15 Discarding google:ubuntu-20.04-64 (may242102-501054)... +2022-05-24 18:03:15 Executing google:ubuntu-22.04-64:tests/test-1 (may242102-500954) (8/10)... +2022-05-24 18:03:16 Restoring google:ubuntu-22.04-64:tests/test-1 (may242102-500954)... +2022-05-24 18:03:17 Preparing google:ubuntu-22.04-64:tests/test-4 (may242102-500954)... +2022-05-24 18:03:17 Executing google:ubuntu-22.04-64:tests/test-4 (may242102-500954) (9/10)... +2022-05-24 18:03:18 Restoring google:ubuntu-22.04-64:tests/test-4 (may242102-500954)... +2022-05-24 18:03:19 Preparing google:ubuntu-22.04-64:tests/test-2 (may242102-500954)... +2022-05-24 18:03:20 Executing google:ubuntu-22.04-64:tests/test-2 (may242102-500954) (10/10)... +2022-05-24 18:03:20 Restoring google:ubuntu-22.04-64:tests/test-2 (may242102-500954)... +2022-05-24 18:03:21 Restoring google:ubuntu-22.04-64:tests/ (may242102-500954)... +2022-05-24 18:03:22 Restoring google:ubuntu-22.04-64 (may242102-500954)... +2022-05-24 18:03:22 Discarding google:ubuntu-22.04-64 (may242102-500954)... +2022-05-24 18:03:23 Successful tasks: 5 +2022-05-24 18:03:23 Aborted tasks: 5 +2022-05-24 18:03:23 Failed suite prepare: 1 + - google:ubuntu-20.04-64:tests/ diff --git a/tests/log-analyzer/data/failed-prepare-task.json b/tests/log-analyzer/data/failed-prepare-task.json new file mode 100644 index 00000000..ce9c10af --- /dev/null +++ b/tests/log-analyzer/data/failed-prepare-task.json @@ -0,0 +1,607 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "17:58:47", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:58:47", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:58:47", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:58:47", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:58:56", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242058-071834) to boot at 34.75.85.33..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:58:56", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242058-071935) to boot at 104.196.44.113..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:58:57", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242058-072004) to boot at 35.196.115.140..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:02", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242058-072021) to boot at 34.139.4.50..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:32", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242058-071834)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:32", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242058-071834)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:33", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242058-071834) at 34.75.85.33." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:33", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242058-071834)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:37", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:38", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:38", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:38", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242058-072021)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:38", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242058-072021)..." + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:59:39", + "info_type": "Error", + "verb": "preparing", + "task": "google:ubuntu-22.04-64:tests/test-1", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo prepare\n", + "prepare\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:39", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:39", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:40", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242058-072021) at 34.139.4.50." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:40", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242058-072021)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:40", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:40", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:41", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:41", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:42", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:42", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:43", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242058-072004)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:43", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242058-072004)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:43", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:43", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:43", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:44", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:44", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:44", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242058-072004) at 35.196.115.140." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:44", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242058-072004)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:44", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:44", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:45", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:45", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242058-071834)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:45", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:46", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:46", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:47", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242058-072021)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:47", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242058-071935)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:47", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242058-071935)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:49", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242058-071935) at 104.196.44.113." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:49", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242058-071935)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:50", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:50", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:51", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:51", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:52", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:52", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:52", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:53", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:53", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:53", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:53", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:54", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:54", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:55", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:55", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:55", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:56", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:56", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:59:56", + "info_type": "Error", + "verb": "preparing", + "task": "google:ubuntu-20.04-64:tests/test-1", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo prepare\n", + "prepare\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:56", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:56", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:57", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:59:57", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:57", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242058-072004)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:59:58", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242058-071935)..." + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:59:58", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "8", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:59:58", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "2", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:59:58", + "result_type": "Failed", + "level": "task", + "stage": "prepare", + "number": "2", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:tests/test-1\n", + " - google:ubuntu-22.04-64:tests/test-1\n" + ] + } + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/failed-prepare-task.log b/tests/log-analyzer/data/failed-prepare-task.log new file mode 100644 index 00000000..70948d10 --- /dev/null +++ b/tests/log-analyzer/data/failed-prepare-task.log @@ -0,0 +1,94 @@ +2022-05-24 17:58:47 Project content is packed for delivery (3.92KB). +2022-05-24 17:58:47 Sequence of jobs produced with -seed=1653425927 +2022-05-24 17:58:47 If killed, discard servers with: spread -reuse-pid=97961 -discard +2022-05-24 17:58:47 Allocating google:ubuntu-22.04-64... +2022-05-24 17:58:47 Allocating google:ubuntu-20.04-64... +2022-05-24 17:58:47 Allocating google:ubuntu-20.04-64... +2022-05-24 17:58:47 Allocating google:ubuntu-22.04-64... +2022-05-24 17:58:56 Waiting for google:ubuntu-22.04-64 (may242058-071834) to boot at 34.75.85.33... +2022-05-24 17:58:56 Waiting for google:ubuntu-20.04-64 (may242058-071935) to boot at 104.196.44.113... +2022-05-24 17:58:57 Waiting for google:ubuntu-20.04-64 (may242058-072004) to boot at 35.196.115.140... +2022-05-24 17:59:02 Waiting for google:ubuntu-22.04-64 (may242058-072021) to boot at 34.139.4.50... +2022-05-24 17:59:32 Allocated google:ubuntu-22.04-64 (may242058-071834). +2022-05-24 17:59:32 Connecting to google:ubuntu-22.04-64 (may242058-071834)... +2022-05-24 17:59:33 Connected to google:ubuntu-22.04-64 (may242058-071834) at 34.75.85.33. +2022-05-24 17:59:33 Sending project content to google:ubuntu-22.04-64 (may242058-071834)... +2022-05-24 17:59:37 Preparing google:ubuntu-22.04-64 (may242058-071834)... +2022-05-24 17:59:38 Preparing google:ubuntu-22.04-64:tests/ (may242058-071834)... +2022-05-24 17:59:38 Preparing google:ubuntu-22.04-64:tests/test-1 (may242058-071834)... +2022-05-24 17:59:38 Allocated google:ubuntu-22.04-64 (may242058-072021). +2022-05-24 17:59:38 Connecting to google:ubuntu-22.04-64 (may242058-072021)... +2022-05-24 17:59:39 Error preparing google:ubuntu-22.04-64:tests/test-1 (may242058-071834) : +----- ++ echo prepare +prepare ++ exit 1 +----- +. +2022-05-24 17:59:39 Restoring google:ubuntu-22.04-64:tests/test-1 (may242058-071834)... +2022-05-24 17:59:39 Preparing google:ubuntu-22.04-64:tests/test-5 (may242058-071834)... +2022-05-24 17:59:40 Connected to google:ubuntu-22.04-64 (may242058-072021) at 34.139.4.50. +2022-05-24 17:59:40 Sending project content to google:ubuntu-22.04-64 (may242058-072021)... +2022-05-24 17:59:40 Executing google:ubuntu-22.04-64:tests/test-5 (may242058-071834) (2/10)... +2022-05-24 17:59:40 Restoring google:ubuntu-22.04-64:tests/test-5 (may242058-071834)... +2022-05-24 17:59:41 Preparing google:ubuntu-22.04-64:tests/test-3 (may242058-071834)... +2022-05-24 17:59:41 Executing google:ubuntu-22.04-64:tests/test-3 (may242058-071834) (3/10)... +2022-05-24 17:59:42 Restoring google:ubuntu-22.04-64:tests/test-3 (may242058-071834)... +2022-05-24 17:59:42 Preparing google:ubuntu-22.04-64:tests/test-2 (may242058-071834)... +2022-05-24 17:59:43 Allocated google:ubuntu-20.04-64 (may242058-072004). +2022-05-24 17:59:43 Connecting to google:ubuntu-20.04-64 (may242058-072004)... +2022-05-24 17:59:43 Executing google:ubuntu-22.04-64:tests/test-2 (may242058-071834) (4/10)... +2022-05-24 17:59:43 Restoring google:ubuntu-22.04-64:tests/test-2 (may242058-071834)... +2022-05-24 17:59:43 Preparing google:ubuntu-22.04-64 (may242058-072021)... +2022-05-24 17:59:44 Preparing google:ubuntu-22.04-64:tests/ (may242058-072021)... +2022-05-24 17:59:44 Restoring google:ubuntu-22.04-64:tests/ (may242058-071834)... +2022-05-24 17:59:44 Connected to google:ubuntu-20.04-64 (may242058-072004) at 35.196.115.140. +2022-05-24 17:59:44 Sending project content to google:ubuntu-20.04-64 (may242058-072004)... +2022-05-24 17:59:44 Preparing google:ubuntu-22.04-64:tests/test-4 (may242058-072021)... +2022-05-24 17:59:44 Restoring google:ubuntu-22.04-64 (may242058-071834)... +2022-05-24 17:59:45 Executing google:ubuntu-22.04-64:tests/test-4 (may242058-072021) (5/10)... +2022-05-24 17:59:45 Discarding google:ubuntu-22.04-64 (may242058-071834)... +2022-05-24 17:59:45 Restoring google:ubuntu-22.04-64:tests/test-4 (may242058-072021)... +2022-05-24 17:59:46 Restoring google:ubuntu-22.04-64:tests/ (may242058-072021)... +2022-05-24 17:59:46 Restoring google:ubuntu-22.04-64 (may242058-072021)... +2022-05-24 17:59:47 Discarding google:ubuntu-22.04-64 (may242058-072021)... +2022-05-24 17:59:47 Allocated google:ubuntu-20.04-64 (may242058-071935). +2022-05-24 17:59:47 Connecting to google:ubuntu-20.04-64 (may242058-071935)... +2022-05-24 17:59:49 Connected to google:ubuntu-20.04-64 (may242058-071935) at 104.196.44.113. +2022-05-24 17:59:49 Sending project content to google:ubuntu-20.04-64 (may242058-071935)... +2022-05-24 17:59:50 Preparing google:ubuntu-20.04-64 (may242058-072004)... +2022-05-24 17:59:50 Preparing google:ubuntu-20.04-64:tests/ (may242058-072004)... +2022-05-24 17:59:51 Preparing google:ubuntu-20.04-64:tests/test-5 (may242058-072004)... +2022-05-24 17:59:51 Executing google:ubuntu-20.04-64:tests/test-5 (may242058-072004) (6/10)... +2022-05-24 17:59:52 Restoring google:ubuntu-20.04-64:tests/test-5 (may242058-072004)... +2022-05-24 17:59:52 Preparing google:ubuntu-20.04-64 (may242058-071935)... +2022-05-24 17:59:52 Preparing google:ubuntu-20.04-64:tests/test-3 (may242058-072004)... +2022-05-24 17:59:53 Preparing google:ubuntu-20.04-64:tests/ (may242058-071935)... +2022-05-24 17:59:53 Executing google:ubuntu-20.04-64:tests/test-3 (may242058-072004) (7/10)... +2022-05-24 17:59:53 Preparing google:ubuntu-20.04-64:tests/test-4 (may242058-071935)... +2022-05-24 17:59:53 Restoring google:ubuntu-20.04-64:tests/test-3 (may242058-072004)... +2022-05-24 17:59:54 Preparing google:ubuntu-20.04-64:tests/test-2 (may242058-072004)... +2022-05-24 17:59:54 Executing google:ubuntu-20.04-64:tests/test-4 (may242058-071935) (8/10)... +2022-05-24 17:59:55 Executing google:ubuntu-20.04-64:tests/test-2 (may242058-072004) (9/10)... +2022-05-24 17:59:55 Restoring google:ubuntu-20.04-64:tests/test-4 (may242058-071935)... +2022-05-24 17:59:55 Restoring google:ubuntu-20.04-64:tests/test-2 (may242058-072004)... +2022-05-24 17:59:56 Preparing google:ubuntu-20.04-64:tests/test-1 (may242058-072004)... +2022-05-24 17:59:56 Restoring google:ubuntu-20.04-64:tests/ (may242058-071935)... +2022-05-24 17:59:56 Error preparing google:ubuntu-20.04-64:tests/test-1 (may242058-072004) : +----- ++ echo prepare +prepare ++ exit 1 +----- +. +2022-05-24 17:59:56 Restoring google:ubuntu-20.04-64:tests/test-1 (may242058-072004)... +2022-05-24 17:59:56 Restoring google:ubuntu-20.04-64:tests/ (may242058-072004)... +2022-05-24 17:59:57 Restoring google:ubuntu-20.04-64 (may242058-071935)... +2022-05-24 17:59:57 Restoring google:ubuntu-20.04-64 (may242058-072004)... +2022-05-24 17:59:57 Discarding google:ubuntu-20.04-64 (may242058-072004)... +2022-05-24 17:59:58 Discarding google:ubuntu-20.04-64 (may242058-071935)... +2022-05-24 17:59:58 Successful tasks: 8 +2022-05-24 17:59:58 Aborted tasks: 2 +2022-05-24 17:59:58 Failed task prepare: 2 + - google:ubuntu-20.04-64:tests/test-1 + - google:ubuntu-22.04-64:tests/test-1 diff --git a/tests/log-analyzer/data/with-aborted-and-failed-restore.json b/tests/log-analyzer/data/with-aborted-and-failed-restore.json new file mode 100644 index 00000000..904d43c8 --- /dev/null +++ b/tests/log-analyzer/data/with-aborted-and-failed-restore.json @@ -0,0 +1,285 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "17:47:36", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:47:36", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:47:46", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242047-566476) to boot at 104.196.212.243..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:47:46", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242047-566626) to boot at 34.75.76.3..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:48:32", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242047-566626)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:48:32", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242047-566626)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:48:34", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242047-566626) at 34.75.76.3." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:48:34", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242047-566626)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:39", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:40", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:40", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:41", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:42", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:48:42", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242047-566476)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:48:42", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242047-566476)..." + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:48:43", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-22.04-64:tests/test-5", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo restore\n", + "restore\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:43", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:48:43", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242047-566476) at 104.196.212.243." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:48:43", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242047-566476)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:44", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:48:45", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242047-566626)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:46", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:47", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:47", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:48", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:48", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:48:49", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-20.04-64:tests/test-1", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo restore\n", + "restore\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:49", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:48:49", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:48:50", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242047-566476)..." + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:48:50", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "2", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:48:50", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "8", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:48:50", + "result_type": "Failed", + "level": "task", + "stage": "restore", + "number": "2", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:tests/test-1\n", + " - google:ubuntu-22.04-64:tests/test-5\n" + ] + } + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/with-aborted-and-failed-restore.log b/tests/log-analyzer/data/with-aborted-and-failed-restore.log new file mode 100644 index 00000000..e13fbb3b --- /dev/null +++ b/tests/log-analyzer/data/with-aborted-and-failed-restore.log @@ -0,0 +1,50 @@ +2022-05-24 17:47:36 Project content is packed for delivery (2.50KB). +2022-05-24 17:47:36 Sequence of jobs produced with -seed=1653425256 +2022-05-24 17:47:36 If killed, discard servers with: spread -reuse-pid=97052 -discard +2022-05-24 17:47:36 Allocating google:ubuntu-22.04-64... +2022-05-24 17:47:36 Allocating google:ubuntu-20.04-64... +2022-05-24 17:47:46 Waiting for google:ubuntu-20.04-64 (may242047-566476) to boot at 104.196.212.243... +2022-05-24 17:47:46 Waiting for google:ubuntu-22.04-64 (may242047-566626) to boot at 34.75.76.3... +2022-05-24 17:48:32 Allocated google:ubuntu-22.04-64 (may242047-566626). +2022-05-24 17:48:32 Connecting to google:ubuntu-22.04-64 (may242047-566626)... +2022-05-24 17:48:34 Connected to google:ubuntu-22.04-64 (may242047-566626) at 34.75.76.3. +2022-05-24 17:48:34 Sending project content to google:ubuntu-22.04-64 (may242047-566626)... +2022-05-24 17:48:39 Preparing google:ubuntu-22.04-64 (may242047-566626)... +2022-05-24 17:48:40 Preparing google:ubuntu-22.04-64:tests/ (may242047-566626)... +2022-05-24 17:48:40 Preparing google:ubuntu-22.04-64:tests/test-5 (may242047-566626)... +2022-05-24 17:48:41 Executing google:ubuntu-22.04-64:tests/test-5 (may242047-566626) (1/10)... +2022-05-24 17:48:42 Restoring google:ubuntu-22.04-64:tests/test-5 (may242047-566626)... +2022-05-24 17:48:42 Allocated google:ubuntu-20.04-64 (may242047-566476). +2022-05-24 17:48:42 Connecting to google:ubuntu-20.04-64 (may242047-566476)... +2022-05-24 17:48:43 Error restoring google:ubuntu-22.04-64:tests/test-5 (may242047-566626) : +----- ++ echo restore +restore ++ exit 1 +----- +. +2022-05-24 17:48:43 Restoring google:ubuntu-22.04-64:tests/ (may242047-566626)... +2022-05-24 17:48:43 Connected to google:ubuntu-20.04-64 (may242047-566476) at 104.196.212.243. +2022-05-24 17:48:43 Sending project content to google:ubuntu-20.04-64 (may242047-566476)... +2022-05-24 17:48:44 Restoring google:ubuntu-22.04-64 (may242047-566626)... +2022-05-24 17:48:45 Discarding google:ubuntu-22.04-64 (may242047-566626)... +2022-05-24 17:48:46 Preparing google:ubuntu-20.04-64 (may242047-566476)... +2022-05-24 17:48:47 Preparing google:ubuntu-20.04-64:tests/ (may242047-566476)... +2022-05-24 17:48:47 Preparing google:ubuntu-20.04-64:tests/test-1 (may242047-566476)... +2022-05-24 17:48:48 Executing google:ubuntu-20.04-64:tests/test-1 (may242047-566476) (2/10)... +2022-05-24 17:48:48 Restoring google:ubuntu-20.04-64:tests/test-1 (may242047-566476)... +2022-05-24 17:48:49 Error restoring google:ubuntu-20.04-64:tests/test-1 (may242047-566476) : +----- ++ echo restore +restore ++ exit 1 +----- +. +2022-05-24 17:48:49 Restoring google:ubuntu-20.04-64:tests/ (may242047-566476)... +2022-05-24 17:48:49 Restoring google:ubuntu-20.04-64 (may242047-566476)... +2022-05-24 17:48:50 Discarding google:ubuntu-20.04-64 (may242047-566476)... +2022-05-24 17:48:50 Successful tasks: 2 +2022-05-24 17:48:50 Aborted tasks: 8 +2022-05-24 17:48:50 Failed task restore: 2 + - google:ubuntu-20.04-64:tests/test-1 + - google:ubuntu-22.04-64:tests/test-5 diff --git a/tests/log-analyzer/data/with-failed-and-failed-restore-suite.json b/tests/log-analyzer/data/with-failed-and-failed-restore-suite.json new file mode 100644 index 00000000..8ebaf677 --- /dev/null +++ b/tests/log-analyzer/data/with-failed-and-failed-restore-suite.json @@ -0,0 +1,493 @@ +[ + { + "type": "operation", + "date": "2022-05-24", + "time": "17:42:58", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-22.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:42:58", + "verb": "Allocating", + "task": null, + "extra": "google:ubuntu-20.04-64..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:07", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-22.04-64 (may242043-312411) to boot at 34.148.59.204..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:07", + "verb": "Waiting", + "task": null, + "extra": "for google:ubuntu-20.04-64 (may242043-312500) to boot at 34.138.215.109..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:43", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242043-312411)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:43", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242043-312411)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:45", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-22.04-64 (may242043-312411) at 34.148.59.204." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:43:45", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-22.04-64 (may242043-312411)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:50", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:50", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:51", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:52", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:52", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:53", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:54", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:43:54", + "info_type": "Error", + "verb": "executing", + "task": "google:ubuntu-22.04-64:tests/test-2", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo execute\n", + "execute\n", + "+ exit 1\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:55", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:55", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:56", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:56", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:57", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:58", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:58", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:43:59", + "verb": "Preparing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:00", + "verb": "Executing", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:00", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:01", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:02", + "verb": "Restoring", + "task": "google:ubuntu-22.04-64" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:44:02", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-22.04-64", + "extra": null, + "detail": { + "lines": [ + "-----\n", + "+ echo 'Restore snapd-testing-tools project'\n", + "Restore snapd-testing-tools project\n", + "/bin/bash: line 26: PROJECT_PATH: unbound variable\n", + "-----\n", + ".\n" + ] + } + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:02", + "verb": "Discarding", + "task": null, + "extra": "google:ubuntu-22.04-64 (may242043-312411)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:04", + "verb": "Allocated", + "task": null, + "extra": "google:ubuntu-20.04-64 (may242043-312500)." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:04", + "verb": "Connecting", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242043-312500)..." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:05", + "verb": "Connected", + "task": null, + "extra": "to google:ubuntu-20.04-64 (may242043-312500) at 34.138.215.109." + }, + { + "type": "operation", + "date": "2022-05-24", + "time": "17:44:05", + "verb": "Sending", + "task": null, + "extra": "project content to google:ubuntu-20.04-64 (may242043-312500)..." + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:08", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:08", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:09", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:09", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:10", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-3" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:10", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:11", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:11", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-1" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:12", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:13", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:13", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-4" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:14", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:14", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:15", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-2" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:15", + "verb": "Preparing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:16", + "verb": "Executing", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:16", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/test-5" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:17", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64:tests/" + }, + { + "type": "action", + "date": "2022-05-24", + "time": "17:44:17", + "verb": "Restoring", + "task": "google:ubuntu-20.04-64" + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:44:18", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-20.04-64:tests/", + "extra": null, + "detail": null + }, + { + "type": "info", + "date": "2022-05-24", + "time": "17:44:18", + "info_type": "Error", + "verb": "restoring", + "task": "google:ubuntu-20.04-64", + "extra": null, + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:44:19", + "result_type": "Successful", + "level": "tasks", + "stage": null, + "number": "9", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:44:19", + "result_type": "Aborted", + "level": "tasks", + "stage": null, + "number": "0", + "detail": null + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:44:19", + "result_type": "Failed", + "level": "tasks", + "stage": null, + "number": "1", + "detail": { + "lines": [ + " - google:ubuntu-22.04-64:tests/test-2\n" + ] + } + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:44:19", + "result_type": "Failed", + "level": "suite", + "stage": "restore", + "number": "1", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:tests/\n" + ] + } + }, + { + "type": "result", + "date": "2022-05-24", + "time": "17:44:19", + "result_type": "Failed", + "level": "project", + "stage": "restore", + "number": "2", + "detail": { + "lines": [ + " - google:ubuntu-20.04-64:project\n", + " - google:ubuntu-22.04-64:project\n" + ] + } + } +] \ No newline at end of file diff --git a/tests/log-analyzer/data/with-failed-and-failed-restore-suite.log b/tests/log-analyzer/data/with-failed-and-failed-restore-suite.log new file mode 100644 index 00000000..919a43b0 --- /dev/null +++ b/tests/log-analyzer/data/with-failed-and-failed-restore-suite.log @@ -0,0 +1,79 @@ +2022-05-24 17:42:58 Project content is packed for delivery (1.30KB). +2022-05-24 17:42:58 Sequence of jobs produced with -seed=1653424978 +2022-05-24 17:42:58 If killed, discard servers with: spread -reuse-pid=96667 -discard +2022-05-24 17:42:58 Allocating google:ubuntu-22.04-64... +2022-05-24 17:42:58 Allocating google:ubuntu-20.04-64... +2022-05-24 17:43:07 Waiting for google:ubuntu-22.04-64 (may242043-312411) to boot at 34.148.59.204... +2022-05-24 17:43:07 Waiting for google:ubuntu-20.04-64 (may242043-312500) to boot at 34.138.215.109... +2022-05-24 17:43:43 Allocated google:ubuntu-22.04-64 (may242043-312411). +2022-05-24 17:43:43 Connecting to google:ubuntu-22.04-64 (may242043-312411)... +2022-05-24 17:43:45 Connected to google:ubuntu-22.04-64 (may242043-312411) at 34.148.59.204. +2022-05-24 17:43:45 Sending project content to google:ubuntu-22.04-64 (may242043-312411)... +2022-05-24 17:43:50 Preparing google:ubuntu-22.04-64 (may242043-312411)... +2022-05-24 17:43:50 Preparing google:ubuntu-22.04-64:tests/ (may242043-312411)... +2022-05-24 17:43:51 Preparing google:ubuntu-22.04-64:tests/test-3 (may242043-312411)... +2022-05-24 17:43:52 Executing google:ubuntu-22.04-64:tests/test-3 (may242043-312411) (1/10)... +2022-05-24 17:43:52 Restoring google:ubuntu-22.04-64:tests/test-3 (may242043-312411)... +2022-05-24 17:43:53 Preparing google:ubuntu-22.04-64:tests/test-2 (may242043-312411)... +2022-05-24 17:43:54 Executing google:ubuntu-22.04-64:tests/test-2 (may242043-312411) (2/10)... +2022-05-24 17:43:54 Error executing google:ubuntu-22.04-64:tests/test-2 (may242043-312411) : +----- ++ echo execute +execute ++ exit 1 +----- +. +2022-05-24 17:43:55 Restoring google:ubuntu-22.04-64:tests/test-2 (may242043-312411)... +2022-05-24 17:43:55 Preparing google:ubuntu-22.04-64:tests/test-4 (may242043-312411)... +2022-05-24 17:43:56 Executing google:ubuntu-22.04-64:tests/test-4 (may242043-312411) (3/10)... +2022-05-24 17:43:56 Restoring google:ubuntu-22.04-64:tests/test-4 (may242043-312411)... +2022-05-24 17:43:57 Preparing google:ubuntu-22.04-64:tests/test-1 (may242043-312411)... +2022-05-24 17:43:58 Executing google:ubuntu-22.04-64:tests/test-1 (may242043-312411) (4/10)... +2022-05-24 17:43:58 Restoring google:ubuntu-22.04-64:tests/test-1 (may242043-312411)... +2022-05-24 17:43:59 Preparing google:ubuntu-22.04-64:tests/test-5 (may242043-312411)... +2022-05-24 17:44:00 Executing google:ubuntu-22.04-64:tests/test-5 (may242043-312411) (5/10)... +2022-05-24 17:44:00 Restoring google:ubuntu-22.04-64:tests/test-5 (may242043-312411)... +2022-05-24 17:44:01 Restoring google:ubuntu-22.04-64:tests/ (may242043-312411)... +2022-05-24 17:44:02 Restoring google:ubuntu-22.04-64 (may242043-312411)... +2022-05-24 17:44:02 Error restoring google:ubuntu-22.04-64 (may242043-312411) : +----- ++ echo 'Restore snapd-testing-tools project' +Restore snapd-testing-tools project +/bin/bash: line 26: PROJECT_PATH: unbound variable +----- +. +2022-05-24 17:44:02 Discarding google:ubuntu-22.04-64 (may242043-312411)... +2022-05-24 17:44:04 Allocated google:ubuntu-20.04-64 (may242043-312500). +2022-05-24 17:44:04 Connecting to google:ubuntu-20.04-64 (may242043-312500)... +2022-05-24 17:44:05 Connected to google:ubuntu-20.04-64 (may242043-312500) at 34.138.215.109. +2022-05-24 17:44:05 Sending project content to google:ubuntu-20.04-64 (may242043-312500)... +2022-05-24 17:44:08 Preparing google:ubuntu-20.04-64 (may242043-312500)... +2022-05-24 17:44:08 Preparing google:ubuntu-20.04-64:tests/ (may242043-312500)... +2022-05-24 17:44:09 Preparing google:ubuntu-20.04-64:tests/test-3 (may242043-312500)... +2022-05-24 17:44:09 Executing google:ubuntu-20.04-64:tests/test-3 (may242043-312500) (6/10)... +2022-05-24 17:44:10 Restoring google:ubuntu-20.04-64:tests/test-3 (may242043-312500)... +2022-05-24 17:44:10 Preparing google:ubuntu-20.04-64:tests/test-1 (may242043-312500)... +2022-05-24 17:44:11 Executing google:ubuntu-20.04-64:tests/test-1 (may242043-312500) (7/10)... +2022-05-24 17:44:11 Restoring google:ubuntu-20.04-64:tests/test-1 (may242043-312500)... +2022-05-24 17:44:12 Preparing google:ubuntu-20.04-64:tests/test-4 (may242043-312500)... +2022-05-24 17:44:13 Executing google:ubuntu-20.04-64:tests/test-4 (may242043-312500) (8/10)... +2022-05-24 17:44:13 Restoring google:ubuntu-20.04-64:tests/test-4 (may242043-312500)... +2022-05-24 17:44:14 Preparing google:ubuntu-20.04-64:tests/test-2 (may242043-312500)... +2022-05-24 17:44:14 Executing google:ubuntu-20.04-64:tests/test-2 (may242043-312500) (9/10)... +2022-05-24 17:44:15 Restoring google:ubuntu-20.04-64:tests/test-2 (may242043-312500)... +2022-05-24 17:44:15 Preparing google:ubuntu-20.04-64:tests/test-5 (may242043-312500)... +2022-05-24 17:44:16 Executing google:ubuntu-20.04-64:tests/test-5 (may242043-312500) (10/10)... +2022-05-24 17:44:16 Restoring google:ubuntu-20.04-64:tests/test-5 (may242043-312500)... +2022-05-24 17:44:17 Restoring google:ubuntu-20.04-64:tests/ (may242043-312500)... +2022-05-24 17:44:17 Restoring google:ubuntu-20.04-64 (may242043-312500)... +2022-05-24 17:44:18 Error restoring google:ubuntu-20.04-64:tests/ (may242043-312500) : EOF +2022-05-24 17:44:18 Error restoring google:ubuntu-20.04-64 (may242043-312500) : EOF +2022-05-24 17:44:19 Successful tasks: 9 +2022-05-24 17:44:19 Aborted tasks: 0 +2022-05-24 17:44:19 Failed tasks: 1 + - google:ubuntu-22.04-64:tests/test-2 +2022-05-24 17:44:19 Failed suite restore: 1 + - google:ubuntu-20.04-64:tests/ +2022-05-24 17:44:19 Failed project restore: 2 + - google:ubuntu-20.04-64:project + - google:ubuntu-22.04-64:project diff --git a/tests/log-analyzer/spread.yaml b/tests/log-analyzer/spread.yaml new file mode 100644 index 00000000..6ada9d62 --- /dev/null +++ b/tests/log-analyzer/spread.yaml @@ -0,0 +1,35 @@ +project: log-analyzer + +details: | + This project is used to test the log analyzer tool. The project contains a + set of tests which are needed by the log analyzer to list all the tests which + have to be consider to be able to detect the tests which have been aborted and + are not listed in the results section. + +backends: + google: + key: '$(HOST: echo "$SPREAD_GOOGLE_KEY")' + location: snapd-spread/us-east1-b + halt-timeout: 2h + systems: + - ubuntu-20.04-64: + workers: 1 + - ubuntu-22.04-64: + workers: 1 + +path: /root/log-analyzer-reexec + +prepare: | + echo "Prepare log-analyzer-reexec project" + +restore: | + echo "Restore snapd-testing-tools project" + +suites: + tests/: + summary: Main test suite for snapd-testing-tools + prepare: | + echo "Preparing log-analyzer-reexec main suite" + + restore: | + echo "Restoring log-analyzer-reexec main suite" diff --git a/tests/log-analyzer/task.yaml b/tests/log-analyzer/task.yaml new file mode 100644 index 00000000..e1f2b42a --- /dev/null +++ b/tests/log-analyzer/task.yaml @@ -0,0 +1,243 @@ +summary: integration tests for log-analyzer tool + +backends: [google] + +# Github actions agents are just running ubuntu jammy +systems: [ubuntu-22.04-64] + +prepare: | + wget https://storage.googleapis.com/snapd-spread-tests/spread/spread-amd64.tar.gz + tar -xvzf spread-amd64.tar.gz + mv spread /usr/bin + +restore: | + rm spread-amd64.tar.gz /usr/bin/spread + +execute: | + compare_tasks_count() { + tasks=$1 + count=$2 + + test "$(echo "$tasks" | wc -w)" = "$count" + } + + # RESULTS OF JSON FILES USED # + # all-failed.json + # When all the tests are failed, no successful and no aborted tests are listed + # ubuntu-20.04 (F:5 P:0 A:0) + # ubuntu-22.04 (F:5 P:0 A:0) + # all-aborted.json + # When all the tests are aborted, no successful and no failed tests are listed + # ubuntu-20.04 (F:0 P:0 A:5) + # ubuntu-22.04 (F:0 P:0 A:5) + # all-success.json + # When all the tests execute correctly, no tests are listed for re-execution + # ubuntu-20.04 (F:0 P:5 A:0) + # ubuntu-22.04 (F:0 P:5 A:0) + # all-success-failed-restore.json + # When all the tasks are executed correctly but the suite fails to restore, all of them are listed to reexec + # ubuntu-20.04 (F:0 P:5 A:0) + # ubuntu-22.04 (F:0 P:5 A:0) + # failed-prepare-task.json + # Tasks which fail to prepare are not counted as failed and are counted as aborted + # ubuntu-20.04 (F:1 P:4 A:1) + # ubuntu-22.04 (F:1 P:4 A:1) + # failed-prepare-and-restore.json + # Tasks which fail to prepare or restore and are not executed are not counted as failed + # ubuntu-20.04 (F:0 P:4 A:1) + # ubuntu-22.04 (F:0 P:1 A:4) + # failed-prepare-project.json + # When a project fails to prepare, all the tasks are aborted + # ubuntu-20.04 (F:0 P:0 A:5) + # ubuntu-22.04 (F:0 P:5 A:0) + # failed-prepare-suite.json + # When a suite fails to prepare, all the tasks are aborted + # ubuntu-20.04 (F:0 P:0 A:5) + # ubuntu-22.04 (F:0 P:5 A:0) + # aborted-and-failed-execute-and-restore.json + # Tasks which fail to execute are counted as fail, when a task fails to restore the following tasks are aborted + # ubuntu-20.04 (F:1 P:4 A:0) + # ubuntu-22.04 (F:1 P:1 A:3) + # with-aborted-and-failed-restore.json + # Tasks which execute correctly and fail to restore are not counted as failed + # ubuntu-20.04 (F:0 P:1 A:4) + # ubuntu-22.04 (F:0 P:1 A:4) + # with-failed-and-failed-restore-suite.json + # Just failed tasks are counted for re-execution + # ubuntu-20.04 (F:0 P:0 A:0) + # ubuntu-22.04 (F:1 P:1 A:0) + + ### CHECK HELP ### + log-analyzer | MATCH "usage: log-analyzer list-failed-tasks " + log-analyzer -h | MATCH "usage: log-analyzer list-failed-tasks " + log-analyzer --help | MATCH "usage: log-analyzer list-failed-tasks " + + ### CHECK RE-EXECUTION ### + + # When all the tasks have to be re-executed, the execution expression is returned + log-analyzer list-reexecute-tasks google: data/all-aborted.json | MATCH "^google:$" + log-analyzer list-reexecute-tasks google:ubuntu-20.04-64: data/all-aborted.json | MATCH "^google:ubuntu-20.04-64:$" + + # When all the tests pass and then fail to restore, no tests are listed for re-execution + log-analyzer list-reexecute-tasks google: data/all-success-failed-restore.json | NOMATCH "google:" + compare_tasks_count "$(log-analyzer list-reexecute-tasks google: data/all-success-failed-restore.json)" 0 + log-analyzer list-reexecute-tasks google:ubuntu-20.04-64: data/all-success-failed-restore.json | NOMATCH "google:ubuntu-20.04-64:" + + # When all the tests are successful, no tests are listed for re-execution + log-analyzer list-reexecute-tasks google: data/all-success.json | NOMATCH "google:" + compare_tasks_count "$(log-analyzer list-reexecute-tasks google: data/all-success.json)" 0 + log-analyzer list-reexecute-tasks google:ubuntu-20.04-64: data/all-success.json | NOMATCH "google:ubuntu-20.04-64:" + + # When all the tests are failed, the execution expression is returned + log-analyzer list-reexecute-tasks google: data/all-failed.json | MATCH "^google:$" + log-analyzer list-reexecute-tasks google:ubuntu-20.04-64: data/all-failed.json | MATCH "^google:ubuntu-20.04-64:$" + + # When some tests failed, those tests are displayed, if those tests are all the tests for the expression, then the expression is returned + log-analyzer list-reexecute-tasks google: data/failed-prepare-project.json | MATCH "google:ubuntu-20.04-64:tests/test-1" + compare_tasks_count "$(log-analyzer list-reexecute-tasks google: data/failed-prepare-project.json)" 5 + log-analyzer list-reexecute-tasks google:ubuntu-20.04-64: data/failed-prepare-project.json | MATCH "^google:ubuntu-20.04-64:$" + + log-analyzer list-reexecute-tasks google: data/failed-prepare-suite.json | MATCH "google:ubuntu-20.04-64:tests/test-1" + compare_tasks_count "$(log-analyzer list-reexecute-tasks google: data/failed-prepare-suite.json)" 5 + log-analyzer list-reexecute-tasks google:ubuntu-20.04-64: data/failed-prepare-suite.json | MATCH "^google:ubuntu-20.04-64:$" + + # when some tasks are aborted, those are listed, also tasks that failed to restore are listed + log-analyzer list-reexecute-tasks google: data/with-aborted-and-failed-restore.json | MATCH "google:" + compare_tasks_count "$(log-analyzer list-reexecute-tasks google: data/with-aborted-and-failed-restore.json)" 1 + + # When some tasks failed to prepare, those are aborted and are listed in the result + log-analyzer list-reexecute-tasks google: data/failed-prepare-task.json | MATCH "google:ubuntu-22.04-64:tests/test-1" + compare_tasks_count "$(log-analyzer list-reexecute-tasks google: data/failed-prepare-task.json)" 2 + + # When some tests failed to prepare and restore, those are listed just once in the result + log-analyzer list-reexecute-tasks google: data/failed-prepare-and-restore.json | MATCH "google:ubuntu-20.04-64:tests/test-1" + log-analyzer list-reexecute-tasks google: data/failed-prepare-and-restore.json | MATCH "google:ubuntu-22.04-64:tests/test-1" + log-analyzer list-reexecute-tasks google: data/failed-prepare-and-restore.json | NOMATCH "google:ubuntu-20.04-64:tests/test-4" + log-analyzer list-reexecute-tasks google: data/failed-prepare-and-restore.json | NOMATCH "google:ubuntu-22.04-64:tests/test-4" + compare_tasks_count "$(log-analyzer list-reexecute-tasks google: data/failed-prepare-and-restore.json)" 5 + + # When some tests failed to execute and restore, those are listed just once in the result + log-analyzer list-reexecute-tasks google: data/aborted-and-failed-execute-and-restore.json | MATCH "google:ubuntu-20.04-64:tests/test-2" + log-analyzer list-reexecute-tasks google: data/aborted-and-failed-execute-and-restore.json | MATCH "google:ubuntu-22.04-64:tests/test-2" + log-analyzer list-reexecute-tasks google: data/aborted-and-failed-execute-and-restore.json | NOMATCH "google:ubuntu-20.04-64:tests/test-4" + log-analyzer list-reexecute-tasks google: data/aborted-and-failed-execute-and-restore.json | NOMATCH "google:ubuntu-22.04-64:tests/test-4" + compare_tasks_count "$(log-analyzer list-reexecute-tasks google: data/aborted-and-failed-execute-and-restore.json)" 5 + + # When some tests failed to execute and the suite and project fails to restore, just the failed test is re-executed + log-analyzer list-reexecute-tasks google: data/with-failed-and-failed-restore-suite.json | MATCH "google:ubuntu-22.04-64:tests/test-2" + compare_tasks_count "$(log-analyzer list-reexecute-tasks google: data/with-failed-and-failed-restore-suite.json)" 1 + + ### CHECK ABORTED ### + + compare_tasks_count "$(log-analyzer list-aborted-tasks google: data/all-aborted.json)" 10 + compare_tasks_count "$(log-analyzer list-aborted-tasks google:ubuntu-20.04-64: data/all-aborted.json)" 5 + + compare_tasks_count "$(log-analyzer list-aborted-tasks google: data/all-success-failed-restore.json)" 0 + + compare_tasks_count "$(log-analyzer list-aborted-tasks google: data/all-success.json)" 0 + compare_tasks_count "$(log-analyzer list-aborted-tasks google:ubuntu-20.04-64: data/all-success.json)" 0 + + compare_tasks_count "$(log-analyzer list-aborted-tasks google: data/all-failed.json)" 0 + + compare_tasks_count "$(log-analyzer list-aborted-tasks google: data/failed-prepare-project.json)" 5 + + compare_tasks_count "$(log-analyzer list-aborted-tasks google: data/failed-prepare-suite.json)" 5 + compare_tasks_count "$(log-analyzer list-aborted-tasks google:ubuntu-20.04-64: data/failed-prepare-suite.json)" 5 + compare_tasks_count "$(log-analyzer list-aborted-tasks google:ubuntu-22.04-64: data/failed-prepare-suite.json)" 0 + + compare_tasks_count "$(log-analyzer list-aborted-tasks google: data/with-aborted-and-failed-restore.json)" 8 + + compare_tasks_count "$(log-analyzer list-aborted-tasks google: data/failed-prepare-task.json)" 2 + + compare_tasks_count "$(log-analyzer list-aborted-tasks google: data/failed-prepare-and-restore.json)" 5 + + compare_tasks_count "$(log-analyzer list-aborted-tasks google: data/aborted-and-failed-execute-and-restore.json)" 3 + compare_tasks_count "$(log-analyzer list-aborted-tasks google:ubuntu-20.04-64: data/aborted-and-failed-execute-and-restore.json)" 0 + compare_tasks_count "$(log-analyzer list-aborted-tasks google:ubuntu-22.04-64: data/aborted-and-failed-execute-and-restore.json)" 3 + + ### CHECK SUCCESSFUL ### + + compare_tasks_count "$(log-analyzer list-successful-tasks google: data/all-aborted.json)" 0 + + compare_tasks_count "$(log-analyzer list-successful-tasks google: data/all-success-failed-restore.json)" 10 + + compare_tasks_count "$(log-analyzer list-successful-tasks google: data/all-success.json)" 10 + compare_tasks_count "$(log-analyzer list-successful-tasks google:ubuntu-20.04-64: data/all-success.json)" 5 + + compare_tasks_count "$(log-analyzer list-successful-tasks google: data/all-failed.json)" 0 + + compare_tasks_count "$(log-analyzer list-successful-tasks google: data/failed-prepare-project.json)" 5 + + compare_tasks_count "$(log-analyzer list-successful-tasks google: data/failed-prepare-suite.json)" 5 + compare_tasks_count "$(log-analyzer list-successful-tasks google:ubuntu-22.04-64: data/failed-prepare-suite.json)" 5 + compare_tasks_count "$(log-analyzer list-successful-tasks google:ubuntu-20.04-64: data/failed-prepare-suite.json)" 0 + + compare_tasks_count "$(log-analyzer list-successful-tasks google: data/with-aborted-and-failed-restore.json)" 0 + + compare_tasks_count "$(log-analyzer list-successful-tasks google: data/failed-prepare-task.json)" 8 + compare_tasks_count "$(log-analyzer list-successful-tasks google:ubuntu-20.04-64: data/failed-prepare-task.json)" 4 + compare_tasks_count "$(log-analyzer list-successful-tasks google:ubuntu-22.04-64: data/failed-prepare-task.json)" 4 + + compare_tasks_count "$(log-analyzer list-successful-tasks google: data/failed-prepare-and-restore.json)" 5 + + compare_tasks_count "$(log-analyzer list-successful-tasks google: data/aborted-and-failed-execute-and-restore.json)" 5 + compare_tasks_count "$(log-analyzer list-successful-tasks google:ubuntu-20.04-64: data/aborted-and-failed-execute-and-restore.json)" 4 + compare_tasks_count "$(log-analyzer list-successful-tasks google:ubuntu-22.04-64: data/aborted-and-failed-execute-and-restore.json)" 1 + + ### CHECK FAILED ### + + compare_tasks_count "$(log-analyzer list-failed-tasks google: data/all-aborted.json)" 0 + + compare_tasks_count "$(log-analyzer list-failed-tasks google: data/all-success-failed-restore.json)" 0 + + compare_tasks_count "$(log-analyzer list-failed-tasks google: data/all-success.json)" 0 + + compare_tasks_count "$(log-analyzer list-failed-tasks google: data/all-failed.json)" 10 + compare_tasks_count "$(log-analyzer list-failed-tasks google:ubuntu-20.04-64: data/all-failed.json)" 5 + + compare_tasks_count "$(log-analyzer list-failed-tasks google: data/failed-prepare-project.json)" 0 + + compare_tasks_count "$(log-analyzer list-failed-tasks google: data/failed-prepare-suite.json)" 0 + + compare_tasks_count "$(log-analyzer list-failed-tasks google: data/with-aborted-and-failed-restore.json)" 0 + + compare_tasks_count "$(log-analyzer list-failed-tasks google: data/failed-prepare-task.json)" 0 + + compare_tasks_count "$(log-analyzer list-failed-tasks google: data/failed-prepare-and-restore.json)" 0 + + compare_tasks_count "$(log-analyzer list-failed-tasks google: data/aborted-and-failed-execute-and-restore.json)" 2 + compare_tasks_count "$(log-analyzer list-failed-tasks google:ubuntu-20.04-64: data/aborted-and-failed-execute-and-restore.json)" 1 + compare_tasks_count "$(log-analyzer list-failed-tasks google:ubuntu-22.04-64: data/aborted-and-failed-execute-and-restore.json)" 1 + + ### CHECK EXECUTED ### + + compare_tasks_count "$(log-analyzer list-executed-tasks google: data/all-aborted.json)" 0 + + compare_tasks_count "$(log-analyzer list-executed-tasks google: data/all-success-failed-restore.json)" 10 + + compare_tasks_count "$(log-analyzer list-executed-tasks google: data/all-success.json)" 10 + + compare_tasks_count "$(log-analyzer list-executed-tasks google: data/all-failed.json)" 10 + compare_tasks_count "$(log-analyzer list-executed-tasks google:ubuntu-20.04-64: data/all-failed.json)" 5 + compare_tasks_count "$(log-analyzer list-executed-tasks google:ubuntu-22.04-64: data/all-failed.json)" 5 + + compare_tasks_count "$(log-analyzer list-executed-tasks google: data/failed-prepare-project.json)" 5 + + compare_tasks_count "$(log-analyzer list-executed-tasks google: data/failed-prepare-suite.json)" 5 + + compare_tasks_count "$(log-analyzer list-executed-tasks google: data/with-aborted-and-failed-restore.json)" 2 + + compare_tasks_count "$(log-analyzer list-executed-tasks google: data/failed-prepare-task.json)" 8 + + compare_tasks_count "$(log-analyzer list-executed-tasks google: data/failed-prepare-and-restore.json)" 5 + + compare_tasks_count "$(log-analyzer list-executed-tasks google: data/aborted-and-failed-execute-and-restore.json)" 7 + compare_tasks_count "$(log-analyzer list-executed-tasks google:ubuntu-20.04-64: data/aborted-and-failed-execute-and-restore.json)" 5 + compare_tasks_count "$(log-analyzer list-executed-tasks google:ubuntu-22.04-64: data/aborted-and-failed-execute-and-restore.json)" 2 + + ### CHECK ALL ### + compare_tasks_count "$(log-analyzer list-all-tasks google:)" 10 + compare_tasks_count "$(log-analyzer list-all-tasks 'google:ubuntu-20.04-64: google:ubuntu-22.04-64:')" 10 + compare_tasks_count "$(log-analyzer list-all-tasks 'google:ubuntu-20.04-64:,google:ubuntu-22.04-64:')" 10 + compare_tasks_count "$(log-analyzer list-all-tasks google:ubuntu-20.04-64:)" 5 + compare_tasks_count "$(log-analyzer list-all-tasks google:ubuntu-22.04-64:)" 5 diff --git a/tests/log-analyzer/tests/test-1/task.yaml b/tests/log-analyzer/tests/test-1/task.yaml new file mode 100644 index 00000000..21cc04f3 --- /dev/null +++ b/tests/log-analyzer/tests/test-1/task.yaml @@ -0,0 +1,10 @@ +summary: summary + +prepare: | + echo "prepare" + +restore: | + echo "restore" + +execute: | + echo "execute" diff --git a/tests/log-analyzer/tests/test-2/task.yaml b/tests/log-analyzer/tests/test-2/task.yaml new file mode 100644 index 00000000..21cc04f3 --- /dev/null +++ b/tests/log-analyzer/tests/test-2/task.yaml @@ -0,0 +1,10 @@ +summary: summary + +prepare: | + echo "prepare" + +restore: | + echo "restore" + +execute: | + echo "execute" diff --git a/tests/log-analyzer/tests/test-3/task.yaml b/tests/log-analyzer/tests/test-3/task.yaml new file mode 100644 index 00000000..21cc04f3 --- /dev/null +++ b/tests/log-analyzer/tests/test-3/task.yaml @@ -0,0 +1,10 @@ +summary: summary + +prepare: | + echo "prepare" + +restore: | + echo "restore" + +execute: | + echo "execute" diff --git a/tests/log-analyzer/tests/test-4/task.yaml b/tests/log-analyzer/tests/test-4/task.yaml new file mode 100644 index 00000000..21cc04f3 --- /dev/null +++ b/tests/log-analyzer/tests/test-4/task.yaml @@ -0,0 +1,10 @@ +summary: summary + +prepare: | + echo "prepare" + +restore: | + echo "restore" + +execute: | + echo "execute" diff --git a/tests/log-analyzer/tests/test-5/task.yaml b/tests/log-analyzer/tests/test-5/task.yaml new file mode 100644 index 00000000..0577d308 --- /dev/null +++ b/tests/log-analyzer/tests/test-5/task.yaml @@ -0,0 +1,10 @@ +summary: summary + +prepare: | + echo "prepare" + +restore: | + echo "restore" + +execute: | + echo "execute" diff --git a/tests/log-parser/all-aborted.log.spread b/tests/log-parser/all-aborted.log.spread new file mode 100644 index 00000000..bb64b51c --- /dev/null +++ b/tests/log-parser/all-aborted.log.spread @@ -0,0 +1,46 @@ +2021-01-20 12:29:36 Project content is packed for delivery (265.87KB). +2021-01-20 12:29:36 Sequence of jobs produced with -seed=1611145776 +2021-01-20 12:29:36 If killed, discard servers with: spread -reuse-pid=30187 -discard +2021-01-20 12:29:36 Allocating google:ubuntu-21.04-64... +2021-01-20 12:29:37 Allocating google:ubuntu-21.04-64... +2021-01-20 12:29:37 Allocating google:ubuntu-21.04-64... +2021-01-20 12:29:37 Allocating google:ubuntu-21.04-64... +2021-01-20 12:29:37 Allocating google:ubuntu-21.04-64... +2021-01-20 12:29:37 Allocating google:ubuntu-21.04-64... +2021-01-20 12:29:37 Allocating google:ubuntu-21.04-64... +2021-01-20 12:29:37 Allocating google:ubuntu-21.04-64... +2021-01-20 12:29:50 Waiting for google:ubuntu-21.04-64 (jan201229-232006) to boot at 35.196.53.112... +2021-01-20 12:29:51 Waiting for google:ubuntu-21.04-64 (jan201229-232290) to boot at 35.237.111.213... +2021-01-20 12:29:52 Waiting for google:ubuntu-21.04-64 (jan201229-232308) to boot at 104.196.172.222... +2021-01-20 12:29:52 Waiting for google:ubuntu-21.04-64 (jan201229-232314) to boot at 34.75.124.6... +2021-01-20 12:29:52 Waiting for google:ubuntu-21.04-64 (jan201229-232320) to boot at 35.185.0.186... +2021-01-20 12:29:56 Waiting for google:ubuntu-21.04-64 (jan201229-232297) to boot at 34.74.223.99... +2021-01-20 12:29:56 Waiting for google:ubuntu-21.04-64 (jan201229-232303) to boot at 35.231.44.102... +2021-01-20 12:30:00 Waiting for google:ubuntu-21.04-64 (jan201229-232278) to boot at 35.185.82.132... +2021-01-20 12:30:50 Server google:ubuntu-21.04-64 (jan201229-232006) is taking a while to boot... +2021-01-20 12:30:51 Server google:ubuntu-21.04-64 (jan201229-232290) is taking a while to boot... +2021-01-20 12:30:52 Server google:ubuntu-21.04-64 (jan201229-232308) is taking a while to boot... +2021-01-20 12:30:52 Server google:ubuntu-21.04-64 (jan201229-232314) is taking a while to boot... +2021-01-20 12:30:52 Server google:ubuntu-21.04-64 (jan201229-232320) is taking a while to boot... +2021-01-20 12:30:56 Server google:ubuntu-21.04-64 (jan201229-232297) is taking a while to boot... +2021-01-20 12:30:56 Server google:ubuntu-21.04-64 (jan201229-232303) is taking a while to boot... +2021-01-20 12:31:00 Server google:ubuntu-21.04-64 (jan201229-232278) is taking a while to boot... +2021-01-20 12:31:50 Server google:ubuntu-21.04-64 (jan201229-232006) is taking a while to boot... +2021-01-20 12:31:51 Server google:ubuntu-21.04-64 (jan201229-232290) is taking a while to boot... +2021-01-20 12:31:52 Server google:ubuntu-21.04-64 (jan201229-232308) is taking a while to boot... +2021-01-20 12:31:52 Server google:ubuntu-21.04-64 (jan201229-232320) is taking a while to boot... +2021-01-20 12:31:53 Server google:ubuntu-21.04-64 (jan201229-232314) is taking a while to boot... +2021-01-20 12:31:56 Server google:ubuntu-21.04-64 (jan201229-232297) is taking a while to boot... +2021-01-20 12:31:56 Server google:ubuntu-21.04-64 (jan201229-232303) is taking a while to boot... +2021-01-20 12:32:00 Server google:ubuntu-21.04-64 (jan201229-232278) is taking a while to boot... +2021-01-20 12:32:51 Cannot allocate google:ubuntu-21.04-64: cannot allocate new Google server google:ubuntu-21.04-64 (jan201229-232006): cannot find ready marker in console output for google:ubuntu-21.04-64 (jan201229-232006) +2021-01-20 12:32:51 Cannot allocate google:ubuntu-21.04-64: cannot allocate new Google server google:ubuntu-21.04-64 (jan201229-232290): cannot find ready marker in console output for google:ubuntu-21.04-64 (jan201229-232290) +2021-01-20 12:32:52 Cannot allocate google:ubuntu-21.04-64: cannot allocate new Google server google:ubuntu-21.04-64 (jan201229-232308): cannot find ready marker in console output for google:ubuntu-21.04-64 (jan201229-232308) +2021-01-20 12:32:52 Cannot allocate google:ubuntu-21.04-64: cannot allocate new Google server google:ubuntu-21.04-64 (jan201229-232314): cannot find ready marker in console output for google:ubuntu-21.04-64 (jan201229-232314) +2021-01-20 12:32:53 Cannot allocate google:ubuntu-21.04-64: cannot allocate new Google server google:ubuntu-21.04-64 (jan201229-232320): cannot find ready marker in console output for google:ubuntu-21.04-64 (jan201229-232320) +2021-01-20 12:32:56 Cannot allocate google:ubuntu-21.04-64: cannot allocate new Google server google:ubuntu-21.04-64 (jan201229-232297): cannot find ready marker in console output for google:ubuntu-21.04-64 (jan201229-232297) +2021-01-20 12:32:57 Cannot allocate google:ubuntu-21.04-64: cannot allocate new Google server google:ubuntu-21.04-64 (jan201229-232303): cannot find ready marker in console output for google:ubuntu-21.04-64 (jan201229-232303) +error: unsuccessful run +2021-01-20 12:33:01 Cannot allocate google:ubuntu-21.04-64: cannot allocate new Google server google:ubuntu-21.04-64 (jan201229-232278): cannot find ready marker in console output for google:ubuntu-21.04-64 (jan201229-232278) +2021-01-20 12:33:01 Successful tasks: 0 +2021-01-20 12:33:01 Aborted tasks: 505 \ No newline at end of file diff --git a/tests/log-parser/all-successful.log.spread b/tests/log-parser/all-successful.log.spread new file mode 100644 index 00000000..c736ff62 --- /dev/null +++ b/tests/log-parser/all-successful.log.spread @@ -0,0 +1,112 @@ +2021-01-20 12:28:57 Project content is packed for delivery (266.41KB). +2021-01-20 12:28:57 Sequence of jobs produced with -seed=1611145737 +2021-01-20 12:28:57 If killed, discard servers with: spread -reuse-pid=24265 -discard +2021-01-20 12:28:57 Allocating google:centos-8-64... +2021-01-20 12:29:10 Waiting for google:centos-8-64 (jan201228-089626) to boot at 35.229.96.196... +2021-01-20 12:29:33 Sending project content to google:centos-8-64 (jan201228-089626)... +2021-01-20 12:29:33 Connected to google:centos-8-64 (jan201228-089359) at 34.73.106.247. +2021-01-20 12:29:33 Sending project content to google:centos-8-64 (jan201228-089359)... +2021-01-20 12:29:33 Connected to google:centos-8-64 (jan201228-089636) at 35.227.44.209. +2021-01-20 12:29:33 Sending project content to google:centos-8-64 (jan201228-089636)... +2021-01-20 12:29:35 Preparing google:centos-8-64 (jan201228-089626)... +2021-01-20 12:29:35 Preparing google:centos-8-64 (jan201228-089596)... +2021-01-20 12:29:35 Preparing google:centos-8-64 (jan201228-089359)... +2021-01-20 12:29:35 Preparing google:centos-8-64 (jan201228-089636)... +2021-01-20 12:34:36 WARNING: jan201228-089636 (google:centos-8-64) running late. Current output: +----- +(... 376 lines above ...) +pkgconfig(libseccomp) +pkgconfig(libselinux) +pkgconfig(libudev) +pkgconfig(systemd) +pkgconfig(udev) +selinux-policy +selinux-policy-devel +systemd +valgrind +xfsprogs-devel +----- +. +2021-01-20 12:42:47 Restoring google:centos-8-64:tests/completion/snippets:hosts (jan201228-089636)... +2021-01-20 12:42:48 Preparing google:centos-8-64:tests/completion/indirect:func (jan201228-089636)... +2021-01-20 12:42:50 Preparing google:centos-8-64:tests/regression/lp-1844496 (jan201228-089359)... +2021-01-20 12:42:54 Executing google:centos-8-64:tests/completion/indirect:func (jan201228-089636) (2/435)... +2021-01-20 12:42:55 Preparing google:centos-8-64:tests/main/degraded (jan201228-089626)... +2021-01-20 12:43:01 Executing google:centos-8-64:tests/main/degraded (jan201228-089626) (3/435)... +2021-01-20 12:43:01 Restoring google:centos-8-64:tests/main/degraded (jan201228-089626)... +2021-01-20 12:43:02 Preparing google:centos-8-64:tests/main/base-snaps (jan201228-089626)... +2021-01-20 12:43:03 Executing google:centos-8-64:tests/regression/lp-1844496 (jan201228-089359) (4/435)... +2021-01-20 12:43:06 Executing google:centos-8-64:tests/main/base-snaps (jan201228-089626) (5/435)... +2021-01-20 12:43:07 Restoring google:centos-8-64:tests/regression/lp-1844496 (jan201228-089359)... +2021-01-20 12:43:09 Preparing google:centos-8-64:tests/regression/lp-1812973 (jan201228-089359)... +2021-01-20 12:43:15 Executing google:centos-8-64:tests/regression/lp-1812973 (jan201228-089359) (6/435)... +2021-01-20 12:43:16 Restoring google:centos-8-64:tests/regression/lp-1812973 (jan201228-089359)... +2021-01-20 12:43:16 Restoring google:centos-8-64:tests/main/base-snaps (jan201228-089626)... +2021-01-20 12:43:17 Preparing google:centos-8-64:tests/main/snap-validate-basic (jan201228-089626)... +2021-01-20 12:43:18 Preparing google:centos-8-64:tests/regression/lp-1665004 (jan201228-089359)... +2021-01-20 12:43:22 Executing google:centos-8-64:tests/main/snap-validate-basic (jan201228-089626) (7/435)... +2021-01-20 12:43:22 Restoring google:centos-8-64:tests/main/snap-validate-basic (jan201228-089626)... +2021-01-20 12:43:23 Preparing google:centos-8-64:tests/main/interfaces-broadcom-asic-control (jan201228-089596)... +2021-01-20 12:43:23 Preparing google:centos-8-64:tests/main/media-sharing (jan201228-089626)... +2021-01-20 12:43:24 Executing google:centos-8-64:tests/regression/lp-1665004 (jan201228-089359) (8/435)... +2021-01-20 12:43:24 Restoring google:centos-8-64:tests/regression/lp-1665004 (jan201228-089359)... +2021-01-20 12:43:25 Preparing google:centos-8-64:tests/regression/lp-1797556 (jan201228-089359)... +2021-01-20 12:43:30 Executing google:centos-8-64:tests/main/interfaces-broadcom-asic-control (jan201228-089596) (9/435)... +2021-01-20 12:43:32 Executing google:centos-8-64:tests/regression/lp-1797556 (jan201228-089359) (10/435)... +2021-01-20 12:43:32 Restoring google:centos-8-64:tests/regression/lp-1797556 (jan201228-089359)... +2021-01-20 12:43:32 Restoring google:centos-8-64:tests/main/interfaces-broadcom-asic-control (jan201228-089596)... +2021-01-20 12:48:55 Restoring google:centos-8-64:tests/lib/tools/suite/mountinfo.query (jan201228-089359)... +2021-01-20 12:48:56 Preparing google:centos-8-64:tests/lib/tools/suite/tests.pkgs (jan201228-089359)... +2021-01-20 12:48:57 Executing google:centos-8-64:tests/lib/tools/suite/tests.pkgs (jan201228-089359) (90/435)... +2021-01-20 12:48:58 Executing google:centos-8-64:tests/main/security-devpts (jan201228-089596) (91/435)... +2021-01-20 12:49:00 Restoring google:centos-8-64:tests/main/security-devpts (jan201228-089596)... +2021-01-20 12:49:01 Preparing google:centos-8-64:tests/main/interfaces-content-circular (jan201228-089596)... +2021-01-20 12:49:06 Executing google:centos-8-64:tests/main/interfaces-content-circular (jan201228-089596) (92/435)... +2021-01-20 12:49:11 Restoring google:centos-8-64:tests/completion/indirect:funcarg (jan201228-089636)... +2021-01-20 12:49:13 Preparing google:centos-8-64:tests/completion/simple:hosts (jan201228-089636)... +2021-01-20 12:49:17 Restoring google:centos-8-64:tests/main/services-snapctl (jan201228-089626)... +2021-01-20 12:49:17 Executing google:centos-8-64:tests/completion/simple:hosts (jan201228-089636) (93/435)... +2021-01-20 12:49:17 Preparing google:centos-8-64:tests/main/services-refresh-mode (jan201228-089626)... +2021-01-20 12:49:22 Discarding google:centos-8-64 (jan201228-089359)... +2021-01-20 12:49:24 Restoring google:centos-8-64:tests/completion/simple:hosts (jan201228-089636)... +2021-01-20 12:49:24 Preparing google:centos-8-64:tests/completion/indirect:hosts_n_dirs (jan201228-089636)... +2021-01-20 12:49:30 Executing google:centos-8-64:tests/completion/indirect:hosts_n_dirs (jan201228-089636) (94/435)... +2021-01-20 12:49:36 Executing google:centos-8-64:tests/main/services-refresh-mode (jan201228-089626) (95/435)... +2021-01-20 12:49:42 Restoring google:centos-8-64:tests/main/interfaces-content-circular (jan201228-089596)... +2021-01-20 12:49:43 Preparing google:centos-8-64:tests/main/refresh:strict_remote (jan201228-089596)... +2021-01-20 12:53:24 Preparing google:centos-8-64:tests/main/base-snaps-refresh (jan201228-089626)... +2021-01-20 12:53:29 Executing google:centos-8-64:tests/main/base-snaps-refresh (jan201228-089626) (124/435)... +2021-01-20 12:53:38 Restoring google:centos-8-64:tests/main/base-snaps-refresh (jan201228-089626)... +2021-01-20 12:53:38 Restoring google:centos-8-64:tests/main/snapd-snap-removal (jan201228-089596)... +2021-01-20 12:53:39 Preparing google:centos-8-64:tests/main/interfaces-daemon-notify (jan201228-089626)... +2021-01-20 12:53:39 Preparing google:centos-8-64:tests/main/interfaces-content-mkdir-writable:data (jan201228-089596)... +2021-01-20 12:53:45 Executing google:centos-8-64:tests/main/interfaces-daemon-notify (jan201228-089626) (125/435)... +2021-01-20 12:53:46 Executing google:centos-8-64:tests/main/interfaces-content-mkdir-writable:data (jan201228-089596) (126/435)... +2021-01-20 12:53:48 Restoring google:centos-8-64:tests/main/interfaces-content-mkdir-writable:data (jan201228-089596)... +2021-01-20 12:53:49 Preparing google:centos-8-64:tests/main/refresh:parallel_strict_remote (jan201228-089596)... +2021-01-20 12:53:56 Restoring google:centos-8-64:tests/completion/indirect:plain_plusdirs (jan201228-089636)... +2021-01-20 12:53:57 Preparing google:centos-8-64:tests/completion/simple:hosts_n_dirs (jan201228-089636)... +2021-01-20 12:53:57 Restoring google:centos-8-64:tests/main/interfaces-daemon-notify (jan201228-089626)... +2021-01-20 12:53:58 Preparing google:centos-8-64:tests/main/core18-configure-hook (jan201228-089626)... +2021-01-20 12:54:01 Executing google:centos-8-64:tests/main/refresh:parallel_strict_remote (jan201228-089596) (127/435)... +2021-01-20 12:54:02 Executing google:centos-8-64:tests/completion/simple:hosts_n_dirs (jan201228-089636) (128/435)... +2021-01-20 12:59:22 Preparing google:centos-8-64:tests/main/interfaces-fuse-support:regular (jan201228-089596)... +2021-01-20 13:29:28 Restoring google:centos-8-64:tests/main/core18-with-hooks (jan201228-089626)... +2021-01-20 13:29:31 Preparing google:centos-8-64:tests/main/proxy (jan201228-089626)... +2021-01-20 13:29:32 Executing google:centos-8-64:tests/main/services-watchdog (jan201228-089596) (434/435)... +2021-01-20 13:29:36 Executing google:centos-8-64:tests/main/proxy (jan201228-089626) (435/435)... +2021-01-20 13:29:38 Restoring google:centos-8-64:tests/main/proxy (jan201228-089626)... +2021-01-20 13:29:39 Restoring google:centos-8-64:tests/main/services-watchdog (jan201228-089596)... +2021-01-20 13:29:39 Restoring google:centos-8-64:tests/main/ (jan201228-089626)... +2021-01-20 13:29:40 Restoring google:centos-8-64:tests/main/ (jan201228-089596)... +2021-01-20 13:29:46 Restoring google:centos-8-64 (jan201228-089626)... +2021-01-20 13:29:47 Restoring google:centos-8-64 (jan201228-089596)... +2021-01-20 13:29:48 Discarding google:centos-8-64 (jan201228-089626)... +2021-01-20 13:29:49 Discarding google:centos-8-64 (jan201228-089596)... +2021-01-20 13:30:03 Restoring google:centos-8-64:tests/main/auto-refresh-retry (jan201228-089636)... +2021-01-20 13:30:04 Restoring google:centos-8-64:tests/main/ (jan201228-089636)... +2021-01-20 13:30:11 Restoring google:centos-8-64 (jan201228-089636)... +2021-01-20 13:30:12 Discarding google:centos-8-64 (jan201228-089636)... +error: unsuccessful run +2021-01-20 13:30:13 Successful tasks: 434 +2021-01-20 13:30:13 Aborted tasks: 0 \ No newline at end of file diff --git a/tests/log-parser/task.yaml b/tests/log-parser/task.yaml new file mode 100644 index 00000000..591a9519 --- /dev/null +++ b/tests/log-parser/task.yaml @@ -0,0 +1,106 @@ +summary: test for the log parser tool + +backends: [google] + +# Github actions agents are just running ubuntu jammy +systems: [ubuntu-22.04-64] + +execute: | + log-parser --help | MATCH 'usage: log-parser \[-h\] \[-c CUT\]' + log-parser -h | MATCH 'usage: log-parser \[-h\] \[-c CUT\]' + + # Check results when the log just contains successful tests + log-parser all-successful.log.spread + TESTS_SUCCESSFUL=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Successful") | .number' spread-results.json) + test "$TESTS_SUCCESSFUL" = "434" + + # Check results when the log contains failed tests + log-parser with-failed.log.spread + TESTS_SUCCESSFUL=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Successful") | .number' spread-results.json) + TESTS_FAILED=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | .number' spread-results.json) + test "$TESTS_SUCCESSFUL" = "434" + test "$TESTS_FAILED" = "1" + + # Check info when the log contains failed tests + jq -r '.[] | select( .type == "info") | select( .info_type == "Error") | .verb' spread-results.json | MATCH 'executing' + jq -r '.[] | select( .type == "info") | select( .info_type == "Error") | .task' spread-results.json | MATCH 'google:centos-8-64:tests/lib/tools/suite/tests.pkgs' + jq -r '.[] | select( .type == "info") | select( .info_type == "Debug") | .verb' spread-results.json | MATCH 'null' + jq -r '.[] | select( .type == "info") | select( .info_type == "Debug") | .task' spread-results.json | MATCH 'google:centos-8-64:tests/lib/tools/suite/tests.pkgs' + + # Check results when the log contains failed tests + log-parser all-aborted.log.spread + TESTS_SUCCESSFUL=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Successful") | .number' spread-results.json) + TESTS_FAILED=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | .number' spread-results.json) + TESTS_ABORTED=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Aborted") | .number' spread-results.json) + test "$TESTS_SUCCESSFUL" = "0" + test -z "$TESTS_FAILED" + test "$TESTS_ABORTED" = "505" + + # Check results when the log contains aborted, failed and successful TESTS + log-parser with-failed-and-aborted.log.spread + TESTS_SUCCESSFUL=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Successful") | .number' spread-results.json) + TESTS_FAILED_TASKS=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "tasks") | .number' spread-results.json) + TESTS_FAILED_TASK=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "task") | .number' spread-results.json) + TESTS_FAILED_PROJECT=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "project") | .number' spread-results.json) + TESTS_ABORTED=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Aborted") | .number' spread-results.json) + test "$TESTS_SUCCESSFUL" = "400" + test "$TESTS_FAILED_TASKS" = "1" + test "$TESTS_FAILED_TASK" = "1" + test "$TESTS_FAILED_PROJECT" = "4" + test "$TESTS_ABORTED" = "24" + + # Check results with all the failed levels + log-parser with-all-results.log.spread + TESTS_SUCCESSFUL=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Successful") | .number' spread-results.json) + TESTS_FAILED_TASKS=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "tasks") | .number' spread-results.json) + TESTS_FAILED_TASK_PREPARE=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "task") | select(.stage == "prepare") | .number' spread-results.json) + TESTS_FAILED_TASK_RESTORE=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "task") | select(.stage == "restore") | .number' spread-results.json) + TESTS_FAILED_SUITE_PREPARE=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "suite") | select(.stage == "prepare") | .number' spread-results.json) + TESTS_FAILED_SUITE_RESTORE=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "suite") | select(.stage == "restore") | .number' spread-results.json) + TESTS_FAILED_PROJECT_PREPARE=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "project") | select(.stage == "prepare") | .number' spread-results.json) + TESTS_FAILED_PROJECT_RESTORE=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "project") | select(.stage == "restore") | .number' spread-results.json) + TESTS_ABORTED=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Aborted") | .number' spread-results.json) + test "$TESTS_SUCCESSFUL" = "7376" + test "$TESTS_FAILED_TASKS" = "2" + test "$TESTS_FAILED_TASK_PREPARE" = "3" + test "$TESTS_FAILED_TASK_RESTORE" = "2" + test "$TESTS_FAILED_SUITE_PREPARE" = "1" + test "$TESTS_FAILED_SUITE_RESTORE" = "2" + test "$TESTS_FAILED_PROJECT_PREPARE" = "1" + test "$TESTS_FAILED_PROJECT_RESTORE" = "2" + test "$TESTS_ABORTED" = "3061" + + # Check results when a detail contains results + log-parser with-results-in-detail.log.spread + TESTS_SUCCESSFUL=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Successful") | .number' spread-results.json) + TESTS_FAILED_TASKS=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "tasks") | .number' spread-results.json) + TESTS_ABORTED=$(jq -r '.[] | select( .type == "result") | select( .result_type == "Aborted") | .number' spread-results.json) + test "$TESTS_SUCCESSFUL" = "7376" + test "$TESTS_FAILED_TASKS" = "2" + test "$TESTS_ABORTED" = "3061" + jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "tasks") | .detail' spread-results.json | NOMATCH "cloud-init-never-used-not-vuln" + jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "tasks") | .detail' spread-results.json | MATCH "degraded" + + # Check the filter + test "$(log-parser with-failed-and-aborted.log.spread -pd error | grep -c "Error preparing")" -eq 5 + test "$(log-parser with-failed-and-aborted.log.spread -pd error | grep -c "command -v restorecon")" -eq 4 + + # Check the filter cuting the logs + test "$(log-parser with-failed-and-aborted.log.spread -pd error | wc -l)" -eq 184 + test "$(log-parser with-failed-and-aborted.log.spread -pd error -c 0 | wc -l)" -eq 14 + test "$(log-parser with-failed-and-aborted.log.spread -pd error -c 0 | grep -c "Error preparing")" -eq 5 + test "$(log-parser with-failed-and-aborted.log.spread -pd error -c 0 | grep -c "")" -eq 0 + test "$(log-parser with-failed-and-aborted.log.spread -pd error -c 2 | wc -l)" -eq 26 + test "$(log-parser with-failed-and-aborted.log.spread -pd error -c 2 | grep -c "Error preparing")" -eq 5 + test "$(log-parser with-failed-and-aborted.log.spread -pd error -c 2 | grep -c "")" -eq 5 + test "$(log-parser with-failed-and-aborted.log.spread -pd error -c 3 | wc -l)" -eq 32 + test "$(log-parser with-failed-and-aborted.log.spread -pd error -c 3 | grep -c "Error preparing")" -eq 5 + test "$(log-parser with-failed-and-aborted.log.spread -pd error -c 3 | grep -c "")" -eq 5 + + # Check the results can be filtered + log-parser with-failed-and-aborted.log.spread -pr failed | grep -q "Failed tasks: 1" + log-parser with-failed-and-aborted.log.spread -pr failed | grep -c "Failed project prepare: 4" + log-parser with-failed-and-aborted.log.spread -pr aborted | grep -c "Aborted tasks: 24" + log-parser all-successful.log.spread -pr successful | grep -q "Successful tasks: 434" + log-parser all-successful.log.spread -pr failed | grep -v "Aborted tasks" + diff --git a/tests/log-parser/with-all-results.log.spread b/tests/log-parser/with-all-results.log.spread new file mode 100644 index 00000000..c64ac9ac --- /dev/null +++ b/tests/log-parser/with-all-results.log.spread @@ -0,0 +1,163 @@ +2022-05-18 17:49:24 Project content is packed for delivery (8.86MB). +2022-05-18 17:49:24 Sequence of jobs produced with -seed=1652896164 +2022-05-18 17:49:24 If killed, discard servers with: spread -reuse-pid=9308 -discard +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-432987) to boot at 104.196.14.127... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-433163) to boot at 35.237.37.145... +2022-05-18 17:49:47 Waiting for google-nested:ubuntu-16.04-64 (may181749-433044) to boot at 34.148.64.110... +2022-05-18 17:50:03 Allocated google-nested:ubuntu-16.04-64 (may181749-432987). +2022-05-18 17:50:03 Connecting to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:04 Connected to google-nested:ubuntu-16.04-64 (may181749-432987) at 104.196.14.127. +2022-05-18 17:50:04 Sending project content to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:06 Preparing google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:08 Allocated google-nested:ubuntu-16.04-64 (may181749-433163). +2022-05-18 17:50:08 Connecting to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:09 Connected to google-nested:ubuntu-16.04-64 (may181749-433163) at 35.237.37.145. +2022-05-18 17:50:09 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:11 Preparing google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:13 Allocated google-nested:ubuntu-16.04-64 (may181749-433044). +2022-05-18 17:50:13 Connecting to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:13 Connected to google-nested:ubuntu-16.04-64 (may181749-433044) at 34.148.64.110. +2022-05-18 17:50:13 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:15 Preparing google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:55:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 365 lines above ...) ++ restart_logind= ++ loginctl enable-linger test ++ loginctl disable-linger test +Unpacking systemd (229-4ubuntu21.31) over (229-4ubuntu21.28) ... +Processing triggers for dbus (1.10.6-1ubuntu3.6) ... +Processing triggers for ureadahead (0.100.0-19.1) ... +Processing triggers for man-db (2.7.5-1) ... +Setting up systemd (229-4ubuntu21.31) ... +addgroup: The group `systemd-journal' already exists as a system group. Exiting. +[/usr/lib/tmpfiles.d/var.conf:14] Duplicate line for path "/var/log", ignoring. +Setting up libpam-systemd:amd64 (229-4ubuntu21.31) ... +----- +. +2022-05-18 18:00:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:11 WARNING: may181749-433163 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:01:03 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/ (may181749-432987)... +2022-05-18 18:01:17 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/ (may181749-433163)... +2022-05-18 18:03:19 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:05:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:06:03 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64:tests/nested/core/) running late. Current output: +----- +(... 97 lines above ...) +Parallel unsquashfs: Using 2 processors +11398 inodes (13347 blocks) to write + +[===========================================================\] 13347/13347 100% + +created 8997 files +created 1461 directories +created 2312 symlinks +created 79 devices +created 0 fifos +----- +. +2022-05-18 18:06:52 Executing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163) (1/13)... +2022-05-18 18:06:58 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987)... +2022-05-18 18:07:57 Restoring google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:00 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:40 Executing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987) (2/13)... +Error: 2022-05-18 18:09:34 Error preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163) : +----- ++ /home/gopath/src/github.com/snapcore/snapd/tests/lib/prepare-restore.sh --prepare-project-each ++ set -e ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/pkgdb.sh +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/random.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/state.sh +++ SNAPD_STATE_PATH=/var/tmp/snapd-tools/snapd-state +++ SNAPD_STATE_FILE=/var/tmp/snapd-tools/snapd-state/snapd-state.tar +++ RUNTIME_STATE_PATH=/var/tmp/snapd-tools/runtime-state +++ SNAPD_ACTIVE_UNITS=/var/tmp/snapd-tools/runtime-state/snapd-active-units +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/systemd.sh ++ case "$1" in ++ prepare_project_each ++ dmesg -c ++ fixup_dev_random ++ mv /dev/random /dev/random.orig ++ mknod /dev/random c 1 9 ++ kill_gpg_agent ++ pkill -9 -e gpg-agent + +May 18 18:50:05 may181749-433044 kernel: veth33879c75: renamed from physLGGOmx +May 18 18:50:05 may181749-433044 libvirtd[21899]: Failed to open file '/sys/class/net/eth0/operstate': No such file or directory +May 18 18:50:05 may181749-433044 libvirtd[21899]: unable to read: /sys/class/net/eth0/operstate: No such file or directory +May 18 18:50:05 may181749-433044 kernel: device veth690dd0d2 left promiscuous mode +May 18 18:50:05 may181749-433044 kernel: lxdbr0: port 1(veth690dd0d2) entered disabled state +May 18 18:50:05 may181749-433044 audit[20780]: AVC apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:05 may181749-433044 kernel: audit: type=1400 audit(1652899805.951:102): apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #8 lxdbr0, 10.253.239.1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #9 lxdbr0, fd42:9473:7f21:63ab::1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #10 lxdbr0, fe80::216:3eff:feec:f39f%5#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs ++ echo '# tasks executed on system' +# tasks executed on system ++ echo '' ++ cat /var/tmp/snapd-tools/runtime-state/runs - +google-nested:ubuntu-16.04-64:tests/nested/classic/hotplug google-nested:ubuntu-16.04-64:tests/nested/classic/snapshots-with-core-refresh-revert google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_disabled google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_enabled google-nested:ubuntu-16.04-64:tests/nested/manual/devmode-snaps-can-run-other-snaps +----- +. +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Error debugging google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Restoring google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64 (may181431-047051) : EOF +2022-05-18 16:45:15 Discarding google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Successful tasks: 7376 +2022-05-18 16:45:15 Aborted tasks: 3061 +2022-05-18 16:45:15 Failed tasks: 2 + - google:ubuntu-20.04-64:tests/main/degraded + - google:ubuntu-core-22-64:tests/main/dbus-activation-session +2022-05-18 16:45:15 Failed task prepare: 3 + - google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:refresh + - google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot + - google-nested:ubuntu-16.04-64:tests/nested/manual/devmode-snaps-can-run-other-snaps +2022-05-18 16:45:15 Failed task restore: 2 + - google:ubuntu-core-22-64:tests/main/dbus-activation-session + - google:ubuntu-core-22-64:tests/main/parallel-install-desktop +2022-05-18 16:45:15 Failed suite prepare: 1 + - google:opensuse-15.3-64:tests/completion/ +2022-05-18 16:45:15 Failed suite restore: 2 + - google:ubuntu-core-22-64:tests/main/ + - google:ubuntu-core-22-64:tests/main/ +2022-05-18 16:45:15 Failed project prepare: 1 + - google:ubuntu-core-20-64:project +2022-05-18 16:45:15 Failed project restore: 2 + - google:ubuntu-core-22-64:project + - google:ubuntu-core-22-64:project +error: unsuccessful run \ No newline at end of file diff --git a/tests/log-parser/with-failed-and-aborted.log.spread b/tests/log-parser/with-failed-and-aborted.log.spread new file mode 100644 index 00000000..a5e0aeb8 --- /dev/null +++ b/tests/log-parser/with-failed-and-aborted.log.spread @@ -0,0 +1,265 @@ +2020-11-27 19:30:40 Project content is packed for delivery (169.92KB). +2020-11-27 19:30:40 Sequence of jobs produced with -seed=1606505440 +2020-11-27 19:30:40 If killed, discard servers with: spread -reuse-pid=313960 -discard +2020-11-27 19:30:40 Allocating google:opensuse-tumbleweed-64... +2020-11-27 19:30:40 Allocating google:opensuse-tumbleweed-64... +2020-11-27 19:30:40 Allocating google:opensuse-tumbleweed-64... +2020-11-27 19:30:40 Allocating google:opensuse-tumbleweed-64... +2020-11-27 19:30:40 Allocating google:opensuse-tumbleweed-64... +2020-11-27 19:30:40 Allocating google:opensuse-tumbleweed-64... +2020-11-27 19:30:49 Waiting for google:opensuse-tumbleweed-64 (nov271930-268545) to boot at 35.229.111.181... +2020-11-27 19:30:52 Waiting for google:opensuse-tumbleweed-64 (nov271930-268322) to boot at 35.243.146.54... +2020-11-27 19:30:53 Waiting for google:opensuse-tumbleweed-64 (nov271930-268530) to boot at 35.243.170.137... +2020-11-27 19:30:54 Waiting for google:opensuse-tumbleweed-64 (nov271930-268552) to boot at 34.73.120.227... +2020-11-27 19:30:54 Waiting for google:opensuse-tumbleweed-64 (nov271930-268558) to boot at 35.237.32.105... +2020-11-27 19:30:54 Waiting for google:opensuse-tumbleweed-64 (nov271930-268563) to boot at 34.74.49.214... +2020-11-27 19:31:29 Allocated google:opensuse-tumbleweed-64 (nov271930-268530). +2020-11-27 19:31:29 Connecting to google:opensuse-tumbleweed-64 (nov271930-268530)... +2020-11-27 19:31:29 Connected to google:opensuse-tumbleweed-64 (nov271930-268530) at 35.243.170.137. +2020-11-27 19:31:29 Sending project content to google:opensuse-tumbleweed-64 (nov271930-268530)... +2020-11-27 19:31:30 Allocated google:opensuse-tumbleweed-64 (nov271930-268552). +2020-11-27 19:31:30 Connecting to google:opensuse-tumbleweed-64 (nov271930-268552)... +2020-11-27 19:31:30 Connected to google:opensuse-tumbleweed-64 (nov271930-268552) at 34.73.120.227. +2020-11-27 19:31:30 Sending project content to google:opensuse-tumbleweed-64 (nov271930-268552)... +2020-11-27 19:31:30 Allocated google:opensuse-tumbleweed-64 (nov271930-268558). +2020-11-27 19:31:30 Connecting to google:opensuse-tumbleweed-64 (nov271930-268558)... +2020-11-27 19:31:30 Preparing google:opensuse-tumbleweed-64 (nov271930-268530)... +2020-11-27 20:01:27 Preparing google:opensuse-tumbleweed-64:tests/main/user-data-handling (nov271930-268530)... +2020-11-27 20:01:30 Error preparing google:opensuse-tumbleweed-64 (nov271930-268552) : +----- ++ cat ++ mv gai.conf /etc/gai.conf ++ command -v restorecon ++ [[ opensuse-tumbleweed-64 == fedora-* ]] ++ [[ opensuse-tumbleweed-64 == opensuse-* ]] ++ zypper ref +Retrieving repository 'Cloud:Tools (openSUSE_Tumbleweed)' metadata [.done] +Building repository 'Cloud:Tools (openSUSE_Tumbleweed)' cache [....done] +Retrieving repository 'kernel-repo' metadata [..done] +Building repository 'kernel-repo' cache [....done] +Retrieving repository 'repo-debug' metadata [............done] +Building repository 'repo-debug' cache [....done] +Retrieving repository 'repo-non-oss' metadata [..done] +Building repository 'repo-non-oss' cache [....done] +Retrieving repository 'repo-oss' metadata [......done] +Building repository 'repo-oss' cache [....done] +Repository 'repo-update' is up to date. +All repositories have been refreshed. ++ cat ++ [[ opensuse-tumbleweed-64 == arch-* ]] ++ [[ opensuse-tumbleweed-64 == debian-* ]] ++ [[ opensuse-tumbleweed-64 == centos-* ]] ++ [[ opensuse-tumbleweed-64 == ubuntu-* ]] ++ '[' -f current.delta ']' +++ mktemp ++ tf=/tmp/tmp.xq251br0RX ++ case "$SPREAD_SYSTEM" in ++ zypper -q --gpg-auto-import-keys refresh ++ zypper -q install -y xdelta3 curl ++ quiet govendor sync + + +----- +. +2020-11-27 20:01:30 Discarding google:opensuse-tumbleweed-64 (nov271930-268552)... +2020-11-27 20:01:30 Error preparing google:opensuse-tumbleweed-64 (nov271930-268558) : +----- ++ cat ++ mv gai.conf /etc/gai.conf ++ command -v restorecon ++ [[ opensuse-tumbleweed-64 == fedora-* ]] ++ [[ opensuse-tumbleweed-64 == opensuse-* ]] ++ zypper ref ++ go get -u github.com/kardianos/govendor +++ seq 10 ++ for _ in $(seq 10) ++ quiet govendor sync + + +----- +. +2020-11-27 20:01:30 Discarding google:opensuse-tumbleweed-64 (nov271930-268558)... +2020-11-27 20:01:30 Error preparing google:opensuse-tumbleweed-64 (nov271930-268563) : +----- ++ cat ++ mv gai.conf /etc/gai.conf ++ command -v restorecon ++ [[ opensuse-tumbleweed-64 == fedora-* ]] ++ [[ opensuse-tumbleweed-64 == opensuse-* ]] ++ zypper ref +Retrieving repository 'Cloud:Tools (openSUSE_Tumbleweed)' metadata [...done] +Building repository 'Cloud:Tools (openSUSE_Tumbleweed)' cache [....done] +Retrieving repository 'kernel-repo' metadata [..done] +Building repository 'kernel-repo' cache [....done] ++ loginctl enable-linger test ++ loginctl disable-linger test ++ '[' '' = yes ']' ++ case "$SPREAD_SYSTEM" in +++ command -v govendor ++ '[' -z '' ']' ++ rm -rf /home/gopath/src/github.com/kardianos/govendor ++ go get -u github.com/kardianos/govendor +++ seq 10 ++ for _ in $(seq 10) ++ quiet govendor sync + + +----- +. +2020-11-27 20:01:30 Discarding google:opensuse-tumbleweed-64 (nov271930-268563)... +2020-11-27 20:01:30 Error preparing google:opensuse-tumbleweed-64 (nov271930-268545) : +----- ++ cat ++ mv gai.conf /etc/gai.conf ++ command -v restorecon ++ [[ opensuse-tumbleweed-64 == fedora-* ]] +++ command -v govendor ++ '[' -z '' ']' ++ rm -rf /home/gopath/src/github.com/kardianos/govendor ++ go get -u github.com/kardianos/govendor +++ seq 10 ++ for _ in $(seq 10) ++ quiet govendor sync + + +----- +. +2020-11-27 20:01:30 Discarding google:opensuse-tumbleweed-64 (nov271930-268545)... +2020-11-27 20:51:19 Preparing google:opensuse-tumbleweed-64:tests/main/interfaces-kvm (nov271930-268530)... +2020-11-27 20:51:30 Executing google:opensuse-tumbleweed-64:tests/main/interfaces-kvm (nov271930-268530) (338/425)... +2020-11-27 20:51:30 Restoring google:opensuse-tumbleweed-64:tests/main/interfaces-kvm (nov271930-268530)... +2020-11-27 20:51:31 Preparing google:opensuse-tumbleweed-64:tests/main/snap-disconnect (nov271930-268530)... +2020-11-27 20:51:45 Executing google:opensuse-tumbleweed-64:tests/main/snap-disconnect (nov271930-268530) (339/425)... +2020-11-27 20:51:59 Restoring google:opensuse-tumbleweed-64:tests/main/snap-disconnect (nov271930-268530)... +2020-11-27 20:52:00 Preparing google:opensuse-tumbleweed-64:tests/main/services-disable-install-hook (nov271930-268530)... +2020-11-27 20:52:02 Error executing google:opensuse-tumbleweed-64:tests/main/interfaces-x11-unix-socket (nov271930-268322) : +----- ++ echo 'Install test snaps' +Install test snaps ++ /home/gopath/src/github.com/snapcore/snapd/tests/lib/tools/snaps-state install-local x11-client +x11-client 1.0 installed ++ /home/gopath/src/github.com/snapcore/snapd/tests/lib/tools/snaps-state install-local x11-server +x11-server 1.0 installed ++ echo 'Ensure x11 plug is not connected to implicit slot' +Ensure x11 plug is not connected to implicit slot ++ snap disconnect x11-client:x11 ++ echo 'Connect x11-client to x11-server' +Connect x11-client to x11-server ++ snap connect x11-client:x11 x11-server:x11 ++ echo 'The snaps can communicate via the unix domain socket in /tmp' +The snaps can communicate via the unix domain socket in /tmp ++ retry -n 4 --wait 0.5 test -e /tmp/snap.x11-server/tmp/.X11-unix/X0 ++ x11-server +retry: command test -e /tmp/snap.x11-server/tmp/.X11-unix/X0 failed with code 1 +retry: next attempt in 0.5 second(s) (attempt 1 of 4) ++ MATCH 'Hello from xserver' ++ x11-client +nc: create unix socket failed +grep error: pattern not found, got: + + + +----- +. +2020-11-27 20:52:02 Debug output for google:opensuse-tumbleweed-64:tests/main/interfaces-x11-unix-socket (nov271930-268322) : +----- ++ '[' 1 = 1 ']' ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/state.sh +++ SNAPD_STATE_PATH=/home/gopath/src/github.com/snapcore/snapd/tests/snapd-state +++ SNAPD_STATE_FILE=/home/gopath/src/github.com/snapcore/snapd/tests/snapd-state/snapd-state.tar +++ RUNTIME_STATE_PATH=/home/gopath/src/github.com/snapcore/snapd/tests/runtime-state +++ SNAPD_ACTIVE_UNITS=/home/gopath/src/github.com/snapcore/snapd/tests/runtime-state/snapd-active-units +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/dirs.sh ++++ export SNAP_MOUNT_DIR=/snap ++++ SNAP_MOUNT_DIR=/snap ++++ export LIBEXECDIR=/usr/lib ++++ LIBEXECDIR=/usr/lib ++++ export MEDIA_DIR=/media +----- +. +2020-11-27 20:52:03 Discarding google:opensuse-tumbleweed-64 (nov271930-268322)... +2020-11-27 20:52:06 Executing google:opensuse-tumbleweed-64:tests/main/services-disable-install-hook (nov271930-268530) (340/425)... +2020-11-27 20:52:12 Restoring google:opensuse-tumbleweed-64:tests/main/services-disable-install-hook (nov271930-268530)... +2020-11-27 20:52:13 Preparing google:opensuse-tumbleweed-64:tests/main/snap-debug-state (nov271930-268530)... +2020-11-27 20:52:24 Executing google:opensuse-tumbleweed-64:tests/main/snap-debug-state (nov271930-268530) (341/425)... +2020-11-27 20:52:24 Restoring google:opensuse-tumbleweed-64:tests/main/snap-debug-state (nov271930-268530)... +2020-11-27 20:52:26 Preparing google:opensuse-tumbleweed-64:tests/main/refresh-all (nov271930-268530)... +2020-11-27 20:52:45 Executing google:opensuse-tumbleweed-64:tests/main/refresh-all (nov271930-268530) (342/425)... +2020-11-27 20:53:06 Restoring google:opensuse-tumbleweed-64:tests/main/refresh-all (nov271930-268530)... +2020-11-27 20:53:08 Preparing google:opensuse-tumbleweed-64:tests/main/snap-service (nov271930-268530)... +2020-11-27 20:53:15 Executing google:opensuse-tumbleweed-64:tests/main/snap-service (nov271930-268530) (343/425)... +2020-11-27 20:53:47 Restoring google:opensuse-tumbleweed-64:tests/main/snap-service (nov271930-268530)... +2020-11-27 20:53:48 Preparing google:opensuse-tumbleweed-64:tests/main/snapctl-is-connected (nov271930-268530)... +2020-11-27 20:54:03 Executing google:opensuse-tumbleweed-64:tests/main/snapctl-is-connected (nov271930-268530) (344/425)... +2020-11-27 21:15:00 Preparing google:opensuse-tumbleweed-64:tests/main/install-sideload:reexec0 (nov271930-268530)... +2020-11-27 21:15:04 Error preparing google:opensuse-tumbleweed-64:tests/main/install-sideload:reexec0 (nov271930-268530) : +----- ++ /home/gopath/src/github.com/snapcore/snapd/tests/lib/prepare-restore.sh --prepare-project-each ++ set -e ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/dirs.sh +++ export SNAP_MOUNT_DIR=/snap +++ SNAP_MOUNT_DIR=/snap +++ export LIBEXECDIR=/usr/lib +++ LIBEXECDIR=/usr/lib +++ export MEDIA_DIR=/media +++ MEDIA_DIR=/media +++ case "$SPREAD_SYSTEM" in +++ export SNAP_MOUNT_DIR=/snap +++ SNAP_MOUNT_DIR=/snap +++ export MEDIA_DIR=/run/media +++ MEDIA_DIR=/run/media ++++ . /etc/os-release +++++ NAME='openSUSE Tumbleweed' +++++ ID=opensuse-tumbleweed +++++ ID_LIKE='opensuse suse' +++++ VERSION_ID=20201107 +++++ PRETTY_NAME='openSUSE Tumbleweed' +++++ ANSI_COLOR='0;32' +++++ CPE_NAME=cpe:/o:opensuse:tumbleweed:20201107 +++++ BUG_REPORT_URL=https://bugs.opensuse.org +++++ HOME_URL=https://www.opensuse.org/ +++++ DOCUMENTATION_URL=https://en.opensuse.org/Portal:Tumbleweed +++++ LOGO=distributor-logo ++++ echo opensuse-tumbleweed +++ '[' opensuse-tumbleweed = opensuse-tumbleweed ']' +++ export LIBEXECDIR=/usr/libexec +++ LIBEXECDIR=/usr/libexec ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/pkgdb.sh +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh +Stopping snap-core-10475.mount +Stopping snap-core-10475.mount +Removing snap core +Removing snap-core-10475.mount +Stopping snap-core16-46.mount +Stopping snap-core16-46.mount +Removing snap core16 +Removing snap-core16-46.mount +Stopping snap-test\x2dsnapd\x2dsh\x2dcore16-x1.mount +Stopping snap-test\x2dsnapd\x2dsh\x2dcore16-x1.mount +Removing snap test-snapd-sh-core16 +Removing snap-test\x2dsnapd\x2dsh\x2dcore16-x1.mount +Discarding preserved snap namespaces +Removing downloaded snaps +Removing features exported from snapd to helper tools +Final directory cleanup +Removing leftover snap shared state data +Removing snapd catalog cache +Removing extra snap-confine apparmor rules +active +----- +. +2020-11-27 21:15:04 Error debugging google:opensuse-tumbleweed-64:tests/main/install-sideload:reexec0 (nov271930-268530) : EOF +2020-11-27 21:15:04 Discarding google:opensuse-tumbleweed-64 (nov271930-268530)... +error: unsuccessful run +2020-11-27 21:15:04 Successful tasks: 400 +2020-11-27 21:15:04 Aborted tasks: 24 +2020-11-27 21:15:04 Failed tasks: 1 + - google:opensuse-tumbleweed-64:tests/main/interfaces-x11-unix-socket +2020-11-27 21:15:04 Failed task prepare: 1 + - google:opensuse-tumbleweed-64:tests/main/install-sideload:reexec0 +2020-11-27 21:15:04 Failed project prepare: 4 + - google:opensuse-tumbleweed-64:project + - google:opensuse-tumbleweed-64:project + - google:opensuse-tumbleweed-64:project + - google:opensuse-tumbleweed-64:project \ No newline at end of file diff --git a/tests/log-parser/with-failed-project-restore.log.spread b/tests/log-parser/with-failed-project-restore.log.spread new file mode 100644 index 00000000..5253c5a6 --- /dev/null +++ b/tests/log-parser/with-failed-project-restore.log.spread @@ -0,0 +1,146 @@ +2022-05-18 17:49:24 Project content is packed for delivery (8.86MB). +2022-05-18 17:49:24 Sequence of jobs produced with -seed=1652896164 +2022-05-18 17:49:24 If killed, discard servers with: spread -reuse-pid=9308 -discard +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-432987) to boot at 104.196.14.127... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-433163) to boot at 35.237.37.145... +2022-05-18 17:49:47 Waiting for google-nested:ubuntu-16.04-64 (may181749-433044) to boot at 34.148.64.110... +2022-05-18 17:50:03 Allocated google-nested:ubuntu-16.04-64 (may181749-432987). +2022-05-18 17:50:03 Connecting to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:04 Connected to google-nested:ubuntu-16.04-64 (may181749-432987) at 104.196.14.127. +2022-05-18 17:50:04 Sending project content to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:06 Preparing google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:08 Allocated google-nested:ubuntu-16.04-64 (may181749-433163). +2022-05-18 17:50:08 Connecting to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:09 Connected to google-nested:ubuntu-16.04-64 (may181749-433163) at 35.237.37.145. +2022-05-18 17:50:09 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:11 Preparing google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:13 Allocated google-nested:ubuntu-16.04-64 (may181749-433044). +2022-05-18 17:50:13 Connecting to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:13 Connected to google-nested:ubuntu-16.04-64 (may181749-433044) at 34.148.64.110. +2022-05-18 17:50:13 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:15 Preparing google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:55:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 365 lines above ...) ++ restart_logind= ++ loginctl enable-linger test ++ loginctl disable-linger test +Unpacking systemd (229-4ubuntu21.31) over (229-4ubuntu21.28) ... +Processing triggers for dbus (1.10.6-1ubuntu3.6) ... +Processing triggers for ureadahead (0.100.0-19.1) ... +Processing triggers for man-db (2.7.5-1) ... +Setting up systemd (229-4ubuntu21.31) ... +addgroup: The group `systemd-journal' already exists as a system group. Exiting. +[/usr/lib/tmpfiles.d/var.conf:14] Duplicate line for path "/var/log", ignoring. +Setting up libpam-systemd:amd64 (229-4ubuntu21.31) ... +----- +. +2022-05-18 18:00:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:11 WARNING: may181749-433163 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:01:03 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/ (may181749-432987)... +2022-05-18 18:01:17 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/ (may181749-433163)... +2022-05-18 18:03:19 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:05:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:06:03 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64:tests/nested/core/) running late. Current output: +----- +(... 97 lines above ...) +Parallel unsquashfs: Using 2 processors +11398 inodes (13347 blocks) to write + +[===========================================================\] 13347/13347 100% + +created 8997 files +created 1461 directories +created 2312 symlinks +created 79 devices +created 0 fifos +----- +. +2022-05-18 18:06:52 Executing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163) (1/13)... +2022-05-18 18:06:58 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987)... +2022-05-18 18:07:57 Restoring google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:00 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:40 Executing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987) (2/13)... +Error: 2022-05-18 18:09:34 Error preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163) : +----- ++ /home/gopath/src/github.com/snapcore/snapd/tests/lib/prepare-restore.sh --prepare-project-each ++ set -e ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/pkgdb.sh +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/random.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/state.sh +++ SNAPD_STATE_PATH=/var/tmp/snapd-tools/snapd-state +++ SNAPD_STATE_FILE=/var/tmp/snapd-tools/snapd-state/snapd-state.tar +++ RUNTIME_STATE_PATH=/var/tmp/snapd-tools/runtime-state +++ SNAPD_ACTIVE_UNITS=/var/tmp/snapd-tools/runtime-state/snapd-active-units +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/systemd.sh ++ case "$1" in ++ prepare_project_each ++ dmesg -c ++ fixup_dev_random ++ mv /dev/random /dev/random.orig ++ mknod /dev/random c 1 9 ++ kill_gpg_agent ++ pkill -9 -e gpg-agent + +May 18 18:50:05 may181749-433044 kernel: veth33879c75: renamed from physLGGOmx +May 18 18:50:05 may181749-433044 libvirtd[21899]: Failed to open file '/sys/class/net/eth0/operstate': No such file or directory +May 18 18:50:05 may181749-433044 libvirtd[21899]: unable to read: /sys/class/net/eth0/operstate: No such file or directory +May 18 18:50:05 may181749-433044 kernel: device veth690dd0d2 left promiscuous mode +May 18 18:50:05 may181749-433044 kernel: lxdbr0: port 1(veth690dd0d2) entered disabled state +May 18 18:50:05 may181749-433044 audit[20780]: AVC apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:05 may181749-433044 kernel: audit: type=1400 audit(1652899805.951:102): apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #8 lxdbr0, 10.253.239.1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #9 lxdbr0, fd42:9473:7f21:63ab::1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #10 lxdbr0, fe80::216:3eff:feec:f39f%5#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs ++ echo '# tasks executed on system' +# tasks executed on system ++ echo '' ++ cat /var/tmp/snapd-tools/runtime-state/runs - +google-nested:ubuntu-16.04-64:tests/nested/classic/hotplug google-nested:ubuntu-16.04-64:tests/nested/classic/snapshots-with-core-refresh-revert google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_disabled google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_enabled google-nested:ubuntu-16.04-64:tests/nested/manual/devmode-snaps-can-run-other-snaps +----- +. +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Error debugging google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Restoring google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64 (may181431-047051) : EOF +2022-05-18 16:45:15 Discarding google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Successful tasks: 7376 +2022-05-18 16:45:15 Aborted tasks: 0 +2022-05-18 16:45:15 Failed project restore: 2 + - google:ubuntu-core-22-64:project + - google:ubuntu-core-22-64:project +error: unsuccessful run \ No newline at end of file diff --git a/tests/log-parser/with-failed-repeated-and-aborted.log.spread b/tests/log-parser/with-failed-repeated-and-aborted.log.spread new file mode 100644 index 00000000..6e198f0e --- /dev/null +++ b/tests/log-parser/with-failed-repeated-and-aborted.log.spread @@ -0,0 +1,154 @@ +2022-05-18 17:49:24 Project content is packed for delivery (8.86MB). +2022-05-18 17:49:24 Sequence of jobs produced with -seed=1652896164 +2022-05-18 17:49:24 If killed, discard servers with: spread -reuse-pid=9308 -discard +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-432987) to boot at 104.196.14.127... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-433163) to boot at 35.237.37.145... +2022-05-18 17:49:47 Waiting for google-nested:ubuntu-16.04-64 (may181749-433044) to boot at 34.148.64.110... +2022-05-18 17:50:03 Allocated google-nested:ubuntu-16.04-64 (may181749-432987). +2022-05-18 17:50:03 Connecting to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:04 Connected to google-nested:ubuntu-16.04-64 (may181749-432987) at 104.196.14.127. +2022-05-18 17:50:04 Sending project content to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:06 Preparing google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:08 Allocated google-nested:ubuntu-16.04-64 (may181749-433163). +2022-05-18 17:50:08 Connecting to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:09 Connected to google-nested:ubuntu-16.04-64 (may181749-433163) at 35.237.37.145. +2022-05-18 17:50:09 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:11 Preparing google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:13 Allocated google-nested:ubuntu-16.04-64 (may181749-433044). +2022-05-18 17:50:13 Connecting to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:13 Connected to google-nested:ubuntu-16.04-64 (may181749-433044) at 34.148.64.110. +2022-05-18 17:50:13 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:15 Preparing google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:55:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 365 lines above ...) ++ restart_logind= ++ loginctl enable-linger test ++ loginctl disable-linger test +Unpacking systemd (229-4ubuntu21.31) over (229-4ubuntu21.28) ... +Processing triggers for dbus (1.10.6-1ubuntu3.6) ... +Processing triggers for ureadahead (0.100.0-19.1) ... +Processing triggers for man-db (2.7.5-1) ... +Setting up systemd (229-4ubuntu21.31) ... +addgroup: The group `systemd-journal' already exists as a system group. Exiting. +[/usr/lib/tmpfiles.d/var.conf:14] Duplicate line for path "/var/log", ignoring. +Setting up libpam-systemd:amd64 (229-4ubuntu21.31) ... +----- +. +2022-05-18 18:00:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:11 WARNING: may181749-433163 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:01:03 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/ (may181749-432987)... +2022-05-18 18:01:17 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/ (may181749-433163)... +2022-05-18 18:03:19 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:05:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:06:03 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64:tests/nested/core/) running late. Current output: +----- +(... 97 lines above ...) +Parallel unsquashfs: Using 2 processors +11398 inodes (13347 blocks) to write + +[===========================================================\] 13347/13347 100% + +created 8997 files +created 1461 directories +created 2312 symlinks +created 79 devices +created 0 fifos +----- +. +2022-05-18 18:06:52 Executing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163) (1/13)... +2022-05-18 18:06:58 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987)... +2022-05-18 18:07:57 Restoring google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:00 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:40 Executing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987) (2/13)... +Error: 2022-05-18 18:09:34 Error preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163) : +----- ++ /home/gopath/src/github.com/snapcore/snapd/tests/lib/prepare-restore.sh --prepare-project-each ++ set -e ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/pkgdb.sh +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/random.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/state.sh +++ SNAPD_STATE_PATH=/var/tmp/snapd-tools/snapd-state +++ SNAPD_STATE_FILE=/var/tmp/snapd-tools/snapd-state/snapd-state.tar +++ RUNTIME_STATE_PATH=/var/tmp/snapd-tools/runtime-state +++ SNAPD_ACTIVE_UNITS=/var/tmp/snapd-tools/runtime-state/snapd-active-units +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/systemd.sh ++ case "$1" in ++ prepare_project_each ++ dmesg -c ++ fixup_dev_random ++ mv /dev/random /dev/random.orig ++ mknod /dev/random c 1 9 ++ kill_gpg_agent ++ pkill -9 -e gpg-agent + +May 18 18:50:05 may181749-433044 kernel: veth33879c75: renamed from physLGGOmx +May 18 18:50:05 may181749-433044 libvirtd[21899]: Failed to open file '/sys/class/net/eth0/operstate': No such file or directory +May 18 18:50:05 may181749-433044 libvirtd[21899]: unable to read: /sys/class/net/eth0/operstate: No such file or directory +May 18 18:50:05 may181749-433044 kernel: device veth690dd0d2 left promiscuous mode +May 18 18:50:05 may181749-433044 kernel: lxdbr0: port 1(veth690dd0d2) entered disabled state +May 18 18:50:05 may181749-433044 audit[20780]: AVC apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:05 may181749-433044 kernel: audit: type=1400 audit(1652899805.951:102): apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #8 lxdbr0, 10.253.239.1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #9 lxdbr0, fd42:9473:7f21:63ab::1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #10 lxdbr0, fe80::216:3eff:feec:f39f%5#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs ++ echo '# tasks executed on system' +# tasks executed on system ++ echo '' ++ cat /var/tmp/snapd-tools/runtime-state/runs - +google-nested:ubuntu-16.04-64:tests/nested/classic/hotplug google-nested:ubuntu-16.04-64:tests/nested/classic/snapshots-with-core-refresh-revert google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_disabled google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_enabled google-nested:ubuntu-16.04-64:tests/nested/manual/devmode-snaps-can-run-other-snaps +----- +. +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Error debugging google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Restoring google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64 (may181431-047051) : EOF +2022-05-18 16:45:15 Discarding google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Successful tasks: 7376 +2022-05-18 16:45:15 Aborted tasks: 4 +2022-05-18 16:45:15 Failed tasks: 2 + - google:ubuntu-20.04-64:tests/main/degraded + - google:ubuntu-core-22-64:tests/main/dbus-activation-session +2022-05-18 16:45:15 Failed task prepare: 3 + - google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:refresh + - google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot + - google:ubuntu-core-22-64:tests/main/parallel-install-desktop +2022-05-18 16:45:15 Failed task restore: 3 + - google:ubuntu-20.04-64:tests/main/degraded + - google:ubuntu-core-22-64:tests/main/parallel-install-desktop + - google-nested:ubuntu-16.04-64:tests/nested/manual/devmode-snaps-can-run-other-snaps +error: unsuccessful run \ No newline at end of file diff --git a/tests/log-parser/with-failed-repeated.log.spread b/tests/log-parser/with-failed-repeated.log.spread new file mode 100644 index 00000000..76cc171d --- /dev/null +++ b/tests/log-parser/with-failed-repeated.log.spread @@ -0,0 +1,154 @@ +2022-05-18 17:49:24 Project content is packed for delivery (8.86MB). +2022-05-18 17:49:24 Sequence of jobs produced with -seed=1652896164 +2022-05-18 17:49:24 If killed, discard servers with: spread -reuse-pid=9308 -discard +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-432987) to boot at 104.196.14.127... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-433163) to boot at 35.237.37.145... +2022-05-18 17:49:47 Waiting for google-nested:ubuntu-16.04-64 (may181749-433044) to boot at 34.148.64.110... +2022-05-18 17:50:03 Allocated google-nested:ubuntu-16.04-64 (may181749-432987). +2022-05-18 17:50:03 Connecting to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:04 Connected to google-nested:ubuntu-16.04-64 (may181749-432987) at 104.196.14.127. +2022-05-18 17:50:04 Sending project content to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:06 Preparing google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:08 Allocated google-nested:ubuntu-16.04-64 (may181749-433163). +2022-05-18 17:50:08 Connecting to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:09 Connected to google-nested:ubuntu-16.04-64 (may181749-433163) at 35.237.37.145. +2022-05-18 17:50:09 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:11 Preparing google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:13 Allocated google-nested:ubuntu-16.04-64 (may181749-433044). +2022-05-18 17:50:13 Connecting to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:13 Connected to google-nested:ubuntu-16.04-64 (may181749-433044) at 34.148.64.110. +2022-05-18 17:50:13 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:15 Preparing google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:55:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 365 lines above ...) ++ restart_logind= ++ loginctl enable-linger test ++ loginctl disable-linger test +Unpacking systemd (229-4ubuntu21.31) over (229-4ubuntu21.28) ... +Processing triggers for dbus (1.10.6-1ubuntu3.6) ... +Processing triggers for ureadahead (0.100.0-19.1) ... +Processing triggers for man-db (2.7.5-1) ... +Setting up systemd (229-4ubuntu21.31) ... +addgroup: The group `systemd-journal' already exists as a system group. Exiting. +[/usr/lib/tmpfiles.d/var.conf:14] Duplicate line for path "/var/log", ignoring. +Setting up libpam-systemd:amd64 (229-4ubuntu21.31) ... +----- +. +2022-05-18 18:00:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:11 WARNING: may181749-433163 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:01:03 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/ (may181749-432987)... +2022-05-18 18:01:17 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/ (may181749-433163)... +2022-05-18 18:03:19 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:05:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:06:03 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64:tests/nested/core/) running late. Current output: +----- +(... 97 lines above ...) +Parallel unsquashfs: Using 2 processors +11398 inodes (13347 blocks) to write + +[===========================================================\] 13347/13347 100% + +created 8997 files +created 1461 directories +created 2312 symlinks +created 79 devices +created 0 fifos +----- +. +2022-05-18 18:06:52 Executing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163) (1/13)... +2022-05-18 18:06:58 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987)... +2022-05-18 18:07:57 Restoring google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:00 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:40 Executing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987) (2/13)... +Error: 2022-05-18 18:09:34 Error preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163) : +----- ++ /home/gopath/src/github.com/snapcore/snapd/tests/lib/prepare-restore.sh --prepare-project-each ++ set -e ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/pkgdb.sh +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/random.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/state.sh +++ SNAPD_STATE_PATH=/var/tmp/snapd-tools/snapd-state +++ SNAPD_STATE_FILE=/var/tmp/snapd-tools/snapd-state/snapd-state.tar +++ RUNTIME_STATE_PATH=/var/tmp/snapd-tools/runtime-state +++ SNAPD_ACTIVE_UNITS=/var/tmp/snapd-tools/runtime-state/snapd-active-units +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/systemd.sh ++ case "$1" in ++ prepare_project_each ++ dmesg -c ++ fixup_dev_random ++ mv /dev/random /dev/random.orig ++ mknod /dev/random c 1 9 ++ kill_gpg_agent ++ pkill -9 -e gpg-agent + +May 18 18:50:05 may181749-433044 kernel: veth33879c75: renamed from physLGGOmx +May 18 18:50:05 may181749-433044 libvirtd[21899]: Failed to open file '/sys/class/net/eth0/operstate': No such file or directory +May 18 18:50:05 may181749-433044 libvirtd[21899]: unable to read: /sys/class/net/eth0/operstate: No such file or directory +May 18 18:50:05 may181749-433044 kernel: device veth690dd0d2 left promiscuous mode +May 18 18:50:05 may181749-433044 kernel: lxdbr0: port 1(veth690dd0d2) entered disabled state +May 18 18:50:05 may181749-433044 audit[20780]: AVC apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:05 may181749-433044 kernel: audit: type=1400 audit(1652899805.951:102): apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #8 lxdbr0, 10.253.239.1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #9 lxdbr0, fd42:9473:7f21:63ab::1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #10 lxdbr0, fe80::216:3eff:feec:f39f%5#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs ++ echo '# tasks executed on system' +# tasks executed on system ++ echo '' ++ cat /var/tmp/snapd-tools/runtime-state/runs - +google-nested:ubuntu-16.04-64:tests/nested/classic/hotplug google-nested:ubuntu-16.04-64:tests/nested/classic/snapshots-with-core-refresh-revert google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_disabled google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_enabled google-nested:ubuntu-16.04-64:tests/nested/manual/devmode-snaps-can-run-other-snaps +----- +. +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Error debugging google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Restoring google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64 (may181431-047051) : EOF +2022-05-18 16:45:15 Discarding google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Successful tasks: 7376 +2022-05-18 16:45:15 Aborted tasks: 3 +2022-05-18 16:45:15 Failed tasks: 2 + - google:ubuntu-20.04-64:tests/main/degraded + - google:ubuntu-core-22-64:tests/main/dbus-activation-session +2022-05-18 16:45:15 Failed task prepare: 3 + - google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:refresh + - google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot + - google:ubuntu-core-22-64:tests/main/parallel-install-desktop +2022-05-18 16:45:15 Failed task restore: 3 + - google:ubuntu-20.04-64:tests/main/degraded + - google:ubuntu-core-22-64:tests/main/parallel-install-desktop + - google-nested:ubuntu-16.04-64:tests/nested/manual/devmode-snaps-can-run-other-snaps +error: unsuccessful run \ No newline at end of file diff --git a/tests/log-parser/with-failed-suite-restore.log.spread b/tests/log-parser/with-failed-suite-restore.log.spread new file mode 100644 index 00000000..21f7c197 --- /dev/null +++ b/tests/log-parser/with-failed-suite-restore.log.spread @@ -0,0 +1,146 @@ +2022-05-18 17:49:24 Project content is packed for delivery (8.86MB). +2022-05-18 17:49:24 Sequence of jobs produced with -seed=1652896164 +2022-05-18 17:49:24 If killed, discard servers with: spread -reuse-pid=9308 -discard +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-432987) to boot at 104.196.14.127... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-433163) to boot at 35.237.37.145... +2022-05-18 17:49:47 Waiting for google-nested:ubuntu-16.04-64 (may181749-433044) to boot at 34.148.64.110... +2022-05-18 17:50:03 Allocated google-nested:ubuntu-16.04-64 (may181749-432987). +2022-05-18 17:50:03 Connecting to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:04 Connected to google-nested:ubuntu-16.04-64 (may181749-432987) at 104.196.14.127. +2022-05-18 17:50:04 Sending project content to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:06 Preparing google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:08 Allocated google-nested:ubuntu-16.04-64 (may181749-433163). +2022-05-18 17:50:08 Connecting to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:09 Connected to google-nested:ubuntu-16.04-64 (may181749-433163) at 35.237.37.145. +2022-05-18 17:50:09 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:11 Preparing google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:13 Allocated google-nested:ubuntu-16.04-64 (may181749-433044). +2022-05-18 17:50:13 Connecting to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:13 Connected to google-nested:ubuntu-16.04-64 (may181749-433044) at 34.148.64.110. +2022-05-18 17:50:13 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:15 Preparing google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:55:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 365 lines above ...) ++ restart_logind= ++ loginctl enable-linger test ++ loginctl disable-linger test +Unpacking systemd (229-4ubuntu21.31) over (229-4ubuntu21.28) ... +Processing triggers for dbus (1.10.6-1ubuntu3.6) ... +Processing triggers for ureadahead (0.100.0-19.1) ... +Processing triggers for man-db (2.7.5-1) ... +Setting up systemd (229-4ubuntu21.31) ... +addgroup: The group `systemd-journal' already exists as a system group. Exiting. +[/usr/lib/tmpfiles.d/var.conf:14] Duplicate line for path "/var/log", ignoring. +Setting up libpam-systemd:amd64 (229-4ubuntu21.31) ... +----- +. +2022-05-18 18:00:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:11 WARNING: may181749-433163 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:01:03 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/ (may181749-432987)... +2022-05-18 18:01:17 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/ (may181749-433163)... +2022-05-18 18:03:19 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:05:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:06:03 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64:tests/nested/core/) running late. Current output: +----- +(... 97 lines above ...) +Parallel unsquashfs: Using 2 processors +11398 inodes (13347 blocks) to write + +[===========================================================\] 13347/13347 100% + +created 8997 files +created 1461 directories +created 2312 symlinks +created 79 devices +created 0 fifos +----- +. +2022-05-18 18:06:52 Executing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163) (1/13)... +2022-05-18 18:06:58 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987)... +2022-05-18 18:07:57 Restoring google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:00 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:40 Executing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987) (2/13)... +Error: 2022-05-18 18:09:34 Error preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163) : +----- ++ /home/gopath/src/github.com/snapcore/snapd/tests/lib/prepare-restore.sh --prepare-project-each ++ set -e ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/pkgdb.sh +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/random.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/state.sh +++ SNAPD_STATE_PATH=/var/tmp/snapd-tools/snapd-state +++ SNAPD_STATE_FILE=/var/tmp/snapd-tools/snapd-state/snapd-state.tar +++ RUNTIME_STATE_PATH=/var/tmp/snapd-tools/runtime-state +++ SNAPD_ACTIVE_UNITS=/var/tmp/snapd-tools/runtime-state/snapd-active-units +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/systemd.sh ++ case "$1" in ++ prepare_project_each ++ dmesg -c ++ fixup_dev_random ++ mv /dev/random /dev/random.orig ++ mknod /dev/random c 1 9 ++ kill_gpg_agent ++ pkill -9 -e gpg-agent + +May 18 18:50:05 may181749-433044 kernel: veth33879c75: renamed from physLGGOmx +May 18 18:50:05 may181749-433044 libvirtd[21899]: Failed to open file '/sys/class/net/eth0/operstate': No such file or directory +May 18 18:50:05 may181749-433044 libvirtd[21899]: unable to read: /sys/class/net/eth0/operstate: No such file or directory +May 18 18:50:05 may181749-433044 kernel: device veth690dd0d2 left promiscuous mode +May 18 18:50:05 may181749-433044 kernel: lxdbr0: port 1(veth690dd0d2) entered disabled state +May 18 18:50:05 may181749-433044 audit[20780]: AVC apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:05 may181749-433044 kernel: audit: type=1400 audit(1652899805.951:102): apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #8 lxdbr0, 10.253.239.1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #9 lxdbr0, fd42:9473:7f21:63ab::1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #10 lxdbr0, fe80::216:3eff:feec:f39f%5#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs ++ echo '# tasks executed on system' +# tasks executed on system ++ echo '' ++ cat /var/tmp/snapd-tools/runtime-state/runs - +google-nested:ubuntu-16.04-64:tests/nested/classic/hotplug google-nested:ubuntu-16.04-64:tests/nested/classic/snapshots-with-core-refresh-revert google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_disabled google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_enabled google-nested:ubuntu-16.04-64:tests/nested/manual/devmode-snaps-can-run-other-snaps +----- +. +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Error debugging google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Restoring google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64 (may181431-047051) : EOF +2022-05-18 16:45:15 Discarding google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Successful tasks: 7376 +2022-05-18 16:45:15 Aborted tasks: 0 +2022-05-18 16:45:15 Failed suite restore: 2 + - google:ubuntu-core-22-64:tests/main/ + - google:ubuntu-core-22-64:tests/main/ +error: unsuccessful run \ No newline at end of file diff --git a/tests/log-parser/with-failed.log.spread b/tests/log-parser/with-failed.log.spread new file mode 100644 index 00000000..a98e1f58 --- /dev/null +++ b/tests/log-parser/with-failed.log.spread @@ -0,0 +1,216 @@ +2021-01-20 12:28:57 Project content is packed for delivery (266.41KB). +2021-01-20 12:28:57 Sequence of jobs produced with -seed=1611145737 +2021-01-20 12:28:57 If killed, discard servers with: spread -reuse-pid=24265 -discard +2021-01-20 12:28:57 Allocating google:centos-8-64... +2021-01-20 12:29:10 Waiting for google:centos-8-64 (jan201228-089626) to boot at 35.229.96.196... +2021-01-20 12:29:33 Sending project content to google:centos-8-64 (jan201228-089626)... +2021-01-20 12:29:33 Connected to google:centos-8-64 (jan201228-089359) at 34.73.106.247. +2021-01-20 12:29:33 Sending project content to google:centos-8-64 (jan201228-089359)... +2021-01-20 12:29:33 Connected to google:centos-8-64 (jan201228-089636) at 35.227.44.209. +2021-01-20 12:29:33 Sending project content to google:centos-8-64 (jan201228-089636)... +2021-01-20 12:29:35 Preparing google:centos-8-64 (jan201228-089626)... +2021-01-20 12:29:35 Preparing google:centos-8-64 (jan201228-089596)... +2021-01-20 12:29:35 Preparing google:centos-8-64 (jan201228-089359)... +2021-01-20 12:29:35 Preparing google:centos-8-64 (jan201228-089636)... +2021-01-20 12:34:36 WARNING: jan201228-089636 (google:centos-8-64) running late. Current output: +----- +(... 376 lines above ...) +pkgconfig(libseccomp) +pkgconfig(libselinux) +pkgconfig(libudev) +pkgconfig(systemd) +pkgconfig(udev) +selinux-policy +selinux-policy-devel +systemd +valgrind +xfsprogs-devel +----- +. +2021-01-20 12:42:47 Restoring google:centos-8-64:tests/completion/snippets:hosts (jan201228-089636)... +2021-01-20 12:42:48 Preparing google:centos-8-64:tests/completion/indirect:func (jan201228-089636)... +2021-01-20 12:42:50 Preparing google:centos-8-64:tests/regression/lp-1844496 (jan201228-089359)... +2021-01-20 12:42:54 Executing google:centos-8-64:tests/completion/indirect:func (jan201228-089636) (2/435)... +2021-01-20 12:42:55 Preparing google:centos-8-64:tests/main/degraded (jan201228-089626)... +2021-01-20 12:43:01 Executing google:centos-8-64:tests/main/degraded (jan201228-089626) (3/435)... +2021-01-20 12:43:01 Restoring google:centos-8-64:tests/main/degraded (jan201228-089626)... +2021-01-20 12:43:02 Preparing google:centos-8-64:tests/main/base-snaps (jan201228-089626)... +2021-01-20 12:43:03 Executing google:centos-8-64:tests/regression/lp-1844496 (jan201228-089359) (4/435)... +2021-01-20 12:43:06 Executing google:centos-8-64:tests/main/base-snaps (jan201228-089626) (5/435)... +2021-01-20 12:43:07 Restoring google:centos-8-64:tests/regression/lp-1844496 (jan201228-089359)... +2021-01-20 12:43:09 Preparing google:centos-8-64:tests/regression/lp-1812973 (jan201228-089359)... +2021-01-20 12:43:15 Executing google:centos-8-64:tests/regression/lp-1812973 (jan201228-089359) (6/435)... +2021-01-20 12:43:16 Restoring google:centos-8-64:tests/regression/lp-1812973 (jan201228-089359)... +2021-01-20 12:43:16 Restoring google:centos-8-64:tests/main/base-snaps (jan201228-089626)... +2021-01-20 12:43:17 Preparing google:centos-8-64:tests/main/snap-validate-basic (jan201228-089626)... +2021-01-20 12:43:18 Preparing google:centos-8-64:tests/regression/lp-1665004 (jan201228-089359)... +2021-01-20 12:43:22 Executing google:centos-8-64:tests/main/snap-validate-basic (jan201228-089626) (7/435)... +2021-01-20 12:43:22 Restoring google:centos-8-64:tests/main/snap-validate-basic (jan201228-089626)... +2021-01-20 12:43:23 Preparing google:centos-8-64:tests/main/interfaces-broadcom-asic-control (jan201228-089596)... +2021-01-20 12:43:23 Preparing google:centos-8-64:tests/main/media-sharing (jan201228-089626)... +2021-01-20 12:43:24 Executing google:centos-8-64:tests/regression/lp-1665004 (jan201228-089359) (8/435)... +2021-01-20 12:43:24 Restoring google:centos-8-64:tests/regression/lp-1665004 (jan201228-089359)... +2021-01-20 12:43:25 Preparing google:centos-8-64:tests/regression/lp-1797556 (jan201228-089359)... +2021-01-20 12:43:30 Executing google:centos-8-64:tests/main/interfaces-broadcom-asic-control (jan201228-089596) (9/435)... +2021-01-20 12:43:32 Executing google:centos-8-64:tests/regression/lp-1797556 (jan201228-089359) (10/435)... +2021-01-20 12:43:32 Restoring google:centos-8-64:tests/regression/lp-1797556 (jan201228-089359)... +2021-01-20 12:43:32 Restoring google:centos-8-64:tests/main/interfaces-broadcom-asic-control (jan201228-089596)... +2021-01-20 12:48:55 Restoring google:centos-8-64:tests/lib/tools/suite/mountinfo.query (jan201228-089359)... +2021-01-20 12:48:56 Preparing google:centos-8-64:tests/lib/tools/suite/tests.pkgs (jan201228-089359)... +2021-01-20 12:48:57 Executing google:centos-8-64:tests/lib/tools/suite/tests.pkgs (jan201228-089359) (90/435)... +2021-01-20 12:48:58 Executing google:centos-8-64:tests/main/security-devpts (jan201228-089596) (91/435)... +2021-01-20 12:49:00 Restoring google:centos-8-64:tests/main/security-devpts (jan201228-089596)... +2021-01-20 12:49:01 Preparing google:centos-8-64:tests/main/interfaces-content-circular (jan201228-089596)... +2021-01-20 12:49:06 Executing google:centos-8-64:tests/main/interfaces-content-circular (jan201228-089596) (92/435)... +2021-01-20 12:49:11 Restoring google:centos-8-64:tests/completion/indirect:funcarg (jan201228-089636)... +2021-01-20 12:49:13 Preparing google:centos-8-64:tests/completion/simple:hosts (jan201228-089636)... +2021-01-20 12:49:17 Restoring google:centos-8-64:tests/main/services-snapctl (jan201228-089626)... +2021-01-20 12:49:17 Executing google:centos-8-64:tests/completion/simple:hosts (jan201228-089636) (93/435)... +2021-01-20 12:49:17 Preparing google:centos-8-64:tests/main/services-refresh-mode (jan201228-089626)... +2021-01-20 12:49:21 Error executing google:centos-8-64:tests/lib/tools/suite/tests.pkgs (jan201228-089359) : +----- ++ os.query is-core ++ MATCH 'usage: tests.pkgs {install,remove} \[PACKAGE...\]' ++ tests.pkgs ++ tests.pkgs -h ++ MATCH 'usage: tests.pkgs {install,remove} \[PACKAGE...\]' ++ tests.pkgs --help ++ MATCH 'usage: tests.pkgs {install,remove} \[PACKAGE...\]' ++ not tests.pkgs is-installed test-snapd-pkg-1 ++ rpm -qi robotfindskitten ++ tests.pkgs install test-snapd-pkg-1 +++ command -v dnf ++ '[' /usr/bin/dnf '!=' '' ']' ++ dnf install -y robotfindskitten +CentOS-8 - AppStream 3.6 MB/s | 6.3 MB 00:01 +CentOS-8 - Base 5.3 MB/s | 2.3 MB 00:00 +CentOS-8 - Extras 3.5 kB/s | 8.6 kB 00:02 +CentOS-8 - PowerTools 1.3 MB/s | 2.0 MB 00:01 +Extra Packages for Enterprise Linux Modular 8 - 708 kB/s | 537 kB 00:00 +Extra Packages for Enterprise Linux 8 - x86_64 14 MB/s | 8.8 MB 00:00 +Google Compute Engine 8.9 kB/s | 7.4 kB 00:00 +Google Cloud SDK 18 MB/s | 24 MB 00:01 +No match for argument: robotfindskitten +Error: Unable to find a match: robotfindskitten +----- +. +2021-01-20 12:49:22 Debug output for google:centos-8-64:tests/lib/tools/suite/tests.pkgs (jan201228-089359) : +----- ++ '[' 1 = 1 ']' ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/state.sh +++ SNAPD_STATE_PATH=/home/gopath/src/github.com/snapcore/snapd/tests/snapd-state +++ SNAPD_STATE_FILE=/home/gopath/src/github.com/snapcore/snapd/tests/snapd-state/snapd-state.tar +++ RUNTIME_STATE_PATH=/home/gopath/src/github.com/snapcore/snapd/tests/runtime-state +++ SNAPD_ACTIVE_UNITS=/home/gopath/src/github.com/snapcore/snapd/tests/runtime-state/snapd-active-units +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/dirs.sh ++++ export SNAP_MOUNT_DIR=/snap ++++ SNAP_MOUNT_DIR=/snap ++++ export LIBEXECDIR=/usr/lib ++++ LIBEXECDIR=/usr/lib ++++ export MEDIA_DIR=/media ++++ MEDIA_DIR=/media ++++ case "$SPREAD_SYSTEM" in ++++ export SNAP_MOUNT_DIR=/var/lib/snapd/snap ++++ SNAP_MOUNT_DIR=/var/lib/snapd/snap ++++ export LIBEXECDIR=/usr/libexec ++++ LIBEXECDIR=/usr/libexec ++++ export MEDIA_DIR=/run/media ++++ MEDIA_DIR=/run/media +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/systemd.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/nested.sh +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/systemd.sh +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/store.sh ++++ STORE_CONFIG=/etc/systemd/system/snapd.service.d/store.conf ++++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/systemd.sh +++ NESTED_WORK_DIR=/tmp/work-dir +++ NESTED_IMAGES_DIR=/tmp/work-dir/images +++ NESTED_RUNTIME_DIR=/tmp/work-dir/runtime +++ NESTED_ASSETS_DIR=/tmp/work-dir/assets +++ NESTED_LOGS_DIR=/tmp/work-dir/logs +++ NESTED_VM=nested-vm +++ NESTED_SSH_PORT=8022 +++ NESTED_MON_PORT=8888 +++ NESTED_CUSTOM_MODEL= +++ NESTED_CUSTOM_AUTO_IMPORT_ASSERTION= +++ NESTED_FAKESTORE_BLOB_DIR=/tmp/work-dir/fakestore/blobs +++ NESTED_SIGN_SNAPS_FAKESTORE=false +++ NESTED_UBUNTU_IMAGE_SNAPPY_FORCE_SAS_URL= ++ echo '# System information' +# System information ++ cat /etc/os-release +NAME="CentOS Linux" +VERSION="8 (Core)" +ID="centos" +ID_LIKE="rhel fedora" +VERSION_ID="8" +PLATFORM_ID="platform:el8" +PRETTY_NAME="CentOS Linux 8 (Core)" +ANSI_COLOR="0;31" +CPE_NAME="cpe:/o:centos:centos:8" +HOME_URL="https://www.centos.org/" +BUG_REPORT_URL="https://bugs.centos.org/" + +CENTOS_MANTISBT_PROJECT="CentOS-8" +CENTOS_MANTISBT_PROJECT_VERSION="8" +REDHAT_SUPPORT_PRODUCT="centos" +REDHAT_SUPPORT_PRODUCT_VERSION="8" + +# snap connections --all ++ snap connections --all +/bin/bash: line 129: snap: command not found ++ true ++ echo '# tasks executed on system' +# tasks executed on system ++ cat /home/gopath/src/github.com/snapcore/snapd/tests/runtime-state/runs +google:centos-8-64:tests/regression/lp-1844496 google:centos-8-64:tests/regression/lp-1812973 google:centos-8-64:tests/regression/lp-1665004 google:centos-8-64:tests/regression/lp-1797556 google:centos-8-64:tests/regression/lp-1803542:private google:centos-8-64:tests/regression/lp-1848567 google:centos-8-64:tests/regression/lp-1803535 google:centos-8-64:tests/regression/lp-1630479 google:centos-8-64:tests/regression/lp-1891371 google:centos-8-64:tests/regression/lp-1898038 google:centos-8-64:tests/regression/lp-1825883 google:centos-8-64:tests/regression/lp-1615113 google:centos-8-64:tests/regression/lp-1862637 google:centos-8-64:tests/regression/lp-1852361 google:centos-8-64:tests/regression/rhbz-1708991 google:centos-8-64:tests/regression/lp-1808821 google:centos-8-64:tests/regression/lp-1801955 google:centos-8-64:tests/regression/lp-1732555 google:centos-8-64:tests/regression/lp-1803542:shared google:centos-8-64:tests/regression/lp-1831010 google:centos-8-64:tests/regression/lp-1597839 google:centos-8-64:tests/regression/lp-1606277 google:centos-8-64:tests/regression/lp-1805838 google:centos-8-64:tests/regression/lp-1800004 google:centos-8-64:tests/regression/lp-1607796 google:centos-8-64:tests/regression/lp-1597842 google:centos-8-64:tests/regression/lp-1815722 google:centos-8-64:tests/regression/lp-1886786 google:centos-8-64:tests/regression/lp-1693042 google:centos-8-64:tests/regression/lp-1764977 google:centos-8-64:tests/regression/lp-1618683 google:centos-8-64:tests/regression/lp-1803542:absent google:centos-8-64:tests/regression/lp-1803542:present google:centos-8-64:tests/regression/lp-1849845 google:centos-8-64:tests/lib/tools/suite/mountinfo.query google:centos-8-64:tests/lib/tools/suite/tests.pkgs + echo '# free space' +# /var/lib/snapd ++ find /var/lib/snapd/ -not -path '/var/lib/snapd/snap/*' -ls +find: ‘/var/lib/snapd/’: No such file or directory ++ true +----- +. +2021-01-20 12:49:22 Discarding google:centos-8-64 (jan201228-089359)... +2021-01-20 12:49:24 Restoring google:centos-8-64:tests/completion/simple:hosts (jan201228-089636)... +2021-01-20 12:49:24 Preparing google:centos-8-64:tests/completion/indirect:hosts_n_dirs (jan201228-089636)... +2021-01-20 12:49:30 Executing google:centos-8-64:tests/completion/indirect:hosts_n_dirs (jan201228-089636) (94/435)... +2021-01-20 12:49:36 Executing google:centos-8-64:tests/main/services-refresh-mode (jan201228-089626) (95/435)... +2021-01-20 12:49:42 Restoring google:centos-8-64:tests/main/interfaces-content-circular (jan201228-089596)... +2021-01-20 12:49:43 Preparing google:centos-8-64:tests/main/refresh:strict_remote (jan201228-089596)... +2021-01-20 12:53:24 Preparing google:centos-8-64:tests/main/base-snaps-refresh (jan201228-089626)... +2021-01-20 12:53:29 Executing google:centos-8-64:tests/main/base-snaps-refresh (jan201228-089626) (124/435)... +2021-01-20 12:53:38 Restoring google:centos-8-64:tests/main/base-snaps-refresh (jan201228-089626)... +2021-01-20 12:53:38 Restoring google:centos-8-64:tests/main/snapd-snap-removal (jan201228-089596)... +2021-01-20 12:53:39 Preparing google:centos-8-64:tests/main/interfaces-daemon-notify (jan201228-089626)... +2021-01-20 12:53:39 Preparing google:centos-8-64:tests/main/interfaces-content-mkdir-writable:data (jan201228-089596)... +2021-01-20 12:53:45 Executing google:centos-8-64:tests/main/interfaces-daemon-notify (jan201228-089626) (125/435)... +2021-01-20 12:53:46 Executing google:centos-8-64:tests/main/interfaces-content-mkdir-writable:data (jan201228-089596) (126/435)... +2021-01-20 12:53:48 Restoring google:centos-8-64:tests/main/interfaces-content-mkdir-writable:data (jan201228-089596)... +2021-01-20 12:53:49 Preparing google:centos-8-64:tests/main/refresh:parallel_strict_remote (jan201228-089596)... +2021-01-20 12:53:56 Restoring google:centos-8-64:tests/completion/indirect:plain_plusdirs (jan201228-089636)... +2021-01-20 12:53:57 Preparing google:centos-8-64:tests/completion/simple:hosts_n_dirs (jan201228-089636)... +2021-01-20 12:53:57 Restoring google:centos-8-64:tests/main/interfaces-daemon-notify (jan201228-089626)... +2021-01-20 12:53:58 Preparing google:centos-8-64:tests/main/core18-configure-hook (jan201228-089626)... +2021-01-20 12:54:01 Executing google:centos-8-64:tests/main/refresh:parallel_strict_remote (jan201228-089596) (127/435)... +2021-01-20 12:54:02 Executing google:centos-8-64:tests/completion/simple:hosts_n_dirs (jan201228-089636) (128/435)... +2021-01-20 12:59:22 Preparing google:centos-8-64:tests/main/interfaces-fuse-support:regular (jan201228-089596)... +2021-01-20 13:29:28 Restoring google:centos-8-64:tests/main/core18-with-hooks (jan201228-089626)... +2021-01-20 13:29:31 Preparing google:centos-8-64:tests/main/proxy (jan201228-089626)... +2021-01-20 13:29:32 Executing google:centos-8-64:tests/main/services-watchdog (jan201228-089596) (434/435)... +2021-01-20 13:29:36 Executing google:centos-8-64:tests/main/proxy (jan201228-089626) (435/435)... +2021-01-20 13:29:38 Restoring google:centos-8-64:tests/main/proxy (jan201228-089626)... +2021-01-20 13:29:39 Restoring google:centos-8-64:tests/main/services-watchdog (jan201228-089596)... +2021-01-20 13:29:39 Restoring google:centos-8-64:tests/main/ (jan201228-089626)... +2021-01-20 13:29:40 Restoring google:centos-8-64:tests/main/ (jan201228-089596)... +2021-01-20 13:29:46 Restoring google:centos-8-64 (jan201228-089626)... +2021-01-20 13:29:47 Restoring google:centos-8-64 (jan201228-089596)... +2021-01-20 13:29:48 Discarding google:centos-8-64 (jan201228-089626)... +2021-01-20 13:29:49 Discarding google:centos-8-64 (jan201228-089596)... +2021-01-20 13:30:03 Restoring google:centos-8-64:tests/main/auto-refresh-retry (jan201228-089636)... +2021-01-20 13:30:04 Restoring google:centos-8-64:tests/main/ (jan201228-089636)... +2021-01-20 13:30:11 Restoring google:centos-8-64 (jan201228-089636)... +2021-01-20 13:30:12 Discarding google:centos-8-64 (jan201228-089636)... +error: unsuccessful run +2021-01-20 13:30:13 Successful tasks: 434 +2021-01-20 13:30:13 Aborted tasks: 0 +2021-01-20 13:30:13 Failed tasks: 1 + - google:centos-8-64:tests/lib/tools/suite/tests.pkgs \ No newline at end of file diff --git a/tests/log-parser/with-results-in-detail.log.spread b/tests/log-parser/with-results-in-detail.log.spread new file mode 100644 index 00000000..bd69f049 --- /dev/null +++ b/tests/log-parser/with-results-in-detail.log.spread @@ -0,0 +1,149 @@ +2022-05-18 17:49:24 Project content is packed for delivery (8.86MB). +2022-05-18 17:49:24 Sequence of jobs produced with -seed=1652896164 +2022-05-18 17:49:24 If killed, discard servers with: spread -reuse-pid=9308 -discard +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:24 Allocating google-nested:ubuntu-16.04-64... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-432987) to boot at 104.196.14.127... +2022-05-18 17:49:37 Waiting for google-nested:ubuntu-16.04-64 (may181749-433163) to boot at 35.237.37.145... +2022-05-18 17:49:47 Waiting for google-nested:ubuntu-16.04-64 (may181749-433044) to boot at 34.148.64.110... +2022-05-18 17:50:03 Allocated google-nested:ubuntu-16.04-64 (may181749-432987). +2022-05-18 17:50:03 Connecting to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:04 Connected to google-nested:ubuntu-16.04-64 (may181749-432987) at 104.196.14.127. +2022-05-18 17:50:04 Sending project content to google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:06 Preparing google-nested:ubuntu-16.04-64 (may181749-432987)... +2022-05-18 17:50:08 Allocated google-nested:ubuntu-16.04-64 (may181749-433163). +2022-05-18 17:50:08 Connecting to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:09 Connected to google-nested:ubuntu-16.04-64 (may181749-433163) at 35.237.37.145. +2022-05-18 17:50:09 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:11 Preparing google-nested:ubuntu-16.04-64 (may181749-433163)... +2022-05-18 17:50:13 Allocated google-nested:ubuntu-16.04-64 (may181749-433044). +2022-05-18 17:50:13 Connecting to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:13 Connected to google-nested:ubuntu-16.04-64 (may181749-433044) at 34.148.64.110. +2022-05-18 17:50:13 Sending project content to google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:50:15 Preparing google-nested:ubuntu-16.04-64 (may181749-433044)... +2022-05-18 17:55:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 365 lines above ...) ++ restart_logind= ++ loginctl enable-linger test ++ loginctl disable-linger test +Unpacking systemd (229-4ubuntu21.31) over (229-4ubuntu21.28) ... +Processing triggers for dbus (1.10.6-1ubuntu3.6) ... +Processing triggers for ureadahead (0.100.0-19.1) ... +Processing triggers for man-db (2.7.5-1) ... +Setting up systemd (229-4ubuntu21.31) ... +addgroup: The group `systemd-journal' already exists as a system group. Exiting. +[/usr/lib/tmpfiles.d/var.conf:14] Duplicate line for path "/var/log", ignoring. +Setting up libpam-systemd:amd64 (229-4ubuntu21.31) ... +----- +. +2022-05-18 18:00:06 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:11 WARNING: may181749-433163 (google-nested:ubuntu-16.04-64) running late. Current output: +----- +(... 1334 lines above ...) +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +dpkg-gencontrol: warning: File::FcntlLock not available; using flock which is not NFS-safe +make[1]: Leaving directory '/home/gopath/src/github.com/snapcore/snapd' + dh_md5sums -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build + dh_builddeb -u-Zxz -O--buildsystem=golang -O--fail-missing -O--builddirectory=_build +dpkg-deb: building package 'golang-github-ubuntu-core-snappy-dev' in '../golang-github-ubuntu-core-snappy-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'golang-github-snapcore-snapd-dev' in '../golang-github-snapcore-snapd-dev_1337.2.55.5_all.deb'. +dpkg-deb: building package 'snapd' in '../snapd_1337.2.55.5_amd64.deb'. +----- +. +2022-05-18 18:00:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:01:03 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/ (may181749-432987)... +2022-05-18 18:01:17 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/ (may181749-433163)... +2022-05-18 18:03:19 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:05:16 WARNING: may181749-433044 (google-nested:ubuntu-16.04-64) running late. Output unchanged. +2022-05-18 18:06:03 WARNING: may181749-432987 (google-nested:ubuntu-16.04-64:tests/nested/core/) running late. Current output: +----- +(... 97 lines above ...) +Parallel unsquashfs: Using 2 processors +11398 inodes (13347 blocks) to write + +[===========================================================\] 13347/13347 100% + +created 8997 files +created 1461 directories +created 2312 symlinks +created 79 devices +created 0 fifos +----- +. +2022-05-18 18:06:52 Executing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163) (1/13)... +2022-05-18 18:06:58 Preparing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987)... +2022-05-18 18:07:57 Restoring google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:00 Preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163)... +2022-05-18 18:08:40 Executing google-nested:ubuntu-16.04-64:tests/nested/core/image-build (may181749-432987) (2/13)... +2022-05-18 18:09:34 Error preparing google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot (may181749-433163) : +----- ++ /home/gopath/src/github.com/snapcore/snapd/tests/lib/prepare-restore.sh --prepare-project-each ++ set -e ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/pkgdb.sh +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/quiet.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/random.sh ++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/state.sh +++ SNAPD_STATE_PATH=/var/tmp/snapd-tools/snapd-state +++ SNAPD_STATE_FILE=/var/tmp/snapd-tools/snapd-state/snapd-state.tar +++ RUNTIME_STATE_PATH=/var/tmp/snapd-tools/runtime-state +++ SNAPD_ACTIVE_UNITS=/var/tmp/snapd-tools/runtime-state/snapd-active-units +++ . /home/gopath/src/github.com/snapcore/snapd/tests/lib/systemd.sh ++ case "$1" in ++ prepare_project_each ++ dmesg -c ++ fixup_dev_random ++ mv /dev/random /dev/random.orig ++ mknod /dev/random c 1 9 ++ kill_gpg_agent ++ pkill -9 -e gpg-agent +2022-05-18 16:45:15 Failed tasks: 3 + - google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-never-used-not-vuln:refresh + - google-nested:ubuntu-16.04-64:tests/nested/manual/cloud-init-nocloud-not-vuln:firstboot + - google-nested:ubuntu-16.04-64:tests/nested/manual/devmode-snaps-can-run-other-snaps + +May 18 18:50:05 may181749-433044 kernel: veth33879c75: renamed from physLGGOmx +May 18 18:50:05 may181749-433044 libvirtd[21899]: Failed to open file '/sys/class/net/eth0/operstate': No such file or directory +May 18 18:50:05 may181749-433044 libvirtd[21899]: unable to read: /sys/class/net/eth0/operstate: No such file or directory +May 18 18:50:05 may181749-433044 kernel: device veth690dd0d2 left promiscuous mode +May 18 18:50:05 may181749-433044 kernel: lxdbr0: port 1(veth690dd0d2) entered disabled state +May 18 18:50:05 may181749-433044 audit[20780]: AVC apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:05 may181749-433044 kernel: audit: type=1400 audit(1652899805.951:102): apparmor="STATUS" operation="profile_remove" profile="unconfined" name="lxd-snapcraft-snapd_" pid=20780 comm="apparmor_parser" +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #8 lxdbr0, 10.253.239.1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #9 lxdbr0, fd42:9473:7f21:63ab::1#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs +May 18 18:50:07 may181749-433044 ntpd[1698]: Deleting interface #10 lxdbr0, fe80::216:3eff:feec:f39f%5#123, interface stats: received=0, sent=0, dropped=0, active_time=851 secs ++ echo '# tasks executed on system' +# tasks executed on system ++ echo '' ++ cat /var/tmp/snapd-tools/runtime-state/runs - +google-nested:ubuntu-16.04-64:tests/nested/classic/hotplug google-nested:ubuntu-16.04-64:tests/nested/classic/snapshots-with-core-refresh-revert google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_disabled google-nested:ubuntu-16.04-64:tests/nested/manual/minimal-smoke:secboot_enabled google-nested:ubuntu-16.04-64:tests/nested/manual/devmode-snaps-can-run-other-snaps +----- +. +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Error debugging google:ubuntu-core-22-64:tests/main/ (may181431-047051) : EOF +2022-05-18 16:45:15 Restoring google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Error restoring google:ubuntu-core-22-64 (may181431-047051) : EOF +2022-05-18 16:45:15 Discarding google:ubuntu-core-22-64 (may181431-047051)... +2022-05-18 16:45:15 Successful tasks: 7376 +2022-05-18 16:45:15 Aborted tasks: 3061 +2022-05-18 16:45:15 Failed tasks: 2 + - google:ubuntu-20.04-64:tests/main/degraded + - google:ubuntu-core-22-64:tests/main/dbus-activation-session diff --git a/tests/not/task.yaml b/tests/not/task.yaml new file mode 100644 index 00000000..64a5685c --- /dev/null +++ b/tests/not/task.yaml @@ -0,0 +1,6 @@ +summary: test for the not tool + +backends: [google] + +execute: | + not false && echo test | MATCH test diff --git a/tests/os.paths/task.yaml b/tests/os.paths/task.yaml new file mode 100644 index 00000000..7630a522 --- /dev/null +++ b/tests/os.paths/task.yaml @@ -0,0 +1,41 @@ +summary: smoke test for the os.paths tool + +backends: [google] + +execute: | + os.paths --help | MATCH 'usage: os.paths snap-mount-dir, media-dir, libexec-dir' + os.paths -h | MATCH 'usage: os.paths snap-mount-dir, media-dir, libexec-dir' + + case "$SPREAD_SYSTEM" in + ubuntu-*|debian-*) + test "$(os.paths snap-mount-dir)" = "/snap" + test "$(os.paths media-dir)" = "/media" + test "$(os.paths libexec-dir)" = "/usr/lib" + ;; + fedora-*|amazon-*|centos-*) + test "$(os.paths snap-mount-dir)" = "/var/lib/snapd/snap" + test "$(os.paths media-dir)" = "/run/media" + test "$(os.paths libexec-dir)" = "/usr/libexec" + ;; + arch-*) + test "$(os.paths snap-mount-dir)" = "/var/lib/snapd/snap" + test "$(os.paths media-dir)" = "/run/media" + test "$(os.paths libexec-dir)" = "/usr/lib" + ;; + opensuse-tumbleweed-*) + test "$(os.paths snap-mount-dir)" = "/snap" + test "$(os.paths media-dir)" = "/run/media" + test "$(os.paths libexec-dir)" = "/usr/libexec" + ;; + opensuse-*) + test "$(os.paths snap-mount-dir)" = "/snap" + test "$(os.paths media-dir)" = "/run/media" + test "$(os.paths libexec-dir)" = "/usr/lib" + ;; + *) + echo "System $SPREAD_SYSTEM not supported" + exit 1 + ;; + esac + + os.paths my-dir 2>&1 | MATCH "os.paths: unknown path my-dir" diff --git a/tests/os.query/task.yaml b/tests/os.query/task.yaml new file mode 100644 index 00000000..176d013b --- /dev/null +++ b/tests/os.query/task.yaml @@ -0,0 +1,171 @@ +summary: smoke test for the os.query tool + +backends: [google] + +execute: | + os.query --help | MATCH 'usage: os.query is-core, is-classic' + os.query -h | MATCH 'usage: os.query is-core, is-classic' + + case "$SPREAD_SYSTEM" in + ubuntu-14.04-64) + os.query is-trusty + os.query is-classic + os.query is-ubuntu 14.04 + ! os.query is-ubuntu 18.04 + ! os.query is-core + ! os.query is-s390x + ;; + ubuntu-16.04-64) + os.query is-xenial + os.query is-classic + os.query is-ubuntu 16.04 + ! os.query is-ubuntu 14.04 + ! os.query is-core + ;; + ubuntu-18.04-32) + os.query is-bionic + os.query is-classic + os.query is-ubuntu 18.04 + ! os.query is-ubuntu 14.04 + ! os.query is-core + os.query is-pc-i386 + ;; + ubuntu-18.04-64) + os.query is-bionic + os.query is-classic + os.query is-ubuntu 18.04 + ! os.query is-ubuntu 14.04 + ! os.query is-core + os.query is-pc-amd64 + + # check ubuntu comparisons + os.query is-ubuntu-ge 14.04 + os.query is-ubuntu-ge 18.04 + ! os.query is-ubuntu-ge 20.04 + os.query is-ubuntu-gt 16.04 + ! os.query is-ubuntu-gt 18.04 + os.query is-ubuntu-le 18.04 + os.query is-ubuntu-le 20.04 + ! os.query is-ubuntu-le 16.04 + os.query is-ubuntu-lt 20.04 + ! os.query is-ubuntu-lt 18.04 + os.query is-ubuntu-lt 2>&1 | MATCH "os.query: version id is expected" + os.query is-ubuntu-lt 20.04-64 2>&1 | MATCH 'os.query: invalid version format "20.04-64" provided' + ;; + ubuntu-20.04-64) + os.query is-focal + os.query is-ubuntu + os.query is-ubuntu 20.04 + ! os.query is-ubuntu 21.04 + ! os.query is-debian + os.query is-classic + ! os.query is-core + os.query is-pc-amd64 + ! os.query is-arm + ;; + ubuntu-22.04-64) + os.query is-jammy + os.query is-classic + os.query is-ubuntu 22.04 + ! os.query is-ubuntu 20.04 + ! os.query is-core + ;; + ubuntu-23.04-64) + os.query is-classic + os.query is-ubuntu 23.04 + ! os.query is-ubuntu 21.04 + ! os.query is-core + ;; + ubuntu-23.10-64) + os.query is-classic + os.query is-ubuntu 23.10 + ! os.query is-ubuntu 21.04 + ! os.query is-core + ;; + debian-11-64) + os.query is-debian + os.query is-debian 11 + os.query is-classic + ! os.query is-core + + # check ubuntu comparisons + ! os.query is-ubuntu-lt 20.04 + os.query is-ubuntu-ge 20.04 | MATCH "os.query: comparing non ubuntu system" + os.query is-ubuntu-lt 2>&1 | MATCH "os.query: version id is expected" + ;; + debian-12-64) + os.query is-debian + os.query is-debian 12 + os.query is-classic + ! os.query is-core + ;; + debian-sid-64) + os.query is-debian + os.query is-debian sid + os.query is-classic + ! os.query is-core + ;; + fedora-37-64) + os.query is-fedora + os.query is-fedora 37 + ! os.query is-fedora rawhide + os.query is-classic + ! os.query is-core + ;; + fedora-38-64) + os.query is-fedora + os.query is-fedora 38 + ! os.query is-fedora rawhide + os.query is-classic + ! os.query is-core + ;; + arch-linux-64) + os.query is-arch-linux + os.query is-classic + ! os.query is-core + ;; + amazon-linux-2-64) + os.query is-amazon-linux + os.query is-classic + ! os.query is-core + ;; + centos-7-64) + os.query is-centos + os.query is-centos 7 + os.query is-classic + ! os.query is-core + ;; + centos-8-64) + os.query is-centos + os.query is-centos 8 + ! os.query is-core + ;; + centos-9-64) + os.query is-centos 9 + os.query is-centos + ! os.query is-core + ;; + opensuse-15.4-64) + os.query is-opensuse + os.query is-opensuse 15.4 + ! os.query is-opensuse tumbleweed + os.query is-classic + ! os.query is-core + ;; + opensuse-15.5-64) + os.query is-opensuse + os.query is-opensuse 15.5 + os.query is-classic + ! os.query is-core + ;; + opensuse-tumbleweed-64) + os.query is-opensuse + os.query is-opensuse tumbleweed + os.query is-classic + ! os.query is-core + ;; + *) + echo "System $SPREAD_SYSTEM not supported" + exit 1 + ;; + esac diff --git a/tests/quiet/task.yaml b/tests/quiet/task.yaml new file mode 100644 index 00000000..a3dcbaf2 --- /dev/null +++ b/tests/quiet/task.yaml @@ -0,0 +1,9 @@ +summary: test for the quiet tool + +backends: [google] + +execute: | + quiet echo test | NOMATCH test + quiet "cat nofile" 2>&1 | MATCH nofile + quiet "cat nofile" 2>&1 | MATCH "quiet: exit status 127" + quiet "cat nofile" 2>&1 | MATCH "quiet: end of output" diff --git a/tests/remote.exec/task.yaml b/tests/remote.exec/task.yaml new file mode 100644 index 00000000..cbfecdbb --- /dev/null +++ b/tests/remote.exec/task.yaml @@ -0,0 +1,40 @@ +summary: smoke test for the remote.exec tool + +backends: [google] + +# Amazon linux is skipped because no sshpass available +systems: [-amazon-linux-*] + +prepare: | + tests.pkgs install sshpass + remote.setup config --host localhost --port 22 --user tools-user-1 --pass tools-user-1 + +restore: | + tests.pkgs remove sshpass + rm -rf remote.setup.cfg my-key my-key.pub /home/tools-user-1/* /home/tools-user-2/* + +execute: | + remote.exec --help | MATCH 'usage: remote.exec \[--user \] \[--pass \] ' + remote.exec -h | MATCH 'usage: remote.exec \[--user \] \[--pass \] ' + + remote.exec "touch testfile" + test -f /home/tools-user-1/testfile + + remote.exec --user tools-user-2 --pass tools-user-2 "touch testfile" + test -f /home/tools-user-2/testfile + + remote.exec --user tools-user-2 --password tools-user-2 "touch testfile" 2>&1 | MATCH "remote.exec: unknown option --password" + + # Check the remote execution using a certificate + ssh-keygen -t rsa -N "" -f my-key + chmod 0600 my-key my-key.pub + + mkdir -p /home/tools-user-1/.ssh + cat my-key.pub > /home/tools-user-1/.ssh/authorized_keys + + remote.setup config --host localhost --port 22 --user tools-user-1 --cert my-key + remote.exec "ls /home/tools-user-1/testfile" | MATCH testfile + + # Check error when there is no configuration + rm -f remote.setup.cfg + remote.exec --user tools-user-2 --pass tools-user-2 "touch testfile" | MATCH "remote.exec: config file \"$(pwd)/remote.setup.cfg\" not found, please run remote.setup command first" diff --git a/tests/remote.pull/task.yaml b/tests/remote.pull/task.yaml new file mode 100644 index 00000000..aef4f23b --- /dev/null +++ b/tests/remote.pull/task.yaml @@ -0,0 +1,33 @@ +summary: smoke test for the remote.pull tool + +backends: [google] + +# Amazon linux is skipped because no sshpass available +systems: [-amazon-linux-*] + +prepare: | + tests.pkgs install sshpass + remote.setup config --host localhost --port 22 --user tools-user-1 --pass tools-user-1 + +restore: | + tests.pkgs remove sshpass + rm -rf testfile testfile2 /tmp/testfile2 remote.setup.cfg /home/tools-user-1/* + +execute: | + remote.pull --help | MATCH 'usage: remote.pull \[LOCAL_PATH\]' + remote.pull -h | MATCH 'usage: remote.pull \[LOCAL_PATH\]' + + # check basic pull + touch /home/tools-user-1/testfile + remote.pull testfile . + test -f testfile + + # check pull without local dir + touch /tmp/testfile2 + remote.pull /tmp/testfile2 + test -f ./testfile2 + + # Check no parameters + remote.pull | MATCH 'usage: remote.pull \[LOCAL_PATH\]' + rm -f remote.setup.cfg + remote.pull /home/tools-user-1/testfile . 2>&1 | MATCH "remote.pull: config file \"$(pwd)/remote.setup.cfg\" not found, please run remote.setup command first" diff --git a/tests/remote.push/task.yaml b/tests/remote.push/task.yaml new file mode 100644 index 00000000..eb7a9002 --- /dev/null +++ b/tests/remote.push/task.yaml @@ -0,0 +1,33 @@ +summary: smoke test for the remote.push tool + +backends: [google] + +# Amazon linux is skipped because no sshpass available +systems: [-amazon-linux-*] + +prepare: | + tests.pkgs install sshpass + remote.setup config --host localhost --port 22 --user tools-user-1 --pass tools-user-1 + +restore: | + tests.pkgs remove sshpass + rm -rf testfile remote.setup.cfg /home/tools-user-1/* + +execute: | + remote.push --help | MATCH 'usage: remote.push \[REMOTE_PATH\]' + remote.push -h | MATCH 'usage: remote.push \[REMOTE_PATH\]' + + # check basic push + touch testfile + remote.push testfile "/home/tools-user-1" + test -f /home/tools-user-1/testfile + + # check push without target dir + touch testfile2 + remote.push testfile2 + test -f /home/tools-user-1/testfile2 + + # Check no parameters + remote.push | MATCH 'usage: remote.push \[REMOTE_PATH\]' + rm -f remote.setup.cfg + remote.push testfile "/home/tools-user-1" 2>&1 | MATCH "remote.push: config file \"$(pwd)/remote.setup.cfg\" not found, please run remote.setup command first" diff --git a/tests/remote.refresh/task.yaml b/tests/remote.refresh/task.yaml new file mode 100644 index 00000000..4e620a80 --- /dev/null +++ b/tests/remote.refresh/task.yaml @@ -0,0 +1,56 @@ +summary: smoke test for the remote.wait-for tool + +backends: [google-nested] + +systems: [ubuntu-20.04-64] + +environment: + user: test + pass: ubuntu + host: localhost + port: 8022 + unit: nested-vm + TARGET/xenial: xenial + TARGET/bionic: bionic + +prepare: | + if [ "$TARGET" = xenial ]; then + wget -O pc.img.xz https://storage.googleapis.com/snapd-spread-tests/images/booted/pc-amd64-16-stable-core_beta_2.56.2.img.xz + elif [ "$TARGET" = bionic ]; then + wget -O pc.img.xz https://storage.googleapis.com/snapd-spread-tests/images/booted/pc-amd64-18-stable-snapd_beta_2.56.2.img.xz + fi + unxz pc.img.xz + + service_line="kvm -nographic -snapshot -smp 2 -m 1500 -net nic,model=virtio -net user,hostfwd=tcp::$port-:22 -serial mon:stdio $PWD/pc.img" + tests.systemd create-and-start-unit "$unit" "$service_line" + + remote.setup config --host "$host" --port "$port" --user "$user" --pass "$pass" + +restore: | + tests.systemd stop-unit --remove "$unit" + rm -f pc.img "$(remote.setup get-config-path)" + +execute: | + remote.refresh | MATCH 'usage: remote.refresh snap' + remote.refresh -h | MATCH 'usage: remote.refresh snap' + remote.refresh --help | MATCH 'usage: remote.refresh snap' + + # check the vm already started + remote.wait-for ssh + remote.wait-for device-initialized + remote.wait-for snap-command + + # Check waiting when reboot + remote.refresh full + + if [ "$TARGET" = xenial ]; then + remote.refresh snap kernel --channel latest/beta + remote.wait-for refresh + remote.refresh snap core --channel stable + remote.wait-for refresh + elif [ "$TARGET" = bionic ]; then + remote.refresh snap kernel --channel 18/beta + remote.wait-for refresh + remote.refresh snap snapd --channel stable + remote.wait-for refresh + fi diff --git a/tests/remote.retry/task.yaml b/tests/remote.retry/task.yaml new file mode 100644 index 00000000..61ed3048 --- /dev/null +++ b/tests/remote.retry/task.yaml @@ -0,0 +1,43 @@ +summary: smoke test for the remote.retry tool + +backends: [google] + +# Amazon linux is skipped because no sshpass available +systems: [-amazon-linux-*] + +prepare: | + tests.pkgs install sshpass + remote.setup config --host localhost --port 22 --user tools-user-1 --pass tools-user-1 + +restore: | + tests.pkgs remove sshpass + rm -rf remote.setup.cfg /tmp/my-remote-retry-test + +execute: | + remote.retry --help | MATCH 'usage: remote.retry' + remote.retry -h | MATCH 'usage: remote.retry' + + # check the positive scenario without parameters + remote.retry "true" + + # check negative scenario + not remote.retry --wait 1 -attempts 2 "false" + + # check the command is executed correctly + rm -f /tmp/my-remote-retry-test + remote.retry "touch /tmp/my-remote-retry-test" + test -f /tmp/my-remote-retry-test + + # check the --attempts and --wait parameter + not remote.retry --wait 0.5 --attempts 5 "echo 1 >> /tmp/my-remote-retry-test && exit 1" + test "$(grep -c 1 /tmp/my-remote-retry-test)" = 5 + rm -f /tmp/my-remote-retry-test + + # check the -n parameter + not remote.retry --wait 0.5 -n 8 "echo 1 >> /tmp/my-remote-retry-test && exit 1" + test "$(grep -c 1 /tmp/my-remote-retry-test)" = 8 + rm -f /tmp/my-remote-retry-test + + # check errors + remote.retry --wait 0.5 -n 2 "false" 2>&1 | MATCH "remote.retry: timed out retrying command" + remote.retry 2>&1 | MATCH "remote.retry: command to retry not specified" \ No newline at end of file diff --git a/tests/remote.setup/task.yaml b/tests/remote.setup/task.yaml new file mode 100644 index 00000000..a600f8c5 --- /dev/null +++ b/tests/remote.setup/task.yaml @@ -0,0 +1,54 @@ +summary: smoke test for the remote.setup tool + +backends: [google] + +restore: | + rm -f remote.setup.cfg my-key my-key-2 + +execute: | + remote.setup --help | MATCH 'usage: remote.setup config --host --port --user \[--pass \] \[--cert \]' + remote.setup -h | MATCH 'usage: remote.setup config --host --port --user \[--pass \] \[--cert \]' + + # Check basic configuration + remote.setup config --host localhost --port 22 --user tools-user-1 --pass tools-pass-1 + # shellcheck disable=SC1091 + . remote.setup.cfg + test "$TESTS_REMOTE_HOST" = localhost + test "$TESTS_REMOTE_PORT" = 22 + test "$TESTS_REMOTE_USER" = tools-user-1 + test "$TESTS_REMOTE_PASS" = tools-pass-1 + test -z "$TESTS_REMOTE_CERT" + + # Check get-config-path subcommand + remote.setup get-config-path | MATCH "$(pwd)/remote.setup.cfg" + + # check using another config file + REMOTE_CFG_FILE="$(pwd)/remote.newsetup.cfg" + export REMOTE_CFG_FILE + remote.setup config --host localhost --port 22 --user tools-user-1 --pass tools-pass-1 + remote.setup get-config-path | MATCH "$(pwd)/remote.newsetup.cfg" + + # check using the default config file again + unset REMOTE_CFG_FILE + remote.setup config --host localhost --port 22 --user tools-user-1 --pass tools-pass-1 + remote.setup get-config-path | MATCH "$(pwd)/remote.setup.cfg" + + # Check the certificate + touch my-key + remote.setup config --host 127.0.0.1 --port 22 --user tools-user-1 --cert my-key + # shellcheck disable=SC1091 + . remote.setup.cfg + test "$TESTS_REMOTE_HOST" = 127.0.0.1 + test "$TESTS_REMOTE_CERT" = my-key + + # Check basic errors + remote.setup config --port 22 --user tools-user-1 --pass tools-pass-1 2>&1 | MATCH "remote.setup: host, port and user values are require" + remote.setup config --host 127.0.0.1 --user tools-user-1 --pass tools-pass-1 2>&1 | MATCH "remote.setup: host, port and user values are require" + remote.setup config --host 127.0.0.1 --port 22 --pass tools-pass-1 2>&1 | MATCH "remote.setup: host, port and user values are require" + + # Check other errors + remote.setup config --host 127.0.0.1 --port 22 --user tools-user-1 --cert my-key-2 2>&1 | MATCH "remote.setup: certificate is set but file does not exist" + remote.setup config --host localhost --port 22 --user tools-user-1 --password tools-user-1 2>&1 | MATCH "tests.remote: unknown option --password" + if [ -z "$(command -v sshpass)" ]; then + remote.setup config --host localhost --port 22 --user tools-user-1 --pass tools-user-1 | MATCH "remote.setup: sshpass tool is required when password is configured" + fi diff --git a/tests/remote.wait-for/task.yaml b/tests/remote.wait-for/task.yaml new file mode 100644 index 00000000..5ac95c51 --- /dev/null +++ b/tests/remote.wait-for/task.yaml @@ -0,0 +1,83 @@ +summary: smoke test for the remote.wait-for tool + +backends: [google-nested] + +systems: [ubuntu-20.04-64] + +environment: + user: test + pass: ubuntu + host: localhost + port: 8022 + unit: nested-vm + TARGET/xenial: xenial + TARGET/bionic: bionic + +prepare: | + if [ "$TARGET" = xenial ]; then + wget -O pc.img.xz https://storage.googleapis.com/snapd-spread-tests/images/booted/pc-amd64-16-stable-core_beta_2.56.2.img.xz + elif [ "$TARGET" = bionic ]; then + wget -O pc.img.xz https://storage.googleapis.com/snapd-spread-tests/images/booted/pc-amd64-18-stable-snapd_beta_2.56.2.img.xz + fi + unxz pc.img.xz + + service_line="kvm -nographic -snapshot -smp 2 -m 1500 -net nic,model=virtio -net user,hostfwd=tcp::$port-:22 -serial mon:stdio $PWD/pc.img" + tests.systemd create-and-start-unit "$unit" "$service_line" + + remote.setup config --host "$host" --port "$port" --user "$user" --pass "$pass" + +restore: | + tests.systemd stop-unit --remove "$unit" + rm -f pc.img "$(remote.setup get-config-path)" + +execute: | + remote.wait-for | MATCH 'usage: remote.wait-for ssh' + remote.wait-for -h | MATCH 'usage: remote.wait-for ssh' + remote.wait-for --help | MATCH 'usage: remote.wait-for ssh' + + # check the vm already started + remote.wait-for ssh + + # Disable the refreshes for the vm and wait-for + remote.refresh disable-refreshes + remote.wait-for refresh + + # Check if the device has been initialized + remote.wait-for device-initialized + + # Check if the device has snap command + remote.wait-for snap-command + + # Check waiting when reboot + remote.exec "sudo reboot" || true + remote.wait-for no-ssh --wait 1 -n 20 + remote.wait-for ssh --wait 1 -n 120 + + # Check waiting for reboot + initial_boot_id="$(remote.exec "cat /proc/sys/kernel/random/boot_id")" + remote.exec "sudo reboot" || true + remote.wait-for reboot --wait 5 -n 20 "$initial_boot_id" + + # Check waiting for reboot with not enough time + # shellcheck disable=SC2016 + remote.retry --wait 1 -n 10 'test -n "$(cat /proc/sys/kernel/random/boot_id)"' + second_boot_id="$(remote.exec "cat /proc/sys/kernel/random/boot_id")" + + remote.exec "sudo reboot" || true + # shellcheck disable=SC2251 + ! remote.wait-for reboot --wait 0.5 -n 5 "$second_boot_id" + + # Check again if the device has been initialized and the snap command + remote.wait-for device-initialized --wait 1 -n 60 + remote.wait-for snap-command + + # shellcheck disable=SC2016 + remote.retry --wait 1 -n 10 'test -n "$(cat /proc/sys/kernel/random/boot_id)"' + third_boot_id="$(remote.exec "cat /proc/sys/kernel/random/boot_id")" + + # Check boot ids are different + test "$initial_boot_id" != "$second_boot_id" + test "$second_boot_id" != "$third_boot_id" + + # Check waiting for refresh in case no refresh in progress + remote.wait-for refresh diff --git a/tests/repack-kernel/task.yaml b/tests/repack-kernel/task.yaml new file mode 100644 index 00000000..90a946ef --- /dev/null +++ b/tests/repack-kernel/task.yaml @@ -0,0 +1,47 @@ +summary: tests for the repack-kernel tool + +backends: [google] + +# ubuntu-core-initramfs seems to be only available on ubuntu-20.04 +systems: [ubuntu-20.04-64] + +execute: | + repack-kernel | MATCH 'usage: repack-kernel ' + repack-kernel -h | MATCH 'usage: repack-kernel ' + repack-kernel --help | MATCH 'usage: repack-kernel ' + + # verify error when calling without an invalid commnnd + test "$(repack-kernel invalid-command 2>&1 | grep -c "no such command: invalid-command")" -eq 1 + + # verify that an error is thrown when calling commands without arguments + test "$(repack-kernel extract 2>&1 | grep -c "invalid arguments for extract")" -eq 1 + test "$(repack-kernel extract "upstream-pc-kernel.snap" 2>&1 | grep -c "invalid arguments for extract")" -eq 1 + test "$(repack-kernel prepare 2>&1 | grep -c "missing target for prepare")" -eq 1 + test "$(repack-kernel cull-modules 2>&1 | grep -c "missing target for cull-modules")" -eq 1 + test "$(repack-kernel cull-firmware 2>&1 | grep -c "missing target for cull-firmware")" -eq 1 + + # download the kernel snap + snap download pc-kernel --channel=20/stable --basename=upstream-pc-kernel + + # setup dependencies + repack-kernel setup + + # extract the kernel snap, including extracting the initrd from the kernel.efi + kerneldir=/tmp/kernel-workdir + repack-kernel extract "upstream-pc-kernel.snap" "$kerneldir" + + # cull modules and firmware + repack-kernel cull-modules "$kerneldir" + repack-kernel cull-firmware "$kerneldir" + + # repack the initrd into the kernel.efi + repack-kernel prepare "$kerneldir" + + # repack the kernel snap itself + repack-kernel pack "$kerneldir" --filename=pc-kernel.snap + rm -rf "$kerneldir" + + if ! [ -f "pc-kernel.snap" ]; then + echo "Repack failed, pc-kernel.snap was not created" + exit 1 + fi diff --git a/tests/retry/task.yaml b/tests/retry/task.yaml new file mode 100644 index 00000000..d17122dd --- /dev/null +++ b/tests/retry/task.yaml @@ -0,0 +1,26 @@ +summary: smoke test for the retry tool + +backends: [google] + +execute: | + # Retry runs the command that was passed as argument and returns the exit + # code of that command. + retry true + not retry -n 1 false + + # If the command doesn't exist it is not re-tried multiple times. + ( not retry this-command-does-not-exist ) 2>&1 \ + | MATCH 'retry: cannot execute command this-command-does-not-exist: \[Errno 2\] No such file or directory' + + # On failure it tells us about it, showing progress. + retry -n 2 --wait 0.1 false 2>&1 | MATCH "retry: command false failed with code 1" + retry -n 2 --wait 0.1 false 2>&1 | MATCH "retry: next attempt in 0.1 second\(s\) \(attempt 1 of 2\)" + retry -n 2 --wait 0.1 false 2>&1 | MATCH "retry: command false keeps failing after 2 attempts" + # Though all output is removed with the --quiet switch. + test "$(retry -n 2 --wait 0.1 --quiet false 2>&1 | wc -l)" -eq 0 + + # Retry using environment variables + #shellcheck disable=SC2016 + retry --env key1=1 --env key2=2 sh -c 'echo $key1$key2' | MATCH "12" + #shellcheck disable=SC2016 + retry --env key1=1 --env key2,2 sh -c 'echo $key1$key2' 2>&1 | MATCH "retry: error: argument --env: environment variables expected format is 'KEY=VAL' got 'key2,2'" diff --git a/tests/snaps.cleanup/task.yaml b/tests/snaps.cleanup/task.yaml new file mode 100644 index 00000000..97b34fae --- /dev/null +++ b/tests/snaps.cleanup/task.yaml @@ -0,0 +1,69 @@ +summary: smoke test for the snaps.cleanup tool + +backends: [google] + +systems: [ubuntu-16.04-64, ubuntu-18.04-64, ubuntu-20.04-64, ubuntu-22.04-64] + +execute: | + snaps.cleanup --help | MATCH 'usage: snaps.cleanup [--skip ]' + snaps.cleanup -h | MATCH 'usage: snaps.cleanup [--skip ]' + + # Start with a clean list of snaps + snap wait system seed.loaded + for _ in $(seq 30); do + if snap changes | MATCH ".*Doing.*Auto-refresh.*"; then + sleep 1 + else + break + fi + done + snaps.cleanup + + # Check core is not cleaned + if ! snap list core; then + snap install core + fi + if ! snap list snapd; then + snap install snapd + fi + test "$(snap list | wc -l)" = "3" + snaps.cleanup + test "$(snap list | wc -l)" = "3" + + # Check the snaps and the new base are cleaned + snap install test-snapd-tools test-snapd-tools-core18 + test "$(snap list | wc -l)" = "6" + snaps.cleanup + test "$(snap list | wc -l)" = "3" + snap list core &>/dev/null + snap list snapd &>/dev/null + + # Check we can skip a base + snap install test-snapd-tools test-snapd-tools-core18 + snaps.cleanup --skip core18 + test "$(snap list | wc -l)" = "4" + snap list core &>/dev/null + snap list core18 &>/dev/null + snaps.cleanup + test "$(snap list | wc -l)" = "3" + + # Check we can skip a snap and its base + snap install test-snapd-tools test-snapd-tools-core18 test-snapd-tools-core20 + test "$(snap list | wc -l)" = "8" + snaps.cleanup --skip test-snapd-tools-core18 + test "$(snap list | wc -l)" = "5" + snap list core &>/dev/null + snap list core18 &>/dev/null + snap list test-snapd-tools-core18 &>/dev/null + snaps.cleanup + test "$(snap list | wc -l)" = "3" + + # Check we can skip all the snaps + snap install test-snapd-tools test-snapd-tools-core18 test-snapd-tools-core20 + test "$(snap list | wc -l)" = "8" + snaps.cleanup --skip test-snapd-tools --skip test-snapd-tools-core18 --skip test-snapd-tools-core20 + test "$(snap list | wc -l)" = "8" + snaps.cleanup + test "$(snap list | wc -l)" = "3" + + snaps.cleanup skip core 2>&1 | MATCH "snaps.cleanup: unknown subcommand skip" diff --git a/tests/snaps.name/task.yaml b/tests/snaps.name/task.yaml new file mode 100644 index 00000000..434274e8 --- /dev/null +++ b/tests/snaps.name/task.yaml @@ -0,0 +1,25 @@ +summary: smoke test for the snaps.name tool + +backends: [google] + +execute: | + snaps.name --help | MATCH 'usage: snaps.name gadget, kernel, core' + snaps.name -h | MATCH 'usage: snaps.name gadget, kernel, core' + + test -z "$(snaps.name gadget)" + test -z "$(snaps.name kernel)" + test "$(snaps.name core)" = "core" + + if os.query is-core18; then + test "$(snaps.name snap-sufix)" = "-core18" + elif os.query is-core20; then + test "$(snaps.name snap-sufix)" = "-core20" + elif os.query is-core22; then + test "$(snaps.name snap-sufix)" = "-core22" + elif os.query is-core24; then + test "$(snaps.name snap-sufix)" = "-core24" + else + test -z "$(snaps.name snap-sufix)" + fi + + snaps.name my-snap 2>&1 | MATCH "snaps.name: unknown snap my-snap" diff --git a/tests/spread-manager/checks/task1/task.yaml b/tests/spread-manager/checks/task1/task.yaml new file mode 100644 index 00000000..df2d11f3 --- /dev/null +++ b/tests/spread-manager/checks/task1/task.yaml @@ -0,0 +1,13 @@ +summary: this is the summary + +prepare: | + echo "preparing" + +restore: | + echo "restoring" + +debug: | + echo "debugging" + +execute: | + echo "executing" diff --git a/tests/spread-manager/checks/task2/task.yaml b/tests/spread-manager/checks/task2/task.yaml new file mode 100644 index 00000000..04771631 --- /dev/null +++ b/tests/spread-manager/checks/task2/task.yaml @@ -0,0 +1,15 @@ +summary: this is the summary + +manual: false + +prepare: | + echo "preparing" + +restore: | + echo "restoring" + +debug: | + echo "debugging" + +execute: | + echo "executing" diff --git a/tests/spread-manager/checks/task3/task.yaml b/tests/spread-manager/checks/task3/task.yaml new file mode 100644 index 00000000..896d23d7 --- /dev/null +++ b/tests/spread-manager/checks/task3/task.yaml @@ -0,0 +1,15 @@ +summary: this is the summary + +manual: true + +prepare: | + echo "preparing" + +restore: | + echo "restoring" + +debug: | + echo "debugging" + +execute: | + echo "executing" diff --git a/tests/spread-manager/checks/task4/task.yaml b/tests/spread-manager/checks/task4/task.yaml new file mode 100644 index 00000000..e64e4c94 --- /dev/null +++ b/tests/spread-manager/checks/task4/task.yaml @@ -0,0 +1,15 @@ +summary: this is the summary + +#manual: true + +prepare: | + echo "preparing" + +restore: | + echo "restoring" + +debug: | + echo "debugging" + +execute: | + echo "executing" diff --git a/tests/spread-manager/checks/task5/.empty b/tests/spread-manager/checks/task5/.empty new file mode 100644 index 00000000..e69de29b diff --git a/tests/spread-manager/spread.yaml b/tests/spread-manager/spread.yaml new file mode 100644 index 00000000..e9397370 --- /dev/null +++ b/tests/spread-manager/spread.yaml @@ -0,0 +1,12 @@ +project: spread-manager + +backends: + lxd: + systems: + - ubuntu-20.04: + +path: /home/test + +suites: + checks/: + summary: Verification tasks. diff --git a/tests/spread-manager/task.yaml b/tests/spread-manager/task.yaml new file mode 100644 index 00000000..b3f115ab --- /dev/null +++ b/tests/spread-manager/task.yaml @@ -0,0 +1,92 @@ +summary: smoke test for the spread-manager tool + +backends: [google] + +systems: [ ubuntu-20.04-64 ] + +prepare: | + wget -qO- wget https://storage.googleapis.com/snapd-spread-tests/spread/spread-amd64.tar.gz | tar xvz + +restore: | + rm -f spread + +execute: | + spread-manager -h | MATCH "spread-manager set-manual \[--project-path \] " + spread-manager --help | MATCH "spread-manager set-manual \[--project-path \] " + + # Check task without manual tag + TASK=task1 + test "$(./spread -list | wc -l)" == 3 + + spread-manager set-manual --project-path "$PWD" "checks/$TASK" + test -f "checks/$TASK/task.yaml.back" + MATCH "^manual: true" < "checks/$TASK/task.yaml" + + test "$(./spread -list | wc -l)" == 2 + + spread-manager reset-manual --project-path "$PWD" "checks/$TASK" + test -f "checks/$TASK/task.yaml.back" && exit 1 + NOMATCH "^manual: true" < "checks/$TASK/task.yaml" + + test "$(./spread -list | wc -l)" == 3 + + # Check task without manual: false tag + TASK=task2 + test "$(grep -c "manual:" checks/$TASK/task.yaml)" == 1 + spread-manager set-manual --project-path "$PWD" "checks/$TASK" + test "$(grep -c "manual:" checks/$TASK/task.yaml)" == 1 + + test "$(./spread -list | wc -l)" == 2 + + spread-manager reset-manual --project-path "$PWD" "checks/$TASK" + test -f "checks/$TASK/task.yaml.back" && exit 1 + MATCH "^manual: false" < "checks/$TASK/task.yaml" + + test "$(./spread -list | wc -l)" == 3 + + # Check task without manual: true tag + TASK=task3 + test "$(grep -c "manual:" checks/$TASK/task.yaml)" == 1 + spread-manager unset-manual --project-path "$PWD" "checks/$TASK" + test "$(grep -c "manual:" checks/$TASK/task.yaml)" == 1 + + test "$(./spread -list | wc -l)" == 4 + spread-manager reset-manual --project-path "$PWD" "checks/$TASK" + test "$(./spread -list | wc -l)" == 3 + + # Check task without #manual tag + TASK=task4 + spread-manager set-manual --project-path "$PWD" "checks/$TASK" + test "$(./spread -list | wc -l)" == 2 + spread-manager reset-manual --project-path "$PWD" "checks/$TASK" + test "$(./spread -list | wc -l)" == 3 + + # Check set and unset a list of tasks + spread-manager set-manual --project-path "$PWD" "checks/task1" "checks/task2" "checks/task3" + test "$(./spread -list | wc -l)" == 1 + spread-manager reset-manual --project-path "$PWD" "checks/task1" "checks/task2" "checks/task3" + test "$(./spread -list | wc -l)" == 3 + spread-manager unset-manual --project-path "$PWD" "checks/task1" "checks/task2" "checks/task3" + test "$(./spread -list | wc -l)" == 4 + spread-manager reset-manual --project-path "$PWD" "checks/task1" "checks/task2" "checks/task3" + test "$(./spread -list | wc -l)" == 3 + spread-manager set-manual --project-path "$PWD" "checks/task1,checks/task2,checks/task3" + test "$(./spread -list | wc -l)" == 1 + spread-manager reset-manual --project-path "$PWD" "checks/task1,checks/task2,checks/task3" + test "$(./spread -list | wc -l)" == 3 + spread-manager unset-manual --project-path "$PWD" "checks/task1 checks/task2 checks/task3" + test "$(./spread -list | wc -l)" == 4 + spread-manager reset-manual --project-path "$PWD" "checks/task1 checks/task2 checks/task3" + test "$(./spread -list | wc -l)" == 3 + + # Check errors + spread-manager set-manual --project-path "" 2>&1 | MATCH "spread-manager: project path cannot be empty" + spread-manager set-manual --project-path "$PWD/noproject" "checks/task1" 2>&1 | MATCH "spread-manager: project path \"$PWD/noproject\" has to be a directory" + spread-manager set-manual --project-path "checks/task1" "checks/task1" 2>&1 | MATCH "spread-manager: project spread file \"checks/task1/spread.yaml\" does not exist" + + spread-manager set-manual --project-path "$PWD" 2>&1 | MATCH "spread-manager: test path cannot be empty" + spread-manager set-manual --project-path "$PWD" "checks/task1/task.yaml" 2>&1 | MATCH "spread-manager: test path \"checks/task1/task.yaml\" has to be a directory" + spread-manager set-manual --project-path "$PWD" "checks/task5" 2>&1 | MATCH "spread-manager: test task \"checks/task5/task.yaml\" does not exist" + + spread-manager reset-manual --project-path "$PWD" "checks/task1" 2>&1 | MATCH "spread-manager: test task backup does not exist \"$PWD/checks/task1/task.yaml.back\"" + spread-manager set-manuals --project-path "$PWD" "checks/task1" 2>&1 | MATCH "spread-manager: no such command: set-manuals" \ No newline at end of file diff --git a/tests/spread-shellcheck/task.yaml b/tests/spread-shellcheck/task.yaml new file mode 100644 index 00000000..51037cac --- /dev/null +++ b/tests/spread-shellcheck/task.yaml @@ -0,0 +1,44 @@ +summary: smoke test for the spread-shellcheck tool + +backends: [google] + +systems: [ ubuntu-20.04-64 ] + +prepare: | + snap install shellcheck + +restore: | + snap remove shellcheck + +execute: | + spread-shellcheck -h | MATCH "usage: spread-shellcheck" + + # Check the format of the spread tests in this project + spread-shellcheck "$PROJECT_PATH/tests" + + # Check failing tasks + cp "$PWD/tasks/task1" "$PWD/tasks/task.yaml" + spread-shellcheck "$PWD/tasks" 2>&1 | MATCH "SC1035" + rm "$PWD/tasks/task.yaml" + + cp "$PWD/tasks/task2" "$PWD/tasks/task.yaml" + spread-shellcheck "$PWD/tasks" 2>&1 | MATCH "SC1035" + rm "$PWD/tasks/task.yaml" + + cp "$PWD/tasks/task3" "$PWD/tasks/task.yaml" + spread-shellcheck "$PWD/tasks" 2>&1 | MATCH "SC1035" + rm "$PWD/tasks/task.yaml" + + cp "$PWD/tasks/task4" "$PWD/tasks/task.yaml" + spread-shellcheck "$PWD/tasks" 2>&1 | MATCH "SC1035" + rm "$PWD/tasks/task.yaml" + + # Check that dirs can be excluded + cp "$PWD/tasks/task4" "$PWD/tasks/task.yaml" + spread-shellcheck "$PROJECT_PATH/tests" -e "$PWD/tasks" + rm "$PWD/tasks/task.yaml" + + # Check that files can be excluded + cp "$PWD/tasks/task4" "$PWD/tasks/task.yaml" + spread-shellcheck "$PROJECT_PATH/tests" "$PWD/tasks/task.yaml" -e "$PWD/tasks" + rm "$PWD/tasks/task.yaml" diff --git a/tests/spread-shellcheck/tasks/task1 b/tests/spread-shellcheck/tasks/task1 new file mode 100644 index 00000000..073ab026 --- /dev/null +++ b/tests/spread-shellcheck/tasks/task1 @@ -0,0 +1,13 @@ +summary: this is the summary + +prepare: | + echo "preparing" + +restore: | + echo "restoring" + +debug: | + echo "debugging" + +execute: | + ![ -z "something" ] diff --git a/tests/spread-shellcheck/tasks/task2 b/tests/spread-shellcheck/tasks/task2 new file mode 100644 index 00000000..d6f7b492 --- /dev/null +++ b/tests/spread-shellcheck/tasks/task2 @@ -0,0 +1,13 @@ +summary: this is the summary + +prepare: | + ![ -z "something" ] + +restore: | + echo "restoring" + +debug: | + echo "debugging" + +execute: | + echo "executing" diff --git a/tests/spread-shellcheck/tasks/task3 b/tests/spread-shellcheck/tasks/task3 new file mode 100644 index 00000000..eabb81ee --- /dev/null +++ b/tests/spread-shellcheck/tasks/task3 @@ -0,0 +1,13 @@ +summary: this is the summary + +prepare: | + echo "preparing" + +restore: | + ![ -z "something" ] + +debug: | + echo "debugging" + +execute: | + echo "executing" diff --git a/tests/spread-shellcheck/tasks/task4 b/tests/spread-shellcheck/tasks/task4 new file mode 100644 index 00000000..11f915bb --- /dev/null +++ b/tests/spread-shellcheck/tasks/task4 @@ -0,0 +1,13 @@ +summary: this is the summary + +prepare: | + echo "preparing" + +restore: | + echo "restoring" + +debug: | + ![ -z "something" ] + +execute: | + echo "executing" diff --git a/tests/tests.backup/task.yaml b/tests/tests.backup/task.yaml new file mode 100644 index 00000000..43f65d04 --- /dev/null +++ b/tests/tests.backup/task.yaml @@ -0,0 +1,59 @@ +summary: tests for the tests.backup tool + +backends: [google] + +execute: | + # Without any arguments a help message is printed. + tests.backup | MATCH "usage: tests.backup prepare" + tests.backup | MATCH " tests.backup restore" + + # Both -h and --help are recognized. + tests.backup --help | MATCH "usage: tests.backup" + tests.backup -h | MATCH "usage: tests.backup" + + # Unknown commands and options are reported + tests.backup --foo 2>&1 | MATCH "tests.backup: unknown option --foo" + tests.backup foo 2>&1 | MATCH "tests.backup: unknown command foo" + + # Create a file and a directory inside the current path + touch testfile-old + mkdir testdir-old + + # Check prepare creates a backup for the current directory + test ! -f "${PWD}.tar" + tests.backup prepare + test -f "${PWD}.tar" + + # Delete old data and create new data + rm "${PWD}/testfile-old" + rm -r testdir-old + touch testfile-new + mkdir testdir-new + + # Restore the backup + tests.backup restore + + # Check old files and directories are restored after restore + test -e testfile-old + test -e testdir-old + + # Check new files and directories are gone after restore + test ! -e testfile-new + test ! -e testdir-new + + # Check the backup file is gone + test ! -e "${PWD}.tar" + + # Validate restore cannot be called if backup file does not exist + tests.backup restore 2>&1 | MATCH "tests.backup: cannot restore ${PWD}.tar, the file does not exist" + + # Check the tool support a path to prepare and restore + TMP_DIR=$(mktemp -d) + tests.backup prepare "$TMP_DIR" + test -e "${TMP_DIR}.tar" + tests.backup restore "$TMP_DIR" + test ! -e "${TMP_DIR}.tar" + + # Validate prepare cannot be called if backup dir does not exist + rm -rf "$TMP_DIR" + tests.backup prepare "$TMP_DIR" 2>&1 | MATCH "tests.backup: cannot backup $TMP_DIR, not a directory" diff --git a/tests/tests.cleanup/task.yaml b/tests/tests.cleanup/task.yaml new file mode 100644 index 00000000..d753eb0f --- /dev/null +++ b/tests/tests.cleanup/task.yaml @@ -0,0 +1,77 @@ +summary: tests for the tests.cleanup tool + +backends: [google] + +systems: [ubuntu-18.04-64] + +execute: | + # Without any arguments a help message is printed. + tests.cleanup | MATCH "usage: tests.cleanup defer \[args\]" + tests.cleanup | MATCH " tests.cleanup pop" + tests.cleanup | MATCH " tests.cleanup restore" + + # Both -h and --help are also recognized. + tests.cleanup --help | MATCH "usage: tests.cleanup" + tests.cleanup -h | MATCH "usage: tests.cleanup" + + # Unknown commands and options are reported + tests.cleanup --foo 2>&1 | MATCH "tests.cleanup: unknown option --foo" + tests.cleanup foo 2>&1 | MATCH "tests.cleanup: unknown command foo" + + # Normal usage consists of a sequence of defer+, restore + # Note that restore runs the deferred commands in the opposite order. + tests.cleanup defer echo one + tests.cleanup defer echo two + tests.cleanup defer echo three + tests.cleanup restore > restore.log + diff -u restore.log - <&1 | MATCH 'tests.cleanup: deferred command "false" failed with exit code 1' + test -e defer.sh + + # Clean the defer.sh + rm -f defer.sh + + # Deferred commands can be popped and executed one by one. This is useful + # to ensure correctness in case of failure while still allowing precise + # resource management. + tests.cleanup defer echo popped + tests.cleanup pop | MATCH popped + + # Popping removes the last command from the stack + tests.cleanup defer echo cmd-a + tests.cleanup defer echo cmd-b + tests.cleanup defer echo cmd-c + tests.cleanup pop | MATCH cmd-c + diff -u defer.sh - <&1 | MATCH 'tests.cleanup: cannot pop, cleanup stack is empty' + not tests.cleanup pop diff --git a/tests/tests.pkgs/task.yaml b/tests/tests.pkgs/task.yaml new file mode 100644 index 00000000..ee642728 --- /dev/null +++ b/tests/tests.pkgs/task.yaml @@ -0,0 +1,48 @@ +summary: Smoke test for tests.pkgs tool + +backends: [google] + +execute: | + if os.query is-core; then + tests.pkgs -h 2>&1 | MATCH 'tests.pkgs: Ubuntu Core is not supported' + exit + fi + + # pkgs tool presents the usage screen when invoked without arguments + # or with the -h or --help options. + tests.pkgs | MATCH 'usage: tests.pkgs install \[--no-install-recommends\] \[PACKAGE...\]' + tests.pkgs -h | MATCH 'usage: tests.pkgs install \[--no-install-recommends\] \[PACKAGE...\]' + tests.pkgs --help | MATCH 'usage: tests.pkgs install \[--no-install-recommends\] \[PACKAGE...\]' + + # Check the test pkg is not installed + not tests.pkgs is-installed test-snapd-pkg-1 + + # Install the test pkg and check it is installed and query it + tests.pkgs install test-snapd-pkg-1 + tests.pkgs query test-snapd-pkg-1 + tests.pkgs is-installed test-snapd-pkg-1 + + # Remove the test pkg and check it is not installed anymore and query it + tests.pkgs remove test-snapd-pkg-1 + tests.pkgs query test-snapd-pkg-1 + not tests.pkgs is-installed test-snapd-pkg-1 + + # Install a package with --no-install-recommends option + tests.pkgs install --no-install-recommends test-snapd-pkg-1 + tests.pkgs query test-snapd-pkg-1 + tests.pkgs remove test-snapd-pkg-1 + + # Install 2 test pkgs and check they are is installed + tests.pkgs install test-snapd-pkg-1 test-snapd-pkg-2 + tests.pkgs is-installed test-snapd-pkg-1 + tests.pkgs is-installed test-snapd-pkg-2 + + # Remove 2 test pkgs and check they are is not installed anymore + tests.pkgs remove test-snapd-pkg-1 test-snapd-pkg-2 + not tests.pkgs is-installed test-snapd-pkg-1 + not tests.pkgs is-installed test-snapd-pkg-2 + + # Check the message when a command is not supported + tests.pkgs noexist test-snapd-pkg-1 2>&1 | MATCH 'tests.pkgs: unknown command noexist' + tests.pkgs -install test-snapd-pkg-1 2>&1 | MATCH 'tests.pkgs: unknown option -install' + diff --git a/tests/tests.systemd/task.yaml b/tests/tests.systemd/task.yaml new file mode 100644 index 00000000..42edf3ae --- /dev/null +++ b/tests/tests.systemd/task.yaml @@ -0,0 +1,64 @@ +summary: smoke test for the tests.systemd tool + +backends: [google] + +systems: [-ubuntu-14.04-64] + +restore: | + tests.systemd stop-unit --remove my-test + +execute: | + tests.systemd | MATCH 'usage: tests.systemd create-and-start-unit' + tests.systemd -h | MATCH 'usage: tests.systemd create-and-start-unit' + tests.systemd --help | MATCH 'usage: tests.systemd create-and-start-unit' + + # check a simple unit + tests.systemd create-and-start-unit my-test "/bin/sleep 500" + systemctl is-active my-test + tests.systemd stop-unit --remove my-test + not systemctl is-active my-test + + # check the wait-for-service works when unit is inactive + tests.systemd create-and-start-unit my-test "/bin/sleep 5" + tests.systemd wait-for-service --state active my-test + tests.systemd wait-for-service --state inactive my-test + tests.systemd stop-unit --remove my-test + systemctl list-unit-files | NOMATCH my-test + + # check the wait-for-service works when unit is inactive + tests.systemd create-and-start-unit my-test "/bin/sleep 10" + tests.systemd wait-for-service --state active my-test + not tests.systemd wait-for-service --state inactive --wait 1 -n 3 my-test + tests.systemd wait-for-service --state inactive --wait 2 --attempts 5 my-test + tests.systemd stop-unit --remove my-test + systemctl list-unit-files | NOMATCH my-test + + # Check stop-unit + tests.systemd create-and-start-unit my-test-1 "/bin/sleep 10" + tests.systemd create-and-start-unit my-test-2 "/bin/sleep 10" + tests.systemd stop-unit my-test-1 my-test-2 + not systemctl is-active my-test-1 + not systemctl is-active my-test-2 + systemctl is-enabled my-test-1 + systemctl is-enabled my-test-2 + tests.systemd stop-unit --remove my-test-1 my-test-2 + not systemctl is-enabled my-test-1 + not systemctl is-enabled my-test-2 + + # check missing parameters and start twice the same unit + tests.systemd create-and-start-unit 2>&1 | MATCH "tests.systemd: unit name cannot be empty" + tests.systemd create-and-start-unit my-test 2>&1 | MATCH "tests.systemd: unit command line cannot be empty" + tests.systemd create-and-start-unit my-test "/bin/sleep 5" + tests.systemd create-and-start-unit my-test "/bin/sleep 5" | MATCH "tests.systemd: unit service file already exist, it is going to be overwritten" + tests.systemd stop-unit 2>&1 | MATCH "tests.systemd: at least a unit name is required" + tests.systemd stop-unit --remove 2>&1 | MATCH "tests.systemd: at least a unit name is required" + tests.systemd stop-unit --remove my-test + + # check unit override + tests.systemd create-and-start-unit my-test "/bin/sleep 100" "[Unit]\nAfter=foo" + systemctl cat my-test | MATCH "^ExecStart=/bin/sleep 100$" + systemctl cat my-test | MATCH "^After=foo$" + tests.systemd stop-unit --remove my-test + + # check a unit can be removed when it already was removed + tests.systemd stop-unit --remove my-test diff --git a/tools/not b/tools/not new file mode 100755 index 00000000..ce2aade9 --- /dev/null +++ b/tools/not @@ -0,0 +1,6 @@ +#!/bin/sh +# This script executes whatever is given as argument and inverts the return +# value. It is meant as a workaround for shellcheck discovery +# https://github.com/koalaman/shellcheck/wiki/SC2251 where shell scripts using +# "set -e" are not failing with a trivial code like "! true" +! "$@" diff --git a/tools/os.paths b/tools/os.paths new file mode 100755 index 00000000..ff2425d5 --- /dev/null +++ b/tools/os.paths @@ -0,0 +1,64 @@ +#!/bin/bash + +show_help() { + echo "usage: os.paths snap-mount-dir, media-dir, libexec-dir" + echo "" + echo "get paths information for the current system" +} + +snap_mount_dir() { + if os.query is-fedora || os.query is-amazon-linux || os.query is-centos || os.query is-arch-linux; then + echo "/var/lib/snapd/snap" + else + echo "/snap" + fi +} + +media_dir() { + if os.query is-fedora || os.query is-amazon-linux || os.query is-centos || os.query is-arch-linux || os.query is-opensuse; then + echo "/run/media" + else + echo "/media" + fi +} + +libexec_dir() { + if os.query is-fedora || os.query is-amazon-linux || os.query is-centos || os.query is-opensuse tumbleweed; then + echo "/usr/libexec" + else + echo "/usr/lib" + fi +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + local subcommand="$1" + local action= + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit 0 + ;; + *) + action=$(echo "$subcommand" | tr '-' '_') + shift + break + ;; + esac + done + + if [ -z "$(declare -f "$action")" ]; then + echo "os.paths: unknown path $subcommand" >&2 + show_help + exit 1 + fi + + "$action" "$@" +} + +main "$@" diff --git a/tools/os.query b/tools/os.query new file mode 100755 index 00000000..7f1e66a0 --- /dev/null +++ b/tools/os.query @@ -0,0 +1,286 @@ +#!/bin/bash + +show_help() { + echo "usage: os.query is-core, is-classic" + echo " os.query is-core16, is-core18, is-core20, is-core22, is-core24" + echo " os.query is-core-gt, is-core-ge, is-core-lt, is-core-le" + echo " os.query is-trusty, is-xenial, is-bionic, is-focal, is-jammy" + echo " os.query is-ubuntu [ID], is-debian [ID], is-fedora [ID], is-amazon-linux, is-arch-linux, is-centos [ID], is-opensuse [ID]" + echo " os.query is-ubuntu-gt [ID], is-ubuntu-ge [ID], is-ubuntu-lt [ID], is-ubuntu-le [ID]" + echo " os.query is-pc-amd64, is-pc-i386, is-arm, is-armhf, is-arm64, is-s390x" + echo "" + echo "Get general information about the current system" +} + +is_core() { + # We need to check $SPREAD_SYSTEM var because in snapd the os-release file does + # not contain the ubuntu-core info while the system is being prepared + if [ -n "$SPREAD_SYSTEM" ]; then + [[ "$SPREAD_SYSTEM" == ubuntu-core-* ]] + else + grep -qFx 'ID=ubuntu-core' /etc/os-release + fi +} + +is_core16() { + # We need to check $SPREAD_SYSTEM var because in snapd the os-release file does + # not contain the ubuntu-core info while the system is being prepared + if [ -n "$SPREAD_SYSTEM" ]; then + [[ "$SPREAD_SYSTEM" == ubuntu-core-16-* ]] + else + grep -qFx 'ID=ubuntu-core' /etc/os-release && grep -qFx 'VERSION_ID="16"' /etc/os-release + fi +} + +is_core18() { + # We need to check $SPREAD_SYSTEM var because in snapd the os-release file does + # not contain the ubuntu-core info while the system is being prepared + if [ -n "$SPREAD_SYSTEM" ]; then + [[ "$SPREAD_SYSTEM" == ubuntu-core-18-* ]] + else + grep -qFx 'ID=ubuntu-core' /etc/os-release && grep -qFx 'VERSION_ID="18"' /etc/os-release + fi +} + +is_core20() { + # We need to check $SPREAD_SYSTEM var because in snapd the os-release file does + # not contain the ubuntu-core info while the system is being prepared + if [ -n "$SPREAD_SYSTEM" ]; then + [[ "$SPREAD_SYSTEM" == ubuntu-core-20-* ]] + else + grep -qFx 'ID=ubuntu-core' /etc/os-release && grep -qFx 'VERSION_ID="20"' /etc/os-release + fi +} + +is_core22() { + # We need to check $SPREAD_SYSTEM var because in snapd the os-release file does + # not contain the ubuntu-core info while the system is being prepared + if [ -n "$SPREAD_SYSTEM" ]; then + [[ "$SPREAD_SYSTEM" == ubuntu-core-22-* ]] + else + grep -qFx 'ID=ubuntu-core' /etc/os-release && grep -qFx 'VERSION_ID="22"' /etc/os-release + fi +} + +is_core24() { + # We need to check $SPREAD_SYSTEM var because in snapd the os-release file does + # not contain the ubuntu-core info while the system is being prepared + if [ -n "$SPREAD_SYSTEM" ]; then + [[ "$SPREAD_SYSTEM" == ubuntu-core-24-* ]] + else + grep -qFx 'ID=ubuntu-core' /etc/os-release && grep -qFx 'VERSION_ID="24"' /etc/os-release + fi +} + +is_core_gt() { + compare_ubuntu "${1:-}" "-gt" +} + +is_core_ge() { + compare_ubuntu "${1:-}" "-ge" +} + +is_core_lt() { + compare_ubuntu "${1:-}" "-lt" +} + +is_core_le() { + compare_ubuntu "${1:-}" "-le" +} + +is_classic() { + ! is_core +} + +is_trusty() { + grep -qFx 'ID=ubuntu' /etc/os-release && grep -qFx 'VERSION_ID="14.04"' /etc/os-release +} + +is_xenial() { + grep -qFx 'UBUNTU_CODENAME=xenial' /etc/os-release +} + +is_bionic() { + grep -qFx 'UBUNTU_CODENAME=bionic' /etc/os-release +} + +is_focal() { + grep -qFx 'UBUNTU_CODENAME=focal' /etc/os-release +} + +is_jammy() { + grep -qFx 'UBUNTU_CODENAME=jammy' /etc/os-release +} + +is_ubuntu() { + VERSION=$1 + if [ -z "$VERSION" ]; then + grep -qFx 'ID=ubuntu' /etc/os-release || grep -qFx 'ID=ubuntu-core' /etc/os-release + else + grep -qFx 'ID=ubuntu' /etc/os-release && grep -qFx "VERSION_ID=\"$VERSION\"" /etc/os-release + fi +} + +is_ubuntu_gt() { + compare_ubuntu "${1:-}" "-gt" +} + +is_ubuntu_ge() { + compare_ubuntu "${1:-}" "-ge" +} + +is_ubuntu_lt() { + compare_ubuntu "${1:-}" "-lt" +} + +is_ubuntu_le() { + compare_ubuntu "${1:-}" "-le" +} + +compare_ubuntu() { + VERSION=$1 + OPERAND=$2 + + if [ -z "$VERSION" ]; then + echo "os.query: version id is expected" + exit 1 + fi + + if ! grep -q 'ID=ubuntu' /etc/os-release; then + echo "os.query: comparing non ubuntu system" + return 1 + fi + + NUM_RE='^[0-9]+$' + NUM_VERSION="$(echo "$VERSION" | tr -d '".')" + if ! [[ $NUM_VERSION =~ $NUM_RE ]] ; then + echo "os.query: invalid version format \"$VERSION\" provided" + exit 1 + fi + + SYS_VERSION="$(grep 'VERSION_ID' /etc/os-release)" + SYS_VERSION="$(echo "${SYS_VERSION#*=}" | tr -d '".')" + if ! [[ $SYS_VERSION =~ $NUM_RE ]] ; then + echo "os.query: invalid version format \"$SYS_VERSION\" retrieved from system" + exit 1 + fi + + test "$SYS_VERSION" "$OPERAND" "$NUM_VERSION" +} + + +is_debian() { + VERSION=$1 + if [ -z "$VERSION" ]; then + grep -qFx 'ID=debian' /etc/os-release + elif [ "$VERSION" == "sid" ]; then + if [ -n "$SPREAD_SYSTEM" ]; then + [[ "$SPREAD_SYSTEM" == debian-sid-* ]] + else + grep -qFx 'ID=debian' /etc/os-release && grep -qE '^PRETTY_NAME=.*/sid"$' /etc/os-release + fi + else + grep -qFx 'ID=debian' /etc/os-release && grep -qFx "VERSION_ID=\"$VERSION\"" /etc/os-release + fi +} + +is_fedora() { + VERSION=$1 + if [ -z "$VERSION" ]; then + grep -qFx 'ID=fedora' /etc/os-release + elif [ "$VERSION" == "rawhide" ]; then + if [ -n "$SPREAD_SYSTEM" ]; then + [[ "$SPREAD_SYSTEM" == fedora-rawhide-* ]] + else + grep -qFx 'ID=fedora' /etc/os-release && grep -qFx "REDHAT_BUGZILLA_PRODUCT_VERSION=rawhide" /etc/os-release + fi + else + grep -qFx 'ID=fedora' /etc/os-release && grep -qFx "VERSION_ID=$VERSION" /etc/os-release + fi +} + +is_amazon_linux() { + grep -qFx 'ID="amzn"' /etc/os-release +} + +is_centos() { + VERSION=$1 + if [ -z "$VERSION" ]; then + grep -qFx 'ID="centos"' /etc/os-release + else + grep -qFx 'ID="centos"' /etc/os-release && grep -qFx "VERSION_ID=\"$VERSION\"" /etc/os-release + fi +} + +is_arch_linux() { + grep -qFx 'ID=arch' /etc/os-release +} + +is_opensuse() { + VERSION=$1 + if [ -z "$VERSION" ]; then + grep -qFx 'ID="opensuse-leap"' /etc/os-release || grep -qFx 'ID="opensuse-tumbleweed"' /etc/os-release + elif [ "$VERSION" == "tumbleweed" ]; then + grep -qFx 'ID="opensuse-tumbleweed"' /etc/os-release + else + grep -qFx 'ID="opensuse-leap"' /etc/os-release && grep -qFx "VERSION_ID=\"$VERSION\"" /etc/os-release + fi +} + +is_pc_amd64() { + uname -m | grep -qFx 'x86_64' +} + +is_pc_i386() { + uname -m | grep -Eq '(i686|i386)' +} + +is_arm() { + uname -m | grep -Eq '(^arm.*|^aarch*)' +} + +is_armhf() { + uname -m | grep -qx 'armv7.*' +} + +is_arm64() { + uname -m | grep -Eq '(aarch64.*|armv8.*)' +} + +is_s390x() { + uname -m | grep -qFx 's390x' +} + + +main() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + local subcommand="$1" + local action= + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit 0 + ;; + *) + action=$(echo "$subcommand" | tr '-' '_') + shift + break + ;; + esac + done + + if [ -z "$(declare -f "$action")" ]; then + echo "os.query: no such command: $subcommand" >&2 + show_help + exit 1 + fi + + "$action" "$@" +} + +main "$@" diff --git a/tools/quiet b/tools/quiet new file mode 100755 index 00000000..48c1f2aa --- /dev/null +++ b/tools/quiet @@ -0,0 +1,32 @@ +#!/bin/bash + +# use "quiet foo" when you expect "foo" to produce a lot of output +# that isn't useful unless foo itself fails. +quiet() ( + # note this is a subshell (parens instead of braces around the function) + # so this set only affects this function and not the caller + { set +x; } >&/dev/null + + # not strictly needed because it's a subshell, but good practice + local tf retval + + tf="$(mktemp)" + + set +e + "$@" >& "$tf" + retval=$? + set -e + + if [ "$retval" != "0" ]; then + echo "quiet: $*" >&2 + echo "quiet: exit status $retval. Output follows:" >&2 + cat "$tf" >&2 + echo "quiet: end of output." >&2 + fi + + rm -f -- "$tf" + + return $retval +) + +quiet "$@" diff --git a/tools/repack-kernel b/tools/repack-kernel new file mode 100755 index 00000000..92b064db --- /dev/null +++ b/tools/repack-kernel @@ -0,0 +1,230 @@ +#!/bin/bash +set -e + +if [ -n "$D" ]; then + set -x +fi + +show_help() { + echo "usage: repack-kernel " + echo "" + echo "handle extraction of the kernel snap to a workspace directory, and later" + echo "repacking it back to a snap." + echo "" + echo " repack-kernel setup - setup system dependencies" + echo " repack-kernel extract - extract under workspace tree" + echo " repack-kernel prepare - prepare initramfs & kernel for repacking" + echo " repack-kernel pack - pack the kernel" + echo " repack-kernel cull-firmware - remove unnecessary firmware" + echo " repack-kernel cull-modules - remove unnecessary modules" + echo "" +} + +setup() { + if [ "$UID" != "0" ]; then + echo "run as root (only this command)" + exit 1 + fi + + # carries ubuntu-core-initframfs + add-apt-repository ppa:snappy-dev/image -y + apt update + + if ! dpkg -s ubuntu-core-initramfs >/dev/null 2>&1; then + if ! apt install -y ubuntu-core-initramfs; then + echo "ubuntu-core-initramfs was not available in deb repository!" + exit 1 + fi + fi +} + +get_kver() { + local kerneldir="$1" + find "$kerneldir" -maxdepth 1 -name "config-*" | grep -Po 'config-\K.*' +} + +extract() { + local snap_file="$1" + local target="$2" + + if [ -z "$target" ] || [ -z "$snap_file" ]; then + echo "repack-kernel: invalid arguments for extract" + exit 1 + fi + + target=$(realpath "$target") + + mkdir -p "$target" "$target/work" "$target/backup" + + # kernel snap is huge, unpacking to current dir + unsquashfs -d "$target/kernel" "$snap_file" + + kver="$(get_kver "$target/kernel")" + + # repack initrd magic, beware + # assumptions: initrd is compressed with LZ4, cpio block size 512, microcode + # at the beginning of initrd image + + # XXX: ideally we should unpack the initrd, replace snap-boostrap and + # repack it using ubuntu-core-initramfs --skeleton= this does not + # work and the rebuilt kernel.efi panics unable to start init, but we + # still need the unpacked initrd to get the right kernel modules + objcopy -j .initrd -O binary "$target"/kernel/kernel.efi "$target/work/initrd" + + # copy out the kernel image for create-efi command + objcopy -j .linux -O binary "$target"/kernel/kernel.efi "$target/work/vmlinuz-$kver" + + cp -a "$target"/kernel/kernel.efi "$target/backup/" + + # this works on 20.04 but not on 18.04 + unmkinitramfs "$target"/work/initrd "$target"/work/unpacked-initrd + + # copy the unpacked initrd to use as the target skeleton + cp -ar "$target/work/unpacked-initrd" "$target/skeleton" + + echo "prepared workspace at $target" + echo " kernel: $target/kernel ($kver)" + echo " kernel.efi backup: $target/backup/kernel.efi" + echo " temporary artifacts: $target/work" + echo " initramfs skeleton: $target/skeleton" + +} + +prepare() { + local target="$1" + + if [ -z "$target" ]; then + echo "repack-kernel: missing target for prepare" + exit 1 + fi + + target=$(realpath "$target") + + local kver + kver="$(get_kver "$target/kernel")" + + ( + # all the skeleton edits go to a local copy of distro directory + local skeletondir="$target/skeleton" + + cd "$target/work" + # XXX: need to be careful to build an initrd using the right kernel + # modules from the unpacked initrd, rather than the host which may be + # running a different kernel + ( + # accommodate assumptions about tree layout, use the unpacked initrd + # to pick up the right modules + cd unpacked-initrd/main + ubuntu-core-initramfs create-initrd \ + --kernelver "$kver" \ + --skeleton "$skeletondir" \ + --feature main \ + --kerneldir "lib/modules/$kver" \ + --output "$target/work/repacked-initrd" + ) + + # assumes all files are named -$kver + ubuntu-core-initramfs create-efi \ + --kernelver "$kver" \ + --initrd repacked-initrd \ + --kernel vmlinuz \ + --output repacked-kernel.efi + + cp "repacked-kernel.efi-$kver" "$target/kernel/kernel.efi" + + # XXX: needed? + chmod +x "$target/kernel/kernel.efi" + ) +} + +cull_firmware() { + local target="$1" + + if [ -z "$target" ]; then + echo "repack-kernel: missing target for cull-firmware" + exit 1 + fi + + # XXX: drop ~450MB+ of firmware which should not be needed in under qemu + # or the cloud system + rm -rf "$target"/kernel/firmware/* +} + +cull_modules() { + local target="$1" + + if [ -z "$target" ]; then + echo "repack-kernel: missing target for cull-modules" + exit 1 + fi + + target=$(realpath "$target") + + local kver + kver="$(get_kver "$target/kernel")" + + ( + cd "$target/kernel" + # drop unnecessary modules + awk '{print $1}' < /proc/modules | sort > "$target/work/current-modules" + #shellcheck disable=SC2044 + for m in $(find modules/ -name '*.ko'); do + noko=$(basename "$m"); noko="${noko%.ko}" + if echo "$noko" | grep -f "$target/work/current-modules" -q ; then + echo "keeping $m - $noko" + else + rm -f "$m" + fi + done + + # depmod assumes that /lib/modules/$kver is under basepath + mkdir -p fake/lib + ln -s "$PWD/modules" fake/lib/modules + depmod -b "$PWD/fake" -A -v "$kver" + rm -rf fake + ) +} + +pack() { + local target="$1" + + if [ -z "$target" ]; then + echo "repack-kernel: missing target for pack" + exit 1 + fi + snap pack "${@:2}" "$target/kernel" +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + local subcommand="$1" + local action= + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit 0 + ;; + *) + action=$(echo "$subcommand" | tr '-' '_') + shift + break + ;; + esac + done + + if [ -z "$(declare -f "$action")" ]; then + echo "repack-kernel: no such command: $subcommand" >&2 + show_help + exit 1 + fi + + "$action" "$@" +} + +main "$@" + diff --git a/tools/retry b/tools/retry new file mode 100755 index 00000000..89ed2226 --- /dev/null +++ b/tools/retry @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +from __future__ import print_function, absolute_import, unicode_literals + +import argparse +import itertools +import os +import subprocess +import sys +import time + + +# Define MYPY as False and use it as a conditional for typing import. Despite +# this declaration mypy will really treat MYPY as True when type-checking. +# This is required so that we can import typing on Python 2.x without the +# typing module installed. For more details see: +# https://mypy.readthedocs.io/en/latest/common_issues.html#import-cycles +MYPY = False +if MYPY: + from typing import List, Text + +def envpair(s): + # type: (str) -> str + if not "=" in s: + raise argparse.ArgumentTypeError("environment variables expected format is 'KEY=VAL' got '{}'".format(s)) + return s + +def _make_parser(): + # type: () -> argparse.ArgumentParser + parser = argparse.ArgumentParser( + description=""" +Retry executes COMMAND at most N times, waiting for SECONDS between each +attempt. On failure the exit code from the final attempt is returned. +""" + ) + parser.add_argument( + "-n", + "--attempts", + metavar="N", + type=int, + default=3, + help="number of attempts (default %(default)s)", + ) + parser.add_argument( + "--wait", + metavar="SECONDS", + type=float, + default=1, + help="grace period between attempts (default %(default)ss)", + ) + parser.add_argument( + "--env", + type=envpair, + metavar='KEY=VAL', + action='append', + default=[], + help="environment variable to use with format KEY=VALUE (no default)", + ) + parser.add_argument( + "--maxmins", + metavar="MINUTES", + type=float, + default=0, + help="number of minutes after which to give up (no default, if set attempts is ignored)", + ) + parser.add_argument( + "--quiet", + dest="verbose", + action="store_false", + default=True, + help="refrain from printing any output", + ) + parser.add_argument( + "cmd", metavar="COMMAND", nargs="...", help="command to execute" + ) + return parser + + +def get_env(env): + # type: (List[str]) -> dict[str,str] + new_env = os.environ.copy() + maxsplit=1 # no keyword support for str.split() in py2 + for key, val in [s.split("=", maxsplit) for s in env]: + new_env[key] = val + return new_env + + +def run_cmd(cmd, n, wait, maxmins, verbose, env): + # type: (List[Text], int, float, float, bool, List[str]) -> int + if maxmins != 0: + attempts = itertools.count(1) + t0 = time.time() + after = "{} minutes".format(maxmins) + of_attempts_suffix = "" + else: + attempts = range(1, n + 1) + after = "{} attempts".format(n) + of_attempts_suffix = " of {}".format(n) + retcode = 0 + i = 0 + new_env = get_env(env) + for i in attempts: + retcode = subprocess.call(cmd, env=new_env) + if retcode == 0: + return 0 + if verbose: + print( + "retry: command {} failed with code {}".format(" ".join(cmd), retcode), + file=sys.stderr, + ) + if maxmins != 0: + elapsed = (time.time()-t0)/60 + if elapsed > maxmins: + break + if i < n or maxmins != 0: + if verbose: + print( + "retry: next attempt in {} second(s) (attempt {}{})".format( + wait, i, of_attempts_suffix + ), + file=sys.stderr, + ) + time.sleep(wait) + + if verbose and i > 1: + print( + "retry: command {} keeps failing after {}".format( + " ".join(cmd), after + ), + file=sys.stderr, + ) + return retcode + + +def main(): + # type: () -> None + parser = _make_parser() + ns = parser.parse_args() + # The command cannot be empty but it is difficult to express in argparse itself. + if len(ns.cmd) == 0: + parser.print_usage() + parser.exit(0) + # Return the last exit code as the exit code of this process. + try: + retcode = run_cmd(ns.cmd, ns.attempts, ns.wait, ns.maxmins, ns.verbose, ns.env) + except OSError as exc: + if ns.verbose: + print( + "retry: cannot execute command {}: {}".format(" ".join(ns.cmd), exc), + file=sys.stderr, + ) + raise SystemExit(1) + else: + raise SystemExit(retcode) + + +if __name__ == "__main__": + main() diff --git a/tools/snaps.cleanup b/tools/snaps.cleanup new file mode 100755 index 00000000..5cdbb30f --- /dev/null +++ b/tools/snaps.cleanup @@ -0,0 +1,94 @@ +#!/bin/bash -e + +show_help() { + echo "usage: snaps.cleanup [--skip ]" + echo + echo "cleanup the snaps installed in the current system" +} + +cleanup() { + snap_mount_dir="$(os.paths snap-mount-dir)" + remove_bases="" + skip_bases="" + + gadget_name="$(snaps.name gadget)" + kernel_name="$(snaps.name kernel)" + core_name="$(snaps.name core)" + + # remove all app snaps first + for snap in "$snap_mount_dir"/*; do + snap="${snap:6}" + case "$snap" in + "bin" | "$gadget_name" | "$kernel_name" | "$core_name" | "snapd" |README) + ;; + *) + # Check if a snap should be kept, there's a list of those in spread.yaml. + local keep=0 + # shellcheck disable=SC2068 + for skip_snap in $@; do + if [ "$snap" = "$skip_snap" ]; then + # Skip the snap base removal as well + snap_base=$(grep "base:" "$snap_mount_dir/$snap/current/meta/snap.yaml" | awk '{ print $2 }') + if [ -n "$snap_base" ]; then + skip_bases="$skip_bases $snap_base" + fi + keep=1 + break + fi + done + if [ "$keep" -eq 0 ]; then + # remove regular snaps right away; collect base snaps for removal in the second step below? + if snap info --verbose "$snap" | grep -E '^type: +(base|core)'; then + if [ -z "$remove_bases" ]; then + remove_bases="$snap" + else + remove_bases="$remove_bases $snap" + fi + else + snap remove --purge "$snap" + fi + fi + ;; + esac + done + # remove all base/os snaps at the end + # skip the base snaps for the + if [ -n "$remove_bases" ]; then + for base in $remove_bases; do + if ! [[ $skip_bases =~ (^|[[:space:]])$base($|[[:space:]]) ]]; then + snap remove --purge "$base" + if [ -d "$snap_mount_dir/$base" ]; then + echo "Error: removing base $base has unexpected leftover dir $snap_mount_dir/$base" + ls -al "$snap_mount_dir" + ls -al "$snap_mount_dir/$base" + exit 1 + fi + fi + done + fi +} + +main() { + local skip + skip="" + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit 0 + ;; + --skip) + skip="$skip $2" + shift 2 + ;; + *) + echo "snaps.cleanup: unknown subcommand $1" >&2 + show_help + exit 1 + ;; + esac + done + cleanup "$skip" +} + +main "$@" diff --git a/tools/snaps.name b/tools/snaps.name new file mode 100755 index 00000000..e562e926 --- /dev/null +++ b/tools/snaps.name @@ -0,0 +1,77 @@ +#!/bin/bash + +show_help() { + echo "usage: snaps.name gadget, kernel, core, snap-suffix" + echo "" + echo "get the name of a specific snap for the current system" +} + +gadget_name() { + snap list | grep -E '(gadget$|gadget,)' | awk '{ print $1 }' +} + +kernel_name(){ + # TODO this may not always be true during remodel scenarios + # if the old kernel remains + snap list | grep -E '(kernel$|kernel,)' | awk '{ print $1 }' +} + +core_name(){ + local core_name + core_name="$(snap model --verbose | grep -Po "^base:\\s+\\K.*" || true)" + if [ -z "$core_name" ]; then + core_name="core" + fi + echo "$core_name" +} + +snap_suffix(){ + if os.query is-core18; then + echo "-core18" + elif os.query is-core20; then + echo "-core20" + elif os.query is-core22; then + echo "-core22" + elif os.query is-core24; then + echo "-core24" + fi +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit 0 + ;; + gadget) + gadget_name + exit + ;; + kernel) + kernel_name + exit + ;; + core) + core_name + exit + ;; + snap-suffix) + snap_suffix + exit + ;; + *) + echo "snaps.name: unknown snap $1" >&2 + exit 1 + ;; + esac + done + +} + +main "$@" diff --git a/tools/tests.backup b/tools/tests.backup new file mode 100755 index 00000000..62d210c3 --- /dev/null +++ b/tools/tests.backup @@ -0,0 +1,69 @@ +#!/bin/bash -e +# Tool used to backup/restore a specific directory +# It is used by the test tool to make sure each test +# leaves the test directory as was initially + +show_help() { + echo "usage: tests.backup prepare [PATH]" + echo " tests.backup restore [PATH]" +} + +cmd_prepare() { + local BACKUP_PATH=$1 + + if [ ! -d "$BACKUP_PATH" ]; then + echo "tests.backup: cannot backup $BACKUP_PATH, not a directory" >&2 + exit 1 + fi + tar cf "${BACKUP_PATH}.tar" "$BACKUP_PATH" +} + +cmd_restore() { + local BACKUP_PATH=$1 + if [ -f "${BACKUP_PATH}.tar" ]; then + # Find all the files in the path $BACKUP_PATH and delete them + # This command deletes also the hidden files + find "${BACKUP_PATH}" -maxdepth 1 -mindepth 1 -exec rm -rf {} \; + tar -C/ -xf "${BACKUP_PATH}.tar" + rm "${BACKUP_PATH}.tar" + else + echo "tests.backup: cannot restore ${BACKUP_PATH}.tar, the file does not exist" >&2 + exit 1 + fi +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit + ;; + prepare) + local BACKUP_PATH="${2:-$(pwd)}" + cmd_prepare "$BACKUP_PATH" + exit + ;; + restore) + local BACKUP_PATH="${2:-$(pwd)}" + cmd_restore "$BACKUP_PATH" + exit + ;; + -*) + echo "tests.backup: unknown option $1" >&2 + exit 1 + ;; + *) + echo "tests.backup: unknown command $1" >&2 + exit 1 + ;; + esac + done +} + +main "$@" diff --git a/tools/tests.cleanup b/tools/tests.cleanup new file mode 100755 index 00000000..e8f69370 --- /dev/null +++ b/tools/tests.cleanup @@ -0,0 +1,97 @@ +#!/bin/bash -e + +show_help() { + echo "usage: tests.cleanup defer [args]" + echo " tests.cleanup pop" + echo " tests.cleanup restore" + echo + echo "COMMANDS:" + echo " restore: invokes all cleanup commands in reverse order" + echo " defer: pushes a command onto the cleanup stack" + echo " pop: invoke the most recently deferred command, discarding it" + echo + echo "The defer and pop commands can be to establish temporary" + echo "cleanup handler and remove it, in the case of success" +} + +cmd_defer() { + if [ ! -e defer.sh ]; then + truncate --size=0 defer.sh + chmod +x defer.sh + fi + echo "$*" >> defer.sh +} + +run_one_cmd() { + CMD="$1" + set +e + sh -ec "$CMD" + RET=$? + set -e + if [ $RET -ne 0 ]; then + echo "tests.cleanup: deferred command \"$CMD\" failed with exit code $RET" + exit $RET + fi +} + +cmd_pop() { + if [ ! -s defer.sh ]; then + echo "tests.cleanup: cannot pop, cleanup stack is empty" >&2 + exit 1 + fi + head -n-1 defer.sh >defer.sh.pop + trap "mv defer.sh.pop defer.sh" EXIT + tail -n-1 defer.sh | while read -r CMD; do + run_one_cmd "$CMD" + done +} + +cmd_restore() { + if [ -e defer.sh ]; then + tac defer.sh | while read -r CMD; do + run_one_cmd "$CMD" + done + rm -f defer.sh + fi +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit + fi + + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit + ;; + defer) + shift + cmd_defer "$@" + exit + ;; + pop) + shift + cmd_pop "$@" + exit + ;; + restore) + shift + cmd_restore + exit + ;; + -*) + echo "tests.cleanup: unknown option $1" >&2 + exit 1 + ;; + *) + echo "tests.cleanup: unknown command $1" >&2 + exit 1 + ;; + esac + done +} + +main "$@" diff --git a/tools/tests.pkgs b/tools/tests.pkgs new file mode 100755 index 00000000..7c122e9a --- /dev/null +++ b/tools/tests.pkgs @@ -0,0 +1,163 @@ +#!/bin/bash -e + +show_help() { + echo "usage: tests.pkgs install [--no-install-recommends] [PACKAGE...]" + echo " tests.pkgs remove [PACKAGE...]" + echo " tests.pkgs is-installed [PACKAGE]" + echo " tests.pkgs query [PACKAGE]" + echo " tests.pkgs list-installed" + echo + echo "Package names are standardized based on Debian package names" + echo "internally, package names are re-mapped to fit the convention" + echo "of the used system." +} + +unsupported() { + echo "tests.pkgs: cannot manage packages on this system" >&2 + exit 1 +} + +cmd_install() { + # This is re-defined by the backend file. + unsupported +} + +cmd_install_local() { + # This is re-defined by the backend file. + unsupported +} + +cmd_is_installed() { + # This is re-defined by the backend file. + unsupported +} + +cmd_query() { + # This is re-defined by the backend file. + unsupported +} + +cmd_list_installed() { + # This is re-defined by the backend file. + unsupported +} + +cmd_remove() { + # This is re-defined by the backend file. + unsupported +} + +remap_one() { + # This may be re-defined by the backend file. + echo "$1" +} + +remap_many() { + local many + many="" + for pkg in "$@"; do + if [ -z "$many" ]; then + many="$(remap_one "$pkg")" + else + many="$many $(remap_one "$pkg")" + fi + done + echo "$many" +} + +import_backend() { + local TOOLS_DIR + TOOLS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + if [ -n "$TESTSTOOLS" ]; then + TOOLS_DIR="$TESTSTOOLS" + fi + + if os.query is-core; then + echo "tests.pkgs: Ubuntu Core is not supported" >&2 + return 1 + elif os.query is-ubuntu || os.query is-debian; then + # Disabled because when the project is imported as a submodule the + # source is not found failing with SC1090 and SC1091 + #shellcheck disable=SC1090,SC1091 + . "$TOOLS_DIR/tests.pkgs.apt.sh" + elif os.query is-fedora || os.query is-centos || os.query is-amazon-linux; then + # Disabled because when the project is imported as a submodule the + # source is not found failing with SC1090 and SC1091 + #shellcheck disable=SC1090,SC1091 + . "$TOOLS_DIR/tests.pkgs.dnf-yum.sh" + elif os.query is-opensuse; then + # Disabled because when the project is imported as a submodule the + # source is not found failing with SC1090 and SC1091 + #shellcheck disable=SC1090,SC1091 + . "$TOOLS_DIR/tests.pkgs.zypper.sh" + elif os.query is-arch-linux; then + # Disabled because when the project is imported as a submodule the + # source is not found failing with SC1090 and SC1091 + #shellcheck disable=SC1090,SC1091 + . "$TOOLS_DIR/tests.pkgs.pacman.sh" + else + echo "tests.pkgs: cannot import packaging backend" >&2 + return 1 + fi +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit 1 + fi + + import_backend + + action= + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit 0 + ;; + --) + shift + break + ;; + install|remove|query|is-installed|list-installed) + action="$1" + shift + break # consume remaining arguments + ;; + -*) + echo "tests.pkgs: unknown option $1" >&2 + exit 1 + ;; + *) + echo "tests.pkgs: unknown command $1" >&2 + exit 1 + ;; + esac + done + + case "$action" in + install) + # shellcheck disable=SC2046 + cmd_install $(remap_many "$@") + ;; + is-installed) + cmd_is_installed "$(remap_one "$@")" + ;; + query) + cmd_query "$(remap_one "$@")" + ;; + list-installed) + cmd_list_installed + ;; + remove) + cmd_remove "$(remap_many "$@")" + ;; + *) + echo "tests.pkgs: unknown action $action" >&2 + exit 1 + ;; + esac +} + +main "$@" diff --git a/tools/tests.pkgs.apt.sh b/tools/tests.pkgs.apt.sh new file mode 100644 index 00000000..a2ec54a2 --- /dev/null +++ b/tools/tests.pkgs.apt.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +remap_one() { + case "$1" in + man) + if os.query is-debian; then + echo "man-db" + else + echo "$1" + fi + ;; + printer-driver-cups-pdf) + if os.query is-debian || os.query is-trusty; then + echo "cups-pdf" + else + echo "$1" + fi + ;; + test-snapd-pkg-1) + echo "curseofwar" + ;; + test-snapd-pkg-2) + echo "robotfindskitten" + ;; + *) + echo "$1" + ;; + esac +} + +cmd_install() { + apt-get update + + local APT_FLAGS="--yes" + while [ -n "$1" ]; do + case "$1" in + --no-install-recommends) + APT_FLAGS="$APT_FLAGS --no-install-recommends" + shift + ;; + *) + break + ;; + esac + done + # shellcheck disable=SC2068,SC2086 + apt-get install $APT_FLAGS $@ +} + +cmd_is_installed() { + dpkg -S "$1" >/dev/null 2>&1 +} + +cmd_query() { + apt-cache policy "$1" +} + +cmd_list_installed() { + apt list --installed | cut -d/ -f1 | sort +} + +cmd_remove() { + # shellcheck disable=SC2068 + apt-get remove --yes $@ +} diff --git a/tools/tests.pkgs.dnf-yum.sh b/tools/tests.pkgs.dnf-yum.sh new file mode 100644 index 00000000..16a9e02d --- /dev/null +++ b/tools/tests.pkgs.dnf-yum.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +remap_one() { + case "$1" in + xdelta3) + echo "xdelta" + ;; + openvswitch-switch) + echo "openvswitch" + ;; + printer-driver-cups-pdf) + echo "cups-pdf" + ;; + python3-gi) + echo "python3-gobject" + ;; + test-snapd-pkg-1) + echo "freeglut" + ;; + test-snapd-pkg-2) + echo "texlive-base" + ;; + *) + echo "$1" + ;; + esac +} + +cmd_install() { + local CMD="dnf" + if [ -z "$(command -v dnf)" ]; then + CMD="yum" + fi + local DNF_YUM_FLAGS="-y" + + while [ -n "$1" ]; do + case "$1" in + --no-install-recommends) + DNF_YUM_FLAGS="$DNF_YUM_FLAGS --setopt=install_weak_deps=False" + shift + ;; + *) + break + ;; + esac + done + + # shellcheck disable=SC2068,SC2086 + $CMD install $DNF_YUM_FLAGS $@ +} + +cmd_is_installed() { + rpm -qi "$1" >/dev/null 2>&1 +} + +cmd_query() { + if [ "$(command -v dnf)" != "" ]; then + dnf info "$1" + else + yum info "$1" + fi +} + +cmd_list_installed() { + rpm -qa | sort +} + +cmd_remove() { + # shellcheck disable=SC2068 + if [ "$(command -v dnf)" != "" ]; then + dnf remove -y $@ + else + yum remove -y $@ + fi +} diff --git a/tools/tests.pkgs.pacman.sh b/tools/tests.pkgs.pacman.sh new file mode 100644 index 00000000..3a98b0ad --- /dev/null +++ b/tools/tests.pkgs.pacman.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +remap_one() { + case "$1" in + python3-yaml) + echo "python-yaml" + ;; + dbus-x11) + # no separate dbus-x11 package in arch + echo "dbus" + ;; + printer-driver-cups-pdf) + echo "cups-pdf" + ;; + openvswitch-switch) + echo "openvswitch" + ;; + man) + echo "man-db" + ;; + python3-dbus) + echo "python-dbus" + ;; + python3-gi) + echo "python-gobject" + ;; + test-snapd-pkg-1) + echo "freeglut" + ;; + test-snapd-pkg-2) + echo "robotfindskitten" + ;; + *) + echo "$1" + ;; + esac +} + +cmd_install() { + local PACMAN_FLAGS="--noconfirm" + while [ -n "$1" ]; do + case "$1" in + --no-install-recommends) + # Pacman only ever installs the required dependencies + shift + ;; + *) + break + ;; + esac + done + # shellcheck disable=SC2068,SC2086 + pacman -S $PACMAN_FLAGS $@ +} + +cmd_is_installed() { + pacman -Qi "$1" >/dev/null 2>&1 +} + +cmd_query() { + pacman -Si "$1" +} + +cmd_list_installed() { + pacman -Qe | awk '{ print $1 }' | sort +} + +cmd_remove() { + # shellcheck disable=SC2068 + pacman -Rnsc --noconfirm $@ +} diff --git a/tools/tests.pkgs.zypper.sh b/tools/tests.pkgs.zypper.sh new file mode 100644 index 00000000..044ec255 --- /dev/null +++ b/tools/tests.pkgs.zypper.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +remap_one() { + case "$1" in + python3-yaml) + echo "python3-PyYAML" + ;; + dbus-x11) + echo "dbus-1-x11" + ;; + printer-driver-cups-pdf) + echo "cups-pdf" + ;; + python3-dbus) + # In OpenSUSE Leap 15, this is renamed to python3-dbus-python + echo "dbus-1-python3" + ;; + python3-gi) + echo "python3-gobject" + ;; + test-snapd-pkg-1) + echo "nudoku" + ;; + test-snapd-pkg-2) + echo "system-user-games" + ;; + *) + echo "$1" + ;; + esac +} + +cmd_install() { + local ZYPPER_FLAGS="-y" + while [ -n "$1" ]; do + case "$1" in + --no-install-recommends) + ZYPPER_FLAGS="$ZYPPER_FLAGS --no-recommends" + shift + ;; + *) + break + ;; + esac + done + + # shellcheck disable=SC2068,SC2086 + zypper install $ZYPPER_FLAGS $@ +} + +cmd_is_installed() { + rpm -qi "$1" >/dev/null 2>&1 +} + +cmd_query() { + zypper info "$1" +} + +cmd_list_installed() { + rpm -qa | sort +} + +cmd_remove() { + # shellcheck disable=SC2068 + zypper remove -y $@ +} diff --git a/tools/tests.systemd b/tools/tests.systemd new file mode 100755 index 00000000..fc63338b --- /dev/null +++ b/tools/tests.systemd @@ -0,0 +1,177 @@ +#!/bin/bash -e + +show_help() { + echo "usage: tests.systemd create-and-start-unit " + echo " tests.systemd stop-unit [--remove] ..." + echo " tests.systemd wait-for-service [-n|--attempts retries] [--wait seconds] [--state STATE] " +} + +# Create and start a persistent systemd unit that survives reboots. Use as: +# systemd_create_and_start_unit "name" "my-service --args" +# The third arg supports "overrides" which allow to customize the service +# as needed, e.g.: +# systemd_create_and_start_unit "name" "start" "[Unit]\nAfter=foo" +create_and_start_unit() { + local name=$1 + local start_line=$2 + local override=$3 + + if [ -z "$name" ]; then + echo "tests.systemd: unit name cannot be empty" + return 1 + fi + if [ -z "$start_line" ]; then + echo "tests.systemd: unit command line cannot be empty" + return 1 + fi + if [ -f "/etc/systemd/system/$name.service" ]; then + echo "tests.systemd: unit service file already exist, it is going to be overwritten" + fi + + printf '[Unit]\nDescription=Support for test %s\n[Service]\nType=simple\nExecStart=%s\n[Install]\nWantedBy=multi-user.target\n' "$name" "$start_line" > "/etc/systemd/system/$name.service" + if [ -n "$override" ]; then + mkdir -p "/etc/systemd/system/$name.service.d" + # shellcheck disable=SC2059 + printf "$override" > "/etc/systemd/system/$name.service.d/override.conf" + fi + + systemctl daemon-reload + systemctl enable "$name" + systemctl start "$name" + wait_for_service "$name" +} + +_stop_unit() { + local unit=$1 + + if systemctl is-active "$unit"; then + retries=20 + while systemctl status "$unit" | grep -q "Active: activating"; do + if [ $retries -eq 0 ]; then + echo "tests.systemd: unit $unit could not be stopped" + systemctl status "$unit" + exit 1 + fi + retries=$(( retries - 1 )) + sleep 1 + done + + systemctl stop "$unit" + fi +} + +stop_unit() { + local remove=false + while [ $# -gt 0 ]; do + case "$1" in + --remove) + remove=true + shift + ;; + *) + break + ;; + esac + done + + if [ $# -eq 0 ]; then + echo "tests.systemd: at least a unit name is required" + return 1 + fi + + for unit in "$@"; do + _stop_unit "$unit" + if [ "$remove" = true ]; then + if systemctl is-enabled "$unit"; then + systemctl disable "$unit" + fi + rm -f "/etc/systemd/system/$unit.service" + rm -rf "/etc/systemd/system/$unit.service.d" + fi + done + + systemctl daemon-reload +} + +wait_for_service() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + local attempts=300 + local wait=1 + local state="active" + local service_name + + while [ $# -gt 0 ]; do + case "$1" in + --wait) + wait="$2" + shift 2 + ;; + -n|--attempts) + attempts="$2" + shift 2 + ;; + --state) + state="$2" + shift 2 + ;; + *) + service_name=$1 + break + ;; + esac + done + + if [ -z "$service_name" ]; then + echo "tests.systemd: unit name cannot be empty" + return 1 + fi + + for i in $(seq "$attempts"); do + if systemctl show -p ActiveState "$service_name" | grep -q "ActiveState=$state"; then + return + fi + # show debug output every 1min + if [ "$i" -gt 0 ] && [ $(( i % 60 )) = 0 ]; then + systemctl status "$service_name" || true + fi + sleep "$wait" + done + + echo "tests.systemd: service $service_name did not become $state" + return 1 +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit + ;; + *) + action=$(echo "$1" | tr '-' '_') + shift + break + ;; + esac + done + + if [ -z "$(declare -f "$action")" ]; then + echo "tests.systemd: no such command: $action" >&2 + show_help + exit 1 + fi + + "$action" "$@" +} + +main "$@" diff --git a/utils/check-test-format b/utils/check-test-format new file mode 100755 index 00000000..1d0fe993 --- /dev/null +++ b/utils/check-test-format @@ -0,0 +1,149 @@ +#!/usr/bin/python3 + +""" +This tool is used to verify a correct format of spread tests +The input is a directory which is scanned recursively and all +the task.yaml files are check +""" + +import argparse +import glob +import os +import sys +import yaml +import yamlordereddictloader + +SUPPORTED_KEYS = [ + "summary", + "details", + "backends", + "systems", + "manual", + "priority", + "warn-timeout", + "kill-timeout", + "environment", + "prepare", + "restore", + "debug", + "execute", +] +MANDATORY_KEYS = ["summary", "details", "execute"] + + +def check_mandatory_keys(task_keys): + findings = [] + for key in MANDATORY_KEYS: + if key not in task_keys: + findings.append("Key '{}' is mandatory".format(key)) + + return findings + + +def check_keys_order(task_keys): + last_index = -1 + last_key = "" + findings = [] + + for curr_key in task_keys: + try: + curr_index = SUPPORTED_KEYS.index(curr_key) + if curr_index <= last_index: + findings.append( + "Keys '{}' and '{}' do not follow the desired order: {}".format( + last_key, curr_key, SUPPORTED_KEYS + ) + ) + + last_index = curr_index + last_key = curr_key + + except ValueError: + findings.append( + "key '{}' is not among the supported keys: {}".format( + curr_key, SUPPORTED_KEYS + ) + ) + + return findings + + +def check_task_format(filepath): + if not os.path.isfile(filepath): + print("Format checks failed for task {}".format(filepath)) + print(" - The path is not a file") + return False + + filemap = dict() + try: + with open(filepath, "r") as task: + filemap = yaml.load(task, Loader=yamlordereddictloader.Loader) + except yaml.scanner.ScannerError: + print("Invalid task format, checks failed for task {}".format(filepath)) + return False + + findings = check_keys_order(filemap.keys()) + findings.extend(check_mandatory_keys(filemap.keys())) + if findings: + print("Format checks failed for task {}".format(filepath)) + for finding in findings: + print(" - " + finding) + return False + + return True + +def check_dir(directory): + if not os.path.isdir(directory): + print("Format checks failed for directory {}".format(directory)) + print(" - The path is not a directory") + return False + + status = True + for file in glob.glob(os.path.join(directory, "**/task.yaml"), recursive=True): + if not check_task_format(file): + status = False + + return status + +def check_tests(tests): + status = True + for test in tests: + if not os.path.isfile(test): + print("Format checks failed for test {}".format(test)) + print(" - The path is not a file") + status = False + continue + + if not check_task_format(test): + status = False + + return status + +def _make_parser(): + parser = argparse.ArgumentParser() + parser.add_argument( + "--dir", help="path to the directory to check recursively" + ) + parser.add_argument( + "--tests", help="list of tests path to check", nargs='+' + ) + return parser + + +def main(): + parser = _make_parser() + args = parser.parse_args() + + status = 0 + if args.tests: + if not check_tests(args.tests): + status = 1 + + if args.dir: + if not check_dir(args.dir): + status = 1 + + sys.exit(status) + +if __name__ == "__main__": + main() diff --git a/utils/log-analyzer b/utils/log-analyzer new file mode 100755 index 00000000..08a66845 --- /dev/null +++ b/utils/log-analyzer @@ -0,0 +1,330 @@ +#!/bin/bash + +show_help() { + echo "usage: log-analyzer list-failed-tasks " + echo " log-analyzer list-executed-tasks " + echo " log-analyzer list-successful-tasks " + echo " log-analyzer list-aborted-tasks " + echo " log-analyzer list-all-tasks " + echo " log-analyzer list-reexecute-tasks " + echo "" + echo "The log analyzer is an utility wchi provides useful information about a spread" + echo "execution. The main functionality of the analyzer utility is to determine which tests" + echo "have to be re-executed, being able to include the tests that have been aborted, even" + echo "when those tests are not included in the test results." + echo "The log analyzer uses as input the spread expression that was used to run the tests," + echo "this expression determines which are all the tests to be considered. The second input" + echo "is the output of the log-parser utility, which generates a json file including all the" + echo "information extracted from the raw spread log" + echo "" + echo "Available options:" + echo " -h --help show this help message." + echo "" + echo "COMMANDS:" + echo " list-failed-tasks list the tasks that failed during execute" + echo " list-executed-tasks list the tasks that were executed" + echo " list-successful-tasks list the successful tasks" + echo " list-aborted-tasks list the aborted tasks (needs spread to be installed)" + echo " list-all-tasks list all the tasks" + echo " list-reexecute-tasks list the tasks to re-execute to complete (includes aborted and failed tasks)" + echo "" + echo "PARSED-LOG: This is the output generated by the log-parser tool" + echo "EXEC-PARAM: this is the parameter used to run spread (something like this BACKEND:SYSTEM:SUITE)" + echo "" +} + +_check_log() { + local log="$1" + + if [ -z "$log" ]; then + echo "log.analyzer: the log file cannot be empty" + exit 1 + elif [ ! -f "$log" ]; then + echo "log.analyzer: the log file $log does not exist" + exit 1 + fi +} + +_list_failed() { + local level="$1" + local stage="$2" + local log="$3" + + if [ -z "$level" ]; then + echo "log.analyzer: the first parameter cannot be empty" + exit 1 + elif [ ! "$level" = 'task' ] && [ ! "$level" = 'suite' ] && [ ! "$level" = 'project' ]; then + echo "log.analyzer: the first parameter has to be: task, suite or project" + exit 1 + fi + + if [ -z "$stage" ]; then + echo "log.analyzer: the second parameter cannot be empty" + exit 1 + elif [ ! "$stage" = 'prepare' ] && [ ! "$stage" = 'restore' ]; then + echo "log.analyzer: the second parameter has to be: prepare or restore" + exit 1 + fi + _check_log "$log" + + jq -r ".[] | select( .type == \"result\") | select( .result_type == \"Failed\") | select(.level == \"$level\") | select(.stage == \"$stage\") | .detail.lines[]" "$log" | cut -d '-' -f2- | xargs +} + +_merge_tasks_lists() { + # Returns the list1 + the tasks in list2 which are not included in list1 + local list1="$1" + local list2="$2" + local merged_list="$1" + local list1_file + + list1_file=$(mktemp list1.XXXXXX) + for elem in $list1; do + echo "$elem" >> "$list1_file" + done + + # shellcheck disable=SC2086 + for elem2 in $list2; do + if ! grep -Fxq "$elem2" "$list1_file"; then + merged_list="$merged_list $elem2" + fi + done + rm "$list1_file" + echo "$merged_list" +} + +_diff_tasks_lists() { + # Returns the list1 - the tasks in list2 + local list1="$1" + local list2="$2" + local diff_list list2_file + + diff_list="" + list2_file=$(mktemp list2.XXXXXX) + for elem in $list2; do + echo "$elem" >> "$list2_file" + done + + # shellcheck disable=SC2086 + for elem1 in $list1; do + if ! grep -Fxq "$elem1" "$list2_file"; then + diff_list="$diff_list $elem1" + fi + done + rm "$list2_file" + echo "$diff_list" +} + +_intersection_tasks_lists() { + # Returns the tasks in list1 which are also in the list2 + local list1="$1" + local list2="$2" + local both_list list2_file + + both_list="" + list2_file=$(mktemp list2.XXXXXX) + for elem in $list2; do + echo "$elem" >> "$list2_file" + done + for elem in $list1; do + # -F tells grep to look for fixed strings, not regexps + if grep -Fxq "$elem" "$list2_file"; then + both_list="$both_list $elem" + fi + done + rm "$list2_file" + echo "$both_list" +} + +list_all_tasks() { + local exec_exp="$1" + exec_exp="$(echo "$exec_exp" | tr ',' ' ')" + if ! command -v spread >/dev/null; then + echo "log.analyzer: spread tool is not installed, exiting..." + exit 1 + fi + + # shellcheck disable=SC2086 + spread -list $exec_exp +} + +_list_executed_and_failed_tasks() { + local exec_exp="$1" + local log="$2" + + if ! command -v spread >/dev/null; then + echo "log.analyzer: spread tool is not installed, exiting..." + exit 1 + fi + _check_log "$log" + + local failed_tasks failed_tasks_restore failed_tasks_prepare exec_and_failed_tasks + failed_tasks="$(list_failed_tasks "$exec_exp" "$log")" + failed_tasks_prepare="$(_list_failed task prepare "$log")" + failed_tasks_restore="$(_list_failed task restore "$log")" + + exec_and_failed_tasks="$(_merge_tasks_lists "$failed_tasks" "$failed_tasks_restore")" + _diff_tasks_lists "$exec_and_failed_tasks" "$failed_tasks_prepare" +} + +list_failed_tasks() { + local exec_exp="$1" + local log="$2" + + if [ -z "$exec_exp" ]; then + echo "log.analyzer: execution expression for spread cannot be empty" + exit 1 + fi + exec_exp="$(echo "$exec_exp" | tr ',' ' ')" + _check_log "$log" + + local all_tasks failed_tasks + all_tasks="$(list_all_tasks "$exec_exp")" + failed_tasks="$(jq -r '.[] | select( .type == "result") | select( .result_type == "Failed") | select(.level == "tasks") | .detail.lines[]' "$log" | cut -d '-' -f2- | xargs)" + _intersection_tasks_lists "$failed_tasks" "$all_tasks" +} + +list_reexecute_tasks() { + local exec_exp="$1" + local log="$2" + + if [ -z "$exec_exp" ]; then + echo "log.analyzer: execution expression for spread cannot be empty" + exit 1 + fi + exec_exp="$(echo "$exec_exp" | tr ',' ' ')" + _check_log "$log" + + local aborted_tasks exec_and_failed_tasks all_tasks reexec_tasks + aborted_tasks="$(list_aborted_tasks "$exec_exp" "$log")" + all_tasks="$(list_all_tasks "$exec_exp")" + exec_and_failed_tasks="$(_list_executed_and_failed_tasks "$exec_exp" "$log")" + + # Remove the tasks which are not in the filter from the executed and failed + exec_and_failed_tasks="$(_intersection_tasks_lists "$exec_and_failed_tasks" "$all_tasks")" + reexec_tasks="$(_merge_tasks_lists "$aborted_tasks" "$exec_and_failed_tasks")" + + # In case all the tests are failed or aborted, then the execution expression is used to reexecute + if [ "$(echo "$reexec_tasks" | wc -w)" = "$(echo "$all_tasks" | wc -w)" ]; then + echo "$exec_exp" + return + fi + + # When all the tests were successful, then no tests need to be reexecuted + if [ "$(echo "$reexec_tasks" | wc -w)" = 0 ]; then + return + fi + echo "$reexec_tasks" +} + +list_successful_tasks() { + local exec_exp="$1" + local log="$2" + + if [ -z "$exec_exp" ]; then + echo "log.analyzer: execution expression for spread cannot be empty" + exit 1 + fi + exec_exp="$(echo "$exec_exp" | tr ',' ' ')" + _check_log "$log" + + local all_tasks executed_tasks failed_tasks_restore failed_tasks + all_tasks="$(list_all_tasks "$exec_exp")" + executed_tasks="$(list_executed_tasks "$exec_exp" "$log")" + executed_tasks="$(_intersection_tasks_lists "$executed_tasks" "$all_tasks")" + failed_tasks="$(list_failed_tasks "$exec_exp" "$log")" + failed_tasks_restore="$(_list_failed task restore "$log")" + + if [ -n "$failed_tasks_restore" ]; then + failed_tasks="$(_merge_tasks_lists "$failed_tasks" "$failed_tasks_restore")" + fi + + if [ -n "$failed_tasks" ]; then + executed_tasks="$(_diff_tasks_lists "$executed_tasks" "$failed_tasks")" + fi + + echo "$executed_tasks" +} + +list_executed_tasks() { + local exec_exp="$1" + local log="$2" + + if [ -z "$exec_exp" ]; then + echo "log.analyzer: execution expression for spread cannot be empty" + exit 1 + fi + exec_exp="$(echo "$exec_exp" | tr ',' ' ')" + _check_log "$log" + + local all_tasks executed_tasks + all_tasks="$(list_all_tasks "$exec_exp")" + executed_tasks="$(jq -r '.[] | select( .type == "action") | select( .verb == "Executing") | .task' "$log")" + _intersection_tasks_lists "$executed_tasks" "$all_tasks" +} + +list_aborted_tasks() { + local exec_exp="$1" + local log="$2" + + if [ -z "$exec_exp" ]; then + echo "log.analyzer: execution expression for spread cannot be empty" + exit 1 + fi + exec_exp="$(echo "$exec_exp" | tr ',' ' ')" + _check_log "$log" + + local all_tasks executed_tasks failed_tasks_prepare failed_tasks_restore failed_tasks + all_tasks="$(list_all_tasks "$exec_exp")" + executed_tasks="$(list_executed_tasks "$exec_exp" "$log")" + failed_tasks="$(list_failed_tasks "$exec_exp" "$log")" + failed_tasks_prepare="$(_list_failed task prepare "$log")" + failed_tasks_restore="$(_list_failed task restore "$log")" + + # In case no tasks for the expression, the aborted list is empty + if [ -z "$all_tasks" ]; then + return + fi + + # In case no tasks are successfully executed, all the tasks - the failed ones are the aborted + if [ -z "$executed_tasks" ]; then + exec_and_failed_tasks="$(_list_executed_and_failed_tasks "$exec_exp" "$log")" + _diff_tasks_lists "$all_tasks" "$exec_and_failed_tasks" + return + fi + + # In other cases the aborted tasks are all the tasks - the executed - the that failed + _diff_tasks_lists "$all_tasks" "$executed_tasks" +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + local subcommand="$1" + local action= + while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + show_help + exit 0 + ;; + *) + action=$(echo "$subcommand" | tr '-' '_') + shift + break + ;; + esac + done + + if [ -z "$(declare -f "$action")" ]; then + echo "log.analyzer: no such command: $subcommand" >&2 + show_help + exit 1 + fi + + "$action" "$@" +} + +main "$@" diff --git a/utils/log-parser b/utils/log-parser new file mode 100755 index 00000000..25e801f0 --- /dev/null +++ b/utils/log-parser @@ -0,0 +1,590 @@ +#!/usr/bin/env python3 + +""" +This tool reads a spread log and creates a file with all the data +The output file includes the more important information extracted +from the log to be analyzed +""" + +import argparse +import json +import os +import re +import sys + +# Info types +ERROR_TYPE = 'Error' +DEBUG_TYPE = 'Debug' +WARN_TYPE = 'WARNING:' + +# Results +FAILED_TYPE = 'Failed' +ABORTED_TYPE = 'Aborted' +SUCCESSFUL_TYPE = 'Successful' + +# Printable names +ALL = 'all' +NONE = 'none' +ACTION = 'action' +OPERATION = 'operation' +INFO = 'info' +ERROR = 'error' +ERROR_DEBUG = 'error-debug' +FAILED = 'failed' +ABORTED = 'aborted' +SUCCESSFUL = 'successful' + +RESULT = 'result' +START = 'Found' +SPREAD_FILE = 'spread.yaml' + +EXEC_VERBS = ['Preparing', 'Executing', 'Restoring'] +INFO_TYPES = [ERROR_TYPE, DEBUG_TYPE, WARN_TYPE] +OPERATIONS = [ + 'Rebooting', 'Discarding', 'Allocating', 'Waiting', + 'Allocated', 'Connecting', 'Connected', 'Sending' + ] +RESULTS = ['Successful', 'Aborted', 'Failed'] +FAILED_LEVELS = ['task', 'suite', 'project'] +FAILED_STAGES = ['prepare', 'restore'] + + +class Action: + """ + Action represents the main spread tasks actions + The actions can be: Preparing, Executing and Restoring + """ + + def __init__(self, verb, task, date, time, source_line): + self.type = ACTION + self.verb = verb + self.time = time + self.date = date + self.task = task + self.source_line = source_line + + def __repr__(self): + return self.source_line + + def __dict__(self): + return { + 'type': 'action', + 'date': self.date, + 'time': self.time, + 'verb': self.verb, + 'task': self.task + } + + +class Result: + """ + Result represents the results for a spread run + The results can be: Successful, failed and aborted + """ + + def __init__(self, result_type, level, stage, number, date, time, + detail, source_line): + self.type = RESULT + self.result_type = result_type + self.level = level + self.stage = stage + self.number = number + self.time = time + self.date = date + self.detail = detail + self.source_line = source_line + + def __repr__(self): + if self.detail: + return '{}{}'.format(self.source_line, str(self.detail)) + return self.source_line + + def __dict__(self): + prepared_detail = None + if self.detail: + prepared_detail = self.detail.__dict__() + return { + 'type': self.type, + 'date': self.date, + 'time': self.time, + 'result_type': self.result_type, + 'level': self.level, + 'stage': self.stage, + 'number': self.number, + 'detail': prepared_detail + } + + +class Info: + """ + Info represents the extra tasks information which is included in the + spread log. The info can be: Error, Debug and Warning + """ + + def __init__(self, info_type, verb, task, extra, date, time, + detail, source_line): + self.type = INFO + self.info_type = info_type + self.verb = verb + self.time = time + self.date = date + self.task = task + self.extra = extra + self.detail = detail + self.source_line = source_line + + def __repr__(self): + if self.detail: + return '{}{}'.format(self.source_line, self.detail) + return self.source_line + + def __dict__(self): + prepared_detail = None + if self.detail: + prepared_detail = self.detail.__dict__() + return { + 'type': self.type, + 'date': self.date, + 'time': self.time, + 'info_type': self.info_type, + 'verb': self.verb, + 'task': self.task, + 'extra': self.extra, + 'detail': prepared_detail + } + + +class Detail: + """ + Detail represents the extra lines which are displayed after the info + """ + + def __init__(self, lines_limit, lines): + self.lines_limit = lines_limit + self.lines = lines + + def _get_lines(self): + if self.lines_limit < 0 or self.lines_limit > len(self.lines): + return self.lines + + # Use self.lines_limit-1 because the last line is a '.' and we don't + # want to count it as a line in the log details + return self.lines[-self.lines_limit-1:] + + def __repr__(self): + return ''.join(self._get_lines()) + + def __dict__(self): + return {'lines': self.lines[-self.lines_limit-1:]} + + +class Operation: + """ + Operation represents other actions that the spread running can do while + executing tests like: Rebooting, Discarding, Allocating, Waiting, + Allocated, Connecting, Connected, Sending + """ + + def __init__(self, verb, task, extra, date, time, source_line): + self.type = OPERATION + self.verb = verb + self.time = time + self.extra = extra + self.date = date + self.task = task + self.source_line = source_line + + def __repr__(self): + return self.source_line + + def __dict__(self): + return { + 'type': self.type, + 'date': self.date, + 'time': self.time, + 'verb': self.verb, + 'task': self.task, + 'extra': self.extra + } + + +class LogReader: + """ + LogReader manages the spread log, it allows to read, export and print + """ + def __init__(self, filepath, output_type, lines_limit, store_setup): + self.filepath = filepath + self.output_type = output_type + self.lines_limit = lines_limit + self.store_setup = store_setup + self.lines = [] + self.iter = 0 + self.full_log = [] + + def __repr__(self): + return str(self.__dict__()) + + def __dict__(self): + return {'full_log': self.full_log} + + def print_log(self, details, results): + if not self.full_log: + return + + # Print the details + if details == ALL: + print(''.join(str(x) for x in self.full_log)) + elif details == NONE: + pass + elif details == ERROR: + print(''.join(str(x) for x in self.full_log if x.type == INFO and + x.info_type == ERROR_TYPE)) + elif details == ERROR_DEBUG: + print(''.join(str(x) for x in self.full_log if x.type == INFO and + (x.info_type == ERROR_TYPE or x.info_type == DEBUG_TYPE))) + else: + print(''.join(str(x) for x in self.full_log if x.type == details)) + + # Print the results + if results == ALL: + print(''.join(str(x) for x in self.full_log if x.type == RESULT)) + elif results == NONE: + pass + elif results == FAILED: + print(''.join(str(x) for x in self.full_log if x.type == RESULT and + x.result_type == FAILED_TYPE)) + elif results == ABORTED: + print(''.join(str(x) for x in self.full_log if x.type == RESULT and + x.result_type == ABORTED_TYPE)) + else: + print(''.join(str(x) for x in self.full_log if x.type == RESULT and + x.result_type == SUCCESSFUL_TYPE)) + + def export_log(self, filepath): + prepared_log = [] + for item in self.full_log: + if isinstance(item, str): + prepared_log.append(item) + else: + prepared_log.append(item.__dict__()) + with open(filepath, 'w') as json_file: + json.dump(prepared_log, json_file, indent=4) + + def _next_line(self): + self.iter = self.iter + 1 + return self.lines[self.iter-1] + + def check_log_exists(self): + return os.path.exists(self.filepath) + + def read_spread_log(self): + try: + with open(self.filepath, 'r', encoding='utf-8') as filepath: + self.lines = filepath.readlines() + except UnicodeDecodeError: + with open(self.filepath, 'r', encoding='latin-1') as filepath: + self.lines = filepath.readlines() + + # Find the start of the log, the log file could include + # initial lines which are not part of the spread log itself + self.iter = 0 + if self.store_setup: + while self.iter < len(self.lines): + line = self._next_line() + if self._match_start(line): + break + self.full_log.append(line) + + if self.iter >= len(self.lines): + # Start not found, the log is either empty, corrupted or cut + self.iter = 0 + + # Then iterate line by line analyzing the log + while self.iter < len(self.lines): + line = self._next_line() + + # The line is a task execution; preparing, executing, restoring + if self._match_task(line): + action = self._get_action(line) + if action: + self.full_log.append(action) + continue + + # The line shows info: error, debug, warning + if self._match_info(line): + info = self._get_info(line) + if info: + self.full_log.append(info) + continue + + # The line is another operation: Rebooting, Discarding, Allocating + # Waiting, Allocated, Connecting, Connected, Sending' + if self._match_operation(line): + operation = self._get_operation(line) + if operation: + self.full_log.append(operation) + continue + + # The line is a result: Successful, Aborted, Failed + if self._match_result(line): + result = self._get_result(line) + if result: + self.full_log.append(result) + continue + + def _match_date(self, date): + return re.findall(r'\d{4}-\d{2}-\d{2}', date) + + def _match_time(self, time): + return re.findall(r'\d{2}:\d{2}:\d{2}', time) + + def _match_info(self, line): + parts = line.strip().split(' ') + return len(parts) > 3 and \ + parts[2] in INFO_TYPES and \ + self._match_date(parts[0]) and \ + self._match_time(parts[1]) + + def _match_task(self, line): + parts = line.strip().split(' ') + return len(parts) > 2 and \ + parts[2] in EXEC_VERBS and \ + self._match_date(parts[0]) and \ + self._match_time(parts[1]) + + def _match_start(self, line): + parts = line.strip().split(' ') + return len(parts) > 2 and \ + parts[2] == START and \ + self._match_date(parts[0]) and \ + self._match_time(parts[1]) and \ + SPREAD_FILE in parts[3] + + def _match_operation(self, line): + parts = line.strip().split(' ') + return len(parts) > 2 and \ + parts[2] in OPERATIONS and \ + self._match_date(parts[0]) and \ + self._match_time(parts[1]) + + def _match_result(self, line): + parts = line.strip().split(' ') + return len(parts) > 2 and \ + parts[2] in RESULTS and \ + self._match_date(parts[0]) and \ + self._match_time(parts[1]) + + def _get_detail(self, results=False, other_limit=None): + """ + This function is used to get the piece of log which is after the + info lines (error, debug, warning). The detail could also include + a limit of lines to tail the log and show the last lines. + It returns a Detail object included all the lines. + """ + + # If the first line matches with a regular line, this means the detail + # has no output and has to be discarded + line = self.lines[self.iter] + if self._match_task(line) or self._match_info(line) or \ + self._match_operation(line) or self._match_result(line): + return None + + detail=[] + initial_iter = self.iter + while self.iter < len(self.lines): + line = self._next_line() + if self._match_task(line) or self._match_info(line) or \ + self._match_operation(line) or self._match_result(line): + # When the details is for results, then any match is ok to break + if results: + break + # When the details is no for results, then we need to check also + # the the last time was just a '.' + # The details for info (Error, Debug and Warning) always finish with + # ---- + # . + # + # As the iter is already pointing to the next line since 'line = self._next_line()' + # to access the previous line of the current one it is needed to do 'self.iter-2' + elif self.lines[self.iter-2].strip() == '.': + break + + detail.append(line) + + # When the details is for results, if the detail line does not start + # with " - ", then it is time to break + if results and not line.startswith(" - "): + break + else: + detail.append(line) + + # We leave the iter in the last time in case the log has finished + if not self.iter == len(self.lines): + self.iter = self.iter - 1 + if not other_limit: + other_limit = self.lines_limit + + return Detail(other_limit, detail) + + def _get_info(self, line): + """ + Get the Info object for the error, debug and warning lines including + the details for this + """ + parts = line.strip().split(' ') + if len(parts) < 3: + return None + date = parts[0] + time = parts[1] + info_type = parts[2] + + verb = None + task = None + if info_type == WARN_TYPE: + info_type = info_type.split(':')[0] + verb = None + task = None + extra = ' '.join(parts[3:]) + elif info_type == ERROR_TYPE: + verb = parts[3] + task = parts[4] + extra = None + elif info_type == DEBUG_TYPE: + verb = None + task = parts[5] + extra = None + else: + print('log-parser: detail type not recognized: {}'.format(info_type)) + + detail = self._get_detail(results=False) + return Info(info_type, verb, task, extra, date, time, detail, line) + + def _get_result(self, line): + """ Get the Result object including the details for the result """ + parts = line.strip().split(' ') + if len(parts) < 3: + return None + date = parts[0] + time = parts[1] + result_type = parts[2] + level = parts[3].split(':')[0] + number = parts[-1] + + stage = None + detail = None + if result_type == FAILED_TYPE: + if level in FAILED_LEVELS: + stage = parts[4].split(':')[0] + detail = self._get_detail(results=True, other_limit=-1) + + return Result(result_type, level, stage, number.strip(), date, time, detail, + line) + + def _get_action(self, line): + """ + Get the Action object for lines preparing, executing and restoring + """ + parts = line.strip().split(' ') + if len(parts) < 3: + return None + date = parts[0] + time = parts[1] + verb = parts[2] + task = parts[3] + return Action(verb, task.split('...')[0], date, time, line) + + def _get_operation(self, line): + """ Get the Operation object for lines rebooting, allocating, etc """ + parts = line.strip().split(' ') + if len(parts) < 3: + return None + date = parts[0] + time = parts[1] + verb = parts[2] + task = None + extra = ' '.join(parts[3:]) + return Operation(verb, task, extra, date, time, line) + + +def _make_parser(): + # type: () -> argparse.ArgumentParser + parser = argparse.ArgumentParser( + description=""" +Parse the spread log and generates a file with a standardized output. It also +allows to filter the output by type and define the number of lines to show +for the error/debug/warning output. +""" + ) + parser.add_argument( + "-c", + "--cut", + type=int, + default=1000, + help="maximum number of lines for logs on errors and debug sections", + ) + parser.add_argument( + "-f", + "--format", + type=str, + default="json", + choices=['json'], + help="format for the output", + ) + parser.add_argument( + "-pd", + "--print-details", + type=str, + default=NONE, + choices=[ALL, ERROR, ERROR_DEBUG, OPERATION, ACTION, INFO, NONE], + help="Filter which info to print", + ) + parser.add_argument( + "-pr", + "--print-results", + type=str, + default=NONE, + choices=[ALL, FAILED, ABORTED, SUCCESSFUL, NONE], + help="Filter which results to print", + ) + parser.add_argument( + "-o", + "--output", + default="spread-results.json", + type=str, + help="output file to save the result", + ) + parser.add_argument( + "--store-setup", + action="store_true", + help="will save all the text before the spread run is started", + ) + parser.add_argument( + "logpath", metavar="PATH", help="path to the log to be analyzed" + ) + return parser + + +def main(): + # type: () -> None + parser = _make_parser() + args = parser.parse_args() + + if len(args.logpath) == 0: + parser.print_usage() + parser.exit(0) + + reader = LogReader(args.logpath, args.format, args.cut, args.store_setup) + if not reader.check_log_exists(): + print("log-parser: log not found") + sys.exit(1) + + reader.read_spread_log() + + if args.output: + reader.export_log(args.output) + + reader.print_log(args.print_details, args.print_results) + + +if __name__ == "__main__": + main() diff --git a/utils/spread-manager b/utils/spread-manager new file mode 100755 index 00000000..be411f6a --- /dev/null +++ b/utils/spread-manager @@ -0,0 +1,167 @@ +#!/bin/bash + +show_help() { + echo "usage: spread-manager set-manual [--project-path ] " + echo " spread-manager unset-manual [--project-path ] " + echo " spread-manager reset-manual [--project-path ] " + echo "" + echo "Tool used to help with functions that are not already implemented in spread" +} + +_check_project_path() { + local project_path="$1" + if [ -z "$project_path" ]; then + echo "spread-manager: project path cannot be empty" + exit 1 + fi + if [ ! -d "$project_path" ]; then + echo "spread-manager: project path \"$project_path\" has to be a directory" + exit 1 + fi + if [ ! -f "$project_path/spread.yaml" ]; then + echo "spread-manager: project spread file \"$project_path/spread.yaml\" does not exist" + exit 1 + fi +} + +_check_test_paths() { + # shellcheck disable=SC2124 + local test_paths="$@" + if [ -z "$test_paths" ]; then + echo "spread-manager: test path cannot be empty" + exit 1 + fi + for task_path in $test_paths; do + _check_test_path "$task_path" + done +} + +_check_test_path() { + local test_path="$1" + if [ -z "$test_path" ]; then + echo "spread-manager: test path cannot be empty" + exit 1 + fi + if [ ! -d "$test_path" ]; then + echo "spread-manager: test path \"$test_path\" has to be a directory" + exit 1 + fi + if [ ! -f "$test_path/task.yaml" ]; then + echo "spread-manager: test task \"$test_path/task.yaml\" does not exist" + exit 1 + fi +} + +_set_manual_value() { + local task_path=$1 + local manual_value=$2 + + # Update the manual property + if grep -E "^manual:" "$task_path"; then + sed -i -e "s/^manual:.*/manual: $manual_value/g" "$task_path" + else + echo "manual: $manual_value" >> "$task_path" + fi +} + +set_manual() { + local project_path="$1" + shift + # shellcheck disable=SC2124 + local test_paths="$@" + + _check_project_path "$project_path" + test_paths="$(echo "$test_paths" | tr ',' ' ')" + _check_test_paths "$test_paths" + + for test_path in $test_paths; do + local task_path + task_path="$project_path/$test_path/task.yaml" + + # Backup the task + cp "$task_path" "$task_path.back" + _set_manual_value "$task_path" true + done +} + +unset_manual() { + local project_path="$1" + shift + # shellcheck disable=SC2124 + local test_paths="$@" + + _check_project_path "$project_path" + test_paths="$(echo "$test_paths" | tr ',' ' ')" + _check_test_paths "$test_paths" + + for test_path in $test_paths; do + local task_path + task_path="$project_path/$test_path/task.yaml" + + # Backup the task + cp "$task_path" "$task_path.back" + _set_manual_value "$task_path" false + done +} + +reset_manual() { + local project_path="$1" + shift + # shellcheck disable=SC2124 + local test_paths="$@" + + _check_project_path "$project_path" + test_paths="$(echo "$test_paths" | tr ',' ' ')" + _check_test_paths "$test_paths" + + for test_path in $test_paths; do + local task_path + task_path="$project_path/$test_path/task.yaml" + + if [ -f "$task_path.back" ]; then + mv "$task_path.back" "$task_path" + else + echo "spread-manager: test task backup does not exist \"$task_path.back\"" + exit 1 + fi + done +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + local subcommand="$1" + local action= + if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + show_help + exit 0 + else + action=$(echo "$subcommand" | tr '-' '_') + shift + fi + + if [ -z "$(declare -f "$action")" ]; then + echo "spread-manager: no such command: $subcommand" >&2 + show_help + exit 1 + fi + + local project_path + if [ $# -gt 0 ]; then + if [[ "$action" =~ .*_manual ]]; then + project_path="$(pwd)" + if [ "$1" == "--project-path" ]; then + project_path="$2" + shift 2 + fi + "$action" "$project_path" "$@" + else + "$action" "$@" + fi + fi +} + +main "$@" diff --git a/utils/spread-shellcheck b/utils/spread-shellcheck new file mode 100755 index 00000000..4769a7dc --- /dev/null +++ b/utils/spread-shellcheck @@ -0,0 +1,413 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2022 Canonical Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import argparse +import binascii +import hashlib +import itertools +import logging +import os +import re +import subprocess +import yaml + +from collections import namedtuple +from concurrent.futures import ThreadPoolExecutor +from multiprocessing import cpu_count +from pathlib import Path +from threading import Lock +from typing import Dict + + +# default shell for shellcheck +SHELLCHECK_SHELL = os.getenv('SHELLCHECK_SHELL', 'bash') +# set to non-empty to ignore all errors +NO_FAIL = os.getenv('NO_FAIL') +# set to non empty to enable 'set -x' +D = os.getenv('D') +# set to non-empty to enable verbose logging +V = os.getenv('V') +# set to a number to use these many threads +N = int(os.getenv('N') or cpu_count()) +# file with list of files that can fail validation +CAN_FAIL = os.getenv('CAN_FAIL') + +# names of sections +SECTIONS = ['prepare', 'prepare-each', 'restore', 'restore-each', + 'debug', 'debug-each', 'execute', 'repack'] + + +def parse_arguments(): + parser = argparse.ArgumentParser(description='spread shellcheck helper') + parser.add_argument('-s', '--shell', default='bash', + help='shell') + parser.add_argument('-n', '--no-errors', action='store_true', + default=False, help='ignore all errors ') + parser.add_argument('-v', '--verbose', action='store_true', + default=False, help='verbose logging') + parser.add_argument('--can-fail', default=None, + help=('file with list of files that are can fail ' + 'validation')) + parser.add_argument('-P', '--max-procs', default=N, type=int, metavar='N', + help='run these many shellchecks in parallel (default: %(default)s)') + parser.add_argument('-e', '--exclude', default=[], action="append", + help='path to exclude of the shell check') + parser.add_argument('--no-cache', help='disable caching', action='store_true') + parser.add_argument('paths', nargs='+', help='paths to check') + return parser.parse_args() + + +class ShellcheckRunError(Exception): + def __init__(self, stderr): + super().__init__() + self.stderr = stderr + + +class ShellcheckError(Exception): + def __init__(self, path): + super().__init__() + self.sectionerrors = {} + self.path = path + + def addfailure(self, section, error): + self.sectionerrors[section] = error + + def __len__(self): + return len(self.sectionerrors) + + +class ShellcheckFailures(Exception): + def __init__(self, failures=None): + super().__init__() + self.failures = set() + if failures: + self.failures = set(failures) + + def merge(self, otherfailures): + self.failures = self.failures.union(otherfailures.failures) + + def __len__(self): + return len(self.failures) + + def intersection(self, other): + return self.failures.intersection(other) + + def difference(self, other): + return self.failures.difference(other) + + def __iter__(self): + return iter(self.failures) + + +def checksection(data, env: Dict[str, str]): + # spread shell snippets are executed under 'set -e' shell, make sure + # shellcheck knows about that + script_data = [] + script_data.append('set -e') + + for key, value in env.items(): + value = str(value) + disabled_warnings = set() + export_disabled_warnings = set() + def replacement(match): + if match.group(0) == '"': + # SC2089 and SC2090 are about quotes vs arrays + # We cannot have arrays in environment variables of spread + # So we do have to use quotes + disabled_warnings.add('SC2089') + export_disabled_warnings.add('SC2090') + return r'\"' + else: + assert(match.group('command') is not None) + # "Useless" echo. This is what we get. + # We cannot just evaluate to please shellcheck. + disabled_warnings.add('SC2116') + return '$({})'.format(match.group('command')) + value = re.sub(r'[$][(]HOST:(?P.*)[)]|"', replacement, value) + # converts + # FOO: "$(HOST: echo $foo)" -> FOO="$(echo $foo)" + # FOO: "$(HOST: echo \"$foo\")" -> FOO="$(echo "$foo")" + # FOO: "foo" -> FOO="foo" + # FOO: "\"foo\"" -> FOO="\"foo\"" + if disabled_warnings: + script_data.append("# shellcheck disable={}".format(','.join(disabled_warnings))) + script_data.append("{}=\"{}\"".format(key, value)) + if export_disabled_warnings: + script_data.append("# shellcheck disable={}".format(','.join(export_disabled_warnings))) + script_data.append("export {}".format(key, value)) + script_data.append(data) + proc = subprocess.Popen("shellcheck -s {} -x -".format(SHELLCHECK_SHELL), + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + shell=True) + stdout, _ = proc.communicate(input='\n'.join(script_data).encode('utf-8'), timeout=60) + if proc.returncode != 0: + raise ShellcheckRunError(stdout) + + +class Cacher: + _instance = None + + def __init__(self): + self._enabled = True + self._lock = Lock() + self._hit =0 + self._miss = 0 + self._shellcheck_version = None + self._probe_shellcheck_version() + + @classmethod + def init(cls): + cls._instance = Cacher() + + @classmethod + def get(cls): + return cls._instance + + def disable(self): + logging.debug("caching is disabled") + self._enabled = False + + @staticmethod + def _cache_path_for(digest): + prefix = digest[:2] + return Path.home().joinpath(".cache", "spread-shellcheck", prefix, digest) + + def is_cached(self, data, path): + if not self._enabled: + return False, "" + # the digest uses script content and shellcheck versions as inputs, but + # consider other possible inputs: path to the *.yaml file (so moving + # the script around would cause a miss) or even the contents of this + # script + h = hashlib.sha256() + h.update(self._shellcheck_version) + h.update(data) + hdg = binascii.b2a_hex(h.digest()).decode() + cachepath = Cacher._cache_path_for(hdg) + logging.debug("cache stamp %s, exists? %s", cachepath.as_posix(), cachepath.exists()) + hit = cachepath.exists() + self._record_cache_event(hit) + return hit, hdg + + def cache_success(self, digest, path): + if not self._enabled: + return + cachepath = Cacher._cache_path_for(digest) + logging.debug("cache success, path %s", cachepath.as_posix()) + cachepath.parent.mkdir(parents=True, exist_ok=True) + cachepath.touch() + + def _record_cache_event(self, hit): + with self._lock: + if hit: + self._hit += 1 + else: + self._miss += 1 + + def _probe_shellcheck_version(self): + logging.debug("probing shellcheck version") + out = subprocess.check_output("shellcheck --version", shell=True) + self._shellcheck_version = out + + @property + def stats(self): + return namedtuple('Stats', ['hit', 'miss'])(self._hit, self._miss) + + +def checkfile(path, executor): + logging.debug("checking file %s", path) + with open(path, mode='rb') as inf: + rawdata = inf.read() + cached, digest = Cacher.get().is_cached(rawdata, path) + if cached: + logging.debug("entry %s already cached", digest) + return + data = yaml.safe_load(rawdata) + + errors = ShellcheckError(path) + # TODO: handle stacking of environment from other places that influence it: + # spread.yaml -> global env + backend env + suite env -> task.yaml (task + # env + variant env). + env = {} + for key, value in data.get("environment", {}).items(): + if "/" in key: + # TODO: re-check with each variant's value set. + key = key.split('/', 1)[0] + env[key] = value + for section in SECTIONS: + if section not in data: + continue + try: + logging.debug("%s: checking section %s", path, section) + checksection(data[section], env) + except ShellcheckRunError as serr: + errors.addfailure(section, serr.stderr.decode('utf-8')) + + if path.endswith('spread.yaml') and 'suites' in data: + # check suites + suites_sections_and_futures = [] + for suite in data['suites'].keys(): + for section in SECTIONS: + if section not in data['suites'][suite]: + continue + logging.debug("%s (suite %s): checking section %s", path, suite, section) + future = executor.submit(checksection, data['suites'][suite][section], env) + suites_sections_and_futures.append((suite, section, future)) + for item in suites_sections_and_futures: + suite, section, future = item + try: + future.result() + except ShellcheckRunError as serr: + errors.addfailure('suites/' + suite + '/' + section, + serr.stderr.decode('utf-8')) + + if errors: + raise errors + # only stamp the cache when the script was found to be valid + Cacher.get().cache_success(digest, path) + + +def is_file_in_dirs(file, dirs): + for dir in dirs: + if os.path.abspath(file).startswith('{}/'.format(os.path.abspath(dir))): + print('Skipping {}'.format(file)) + return True + + return False + + +def findfiles(locations, exclude): + for loc in locations: + if os.path.isdir(loc): + for root, _, files in os.walk(loc, topdown=True): + for name in files: + if name in ['spread.yaml', 'task.yaml']: + full_path = os.path.join(root, name) + if not is_file_in_dirs(full_path, exclude): + yield full_path + else: + full_path = os.path.abspath(loc) + if not is_file_in_dirs(full_path, exclude): + yield full_path + + +def check1path(path, executor): + try: + checkfile(path, executor) + except ShellcheckError as err: + return err + return None + + +def checkpaths(locs, exclude, executor): + # setup iterator + locations = findfiles(locs, exclude) + failed = [] + for serr in executor.map(check1path, locations, itertools.repeat(executor)): + if serr is None: + continue + logging.error(('shellcheck failed for file %s in sections: ' + '%s; error log follows'), + serr.path, ', '.join(serr.sectionerrors.keys())) + for section, error in serr.sectionerrors.items(): + logging.error("%s: section '%s':\n%s", serr.path, section, error) + failed.append(serr.path) + + if failed: + raise ShellcheckFailures(failures=failed) + + +def loadfilelist(flistpath): + flist = set() + with open(flistpath) as inf: + for line in inf: + if not line.startswith('#'): + flist.add(line.strip()) + return flist + + +def main(opts): + paths = opts.paths or ['.'] + exclude = opts.exclude + failures = ShellcheckFailures() + with ThreadPoolExecutor(max_workers=opts.max_procs) as executor: + try: + checkpaths(paths, exclude, executor) + except ShellcheckFailures as sf: + failures.merge(sf) + + if not opts.no_cache: + stats = Cacher.get().stats + logging.info("cache stats: hit %d miss %d", stats.hit, stats.miss) + + if failures: + if opts.can_fail: + can_fail = loadfilelist(opts.can_fail) + + unexpected = failures.difference(can_fail) + if unexpected: + logging.error(('validation failed for the following ' + 'non-whitelisted files:\n%s'), + '\n'.join([' - ' + f for f in + sorted(unexpected)])) + raise SystemExit(1) + + did_not_fail = can_fail - failures.intersection(can_fail) + if did_not_fail: + logging.error(('the following files are whitelisted ' + 'but validated successfully:\n%s'), + '\n'.join([' - ' + f for f in + sorted(did_not_fail)])) + raise SystemExit(1) + + # no unexpected failures + return + + logging.error('validation failed for the following files:\n%s', + '\n'.join([' - ' + f for f in sorted(failures)])) + + if NO_FAIL or opts.no_errors: + logging.warning("ignoring errors") + else: + raise SystemExit(1) + + +if __name__ == '__main__': + opts = parse_arguments() + if opts.verbose or D or V: + lvl = logging.DEBUG + else: + lvl = logging.INFO + logging.basicConfig(level=lvl) + + if CAN_FAIL: + opts.can_fail = CAN_FAIL + + if NO_FAIL: + opts.no_errors = True + + if opts.max_procs == 1: + # TODO: temporary workaround for a deadlock when running with a single + # worker + opts.max_procs += 1 + logging.warning('workers count bumped to 2 to workaround a deadlock') + + Cacher.init() + if opts.no_cache: + Cacher.get().disable() + + main(opts) diff --git a/utils/spreadJ b/utils/spreadJ new file mode 100755 index 00000000..26f6b4ae --- /dev/null +++ b/utils/spreadJ @@ -0,0 +1,119 @@ +#!/bin/bash + +show_help() { + echo "usage: spreadJ rerun [--suite SUITE] " + echo " spreadJ show [--suite SUITE] " + echo " spreadJ stats [--suite SUITE] " + echo " spreadJ list [--suite SUITE] " + echo "" + echo "Available options:" + echo " -h --help show this help message." + echo "" + echo "TARGET:" + echo " all,failed,passed,aborted" + echo "" + echo "Tool used to help with functions that are not already implemented in spread" +} + +_filter_suite() { + local suite="$1" + if [ -z "$suite" ]; then + echo ".testsuites[]" + else + echo ".testsuites[] | select(.name == \"$suite\")" + fi +} + +rerun() { + local suite="" + if [ "$1" == "--suite" ]; then + suite="$2" + shift 2 + fi + local res_path="$1" + if [ ! -e "$res_path" ]; then + echo "spreadJ: results path not found: $res_path" + exit 1 + fi + + local query + query="$(_filter_suite $suite).tests[] | select((.result == \"failed\") or (.result == \"aborted\")).name" + jq -r "$query" "$res_path" +} + +stats() { + local suite="" + if [ "$1" == "--suite" ]; then + suite="$2" + shift 2 + fi + local res_path="$1" + + if [ ! -e "$res_path" ]; then + echo "spreadJ: results path not found: $res_path" + exit 1 + fi + + local query + if [ -z "$suite" ]; then + query="del(.testsuites)" + else + query="$(_filter_suite $suite) | del(.tests) | del(.name)" + fi + jq -r "$query" "$res_path" +} + +list() { + local suite="" + if [ "$1" == "--suite" ]; then + suite="$2" + shift 2 + fi + local target="$1" + local res_path="$2" + + if [ ! -e "$res_path" ]; then + echo "spreadJ: results path not found: $res_path" + exit 1 + fi + + if [ -z "$target" ]; then + echo "spreadJ: result target cannot be empty" + exit 1 + fi + + local query + if [ "$target" == "all" ]; then + query="$(_filter_suite $suite).tests[]).name" + else + query="$(_filter_suite $suite).tests[] | select((.result == \"$target\")).name" + fi + jq -r "$query" "$res_path" +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + local subcommand="$1" + local action= + if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + show_help + exit 0 + else + action=$(echo "$subcommand" | tr '-' '_') + shift + fi + + if [ -z "$(declare -f "$action")" ]; then + echo "spreadJ: no such command: $subcommand" >&2 + show_help + exit 1 + fi + + "$action" "$@" +} + +main "$@"