backup_rake_spec.rb 6.52 KB
Newer Older
Hugo Duksis's avatar
Hugo Duksis committed
1 2 3 4 5
require 'spec_helper'
require 'rake'

describe 'gitlab:app namespace rake task' do
  before :all do
6
    Rake.application.rake_require "tasks/gitlab/task_helpers"
Hugo Duksis's avatar
Hugo Duksis committed
7
    Rake.application.rake_require "tasks/gitlab/backup"
Andrew Kumanyaev's avatar
Andrew Kumanyaev committed
8
    Rake.application.rake_require "tasks/gitlab/shell"
Hugo Duksis's avatar
Hugo Duksis committed
9 10 11 12
    # empty task as env is already loaded
    Rake::Task.define_task :environment
  end

13 14 15 16 17
  def run_rake_task(task_name)
    Rake::Task[task_name].reenable
    Rake.application.invoke_task task_name
  end

18
  def reenable_backup_sub_tasks
Marin Jankovski's avatar
Marin Jankovski committed
19
    %w{db repo uploads builds artifacts lfs}.each do |subtask|
20 21 22 23
      Rake::Task["gitlab:backup:#{subtask}:create"].reenable
    end
  end

Hugo Duksis's avatar
Hugo Duksis committed
24 25 26
  describe 'backup_restore' do
    before do
      # avoid writing task output to spec progress
27
      allow($stdout).to receive :write
Hugo Duksis's avatar
Hugo Duksis committed
28 29 30 31
    end

    context 'gitlab version' do
      before do
32 33 34 35 36 37 38 39
        allow(Dir).to receive(:glob).and_return([])
        allow(Dir).to receive(:chdir)
        allow(File).to receive(:exists?).and_return(true)
        allow(Kernel).to receive(:system).and_return(true)
        allow(FileUtils).to receive(:cp_r).and_return(true)
        allow(FileUtils).to receive(:mv).and_return(true)
        allow(Rake::Task["gitlab:shell:setup"]).
          to receive(:invoke).and_return(true)
Hugo Duksis's avatar
Hugo Duksis committed
40 41
      end

42
      let(:gitlab_version) { Gitlab::VERSION }
Hugo Duksis's avatar
Hugo Duksis committed
43

Johannes Schleifenbaum's avatar
Johannes Schleifenbaum committed
44
      it 'should fail on mismatch' do
45
        allow(YAML).to receive(:load_file).
46
          and_return({ gitlab_version: "not #{gitlab_version}" })
47 48 49

        expect { run_rake_task('gitlab:backup:restore') }.
          to raise_error(SystemExit)
Hugo Duksis's avatar
Hugo Duksis committed
50 51
      end

Marin Jankovski's avatar
Marin Jankovski committed
52
      it 'should invoke restoration on match' do
53
        allow(YAML).to receive(:load_file).
54
          and_return({ gitlab_version: gitlab_version })
55 56
        expect(Rake::Task["gitlab:backup:db:restore"]).to receive(:invoke)
        expect(Rake::Task["gitlab:backup:repo:restore"]).to receive(:invoke)
57
        expect(Rake::Task["gitlab:backup:builds:restore"]).to receive(:invoke)
Jacob Vosmaer's avatar
Jacob Vosmaer committed
58
        expect(Rake::Task["gitlab:backup:uploads:restore"]).to receive(:invoke)
59
        expect(Rake::Task["gitlab:backup:artifacts:restore"]).to receive(:invoke)
Marin Jankovski's avatar
Marin Jankovski committed
60
        expect(Rake::Task["gitlab:backup:lfs:restore"]).to receive(:invoke)
61 62
        expect(Rake::Task["gitlab:shell:setup"]).to receive(:invoke)
        expect { run_rake_task('gitlab:backup:restore') }.not_to raise_error
Hugo Duksis's avatar
Hugo Duksis committed
63 64 65 66
      end
    end

  end # backup_restore task
67 68 69 70 71 72

  describe 'backup_create' do
    def tars_glob
      Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar'))
    end

73
    def create_backup
74
      FileUtils.rm tars_glob
75 76 77 78

      # Redirect STDOUT and run the rake task
      orig_stdout = $stdout
      $stdout = StringIO.new
79
      reenable_backup_sub_tasks
80
      run_rake_task('gitlab:backup:create')
81
      reenable_backup_sub_tasks
82 83
      $stdout = orig_stdout

84
      @backup_tar = tars_glob.first
85 86
    end

87
    before do
88 89 90
      create_backup
    end

91
    after do
