cem_acpt 0.2.5 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/spec.yml +38 -0
  3. data/Gemfile +4 -3
  4. data/Gemfile.lock +85 -56
  5. data/README.md +144 -83
  6. data/cem_acpt.gemspec +8 -7
  7. data/exe/cem_acpt +41 -7
  8. data/lib/cem_acpt/config.rb +345 -0
  9. data/lib/cem_acpt/core_extensions.rb +17 -61
  10. data/lib/cem_acpt/goss/api/action_response.rb +175 -0
  11. data/lib/cem_acpt/goss/api.rb +83 -0
  12. data/lib/cem_acpt/goss.rb +8 -0
  13. data/lib/cem_acpt/image_name_builder.rb +0 -9
  14. data/lib/cem_acpt/logging/formatter.rb +97 -0
  15. data/lib/cem_acpt/logging.rb +168 -142
  16. data/lib/cem_acpt/platform/base.rb +26 -37
  17. data/lib/cem_acpt/platform/gcp.rb +48 -62
  18. data/lib/cem_acpt/platform.rb +30 -28
  19. data/lib/cem_acpt/provision/terraform/linux.rb +47 -0
  20. data/lib/cem_acpt/provision/terraform/os_data.rb +72 -0
  21. data/lib/cem_acpt/provision/terraform/windows.rb +22 -0
  22. data/lib/cem_acpt/provision/terraform.rb +193 -0
  23. data/lib/cem_acpt/provision.rb +20 -0
  24. data/lib/cem_acpt/puppet_helpers.rb +0 -1
  25. data/lib/cem_acpt/test_data.rb +23 -13
  26. data/lib/cem_acpt/test_runner/log_formatter/goss_action_response.rb +104 -0
  27. data/lib/cem_acpt/test_runner/log_formatter.rb +10 -0
  28. data/lib/cem_acpt/test_runner.rb +170 -3
  29. data/lib/cem_acpt/utils/puppet.rb +29 -0
  30. data/lib/cem_acpt/utils/ssh.rb +197 -0
  31. data/lib/cem_acpt/utils/terminal.rb +27 -0
  32. data/lib/cem_acpt/utils.rb +4 -138
  33. data/lib/cem_acpt/version.rb +1 -1
  34. data/lib/cem_acpt.rb +70 -20
  35. data/lib/terraform/gcp/linux/goss/puppet_idempotent.yaml +10 -0
  36. data/lib/terraform/gcp/linux/goss/puppet_noop.yaml +12 -0
  37. data/lib/terraform/gcp/linux/main.tf +191 -0
  38. data/lib/terraform/gcp/linux/systemd/goss-acpt.service +8 -0
  39. data/lib/terraform/gcp/linux/systemd/goss-idempotent.service +8 -0
  40. data/lib/terraform/gcp/linux/systemd/goss-noop.service +8 -0
  41. data/lib/terraform/gcp/windows/.keep +0 -0
  42. data/sample_config.yaml +22 -21
  43. metadata +88 -56
  44. data/lib/cem_acpt/bootstrap/bootstrapper.rb +0 -206
  45. data/lib/cem_acpt/bootstrap/operating_system/rhel_family.rb +0 -129
  46. data/lib/cem_acpt/bootstrap/operating_system.rb +0 -17
  47. data/lib/cem_acpt/bootstrap.rb +0 -12
  48. data/lib/cem_acpt/context.rb +0 -153
  49. data/lib/cem_acpt/platform/base/cmd.rb +0 -71
  50. data/lib/cem_acpt/platform/gcp/cmd.rb +0 -345
  51. data/lib/cem_acpt/platform/gcp/compute.rb +0 -332
  52. data/lib/cem_acpt/platform/vmpooler.rb +0 -24
  53. data/lib/cem_acpt/rspec_utils.rb +0 -242
  54. data/lib/cem_acpt/shared_objects.rb +0 -537
  55. data/lib/cem_acpt/spec_helper_acceptance.rb +0 -184
  56. data/lib/cem_acpt/test_runner/run_handler.rb +0 -187
  57. data/lib/cem_acpt/test_runner/runner.rb +0 -210
  58. data/lib/cem_acpt/test_runner/runner_result.rb +0 -103
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b36c525ca6904813988ad305cc4a89607dff2edcdc8d749e347660047174b37
4
- data.tar.gz: ed7e418fbcfadd8773f25f026afa0341119ab28c5e3cc91976f46c42e83af5aa
3
+ metadata.gz: 1c774f50c327fab457a1047b30f5155cbe3afb8d55c630ddeb0525dde147304b
4
+ data.tar.gz: 134d1d6cdb6b9de6b7d77a8e634aad01809b2b9fbeb7ddd72f283b32cbcdc292
5
5
  SHA512:
6
- metadata.gz: ee9ccfe1841b755c0f8df1937d66d0e04e62efe29326f16df33af5d9d66fe47441177098a2ffaffd1f843397d19d2f5cf95dcb1b4e536568d0d52cc5848aa052
7
- data.tar.gz: c1c4f2b3a96134009552f9d464b407b64abef6d37f19df28f99b18b17445a492872a77116e924164c38aa65d1b8a96cb089ae7eff58f7414fbc5d7376f24e5cc
6
+ metadata.gz: 65d80bccfc97735e653a01d067efac47c292c432ffd8ade7d4257d89b8a6553a7e5a3b8a3d762e9687c0f2695af0a7cbd9337baef6c6afd65ab2baf0d4c221f4
7
+ data.tar.gz: 3dd0bf49d2d71ca3a18150c1182d0a2b8255981be71653e86e8d1a19bfd4b190348bfce153d244bb6dc35cd0f0b6f2db9edf8d5f8b8f7b40f3231869994ecf25
@@ -0,0 +1,38 @@
1
+ name: Unit Tests
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ pull_request:
6
+ types:
7
+ - opened
8
+ - synchronize
9
+ branches:
10
+ - main
11
+ tags:
12
+ - v.*
13
+
14
+ jobs:
15
+ tests:
16
+ name: RSpec tests
17
+ runs-on: ubuntu-20.04
18
+ strategy:
19
+ matrix:
20
+ ruby:
21
+ - 2.7
22
+ - 3.2
23
+ steps:
24
+ - name: Checkout Source
25
+ uses: actions/checkout@v3
26
+
27
+ - name: Delete Gemfile.lock
28
+ run: rm -f Gemfile.lock
29
+
30
+ - name: Set up Ruby
31
+ uses: ruby/setup-ruby@v1
32
+ with:
33
+ ruby-version: ${{ matrix.ruby }}
34
+ bundler-cache: true
35
+
36
+ - name: Run RSpec
37
+ run: |
38
+ bundle exec rake spec
data/Gemfile CHANGED
@@ -1,7 +1,8 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+ source 'https://rubygems.org'
2
3
 
3
4
  # Specify your gem's dependencies in cem_acpt.gemspec
4
5
  gemspec
5
6
 
6
- gem "rake", "~> 12.0"
7
- gem "rspec", "~> 3.0"
7
+ gem 'rake', '>= 12.0'
8
+ gem 'rspec', '>= 3.0'
data/Gemfile.lock CHANGED
@@ -1,89 +1,118 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cem_acpt (0.2.5)
5
- concurrent-ruby (~> 1.1.9)
6
- deep_merge (~> 1.2.2)
7
- net-ssh (~> 7.0.0.beta1)
8
- puppet-modulebuilder (> 0.0.1)
9
- rake
10
- rspec
11
- serverspec-cem-acpt
4
+ cem_acpt (0.6.1)
5
+ async-http (>= 0.60, < 0.70)
6
+ bcrypt_pbkdf (>= 1.0, < 2.0)
7
+ deep_merge (>= 1.2, < 2.0)
8
+ ed25519 (>= 1.2, < 2.0)
9
+ puppet-modulebuilder (>= 0.0.1)
10
+ ruby-terraform (~> 1.7)
12
11
 
13
12
  GEM
14
13
  remote: https://rubygems.org/
15
14
  specs:
16
15
  ast (2.4.2)
17
- concurrent-ruby (1.1.10)
16
+ async (2.5.0)
17
+ console (~> 1.10)
18
+ io-event (~> 1.1)
19
+ timers (~> 4.1)
20
+ async-http (0.60.1)
21
+ async (>= 1.25)
22
+ async-io (>= 1.28)
23
+ async-pool (>= 0.2)
24
+ protocol-http (~> 0.24.0)
25
+ protocol-http1 (~> 0.15.0)
26
+ protocol-http2 (~> 0.15.0)
27
+ traces (>= 0.8.0)
28
+ async-io (1.34.3)
29
+ async
30
+ async-pool (0.4.0)
31
+ async (>= 1.25)
32
+ bcrypt_pbkdf (1.1.0)
33
+ coderay (1.1.3)
34
+ concurrent-ruby (1.2.2)
35
+ console (1.16.2)
36
+ fiber-local
18
37
  deep_merge (1.2.2)
19
38
  diff-lcs (1.5.0)
39
+ ed25519 (1.3.0)
40
+ fiber-local (1.0.0)
41
+ hamster (3.0.0)
42
+ concurrent-ruby (~> 1.0)
43
+ immutable-struct (2.4.1)
44
+ io-event (1.1.7)
45
+ json (2.6.3)
46
+ lino (3.1.0)
47
+ hamster (~> 3.0)
48
+ open4 (~> 1.3)
49
+ method_source (1.0.0)
20
50
  minitar (0.9)
