Module: CorePluginFunctionalHelper

Constant Summary collapse

TRAIN_CONNECTION =
Train.create("local", command_runner: :generic).connection

Instance Method Summary collapse

Instance Method Details

#__find_plugin_path_from_caller(frames_back = 2) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/plugins/shared/core_plugin_test_helper.rb', line 112

def __find_plugin_path_from_caller(frames_back = 2)
  caller_path = Pathname.new(caller_locations(frames_back, 1).first.absolute_path)
  # Typical caller path:
  # /Users/cwolfe/sandbox/inspec-resource-lister/test/functional/inspec_resource_lister_test.rb
  # We want:
  # /Users/cwolfe/sandbox/inspec-resource-lister/lib/inspec-resource-lister.rb
  cursor = caller_path
  until cursor.basename.to_s == "test" && cursor.parent.basename.to_s =~ /^(inspec|train)-/
    cursor = cursor.parent
    break if cursor.nil?
  end
  raise "Could not comprehend plugin project directory structure" if cursor.nil?

  project_dir = cursor.parent
  plugin_name = project_dir.basename
  entry_point = File.join(project_dir.to_s, "lib", plugin_name.to_s + ".rb")
  raise "Could not find plugin entry point" unless File.exist?(entry_point)

  entry_point
end

#__make_empty_plugin_file_data_structureObject



145
146
147
148
149
150
151
# File 'lib/plugins/shared/core_plugin_test_helper.rb', line 145

def __make_empty_plugin_file_data_structure
  # TODO: dry this up, refs #3350
  {
    "plugins_config_version" => "1.0.0",
    "plugins" => [],
  }
end

#__make_plugin_file_data_structure_with_path(path) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/plugins/shared/core_plugin_test_helper.rb', line 133

def __make_plugin_file_data_structure_with_path(path)
  # TODO: dry this up, refs #3350
  plugin_name = File.basename(path, ".rb")
  data = __make_empty_plugin_file_data_structure
  data["plugins"] << {
    "name" => plugin_name,
    "installation_type" => "path",
    "installation_path" => path,
  }
  data
end

#run_inspec_process(command_line, opts = {}) ⇒ Object



61
62
63
64
65
66
67
68
69
# File 'lib/plugins/shared/core_plugin_test_helper.rb', line 61

def run_inspec_process(command_line, opts = {})
  prefix = ""
  if opts.key?(:prefix)
    prefix = opts[:prefix]
  elsif opts.key?(:env)
    prefix = opts[:env].to_a.map { |assignment| "#{assignment[0]}=#{assignment[1]}" }.join(" ")
  end
  Inspec::FuncTestRunResult.new(TRAIN_CONNECTION.run_command("#{prefix} #{exec_inspec} #{command_line}"))
end

#run_inspec_process_with_this_plugin(command_line, opts = {}) ⇒ Object

This helper does some fancy footwork to make InSpec think a plugin under development is temporarily installed.

Parameters:

  • String

    command_line Invocation, without the word ‘inspec’

  • Hash

    opts options as for run_inspec_process, with more options: :pre_run: Proc(plugin_statefile_data, tmp_dir_path) - optional setup block.

    Modify plugin_statefile_data as needed; it will be written to a plugins.json
    in tmp_dir_path.  You may also copy in other things to the tmp_dir_path. Your PWD
    will be in the tmp_dir, and it will exist and be empty.
    

    :post_run: Proc(FuncTestRunResult, tmp_dir_path) - optional result capture block.

    run_result will be populated, but you can add more to the ostruct .payload
    Your PWD will be the tmp_dir, and it will still exist (for a moment!)
    


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/plugins/shared/core_plugin_test_helper.rb', line 82

def run_inspec_process_with_this_plugin(command_line, opts = {})
  plugin_path = __find_plugin_path_from_caller

  # If it looks like it is a core plugin under test, don't add it to the plugin file
  # since the loader will auto-load it anyway
  if plugin_path.include?("lib/plugins/inspec-")
    plugin_file_data = __make_empty_plugin_file_data_structure
  else
    plugin_file_data = __make_plugin_file_data_structure_with_path(plugin_path)
  end

  Dir.mktmpdir do |tmp_dir|
    opts[:pre_run]&.call(plugin_file_data, tmp_dir)
    plugin_file_path = File.join(tmp_dir, "plugins.json")
    # HACK: If the block cleared the hash, take that to mean it will provide a plugins.json file of its own.
    File.write(plugin_file_path, JSON.generate(plugin_file_data)) unless plugin_file_data.empty?
    opts[:env] ||= {}
    opts[:env]["INSPEC_CONFIG_DIR"] = tmp_dir
    run_result = run_inspec_process(command_line, opts)

    # Read the resulting plugins.json into memory, if any
    if File.exist?(plugin_file_path)
      run_result.payload.plugin_data = JSON.parse(File.read(plugin_file_path))
    end

    opts[:post_run]&.call(run_result, tmp_dir)
    run_result
  end
end