92 93 94
      FileUtils.rm(@backup_tar)
    end

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
    context 'archive file permissions' do
      it 'should set correct permissions on the tar file' do
        expect(File.exist?(@backup_tar)).to be_truthy
        expect(File::Stat.new(@backup_tar).mode.to_s(8)).to eq('100600')
      end

      context 'with custom archive_permissions' do
        before do
          allow(Gitlab.config.backup).to receive(:archive_permissions).and_return(0651)
          # We created a backup in a before(:all) so it got the default permissions.
          # We now need to do some work to create a _new_ backup file using our stub.
          FileUtils.rm(@backup_tar)
          create_backup
        end

        it 'uses the custom permissions' do
          expect(File::Stat.new(@backup_tar).mode.to_s(8)).to eq('100651')
        end
      end
114 115 116 117
    end

    it 'should set correct permissions on the tar contents' do
      tar_contents, exit_status = Gitlab::Popen.popen(
Marin Jankovski's avatar
Marin Jankovski committed
118
        %W{tar -tvf #{@backup_tar} db uploads.tar.gz repositories builds.tar.gz artifacts.tar.gz lfs.tar.gz}
119 120 121
      )
      expect(exit_status).to eq(0)
      expect(tar_contents).to match('db/')
122
      expect(tar_contents).to match('uploads.tar.gz')
123
      expect(tar_contents).to match('repositories/')
124
      expect(tar_contents).to match('builds.tar.gz')
125
      expect(tar_contents).to match('artifacts.tar.gz')
Marin Jankovski's avatar
Marin Jankovski committed
126
      expect(tar_contents).to match('lfs.tar.gz')
127
      expect(tar_contents).not_to match(/^.{4,9}[rwx].* (database.sql.gz|uploads.tar.gz|repositories|builds.tar.gz|artifacts.tar.gz)\/$/)
128 129 130 131
    end

    it 'should delete temp directories' do
      temp_dirs = Dir.glob(
Marin Jankovski's avatar
Marin Jankovski committed
132
        File.join(Gitlab.config.backup.path, '{db,repositories,uploads,builds,artifacts,lfs}')
133 134 135 136 137
      )

      expect(temp_dirs).to be_empty
    end
  end # backup_create task
138 139 140 141 142 143 144 145 146

  describe "Skipping items" do
    def tars_glob
      Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar'))
    end

    before :all do
      @origin_cd = Dir.pwd

147
      reenable_backup_sub_tasks
148

149
      FileUtils.rm tars_glob
150 151 152 153

      # Redirect STDOUT and run the rake task
      orig_stdout = $stdout
      $stdout = StringIO.new
154
      ENV["SKIP"] = "repositories,uploads"
155 156 157
      run_rake_task('gitlab:backup:create')
      $stdout = orig_stdout

158
      @backup_tar = tars_glob.first
159 160 161 162 163 164 165 166
    end

    after :all do
      FileUtils.rm(@backup_tar)
      Dir.chdir @origin_cd
    end

    it "does not contain skipped item" do
167
      tar_contents, _exit_status = Gitlab::Popen.popen(
Marin Jankovski's avatar
Marin Jankovski committed
168
        %W{tar -tvf #{@backup_tar} db uploads.tar.gz repositories builds.tar.gz artifacts.tar.gz lfs.tar.gz}
169 170 171
      )

      expect(tar_contents).to match('db/')
172 173
      expect(tar_contents).to match('uploads.tar.gz')
      expect(tar_contents).to match('builds.tar.gz')
174
      expect(tar_contents).to match('artifacts.tar.gz')
Marin Jankovski's avatar
Marin Jankovski committed
175
      expect(tar_contents).to match('lfs.tar.gz')
176 177 178 179
      expect(tar_contents).not_to match('repositories/')
    end

    it 'does not invoke repositories restore' do
180 181
      allow(Rake::Task["gitlab:shell:setup"]).
        to receive(:invoke).and_return(true)
182 183 184 185
      allow($stdout).to receive :write

      expect(Rake::Task["gitlab:backup:db:restore"]).to receive :invoke
      expect(Rake::Task["gitlab:backup:repo:restore"]).not_to receive :invoke
186
      expect(Rake::Task["gitlab:backup:uploads:restore"]).not_to receive :invoke
187
      expect(Rake::Task["gitlab:backup:builds:restore"]).to receive :invoke
188
      expect(Rake::Task["gitlab:backup:artifacts:restore"]).to receive :invoke
Marin Jankovski's avatar
Marin Jankovski committed
189
      expect(Rake::Task["gitlab:backup:lfs:restore"]).to receive :invoke
190
      expect(Rake::Task["gitlab:shell:setup"]).to receive :invoke
191
      expect { run_rake_task('gitlab:backup:restore') }.not_to raise_error
192 193
    end
  end
Hugo Duksis's avatar
Hugo Duksis committed
194
end # gitlab:app namespace