From 0f81816311af3ea946f232da4312e15f7180f916 Mon Sep 17 00:00:00 2001 From: Ry Biesemeyer Date: Thu, 27 Feb 2025 13:24:04 -0800 Subject: [PATCH] qa: don't bypass plugin manger tests on linux (#17171) * qa: don't bypass plugin manger tests on linux * add gradle task to build gem fixtures for integration tests --- build.gradle | 3 +- qa/integration/build.gradle | 13 + qa/integration/fixtures/plugins/.gitignore | 1 + qa/integration/specs/cli/install_spec.rb | 19 +- qa/integration/specs/cli/remove_spec.rb | 316 ++++++++++----------- 5 files changed, 183 insertions(+), 169 deletions(-) create mode 100644 qa/integration/fixtures/plugins/.gitignore diff --git a/build.gradle b/build.gradle index 8696ac4b2f8..31272e786fb 100644 --- a/build.gradle +++ b/build.gradle @@ -594,7 +594,8 @@ project(":logstash-integration-tests") { systemProperty 'org.logstash.integration.specs', rubyIntegrationSpecs environment "FEATURE_FLAG", System.getenv('FEATURE_FLAG') workingDir integrationTestPwd - dependsOn = [installIntegrationTestGems, copyProductionLog4jConfiguration] + dependsOn installIntegrationTestGems + dependsOn copyProductionLog4jConfiguration } } diff --git a/qa/integration/build.gradle b/qa/integration/build.gradle index 3cf9a5455b3..f54d1abfaf4 100644 --- a/qa/integration/build.gradle +++ b/qa/integration/build.gradle @@ -60,11 +60,24 @@ clean { delete "${projectDir}/fixtures/logs_rollover/log4j2.properties" } +tasks.register("preparePluginTestFixtures", Exec) { + + def fixtureDir = layout.projectDirectory.dir("fixtures/plugins") + def scriptPath = fixtureDir.file("generate-gems.sh") + + inputs.file scriptPath + inputs.files fileTree(fixtureDir) { include("*.gemspec") } + outputs.files fileTree(fixtureDir) { include("*.gem") } + + commandLine = scriptPath.toString() +} + tasks.register("integrationTests", Test) { if ((JavaVersion.current().getMajorVersion() as int) >= 17) { jvmArgs = ['--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED', '--add-opens', 'java.base/java.io=ALL-UNNAMED'] } dependsOn copyProductionLog4jConfiguration + dependsOn preparePluginTestFixtures inputs.files fileTree("${projectDir}/services") inputs.files fileTree("${projectDir}/framework") diff --git a/qa/integration/fixtures/plugins/.gitignore b/qa/integration/fixtures/plugins/.gitignore new file mode 100644 index 00000000000..c111b331371 --- /dev/null +++ b/qa/integration/fixtures/plugins/.gitignore @@ -0,0 +1 @@ +*.gem diff --git a/qa/integration/specs/cli/install_spec.rb b/qa/integration/specs/cli/install_spec.rb index 494b51d049e..89a97973c6e 100644 --- a/qa/integration/specs/cli/install_spec.rb +++ b/qa/integration/specs/cli/install_spec.rb @@ -78,20 +78,19 @@ def gem_in_lock_file?(pattern, lock_file) expect(gem_in_lock_file?(/gemoji/, @logstash.lock_file)).to be_truthy end end - else + end - context "with internet connection" do - it "successfully install the pack" do - execute = @logstash_plugin.run_raw("#{install_command} #{pack}", change_dir) + context "with internet connection" do + it "successfully install the pack" do + execute = @logstash_plugin.run_raw("#{install_command} #{pack}", change_dir) - expect(execute.stderr_and_stdout).to match(INSTALL_SUCCESS_RE) - expect(execute.exit_code).to eq(0) + expect(execute.stderr_and_stdout).to match(INSTALL_SUCCESS_RE) + expect(execute.exit_code).to eq(0) - installed = @logstash_plugin.list("logstash-output-secret") - expect(installed.stderr_and_stdout).to match(/logstash-output-secret/) + installed = @logstash_plugin.list("logstash-output-secret") + expect(installed.stderr_and_stdout).to match(/logstash-output-secret/) - expect(gem_in_lock_file?(/gemoji/, @logstash.lock_file)).to be_truthy - end + expect(gem_in_lock_file?(/gemoji/, @logstash.lock_file)).to be_truthy end end end diff --git a/qa/integration/specs/cli/remove_spec.rb b/qa/integration/specs/cli/remove_spec.rb index efc64f1be27..b3d914f6565 100644 --- a/qa/integration/specs/cli/remove_spec.rb +++ b/qa/integration/specs/cli/remove_spec.rb @@ -27,54 +27,18 @@ @logstash_plugin = @fixture.get_service("logstash").plugin_cli end - if RbConfig::CONFIG["host_os"] == "linux" - context "without internet connection (linux seccomp wrapper)" do - let(:offline_wrapper_path) { File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "fixtures", "offline_wrapper")) } - let(:offline_wrapper_cmd) { File.join(offline_wrapper_path, "offline") } - - before do - Dir.chdir(offline_wrapper_path) do - system("make clean") - system("make") - end - end - - context "when no other plugins depends on this plugin" do - let(:test_plugin) { "logstash-filter-qatest" } - - before :each do - @logstash_plugin.install(File.join(File.dirname(__FILE__), "..", "..", "fixtures", "logstash-filter-qatest-0.1.1.gem")) - end - - it "successfully remove the plugin" do - execute = @logstash_plugin.run_raw("#{offline_wrapper_cmd} bin/logstash-plugin remove #{test_plugin}") - - expect(execute.exit_code).to eq(0) - expect(execute.stderr_and_stdout).to match(/Successfully removed #{test_plugin}/) - - presence_check = @logstash_plugin.list(test_plugin) - expect(presence_check.exit_code).to eq(1) - expect(presence_check.stderr_and_stdout).to match(/ERROR: No plugins found/) - end - end - - context "when other plugins depends on this plugin" do - it "refuses to remove the plugin and display the plugin that depends on it." do - execute = @logstash_plugin.run_raw("#{offline_wrapper_cmd} bin/logstash-plugin remove logstash-codec-json") - - expect(execute.exit_code).to eq(1) - expect(execute.stderr_and_stdout).to match(/Failed to remove "logstash-codec-json"/) - expect(execute.stderr_and_stdout).to match(/logstash-integration-kafka/) # one of the dependency - expect(execute.stderr_and_stdout).to match(/logstash-output-udp/) # one of the dependency - - presence_check = @logstash_plugin.list("logstash-codec-json") - - expect(presence_check.exit_code).to eq(0) - expect(presence_check.stderr_and_stdout).to match(/logstash-codec-json/) - end + if RbConfig::CONFIG["host_os"] == "linux" + context "without internet connection (linux seccomp wrapper)" do + let(:offline_wrapper_path) { File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "fixtures", "offline_wrapper")) } + let(:offline_wrapper_cmd) { File.join(offline_wrapper_path, "offline") } + + before do + Dir.chdir(offline_wrapper_path) do + system("make clean") + system("make") end end - else + context "when no other plugins depends on this plugin" do let(:test_plugin) { "logstash-filter-qatest" } @@ -83,7 +47,7 @@ end it "successfully remove the plugin" do - execute = @logstash_plugin.remove(test_plugin) + execute = @logstash_plugin.run_raw("#{offline_wrapper_cmd} bin/logstash-plugin remove #{test_plugin}") expect(execute.exit_code).to eq(0) expect(execute.stderr_and_stdout).to match(/Successfully removed #{test_plugin}/) @@ -96,7 +60,7 @@ context "when other plugins depends on this plugin" do it "refuses to remove the plugin and display the plugin that depends on it." do - execute = @logstash_plugin.remove("logstash-codec-json") + execute = @logstash_plugin.run_raw("#{offline_wrapper_cmd} bin/logstash-plugin remove logstash-codec-json") expect(execute.exit_code).to eq(1) expect(execute.stderr_and_stdout).to match(/Failed to remove "logstash-codec-json"/) @@ -109,131 +73,167 @@ expect(presence_check.stderr_and_stdout).to match(/logstash-codec-json/) end end + end + end - context "multiple plugins" do + context "when no other plugins depends on this plugin" do + let(:test_plugin) { "logstash-filter-qatest" } - let(:setup_plugin_list) do - fail("spec must override `setup_plugin_list`") - end + before :each do + @logstash_plugin.install(File.join(File.dirname(__FILE__), "..", "..", "fixtures", "logstash-filter-qatest-0.1.1.gem")) + end - before(:each) do - if setup_plugin_list.any? - search_dir = File.expand_path(File.join(__dir__, "..", "..", "fixtures", "plugins")) - plugin_paths = [] - - aggregate_failures('setup: resolve plugin paths') do - setup_plugin_list.each do |requested_plugin| - found = Dir.glob(File.join(search_dir, "#{requested_plugin}-*.gem")) - expect(found).to have_attributes(:size => 1), lambda { "expected exactly one `#{requested_plugin}` in `#{search_dir}`, got #{found.inspect}" } - plugin_paths << found.first - end - end + it "successfully remove the plugin" do + execute = @logstash_plugin.remove(test_plugin) - aggregate_failures('setup: installing plugins') do - puts "installing plugins #{plugin_paths.inspect}" - outcome = @logstash_plugin.install(*plugin_paths) + expect(execute.exit_code).to eq(0) + expect(execute.stderr_and_stdout).to match(/Successfully removed #{test_plugin}/) - expect(outcome.exit_code).to eq(0) - expect(outcome.stderr_and_stdout).to match(/Installation successful/) - end + presence_check = @logstash_plugin.list(test_plugin) + expect(presence_check.exit_code).to eq(1) + expect(presence_check.stderr_and_stdout).to match(/ERROR: No plugins found/) + end + end + + context "when other plugins depends on this plugin" do + it "refuses to remove the plugin and display the plugin that depends on it." do + execute = @logstash_plugin.remove("logstash-codec-json") + + expect(execute.exit_code).to eq(1) + expect(execute.stderr_and_stdout).to match(/Failed to remove "logstash-codec-json"/) + expect(execute.stderr_and_stdout).to match(/logstash-integration-kafka/) # one of the dependency + expect(execute.stderr_and_stdout).to match(/logstash-output-udp/) # one of the dependency + + presence_check = @logstash_plugin.list("logstash-codec-json") + + expect(presence_check.exit_code).to eq(0) + expect(presence_check.stderr_and_stdout).to match(/logstash-codec-json/) + end + end + + context "multiple plugins" do + + let(:setup_plugin_list) do + fail("spec must override `setup_plugin_list`") + end + + before(:each) do + if setup_plugin_list.any? + search_dir = File.expand_path(File.join(__dir__, "..", "..", "fixtures", "plugins")) + plugin_paths = [] + + aggregate_failures('setup: resolve plugin paths') do + setup_plugin_list.each do |requested_plugin| + found = Dir.glob(File.join(search_dir, "#{requested_plugin}-*.gem")) + expect(found).to have_attributes(:size => 1), lambda { "expected exactly one `#{requested_plugin}` in `#{search_dir}`, got #{found.inspect}" } + plugin_paths << found.first end end - context "when a remaining plugin has a dependency on a removed plugin" do - let(:setup_plugin_list) do - %w( - logstash-filter-zero_no_dependencies - logstash-filter-one_no_dependencies - logstash-filter-two_depends_on_one - logstash-filter-three_no_dependencies - logstash-filter-four_depends_on_one_and_three - ) - end - it "errors helpfully without removing any of the plugins" do - execute = @logstash_plugin.remove("logstash-filter-three_no_dependencies", "logstash-filter-zero_no_dependencies") - - expect(execute.exit_code).to eq(1) - expect(execute.stderr_and_stdout).to include('Failed to remove "logstash-filter-three_no_dependencies"') - expect(execute.stderr_and_stdout).to include("* logstash-filter-four_depends_on_one_and_three") # one of the dependency - expect(execute.stderr_and_stdout).to include("No plugins were removed.") - - aggregate_failures("list plugins") do - presence_check = @logstash_plugin.list - expect(presence_check.exit_code).to eq(0) - expect(presence_check.stderr_and_stdout).to include('logstash-filter-three_no_dependencies') - expect(presence_check.stderr_and_stdout).to include('logstash-filter-zero_no_dependencies') - end - end + aggregate_failures('setup: installing plugins') do + puts "installing plugins #{plugin_paths.inspect}" + outcome = @logstash_plugin.install(*plugin_paths) + + expect(outcome.exit_code).to eq(0) + expect(outcome.stderr_and_stdout).to match(/Installation successful/) end - context "when multiple remaining plugins have a dependency on a removed plugin" do - let(:setup_plugin_list) do - %w( - logstash-filter-zero_no_dependencies - logstash-filter-one_no_dependencies - logstash-filter-two_depends_on_one - logstash-filter-three_no_dependencies - logstash-filter-four_depends_on_one_and_three - ) - end - it "errors helpfully without removing any of the plugins" do - execute = @logstash_plugin.remove("logstash-filter-one_no_dependencies", "logstash-filter-zero_no_dependencies") - - expect(execute.exit_code).to eq(1) - expect(execute.stderr_and_stdout).to include('Failed to remove "logstash-filter-one_no_dependencies"') - expect(execute.stderr_and_stdout).to include("* logstash-filter-four_depends_on_one_and_three") # one of the dependency - expect(execute.stderr_and_stdout).to include("* logstash-filter-two_depends_on_one") # one of the dependency - expect(execute.stderr_and_stdout).to include("No plugins were removed.") - - aggregate_failures("list plugins") do - presence_check = @logstash_plugin.list - expect(presence_check.exit_code).to eq(0) - expect(presence_check.stderr_and_stdout).to include('logstash-filter-one_no_dependencies') - expect(presence_check.stderr_and_stdout).to include('logstash-filter-zero_no_dependencies') - end - end + end + end + + context "when a remaining plugin has a dependency on a removed plugin" do + let(:setup_plugin_list) do + %w( + logstash-filter-zero_no_dependencies + logstash-filter-one_no_dependencies + logstash-filter-two_depends_on_one + logstash-filter-three_no_dependencies + logstash-filter-four_depends_on_one_and_three + ) + end + it "errors helpfully without removing any of the plugins" do + execute = @logstash_plugin.remove("logstash-filter-three_no_dependencies", "logstash-filter-zero_no_dependencies") + + expect(execute.exit_code).to eq(1) + expect(execute.stderr_and_stdout).to include('Failed to remove "logstash-filter-three_no_dependencies"') + expect(execute.stderr_and_stdout).to include("* logstash-filter-four_depends_on_one_and_three") # one of the dependency + expect(execute.stderr_and_stdout).to include("No plugins were removed.") + + aggregate_failures("list plugins") do + presence_check = @logstash_plugin.list + expect(presence_check.exit_code).to eq(0) + expect(presence_check.stderr_and_stdout).to include('logstash-filter-three_no_dependencies') + expect(presence_check.stderr_and_stdout).to include('logstash-filter-zero_no_dependencies') end - context "when removing plugins and all plugins that depend on them" do - let(:setup_plugin_list) do - %w( - logstash-filter-zero_no_dependencies - logstash-filter-one_no_dependencies - logstash-filter-two_depends_on_one - logstash-filter-three_no_dependencies - logstash-filter-four_depends_on_one_and_three - ) + end + end + context "when multiple remaining plugins have a dependency on a removed plugin" do + let(:setup_plugin_list) do + %w( + logstash-filter-zero_no_dependencies + logstash-filter-one_no_dependencies + logstash-filter-two_depends_on_one + logstash-filter-three_no_dependencies + logstash-filter-four_depends_on_one_and_three + ) + end + it "errors helpfully without removing any of the plugins" do + execute = @logstash_plugin.remove("logstash-filter-one_no_dependencies", "logstash-filter-zero_no_dependencies") + + expect(execute.exit_code).to eq(1) + expect(execute.stderr_and_stdout).to include('Failed to remove "logstash-filter-one_no_dependencies"') + expect(execute.stderr_and_stdout).to include("* logstash-filter-four_depends_on_one_and_three") # one of the dependency + expect(execute.stderr_and_stdout).to include("* logstash-filter-two_depends_on_one") # one of the dependency + expect(execute.stderr_and_stdout).to include("No plugins were removed.") + + aggregate_failures("list plugins") do + presence_check = @logstash_plugin.list + expect(presence_check.exit_code).to eq(0) + expect(presence_check.stderr_and_stdout).to include('logstash-filter-one_no_dependencies') + expect(presence_check.stderr_and_stdout).to include('logstash-filter-zero_no_dependencies') + end + end + end + context "when removing plugins and all plugins that depend on them" do + let(:setup_plugin_list) do + %w( + logstash-filter-zero_no_dependencies + logstash-filter-one_no_dependencies + logstash-filter-two_depends_on_one + logstash-filter-three_no_dependencies + logstash-filter-four_depends_on_one_and_three + ) + end + it "removes the plugins" do + plugins_to_remove = %w( + logstash-filter-one_no_dependencies + logstash-filter-two_depends_on_one + logstash-filter-three_no_dependencies + logstash-filter-four_depends_on_one_and_three + ).shuffle #random order + execute = @logstash_plugin.remove(*plugins_to_remove) + + aggregate_failures("removal action") do + expect(execute).to have_attributes(:exit_code => 0, :stderr_and_stdout => include("Success")) + plugins_to_remove.each do |gem_name| + expect(execute.stderr_and_stdout).to include("Successfully removed #{gem_name}") end - it "removes the plugins" do - plugins_to_remove = %w( - logstash-filter-one_no_dependencies - logstash-filter-two_depends_on_one - logstash-filter-three_no_dependencies - logstash-filter-four_depends_on_one_and_three - ).shuffle #random order - execute = @logstash_plugin.remove(*plugins_to_remove) - - aggregate_failures("removal action") do - expect(execute).to have_attributes(:exit_code => 0, :stderr_and_stdout => include("Success")) - plugins_to_remove.each do |gem_name| - expect(execute.stderr_and_stdout).to include("Successfully removed #{gem_name}") - end - end + end - aggregate_failures("list plugins") do - presence_check = @logstash_plugin.list - expect(presence_check.exit_code).to eq(0) - aggregate_failures("removed plugins") do - plugins_to_remove.each do |expected_removed_plugin| - expect(presence_check.stderr_and_stdout).to_not include(expected_removed_plugin) - end - end - aggregate_failures("non-removed plugins") do - (setup_plugin_list - plugins_to_remove).each do |expected_remaining_plugin| - expect(presence_check.stderr_and_stdout).to include(expected_remaining_plugin) - end - end + aggregate_failures("list plugins") do + presence_check = @logstash_plugin.list + expect(presence_check.exit_code).to eq(0) + aggregate_failures("removed plugins") do + plugins_to_remove.each do |expected_removed_plugin| + expect(presence_check.stderr_and_stdout).to_not include(expected_removed_plugin) + end + end + aggregate_failures("non-removed plugins") do + (setup_plugin_list - plugins_to_remove).each do |expected_remaining_plugin| + expect(presence_check.stderr_and_stdout).to include(expected_remaining_plugin) end end end end end + end end