inspec 4.16.0 → 4.17.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/lib/inspec.rb +0 -1
  3. data/lib/inspec/backend.rb +7 -0
  4. data/lib/inspec/base_cli.rb +2 -0
  5. data/lib/inspec/cli.rb +3 -10
  6. data/lib/inspec/config.rb +3 -4
  7. data/lib/inspec/control_eval_context.rb +5 -3
  8. data/lib/inspec/dsl.rb +24 -1
  9. data/lib/inspec/errors.rb +0 -26
  10. data/lib/inspec/file_provider.rb +33 -43
  11. data/lib/inspec/formatters/base.rb +1 -0
  12. data/lib/inspec/impact.rb +2 -0
  13. data/lib/inspec/input.rb +410 -0
  14. data/lib/inspec/input_registry.rb +10 -1
  15. data/lib/inspec/objects.rb +3 -1
  16. data/lib/inspec/objects/input.rb +5 -387
  17. data/lib/inspec/objects/tag.rb +1 -1
  18. data/lib/inspec/plugin/v1/plugin_types/resource.rb +16 -5
  19. data/lib/inspec/plugin/v2/activator.rb +4 -8
  20. data/lib/inspec/plugin/v2/loader.rb +19 -3
  21. data/lib/inspec/profile.rb +1 -1
  22. data/lib/inspec/profile_context.rb +1 -1
  23. data/lib/inspec/reporters/json.rb +70 -88
  24. data/lib/inspec/resource.rb +1 -0
  25. data/lib/inspec/resources.rb +9 -2
  26. data/lib/inspec/resources/aide_conf.rb +4 -0
  27. data/lib/inspec/resources/apt.rb +19 -19
  28. data/lib/inspec/resources/etc_fstab.rb +4 -0
  29. data/lib/inspec/resources/etc_hosts.rb +4 -0
  30. data/lib/inspec/resources/firewalld.rb +4 -0
  31. data/lib/inspec/resources/json.rb +10 -3
  32. data/lib/inspec/resources/mssql_session.rb +1 -1
  33. data/lib/inspec/resources/platform.rb +18 -13
  34. data/lib/inspec/resources/postfix_conf.rb +6 -2
  35. data/lib/inspec/resources/security_identifier.rb +4 -0
  36. data/lib/inspec/resources/sys_info.rb +65 -4
  37. data/lib/inspec/resources/user.rb +1 -0
  38. data/lib/inspec/rule.rb +68 -6
  39. data/lib/inspec/runner.rb +6 -1
  40. data/lib/inspec/runner_rspec.rb +1 -0
  41. data/lib/inspec/shell.rb +8 -1
  42. data/lib/inspec/utils/pkey_reader.rb +1 -1
  43. data/lib/inspec/version.rb +1 -1
  44. data/lib/matchers/matchers.rb +2 -0
  45. data/lib/plugins/inspec-plugin-manager-cli/test/functional/help_test.rb +23 -0
  46. data/lib/plugins/inspec-plugin-manager-cli/test/functional/helper.rb +62 -0
  47. data/lib/plugins/inspec-plugin-manager-cli/test/functional/install_test.rb +368 -0
  48. data/lib/plugins/inspec-plugin-manager-cli/test/functional/list_test.rb +101 -0
  49. data/lib/plugins/inspec-plugin-manager-cli/test/functional/search_test.rb +129 -0
  50. data/lib/plugins/inspec-plugin-manager-cli/test/functional/uninstall_test.rb +63 -0
  51. data/lib/plugins/inspec-plugin-manager-cli/test/functional/update_test.rb +84 -0
  52. metadata +11 -3
  53. data/lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb +0 -845
