diff options
author | Rémy Coutable <remy@rymai.me> | 2016-07-05 11:37:16 +0300 |
---|---|---|
committer | Rémy Coutable <remy@rymai.me> | 2016-07-05 11:37:16 +0300 |
commit | 06c7d6f3a863a1ac8d9f47fed8423387d6e672a6 (patch) | |
tree | c3c182c203626e4fd67f13b2df25998f46d57f79 /spec | |
parent | ba9ef7f3935cfaa42fcdb2317567cc383c7e9c22 (diff) | |
parent | bfad4c61f10f689868817cf0b94cddaa1de22240 (diff) |
Merge branch 'refactor/ci-config-move-global-entries' into 'master'
Move global ci entries handling from legacy to new config
## What does this MR do?
This MR moves responsibility of handling global CI config entries (like `image`, `services`), from legacy `GitlabCiYamlProcessor` to new CI Config
## Why was this MR needed?
This is the next iteration of CI configuration refactoring
## What are the relevant issue numbers?
#15060
## Does this MR meet the acceptance criteria?
- Tests
- [x] Added for this feature/bug
- [x] All builds are passing
- [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [x] Branch has no merge conflicts with `master` (if you do - rebase it please)
See merge request !4820
Diffstat (limited to 'spec')
-rw-r--r-- | spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 47 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/boolean_spec.rb | 34 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/cache_spec.rb | 60 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/configurable_spec.rb | 34 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/factory_spec.rb | 27 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/global_spec.rb | 186 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/image_spec.rb | 46 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/key_spec.rb | 34 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/null_spec.rb | 23 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/paths_spec.rb | 34 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/script_spec.rb | 6 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/services_spec.rb | 40 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/stages_spec.rb | 46 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/undefined_spec.rb | 40 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/validator_spec.rb | 42 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/variables_spec.rb | 48 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config_spec.rb | 46 |
17 files changed, 657 insertions, 136 deletions
diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index ec658668c61..bad439bc489 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -550,8 +550,8 @@ module Ci config_processor = GitlabCiYamlProcessor.new(config, path) ## - # TODO, in next version of CI configuration processor this - # should be invalid configuration, see #18775 and #15060 + # When variables config is empty, we assume this is a valid + # configuration, see issue #18775 # expect(config_processor.job_variables(:rspec)) .to be_an_instance_of(Array).and be_empty @@ -590,7 +590,20 @@ module Ci end end - describe "Caches" do + describe 'cache' do + context 'when cache definition has unknown keys' do + it 'raises relevant validation error' do + config = YAML.dump( + { cache: { untracked: true, invalid: 'key' }, + rspec: { script: 'rspec' } }) + + expect { GitlabCiYamlProcessor.new(config) }.to raise_error( + GitlabCiYamlProcessor::ValidationError, + 'cache config contains unknown keys: invalid' + ) + end + end + it "returns cache when defined globally" do config = YAML.dump({ cache: { paths: ["logs/", "binaries/"], untracked: true, key: 'key' }, @@ -950,7 +963,7 @@ EOT config = YAML.dump({ before_script: "bundle update", rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "Before script config should be an array of strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "before_script config should be an array of strings") end it "returns errors if job before_script parameter is not an array of strings" do @@ -964,7 +977,7 @@ EOT config = YAML.dump({ after_script: "bundle update", rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "after_script should be an array of strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "after_script config should be an array of strings") end it "returns errors if job after_script parameter is not an array of strings" do @@ -978,7 +991,7 @@ EOT config = YAML.dump({ image: ["test"], rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "image should be a string") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "image config should be a string") end it "returns errors if job name is blank" do @@ -1006,14 +1019,14 @@ EOT config = YAML.dump({ services: "test", rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "services should be an array of strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "services config should be an array of strings") end it "returns errors if services parameter is not an array of strings" do config = YAML.dump({ services: [10, "test"], rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "services should be an array of strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "services config should be an array of strings") end it "returns errors if job services parameter is not an array" do @@ -1080,31 +1093,31 @@ EOT end it "returns errors if stages is not an array" do - config = YAML.dump({ types: "test", rspec: { script: "test" } }) + config = YAML.dump({ stages: "test", rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "stages should be an array of strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "stages config should be an array of strings") end it "returns errors if stages is not an array of strings" do - config = YAML.dump({ types: [true, "test"], rspec: { script: "test" } }) + config = YAML.dump({ stages: [true, "test"], rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "stages should be an array of strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "stages config should be an array of strings") end it "returns errors if variables is not a map" do config = YAML.dump({ variables: "test", rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "variables should be a map of key-value strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "variables config should be a hash of key value pairs") end it "returns errors if variables is not a map of key-value strings" do config = YAML.dump({ variables: { test: false }, rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "variables should be a map of key-value strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "variables config should be a hash of key value pairs") end it "returns errors if job when is not on_success, on_failure or always" do @@ -1160,21 +1173,21 @@ EOT config = YAML.dump({ cache: { untracked: "string" }, rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "cache:untracked parameter should be an boolean") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "cache:untracked config should be a boolean value") end it "returns errors if cache:paths is not an array of strings" do config = YAML.dump({ cache: { paths: "string" }, rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "cache:paths parameter should be an array of strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "cache:paths config should be an array of strings") end it "returns errors if cache:key is not a string" do config = YAML.dump({ cache: { key: 1 }, rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "cache:key parameter should be a string") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "cache:key config should be a string or symbol") end it "returns errors if job cache:key is not an a string" do diff --git a/spec/lib/gitlab/ci/config/node/boolean_spec.rb b/spec/lib/gitlab/ci/config/node/boolean_spec.rb new file mode 100644 index 00000000000..deafa8bf8a7 --- /dev/null +++ b/spec/lib/gitlab/ci/config/node/boolean_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Node::Boolean do + let(:entry) { described_class.new(config) } + + describe 'validations' do + context 'when entry config value is valid' do + let(:config) { false } + + describe '#value' do + it 'returns key value' do + expect(entry.value).to eq false + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when entry value is not valid' do + let(:config) { ['incorrect'] } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'boolean config should be a boolean value' + end + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/node/cache_spec.rb b/spec/lib/gitlab/ci/config/node/cache_spec.rb new file mode 100644 index 00000000000..50f619ce26e --- /dev/null +++ b/spec/lib/gitlab/ci/config/node/cache_spec.rb @@ -0,0 +1,60 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Node::Cache do + let(:entry) { described_class.new(config) } + + describe 'validations' do + before { entry.process! } + + context 'when entry config value is correct' do + let(:config) do + { key: 'some key', + untracked: true, + paths: ['some/path/'] } + end + + describe '#value' do + it 'returns hash value' do + expect(entry.value).to eq config + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when entry value is not correct' do + describe '#errors' do + context 'when is not a hash' do + let(:config) { 'ls' } + + it 'reports errors with config value' do + expect(entry.errors) + .to include 'cache config should be a hash' + end + end + + context 'when descendants are invalid' do + let(:config) { { key: 1 } } + + it 'reports error with descendants' do + expect(entry.errors) + .to include 'key config should be a string or symbol' + end + end + + context 'when there is an unknown key present' do + let(:config) { { invalid: true } } + + it 'reports error with descendants' do + expect(entry.errors) + .to include 'cache config contains unknown keys: invalid' + end + end + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/node/configurable_spec.rb b/spec/lib/gitlab/ci/config/node/configurable_spec.rb index 9bbda6e7396..c468ecf957b 100644 --- a/spec/lib/gitlab/ci/config/node/configurable_spec.rb +++ b/spec/lib/gitlab/ci/config/node/configurable_spec.rb @@ -7,10 +7,42 @@ describe Gitlab::Ci::Config::Node::Configurable do node.include(described_class) end + describe 'validations' do + let(:validator) { node.validator.new(instance) } + + before do + node.class_eval do + attr_reader :config + + def initialize(config) + @config = config + end + end + + validator.validate + end + + context 'when node validator is invalid' do + let(:instance) { node.new('ls') } + + it 'returns invalid validator' do + expect(validator).to be_invalid + end + end + + context 'when node instance is valid' do + let(:instance) { node.new(key: 'value') } + + it 'returns valid validator' do + expect(validator).to be_valid + end + end + end + describe 'configured nodes' do before do node.class_eval do - allow_node :object, Object, description: 'test object' + node :object, Object, description: 'test object' end end diff --git a/spec/lib/gitlab/ci/config/node/factory_spec.rb b/spec/lib/gitlab/ci/config/node/factory_spec.rb index 01a707a6bd4..91ddef7bfbf 100644 --- a/spec/lib/gitlab/ci/config/node/factory_spec.rb +++ b/spec/lib/gitlab/ci/config/node/factory_spec.rb @@ -5,13 +5,13 @@ describe Gitlab::Ci::Config::Node::Factory do let(:factory) { described_class.new(entry_class) } let(:entry_class) { Gitlab::Ci::Config::Node::Script } - context 'when value setting value' do + context 'when setting up a value' do it 'creates entry with valid value' do entry = factory .with(value: ['ls', 'pwd']) .create! - expect(entry.value).to eq "ls\npwd" + expect(entry.value).to eq ['ls', 'pwd'] end context 'when setting description' do @@ -21,7 +21,7 @@ describe Gitlab::Ci::Config::Node::Factory do .with(description: 'test description') .create! - expect(entry.value).to eq "ls\npwd" + expect(entry.value).to eq ['ls', 'pwd'] expect(entry.description).to eq 'test description' end end @@ -35,9 +35,21 @@ describe Gitlab::Ci::Config::Node::Factory do expect(entry.key).to eq 'test key' end end + + context 'when setting a parent' do + let(:parent) { Object.new } + + it 'creates entry with valid parent' do + entry = factory + .with(value: 'ls', parent: parent) + .create! + + expect(entry.parent).to eq parent + end + end end - context 'when not setting value' do + context 'when not setting up a value' do it 'raises error' do expect { factory.create! }.to raise_error( Gitlab::Ci::Config::Node::Factory::InvalidFactory @@ -45,14 +57,13 @@ describe Gitlab::Ci::Config::Node::Factory do end end - context 'when creating a null entry' do - it 'creates a null entry' do + context 'when creating entry with nil value' do + it 'creates an undefined entry' do entry = factory .with(value: nil) - .nullify! .create! - expect(entry).to be_an_instance_of Gitlab::Ci::Config::Node::Null + expect(entry).to be_an_instance_of Gitlab::Ci::Config::Node::Undefined end end end diff --git a/spec/lib/gitlab/ci/config/node/global_spec.rb b/spec/lib/gitlab/ci/config/node/global_spec.rb index fddd53a2b57..c87c9e97bc8 100644 --- a/spec/lib/gitlab/ci/config/node/global_spec.rb +++ b/spec/lib/gitlab/ci/config/node/global_spec.rb @@ -13,57 +13,163 @@ describe Gitlab::Ci::Config::Node::Global do end end - describe '#key' do - it 'returns underscored class name' do - expect(global.key).to eq 'global' - end - end - context 'when hash is valid' do - let(:hash) do - { before_script: ['ls', 'pwd'] } - end + context 'when all entries defined' do + let(:hash) do + { before_script: ['ls', 'pwd'], + image: 'ruby:2.2', + services: ['postgres:9.1', 'mysql:5.5'], + variables: { VAR: 'value' }, + after_script: ['make clean'], + stages: ['build', 'pages'], + cache: { key: 'k', untracked: true, paths: ['public/'] } } + end - describe '#process!' do - before { global.process! } + describe '#process!' do + before { global.process! } - it 'creates nodes hash' do - expect(global.nodes).to be_an Array + it 'creates nodes hash' do + expect(global.nodes).to be_an Array + end + + it 'creates node object for each entry' do + expect(global.nodes.count).to eq 8 + end + + it 'creates node object using valid class' do + expect(global.nodes.first) + .to be_an_instance_of Gitlab::Ci::Config::Node::Script + expect(global.nodes.second) + .to be_an_instance_of Gitlab::Ci::Config::Node::Image + end + + it 'sets correct description for nodes' do + expect(global.nodes.first.description) + .to eq 'Script that will be executed before each job.' + expect(global.nodes.second.description) + .to eq 'Docker image that will be used to execute jobs.' + end end - it 'creates node object for each entry' do - expect(global.nodes.count).to eq 1 + describe '#leaf?' do + it 'is not leaf' do + expect(global).not_to be_leaf + end end - it 'creates node object using valid class' do - expect(global.nodes.first) - .to be_an_instance_of Gitlab::Ci::Config::Node::Script + context 'when not processed' do + describe '#before_script' do + it 'returns nil' do + expect(global.before_script).to be nil + end + end end - it 'sets correct description for nodes' do - expect(global.nodes.first.description) - .to eq 'Script that will be executed before each job.' + context 'when processed' do + before { global.process! } + + describe '#before_script' do + it 'returns correct script' do + expect(global.before_script).to eq ['ls', 'pwd'] + end + end + + describe '#image' do + it 'returns valid image' do + expect(global.image).to eq 'ruby:2.2' + end + end + + describe '#services' do + it 'returns array of services' do + expect(global.services).to eq ['postgres:9.1', 'mysql:5.5'] + end + end + + describe '#after_script' do + it 'returns after script' do + expect(global.after_script).to eq ['make clean'] + end + end + + describe '#variables' do + it 'returns variables' do + expect(global.variables).to eq(VAR: 'value') + end + end + + describe '#stages' do + context 'when stages key defined' do + it 'returns array of stages' do + expect(global.stages).to eq %w[build pages] + end + end + + context 'when deprecated types key defined' do + let(:hash) { { types: ['test', 'deploy'] } } + + it 'returns array of types as stages' do + expect(global.stages).to eq %w[test deploy] + end + end + end + + describe '#cache' do + it 'returns cache configuration' do + expect(global.cache) + .to eq(key: 'k', untracked: true, paths: ['public/']) + end + end end end - describe '#leaf?' do - it 'is not leaf' do - expect(global).not_to be_leaf + context 'when most of entires not defined' do + let(:hash) { { cache: { key: 'a' }, rspec: {} } } + before { global.process! } + + describe '#nodes' do + it 'instantizes all nodes' do + expect(global.nodes.count).to eq 8 + end + + it 'contains undefined nodes' do + expect(global.nodes.first) + .to be_an_instance_of Gitlab::Ci::Config::Node::Undefined + end end - end - describe '#before_script' do - context 'when processed' do - before { global.process! } + describe '#variables' do + it 'returns default value for variables' do + expect(global.variables).to eq({}) + end + end - it 'returns correct script' do - expect(global.before_script).to eq "ls\npwd" + describe '#stages' do + it 'returns an array of default stages' do + expect(global.stages).to eq %w[build test deploy] end end - context 'when not processed' do - it 'returns nil' do - expect(global.before_script).to be nil + describe '#cache' do + it 'returns correct cache definition' do + expect(global.cache).to eq(key: 'a') + end + end + end + + ## + # 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 + let(:hash) { { variables: nil } } + before { global.process! } + + describe '#variables' do + it 'undefined entry returns a default value' do + expect(global.variables).to eq({}) end end end @@ -85,7 +191,7 @@ describe Gitlab::Ci::Config::Node::Global do describe '#errors' do it 'reports errors from child nodes' do expect(global.errors) - .to include 'Before script config should be an array of strings' + .to include 'before_script config should be an array of strings' end end @@ -106,5 +212,17 @@ describe Gitlab::Ci::Config::Node::Global do expect(global).not_to be_valid end end + + describe '#errors' do + it 'returns error about invalid type' do + expect(global.errors.first).to match /should be a hash/ + end + end + end + + describe '#defined?' do + it 'is concrete entry that is defined' do + expect(global.defined?).to be true + end end end diff --git a/spec/lib/gitlab/ci/config/node/image_spec.rb b/spec/lib/gitlab/ci/config/node/image_spec.rb new file mode 100644 index 00000000000..d11bb39f328 --- /dev/null +++ b/spec/lib/gitlab/ci/config/node/image_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Node::Image do + let(:entry) { described_class.new(config) } + + describe 'validation' do + context 'when entry config value is correct' do + let(:config) { 'ruby:2.2' } + + describe '#value' do + it 'returns image string' do + expect(entry.value).to eq 'ruby:2.2' + end + end + + describe '#errors' do + it 'does not append errors' do + expect(entry.errors).to be_empty + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when entry value is not correct' do + let(:config) { ['ruby:2.2'] } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'image config should be a string' + end + end + + describe '#valid?' do + it 'is not valid' do + expect(entry).not_to be_valid + end + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/node/key_spec.rb b/spec/lib/gitlab/ci/config/node/key_spec.rb new file mode 100644 index 00000000000..8cda43173fe --- /dev/null +++ b/spec/lib/gitlab/ci/config/node/key_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Node::Key do + let(:entry) { described_class.new(config) } + + describe 'validations' do + context 'when entry config value is correct' do + let(:config) { 'test' } + + describe '#value' do + it 'returns key value' do + expect(entry.value).to eq 'test' + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when entry value is not correct' do + let(:config) { [ 'incorrect' ] } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'key config should be a string or symbol' + end + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/node/null_spec.rb b/spec/lib/gitlab/ci/config/node/null_spec.rb deleted file mode 100644 index 36101c62462..00000000000 --- a/spec/lib/gitlab/ci/config/node/null_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Ci::Config::Node::Null do - let(:entry) { described_class.new(nil) } - - describe '#leaf?' do - it 'is leaf node' do - expect(entry).to be_leaf - end - end - - describe '#any_method' do - it 'responds with nil' do - expect(entry.any_method).to be nil - end - end - - describe '#value' do - it 'returns nil' do - expect(entry.value).to be nil - end - end -end diff --git a/spec/lib/gitlab/ci/config/node/paths_spec.rb b/spec/lib/gitlab/ci/config/node/paths_spec.rb new file mode 100644 index 00000000000..6fd744b3975 --- /dev/null +++ b/spec/lib/gitlab/ci/config/node/paths_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Node::Paths do + let(:entry) { described_class.new(config) } + + describe 'validations' do + context 'when entry config value is valid' do + let(:config) { ['some/file', 'some/path/'] } + + describe '#value' do + it 'returns key value' do + expect(entry.value).to eq config + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when entry value is not valid' do + let(:config) { [ 1 ] } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'paths config should be an array of strings' + end + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/node/script_spec.rb b/spec/lib/gitlab/ci/config/node/script_spec.rb index 6af6aa15eef..ee7395362a9 100644 --- a/spec/lib/gitlab/ci/config/node/script_spec.rb +++ b/spec/lib/gitlab/ci/config/node/script_spec.rb @@ -10,8 +10,8 @@ describe Gitlab::Ci::Config::Node::Script do let(:config) { ['ls', 'pwd'] } describe '#value' do - it 'returns concatenated command' do - expect(entry.value).to eq "ls\npwd" + it 'returns array of strings' do + expect(entry.value).to eq config end end @@ -34,7 +34,7 @@ describe Gitlab::Ci::Config::Node::Script do describe '#errors' do it 'saves errors' do expect(entry.errors) - .to include 'Script config should be an array of strings' + .to include 'script config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/node/services_spec.rb b/spec/lib/gitlab/ci/config/node/services_spec.rb new file mode 100644 index 00000000000..be0fe46befd --- /dev/null +++ b/spec/lib/gitlab/ci/config/node/services_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Node::Services do + let(:entry) { described_class.new(config) } + + describe 'validations' do + context 'when entry config value is correct' do + let(:config) { ['postgres:9.1', 'mysql:5.5'] } + + describe '#value' do + it 'returns array of services as is' do + expect(entry.value).to eq config + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when entry value is not correct' do + let(:config) { 'ls' } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'services config should be an array of strings' + end + end + + describe '#valid?' do + it 'is not valid' do + expect(entry).not_to be_valid + end + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/node/stages_spec.rb b/spec/lib/gitlab/ci/config/node/stages_spec.rb new file mode 100644 index 00000000000..1a3818d8997 --- /dev/null +++ b/spec/lib/gitlab/ci/config/node/stages_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Node::Stages do + let(:entry) { described_class.new(config) } + + describe 'validations' do + context 'when entry config value is correct' do + let(:config) { [:stage1, :stage2] } + + describe '#value' do + it 'returns array of stages' do + expect(entry.value).to eq config + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when entry value is not correct' do + let(:config) { { test: true } } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'stages config should be an array of strings' + end + end + + describe '#valid?' do + it 'is not valid' do + expect(entry).not_to be_valid + end + end + end + end + + describe '.default' do + it 'returns default stages' do + expect(described_class.default).to eq %w[build test deploy] + end + end +end diff --git a/spec/lib/gitlab/ci/config/node/undefined_spec.rb b/spec/lib/gitlab/ci/config/node/undefined_spec.rb new file mode 100644 index 00000000000..0c6608d906d --- /dev/null +++ b/spec/lib/gitlab/ci/config/node/undefined_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Node::Undefined do + let(:undefined) { described_class.new(entry) } + let(:entry) { Class.new } + + describe '#leaf?' do + it 'is leaf node' do + expect(undefined).to be_leaf + end + end + + describe '#valid?' do + it 'is always valid' do + expect(undefined).to be_valid + end + end + + describe '#errors' do + it 'is does not contain errors' do + expect(undefined.errors).to be_empty + end + end + + describe '#value' do + before do + allow(entry).to receive(:default).and_return('some value') + end + + it 'returns default value for entry' do + expect(undefined.value).to eq 'some value' + end + end + + describe '#undefined?' do + it 'is not a defined entry' do + expect(undefined.defined?).to be false + end + end +end diff --git a/spec/lib/gitlab/ci/config/node/validator_spec.rb b/spec/lib/gitlab/ci/config/node/validator_spec.rb index ad875d55384..090fd63b844 100644 --- a/spec/lib/gitlab/ci/config/node/validator_spec.rb +++ b/spec/lib/gitlab/ci/config/node/validator_spec.rb @@ -5,7 +5,18 @@ describe Gitlab::Ci::Config::Node::Validator do let(:validator_instance) { validator.new(node) } let(:node) { spy('node') } - shared_examples 'delegated validator' do + before do + allow(node).to receive(:key).and_return('node') + allow(node).to receive(:ancestors).and_return([]) + end + + describe 'delegated validator' do + before do + validator.class_eval do + validates :test_attribute, presence: true + end + end + context 'when node is valid' do before do allow(node).to receive(:test_attribute).and_return('valid value') @@ -19,7 +30,7 @@ describe Gitlab::Ci::Config::Node::Validator do it 'returns no errors' do validator_instance.validate - expect(validator_instance.full_errors).to be_empty + expect(validator_instance.messages).to be_empty end end @@ -36,32 +47,9 @@ describe Gitlab::Ci::Config::Node::Validator do it 'returns errors' do validator_instance.validate - expect(validator_instance.full_errors).not_to be_empty + expect(validator_instance.messages) + .to include "node test attribute can't be blank" end end end - - describe 'attributes validations' do - before do - validator.class_eval do - validates :test_attribute, presence: true - end - end - - it_behaves_like 'delegated validator' - end - - describe 'interface validations' do - before do - validator.class_eval do - validate do - unless @node.test_attribute == 'valid value' - errors.add(:test_attribute, 'invalid value') - end - end - end - end - - it_behaves_like 'delegated validator' - end end diff --git a/spec/lib/gitlab/ci/config/node/variables_spec.rb b/spec/lib/gitlab/ci/config/node/variables_spec.rb new file mode 100644 index 00000000000..4b6d971ec71 --- /dev/null +++ b/spec/lib/gitlab/ci/config/node/variables_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Node::Variables do + let(:entry) { described_class.new(config) } + + describe 'validations' do + context 'when entry config value is correct' do + let(:config) do + { 'VARIABLE_1' => 'value 1', 'VARIABLE_2' => 'value 2' } + end + + describe '#value' do + it 'returns hash with key value strings' do + expect(entry.value).to eq config + end + end + + describe '#errors' do + it 'does not append errors' do + expect(entry.errors).to be_empty + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when entry value is not correct' do + let(:config) { [ :VAR, 'test' ] } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include /should be a hash of key value pairs/ + end + end + + describe '#valid?' do + it 'is not valid' do + expect(entry).not_to be_valid + end + end + end + end +end diff --git a/spec/lib/gitlab/ci/config_spec.rb b/spec/lib/gitlab/ci/config_spec.rb index 2a5d132db7b..bc5a5e43103 100644 --- a/spec/lib/gitlab/ci/config_spec.rb +++ b/spec/lib/gitlab/ci/config_spec.rb @@ -40,38 +40,38 @@ describe Gitlab::Ci::Config do end end end + end - context 'when config is invalid' do - context 'when yml is incorrect' do - let(:yml) { '// invalid' } + context 'when config is invalid' do + context 'when yml is incorrect' do + let(:yml) { '// invalid' } - describe '.new' do - it 'raises error' do - expect { config }.to raise_error( - Gitlab::Ci::Config::Loader::FormatError, - /Invalid configuration format/ - ) - end + describe '.new' do + it 'raises error' do + expect { config }.to raise_error( + Gitlab::Ci::Config::Loader::FormatError, + /Invalid configuration format/ + ) end end + end - context 'when config logic is incorrect' do - let(:yml) { 'before_script: "ls"' } + context 'when config logic is incorrect' do + let(:yml) { 'before_script: "ls"' } - describe '#valid?' do - it 'is not valid' do - expect(config).not_to be_valid - end + describe '#valid?' do + it 'is not valid' do + expect(config).not_to be_valid + end - it 'has errors' do - expect(config.errors).not_to be_empty - end + it 'has errors' do + expect(config.errors).not_to be_empty end + end - describe '#errors' do - it 'returns an array of strings' do - expect(config.errors).to all(be_an_instance_of(String)) - end + describe '#errors' do + it 'returns an array of strings' do + expect(config.errors).to all(be_an_instance_of(String)) end end end |