BigW Consortium Gitlab

global_spec.rb 9.25 KB
Newer Older
1 2
require 'spec_helper'

3
describe Gitlab::Ci::Config::Entry::Global do
4
  let(:global) { described_class.new(hash) }
5

6
  describe '.nodes' do
7 8 9
    it 'returns a hash' do
      expect(described_class.nodes).to be_a(Hash)
    end
10 11

    context 'when filtering all the entry/node names' do
12
      it 'contains the expected node names' do
13 14 15 16
        expect(described_class.nodes.keys)
          .to match_array(%i[before_script image services
                             after_script variables stages
                             types cache])
17
      end
18
    end
19 20
  end

21
  context 'when configuration is valid' do
22
    context 'when some entries defined' do
23
      let(:hash) do
Douwe Maan committed
24
        { before_script: %w(ls pwd),
25 26 27
          image: 'ruby:2.2',
          services: ['postgres:9.1', 'mysql:5.5'],
          variables: { VAR: 'value' },
28
          after_script: ['make clean'],
Douwe Maan committed
29
          stages: %w(build pages),
30
          cache: { key: 'k', untracked: true, paths: ['public/'] },
31
          rspec: { script: %w[rspec ls] },
32
          spinach: { before_script: [], variables: {}, script: 'spinach' } }
33
      end
34

35
      describe '#compose!' do
36 37 38
        before do
          global.compose!
        end
39

40
        it 'creates nodes hash' do
41
          expect(global.descendants).to be_an Array
42
        end
43

44
        it 'creates node object for each entry' do
45
          expect(global.descendants.count).to eq 8
46
        end
47

48
        it 'creates node object using valid class' do
49 50 51 52
          expect(global.descendants.first)
            .to be_an_instance_of Gitlab::Ci::Config::Entry::Script
          expect(global.descendants.second)
            .to be_an_instance_of Gitlab::Ci::Config::Entry::Image
53 54 55
        end

        it 'sets correct description for nodes' do
56 57 58 59
          expect(global.descendants.first.description)
            .to eq 'Script that will be executed before each job.'
          expect(global.descendants.second.description)
            .to eq 'Docker image that will be used to execute jobs.'
60
        end
61

62 63 64 65
        describe '#leaf?' do
          it 'is not leaf' do
            expect(global).not_to be_leaf
          end
66
        end
67
      end
68

69
      context 'when not composed' do
70
        describe '#before_script_value' do
71
          it 'returns nil' do
72
            expect(global.before_script_value).to be nil
73 74
          end
        end
75 76 77 78 79 80

        describe '#leaf?' do
          it 'is leaf' do
            expect(global).to be_leaf
          end
        end
81
      end
82

83
      context 'when composed' do
84 85 86
        before do
          global.compose!
        end
87

88 89 90 91 92 93
        describe '#errors' do
          it 'has no errors' do
            expect(global.errors).to be_empty
          end
        end

94
        describe '#before_script_value' do
95
          it 'returns correct script' do
Douwe Maan committed
96
            expect(global.before_script_value).to eq %w(ls pwd)
97 98 99
          end
        end

100
        describe '#image_value' do
101
          it 'returns valid image' do
102
            expect(global.image_value).to eq(name: 'ruby:2.2')
103 104 105
          end
        end

106
        describe '#services_value' do
107
          it 'returns array of services' do
108
            expect(global.services_value).to eq [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }]
109 110 111
          end
        end

112
        describe '#after_script_value' do
113
          it 'returns after script' do
114
            expect(global.after_script_value).to eq ['make clean']
115 116 117
          end
        end

118
        describe '#variables_value' do
119
          it 'returns variables' do
120
            expect(global.variables_value).to eq('VAR' => 'value')
121
          end
122
        end
123

124
        describe '#stages_value' do
125 126
          context 'when stages key defined' do
            it 'returns array of stages' do
127
              expect(global.stages_value).to eq %w[build pages]
128 129 130 131
            end
          end

          context 'when deprecated types key defined' do
132
            let(:hash) do
Douwe Maan committed
133
              { types: %w(test deploy),
134 135
                rspec: { script: 'rspec' } }
            end
136 137

            it 'returns array of types as stages' do
138
              expect(global.stages_value).to eq %w[test deploy]
139 140 141
            end
          end
        end
142

143
        describe '#cache_value' do
144
          it 'returns cache configuration' do
145
            expect(global.cache_value)