21
- multi_json (1.15.0)
22
- net-scp (3.0.0)
23
- net-ssh (>= 2.6.5, < 7.0.0)
24
- net-ssh (7.0.0.beta1)
25
- net-telnet (0.1.1)
51
+ open4 (1.3.4)
26
52
  parallel (1.22.1)
27
- parser (3.1.2.0)
53
+ parser (3.2.1.1)
28
54
  ast (~> 2.4.1)
29
- pathspec (1.0.0)
55
+ pathspec (1.1.3)
56
+ protocol-hpack (1.4.2)
57
+ protocol-http (0.24.1)
58
+ protocol-http1 (0.15.0)
59
+ protocol-http (~> 0.22)
60
+ protocol-http2 (0.15.1)
61
+ protocol-hpack (~> 1.4)
62
+ protocol-http (~> 0.18)
63
+ pry (0.14.2)
64
+ coderay (~> 1.1)
65
+ method_source (~> 1.0)
30
66
  puppet-modulebuilder (0.3.0)
31
67
  minitar (~> 0.9)
32
68
  pathspec (>= 0.2.1, < 2.0.0)
33
69
  rainbow (3.1.1)
34
- rake (12.3.3)
35
- regexp_parser (2.5.0)
70
+ rake (13.0.6)
71
+ regexp_parser (2.7.0)
36
72
  rexml (3.2.5)
37
- rspec (3.11.0)
38
- rspec-core (~> 3.11.0)
39
- rspec-expectations (~> 3.11.0)
40
- rspec-mocks (~> 3.11.0)
41
- rspec-core (3.11.0)
42
- rspec-support (~> 3.11.0)
43
- rspec-expectations (3.11.0)
73
+ rspec (3.12.0)
74
+ rspec-core (~> 3.12.0)
75
+ rspec-expectations (~> 3.12.0)
76
+ rspec-mocks (~> 3.12.0)
77
+ rspec-core (3.12.1)
78
+ rspec-support (~> 3.12.0)
79
+ rspec-expectations (3.12.2)
44
80
  diff-lcs (>= 1.2.0, < 2.0)
45
- rspec-support (~> 3.11.0)
46
- rspec-its (1.3.0)
47
- rspec-core (>= 3.0.0)
48
- rspec-expectations (>= 3.0.0)
49
- rspec-mocks (3.11.1)
81
+ rspec-support (~> 3.12.0)
82
+ rspec-mocks (3.12.4)
50
83
  diff-lcs (>= 1.2.0, < 2.0)
51
- rspec-support (~> 3.11.0)
52
- rspec-support (3.11.0)
53
- rubocop (1.30.1)
84
+ rspec-support (~> 3.12.0)
85
+ rspec-support (3.12.0)
86
+ rubocop (1.48.1)
87
+ json (~> 2.3)
54
88
  parallel (~> 1.10)
55
- parser (>= 3.1.0.0)
89
+ parser (>= 3.2.0.0)
56
90
  rainbow (>= 2.2.2, < 4.0)
57
91
  regexp_parser (>= 1.8, < 3.0)
58
92
  rexml (>= 3.2.5, < 4.0)
59
- rubocop-ast (>= 1.18.0, < 2.0)
93
+ rubocop-ast (>= 1.26.0, < 2.0)
60
94
  ruby-progressbar (~> 1.7)
61
- unicode-display_width (>= 1.4.0, < 3.0)
62
- rubocop-ast (1.18.0)
63
- parser (>= 3.1.1.0)
64
- ruby-progressbar (1.11.0)
65
- serverspec-cem-acpt (2.42.0)
66
- multi_json
67
- rspec (~> 3.0)
68
- rspec-its
69
- specinfra (~> 2.83.1)
70
- sfl (2.3)
71
- specinfra (2.83.2)
72
- net-scp
73
- net-ssh (>= 2.7)
74
- net-telnet (= 0.1.1)
75
- sfl
76
- unicode-display_width (2.1.0)
95
+ unicode-display_width (>= 2.4.0, < 3.0)
96
+ rubocop-ast (1.28.0)
97
+ parser (>= 3.2.1.0)
98
+ ruby-progressbar (1.13.0)
99
+ ruby-terraform (1.7.0)
100
+ immutable-struct (~> 2.4)
101
+ lino (~> 3.0)
102
+ timers (4.3.5)
103
+ traces (0.9.1)
104
+ unicode-display_width (2.4.2)
77
105
 
78
106
  PLATFORMS
79
- universal-java-17
80
- x86_64-darwin-19
107
+ x86_64-darwin-20
108
+ x86_64-linux
81
109
 
82
110
  DEPENDENCIES
83
111
  cem_acpt!
