lib/gitlab/qa/component/mock_server.rb in gitlab-qa-12.3.0 vs lib/gitlab/qa/component/mock_server.rb in gitlab-qa-12.4.0

- old
+ new

@@ -16,54 +16,93 @@ @tls = false @name = "smocker" @tls_path = "/etc/smocker/tls" @ports = [80, 8081] @environment = { "SMOCKER_MOCK_SERVER_LISTEN_PORT" => 80 } - @log_volume = {} + @tls_volume = { "smocker-ssl" => @tls_path } end - attr_reader :name + attr_reader :name, :tls_volume attr_writer :tls def prepare super + alpine_service_container.start_instance setup_tls if tls end - # Print smocker log output by using docker logs command because smocker only logs to stdout - # - # @return [void] def teardown! + # Print smocker log output by using docker logs command because smocker only logs to stdout Docker::Command.execute("logs #{name}") + # Remove alpine service container + alpine_service_container.teardown! super end private attr_reader :tls_path, :tls + # Run healthcheck validate startup of mock server + # + # @return [void] + def wait_until_ready + logger.info("Waiting for mock server to start!") + poll_mock_healthcheck(3) + logger.info("Mock server container is healthy!") + end + + # Poll healthcheck endpoint + # + # @param [Integer] max_tries + # @return [void] + def poll_mock_healthcheck(max_tries) + url = "#{tls ? 'https' : 'http'}://#{hostname}:8081/version" + curl_cmd = "curl --cacert #{tls_path}/smocker.crt -s -f -o /dev/null -w '%{http_code}' #{url}" + tries = 0 + + loop do + # Poll healthcheck endpoint and remove service container if it passes + if docker.exec(alpine_service_container.name, curl_cmd, shell: "sh") + alpine_service_container.teardown! + break + end + rescue Support::ShellCommand::StatusError => e + # re-raise StatusError so that built in startup retry is used in case of failure + raise e if tries >= max_tries + + tries += 1 + sleep 1 + end + end + # Set up tls certs # # @return [void] def setup_tls - @volumes = { "smocker-ssl" => tls_path } + @volumes = tls_volume @ports = [443, 8081] @environment = { "SMOCKER_MOCK_SERVER_LISTEN_PORT" => 443, "SMOCKER_TLS_ENABLE" => "true", - "SMOCKER_TLS_CERT_FILE" => "#{@tls_path}/smocker.crt", - "SMOCKER_TLS_PRIVATE_KEY_FILE" => "#{@tls_path}/smocker.key" + "SMOCKER_TLS_CERT_FILE" => "#{tls_path}/smocker.crt", + "SMOCKER_TLS_PRIVATE_KEY_FILE" => "#{tls_path}/smocker.key" } - Alpine.perform do |alpine| - alpine.volumes = volumes + docker.copy(alpine_service_container.name, "#{CERTIFICATES_PATH}/smocker/.", tls_path) + end - alpine.start_instance - docker.copy(alpine.name, "#{CERTIFICATES_PATH}/smocker/.", tls_path) - ensure - alpine.teardown! # always remove container, even when global `--no-tests` flag was provided + # Helper container to run tls cert copy and curl healthcheck command + # Separate container is required because tls certs have to be copied before smocker startup and smocker + # container itself doesn't ship with curl to perform healthcheck requests + # + # @return [Component::Alpine] + def alpine_service_container + @alpine_service_container ||= Alpine.new.tap do |alpine| + alpine.volumes = tls_volume + alpine.network = network end end end end end