forked from chef/automate
-
Notifications
You must be signed in to change notification settings - Fork 1
/
README
122 lines (102 loc) · 6 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# A2 Integration Test Framework
The A2 integration test framework allows you to write tests against full A2
stack under different scenarios, such as A1 migration, upgrades from a
previous A2, backup/restore, etc.
## Running
To run a test, run the following from the A2 root folder outside the studio:
```bash
HAB_ORIGIN=yourorigin ./integration/run_test ./integration/tests/testname.sh
```
## Test specifications
Tests are written in bash. All tests will inherit integration/base.sh by default.
The test framework allows certain callbacks to be defined in a test, and certain
variables may be set to change default behaviors. Below, some of the common ones
are listed. Read base.sh for more details.
Constants:
- test_build_slug: Randomizes your container name
- test_container_name: The name the test framework gave your container
Variables:
- test_name: [required] Set this to the name of your test
- test_upgrades: [optional, default=false] Set this to true if your test requires
upgrading from a previous version of A2.
- test_backup_restore: [optional, default=false] Set this to true if your test requires backup/restore.
Only one of test_upgrades and test_backup_restore is supported at a time. If you
need more, make it work.
- test_loadbalancer_url: [optional, default="https://localhost"] The A2 https loadbalancer url
- test_deploy_inspec_profiles: [optional, default=()] A list of inspec profiles to run after deploy
- test_upgrade_inspec_profiles: [optional, default=()] A list of inspec profiles to run after upgrade
- test_skip_diagnostics: [optional, default=false] Set to true if you do not wish for the diagnostics
tests to be run
- test_config_path: The location of the config
- test_external_services: External services required to run this test. See the External Services section.
Callbacks:
- do_setup(): Do any setup you need prior to having A2 installed
- do_build(): Build the harts for your change. In CI, this step only downloads because the changes are
built in another build step in the pipeline.
- do_create_config(): Initialize the config. At the end of this step, the config should be written to
$test_config_path
- do_prepare_deploy(): This step runs right before deploying A2. For upgrades, the default implementation
will lay down the dev deployment manifest and move out the changes, to be put back
in place in the upgrade step.
- do_deploy(): Deploys A2
- do_test_deploy(): Runs tests after deploy. Uses the test_deploy_inspec_profiles and test_skip_diagnostics
variables. to figure out what to run in the default implementation.
- do_upgrade(): Moves the changes back into place and waits for A2 to finish upgrading.
- do_test_upgrade(): Runs tests after upgrade. Uses the test_upgrade_inspec_profiles and test_skip_diagnostics
variables. to figure out what to run in the default implementation.
- do_backup(): Create a backup of A2
- do_prepare_restore(): Prepare A2 for restore. The default implementation brings down A2 and deletes stuff
- do_restore(): Restore A2. The id for the backup is stored in test_backup_id
- do_test_restore(): Runs tests post restore. Default implementation only deals with diagnostics
## External Services
The ability to run external services was introduced in https://github.com/chef/automate/pull/5103.
To add an external service, add a folder with the service name (no spaces) to `integration/services`.
For example, `integration/services/elasticsearch`. In the folder for the service, create a shell
script called `init` with 2 functions: `service_name_setup` and `service_name_teardown`, where
`service_name` should be replaced with the service name. For example, in the elasticsearch case,
they would be `elasticsearch_setup` and `elasticsearch_teardown`. This init file will be sourced
into the `run_test` script and the functions called if a test defines it as a dependency through
the `test_external_services` array. For example, a test might look like this:
```bash
test_name="product"
test_deploy_inspec_profiles=(a2-deploy-integration)
test_external_services=(
elasticsearch
)
do_prepare_config() {
...
}
```
The `_setup` function is responsible for setting up containers. There are a few helper functions provided
for that. `service_container_name container_name` appends the `test_build_slug` variable to the container
name, ensuring that multiple tests can run without interfering with each other. The `docker_run` function
wraps `docker run` to setup the correct volumes, environment variables, etc.
The `_setup` function can share config with the test container by writing a file in the service config
path. For convention, services should use the `service_config_path service_name` function which will namespace
the directory. `service_config_path` will create a folder `$SERVICES_CONFIG_PATH/service_name`.
`$SERVICES_CONFIG_PATH` gets mounted at `/services` in the test container. As en example,
the elasticsearch config could write out the toml required to start an external elasticsearch in A2.
The test container would append this file to its generated toml.
An example init file:
```bash
SERVICE_A_DIR=$(dirname ${BASH_SOURCE[0]})
service_a_container1=$(service_container_name "service_a_1")
service_a_container2=$(service_container_name "service_a_2")
service_a_config=$(service_config_path "service_a")
service_a_setup() {
mkdir -p $(dirname $service_a_config)
docker_run $service_a_container1
docker cp "$SERVICE_A_DIR/setup.sh" "${service_a_container1}:/setup.sh"
docker exec $service_a_container1 /setup.sh
log_info "Launched $service_a_container1 with ip $(container_ip $service_a_container1)"
docker_run $service_a_container2
log_info "Launched $service_a_container2 with ip $(container_ip $service_a_container2)"
cat <<DOC > $service_a_config
hello
DOC
}
service_a_teardown() {
docker stop "$service_a_container1"
docker stop "$service_a_container2"
}
```