class Gitlab::QA::Component::Specs
the ‘qa/` directory located in GitLab CE / EE repositories.
This class represents GitLab QA specs image that is implemented in
#
def args_with_flags(args, feature_flag_set)
def args_with_flags(args, feature_flag_set) return args if feature_flag_set.empty? Runtime::Logger.info("Running with feature flag: #{feature_flag_set.join(' ')}") args_with_f = args.dup args_with_f.insert(1, *feature_flag_set) end
def docker_pull_qa_image_if_needed
def docker_pull_qa_image_if_needed @docker.login(**release.login_params) if release.login_params @docker.pull(image: qa_image) unless Runtime::Env.skip_pull? end
def initialize
def initialize @docker = Docker::Engine.new(stream_output: true) # stream test output directly instead of through logger @env = {} @volumes = {} @default_volumes = { '/var/run/docker.sock' => '/var/run/docker.sock' } return if Runtime::Env.qa_knapsack_report_path.blank? @default_volumes[Runtime::Env.qa_knapsack_report_path] = File.join( Docker::Volumes::QA_CONTAINER_WORKDIR, 'knapsack' ) end
def perform
def perform return Runtime::Logger.info("Skipping tests.") if skip_tests? raise ArgumentError unless [suite, release].all? docker_pull_qa_image_if_needed Runtime::Logger.info("Running test suite `#{suite}` for #{release.project_name}") name = "#{release.project_name}-qa-#{SecureRandom.hex(4)}" feature_flag_sets = [] # When `args` includes `[..., "--disable-feature", "a", "--enable-feature", "b", "--set-feature-flags", "c=enable", ...]` # `feature_flag_sets` will be set to `[["--disable-feature", "a"], ["--enable-feature", "b"], ["--set-feature-flags", "c=enable"]]` # This will result in tests running three times, once with each feature flag option. while (index = args&.index { |x| x =~ /--.*-feature/ }) feature_flag_sets << args.slice!(index, 2) end # When `args` do not have any feature flag options, we add [] so that test is run exactly once. feature_flag_sets << [] unless feature_flag_sets.any? feature_flag_sets.each do |feature_flag_set| @docker.run(image: qa_image, args: [suite, *args_with_flags(args, feature_flag_set)]) do |command| command << "-t --rm --net=#{network || 'bridge'}" unless hostname.nil? command << "--hostname #{hostname}" command.env('QA_HOSTNAME', hostname) end unless Runtime::Env.docker_add_hosts.empty? hosts = Runtime::Env.docker_add_hosts.map { |host| "--add-host=#{host} " }.join command << hosts # override /etc/hosts in docker container when test runs end env.merge(Runtime::Env.variables).each do |key, value| command.env(key, value) end command.volume( File.join(Runtime::Env.host_artifacts_dir, name), File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, 'tmp') ) volumes.to_h.merge(default_volumes).each { |to, from| command.volume(to, from) } command.name(name) end end end
def qa_image
def qa_image if Runtime::Scenario.attributes.include?(:qa_image) Runtime::Scenario.qa_image else "#{release.qa_image}:#{release.qa_tag}" end end
def skip_tests?
def skip_tests? Runtime::Scenario.attributes.include?(:run_tests) && !Runtime::Scenario.run_tests end