146
              .to eq(key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push')
147 148
          end
        end
149

150
        describe '#jobs_value' do
151
          it 'returns jobs configuration' do
152
            expect(global.jobs_value).to eq(
153 154
              rspec: { name: :rspec,
                       script: %w[rspec ls],
Douwe Maan committed
155
                       before_script: %w(ls pwd),
156
                       commands: "ls\npwd\nrspec\nls",
157 158
                       image: { name: 'ruby:2.2' },
                       services: [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }],
159
                       stage: 'test',
160
                       cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push' },
161
                       variables: { 'VAR' => 'value' },
162
                       ignore: false,
163
                       after_script: ['make clean'] },
164
              spinach: { name: :spinach,
165
                         before_script: [],
166 167
                         script: %w[spinach],
                         commands: 'spinach',
168 169
                         image: { name: 'ruby:2.2' },
                         services: [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }],
170
                         stage: 'test',
171
                         cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push' },
172
                         variables: {},
173
                         ignore: false,
174
                         after_script: ['make clean'] }
175
            )
176 177
          end
        end
178 179
      end
    end
180

181
    context 'when most of entires not defined' do
182 183 184
      before do
        global.compose!
      end
185 186 187 188

      let(:hash) do
        { cache: { key: 'a' }, rspec: { script: %w[ls] } }
      end
189

190 191
      describe '#nodes' do
        it 'instantizes all nodes' do
192
          expect(global.descendants.count).to eq 8
193 194
        end

195
        it 'contains unspecified nodes' do
196
          expect(global.descendants.first)
197
            .not_to be_specified
198
        end
199
      end
200

201
      describe '#variables_value' do
202
        it 'returns default value for variables' do
203
          expect(global.variables_value).to eq({})
204 205
        end
      end
206

207
      describe '#stages_value' do
208
        it 'returns an array of default stages' do
209
          expect(global.stages_value).to eq %w[build test deploy]
210 211
        end
      end
212

213
      describe '#cache_value' do
214
        it 'returns correct cache definition' do
215
          expect(global.cache_value).to eq(key: 'a', policy: 'pull-push')
216 217
        end
      end
218
    end
219

220 221 222 223 224 225 226
    ##
    # When nodes are specified but not defined, we assume that
    # configuration is valid, and we asume that entry is simply undefined,
    # despite the fact, that key is present. See issue #18775 for more
    # details.
    #
    context 'when entires specified but not defined' do
227 228 229
      before do
        global.compose!
      end
230 231 232 233

      let(:hash) do
        { variables: nil, rspec: { script: 'rspec' } }
      end
234

235
      describe '#variables_value' do
236
        it 'undefined entry returns a default value' do
237
          expect(global.variables_value).to eq({})
238 239
        end
      end
240
    end
241
  end
242

243
  context 'when configuration is not valid' do
244 245 246
    before do
      global.compose!
    end
247

248 249 250 251
    context 'when before script is not an array' do
      let(:hash) do
        { before_script: 'ls' }
      end
252

253 254 255 256
      describe '#valid?' do
        it 'is not valid' do
          expect(global).not_to be_valid
        end
257 258
      end

259 260
      describe '#errors' do
        it 'reports errors from child nodes' do
261 262
          expect(global.errors)
            .to include 'before_script config should be an array of strings'
263 264 265 266 267 268 269
        end
      end

      describe '#before_script_value' do
        it 'returns nil' do
          expect(global.before_script_value).to be_nil
        end
270 271
      end
    end
272

273
    context 'when job does not have commands' do
274 275 276
      let(:hash) do
        { before_script: ['echo 123'], rspec: { stage: 'test' } }
      end
277 278 279

      describe '#errors' do
        it 'reports errors about missing script' do
280 281
          expect(global.errors)
            .to include "jobs:rspec script can't be blank"
282
        end
283 284
      end
    end
285
  end
286 287 288 289 290 291 292 293 294

  context 'when value is not a hash' do
    let(:hash) { [] }

    describe '#valid?' do
      it 'is not valid' do
        expect(global).not_to be_valid
      end
    end
295 296 297 298 299 300

    describe '#errors' do
      it 'returns error about invalid type' do
        expect(global.errors.first).to match /should be a hash/
      end
    end
301
  end
302

303
  describe '#specified?' do
304
    it 'is concrete entry that is defined' do
305
      expect(global.specified?).to be true
306 307
    end
  end
308 309

  describe '#[]' do
310 311 312
    before do
      global.compose!
    end
313 314 315 316 317

    let(:hash) do
      { cache: { key: 'a' }, rspec: { script: 'ls' } }
    end

318
    context 'when entry exists' do
319
      it 'returns correct entry' do
320 321
        expect(global[:cache])
          .to be_an_instance_of Gitlab::Ci::Config::Entry::Cache
322 323 324 325
        expect(global[:jobs][:rspec][:script].value).to eq ['ls']
      end
    end

326
    context 'when entry does not exist' do
327
      it 'always return unspecified node' do
328 329
        expect(global[:some][:unknown][:node])
          .not_to be_specified
330 331 332
      end
    end
  end
333
end