Rewriting bundle-remove and check-update tests

A new test library.bash was introduced that simplifies the creation
of test environments and test objects.

This commit rewrites all existing tests from
test/functional/bundleremove and test/functional/checkupdate but this
time using the new test library.

NOTE: Once all the tests have been rewriten to use the new lib, they
can be included in the Makefile so they are run with every patch,
and the old tests can be deleted.
This commit is contained in:
Castulo Martinez
2018-07-25 10:52:37 -07:00
committed by Matthew Johnson
parent 6496182f96
commit ca3a68f634
40 changed files with 1001 additions and 348 deletions
+1
View File
@@ -59,4 +59,5 @@ test/functional/*/*/debug.log
test/functional/*/*/state
test/functional/*/*/lines-output
test/functional/*/*/target-dir/usr/share/clear/bundles/.MoM
test/functional/*/*.log
verifytime
+1
View File
@@ -24,6 +24,7 @@ install:
- tar -xvf v3.3.1.tar.gz
- pushd libarchive-3.3.1 && autoreconf -fi && ./configure --prefix=/usr && make -j48 && sudo make install && popd
- sudo apt-get install python3-docutils
- sudo apt-get install realpath
- sudo ln -s /usr/share/docutils/scripts/python3/rst2man /usr/bin/rst2man.py
# Ubuntu's default umask is 0002, but this break's swupd hash calculations.
+34
View File
@@ -114,38 +114,72 @@ TESTS = $(dist_check_SCRIPTS)
BATS = \
test/documentation/manpages/test.bats \
test/functional/bundleadd/add-directory/test.bats \
test/functional/bundleadd_v2/add-directory.bats \
test/functional/bundleadd/add-existing/test.bats \
test/functional/bundleadd_v2/add-existing.bats \
test/functional/bundleadd/add-multiple/test.bats \
test/functional/bundleadd_v2/add-multiple.bats \
test/functional/bundleadd/add-rc/test.bats \
test/functional/bundleadd_v2/add-rc.bats \
test/functional/bundleadd/bad-hash/test.bats \
test/functional/bundleadd_v2/add-bad-hash.bats \
test/functional/bundleadd/bad-hash-state/test.bats \
test/functional/bundleadd_v2/add-bad-hash-state.bats \
test/functional/bundleadd/bad-manifest/test.bats \
test/functional/bundleadd_v2/add-bad-manifest.bats \
test/functional/bundleadd/boot-file/test.bats \
test/functional/bundleadd_v2/add-boot-file.bats \
test/functional/bundleadd/boot-skip/test.bats \
test/functional/bundleadd_v2/add-boot-skip.bats \
test/functional/bundleadd/include/test.bats \
test/functional/bundleadd_v2/add-include.bats \
test/functional/bundleadd/fix-missing-file/test.bats \
test/functional/bundleadd/skip-scripts/test.bats \
test/functional/bundleadd_v2/add-skip-scripts.bats \
test/functional/bundleadd/verify-fix-path/test.bats \
test/functional/bundleadd_v2/add-verify-fix-path.bats \
test/functional/bundlelist/all/test.bats \
test/functional/bundlelist_v2/list-all.bats \
test/functional/bundlelist/deps-flat/test.bats \
test/functional/bundlelist_v2/list-deps-flat.bats \
test/functional/bundlelist/deps-invalid-bundle/test.bats \
test/functional/bundlelist_v2/list-deps-invalid-bundle.bats \
test/functional/bundlelist/deps-nested/test.bats \
test/functional/bundlelist_v2/list-deps-nested.bats \
test/functional/bundlelist/has-dep-nested/test.bats \
test/functional/bundlelist_v2/list-has-dep-nested.bats \
test/functional/bundlelist/has-dep-nested-not-installed/test.bats \
test/functional/bundlelist_v2/list-has-dep-nested-not-installed.bats \
test/functional/bundlelist/has-dep-nested-server/test.bats \
test/functional/bundlelist_v2/list-has-dep-nested-server.bats \
test/functional/bundlelist/no-deps/test.bats \
test/functional/bundlelist_v2/list-no-deps.bats \
test/functional/bundlelist/none-has-deps/test.bats \
test/functional/bundlelist_v2/list-none-has-deps.bats \
test/functional/bundleremove/boot-file/test.bats \
test/functional/bundleremove_v2/remove-boot-file.bats \
test/functional/bundleremove/include/test.bats \
test/functional/bundleremove_v2/remove-include.bats \
test/functional/bundleremove/include-nested/test.bats \
test/functional/bundleremove_v2/remove-include-nested.bats \
test/functional/bundleremove_v2/remove-os-core.bats \
test/functional/bundleremove/parse-args/test.bats \
test/functional/bundleremove_v2/remove-parse-args.bats \
test/functional/bundleremove/remove-file/test.bats \
test/functional/bundleremove_v2/remove-file.bats \
test/functional/bundleremove/remove-multiple/test.bats \
test/functional/bundleremove_v2/remove-multiple.bats \
test/functional/bundleremove_v2/remove-rc.bats \
test/functional/checkupdate/new-version/test.bats \
test/functional/checkupdate_v2/chk-update-new-version.bats \
test/functional/checkupdate/no-server-content/test.bats \
test/functional/checkupdate_v2/chk-update-no-server-content.bats \
test/functional/checkupdate/no-target-content/test.bats \
test/functional/checkupdate_v2/chk-update-no-target-content.bats \
test/functional/checkupdate/slow-server/test.bats \
test/functional/checkupdate_v2/chk-update-slow-server.bats \
test/functional/checkupdate/version-match/test.bats \
test/functional/checkupdate_v2/chk-update-version-match.bats \
test/functional/completion/basic/test.bats \
test/functional/hashdump/file-hash/test.bats \
test/functional/hashdump/file-hash-no-path-prefix/test.bats \
+105 -31
View File
@@ -1,7 +1,11 @@
# Writing tests for swupd-client
<br/>
When writing tests for swupd-client, the swupd test library (testlib.bash) should be used. This will facilitate the creation of test environments and test objects, and will also ensure that validations are performed in a consistent manner accross tests. The swupd-client uses BATS as the test framework of choice, to discover and run tests.
When writing tests for swupd-client, the swupd test library (testlib.bash) should
be used. This will facilitate the creation of test environments and test objects,
and will also ensure that validations are performed in a consistent manner accross
tests. The swupd-client uses BATS as the test framework of choice, to discover and
run tests.
<br/>
To use the test library you just need to source it in your shell
```bash
@@ -15,12 +19,14 @@ load "testlib"
## Quickstart
1. Source testlib.bash from your terminal, this will load all the test functions from the library into your current shell process:
1. Source testlib.bash from your terminal, this will load all the test functions
from the library into your current shell process:
```bash
$ source testlib.bash
```
2. If necessary, create a directory to group the new test script with other test scripts of the same theme.
2. If necessary, create a directory to group the new test script with other test
scripts of the same theme.
```bash
$ mkdir <some_test_theme>
$ cd <some_test_theme>
@@ -37,16 +43,27 @@ A new test script will be generated in the current directory.
load "../testlib"
setup() {
global_setup() {
create_test_environment "$TEST_NAME"
# global setup
}
test_setup() {
# create_test_environment "$TEST_NAME"
# create_bundle -n <bundle_name> -f <file_1>,<file_2>,<file_N> "$TEST_NAME"
}
teardown() {
test_teardown() {
destroy_test_environment "$TEST_NAME"
# destroy_test_environment "$TEST_NAME"
}
global_teardown() {
# global cleanup
}
@@ -58,24 +75,53 @@ teardown() {
}
```
4. The setup() function contains commands that should be executed before every test in the test script. This is usually the best place for creating test objects that are pre-requists for all tests in the script. The test library provides many [fixtures](#test-fixtures) to create all these pre-requisits easily.
4. The global_setup() function contains commands that are run only once per test
script, it runs before any test in the script is executed.
5. The teardown() function contains commands that should be executed after every test in the test script. It is the most common place for cleaning up test resources created for and by tests.
5. The test_setup() function contains commands that should be executed before every
test in the test script. This is usually the best place for creating test
objects that are prerequisites for all tests in the script. The test library
provides many [fixtures](#test-fixtures) to create all these prerequisites easily.
A default value for the test_setup() function is already defined in the test library,
but this is a minimal definition, only a test environment with name $TEST_NAME gets
created, so if this is all your test needs you can then just remove the test_setup()
from the test script so the pre-defined one is used, otherwise you will need to
overwrite that function with your test prerequisites.
6. Every test within the test file starts with the @test identifier followed by a description of the test. Add one or more tests to the script as needed.
6. The test_teardown() function contains commands that should be executed after
every test in the test script. It is the most common place for cleaning up
test resources created for and by tests.
Similarly as with the test_setup(), there is a minimal definition of the test_teardown()
function already in the test library. In this definition, the test environment $TEST_NAME
gets deleted, in most tests this is all it needs to be done as part of the cleanup, so
if this is the case you can go ahead and remove the local test_teardown definition from the
test script so the pre-defined one is used, if you have more specific cleanup needs you will
need to overwrite the function.
7. From within each test, execute the command you want to validate by using the `run` helper.
6. The global_teardown() function contains commands that are run only once per test
script, it runs once all tests in the scripts have finished.
8. Validate that the program under test performed as expected by using one or more of the [assertions](#assertions) provided by the test library.
7. Every test within the test file starts with the @test identifier followed
by a description of the test. Add one or more tests to the script as needed.
8. From within each test, execute the command you want to validate by using
the `run` helper.
9. Validate that the program under test performed as expected by using one
or more of the [assertions](#assertions) provided by the test library.
<br/>
### Test Principles
* Every test needs to run in its own test environment so they don't interfere with each other.
* Every test needs to run in its own test environment so they don't interfere with
each other.
* Every test should clean up after itself.
* Tests should be atomic and test only one thing per test.
* Tests should be independent from each other, one should not need another one in order to work.
* Test files from the same "theme" should be grouped within the theme directory. Tests from the same type can optionally be added to the same test file, for example:
* Tests should be independent from each other, one should not need another
one in order to work.
* Test files from the same "theme" should be grouped within the theme directory.
Tests from the same type can optionally be added to the same test file, for
example:
* bundle-add # A theme
* add-single-bundle.bats
* @test "add a bundle"
@@ -109,19 +155,30 @@ $ cd swupd-client/test/functional
$ bats *
```
Alternatively, to run all tests locally you can also use make:
```bash
$ cd swupd-client/
$ make check
```
To include tests to be run in the CI system:
TBD
<br/>
## Test Fixtures
### Test Environment
A test environment is nothing but a directory that contains the necessary file structure that is used to emulate the existance of the following resources:
A test environment is nothing but a directory that contains the necessary file
structure that is used to emulate the existance of the following resources:
* a target file system <test_enviroment>/target-dir
* an alternate swupd state directory <test_enviroment>/state
* a local state directory to avoid conflicts with the system state directory
<test_enviroment>/state
* a remote system that provides content file downloads <test_enviroment>/web-dir
* the os-core bundle, since this bundle is required in every system it gets created by default in the content download directory, and "installed" in the target system
* the os-core bundle, since this bundle is required in every system it gets
created by default in the content download directory, and "installed" in the
target system
To create a test environment called "my_env" for a test you would run the following command from within the test script.
To create a test environment called "my_env" for a test you would run the following
command from within the test script.
```bash
# create a test environment for version 10 (default)
create_test_environment my_env
@@ -138,15 +195,22 @@ The test library provides the following functions for handling test environments
<br/>
### Test Objects
Test objects are all those elements that need to be mocked up in order to automate a test. The test library provides many functions for the creation and manipulation of these test objects. By far, the most useful test object that can be created by the test library are bundles. When creating a bundle using the test library, many other required test objects are created as a side effect, all things that are necessary for the bundle like, files, directories, manifests, packs, etc.
Test objects are all those elements that need to be mocked up in order to automate
a test. The test library provides many functions for the creation and manipulation
of these test objects. By far, the most useful test object that can be created by
the test library are bundles. When creating a bundle using the test library, many
other required test objects are created as a side effect, all things that are
necessary for the bundle like files, directories, manifests, packs, etc.
Use the following command to crate a bundle with two files called "test-bundle" in the "my_env" test environment.
Use the following command to create a bundle with two files called "test-bundle" in
the "my_env" test environment.
```bash
create_bundle -n test-bundle -f /foo/bar/test-file1,/baz/test-file2 my_env
```
By creating that bundle the following objects will also be created:
* A hashed directory (to be used for the /foo, /foo/bar and /baz directories)
* Two hashed files (test-file1 and test-file2)
* Two hashed files (test-file1 and test-file2, the content for these files is
randomly generated so hashes are different)
* A hashed tracking file for the bundle
* A bundle manifest
* A Manifest of Manifests (MoM)
@@ -157,28 +221,38 @@ Another example:
```bash
create_bundle -L -n another-bundle -d /some_dir -f /baz/test-file -l /test-link my_env
```
This bundle, besides having characteristics similar to the previous bundle will have this new characteristics:
This bundle, besides having characteristics similar to the previous bundle will
have this new characteristics:
* One directory without any file (/some_dir)
* One link (test-link), this will also generate another extra file to which the symbolic link is pointing to
* Since the -L flag was used, the bundle will not only be created in the directory for content download, but it will also be installed in the target file system, this is useful for tests that need a pre-installed bundle as pre-requisite
* One link (test-link), this will also generate another extra file to which the
symbolic link is pointing to
* Since the -L flag was used, the bundle will not only be created in the directory
for content download, but it will also be installed in the target file system, this
is useful for tests that need a pre-installed bundle as prerequisite
The following are some of the functions provided by the test library to create and handle test objects:
The following are some of the functions provided by the test library to create and
handle test objects:
* create_bundle: creates a bundle
* create_dir: creates a hashed directory
* create_file: creates a hashed file
* create_link: creates a hashed file and a hashed link pointing to the file
* create_tar: creates a tar of the specified object (manifest, full file, etc.)
* create_manifest: creates an empty manifest (with initial headers)
* add_to_manifest: adds the specified object (directory, file, or link) to the manifest, and creates/updates the manifest tar
* add_dependency_to_manifest: adds another bundle as dependency in the manifest, and creates/updates the manifest tar
* remove_from_manifest: removes an object from the manifest, and updates the manifest tar
* add_to_manifest: adds the specified object (directory, file, or link) to the
manifest, and creates/updates the manifest tar
* add_dependency_to_manifest: adds another bundle as dependency in the manifest,
and creates/updates the manifest tar
* remove_from_manifest: removes an object from the manifest, and updates the
manifest tar
* sign_manifest: signs the manifest using Swupd_Root.pem
* update_hashes_in_mom: after modifying manifests included in a MoM, this function can be run to update the manifest hashes in the MoM
* update_hashes_in_mom: after modifying manifests included in a MoM, this function
can be run to update the manifest hashes in the MoM
* get_hash_from_manifest: retrieves the hash of an object within a manifest
<br/>
## Assertions
The following assertions are included in the test library. These should be used to perform the test validations.
The following assertions are included in the test library. These should be used to
perform the test validations.
*assert_status_is*
passes if the exit status matches the provided one, fails otherwise
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle -f /usr/bin/test-file "$TEST_NAME"
@@ -13,17 +13,11 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add add bundle with bad hash in state dir" {
# since one of the files needed to install the bundle is already in the state/staged
# directory, in theory this one shuld be used instead of downloading it again...
# however since the hash of this file is wrong it should be deleted and re-downloaded
# since one of the files needed to install the bundle is already in the state/staged
# directory, in theory this one should be used instead of downloading it again...
# however since the hash of this file is wrong it should be deleted and re-downloaded
hash_before=$(sudo "$SWUPD" hashdump "$TEST_NAME"/state/staged/"$file_hash")
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle"
@@ -34,8 +28,6 @@ teardown() {
assert_not_equal "$hash_before" "$hash_after"
expected_output=$(cat <<-EOM
Starting download of remaining update content. This may take a while...
File /usr/bin/test-file was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle -f /usr/bin/file1 "$TEST_NAME"
@@ -22,12 +22,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add add bundle containing file with different hash from what is listed in manifest" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle"
@@ -38,8 +32,6 @@ teardown() {
assert_file_not_exists "$TEST_NAME"/target-dir/usr/bin/file1
expected_output=$(cat <<-EOM
Starting download of remaining update content. This may take a while...
File /usr/bin/file1 was not in a pack
.
Finishing download of update content...
Error: File content hash mismatch for $TEST_DIRNAME/state/staged/e6d85023c5e619eb43d5cfbfdbdec784afef5a82ffa54e8c93bda3e0883360a3 (bad server data?)
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle -f /usr/bin/test-file "$TEST_NAME"
@@ -14,12 +14,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add add bundle with invalid number of files in manifest" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle"
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
# create a bundle with a boot file (in /usr/lib/kernel)
@@ -10,12 +10,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add add bundle containing boot file" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle"
@@ -24,8 +18,6 @@ teardown() {
assert_file_exists "$TEST_NAME/target-dir/usr/lib/kernel/test-file"
expected_output=$(cat <<-EOM
Starting download of remaining update content. This may take a while...
File /usr/lib/kernel was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
# create a bundle with a boot file (in /usr/lib/kernel)
@@ -10,12 +10,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add add bundle containing boot file with boot update override" {
run sudo sh -c "$SWUPD bundle-add -b $SWUPD_OPTS test-bundle"
@@ -24,8 +18,6 @@ teardown() {
assert_file_exists "$TEST_NAME/target-dir/usr/lib/kernel/test-file"
expected_output=$(cat <<-EOM
Starting download of remaining update content. This may take a while...
File /usr/lib/kernel was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
+1 -9
View File
@@ -2,19 +2,13 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle -d /usr/bin/test "$TEST_NAME"
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add add bundle containing a directory" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle"
@@ -23,8 +17,6 @@ teardown() {
assert_dir_exists "$TEST_NAME/target-dir/usr/bin/test"
expected_output=$(cat <<-EOM
Starting download of remaining update content. This may take a while...
File /usr/bin/test was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
+2 -8
View File
@@ -2,24 +2,18 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -L -n test-bundle -f /usr/bin/file1 "$TEST_NAME"
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add an already existing bundle" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle"
assert_status_is 18
assert_status_is "$EBUNDLE_INSTALL"
expected_output=$(cat <<-EOM
Warning: Bundle "test-bundle" is already installed, skipping it...
1 bundle was already installed
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle1 -f /foo/test-file1 "$TEST_NAME"
@@ -14,12 +14,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add verify include support" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle1"
@@ -29,8 +23,6 @@ teardown() {
assert_file_exists "$TEST_NAME"/target-dir/bar/test-file2
expected_output=$(cat <<-EOM
Starting download of remaining update content. This may take a while...
File /bar was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
+1 -9
View File
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
test_files=/usr/bin/1,/usr/bin/2,/usr/bin/3,/usr/bin/4,/usr/bin/5,/usr/bin/6,/usr/bin/7,/usr/bin/8,/usr/bin/9,/usr/bin/10
@@ -11,12 +11,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add add multiple bundles" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle1 test-bundle2"
@@ -34,8 +28,6 @@ teardown() {
Extracting test-bundle2 pack for version 10
Starting download of remaining update content. This may take a while...
File /media was not in a pack
..
Finishing download of update content...
Installing bundle(s) files...
+17 -35
View File
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle1 -f /foo/test-file1 "$TEST_NAME"
@@ -10,12 +10,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
# ------------------------------------------
# Good Cases (all good bundles)
# ------------------------------------------
@@ -26,8 +20,6 @@ teardown() {
assert_status_is 0
expected_output=$(cat <<-EOM
Starting download of remaining update content. This may take a while...
File /foo was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
@@ -48,8 +40,6 @@ teardown() {
assert_status_is 0
expected_output=$(cat <<-EOM
Starting download of remaining update content. This may take a while...
File /baz was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
@@ -69,7 +59,7 @@ teardown() {
@test "bundle-add output: adding one bundle that is already added" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle2"
assert_status_is 18
assert_status_is "$EBUNDLE_INSTALL"
expected_output=$(cat <<-EOM
Warning: Bundle "test-bundle2" is already installed, skipping it...
1 bundle was already installed
@@ -82,7 +72,7 @@ teardown() {
@test "bundle-add output: adding one bundle that does not exist" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS fake-bundle"
assert_status_is 18
assert_status_is "$EBUNDLE_INSTALL"
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle" is invalid, skipping it...
Failed to install 1 of 1 bundles
@@ -95,7 +85,7 @@ teardown() {
@test "bundle-add output: adding multiple bundles, all invalid, both non existent" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS fake-bundle1 fake-bundle2"
assert_status_is 18
assert_status_is "$EBUNDLE_INSTALL"
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle2" is invalid, skipping it...
Warning: Bundle "fake-bundle1" is invalid, skipping it...
@@ -111,7 +101,7 @@ teardown() {
# for this test we need another bundle already installed
create_bundle -L -n test-bundle3 -f /baz/test-file3 "$TEST_NAME"
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle2 test-bundle3"
assert_status_is 18
assert_status_is "$EBUNDLE_INSTALL"
expected_output=$(cat <<-EOM
Warning: Bundle "test-bundle3" is already installed, skipping it...
Warning: Bundle "test-bundle2" is already installed, skipping it...
@@ -125,7 +115,7 @@ teardown() {
@test "bundle-add output: adding multiple bundles, all invalid, one already added, one invalid" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS fake-bundle test-bundle2"
assert_status_is 18
assert_status_is "$EBUNDLE_INSTALL"
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle" is invalid, skipping it...
Warning: Bundle "test-bundle2" is already installed, skipping it...
@@ -144,12 +134,10 @@ teardown() {
@test "bundle-add output: adding multiple bundles, one valid, one already added" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle1 test-bundle2"
assert_status_is 18
assert_status_is "$EBUNDLE_INSTALL"
expected_output=$(cat <<-EOM
Warning: Bundle "test-bundle2" is already installed, skipping it...
Starting download of remaining update content. This may take a while...
File /foo was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
@@ -166,12 +154,10 @@ teardown() {
@test "bundle-add output: adding multiple bundles, one valid, one non existent" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle1 fake-bundle"
assert_status_is 18
assert_status_is "$EBUNDLE_INSTALL"
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle" is invalid, skipping it...
Starting download of remaining update content. This may take a while...
File /foo was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
@@ -187,13 +173,11 @@ teardown() {
@test "bundle-add output: adding multiple bundles, one valid, one already added, one non existent" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle1 test-bundle2 fake-bundle"
assert_status_is 18
assert_status_is "$EBUNDLE_INSTALL"
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle" is invalid, skipping it...
Warning: Bundle "test-bundle2" is already installed, skipping it...
Starting download of remaining update content. This may take a while...
File /foo was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
@@ -207,7 +191,7 @@ teardown() {
}
@test "bundle-add output: adding multiple bundles, one valid, one with a missing file" {
@test "bundle-add output: adding multiple bundles, one valid, one invalid, one already installed, one with a missing file" {
# for this test we need a bundle with a missing file so it fails when
# trying to download the fullfile
@@ -216,24 +200,22 @@ teardown() {
file_hash=$(get_hash_from_manifest "$TEST_NAME"/web-dir/10/Manifest.test-bundle3 /baz/test-file3)
sudo rm "$TEST_NAME"/web-dir/10/files/"$file_hash"
sudo rm "$TEST_NAME"/web-dir/10/files/"$file_hash".tar
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle1 test-bundle3"
assert_status_is 18
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle1 test-bundle2 fake-bundle test-bundle3"
assert_status_is "$EBUNDLE_INSTALL"
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle" is invalid, skipping it...
Warning: Bundle "test-bundle2" is already installed, skipping it...
Starting download of remaining update content. This may take a while...
File /baz was not in a pack
.
Finishing download of update content...
Error for $file_hash tarfile extraction
EOM
)
assert_in_output "$expected_output"
assert_in_output "Starting download retry #1"
assert_in_output "Starting download retry #2"
assert_in_output "Starting download retry #3"
expected_output=$(cat <<-EOM
ERROR: Could not download some files from bundles, aborting bundle installation.
Failed to install 2 of 2 bundles
Error: Failed to download file /baz/test-file3 in verify_fix_path
Failed to install 3 of 3 bundles
1 bundle was already installed
EOM
)
assert_in_output "$expected_output"
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
# create a bundle with a boot file (in /usr/lib/kernel)
@@ -10,12 +10,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add add bundle with --no-scripts" {
run sudo sh -c "$SWUPD bundle-add --no-scripts $SWUPD_OPTS test-bundle"
@@ -23,8 +17,6 @@ teardown() {
assert_file_exists "$TEST_NAME/target-dir/usr/lib/kernel/test-file"
expected_output=$(cat <<-EOM
Starting download of remaining update content. This may take a while...
File /usr/lib/kernel was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle1 -f /foo/bar/test-file1 "$TEST_NAME"
@@ -22,20 +22,12 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-add verify_fix_path support" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle1"
assert_status_is 0
expected_output=$(cat <<-EOM
Starting download of remaining update content. This may take a while...
File /foo/bar/test-file1 was not in a pack
.
Finishing download of update content...
Installing bundle(s) files...
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle1 -f /foo "$TEST_NAME"
@@ -10,12 +10,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-list all bundles" {
run sudo sh -c "$SWUPD bundle-list $SWUPD_OPTS --all"
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle1 -f /foo "$TEST_NAME"
@@ -15,12 +15,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-list list bundle deps with flat included bundles" {
run sudo sh -c "$SWUPD bundle-list $SWUPD_OPTS --deps test-bundle1"
@@ -2,18 +2,6 @@
load "../testlib"
setup() {
create_test_environment "$TEST_NAME"
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-list list bundle deps with invalid bundle name" {
run sudo sh -c "$SWUPD bundle-list $SWUPD_OPTS --deps not-a-bundle"
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle1 -f /foo "$TEST_NAME"
@@ -15,12 +15,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-list list bundle deps with nested included bundles" {
run sudo sh -c "$SWUPD bundle-list $SWUPD_OPTS --deps test-bundle1"
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle1 -f /foo "$TEST_NAME"
@@ -15,16 +15,10 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-list list bundle has-deps with bundle not installed" {
run sudo sh -c "$SWUPD bundle-list $SWUPD_OPTS --has-dep test-bundle1"
assert_status_is 13
assert_status_is "$EBUNDLE_NOT_TRACKED"
expected_output=$(cat <<-EOM
Error: Bundle "test-bundle1" does not seem to be installed
try passing --all to check uninstalled bundles
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle1 -f /foo "$TEST_NAME"
@@ -15,12 +15,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-list list bundle has-deps with --all dependent packages" {
run sudo sh -c "$SWUPD bundle-list $SWUPD_OPTS --has-dep test-bundle1 --all"
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -L -n test-bundle1 -f /foo "$TEST_NAME"
@@ -15,12 +15,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-list list bundle has-deps with nested dependent bundles" {
run sudo sh -c "$SWUPD bundle-list $SWUPD_OPTS --has-dep test-bundle1"
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -n test-bundle1 -f /foo "$TEST_NAME"
@@ -10,12 +10,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-list list bundle deps with no included bundles" {
run sudo sh -c "$SWUPD bundle-list $SWUPD_OPTS --deps test-bundle1"
@@ -2,7 +2,7 @@
load "../testlib"
setup() {
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -L -n test-bundle1 -f /foo "$TEST_NAME"
@@ -10,12 +10,6 @@ setup() {
}
teardown() {
destroy_test_environment "$TEST_NAME"
}
@test "bundle-list list bundle has-deps with no dependent bundles" {
run sudo sh -c "$SWUPD bundle-list $SWUPD_OPTS --has-dep test-bundle1"
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env bats
load "../testlib"
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -L -n test-bundle -f /usr/lib/kernel/test-file "$TEST_NAME"
}
@test "bundle-remove remove bundle containing a boot file" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle"
assert_status_is 0
assert_file_not_exists "$TEST_NAME"/target-dir/usr/lib/kernel/testfile
expected_output=$(cat <<-EOM
Deleting bundle files...
Total deleted files: 2
Successfully removed 1 bundle
EOM
)
assert_in_output "$expected_output"
}
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env bats
load "../testlib"
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -L -n test-bundle1 -f /test-file1 "$TEST_NAME"
}
@test "bundle-remove remove bundle containing a file" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle1"
assert_status_is 0
assert_file_not_exists "$TEST_NAME"/target-dir/test-file1
expected_output=$(cat <<-EOM
Deleting bundle files...
Total deleted files: 2
Successfully removed 1 bundle
EOM
)
assert_in_output "$expected_output"
}
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bats
load "../testlib"
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -L -n test-bundle1 -f /test-file1 "$TEST_NAME"
create_bundle -L -n test-bundle2 -f /test-file2 "$TEST_NAME"
create_bundle -L -n test-bundle3 -f /test-file3 "$TEST_NAME"
# add dependencies
add_dependency_to_manifest "$TEST_NAME"/web-dir/10/Manifest.test-bundle2 test-bundle1
add_dependency_to_manifest "$TEST_NAME"/web-dir/10/Manifest.test-bundle3 test-bundle2
update_hashes_in_mom "$TEST_NAME"/web-dir/10/Manifest.MoM
}
@test "bundle-remove remove bundle with nested dependent bundles" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle1"
assert_status_is "$EBUNDLE_REMOVE"
assert_file_exists "$TEST_NAME"/target-dir/test-file1
assert_file_exists "$TEST_NAME"/target-dir/test-file2
assert_file_exists "$TEST_NAME"/target-dir/test-file3
expected_output=$(cat <<-EOM
Error: bundle requested to be removed is required by the following bundles:
format:
# * is-required-by
# |-- is-required-by
# * is-also-required-by
# ...
* test-bundle2
|-- test-bundle3
Failed to remove 1 of 1 bundles
EOM
)
assert_in_output "$expected_output"
}
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bats
load "../testlib"
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -L -n test-bundle1 -f /foo/test-file1 "$TEST_NAME"
create_bundle -L -n test-bundle2 -f /bar/test-file2 "$TEST_NAME"
# add test-bundle1 as dependency of test-bundle2
add_dependency_to_manifest "$TEST_NAME"/web-dir/10/Manifest.test-bundle2 test-bundle1
update_hashes_in_mom "$TEST_NAME"/web-dir/10/Manifest.MoM
}
@test "bundle-remove remove bundle containing a file" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle1"
assert_status_is "$EBUNDLE_REMOVE"
assert_file_exists "$TEST_NAME"/target-dir/foo/test-file1
assert_file_exists "$TEST_NAME"/target-dir/bar/test-file2
expected_output=$(cat <<-EOM
Error: bundle requested to be removed is required by the following bundles:
format:
# * is-required-by
# |-- is-required-by
# * is-also-required-by
# ...
* test-bundle2
Failed to remove 1 of 1 bundles
EOM
)
assert_in_output "$expected_output"
}
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env bats
load "../testlib"
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -L -n test-bundle1 -f /foo/file1 "$TEST_NAME"
create_bundle -L -n test-bundle2 -f /bar/file2 "$TEST_NAME"
create_bundle -L -n test-bundle3 -f /file3 "$TEST_NAME"
}
@test "bundle-remove remove multiple bundles each containing a file" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle1 test-bundle2 test-bundle3"
assert_status_is 0
assert_file_not_exists "$TEST_NAME"/target-dir/foo/file1
assert_file_not_exists "$TEST_NAME"/target-dir/bar/file2
assert_file_not_exists "$TEST_NAME"/target-dir/file3
assert_file_not_exists "$TEST_NAME"/target-dir/usr/share/clear/bundles/test-bundle1
assert_file_not_exists "$TEST_NAME"/target-dir/usr/share/clear/bundles/test-bundle2
assert_file_not_exists "$TEST_NAME"/target-dir/usr/share/clear/bundles/test-bundle3
assert_dir_not_exists "$TEST_NAME"/target-dir/foo
assert_dir_not_exists "$TEST_NAME"/target-dir/bar
expected_output=$(cat <<-EOM
Removing bundle: test-bundle1
Deleting bundle files...
Total deleted files: 2
Removing bundle: test-bundle2
Deleting bundle files...
Total deleted files: 2
Removing bundle: test-bundle3
Deleting bundle files...
Total deleted files: 2
Successfully removed 3 bundles
EOM
)
assert_in_output "$expected_output"
}
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env bats
load "../testlib"
@test "bundle-remove remove bundle os-core" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS os-core"
assert_status_is "$EBUNDLE_NOT_TRACKED"
assert_file_exists "$TEST_NAME"/target-dir/usr/bin/core
expected_output=$(cat <<-EOM
Warning: Bundle "os-core" not allowed to be removed
Failed to remove 1 of 1 bundles
EOM
)
assert_in_output "$expected_output"
}
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/env bats
load "../testlib"
@test "bundle-remove ensure bundle name is passed as an option" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS"
assert_status_is "$EINVALID_OPTION"
assert_in_output "error: missing bundle(s) to be removed"
}
+114
View File
@@ -0,0 +1,114 @@
#!/usr/bin/env bats
load "../testlib"
test_setup() {
create_test_environment "$TEST_NAME"
create_bundle -L -n test-bundle1 -f /foo/test-file1 "$TEST_NAME"
create_bundle -n test-bundle2 -f /bar/test-file2 "$TEST_NAME"
}
# ------------------------------------------
# Good Cases (all good bundles)
# ------------------------------------------
@test "bundle-remove output: removing one bundle" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle1"
assert_status_is 0
expected_output=$(cat <<-EOM
Deleting bundle files...
Total deleted files: 2
Successfully removed 1 bundle
EOM
)
assert_in_output "$expected_output"
}
@test "bundle-remove output: removing multiple bundles" {
# for this test we need another installed bundle
create_bundle -L -n test-bundle3 -f /baz/test-file3 "$TEST_NAME"
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle1 test-bundle3"
assert_status_is 0
expected_output=$(cat <<-EOM
Removing bundle: test-bundle1
Deleting bundle files...
Total deleted files: 2
Removing bundle: test-bundle3
Deleting bundle files...
Total deleted files: 2
Successfully removed 2 bundles
EOM
)
assert_in_output "$expected_output"
}
# ------------------------------------------
# Bad Cases (all bad bundles)
# ------------------------------------------
@test "bundle-remove output: removing one bundle that is not added" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle2"
assert_status_is "$EBUNDLE_NOT_TRACKED"
expected_output=$(cat <<-EOM
Warning: Bundle "test-bundle2" is not installed, skipping it...
Failed to remove 1 of 1 bundles
EOM
)
assert_in_output "$expected_output"
}
@test "bundle-remove output: removing one bundle that does not exist" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS fake-bundle"
assert_status_is "$EBUNDLE_NOT_TRACKED"
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle" is not installed, skipping it...
Failed to remove 1 of 1 bundles
EOM
)
assert_in_output "$expected_output"
}
@test "bundle-remove output: removing multiple bundles, all invalid, one non existent, one already removed" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS fake-bundle1 test-bundle2"
assert_status_is "$EBUNDLE_NOT_TRACKED"
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle1" is not installed, skipping it...
Warning: Bundle "test-bundle2" is not installed, skipping it...
Failed to remove 2 of 2 bundles
EOM
)
assert_in_output "$expected_output"
}
# ------------------------------------------
# Partial Cases (at least one good bundle)
# ------------------------------------------
@test "bundle-remove output: removing multiple bundles, one valid, one already removed, one non existent" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle2 fake-bundle test-bundle1"
assert_status_is "$EBUNDLE_NOT_TRACKED"
expected_output=$(cat <<-EOM
Warning: Bundle "test-bundle2" is not installed, skipping it...
Warning: Bundle "fake-bundle" is not installed, skipping it...
Removing bundle: test-bundle1
Deleting bundle files...
Total deleted files: 2
Failed to remove 2 of 3 bundles
EOM
)
assert_in_output "$expected_output"
}
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env bats
load "../testlib"
test_setup() {
create_test_environment "$TEST_NAME"
# create a new version 100
create_test_environment "$TEST_NAME" 100
# this will leave both latest version and current version as 100
# so change current version back to 10
set_current_version "$TEST_NAME" 10
}
@test "check-update with a new version available" {
run sudo sh -c "$SWUPD check-update $SWUPD_OPTS_NO_CERT"
assert_status_is 0
expected_output=$(cat <<-EOM
Current OS version: 10
There is a new OS version available: 100
EOM
)
assert_in_output "$expected_output"
}
@@ -0,0 +1,19 @@
#!/usr/bin/env bats
load "../testlib"
test_setup() {
create_test_environment "$TEST_NAME"
# remove the version from web-dir so there is no "server" data
sudo rm -rf "$TEST_NAME"/web-dir/version
}
@test "check-update with no server version file available" {
run sudo sh -c "$SWUPD check-update $SWUPD_OPTS_NO_CERT"
assert_status_is_not 0
assert_in_output "Error: server does not report any version"
}
@@ -0,0 +1,19 @@
#!/usr/bin/env bats
load "../testlib"
test_setup() {
create_test_environment "$TEST_NAME"
# remove os-release file from target-dir so no current version can be determined
sudo rm "$TEST_NAME"/target-dir/usr/lib/os-release
}
@test "check-update with no target version file available" {
run sudo sh -c "$SWUPD check-update $SWUPD_OPTS_NO_CERT"
assert_status_is_not 0
assert_in_output "Unable to determine current OS version"
}
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env bats
load "../testlib"
server_pid=""
port=""
THEME_DIRNAME="$FUNC_DIR/checkupdate_v2"
test_teardown() {
echo "terminating web server..." >&3
kill "$server_pid" >&3
destroy_test_environment "$TEST_NAME"
}
@test "check-update with a slow server" {
# Pre-req: create a web server that can serve as a slow content download server
echo "starting web server..." >&3
start_web_server
slow_opts="-p $TEST_NAME/target-dir -F staging -u http://localhost:$port/"
# test
run sudo sh -c "$SWUPD check-update $slow_opts"
assert_status_is 0
expected_output=$(cat <<-EOM
Current OS version: 10
There is a new OS version available: 99990
EOM
)
assert_in_output "$expected_output"
}
start_web_server() {
for i in {8080..8180}; do
"$THEME_DIRNAME"/server.py $i &
sleep .5
server_pid=$!
if [ -d /proc/$server_pid ]; then
port=$i
break
fi
done
# wait until server becomes available by expecting a successful curl
for i in $(seq 1 10); do
flag=true
curl http://localhost:"$port"/ || flag=false
if [ "$flag" == false ]; then
sleep .5
continue
else
echo "responding"
break
fi
done
}
@@ -0,0 +1,16 @@
#!/usr/bin/env bats
load "../testlib"
@test "check-update with no new version available" {
run sudo sh -c "$SWUPD check-update $SWUPD_OPTS_NO_CERT"
assert_status_is 1
expected_output=$(cat <<-EOM
Current OS version: 10
There are no updates available
EOM
)
assert_in_output "$expected_output"
}
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env python3
import http.server as server
import sys
import time
class SlowResponse(server.BaseHTTPRequestHandler):
"""Handler that returns data with a set delay between writes"""
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
response = "99990"
delay = 0.00001 # seconds
for c in response:
self.wfile.write(str.encode(c))
time.sleep(delay)
if __name__ == '__main__':
print(sys.argv)
addr = ('', int(sys.argv[1]))
httpd = server.HTTPServer(addr, SlowResponse)
httpd.serve_forever()
+343 -114
View File
@@ -8,13 +8,38 @@ export FUNC_DIR
export SWUPD_DIR="$FUNC_DIR/../.."
export SWUPD="$SWUPD_DIR/swupd"
# Error codes
export EBUNDLE_MISMATCH=2 # at least one local bundle mismatches from MoM
export EBUNDLE_REMOVE=3 # cannot delete local bundle filename
export EMOM_NOTFOUND=4 # MoM cannot be loaded into memory (this could imply network issue)
export ETYPE_CHANGED_FILE_RM=5 # do_staging() couldn't delete a file which must be deleted
export EDIR_OVERWRITE=6 # do_staging() couldn't overwrite a directory
export EDOTFILE_WRITE=7 # do_staging() couldn't create a dotfile
export ERECURSE_MANIFEST=8 # error while recursing a manifest
export ELOCK_FILE=9 # cannot get the lock
export ECURL_INIT=11 # cannot initialize curl agent
export EINIT_GLOBALS=12 # cannot initialize globals
export EBUNDLE_NOT_TRACKED=13 # bundle is not tracked on the system
export EMANIFEST_LOAD=14 # cannot load manifest into memory
export EINVALID_OPTION=15 # invalid command option
export ENOSWUPDSERVER=16 # no net connection to swupd server
export EFULLDOWNLOAD=17 # full_download problem
export ENET404=404 # download 404'd
export EBUNDLE_INSTALL=18 # Cannot install bundles
export EREQUIRED_DIRS=19 # Cannot create required dirs
export ECURRENT_VERSION=20 # Cannot determine current OS version
export ESIGNATURE=21 # Cannot initialize signature verification
export EBADTIME=22 # System time is bad
export EDOWNLOADPACKS=23 # Pack download failed
export EBADCERT=24 # unable to verify server SSL certificate
generate_random_content() {
local bottom_range=5
local top_range=100
local bottom_range=${1:-5}
local top_range=${2:-100}
local range=$((top_range - bottom_range + 1))
local number_of_lines=$((RANDOM%range))
local number_of_lines=$((RANDOM%range+$bottom_range))
< /dev/urandom tr -dc 'a-zA-Z0-9-_!@#$%^&*()_+{}|:<>?=' | fold -w 100 | head -n $number_of_lines
}
@@ -30,12 +55,27 @@ generate_random_name() {
}
terminate() {
# since the library could be sourced and run from an interactive shell
# not only from a script, we cannot use exit in interactive shells since it
# would terminate the shell, so we are using parameter expansion with a fake
# parameter "param" to force an error when running interactive shells
local msg=$1
local param
case "$-" in
*i*) : ${param:?"$msg, exiting..."} ;;
*) echo "$msg, exiting..."
exit 1;;
esac
}
validate_path() {
local path=$1
if [ -z "$path" ] || [ ! -d "$path" ]; then
echo "Please provide a valid path"
return 1
terminate "Please provide a valid path"
fi
}
@@ -44,8 +84,7 @@ validate_item() {
local vfile=$1
if [ -z "$vfile" ] || [ ! -e "$vfile" ]; then
echo "Please provide a valid file"
return 1
terminate "Please provide a valid file"
fi
}
@@ -54,12 +93,27 @@ validate_param() {
local param=$1
if [ -z "$param" ]; then
echo "Mandatory parameter missing"
return 1
terminate "Mandatory parameter missing"
fi
}
# Writes to a file that is owned by root
# Parameters:
# - "-a": if set, the text will be appeneded to the file,
# otherwise will be overwritten
# - FILE: the path to the file to write to
# - STREAM: the content to be written
write_to_protected_file() {
local arg
[ "$1" = "-a" ] && { arg=-a ; shift ; }
local file=${1?Missing output file in write_to_protected_file}
shift
printf "$@" | sudo tee $arg "$file" >/dev/null
}
# Exports environment variables that are dependent on the test environment
# Parameters:
# - ENV_NAME: the name of the test environment
@@ -68,9 +122,10 @@ set_env_variables() {
local env_name=$1
local path
validate_path "$env_name"
path=$(dirname "$(realpath "env_name")")
path=$(dirname "$(realpath "$env_name")")
export SWUPD_OPTS="-S $path/$env_name/state -p $path/$env_name/target-dir -F staging -u file://$path/$env_name/web-dir -C $FUNC_DIR/Swupd_Root.pem -I"
export SWUPD_OPTS_NO_CERT="-S $path/$env_name/state -p $path/$env_name/target-dir -F staging -u file://$path/$env_name/web-dir"
export TEST_DIRNAME="$path"/"$env_name"
}
@@ -122,9 +177,10 @@ create_file() {
# Creates a symbolic link with a hashed name to the specified file in the specified path.
# If no existing file is specified to point to, a new file will be created and pointed to
# by the link.
# If a file is provided but doesn't exist, then a dangling file will be created
# Parameters:
# - PATH: the path where the symbolic link will be created
# - FILE: the path to the file to point to
# - FILE: the path to the file to point to
create_link() {
local path=$1
@@ -135,26 +191,31 @@ create_link() {
# if no file is specified, create one
if [ -z "$pfile" ]; then
pfile=$(create_file "$path")
else
validate_item "$pfile"
fi
sudo ln -rs "$pfile" "$path"/testlink
hashed_name=$(sudo "$SWUPD" hashdump "$path"/testlink 2> /dev/null)
sudo mv "$path"/testlink "$path"/"$hashed_name"
create_tar "$path"/"$hashed_name"
create_tar --skip-validation "$path"/"$hashed_name"
echo "$path/$hashed_name"
}
# Creates a tar for the specified item in the same location
# Parameters:
# - --skip-validation: if this flag is set (as first parameter) the other parameter
# is not validated, so use this option carefully
# - ITEM: the relative path to the item (file, directory, link, manifest)
create_tar() {
local item=$1
local path
local item_name
validate_item "$item"
local skip_param_validation=false
[ "$1" = "--skip-validation" ] && { skip_param_validation=true ; shift ; }
local item=$1
if [ "$skip_param_validation" = false ]; then
validate_item "$item"
fi
path=$(dirname "$(realpath "$item")")
item_name=$(basename "$item")
@@ -179,28 +240,29 @@ create_manifest() {
validate_path "$path"
validate_param "$name"
version=$(basename "$path")
echo -e "MANIFEST\\t3" | sudo tee "$path"/Manifest."$name" > /dev/null
echo -e "version:\\t$version" | sudo tee -a "$path"/Manifest."$name" > /dev/null
echo -e "previous:\\t0" | sudo tee -a "$path"/Manifest."$name" > /dev/null
echo -e "filecount:\\t0" | sudo tee -a "$path"/Manifest."$name" > /dev/null
echo -e "timestamp:\\t$(date +"%s")" | sudo tee -a "$path"/Manifest."$name" > /dev/null
echo -e "contentsize:\\t0" | sudo tee -a "$path"/Manifest."$name" > /dev/null
echo "" | sudo tee -a "$path"/Manifest."$name" > /dev/null
version=$(basename "$path")
{
printf 'MANIFEST\t1\n'
printf 'version:\t%s\n' "$version"
printf 'previous:\t0\n'
printf 'filecount:\t0\n'
printf 'timestamp:\t%s\n' "$(date +"%s")"
printf 'contentsize:\t0\n'
printf '\n'
} | sudo tee "$path"/Manifest."$name" > /dev/null
echo "$path/Manifest.$name"
}
# Adds the specified item to an existing bundle manifest
# Parameters:
# - --skip-validation: if this flag is set (as first parameter) the other parameters
# are not validated, so use this option carefully
# - MANIFEST: the relative path to the manifest file
# - ITEM: the relative path to the item (file, directory, symlink) to be added
# - ITEM_PATH: the absolute path of the item in the target system when installed
add_to_manifest() {
local manifest=$1
local item=$2
local item_path=$3
local item_type
local item_size
local name
@@ -210,15 +272,23 @@ add_to_manifest() {
local linked_file
local boot_type="."
local file_path
validate_item "$manifest"
validate_item "$item"
validate_param "$item_path"
item_size=$(du -b "$item" | cut -f1)
local skip_param_validation=false
[ "$1" = "--skip-validation" ] && { skip_param_validation=true ; shift ; }
local manifest=$1
local item=$2
local item_path=$3
if [ "$skip_param_validation" = false ]; then
validate_item "$manifest"
validate_item "$item"
validate_param "$item_path"
fi
item_size=$(stat -c "%s" "$item")
name=$(basename "$item")
version=$(basename "$(dirname "$manifest")")
# add to filecount
filecount=$(sudo cat "$manifest" | grep filecount | awk '{ print $2 }')
filecount=$(awk '/filecount/ { print $2}' "$manifest")
filecount=$((filecount + 1))
sudo sed -i "s/filecount:.*/filecount:\\t$filecount/" "$manifest"
# add to contentsize
@@ -236,14 +306,16 @@ add_to_manifest() {
elif [ -L "$item" ]; then
item_type=L
# when adding a link to a bundle, we need to make sure we add
# its associated file too
# its associated file too, unless it is a dangling link
linked_file=$(readlink "$item")
if [ ! "$(sudo cat "$manifest" | grep "$linked_file")" ]; then
file_path="$(dirname "$item_path")"
if [ "$file_path" = "/" ]; then
file_path=""
if [ -e "$(dirname "$item")"/"$linked_file" ]; then
if [ ! "$(sudo cat "$manifest" | grep "$linked_file")" ]; then
file_path="$(dirname "$item_path")"
if [ "$file_path" = "/" ]; then
file_path=""
fi
add_to_manifest "$manifest" "$(dirname "$item")"/"$linked_file" "$file_path"/"$(generate_random_name test-file-)"
fi
add_to_manifest "$manifest" "$(dirname "$item")"/"$linked_file" "$file_path"/"$(generate_random_name test-file-)"
fi
elif [ -f "$item" ]; then
item_type=F
@@ -256,10 +328,15 @@ add_to_manifest() {
fi
sudo sed -i "s/contentsize:.*/contentsize:\\t$contentsize/" "$manifest"
# add to manifest content
echo -e "$item_type.$boot_type.\\t$name\\t$version\\t$item_path" | sudo tee -a "$manifest" > /dev/null
write_to_protected_file -a "$manifest" "$item_type.$boot_type.\\t$name\\t$version\\t$item_path\\n"
# If a manifest tar already exists for that manifest, renew the manifest tar
sudo rm -f "$manifest".tar
create_tar "$manifest"
# if the modified manifest is the MoM, sign it again since it has changed
if [ "$(basename "$manifest")" = Manifest.MoM ]; then
sudo rm -f "$manifest".sig
sign_manifest "$manifest"
fi
}
@@ -305,6 +382,11 @@ remove_from_manifest() {
# If a manifest tar already exists for that manifest, renew the manifest tar
sudo rm -f "$manifest".tar
create_tar "$manifest"
# if the modified manifest is the MoM, sign it again
if [ "$(basename "$manifest")" = Manifest.MoM ]; then
sudo rm -f "$manifest".sig
sign_manifest "$manifest"
fi
}
@@ -328,6 +410,9 @@ update_hashes_in_mom() {
remove_from_manifest "$manifest" $bundle
add_to_manifest "$manifest" "$path"/Manifest.$bundle $bundle
done
# since the MoM has changed, sign it again
sudo rm -f "$manifest".sig
sign_manifest "$manifest"
else
echo "The provided manifest is not the MoM"
return 1
@@ -366,6 +451,34 @@ get_hash_from_manifest() {
}
# Sets the current version of the target system to the desired version
# Parameters:
# - ENVIRONMENT_NAME: the name of the test environmnt to act upon
# - NEW_VERSION: the version for the target to be set to
set_current_version() {
local env_name=$1
local new_version=$2
validate_path "$env_name"
sudo sed -i "s/VERSION_ID=.*/VERSION_ID=$new_version/" "$env_name"/target-dir/usr/lib/os-release
}
# Sets the latest version on the "server" to the desired version
# Parameters:
# - ENVIRONMENT_NAME: the name of the test environmnt to act upon
# - NEW_VERSION: the version for the target to be set to
set_latest_version() {
local env_name=$1
local new_version=$2
validate_path "$env_name"
write_to_protected_file "$env_name"/web-dir/version/formatstaging/latest "$new_version"
}
# Creates a test environment with the basic directory structure needed to
# validate the swupd client
# Parameters:
@@ -381,30 +494,28 @@ create_test_environment() {
# create all the files and directories needed
# web-dir files & dirs
sudo mkdir -p "$env_name"/web-dir/version/formatstaging
echo "$version" | sudo tee "$env_name"/web-dir/version/formatstaging/latest > /dev/null
write_to_protected_file "$env_name"/web-dir/version/formatstaging/latest "$version"
sudo mkdir -p "$env_name"/web-dir/"$version"/files
sudo mkdir -p "$env_name"/web-dir/"$version"/staged
mom=$(create_manifest "$env_name"/web-dir/"$version" MoM)
sign_manifest "$mom"
# target-dir files & dirs
sudo mkdir -p "$env_name"/target-dir/usr/lib
echo "NAME=\"Clear Linux Software for Intel Architecture\"" | sudo tee "$env_name"/target-dir/usr/lib/os-release > /dev/null
echo "VERSION=1" | sudo tee -a "$env_name"/target-dir/usr/lib/os-release > /dev/null
echo "ID=clear-linux-os" | sudo tee -a "$env_name"/target-dir/usr/lib/os-release > /dev/null
echo "VERSION_ID=$version" | sudo tee -a "$env_name"/target-dir/usr/lib/os-release > /dev/null
echo "PRETTY_NAME=\"Clear Linux Software for Intel Architecture\"" | sudo tee -a "$env_name"/target-dir/usr/lib/os-release > /dev/null
echo "ANSI_COLOR=\"1;35\"" | sudo tee -a "$env_name"/target-dir/usr/lib/os-release > /dev/null
echo "HOME_URL=\"https://clearlinux.org\"" | sudo tee -a "$env_name"/target-dir/usr/lib/os-release > /dev/null
echo "SUPPORT_URL=\"https://clearlinux.org\"" | sudo tee -a "$env_name"/target-dir/usr/lib/os-release > /dev/null
echo "BUG_REPORT_URL=\"https://bugs.clearlinux.org/jira\"" | sudo tee -a "$env_name"/target-dir/usr/lib/os-release > /dev/null
{
printf 'NAME="Clear Linux Software for Intel Architecture"\n'
printf 'VERSION=1\n'
printf 'ID=clear-linux-os\n'
printf 'VERSION_ID=%s\n' "$version"
printf 'PRETTY_NAME="Clear Linux Software for Intel Architecture"\n'
printf 'ANSI_COLOR="1;35"\n'
printf 'HOME_URL="https://clearlinux.org"\n'
printf 'SUPPORT_URL="https://clearlinux.org"\n'
printf 'BUG_REPORT_URL="https://bugs.clearlinux.org/jira"\n'
} | sudo tee "$env_name"/target-dir/usr/lib/os-release > /dev/null
sudo mkdir -p "$env_name"/target-dir/usr/share/clear/bundles
# state files & dirs
sudo mkdir -p "$env_name"/state/staged
sudo mkdir -p "$env_name"/state/download
sudo mkdir -p "$env_name"/state/delta
sudo mkdir -p "$env_name"/state/telemetry
sudo mkdir -p "$env_name"/state/{staged,download,delta,telemetry}
sudo chmod -R 0700 "$env_name"/state
# export environment variables that are dependent of the test env
@@ -422,21 +533,17 @@ create_test_environment() {
destroy_test_environment() {
local env_name=$1
local deletable=true
validate_path "$env_name"
# since the action to be performed is very destructive, at least
# make sure the directory does look like a test environment
for var in "state" "target-dir" "web-dir"; do
if [ ! -d "$env_name/$var" ]; then
deletable=false
echo "The name provided doesn't seem to be a valid test environment"
return 1
fi
done
if [ "$deletable" = true ]; then
sudo rm -rf "$env_name"
else
echo "The name provided doesn't seem to be a valid test environment"
return 1
fi
sudo rm -rf "$env_name"
}
@@ -444,27 +551,35 @@ destroy_test_environment() {
create_bundle() {
cb_usage() {
echo "Usage:"
echo -e "\\tcreate_bundle [-L] [-n] <bundle_name> [-v] <version> [-d] <list of dirs> [-f] <list of files> [-l] <list of links> ENV_NAME"
echo "Options:"
echo -e "\\t-L\\tWhen the flag is selected the bundle will be 'installed' in the target-dir, otherwise it will only be created in web-dir"
echo -e "\\t-n\\tThe name of the bundle to be created, if not specified a name will be autogenerated"
echo -e "\\t-v\\tThe version for the bundle, if non selected version 10 will be used"
echo -e "\\t-d\\tComma-separated list of directories to be included in the bundle"
echo -e "\\t-f\\tComma-separated list of files to be created and included in the bundle"
echo -e "\\t-l\\tComma-separated list of symlinks to be created and included in the bundle,"
echo "Notes:"
echo -e "\\t- if no option is selected, a minimal bundle will be created with only one directory"
echo -e "\\t- for every symlink created a related file will be created and added to the bundle as well"
echo -e "\\t- if the '-f' or '-l' options are used, and the directories where the files live don't exist,"
echo -e "\\t they will be automatically created and added to the bundle for each file"
echo -e "\\nExample of usage:\\n"
echo -e "\\tThe following command will create a bundle named 'test-bundle', which will include three directories,"
echo -e "\\tfour files, and one symlink (they will be added to the bundle's manifest), all these resources will also"
echo -e "\\tbe tarred. The bundle's manifest will be added to the MoM."
echo -e "\\n\\tcreate_bundle -n test-bundle -f /usr/bin/test-1,/usr/bin/test-2,/etc/systemd/test-3 -l /etc/test-link my_test_env"
echo -e "\\n"
echo $(cat <<-EOF
Usage:
create_bundle [-L] [-n] <bundle_name> [-v] <version> [-d] <list of dirs> [-f] <list of files> [-l] <list of links> ENV_NAME
Options:
-L When the flag is selected the bundle will be 'installed' in the target-dir, otherwise it will only be created in web-dir
-n The name of the bundle to be created, if not specified a name will be autogenerated
-v The version for the bundle, if non selected version 10 will be used
-d Comma-separated list of directories to be included in the bundle
-f Comma-separated list of files to be created and included in the bundle
-l Comma-separated list of symlinks to be created and included in the bundle
-b Comma-separated list of dangling (broken) symlinks to be created and included in the bundle
Notes:
- if no option is selected, a minimal bundle will be created with only one directory
- for every symlink created a related file will be created and added to the bundle as well (except for dangling links)
- if the '-f' or '-l' options are used, and the directories where the files live don't exist,
they will be automatically created and added to the bundle for each file
Example of usage:
The following command will create a bundle named 'test-bundle', which will include three directories,
four files, and one symlink (they will be added to the bundle's manifest), all these resources will also
be tarred. The manifest will be added to the MoM.
create_bundle -n test-bundle -f /usr/bin/test-1,/usr/bin/test-2,/etc/systemd/test-3 -l /etc/test-link my_test_env
EOF
)
}
local OPTIND
@@ -472,6 +587,7 @@ create_bundle() {
local dir_list
local file_list
local link_list
local dangling_link_list
local version
local bundle_name
local env_name
@@ -481,14 +597,12 @@ create_bundle() {
local local_bundle=false
set -f # turn off globbing
while getopts :v:d:f:l:n:L opt; do
while getopts :v:d:f:l:b:n:L opt; do
case "$opt" in
d) IFS=,
read -r -a dir_list <<< "$OPTARG" ;;
f) IFS=,
read -r -a file_list <<< "$OPTARG" ;;
l) IFS=,
read -r -a link_list <<< "$OPTARG" ;;
d) IFS=, read -r -a dir_list <<< "$OPTARG" ;;
f) IFS=, read -r -a file_list <<< "$OPTARG" ;;
l) IFS=, read -r -a link_list <<< "$OPTARG" ;;
b) IFS=, read -r -a dangling_link_list <<< "$OPTARG" ;;
n) bundle_name="$OPTARG" ;;
v) version="$OPTARG" ;;
L) local_bundle=true ;;
@@ -498,11 +612,11 @@ create_bundle() {
done
set +f # turn globbing back on
env_name=${@:$OPTIND:1}
# set default values
bundle_name=${bundle_name:-$(generate_random_name test-bundle-)}
version=${version:-10}
if [ -z "$dir_list" ] && [ -z "$file_list" ] && [ -z "$link_list" ] ; then
if [ -z "$dir_list" ] && [ -z "$file_list" ] && [ -z "$link_list" ] && [ -z "$dangling_link_list" ] ; then
# if nothing was specified to be created, at least create
# one directory which is the bare minimum for a bundle
dir_list=(/usr/bin)
@@ -512,16 +626,16 @@ create_bundle() {
file_list+=(/usr/share/clear/bundles/"$bundle_name")
# get useful paths
if [ "$(validate_path "$env_name")" ]; then
echo "Please specify a valid environment"
return 1
fi
validate_path "$env_name"
version_path="$env_name"/web-dir/"$version"
files_path="$version_path"/files
target_path="$env_name"/target-dir
# 1) create the initial manifest
manifest=$(create_manifest "$version_path" "$bundle_name")
if [ "$DEBUG" == true ]; then
echo "Manifest -> $manifest"
fi
# 2) Create one directory for the bundle and add it the requested
# times to the manifest.
@@ -529,6 +643,9 @@ create_bundle() {
# hashes in directories vary depending on owner and permissions,
# so one directory hash can be reused many times
bundle_dir=$(create_dir "$files_path")
if [ "$DEBUG" == true ]; then
echo "Directory -> $bundle_dir"
fi
# Create a zero pack for the bundle and add the directory to it
sudo tar -cf "$version_path"/pack-"$bundle_name"-from-0.tar --exclude="$bundle_dir"/* "$bundle_dir"
for val in "${dir_list[@]}"; do
@@ -558,6 +675,9 @@ create_bundle() {
done
fi
bundle_file=$(create_file "$files_path")
if [ "$DEBUG" == true ]; then
echo "file -> $bundle_file"
fi
add_to_manifest "$manifest" "$bundle_file" "$val"
# Add the file to the zero pack of the bundle
sudo tar -rf "$version_path"/pack-"$bundle_name"-from-0.tar "$bundle_file"
@@ -586,24 +706,58 @@ create_bundle() {
# Add the file pointed by the link to the zero pack of the bundle
pfile=$(basename "$(readlink -f "$bundle_link")")
sudo tar -rf "$version_path"/pack-"$bundle_name"-from-0.tar "$files_path"/"$pfile"
if [ "$DEBUG" == true ]; then
echo "link -> $bundle_link"
echo "file pointed to -> $(readlink -f "$bundle_link")"
fi
if [ "$local_bundle" = true ]; then
sudo mkdir -p "$target_path$(dirname "$val")"
# if local_bundle is enabled copy the link to target-dir but also
# copy the file it points to
pfile_path=$(sudo cat "$manifest" | grep "$(basename "$pfile")" | awk '{ print $4 }')
pfile_path=$(awk "/$(basename $pfile)/"'{ print $4 }' "$manifest")
sudo cp "$files_path"/"$pfile" "$target_path$pfile_path"
sudo ln -rs "$target_path$pfile_path" "$target_path$val"
fi
done
# 5) Add the bundle to the MoM
# 5) Create the requested dangling link(s) in the bundle
for val in "${dangling_link_list[@]}"; do
# if the directory the link is doesn't exist,
# add it to the bundle (except if the directory is "/")
fdir=$(dirname "$val")
if [ "$fdir" != "/" ]; then
if [ ! "$(sudo cat "$manifest" | grep -x "D\\.\\.\\..*$fdir")" ]; then
bundle_dir=$(create_dir "$files_path")
add_to_manifest "$manifest" "$bundle_dir" "$fdir"
fi
fi
# Create a link passing a file that does not exits
bundle_link=$(create_link "$files_path" "$files_path"/"$(generate_random_name does_not_exist-)")
sudo tar -rf "$version_path"/pack-"$bundle_name"-from-0.tar "$bundle_link"
add_to_manifest --skip-validation "$manifest" "$bundle_link" "$val"
# Add the file pointed by the link to the zero pack of the bundle
if [ "$DEBUG" == true ]; then
echo "dangling link -> $bundle_link"
fi
if [ "$local_bundle" = true ]; then
sudo mkdir -p "$target_path$(dirname "$val")"
# if local_bundle is enabled since we cannot copy a bad link create a new one
# in the appropriate location in target-dir with the corrent name
sudo ln -s "$(generate_random_name /does_not_exist-)" "$target_path$val"
fi
done
# 6) Add the bundle to the MoM
add_to_manifest "$version_path"/Manifest.MoM "$manifest" "$bundle_name"
# 6) Create/renew manifest tars
# 7) Create/renew manifest tars
sudo rm -f "$version_path"/Manifest.MoM.tar
create_tar "$version_path"/Manifest.MoM
# 7) Create the subscription to the bundle if the local_bundle flag iss enabled
# 8) Sign the manifest MoM
sign_manifest "$version_path"/Manifest.MoM
# 9) Create the subscription to the bundle if the local_bundle flag is enabled
if [ "$local_bundle" = true ]; then
sudo touch "$target_path"/usr/share/clear/bundles/"$bundle_name"
fi
@@ -622,19 +776,88 @@ generate_test() {
path=$(dirname "$name")/
name=$(basename "$name")
echo -e "#!/usr/bin/env bats\\n" > "$path$name".bats
echo -e "load \"../testlib\"\\n" >> "$path$name".bats
echo -e "setup() {\\n" >> "$path$name".bats
echo -e "\\tcreate_test_environment \"\$TEST_NAME\"" >> "$path$name".bats
echo -e "\\t# create_bundle -n <bundle_name> -f <file_1>,<file_2>,<file_N> \"\$TEST_NAME\"" >> "$path$name".bats
echo -e "\\n}\\n" >> "$path$name".bats
echo -e "teardown() {\\n" >> "$path$name".bats
echo -e "\\tdestroy_test_environment \"\$TEST_NAME\"" >> "$path$name".bats
echo -e "\\n}\\n" >> "$path$name".bats
echo -e "@test \"<test description>\" {\\n" >> "$path$name".bats
echo -e "\\trun sudo sh -c \"\$SWUPD <swupd_command> \$SWUPD_OPTS <command_options>\"" >> "$path$name".bats
echo -e "\\t# <validations>" >> "$path$name".bats
echo -e "\\n}" >> "$path$name".bats
{
printf '#!/usr/bin/env bats\n\n'
printf 'load "../testlib"\n\n'
printf 'global_setup() {\n\n'
printf '\t# global setup\n\n'
printf '}\n\n'
printf 'test_setup() {\n\n'
printf '\t# create_test_environment "$TEST_NAME"\n'
printf '\t# create_bundle -n <bundle_name> -f <file_1>,<file_2>,<file_N> "$TEST_NAME"\n\n'
printf '}\n\n'
printf 'test_teardown() {\n\n'
printf '\t# destroy_test_environment "$TEST_NAME"\n\n'
printf '}\n\n'
printf 'global_teardown() {\n\n'
printf '\t# global cleanup\n\n'
printf '}\n\n'
printf '@test "<test description>" {\n\n'
printf '\trun sudo sh -c "$SWUPD <swupd_command> $SWUPD_OPTS <command_options>"\n'
printf '\t# <validations>\n\n'
printf '}\n\n'
} > "$path$name".bats
# make the test script executable
chmod +x "$path$name".bats
}
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# The section below contains test fixtures that can be used from tests to create and
# cleanup test dependencies, these functions can be overwritten in the test script.
# The intention of these is to try reducing the amount of boilerplate included in
# tests since all tests require at least the creation of a test environment
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
setup() {
# the first time setup runs, run the global_setup
if [ "$BATS_TEST_NUMBER" -eq 1 ]; then
global_setup
fi
# in case the env was created in global_setup set environment variables
if [ -d "$TEST_NAME" ]; then
set_env_variables "$TEST_NAME"
fi
test_setup
}
teardown() {
test_teardown
# if the last test just ran, run the global teardown
if [ "$BATS_TEST_NUMBER" -eq "${#BATS_TEST_NAMES[@]}" ]; then
global_teardown
fi
}
global_setup() {
# dummy value in case function is not defined
return
}
global_teardown() {
# dummy value in case function is not defined
return
}
# Default test_setup
test_setup() {
create_test_environment "$TEST_NAME"
}
# Default test_teardown
test_teardown() {
destroy_test_environment "$TEST_NAME"
}
@@ -673,7 +896,10 @@ assert_status_is() {
else
# if the assertion was successful show the output only if the user
# runs the test with the -t flag
echo -e "\\nCommand output:" >&3
echo "------------------------------------------------------------------" >&3
echo "$output" >&3
echo -e "------------------------------------------------------------------\\n" >&3
fi
}
@@ -695,7 +921,10 @@ assert_status_is_not() {
else
# if the assertion was successful show the output only if the user
# runs the test with the -t flag
echo -e "\\nCommand output:" >&3
echo "------------------------------------------------------------------" >&3
echo "$output" >&3
echo -e "------------------------------------------------------------------\\n" >&3
fi
}