@@ -0,0 +1,101 @@
1
+ require_relative "helper"
2
+
3
+ class PluginManagerCliList < Minitest::Test
4
+ include CorePluginFunctionalHelper
5
+ include PluginManagerHelpers
6
+
7
+ # Listing all plugins is now default behavior
8
+ LIST_CASES = [
9
+ { arg: "-c", name: "inspec-plugin-manager-cli", type: "core" },
10
+ { arg: "-c", name: "inspec-supermarket", type: "core" },
11
+ { arg: "-s", name: "train-aws", type: "gem (system)" },
12
+ ].freeze
13
+
14
+ def test_list_all_when_no_user_plugins_installed
15
+ result = run_inspec_process_with_this_plugin("plugin list --all")
16
+ skip_windows!
17
+ assert_empty result.stderr
18
+
19
+ plugins_seen = parse_plugin_list_lines(result.stdout)
20
+
21
+ # Look for a specific plugin of each type - core, bundle, and system
22
+ LIST_CASES.each do |test_case|
23
+ plugin_line = plugins_seen.detect { |plugin| plugin[:name] == test_case[:name] }
24
+ refute_nil plugin_line, "#{test_case[:name]} should be detected in plugin list --all output"
25
+ assert_equal test_case[:type], plugin_line[:type], "#{test_case[:name]} should be detected as a '#{test_case[:type]}' type in list --all "
26
+ end
27
+ assert_exit_code 0, result
28
+ end
29
+
30
+ def test_list_selective_when_no_user_plugins_installed
31
+ LIST_CASES.each do |test_case|
32
+ result = run_inspec_process_with_this_plugin("plugin list #{test_case[:arg]}")
33
+ skip_windows!
34
+
35
+ assert_empty result.stderr
36
+ plugins_seen = parse_plugin_list_lines(result.stdout)
37
+ plugin_line = plugins_seen.detect { |plugin| plugin[:name] == test_case[:name] }
38
+ refute_nil plugin_line, "#{test_case[:name]} should be detected in plugin list #{test_case[:arg]} output"
39
+ assert_equal plugin_line[:type], test_case[:type], "#{test_case[:name]} should be detected as a '#{test_case[:type]}' type in list #{test_case[:arg]} "
40
+ assert_exit_code 0, result
41
+ end
42
+ end
43
+
44
+ def test_list_when_gem_and_path_plugins_installed
45
+ pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
46
+ plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
47
+ copy_in_core_config_dir("test-fixture-1-float", tmp_dir)
48
+ end
49
+
50
+ result = run_inspec_process_with_this_plugin("plugin list --user ", pre_run: pre_block)
51
+ skip_windows!
52
+
53
+ assert_empty result.stderr
54
+ plugins_seen = parse_plugin_list_lines(result.stdout)
55
+ assert_equal 2, plugins_seen.count
56
+ # Plugin Name Version Via ApiVer
57
+ # ---------------------------------------------------------
58
+ # inspec-meaning-of-life src path 2
59
+ # inspec-test-fixture 0.1.0 gem (user) 2
60
+ # ---------------------------------------------------------
61
+ # 2 plugin(s) total
62
+ meaning = plugins_seen.detect { |p| p[:name] == "inspec-meaning-of-life" }
63
+ refute_nil meaning
64
+ assert_equal "path", meaning[:type]
65
+
66
+ fixture = plugins_seen.detect { |p| p[:name] == "inspec-test-fixture" }
67
+ refute_nil fixture
68
+ assert_equal "gem (user)", fixture[:type]
69
+ assert_equal "0.1.0", fixture[:version]
70
+
71
+ assert_exit_code 0, result
72
+ end
73
+
74
+ def test_list_when_a_train_plugin_is_installed
75
+ pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
76
+ plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
77
+ copy_in_core_config_dir("train-test-fixture", tmp_dir)
78
+ end
79
+
80
+ result = run_inspec_process_with_this_plugin("plugin list --user ", pre_run: pre_block)
81
+ skip_windows!
82
+
83
+ assert_empty result.stderr
84
+ plugins_seen = parse_plugin_list_lines(result.stdout)
85
+ assert_equal 1, plugins_seen.count
86
+ assert_includes result.stdout, "1 plugin(s) total", "list train should show one plugins"
87
+
88
+ # Plugin Name Version Via ApiVer
89
+ # -------------------------------------------------------------
90
+ # train-test-fixture 0.1.0 gem (user) train-1
91
+ # -------------------------------------------------------------
92
+ # 1 plugin(s) total
93
+ train_plugin = plugins_seen.detect { |p| p[:name] == "train-test-fixture" }
94
+ refute_nil train_plugin
95
+ assert_equal "gem (user)", train_plugin[:type]
96
+ assert_equal "train-1", train_plugin[:generation]
97
+ assert_equal "0.1.0", train_plugin[:version]
98
+
99
+ assert_exit_code 0, result
100
+ end
101
+ end
@@ -0,0 +1,129 @@
1
+ require_relative "helper"
2
+
3
+ class PluginManagerCliSearch < Minitest::Test
4
+ include CorePluginFunctionalHelper
5
+ include PluginManagerHelpers
6
+
7
+ parallelize_me!
8
+
9
+ # TODO: Thor can't hide options, but we wish it could.
10
+ # def test_search_include_fixture_hidden_option
11
+ # result = run_inspec_process_with_this_plugin('plugin help search')
12
+ # refute_includes result.stdout, '--include-test-fixture'
13
+ # end
14
+
15
+ def test_search_for_a_real_gem_with_full_name_no_options
16
+ result = run_inspec_process("plugin search --include-test-fixture inspec-test-fixture")
17
+
18
+ assert_includes result.stdout, "inspec-test-fixture", "Search result should contain the gem name"
19
+ assert_includes result.stdout, "1 plugin(s) found", "Search result should find 1 plugin"
20
+ line = result.stdout.split("\n").grep(/inspec-test-fixture/).first
21
+ assert_match(/\s*inspec-test-fixture\s+\((\d+\.\d+\.\d+){1}\)/, line, "Plugin line should include name and exactly one version")
22
+
23
+ assert_exit_code 0, result
24
+ end
25
+
26
+ def test_search_for_a_real_gem_with_stub_name_no_options
27
+ result = run_inspec_process("plugin search --include-test-fixture inspec-test-")
28
+
29
+ assert_includes result.stdout, "inspec-test-fixture", "Search result should contain the gem name"
30
+ assert_includes result.stdout, "1 plugin(s) found", "Search result should find 1 plugin"
31
+
32
+ line = result.stdout.split("\n").grep(/inspec-test-fixture/).first
33
+ assert_match(/\s*inspec-test-fixture\s+\((\d+\.\d+\.\d+){1}\)/, line, "Plugin line should include name and exactly one version")
34
+
35
+ assert_exit_code 0, result
36
+ end
37
+
38
+ def test_search_for_a_real_gem_with_full_name_and_exact_option
39
+ result = run_inspec_process("plugin search --exact --include-test-fixture inspec-test-fixture")
40
+
41
+ assert_includes result.stdout, "inspec-test-fixture", "Search result should contain the gem name"
42
+ assert_includes result.stdout, "1 plugin(s) found", "Search result should find 1 plugin"
43
+
44
+ assert_exit_code 0, result
45
+
46
+ # TODO: split
47
+ result = run_inspec_process("plugin search -e --include-test-fixture inspec-test-fixture")
48
+
49
+ assert_exit_code 0, result
50
+ end
51
+
52
+ def test_search_for_a_real_gem_with_stub_name_and_exact_option
53
+ result = run_inspec_process("plugin search --exact --include-test-fixture inspec-test-")
54
+
55
+ assert_includes result.stdout, "0 plugin(s) found", "Search result should find 0 plugins"
56
+
57
+ assert_exit_code 2, result
58
+
59
+ # TODO: split
60
+ result = run_inspec_process("plugin search -e --include-test-fixture inspec-test-")
61
+
62
+ assert_exit_code 2, result
63
+ end
64
+
65
+ def test_search_for_a_real_gem_with_full_name_and_all_option
66
+ result = run_inspec_process("plugin search --all --include-test-fixture inspec-test-fixture")
67
+ assert_includes result.stdout, "inspec-test-fixture", "Search result should contain the gem name"
68
+ assert_includes result.stdout, "1 plugin(s) found", "Search result should find 1 plugin"
69
+
70
+ line = result.stdout.split("\n").grep(/inspec-test-fixture/).first
71
+ assert_match(/\s*inspec-test-fixture\s+\((\d+\.\d+\.\d+(,\s)?){2,}\)/, line, "Plugin line should include name and at least two versions")
72
+
73
+ assert_exit_code 0, result
74
+
75
+ # TODO: split
76
+ result = run_inspec_process("plugin search -a --include-test-fixture inspec-test-fixture")
77
+
78
+ assert_exit_code 0, result
79
+ end
80
+
81
+ def test_search_for_a_gem_with_missing_prefix
82
+ result = run_inspec_process("plugin search --include-test-fixture test-fixture")
83
+ assert_exit_code 1, result
84
+ assert_includes result.stdout, "All inspec plugins must begin with either 'inspec-' or 'train-'"
85
+ end
86
+
87
+ def test_search_for_a_gem_that_does_not_exist
88
+ result = run_inspec_process("plugin search --include-test-fixture inspec-test-fixture-nonesuch")
89
+
90
+ assert_includes result.stdout, "0 plugin(s) found", "Search result should find 0 plugins"
91
+
92
+ assert_exit_code 2, result
93
+ end
94
+
95
+ def test_search_for_a_real_gem_with_full_name_no_options_and_train_name
96
+ result = run_inspec_process("plugin search --include-test-fixture train-test-fixture")
97
+
98
+ assert_includes result.stdout, "train-test-fixture", "Search result should contain the gem name"
99
+ assert_includes result.stdout, "1 plugin(s) found", "Search result should find 1 plugin"
100
+ line = result.stdout.split("\n").grep(/train-test-fixture/).first
101
+ assert_match(/\s*train-test-fixture\s+\((\d+\.\d+\.\d+){1}\)/, line, "Plugin line should include name and exactly one version")
102
+
103
+ assert_exit_code 0, result
104
+ end
105
+
106
+ def test_search_omit_excluded_inspec_plugins
107
+ result = run_inspec_process("plugin search --include-test-fixture inspec-")
108
+
109
+ assert_includes result.stdout, "inspec-test-fixture", "Search result should contain the test gem"
110
+ %w{
111
+ inspec-core
112
+ inspec-multi-server
113
+ }.each do |plugin_name|
114
+ refute_includes result.stdout, plugin_name, "Search result should not contain excluded gems"
115
+ end
116
+
117
+ assert_exit_code 0, result
118
+ end
119
+
120
+ def test_search_for_a_real_gem_with_full_name_no_options_filter_fixtures
121
+ result = run_inspec_process("plugin search inspec-test-fixture")
122
+ refute_includes result.stdout, "inspec-test-fixture", "Search result should not contain the fixture gem name"
123
+ end
124
+
125
+ def test_search_for_a_real_gem_with_full_name_no_options_filter_fixtures_train
126
+ result = run_inspec_process("plugin search train-test-fixture")
127
+ refute_includes result.stdout, "train-test-fixture", "Search result should not contain the fixture gem name"
128
+ end
129
+ end
@@ -0,0 +1,63 @@
1
+ require_relative "helper"
2
+
3
+ class PluginManagerCliUninstall < Minitest::Test
4
+ include CorePluginFunctionalHelper
5
+ include PluginManagerHelpers
6
+
7
+ def test_when_a_gem_plugin_can_be_uninstalled
8
+ pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
9
+ plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
10
+ copy_in_core_config_dir("test-fixture-1-float", tmp_dir)
11
+ end
12
+
13
+ # Attempt uninstall
14
+ uninstall_result = run_inspec_process_with_this_plugin("plugin uninstall inspec-test-fixture", pre_run: pre_block, post_run: list_after_run)
15
+
16
+ success_message = uninstall_result.stdout.split("\n").grep(/uninstalled/).last
17
+ skip_windows!
18
+ refute_nil success_message, "Should find a success message at the end"
19
+ assert_includes success_message, "inspec-test-fixture"
20
+ assert_includes success_message, "0.1.0"
21
+ assert_includes success_message, "has been uninstalled"
22
+
23
+ itf_plugins = uninstall_result.payload.list_result.select { |p| p[:name] == "inspec-test-fixture" }
24
+ assert_empty itf_plugins, "inspec-test-fixture should not appear in the output of inspec list"
25
+
26
+ assert_empty uninstall_result.stderr
27
+ assert_exit_code 0, uninstall_result
28
+ end
29
+
30
+ def test_when_a_path_plugin_can_be_uninstalled
31
+ pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
32
+ plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
33
+ # This fixture includes a path install for inspec-meaning-of-life
34
+ copy_in_core_config_dir("test-fixture-1-float", tmp_dir)
35
+ end
36
+ uninstall_result = run_inspec_process_with_this_plugin("plugin uninstall inspec-meaning-of-life", pre_run: pre_block, post_run: list_after_run)
37
+ skip_windows!
38
+
39
+ success_message = uninstall_result.stdout.split("\n").grep(/uninstalled/).last
40
+ refute_nil success_message, "Should find a success message at the end"
41
+ assert_includes success_message, "inspec-meaning-of-life"
42
+ assert_includes success_message, "path-based plugin install"
43
+ assert_includes success_message, "has been uninstalled"
44
+
45
+ itf_plugins = uninstall_result.payload.list_result.select { |p| p[:name] == "inspec-meaning-of-life" }
46
+ assert_empty itf_plugins, "inspec-meaning-of-life should not appear in the output of inspec list"
47
+
48
+ assert_empty uninstall_result.stderr
49
+ assert_exit_code 0, uninstall_result
50
+ end
51
+
52
+ def test_fail_uninstall_from_plugin_that_is_not_installed
53
+ uninstall_result = run_inspec_process_with_this_plugin("plugin uninstall inspec-test-fixture-nonesuch")
54
+
55
+ skip_windows!
56
+ refute_includes "Inspec::Plugin::V2::UnInstallError", uninstall_result.stdout # Stacktrace marker
57
+ assert_match(/No such plugin installed:.+ - uninstall failed/, uninstall_result.stdout)
58
+
59
+ assert_empty uninstall_result.stderr
60
+
61
+ assert_exit_code 1, uninstall_result
62
+ end
63
+ end
@@ -0,0 +1,84 @@
1
+ require_relative "helper"
2
+
3
+ class PluginManagerCliUpdate < Minitest::Test
4
+ include CorePluginFunctionalHelper
5
+ include PluginManagerHelpers
6
+
7
+ def test_when_a_plugin_can_be_updated
8
+ skip "this test requires bundler to pass" unless defined? ::Bundler
9
+
10
+ pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
11
+ plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
12
+ copy_in_core_config_dir("test-fixture-1-float", tmp_dir)
13
+ end
14
+
15
+ update_result = run_inspec_process_with_this_plugin("plugin update inspec-test-fixture", pre_run: pre_block, post_run: list_after_run)
16
+
17
+ success_message = update_result.stdout.split("\n").grep(/updated/).last
18
+ skip_windows!
19
+ refute_nil success_message, "Should find a success message at the end"
20
+ assert_includes success_message, "inspec-test-fixture"
21
+ assert_includes success_message, "0.1.0"
22
+ assert_includes success_message, "0.2.0"
23
+ assert_includes success_message, "updated from rubygems.org"
24
+
25
+ itf_plugin = update_result.payload.list_result.detect { |p| p[:name] == "inspec-test-fixture" }
26
+ refute_nil itf_plugin, "plugin name should now appear in the output of inspec list"
27
+ assert_equal "gem (user)", itf_plugin[:type]
28
+ assert_equal "0.2.0", itf_plugin[:version]
29
+
30
+ assert_empty update_result.stderr
31
+ assert_exit_code 0, update_result
32
+ end
33
+
34
+ def test_refuse_update_when_already_current
35
+ pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
36
+ plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
37
+ copy_in_core_config_dir("test-fixture-2-float", tmp_dir)
38
+ end
39
+
40
+ update_result = run_inspec_process_with_this_plugin("plugin update inspec-test-fixture", pre_run: pre_block)
41
+
42
+ refusal_message = update_result.stdout.split("\n").grep(/refusing/).last
43
+ skip_windows!
44
+ refute_nil refusal_message, "Should find a failure message at the end"
45
+ assert_includes refusal_message, "inspec-test-fixture"
46
+ assert_includes refusal_message, "0.2.0"
47
+ assert_includes refusal_message, "Already installed at latest version"
48
+
49
+ assert_empty update_result.stderr
50
+
51
+ assert_exit_code 2, update_result
52
+ end
53
+
54
+ def test_fail_update_from_nonexistant_gem
55
+ update_result = run_inspec_process_with_this_plugin("plugin update inspec-test-fixture-nonesuch")
56
+
57
+ skip_windows!
58
+ assert_match(/No such plugin installed:.+ - update failed/, update_result.stdout)
59
+
60
+ assert_empty update_result.stderr
61
+
62
+ assert_exit_code 1, update_result
63
+ end
64
+
65
+ def test_fail_update_path
66
+ pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
67
+ plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
68
+ copy_in_core_config_dir("meaning_by_path", tmp_dir)
69
+ end
70
+
71
+ update_result = run_inspec_process_with_this_plugin("plugin update inspec-meaning-of-life", pre_run: pre_block)
72
+
73
+ refusal_message = update_result.stdout.split("\n").grep(/refusing/).last
74
+ skip_windows!
75
+ refute_nil refusal_message, "Should find a failure message at the end"
76
+ assert_includes refusal_message, "inspec-meaning-of-life"
77
+ assert_includes refusal_message, "inspec plugin uninstall"
78
+ assert_includes refusal_message, "Cannot update path-based install"
79
+
80
+ assert_empty update_result.stderr
81
+
82
+ assert_exit_code 2, update_result
83
+ end
84
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.16.0
4
+ version: 4.17.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef InSpec Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-28 00:00:00.000000000 Z
11
+ date: 2019-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: train
@@ -464,6 +464,7 @@ files:
464
464
  - lib/inspec/formatters/show_progress.rb