84
- rake (~> 12.0)
85
- rspec (~> 3.0)
112
+ pry
113
+ rake (>= 12.0)
114
+ rspec (>= 3.0)
86
115
  rubocop
87
116
 
88
117
  BUNDLED WITH
89
- 2.3.9
118
+ 2.4.6
data/README.md CHANGED
@@ -1,150 +1,211 @@
1
1
  # CemAcpt
2
2
 
3
- CemAcpt is an acceptance testing library / command line application for running acceptance tests against the CEM modules. It is heavily inspired by Puppet Litmus. CemAcpt is fully compatible with Puppet Litmus acceptance tests.
3
+ CemAcpt is an acceptance testing library / command line application for running acceptance tests for the CEM modules.
4
4
 
5
- CemAcpt was written to facilitate running a single acceptance test file against one or more test nodes concurrently. This is useful when your module supports a lot of different operating systems and modifies low-level components of those operating systems. For CEM, we manage things such as firewall and bootloader configurations which requires us to test against multiple base images of a single operating system (i.e. RHEL 8 with `iptables` and RHEL 8 with `firewalld`). Additionally, we test our module using both Puppet 6 and Puppet 7. As you can see, we now need to test against four test nodes that are all RHEL 8 with slightly different baseline configs. CemAcpt allows us to do so quickly in parallel.
5
+ CemAcpt uses [Terraform](#terraform) for provisioning test nodes, and [Goss](#goss) to execute acceptance tests.
6
6
 
7
- Major differences between Puppet Litmus and CemAcpt are:
7
+ ## Installation
8
8
 
9
- - CemAcpt revolves around mapping a single acceptance test file to one or more test hosts.
10
- - Test node image names can be dynamically defined by configurable parsing of the acceptance test name.
11
- - This allows your acceptance test names to define the node it will run against.
12
- - CemAcpt has it's own CLI for running provisioning of hosts and the test suite and does not use `rake`.
13
- - CemAcpt runs everything, including provisioning the test node, creating a temporary manifest on the test node, and running the acceptance test on the test node, in parallel. No matter how many test / host combinations there are, running the test suite will only take as long as the longest running single test / host combo.
14
- - CemAcpt is configurable via a YAML file.
9
+ ```bash
10
+ gem install cem_acpt
11
+ ```
15
12
 
16
- ## Concepts
13
+ `cem_acpt` was developed using Ruby 3.2.1, but other Ruby versions may work.
17
14
 
18
- CemAcpt is underpinned with a few core concepts. These concepts shape the architecture and functionality of CemAcpt.
15
+ ## Usage
19
16
 
20
- ### Platforms
17
+ ### Quickstart
21
18
 
22
- Platforms are backends that handle provisioning, interacting with, and destroying test nodes. Platforms typically represent something like a cloud provider or hypervisor, but as long as a platform implements the required methods it could do anything.
19
+ Make sure Terraform is installed and in your PATH. Instructions for installing Terraform can be found [here](https://learn.hashicorp.com/tutorials/terraform/install-cli).Then, navigate to the root of the `cem_linux` module and run the following command:
23
20
 
24
- Platforms are created by creating a file in `lib/cem_acpt/platform`. The name of the platform file is significant as it will be capitalized and used as a classname. PLATFORMS MUST implement the methods stipulated by `lib/cem_acpt/platform/base.rb` in a single module called `Platform` because the platform system will dynamically create the platform class from this module. How the methods are implemented is irrelevant as long as they take the correct input and give the correct output.
21
+ ```bash
22
+ cem_acpt --config ./cem_acpt_config.yaml
23
+ ```
25
24
 
26
- Platforms will be passed all configuration options under the top-level key `node_data`. Node configuration should be generic and should apply to all test nodes regardless of the test being ran against them. For test-specific configurations, use `test data`.
25
+ ### Command-line
27
26
 
28
- See [lib/cem_acpt/platform/gcp.rb](lib/cem_acpt/platform/gcp.rb) for an example of a platform file.
27
+ ```bash
28
+ cem_acpt -h | --help
29
+ ```
29
30
 
30
- ### Tests
31
+ > If you do not delete Gemfile.lock before running `bundle install`, you may encounter dependency version errors. Just delete Gemfile.lock and run `bundle install` again to get past these.
31
32
 
32
- Each acceptance test should be specified in the config under the top-level key `tests`. These tests SHOULD NOT be paths and should not contain the suffix `_spec.rb`. For example, if you have an acceptance test `spec/acceptance/our_acceptance_test_spec.rb`, the tests config would look like this:
33
+ ## Test directory structure
33
34
 
34
- ```yaml
35
- tests:
36
- - our_acceptance_test
35
+ CemAcpt expects a specific directory structure for your acceptance tests. The directory structure is as follows:
36
+
37
+ ```bash
38
+ spec
39
+ └── acceptance
40
+ └── <framework>_<os>-<version>_firewalld_<profile>_<level>
41
+ ├── goss.yaml # Goss test file
42
+ └── manifest.pp # Puppet manifest to apply
37
43
  ```
38
44
 
39
- Aside from ways of manipulating test data outlined below, tests are typically matched one-to-one with a test node.
45
+ For example, the following directory structure would be valid:
40
46
 
41
- ### Test data
47
+ ```bash
48
+ spec
49
+ └── acceptance
50
+ └── cis_rhel-8_firewalld_server_2
51
+ ├── goss.yaml
52
+ └── manifest.pp
53
+ ```
42
54
 
43
- Test data is a collection of data about a specific test that persists through the entire acceptance test suite lifecycle. Specifically, test data is implemented as an array of hashes with each hash representing a single run through the acceptance test suite lifecycle. What this means is that each item in the test data array is couple with a single test node that is provisioned and a single test run against that node. Test data is used to store values that are test-specific, as opposed to node data which is generic.
55
+ The directory name is used to generate test data. See [Test data](#test-data) for more information. The file `goss.yaml` is used as the [Goss](#goss) test file. The file `manifest.pp` is used as the Puppet manifest to apply.
44
56
 
45
- Test data can be configured using the top-level key `test_data`. There are several supported options for manipulating test data:
57
+ ## Configuration
46
58
 
47
- #### for_each
59
+ There are several ways to configure CemAcpt which are outlined below in order of precendence. Options specified later in the list will be merged with or override options specified earlier in the list. If an option is specified in multiple places, the last place it is specified will be used.
48
60
 
49
- When specified, should be a hash of `key -> Array` pairs. For each of these pairs, a copy of the test data is made for each item in the array, with that item becoming the value of a variable `key`.
61
+ 1. [Environment variables](#environment-variables)
62
+ 2. [User-specific config file](#config-file)
63
+ 3. [Config file specified by `--config` option](#config-file)
64
+ 4. [Command-line options](#command-line-options)
50
65
 
51
- Example:
66
+ You can view your working config by adding the `-Y` flag to any command. This will print the merged config to STDOUT as a YAML document. You can also use the `-X` flag to print an explanation of how the config was merged.
52
67
 
53
- ```yaml
54
- test_data:
55
- for_each:
56
- collection:
57
- - puppet6
58
- - puppet7
68
+ ### Environment variables
59
69
 
60
- tests:
61
- - our_acceptance_test
70
+ Environment variables are the most basic way to configure CemAcpt. They are useful for setting sensitive information like API keys or passwords. Environment variables are prefixed with `CEM_ACPT_` and are converted to the nested structure of the config file, if applicable. Double underscores \(`__`\) are used to separate key levels. For example, the environment variable `CEM_ACPT_NODE_DATA__DISK_SIZE=40` would be converted to the following config:
71
+
72
+ ```yaml
73
+ node_data:
74
+ disk_size: 40
62
75
  ```
63
76
 
64
- In the above config, instead of test data consisting of a single hash, it will have two hashes that have the `collection` variable set to `puppet6` and `puppet7` respectively. This means that there will be two test nodes provisioned and two runs of the test `our_acceptance_test`, one run against each node.
77
+ All environment variables are optional. If an environment variable is not set, the value will be taken from the config file or command-line option. If an environment variable is set, it will be overridden by the same value from the config file or command-line option.
65
78
 
66
- #### vars
79
+ ### Config file
67
80
 
68
- Aribitrary key-value pairs that are injected into the test data hashes. Think of these as constants.
81
+ The most common way is to create a config file and pass it to CemAcpt using the `--config` option. The config file should be a YAML file. See [sample_config.yaml](sample_config.yaml) for an example.
69
82
 
70
- #### name_pattern_vars
83
+ You can also create a user-specific config file at `$HOME/.cem_acpt/config.yaml`. This file will be merged with the config file specified by the `--config` option. This is useful for storing sensitive information or making config changes that you don't want to commit to a repo.
71
84
 
72
- A Ruby regex pattern that is matched against the test name with the intent of creating variables from named capture groups. See [sample_config.yaml](sample_config.yaml) for an example.
85
+ Options set in the user-specific config file will be overridden by options set in the config file specified by the `--config` option. Both config files will override options specified by environment variables.
73
86
 
74
- #### vars_post_processing
87
+ ### Command-line options
75
88
 
76
- Rules that allow for processing variables after all other test data rules are ran. See [sample_config.yaml](sample_config.yaml) for an example.
89
+ CemAcpt can be configured using command-line options. These options are specified using the `--<option>` syntax. For a full list of options, run `cem_acpt -h`. Options specified on the command-line will override options specified in the config file and environment variables.
77
90
 
78
- ### Image name builder
91
+ ## Goss
79
92
 
80
- Much like `name_pattern_vars`, specifying the `image_name_builder` top-level key in the config allows you to manipulate acceptance test names to create a special test data variable called `image_name`. This is helpful for when you have multiple platform base images and want to use the correct image with the correct test. See [sample_config.yaml](sample_config.yaml) for an example.
93
+ [Goss](https://github.com/goss-org/goss/blob/master/docs/manual.md) is the core infrastructure testing tool used by CemAcpt. The `goss.yaml` file is used to specify the tests to run. Please see the [Goss documentation](https://github.com/goss-org/goss/blob/master/docs/manual.md#goss-test-creation) for more information on how to write Goss tests.
81
94
 
82
- ## Installation
95
+ ## Terraform
83
96
 
84
- ### Installing from RubyGems
97
+ CemAcpt uses [Terraform](https://www.terraform.io/) for managing the lifecycle of test nodes. Users don't interact with Terraform directly, but you will need it installed to use CemAcpt.
85
98
 
86
- To install the gem locally to use as a CLI tool:
99
+ ## Platforms
87
100
 
88
- `gem install cem_acpt --prerelease`
101
+ Platforms are the underlying infrastructure that nodes are provisioned on. Currently, only GCP is supported. Each platform has two parts to it: the [platform](#platform) and the [node data](#node-data).
89
102
 
90
- ### Installing into a Puppet module
103
+ ### Platform
91
104
 
92
- Add this line to your module's Gemfile (usually under `group :development`):
105
+ A platform represents where nodes are provisioned. Currently, only GCP is supported. Platforms are configured using the top-level key `platform`. For example, the following config would configure a GCP platform:
93
106
 
94
- ```ruby
95
- gem 'cem_acpt', require: false
107
+ ```yaml
108
+ platform:
109
+ name: gcp
110
+ project: my-project
111
+ region: us-west1
112
+ zone: us-west1-b
113
+ subnetwork: my-subnetwork
96
114
  ```
97
115
 
98
- Then, add the following to your `spec_helper_acceptance.rb` (replacing the Puppet Litmus configuration lines):
116
+ ### Node data
99
117
 
100
- ```ruby
101
- require 'cem_acpt'
118
+ Node data is a more generic complement to the [platform](#platform) that specifies node-level details for test nodes. Node data is configured using the top-level key `node_data`. For example, the following config would configure node data:
102
119
 
103
- CemAcpt.configure_spec_helper!
120
+ ```yaml
121
+ node_data:
122
+ disk_size: 40
123
+ machine_type: e2-small
104
124
  ```
105
125
 
106
- To use CemAcpt in your acceptance tests, you must call the method `initialize_test_environment!` in your acceptance test's `describe` block before doing anything else:
126
+ ### Developing new platforms
127
+
128
+ Platforms are defined as Ruby files in the `lib/cem_acpt/platform` directory. Each platform file should define a module called `Platform` that implements the following methods:
107
129
 
108
130
  ```ruby
109
- describe 'cem_linux CIS Level 1' do
110
- initialize_test_environment!
111
- ...
131
+ module Platform
132
+ # @return [Hash] A hash of platform data
133
+ def platform_data
134
+ # Return a hash of platform data
135
+ end
136
+
137
+ # @return [Hash] A hash of node data
138
+ def node_data
139
+ # Destroy a node
140
+ end
141
+ end
112
142
  ```
113
143
 
114
- ## Usage
144
+ Both the `#platform_data` and `#node_data` methods should return a hash. Each method should also also ensure the config is queried for values for each key in each hash. This is enabled by the exposed instance variables `@config` and `@test_data` in the `Platform` module. For an example, see the [GCP platform](lib/cem_acpt/platform/gcp.rb).
115
145
 
116
- ### RSpec methods
146
+ ## Tests
117
147
 
118
- CemAcpt enables you to use all ServerSpec methods in your acceptance tests, and adds three new methods that can be used (these methods are used the same as in Litmus):
148
+ Each acceptance test should be specified in the config under the top-level key `tests`. These tests SHOULD NOT be paths, just the test directory name. For example, if you have an acceptance test directory `spec/acceptance/cis_rhel_acceptance_test/*`, the tests config would look like this:
119
149
 
120
- - `apply_manifest(manifest, opts = {})`: Applies a Puppet manifest given as a string.
121
- - `idempotent_apply(manifest, opts = {})`: Applies a Puppet manifest given as a string twice and fails if the second apply reports changes.
122
- - `run_shell(command, opts = {})`: Runs a shell command against the test node.
150
+ ```yaml
151
+ tests:
152
+ - our_acceptance_test
153
+ ```
123
154
 
124
- ### Config file
155
+ Aside from ways of manipulating test data outlined below, tests are typically matched one-to-one with a test node.
156
+
157
+ ## Test data
158
+
159
+ Test data is a collection of data about a specific test that persists through the entire acceptance test suite lifecycle. Specifically, test data is implemented as an array of hashes with each hash representing a single run through the acceptance test suite lifecycle. What this means is that each item in the test data array is couple with a single test node that is provisioned and a single test run against that node. Test data is used to store values that are test-specific, as opposed to node data which is generic.
160
+
161
+ Test data can be configured using the top-level key `test_data`. There are several supported options for manipulating test data:
162
+
163
+ ### for_each
164
+
165
+ When specified, should be a hash of `key -> Array` pairs. For each of these pairs, a copy of the test data is made for each item in the array, with that item becoming the value of a variable `key`.
125
166
 
126
- CemAcpt can use a config file (default path is `./cem_acpt_config.yaml`) to configure it's settings. Below are some of the options available in the config file:
167
+ Example:
127
168
 
128
- - `tests`: An array of test names you want to run. These are assumed to exist in the path `spec/acceptance`. You should leave off the suffix `_spec.rb` from the test file names.
129
- - `platform`: The backend platform that acceptance tests will run on. Currently, only `gcp` is supported.
130
- - `test_data`: Configurations for test data. Allows assigning variables to test data either dynamically or statically.
131
- - `node_data`: Configurations for nodes created by the platform. The available options are platform-dependent.
132
- - `image_name_builder`: If this key is specified, platforms will be passed a dynamically generated image name based on the configurations under this key.
169
+ ```yaml
170
+ test_data:
171
+ for_each:
172
+ collection:
173
+ - puppet6
174
+ - puppet7
133
175
 
134
- ### Semantic acceptance test names
176
+ tests:
177
+ - our_acceptance_test
178
+ ```
179
+
180
+ In the above config, instead of test data consisting of a single hash, it will have two hashes that have the `collection` variable set to `puppet6` and `puppet7` respectively. This means that there will be two test nodes provisioned and two runs of the test `our_acceptance_test`, one run against each node.
181
+
182
+ ### vars
135
183
 
136
- With CemAcpt, acceptance test names can have semantic meaning and influence how your acceptance test nodes are provisioned and how test data is created. The semantic meaning of the test names can be configured in the config file.
184
+ Aribitrary key-value pairs that are injected into the test data hashes. Think of these as constants.
137
185
 
138
- ## Development
186
+ ### name_pattern_vars
139
187
 
140
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
188
+ A Ruby regex pattern that is matched against the test name with the intent of creating variables from named capture groups. See [sample_config.yaml](sample_config.yaml) for an example.
141
189
 
142
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
190
+ ### vars_post_processing
143
191
 
144
- ## Contributing
192
+ Rules that allow for processing variables after all other test data rules are ran. See [sample_config.yaml](sample_config.yaml) for an example.
145
193
 
146
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/cem_acpt.
194
+ ## Image name builder
147
195
 
148
- ## License
196
+ Much like `name_pattern_vars`, specifying the `image_name_builder` top-level key in the config allows you to manipulate acceptance test names to create a special test data variable called `image_name`. This is helpful for when you have multiple platform base images and want to use the correct image with the correct test. See [sample_config.yaml](sample_config.yaml) for an example.
149
197
 
150
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
198
+ ## The acceptance test lifecycle
199
+
200
+ - Load and merge the config
201
+ - Create the local test directory under `$HOME/.cem_acpt`
202
+ - Build the Puppet module. Uses current dir if no `module_dir` is specified in the config
203
+ - Copy all relevant files into the local test directory
204
+ - This includes the Terraform files provided by CemAcpt, as well as the files under the specified acceptance test directory, and the built Puppet module
205
+ - Provision test nodes using Terraform
206
+ - After the node is created, the contents of the local test directory are copied to the node
207
+ - Additionally, the Puppet module is installed on the node and Puppet is ran once to apply `manifest.pp`
208
+ - After, the Goss server endpoints are started and exposed on the node
209
+ - Once node is provisioned, make HTTP get requests to the Goss server endpoints to run the tests
210
+ - Destroy the test nodes
211
+ - Report the results of the tests
data/cem_acpt.gemspec CHANGED
@@ -26,12 +26,13 @@ Gem::Specification.new do |spec|
26
26
  spec.bindir = 'exe'
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
- spec.add_runtime_dependency 'concurrent-ruby', '~> 1.1.9'
30
- spec.add_runtime_dependency 'deep_merge', '~> 1.2.2'
31
- spec.add_runtime_dependency 'net-ssh', '~> 7.0.0.beta1'
32
- spec.add_runtime_dependency 'puppet-modulebuilder', '> 0.0.1'
33
- spec.add_runtime_dependency 'rake'
34
- spec.add_runtime_dependency 'rspec'
35
- spec.add_runtime_dependency 'serverspec-cem-acpt'
29
+ # spec.platform = Gem::Platform.local
30
+ spec.add_runtime_dependency 'async-http', '>= 0.60', '< 0.70'
31
+ spec.add_runtime_dependency 'bcrypt_pbkdf', '>= 1.0', '< 2.0'
32
+ spec.add_runtime_dependency 'deep_merge', '>= 1.2', '< 2.0'
33
+ spec.add_runtime_dependency 'ed25519', '>= 1.2', '< 2.0'
34
+ spec.add_runtime_dependency 'puppet-modulebuilder', '>= 0.0.1'
35
+ spec.add_runtime_dependency 'ruby-terraform', '~> 1.7'
36
+ spec.add_development_dependency 'pry'
36
37
  spec.add_development_dependency 'rubocop'
37
38
  end
data/exe/cem_acpt CHANGED
@@ -11,6 +11,25 @@ options = {}
11
11
  parser = OptionParser.new do |opts|
12
12
  opts.banner = 'Usage: cem_acpt [options]'
13
13
 
14
+ opts.on('-h', '--help', 'Show this help message') do
15
+ puts opts
16
+ exit 0
17
+ end
18
+
19
+ opts.on('-a', '--only-actions ACTIONS', 'Set actions. Example: -a "acpt,noop"') do |a|
20
+ options[:actions] ||= {}
21
+ options[:actions][:only] = a.split(',')
22
+ end
23
+
24
+ opts.on('-A', '--except-actions ACTIONS', 'Set excluded actions. Example: -A "noop,idempotent"') do |a|
25
+ options[:actions] ||= {}
26
+ options[:actions][:except] = a.split(',')
27
+ end
28
+
29
+ opts.on('-t', '--tests TESTS', 'Set tests. Example: -t "test1,test2"') do |t|
30
+ options[:tests] = t.split(',')
31
+ end
32
+
14
33
  opts.on('-D', '--debug', 'Enable debug logging') do
15
34
  options[:log_level] = 'debug'
16
35
  end
@@ -39,7 +58,7 @@ parser = OptionParser.new do |opts|
39
58
  end
40
59
 
41
60
  opts.on('-I', '--CI', 'Run in CI mode') do
42
- options[:CI] = true
61
+ options[:ci_mode] = true
43
62
  options[:log_format] = 'github_action'
44
63
  end
45
64
 
@@ -55,12 +74,21 @@ parser = OptionParser.new do |opts|
55
74
  options[:verbose] = true
56
75
  end
57
76
 
77
+ opts.on('-S', '--no-epehemeral-ssh-key', 'Do not generate an ephemeral SSH key for test suites') do
78
+ options[:no_ephemeral_ssh_key] = true
79
+ end
80
+
58
81
  opts.on('-V', '--version', 'Show the cem_acpt version') do
59
- options[:show_version] = true
82
+ puts CemAcpt.version(as_str: true)
83
+ exit 0
60
84
  end
61
85
 
62
- opts.on('-S', '--no-epehemeral-ssh-key', 'Do not generate an ephemeral SSH key for test suites') do
63
- options[:no_ephemeral_ssh_key] = true
86
+ opts.on('-Y', '--print-yaml-config', 'Loads and prints the config as YAML. Other specified options will be added to the config.') do
87
+ options[:print_yaml_config] = true
88
+ end
89
+
90
+ opts.on('-X', '--explain-config', 'Loads and prints the config explanation. Other specified options will be added to the config.') do
91
+ options[:explain_config] = true
64
92
  end
65
93
 
66
94
  # NOT IMPLEMENTED
@@ -70,12 +98,18 @@ parser = OptionParser.new do |opts|
70
98
  end
71
99
 
72
100
  parser.parse!
73
- if options[:show_version]
74
- puts CemAcpt::VERSION
101
+ if options[:print_yaml_config]
102
+ options.delete(:print_yaml_config)
103
+ puts CemAcpt.print_config(options, format: :yaml)
104
+ exit 0
105
+ end
106
+ if options[:explain_config]
107
+ options.delete(:explain_config)
108
+ puts CemAcpt.print_config(options, format: :explain)
75
109
  exit 0
76
110
  end
111
+ # Set CLI defaults
77
112
  options[:module_dir] = Dir.pwd unless options[:module_dir]
78
- options[:platforms] = %w[gcp vmpooler] unless options[:platform]
79
113
  if (options[:log_level] == 'debug' || options[:verbose]) && !options[:quiet]
80
114
  puts '#################### RUNNING ACCEPTANCE TEST SUITE ####################'
81
115
  puts "Using options from command line: #{options}"