global_spec.rb 8.9 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's avatar
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's avatar
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 36
      describe '#compose!' do
        before { global.compose! }
37

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

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

46
        it 'creates node object using valid class' do
47 48 49 50
          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
51 52 53
        end

        it 'sets correct description for nodes' do
54 55 56 57
          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.'
58
        end
59

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

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

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

81 82
      context 'when composed' do
        before { global.compose! }
83

84 85 86 87 88 89
        describe '#errors' do
          it 'has no errors' do
            expect(global.errors).to be_empty
          end
        end

90
        describe '#before_script_value' do
91
          it 'returns correct script' do
Douwe Maan's avatar
Douwe Maan committed
92
            expect(global.before_script_value).to eq %w(ls pwd)
93 94 95
          end
        end

96
        describe '#image_value' do
97
          it 'returns valid image' do
98
            expect(global.image_value).to eq 'ruby:2.2'
99 100 101
          end
        end

102
        describe '#services_value' do
103
          it 'returns array of services' do
104
            expect(global.services_value).to eq ['postgres:9.1', 'mysql:5.5']
105 106 107
          end
        end

108
        describe '#after_script_value' do
109
          it 'returns after script' do
110
            expect(global.after_script_value).to eq ['make clean']
111 112 113
          end
        end

114
        describe '#variables_value' do
115
          it 'returns variables' do
116
            expect(global.variables_value).to eq(VAR: 'value')
117
          end
118
        end
119

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

          context 'when deprecated types key defined' do
128
            let(:hash) do
Douwe Maan's avatar
Douwe Maan committed
129
              { types: %w(test deploy),
130 131
                rspec: { script: 'rspec' } }
            end
132 133

            it 'returns array of types as stages' do
134
              expect(global.stages_value).to eq %w[test deploy]
135 136 137
            end
          end
        end
138

139
        describe '#cache_value' do
140
          it 'returns cache configuration' do
141 142
            expect(global.cache_value)
              .to eq(key: 'k', untracked: true, paths: ['public/'])
143 144
          end
        end
145

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

175
    context 'when most of entires not defined' do
176 177 178 179 180
      before { global.compose! }

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

182 183
      describe '#nodes' do
        it 'instantizes all nodes' do
184
          expect(global.descendants.count).to eq 8
185 186
        end

187
        it 'contains unspecified nodes' do
188
          expect(global.descendants.first)
189
            .not_to be_specified
190
        end
191
      end
192

193
      describe '#variables_value' do
194
        it 'returns default value for variables' do
195
          expect(global.variables_value).to eq({})
196 197
        end
      end
198

199
      describe '#stages_value' do
200
        it 'returns an array of default stages' do
201
          expect(global.stages_value).to eq %w[build test deploy]
202 203
        end
      end
204

205
      describe '#cache_value' do
206
        it 'returns correct cache definition' do
207
          expect(global.cache_value).to eq(key: 'a')
208 209
        end
      end
210
    end
211

212 213 214 215 216 217 218
    ##
    # 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
219 220 221 222 223
      before { global.compose! }

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

225
      describe '#variables_value' do
226
        it 'undefined entry returns a default value' do
227
          expect(global.variables_value).to eq({})
228 229
        end
      end
230
    end
231
  end
232

233
  context 'when configuration is not valid' do
234
    before { global.compose! }
235

236 237 238 239
    context 'when before script is not an array' do
      let(:hash) do
        { before_script: 'ls' }
      end
240

241 242 243 244
      describe '#valid?' do
        it 'is not valid' do
          expect(global).not_to be_valid
        end
245 246
      end

247 248
      describe '#errors' do
        it 'reports errors from child nodes' do
249 250
          expect(global.errors)
            .to include 'before_script config should be an array of strings'
251 252 253 254 255 256 257
        end
      end

      describe '#before_script_value' do
        it 'returns nil' do
          expect(global.before_script_value).to be_nil
        end
258 259
      end
    end
260

261
    context 'when job does not have commands' do
262 263 264
      let(:hash) do
        { before_script: ['echo 123'], rspec: { stage: 'test' } }
      end
265 266 267

      describe '#errors' do
        it 'reports errors about missing script' do
268 269
          expect(global.errors)
            .to include "jobs:rspec script can't be blank"
270
        end
271 272
      end
    end
273
  end
274 275 276 277 278 279 280 281 282

  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
283 284 285 286 287 288

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

291
  describe '#specified?' do
292
    it 'is concrete entry that is defined' do
293
      expect(global.specified?).to be true
294 295
    end
  end
296 297 298 299 300 301 302 303

  describe '#[]' do
    before { global.compose! }

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

304
    context 'when entry exists' do
305
      it 'returns correct entry' do
306 307
        expect(global[:cache])
          .to be_an_instance_of Gitlab::Ci::Config::Entry::Cache
308 309 310 311
        expect(global[:jobs][:rspec][:script].value).to eq ['ls']
      end
    end

312
    context 'when entry does not exist' do
313
      it 'always return unspecified node' do
314 315
        expect(global[:some][:unknown][:node])
          .not_to be_specified
316 317 318
      end
    end
  end
319
end