465
465
  - lib/inspec/globals.rb
466
466
  - lib/inspec/impact.rb
467
+ - lib/inspec/input.rb
467
468
  - lib/inspec/input_registry.rb
468
469
  - lib/inspec/library_eval_context.rb
469
470
  - lib/inspec/log.rb
@@ -608,6 +609,7 @@ files:
608
609
  - lib/inspec/resources/ssl.rb
609
610
  - lib/inspec/resources/sys_info.rb
610
611
  - lib/inspec/resources/toml.rb
612
+ - lib/inspec/resources/user.rb
611
613
  - lib/inspec/resources/users.rb
612
614
  - lib/inspec/resources/vbscript.rb
613
615
  - lib/inspec/resources/virtualization.rb
@@ -758,7 +760,13 @@ files:
758
760
  - lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/inspec-wrong-structure/.gitkeep
759
761
  - lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/wrong-name/lib/wrong-name.rb
760
762
  - lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/wrong-name/lib/wrong-name/.gitkeep
761
- - lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb
763
+ - lib/plugins/inspec-plugin-manager-cli/test/functional/help_test.rb
764
+ - lib/plugins/inspec-plugin-manager-cli/test/functional/helper.rb
765
+ - lib/plugins/inspec-plugin-manager-cli/test/functional/install_test.rb
766
+ - lib/plugins/inspec-plugin-manager-cli/test/functional/list_test.rb
767
+ - lib/plugins/inspec-plugin-manager-cli/test/functional/search_test.rb
768
+ - lib/plugins/inspec-plugin-manager-cli/test/functional/uninstall_test.rb
769
+ - lib/plugins/inspec-plugin-manager-cli/test/functional/update_test.rb
762
770
  - lib/plugins/inspec-plugin-manager-cli/test/unit/cli_args_test.rb
763
771
  - lib/plugins/inspec-plugin-manager-cli/test/unit/plugin_def_test.rb
