summaryrefslogtreecommitdiff
path: root/spec/commands/diagnostic_reports/uploader_smoke_spec.rb
blob: 9fbceb688449fd947a7cf8a9da8cd12f7c63ed12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# frozen_string_literal: true

require 'fast_spec_helper'
require 'tempfile'

# We need to capture pid from Process.spawn and then clean up by killing the process, which requires instance variables.
# rubocop: disable RSpec/InstanceVariable
RSpec.describe 'bin/diagnostic-reports-uploader' do
  # This is a smoke test for 'bin/diagnostic-reports-uploader'.
  # We intend to run this binary with `ruby bin/diagnostic-reports-uploader`, without preloading the entire Rails app.
  # Also, we use inline gemfile, to avoid pulling full Gemfile from the main app into memory.
  # The goal of that test is to confirm that the binary starts that way.
  # The implementation logic is covered in 'spec/bin/diagnostic_reports_uploader_spec.rb'
  include FastRailsRoot

  let(:gcs_bucket) { 'test_bucket' }
  let(:gcs_project) { 'test_project' }
  let(:gcs_key) { Tempfile.new }
  let(:reports_dir) { Dir.mktmpdir }
  let(:report) { Tempfile.new('report.json', reports_dir) }

  let(:env) do
    {
      'GITLAB_DIAGNOSTIC_REPORTS_BUCKET' => gcs_bucket,
      'GITLAB_DIAGNOSTIC_REPORTS_PROJECT' => gcs_project,
      'GITLAB_GCP_KEY_PATH' => gcs_key.path,
      'GITLAB_DIAGNOSTIC_REPORTS_PATH' => reports_dir,
      'GITLAB_DIAGNOSTIC_REPORTS_UPLOADER_SLEEP_S' => '1'
    }
  end

  before do
    gcs_key.write(
      {
        type: "service_account",
        client_email: 'test@gitlab.com',
        private_key_id: "test_id",
        private_key: File.read(rails_root_join('spec/fixtures/ssl_key.pem'))
      }.to_json
    )
    gcs_key.rewind

    FileUtils.touch(report.path)
  end

  after do
    if @pid
      Timeout.timeout(10) do
        Process.kill('TERM', @pid)
        Process.waitpid(@pid)
      end
    end
  rescue Errno::ESRCH, Errno::ECHILD => _
    # 'No such process' or 'No child processes' means the process died before
  ensure
    gcs_key.unlink
    FileUtils.rm_rf(reports_dir, secure: true)
  end

  it 'starts successfully' do
    expect(File.exist?(report.path)).to be true

    bin_path = rails_root_join("bin/diagnostic-reports-uploader")

    cmd = ['bundle', 'exec', 'ruby', bin_path]
    @pid = Process.spawn(env, *cmd)

    expect(Gitlab::ProcessManagement.process_alive?(@pid)).to be true

    expect do
      Timeout.timeout(10) do
        # Uploader will remove the file, no matter the upload result. We are waiting for exactly that.
        # The report being removed means the uploader loop works. We are not attempting real upload.
        attempted_upload_and_cleanup = false
        until attempted_upload_and_cleanup
          sleep 1
          attempted_upload_and_cleanup = !File.exist?(report.path)
        end
      end
    end.not_to raise_error
  end
end
# rubocop: enable RSpec/InstanceVariable