logstash/qa/rspec/commands.rb
Dimitrios Liappis b66dc7f460
Fix service startup with acceptance tests (#15900)
This commit fixes the startup of the Logstash service during packaging
tests by adding a minimal pipeline config. Without it, the service was
flapping from start to start and vice versa causing test flakiness.

Relates https://github.com/elastic/logstash/issues/15784
2024-02-06 17:38:12 +02:00

206 lines
5.3 KiB
Ruby

# Licensed to Elasticsearch B.V. under one or more contributor
# license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright
# ownership. Elasticsearch B.V. licenses this file to you under
# the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
require_relative "./commands/debian"
require_relative "./commands/ubuntu"
require_relative "./commands/redhat"
require_relative "./commands/suse"
require_relative "./commands/opensuse"
require_relative "./commands/centos/centos-6"
require_relative "./commands/oel/oel-6"
require_relative "./commands/suse/sles-11"
require "forwardable"
require "open3"
OS_RELEASE_PATH = "/etc/os-release"
class HostFacts
def initialize()
@os_release = {}
begin
os_release_hash = File.foreach(OS_RELEASE_PATH).each_with_object({}) do |line, hash|
next if line.strip.empty?
key, value = line.strip.split("=")
@os_release[key] = value.tr('"', "")
end
rescue Errno::ENOENT
puts "File not found: #{OS_RELEASE_PATH}"
rescue Errno::EACCES
puts "Permission denied to read file: #{OS_RELEASE_PATH}"
rescue StandardError => e
puts "Error parsing content of #{OS_RELEASE_PATH}: #{e.message}"
end
end
def orig_name
# e.g. openSUSE Leap
@os_release["NAME"]
end
def name
# e.g. opensuse leap
@os_release["NAME"].downcase
end
def id
# e.g. ubuntu for Ubuntu 22.04, or debian for Debian 11, or centos for centos-7
@os_release["ID"].downcase
end
def id_like
# e.g. "rhel fedora" for centos-7
@os_release["ID_LIKE"].downcase
end
def version_codename
# e.g. jammy for Ubuntu 22.04, or bullseye for Debian 11, unset for RHEL
@os_release["VERSION_CODENAME"].downcase
end
def version_id
# e.g. 22.04 for Ubuntu jammy, 11 for Debian Bullseye, 8.x for RHEL 8 distros
@os_release["VERSION_ID"].downcase
end
def human_name
if self.version_id
"#{self.orig_name} #{self.version_id}"
else
orig_name
end
end
end
module ServiceTester
# An artifact is the component being tested, it's able to interact with
# a destination machine by holding a client and is basically provides all
# necessary abstractions to make the test simple.
class Artifact
extend Forwardable
def_delegators :@client, :installed?, :removed?, :running?
attr_reader :client
def initialize(options = {})
@options = options
@hostfacts = HostFacts.new()
@client = CommandsFactory.fetch(@hostfacts)
@skip_jdk_infix = false
end
def hostname
`hostname`.chomp
end
def human_name
@hostfacts.human_name
end
def hosts
[@hostname]
end
def name
"logstash"
end
def start_service
client.start_service(name)
end
def stop_service
client.stop_service(name)
end
def install(options = {})
base = options.fetch(:base, ServiceTester::Base::LOCATION)
@skip_jdk_infix = options.fetch(:skip_jdk_infix, false)
filename = filename(options)
package = client.package_for(filename, @skip_jdk_infix, base)
client.install(package)
end
def write_default_pipeline()
# defines a minimal pipeline so that the service is able to start
client.write_pipeline("input { heartbeat {} } output { null {} }")
end
def uninstall
client.uninstall(name)
end
def run_command_in_path(cmd)
client.run_command_in_path(cmd)
end
def run_command(cmd)
client.run_command(cmd)
end
def plugin_installed?(name, version = nil)
client.plugin_installed?(name, version)
end
def gem_vendored?(gem_name)
client.gem_vendored?(gem_name)
end
def download(from, to)
client.download(from, to)
end
def replace_in_gemfile(pattern, replace)
client.replace_in_gemfile(pattern, replace)
end
def delete_file(path)
client.delete_file(path)
end
def to_s
"Artifact #{name}@#{host}"
end
private
def filename(options = {})
snapshot = options.fetch(:snapshot, true)
"logstash-#{options[:version]}#{(snapshot ? "-SNAPSHOT" : "")}"
end
end
# Factory of commands used to select the right clients for a given type of OS
class CommandsFactory
def self.fetch(hostfacts)
case
when hostfacts.name.include?("ubuntu")
return UbuntuCommands.new
when hostfacts.name.include?("debian")
return DebianCommands.new
when hostfacts.name.include?("opensuse")
return OpenSuseCommands.new
when hostfacts.name.include?("red hat")
return RedhatCommands.new
when hostfacts.id_like.include?("rhel"), hostfacts.id_like.include?("fedora")
# covers Oracle Linux, CentOS, Rocky Linux, Amazon Linux
# TODO add specific commands (e.g. to use dnf instead of yum where applicable)
return RedhatCommands.new
end
end
end
end