764
772
  - lib/plugins/shared/core_plugin_test_helper.rb
@@ -1,845 +0,0 @@
1
- #=========================================================================================#
2
- # `inspec plugin SUBCOMMAND` facility
3
- #=========================================================================================#
4
- require_relative "../../../shared/core_plugin_test_helper.rb"
5
-
6
- #-----------------------------------------------------------------------------------------#
7
- # utilities
8
- #-----------------------------------------------------------------------------------------#
9
- module PluginManagerHelpers
10
- let(:project_repo_path) { File.expand_path(File.join(__FILE__, "..", "..", "..")) }
11
- let(:project_fixtures_path) { File.join(project_repo_path, "test", "fixtures") }
12
- let(:project_config_dirs_path) { File.join(project_fixtures_path, "config_dirs") }
13
- let(:empty_config_dir_path) { File.join(project_config_dirs_path, "empty") }
14
-
15
- let(:list_after_run) do
16
- Proc.new do |run_result, tmp_dir|
17
- # After installing/uninstalling/whatevering, run list with config in the same dir, and capture it.
18
- run_result.payload.list_result = parse_plugin_list_lines(
19
- run_inspec_process("plugin list", env: { INSPEC_CONFIG_DIR: tmp_dir }).stdout
20
- )
21
- end
22
- end
23
-
24
- def copy_in_project_config_dir(fixture_name, dest = nil)
25
- src = Dir.glob(File.join(project_config_dirs_path, fixture_name, "*"))
26
- dest ||= File.join(project_config_dirs_path, "empty")
27
- src.each { |path| FileUtils.cp_r(path, dest) }
28
- end
29
-
30
- def copy_in_core_config_dir(fixture_name, dest = nil)
31
- src = Dir.glob(File.join(core_config_dir_path, fixture_name, "*"))
32
- dest ||= File.join(project_config_dirs_path, "empty")
33
- src.each { |path| FileUtils.cp_r(path, dest) }
34
- end
35
-
36
- def clear_empty_config_dir
37
- Dir.glob(File.join(project_config_dirs_path, "empty", "*")).each do |path|
38
- next if path.end_with? ".gitkeep"
39
-
40
- FileUtils.rm_rf(path)
41
- end
42
- end
43
-
44
- def parse_plugin_list_lines(stdout)
45
- plugins = []
46
-
47
- stdout.force_encoding("UTF-8").lines.each do |line|
48
- next if line.strip.empty?
49
- next if line.include? "─────" # This is some unicode glyphiness
50
- next if line.include? "Plugin Name"
51
- next if line.include? "plugin(s) total"
52
-
53
- parts = line.split(/│/u).map(&:strip!).compact
54
- plugins << {
55
- name: parts[0],
56
- version: parts[1],
57
- type: parts[2],
58
- generation: parts[3],
59
- raw: line,
60
- }
61
- end
62
- plugins
63
- end
64
-
65
- def teardown
66
- clear_empty_config_dir
67
- end
68
- end
69
-
70
- #-----------------------------------------------------------------------------------------#
71
- # inspec help
72
- #-----------------------------------------------------------------------------------------#
73
- class PluginManagerCliHelp < Minitest::Test
74
- include CorePluginFunctionalHelper
75
-
76
- # Main inspec help subcommand listing
77
- def test_inspec_help_includes_plugin
78
- result = run_inspec_process_with_this_plugin("help")
79
- skip_windows!
80
- assert_includes result.stdout, "inspec plugin"
81
- end
82
-
83
- # inspec plugin help subcommand listing
84
- def test_inspec_plugin_help_includes_plugin
85
- result = run_inspec_process_with_this_plugin("plugin help")
86
- skip_windows!
87
- assert_includes result.stdout, "inspec plugin list"
88
- assert_includes result.stdout, "inspec plugin search"
89
- assert_includes result.stdout, "inspec plugin install"
90
- assert_includes result.stdout, "inspec plugin update"
91
- assert_includes result.stdout, "inspec plugin uninstall"
92
- end
93
- end
94
-
95
- #-----------------------------------------------------------------------------------------#
96
- # inspec plugin list
97
- #-----------------------------------------------------------------------------------------#
98
- class PluginManagerCliList < Minitest::Test
99
- include CorePluginFunctionalHelper
100
- include PluginManagerHelpers
101
-
102
- # Listing all plugins is now default behavior
103
- LIST_CASES = [
104
- { arg: "-c", name: "inspec-plugin-manager-cli", type: "core" },
105
- { arg: "-c", name: "inspec-supermarket", type: "core" },
106
- { arg: "-s", name: "train-aws", type: "gem (system)" },
107
- ].freeze
108
-
109
- def test_list_all_when_no_user_plugins_installed
110
- result = run_inspec_process_with_this_plugin("plugin list --all")
111
- skip_windows!
112
- assert_empty result.stderr
113
-
114
- plugins_seen = parse_plugin_list_lines(result.stdout)
115
-
116
- # Look for a specific plugin of each type - core, bundle, and system
117
- LIST_CASES.each do |test_case|
118
- plugin_line = plugins_seen.detect { |plugin| plugin[:name] == test_case[:name] }
119
- refute_nil plugin_line, "#{test_case[:name]} should be detected in plugin list --all output"
120
- assert_equal test_case[:type], plugin_line[:type], "#{test_case[:name]} should be detected as a '#{test_case[:type]}' type in list --all "
121
- end
122
- assert_exit_code 0, result
123
- end
124
-
125
- def test_list_selective_when_no_user_plugins_installed
126
- LIST_CASES.each do |test_case|
127
- result = run_inspec_process_with_this_plugin("plugin list #{test_case[:arg]}")
128
- skip_windows!
129
-
130
- assert_empty result.stderr
131
- plugins_seen = parse_plugin_list_lines(result.stdout)
132
- plugin_line = plugins_seen.detect { |plugin| plugin[:name] == test_case[:name] }
133
- refute_nil plugin_line, "#{test_case[:name]} should be detected in plugin list #{test_case[:arg]} output"
134
- assert_equal plugin_line[:type], test_case[:type], "#{test_case[:name]} should be detected as a '#{test_case[:type]}' type in list #{test_case[:arg]} "
135
- assert_exit_code 0, result
136
- end
137
- end
138
-
139
- def test_list_when_gem_and_path_plugins_installed
140
- pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
141
- plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
142
- copy_in_core_config_dir("test-fixture-1-float", tmp_dir)
143
- end
144
-
145
- result = run_inspec_process_with_this_plugin("plugin list --user ", pre_run: pre_block)
146
- skip_windows!
147
-
148
- assert_empty result.stderr
149
- plugins_seen = parse_plugin_list_lines(result.stdout)
150
- assert_equal 2, plugins_seen.count
151
- # Plugin Name Version Via ApiVer
152
- # ---------------------------------------------------------
153
- # inspec-meaning-of-life src path 2
154
- # inspec-test-fixture 0.1.0 gem (user) 2
155
- # ---------------------------------------------------------
156
- # 2 plugin(s) total
157
- meaning = plugins_seen.detect { |p| p[:name] == "inspec-meaning-of-life" }
158
- refute_nil meaning
159
- assert_equal "path", meaning[:type]
160
-
161
- fixture = plugins_seen.detect { |p| p[:name] == "inspec-test-fixture" }
162
- refute_nil fixture
163
- assert_equal "gem (user)", fixture[:type]
164
- assert_equal "0.1.0", fixture[:version]
165
-
166
- assert_exit_code 0, result
167
- end
168
-
169
- def test_list_when_a_train_plugin_is_installed
170
- pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
171
- plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
172
- copy_in_core_config_dir("train-test-fixture", tmp_dir)
173
- end
174
-
175
- result = run_inspec_process_with_this_plugin("plugin list --user ", pre_run: pre_block)
176
- skip_windows!
177
-
178
- assert_empty result.stderr
179
- plugins_seen = parse_plugin_list_lines(result.stdout)
180
- assert_equal 1, plugins_seen.count
181
- assert_includes result.stdout, "1 plugin(s) total", "list train should show one plugins"
182
-
183
- # Plugin Name Version Via ApiVer
184
- # -------------------------------------------------------------
185
- # train-test-fixture 0.1.0 gem (user) train-1
186
- # -------------------------------------------------------------
187
- # 1 plugin(s) total
188
- train_plugin = plugins_seen.detect { |p| p[:name] == "train-test-fixture" }
189
- refute_nil train_plugin
190
- assert_equal "gem (user)", train_plugin[:type]
191
- assert_equal "train-1", train_plugin[:generation]
192
- assert_equal "0.1.0", train_plugin[:version]
193
-
194
- assert_exit_code 0, result
195
- end
196
- end
197
-
198
- #-----------------------------------------------------------------------------------------#
199
- # inspec plugin search
200
- #-----------------------------------------------------------------------------------------#
201
- class PluginManagerCliSearch < Minitest::Test
202
- include CorePluginFunctionalHelper
203
- include PluginManagerHelpers
204
-
205
- # TODO: Thor can't hide options, but we wish it could.
206
- # def test_search_include_fixture_hidden_option
207
- # result = run_inspec_process_with_this_plugin('plugin help search')
208
- # refute_includes result.stdout, '--include-test-fixture'
209
- # end
210
-
211
- def test_search_for_a_real_gem_with_full_name_no_options
212
- result = run_inspec_process("plugin search --include-test-fixture inspec-test-fixture")
213
-
214
- assert_includes result.stdout, "inspec-test-fixture", "Search result should contain the gem name"
215
- assert_includes result.stdout, "1 plugin(s) found", "Search result should find 1 plugin"
216
- line = result.stdout.split("\n").grep(/inspec-test-fixture/).first
217
- assert_match(/\s*inspec-test-fixture\s+\((\d+\.\d+\.\d+){1}\)/, line, "Plugin line should include name and exactly one version")
218
-
219
- assert_exit_code 0, result
220
- end
221
-
222
- def test_search_for_a_real_gem_with_stub_name_no_options
223
- result = run_inspec_process("plugin search --include-test-fixture inspec-test-")
224
-
225
- assert_includes result.stdout, "inspec-test-fixture", "Search result should contain the gem name"
226
- assert_includes result.stdout, "1 plugin(s) found", "Search result should find 1 plugin"
227
-
228
- line = result.stdout.split("\n").grep(/inspec-test-fixture/).first
229
- assert_match(/\s*inspec-test-fixture\s+\((\d+\.\d+\.\d+){1}\)/, line, "Plugin line should include name and exactly one version")
230
-
231
- assert_exit_code 0, result
232
- end
233
-
234
- def test_search_for_a_real_gem_with_full_name_and_exact_option
235
- result = run_inspec_process("plugin search --exact --include-test-fixture inspec-test-fixture")
236
-
237
- assert_includes result.stdout, "inspec-test-fixture", "Search result should contain the gem name"
238
- assert_includes result.stdout, "1 plugin(s) found", "Search result should find 1 plugin"
239
-
240
- assert_exit_code 0, result
241
-
242
- # TODO: split
243
- result = run_inspec_process("plugin search -e --include-test-fixture inspec-test-fixture")
244
-
245
- assert_exit_code 0, result
246
- end
247
-
248
- def test_search_for_a_real_gem_with_stub_name_and_exact_option
249
- result = run_inspec_process("plugin search --exact --include-test-fixture inspec-test-")
250
-
251
- assert_includes result.stdout, "0 plugin(s) found", "Search result should find 0 plugins"
252
-
253
- assert_exit_code 2, result
254
-
255
- # TODO: split
256
- result = run_inspec_process("plugin search -e --include-test-fixture inspec-test-")
257
-
258
- assert_exit_code 2, result
259
- end
260
-
261
- def test_search_for_a_real_gem_with_full_name_and_all_option
262
- result = run_inspec_process("plugin search --all --include-test-fixture inspec-test-fixture")
263
- assert_includes result.stdout, "inspec-test-fixture", "Search result should contain the gem name"
264
- assert_includes result.stdout, "1 plugin(s) found", "Search result should find 1 plugin"
265
-
266
- line = result.stdout.split("\n").grep(/inspec-test-fixture/).first
267
- assert_match(/\s*inspec-test-fixture\s+\((\d+\.\d+\.\d+(,\s)?){2,}\)/, line, "Plugin line should include name and at least two versions")
268
-
269
- assert_exit_code 0, result
270
-
271
- # TODO: split
272
- result = run_inspec_process("plugin search -a --include-test-fixture inspec-test-fixture")
273
-
274
- assert_exit_code 0, result
275
- end
276
-
277
- def test_search_for_a_gem_with_missing_prefix
278
- result = run_inspec_process("plugin search --include-test-fixture test-fixture")
279
- assert_exit_code 1, result
280
- assert_includes result.stdout, "All inspec plugins must begin with either 'inspec-' or 'train-'"
281
- end
282
-
283
- def test_search_for_a_gem_that_does_not_exist
284
- result = run_inspec_process("plugin search --include-test-fixture inspec-test-fixture-nonesuch")
285
-
286
- assert_includes result.stdout, "0 plugin(s) found", "Search result should find 0 plugins"
287
-
288
- assert_exit_code 2, result
289
- end
290
-
291
- def test_search_for_a_real_gem_with_full_name_no_options_and_train_name
292
- result = run_inspec_process("plugin search --include-test-fixture train-test-fixture")
293
-
294
- assert_includes result.stdout, "train-test-fixture", "Search result should contain the gem name"
295
- assert_includes result.stdout, "1 plugin(s) found", "Search result should find 1 plugin"
296
- line = result.stdout.split("\n").grep(/train-test-fixture/).first
297
- assert_match(/\s*train-test-fixture\s+\((\d+\.\d+\.\d+){1}\)/, line, "Plugin line should include name and exactly one version")
298
-
299
- assert_exit_code 0, result
300
- end
301
-
302
- def test_search_omit_excluded_inspec_plugins
303
- result = run_inspec_process("plugin search --include-test-fixture inspec-")
304
-
305
- assert_includes result.stdout, "inspec-test-fixture", "Search result should contain the test gem"
306
- %w{
307
- inspec-core
308
- inspec-multi-server
309
- }.each do |plugin_name|
310
- refute_includes result.stdout, plugin_name, "Search result should not contain excluded gems"
311
- end
312
-
313
- assert_exit_code 0, result
314
- end
315
-
316
- def test_search_for_a_real_gem_with_full_name_no_options_filter_fixtures
317
- result = run_inspec_process("plugin search inspec-test-fixture")
318
- refute_includes result.stdout, "inspec-test-fixture", "Search result should not contain the fixture gem name"
319
- end
320
-
321
- def test_search_for_a_real_gem_with_full_name_no_options_filter_fixtures_train
322
- result = run_inspec_process("plugin search train-test-fixture")
323
- refute_includes result.stdout, "train-test-fixture", "Search result should not contain the fixture gem name"
324
- end
325
-
326
- end
327
-
328
- #-----------------------------------------------------------------------------------------#
329
- # inspec plugin install
330
- #-----------------------------------------------------------------------------------------#
331
- class PluginManagerCliInstall < Minitest::Test
332
- include CorePluginFunctionalHelper # gives us instance methods, like `let` aliases inside test methods
333
- extend CorePluginFunctionalHelper # gives us class methods, like `let` aliases out here outside test methods
334
-
335
- include PluginManagerHelpers
336
- ruby_abi_version = (Gem.ruby_version.segments[0, 2] << 0).join(".")
337
- # Test multiple hueristics of the path-mode install.
338
- # These are all positive tests; they should resolve the entry point to the same path in each case.
339
- {
340
- "is_perfect" => {
341
- given: File.join(core_fixture_plugins_path, "inspec-test-fixture", "lib", "inspec-test-fixture.rb"),
342
- },
343
- "refers_to_the_entry_point_with_no_extension" => {
344
- given: File.join(core_fixture_plugins_path, "inspec-test-fixture", "lib", "inspec-test-fixture"),
345
- },
346
- "refers_to_the_src_root_of_a_plugin" => {
347
- given: File.join(core_fixture_plugins_path, "inspec-test-fixture"),
348
- },
349
- "refers_to_a_versioned_gem_install" => {
350
- given: File.join(core_config_dir_path, "test-fixture-1-float", "gems", ruby_abi_version, "gems", "inspec-test-fixture-0.1.0", "lib", "inspec-test-fixture.rb"),
351
- resolved_path: File.join(core_config_dir_path, "test-fixture-1-float", "gems", ruby_abi_version, "gems", "inspec-test-fixture-0.1.0", "lib", "inspec-test-fixture.rb"),
352
- },
353
- "refers_to_a_versioned_gem_install_missing_extension" => {
354
- given: File.join(core_config_dir_path, "test-fixture-1-float", "gems", ruby_abi_version, "gems", "inspec-test-fixture-0.1.0", "lib", "inspec-test-fixture"),
355
- resolved_path: File.join(core_config_dir_path, "test-fixture-1-float", "gems", ruby_abi_version, "gems", "inspec-test-fixture-0.1.0", "lib", "inspec-test-fixture.rb"),
356
- },
357
- "refers_to_a_relative_path" => {
358
- given: File.join("test", "unit", "mock", "plugins", "inspec-test-fixture", "lib", "inspec-test-fixture.rb"),
359
- },
360
- "refers_to_a_train_plugin" => {
361
- given: File.join(core_config_dir_path, "train-test-fixture", "gems", ruby_abi_version, "gems", "train-test-fixture-0.1.0", "lib", "train-test-fixture.rb"),
362
- plugin_name: "train-test-fixture",
363
- resolved_path: File.join(core_config_dir_path, "train-test-fixture", "gems", ruby_abi_version, "gems", "train-test-fixture-0.1.0", "lib", "train-test-fixture.rb"),
364
- },
365
- }.each do |test_name, fixture_info|
366
- define_method(("test_install_from_path_when_path_" + test_name).to_sym) do
367
- fixture_info = {
368
- plugin_name: "inspec-test-fixture",
369
- resolved_path: File.join(core_fixture_plugins_path, "inspec-test-fixture", "lib", "inspec-test-fixture.rb"),
370
- }.merge(fixture_info)
371
-
372
- install_result = run_inspec_process_with_this_plugin("plugin install #{fixture_info[:given]}", post_run: list_after_run)
373
-
374
- # Check UX messaging
375
- success_message = install_result.stdout.split("\n").grep(/installed/).last
376
- skip_windows!
377
- assert_empty install_result.stderr
378
- refute_nil success_message, "Should find a success message at the end"
379
- assert_includes success_message, fixture_info[:plugin_name]
380
- assert_includes success_message, "plugin installed via source path reference"
381
-
382
- # Check round-trip UX via list
383
- itf_plugin = install_result.payload.list_result.detect { |p| p[:name] == fixture_info[:plugin_name] }
384
- refute_nil itf_plugin, "plugin name should now appear in the output of inspec list"
385
- assert_equal "path", itf_plugin[:type], "list output should show that it is a path installation"
386
-
387
- # Check plugin statefile. Extra important in this case, since all should resolve to the same entry point.
388
- plugin_data = install_result.payload.plugin_data
389
- entry = plugin_data["plugins"].detect { |e| e["name"] == fixture_info[:plugin_name] }
390
- assert_equal fixture_info[:resolved_path], entry["installation_path"], "Regardless of input, the entry point should be correct."
391
-
392
- assert_exit_code 0, install_result
393
- end
394
- end
395
-
396
- def test_fail_install_from_nonexistant_path
397
- bad_path = File.join(project_fixtures_path, "none", "such", "inspec-test-fixture-nonesuch.rb")
398
- install_result = run_inspec_process_with_this_plugin("plugin install #{bad_path}")
399
- skip_windows!
400
-
401
- error_message = install_result.stdout
402
- assert_includes error_message, "No such source code path"
403
- assert_includes error_message, "inspec-test-fixture-nonesuch.rb"
404
- assert_includes error_message, "installation failed"
405
-
406
- assert_empty install_result.stderr
407
-
408
- assert_exit_code 1, install_result
409
- end
410
-
411
- def test_fail_install_from_path_with_wrong_name
412
- bad_path = File.join(project_fixtures_path, "plugins", "wrong-name", "lib", "wrong-name.rb")
413
- install_result = run_inspec_process_with_this_plugin("plugin install #{bad_path}")
414
- skip_windows!
415
-
416
- error_message = install_result.stdout
417
- assert_includes error_message, "Invalid plugin name"
418
- assert_includes error_message, "wrong-name"
419
- assert_includes error_message, "All inspec plugins must begin with either 'inspec-' or 'train-'"
420
- assert_includes error_message, "installation failed"
421
-
422
- assert_empty install_result.stderr
423
-
424
- assert_exit_code 1, install_result
425
- end
426
-
427
- def test_fail_install_from_path_when_it_is_not_a_plugin
428
- bad_path = File.join(project_fixtures_path, "plugins", "inspec-egg-white-omelette", "lib", "inspec-egg-white-omelette.rb")
429
- install_result = run_inspec_process_with_this_plugin("plugin install #{bad_path}")
430
- skip_windows!
431
-
432
- error_message = install_result.stdout
433
- assert_includes error_message, "Does not appear to be a plugin"
434
- assert_includes error_message, "inspec-egg-white-omelette"
435
- assert_includes error_message, "After probe-loading the supposed plugin, it did not register"
436
- assert_includes error_message, "Ensure something inherits from 'Inspec.plugin(2)'"
437
- assert_includes error_message, "installation failed"
438
-
439
- assert_empty install_result.stderr
440
-
441
- assert_exit_code 1, install_result
442
- end
443
-
444
- def test_fail_install_from_path_when_it_is_already_installed
445
- plugin_path = File.join(core_fixture_plugins_path, "inspec-test-fixture", "lib", "inspec-test-fixture.rb")
446
- pre_block = Proc.new do |plugin_data, _tmp_dir|
447
- plugin_data["plugins"] << {
448
- "name" => "inspec-test-fixture",
449
- "installation_type" => "path",
450
- "installation_path" => plugin_path,
451
- }
452
- end
453
-
454
- install_result = run_inspec_process_with_this_plugin("plugin install #{plugin_path}", pre_run: pre_block)
455
- skip_windows!
456
-
457
- error_message = install_result.stdout
458
- assert_includes error_message, "Plugin already installed"
459
- assert_includes error_message, "inspec-test-fixture"
460
- assert_includes error_message, "Use 'inspec plugin list' to see previously installed plugin"
461
- assert_includes error_message, "installation failed"
462
-
463
- assert_empty install_result.stderr
464
-
465
- assert_exit_code 2, install_result
466
- end
467
-
468
- def test_fail_install_from_path_when_the_dir_structure_is_wrong
469
- bad_path = File.join(project_fixtures_path, "plugins", "inspec-wrong-structure")
470
- install_result = run_inspec_process_with_this_plugin("plugin install #{bad_path}")
471
- skip_windows!
472
-
473
- error_message = install_result.stdout
474
- assert_includes error_message, "Unrecognizable plugin structure"
475
- assert_includes error_message, "inspec-wrong-structure"
476
- assert_includes error_message, " When installing from a path, please provide the path of the entry point file"
477
- assert_includes error_message, "installation failed"
478
-
479
- assert_empty install_result.stderr
480
-
481
- assert_exit_code 1, install_result
482
- end
483
-
484
- def test_install_from_gemfile
485
- fixture_gemfile_path = File.join(core_fixture_plugins_path, "inspec-test-fixture", "pkg", "inspec-test-fixture-0.1.0.gem")
486
- install_result = run_inspec_process_with_this_plugin("plugin install #{fixture_gemfile_path}", post_run: list_after_run)
487
- skip_windows!
488
-
489
- success_message = install_result.stdout.split("\n").grep(/installed/).last
490
- refute_nil success_message, "Should find a success message at the end"
491
- assert_includes success_message, "installed from local .gem file"
492
-
493
- itf_plugin = install_result.payload.list_result.detect { |p| p[:name] == "inspec-test-fixture" }
494
- refute_nil itf_plugin, "plugin name should now appear in the output of inspec list"
495
- assert_equal "gem (user)", itf_plugin[:type]
496
- assert_equal "0.1.0", itf_plugin[:version]
497
-
498
- assert_empty install_result.stderr
499
- assert_exit_code 0, install_result
500
- end
501
-
502
- def test_fail_install_from_nonexistant_gemfile
503
- bad_path = File.join(project_fixtures_path, "none", "such", "inspec-test-fixture-nonesuch-0.3.0.gem")
504
- install_result = run_inspec_process_with_this_plugin("plugin install #{bad_path}")
505
-
506
- skip_windows!
507
- assert_match(/No such plugin gem file .+ - installation failed./, install_result.stdout)
508
-
509
- assert_empty install_result.stderr
510
-
511
- assert_exit_code 1, install_result
512
- end
513
-
514
- def test_install_from_rubygems_latest
515
- install_result = run_inspec_process_with_this_plugin("plugin install inspec-test-fixture", post_run: list_after_run)
516
- skip_windows!
517
-
518
- success_message = install_result.stdout.split("\n").grep(/installed/).last
519
- refute_nil success_message, "Should find a success message at the end"
520
- assert_includes success_message, "inspec-test-fixture"
521
- assert_includes success_message, "0.2.0"
522
- assert_includes success_message, "installed from rubygems.org"
523
-
524
- itf_plugin = install_result.payload.list_result.detect { |p| p[:name] == "inspec-test-fixture" }
525
- refute_nil itf_plugin, "plugin name should now appear in the output of inspec list"
526
- assert_equal "gem (user)", itf_plugin[:type]
527
- assert_equal "0.2.0", itf_plugin[:version]
528
-
529
- assert_empty install_result.stderr
530
- assert_exit_code 0, install_result
531
- end
532
-
533
- def test_fail_install_from_nonexistant_remote_rubygem
534
- install_result = run_inspec_process_with_this_plugin("plugin install inspec-test-fixture-nonesuch")
535
-
536
- skip_windows!
537
- assert_match(/No such plugin gem .+ could be found on rubygems.org - installation failed./, install_result.stdout)
538
-
539
- assert_empty install_result.stderr
540
-
541
- assert_exit_code 1, install_result
542
- end
543
-
544
- def test_install_from_rubygems_with_pinned_version
545
- install_result = run_inspec_process_with_this_plugin("plugin install inspec-test-fixture -v 0.1.0", post_run: list_after_run)
546
-
547
- success_message = install_result.stdout.split("\n").grep(/installed/).last
548
- skip_windows!
549
- refute_nil success_message, "Should find a success message at the end"
550
- assert_includes success_message, "inspec-test-fixture"
551
- assert_includes success_message, "0.1.0"
552
- assert_includes success_message, "installed from rubygems.org"
553
-
554
- itf_plugin = install_result.payload.list_result.detect { |p| p[:name] == "inspec-test-fixture" }
555
- refute_nil itf_plugin, "plugin name should now appear in the output of inspec list"
556
- assert_equal "gem (user)", itf_plugin[:type]
557
- assert_equal "0.1.0", itf_plugin[:version]
558
-
559
- assert_empty install_result.stderr
560
-
561
- assert_exit_code 0, install_result
562
- end
563
-
564
- def test_fail_install_from_nonexistant_rubygem_version
565
- install_result = run_inspec_process_with_this_plugin("plugin install inspec-test-fixture -v 99.99.99")
566
-
567
- fail_message = install_result.stdout.split("\n").grep(/failed/).last
568
- skip_windows!
569
- refute_nil fail_message, "Should find a failure message at the end"
570
- assert_includes fail_message, "inspec-test-fixture"
571
- assert_includes fail_message, "99.99.99"
572
- assert_includes fail_message, "no such version"
573
- assert_includes fail_message, "on rubygems.org"
574
-
575
- assert_empty install_result.stderr
576
-
577
- assert_exit_code 1, install_result
578
- end
579
-
580
- def test_refuse_install_when_missing_prefix
581
- install_result = run_inspec_process_with_this_plugin("plugin install test-fixture")
582
-
583
- fail_message = install_result.stdout.split("\n").grep(/failed/).last
584
- skip_windows!
585
- refute_nil fail_message, "Should find a failure message at the end"
586
- assert_includes fail_message, "test-fixture"
587
- assert_includes fail_message, "All inspec plugins must begin with either 'inspec-' or 'train-'"
588
-
589
- assert_empty install_result.stderr
590
-
591
- assert_exit_code 1, install_result
592
- end
593
-
594
- def test_refuse_install_when_already_installed_same_version
595
- pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
596
- plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
597
- copy_in_core_config_dir("test-fixture-2-float", tmp_dir)
598
- end
599
-
600
- install_result = run_inspec_process_with_this_plugin("plugin install inspec-test-fixture", pre_run: pre_block)
601
-
602
- refusal_message = install_result.stdout.split("\n").grep(/refusing/).last
603
- skip_windows!
604
- refute_nil refusal_message, "Should find a failure message at the end"
605
- assert_includes refusal_message, "inspec-test-fixture"
606
- assert_includes refusal_message, "0.2.0"
607
- assert_includes refusal_message, "Plugin already installed at latest version"
608
-
609
- assert_empty install_result.stderr
610
-
611
- assert_exit_code 2, install_result
612
- end
613
-
614
- def test_refuse_install_when_already_installed_can_update
615
- pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
616
- plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
617
- copy_in_core_config_dir("test-fixture-1-float", tmp_dir)
618
- end
619
-
620
- install_result = run_inspec_process_with_this_plugin("plugin install inspec-test-fixture", pre_run: pre_block)
621
-
622
- refusal_message = install_result.stdout.split("\n").grep(/refusing/).last
623
- skip_windows!
624
- refute_nil refusal_message, "Should find a failure message at the end"
625
- assert_includes refusal_message, "inspec-test-fixture"
626
- assert_includes refusal_message, "0.1.0"
627
- assert_includes refusal_message, "0.2.0"
628
- assert_includes refusal_message, "Update required"
629
- assert_includes refusal_message, "inspec plugin update"
630
-
631
- assert_empty install_result.stderr
632
-
633
- assert_exit_code 2, install_result
634
- end
635
-
636
- def test_install_from_rubygems_latest_with_train_plugin
637
- install_result = run_inspec_process_with_this_plugin("plugin install train-test-fixture", post_run: list_after_run)
638
- skip_windows!
639
-
640
- success_message = install_result.stdout.split("\n").grep(/installed/).last
641
- refute_nil success_message, "Should find a success message at the end"
642
- assert_includes success_message, "train-test-fixture"
643
- assert_includes success_message, "0.1.0"
644
- assert_includes success_message, "installed from rubygems.org"
645
-
646
- ttf_plugin = install_result.payload.list_result.detect { |p| p[:name] == "train-test-fixture" }
647
- refute_nil ttf_plugin, "plugin name should now appear in the output of inspec list"
648
- assert_equal "gem (user)", ttf_plugin[:type]
649
- assert_equal "0.1.0", ttf_plugin[:version]
650
-
651
- assert_empty install_result.stderr
652
- assert_exit_code 0, install_result
653
- end
654
-
655
- def test_refuse_install_when_plugin_on_exclusion_list
656
- # Here, 'inspec-core', 'inspec-multi-server', and 'train-tax-collector'
657
- # are the names of real rubygems. They are not InSpec/Train plugins, though,
658
- # and installing them would be a jam-up.
659
- # This is configured in 'etc/plugin-filter.json'.
660
- %w{
661
- inspec-core
662
- inspec-multi-server
663
- train-tax-calculator
664
- }.each do |plugin_name|
665
- install_result = run_inspec_process_with_this_plugin("plugin install #{plugin_name}")
666
- refusal_message = install_result.stdout
667
- refute_nil refusal_message, "Should find a failure message at the end"
668
- skip_windows!
669
- assert_includes refusal_message, plugin_name
670
- assert_includes refusal_message, "Plugin on Exclusion List"
671
- assert_includes refusal_message, "refusing to install"
672
- assert_includes refusal_message, "Rationale:"
673
- assert_includes refusal_message, "etc/plugin_filters.json"
674
- assert_includes refusal_message, "github.com/inspec/inspec/issues/new"
675
-
676
- assert_empty install_result.stderr
677
-
678
- assert_exit_code 2, install_result
679
- end
680
- end
681
-
682
- def test_error_install_with_debug_enabled
683
- skip "this test requires bundler to pass" unless defined? ::Bundler
684
-
685
- install_result = run_inspec_process_with_this_plugin("plugin install inspec-test-fixture -v 0.1.1 --log-level debug")
686
- skip_windows!
687
-
688
- assert_includes install_result.stdout, "DEBUG"
689
-
690
- assert_includes install_result.stderr, "can't activate rake"
691
-
692
- assert_exit_code 1, install_result
693
- end
694
- end
695
-
696
- #-----------------------------------------------------------------------------------------#
697
- # inspec plugin update
698
- #-----------------------------------------------------------------------------------------#
699
- class PluginManagerCliUpdate < Minitest::Test
700
- include CorePluginFunctionalHelper
701
- include PluginManagerHelpers
702
-
703
- def test_when_a_plugin_can_be_updated
704
- skip "this test requires bundler to pass" unless defined? ::Bundler
705
-
706
- pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
707
- plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
708
- copy_in_core_config_dir("test-fixture-1-float", tmp_dir)
709
- end
710
-
711
- update_result = run_inspec_process_with_this_plugin("plugin update inspec-test-fixture", pre_run: pre_block, post_run: list_after_run)
712
-
713
- success_message = update_result.stdout.split("\n").grep(/updated/).last
714
- skip_windows!
715
- refute_nil success_message, "Should find a success message at the end"
716
- assert_includes success_message, "inspec-test-fixture"
717
- assert_includes success_message, "0.1.0"
718
- assert_includes success_message, "0.2.0"
719
- assert_includes success_message, "updated from rubygems.org"
720
-
721
- itf_plugin = update_result.payload.list_result.detect { |p| p[:name] == "inspec-test-fixture" }
722
- refute_nil itf_plugin, "plugin name should now appear in the output of inspec list"
723
- assert_equal "gem (user)", itf_plugin[:type]
724
- assert_equal "0.2.0", itf_plugin[:version]
725
-
726
- assert_empty update_result.stderr
727
- assert_exit_code 0, update_result
728
- end
729
-
730
- def test_refuse_update_when_already_current
731
- pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
732
- plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
733
- copy_in_core_config_dir("test-fixture-2-float", tmp_dir)
734
- end
735
-
736
- update_result = run_inspec_process_with_this_plugin("plugin update inspec-test-fixture", pre_run: pre_block)
737
-
738
- refusal_message = update_result.stdout.split("\n").grep(/refusing/).last
739
- skip_windows!
740
- refute_nil refusal_message, "Should find a failure message at the end"
741
- assert_includes refusal_message, "inspec-test-fixture"
742
- assert_includes refusal_message, "0.2.0"
743
- assert_includes refusal_message, "Already installed at latest version"
744
-
745
- assert_empty update_result.stderr
746
-
747
- assert_exit_code 2, update_result
748
- end
749
-
750
- def test_fail_update_from_nonexistant_gem
751
- update_result = run_inspec_process_with_this_plugin("plugin update inspec-test-fixture-nonesuch")
752
-
753
- skip_windows!
754
- assert_match(/No such plugin installed:.+ - update failed/, update_result.stdout)
755
-
756
- assert_empty update_result.stderr
757
-
758
- assert_exit_code 1, update_result
759
- end
760
-
761
- def test_fail_update_path
762
- pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
763
- plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
764
- copy_in_core_config_dir("meaning_by_path", tmp_dir)
765
- end
766
-
767
- update_result = run_inspec_process_with_this_plugin("plugin update inspec-meaning-of-life", pre_run: pre_block)
768
-
769
- refusal_message = update_result.stdout.split("\n").grep(/refusing/).last
770
- skip_windows!
771
- refute_nil refusal_message, "Should find a failure message at the end"
772
- assert_includes refusal_message, "inspec-meaning-of-life"
773
- assert_includes refusal_message, "inspec plugin uninstall"
774
- assert_includes refusal_message, "Cannot update path-based install"
775
-
776
- assert_empty update_result.stderr
777
-
778
- assert_exit_code 2, update_result
779
- end
780
- end
781
-
782
- #-----------------------------------------------------------------------------------------#
783
- # inspec plugin uninstall
784
- #-----------------------------------------------------------------------------------------#
785
- class PluginManagerCliUninstall < Minitest::Test
786
- include CorePluginFunctionalHelper
787
- include PluginManagerHelpers
788
-
789
- def test_when_a_gem_plugin_can_be_uninstalled
790
- pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
791
- plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
792
- copy_in_core_config_dir("test-fixture-1-float", tmp_dir)
793
- end
794
-
795
- # Attempt uninstall
796
- uninstall_result = run_inspec_process_with_this_plugin("plugin uninstall inspec-test-fixture", pre_run: pre_block, post_run: list_after_run)
797
-
798
- success_message = uninstall_result.stdout.split("\n").grep(/uninstalled/).last
799
- skip_windows!
800
- refute_nil success_message, "Should find a success message at the end"
801
- assert_includes success_message, "inspec-test-fixture"
802
- assert_includes success_message, "0.1.0"
803
- assert_includes success_message, "has been uninstalled"
804
-
805
- itf_plugins = uninstall_result.payload.list_result.select { |p| p[:name] == "inspec-test-fixture" }
806
- assert_empty itf_plugins, "inspec-test-fixture should not appear in the output of inspec list"
807
-
808
- assert_empty uninstall_result.stderr
809
- assert_exit_code 0, uninstall_result
810
- end
811
-
812
- def test_when_a_path_plugin_can_be_uninstalled
813
- pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
814
- plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
815
- # This fixture includes a path install for inspec-meaning-of-life
816
- copy_in_core_config_dir("test-fixture-1-float", tmp_dir)
817
- end
818
- uninstall_result = run_inspec_process_with_this_plugin("plugin uninstall inspec-meaning-of-life", pre_run: pre_block, post_run: list_after_run)
819
- skip_windows!
820
-
821
- success_message = uninstall_result.stdout.split("\n").grep(/uninstalled/).last
822
- refute_nil success_message, "Should find a success message at the end"
823
- assert_includes success_message, "inspec-meaning-of-life"
824
- assert_includes success_message, "path-based plugin install"
825
- assert_includes success_message, "has been uninstalled"
826
-
827
- itf_plugins = uninstall_result.payload.list_result.select { |p| p[:name] == "inspec-meaning-of-life" }
828
- assert_empty itf_plugins, "inspec-meaning-of-life should not appear in the output of inspec list"
829
-
830
- assert_empty uninstall_result.stderr
831
- assert_exit_code 0, uninstall_result
832
- end
833
-
834
- def test_fail_uninstall_from_plugin_that_is_not_installed
835
- uninstall_result = run_inspec_process_with_this_plugin("plugin uninstall inspec-test-fixture-nonesuch")
836
-
837
- skip_windows!
838
- refute_includes "Inspec::Plugin::V2::UnInstallError", uninstall_result.stdout # Stacktrace marker
839
- assert_match(/No such plugin installed:.+ - uninstall failed/, uninstall_result.stdout)
840
-
841
- assert_empty uninstall_result.stderr
842
-
843
- assert_exit_code 1, uninstall_result
844
- end
845
- end