summaryrefslogtreecommitdiff
path: root/spec/ci/lib
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ci/lib')
-rw-r--r--spec/ci/lib/ansi2html_spec.rb133
-rw-r--r--spec/ci/lib/charts_spec.rb17
-rw-r--r--spec/ci/lib/gitlab_ci_yaml_processor_spec.rb311
-rw-r--r--spec/ci/lib/upgrader_spec.rb39
4 files changed, 500 insertions, 0 deletions
diff --git a/spec/ci/lib/ansi2html_spec.rb b/spec/ci/lib/ansi2html_spec.rb
new file mode 100644
index 00000000000..aa60011685b
--- /dev/null
+++ b/spec/ci/lib/ansi2html_spec.rb
@@ -0,0 +1,133 @@
+require 'spec_helper'
+
+describe Ansi2html do
+
+ it "prints non-ansi as-is" do
+ Ansi2html::convert("Hello").should == 'Hello'
+ end
+
+ it "strips non-color-changing controll sequences" do
+ Ansi2html::convert("Hello \e[2Kworld").should == 'Hello world'
+ end
+
+ it "prints simply red" do
+ Ansi2html::convert("\e[31mHello\e[0m").should == '<span class="term-fg-red">Hello</span>'
+ end
+
+ it "prints simply red without trailing reset" do
+ Ansi2html::convert("\e[31mHello").should == '<span class="term-fg-red">Hello</span>'
+ end
+
+ it "prints simply yellow" do
+ Ansi2html::convert("\e[33mHello\e[0m").should == '<span class="term-fg-yellow">Hello</span>'
+ end
+
+ it "prints default on blue" do
+ Ansi2html::convert("\e[39;44mHello").should == '<span class="term-bg-blue">Hello</span>'
+ end
+
+ it "prints red on blue" do
+ Ansi2html::convert("\e[31;44mHello").should == '<span class="term-fg-red term-bg-blue">Hello</span>'
+ end
+
+ it "resets colors after red on blue" do
+ Ansi2html::convert("\e[31;44mHello\e[0m world").should == '<span class="term-fg-red term-bg-blue">Hello</span> world'
+ end
+
+ it "performs color change from red/blue to yellow/blue" do
+ Ansi2html::convert("\e[31;44mHello \e[33mworld").should == '<span class="term-fg-red term-bg-blue">Hello </span><span class="term-fg-yellow term-bg-blue">world</span>'
+ end
+
+ it "performs color change from red/blue to yellow/green" do
+ Ansi2html::convert("\e[31;44mHello \e[33;42mworld").should == '<span class="term-fg-red term-bg-blue">Hello </span><span class="term-fg-yellow term-bg-green">world</span>'
+ end
+
+ it "performs color change from red/blue to reset to yellow/green" do
+ Ansi2html::convert("\e[31;44mHello\e[0m \e[33;42mworld").should == '<span class="term-fg-red term-bg-blue">Hello</span> <span class="term-fg-yellow term-bg-green">world</span>'
+ end
+
+ it "ignores unsupported codes" do
+ Ansi2html::convert("\e[51mHello\e[0m").should == 'Hello'
+ end
+
+ it "prints light red" do
+ Ansi2html::convert("\e[91mHello\e[0m").should == '<span class="term-fg-l-red">Hello</span>'
+ end
+
+ it "prints default on light red" do
+ Ansi2html::convert("\e[101mHello\e[0m").should == '<span class="term-bg-l-red">Hello</span>'
+ end
+
+ it "performs color change from red/blue to default/blue" do
+ Ansi2html::convert("\e[31;44mHello \e[39mworld").should == '<span class="term-fg-red term-bg-blue">Hello </span><span class="term-bg-blue">world</span>'
+ end
+
+ it "performs color change from light red/blue to default/blue" do
+ Ansi2html::convert("\e[91;44mHello \e[39mworld").should == '<span class="term-fg-l-red term-bg-blue">Hello </span><span class="term-bg-blue">world</span>'
+ end
+
+ it "prints bold text" do
+ Ansi2html::convert("\e[1mHello").should == '<span class="term-bold">Hello</span>'
+ end
+
+ it "resets bold text" do
+ Ansi2html::convert("\e[1mHello\e[21m world").should == '<span class="term-bold">Hello</span> world'
+ Ansi2html::convert("\e[1mHello\e[22m world").should == '<span class="term-bold">Hello</span> world'
+ end
+
+ it "prints italic text" do
+ Ansi2html::convert("\e[3mHello").should == '<span class="term-italic">Hello</span>'
+ end
+
+ it "resets italic text" do
+ Ansi2html::convert("\e[3mHello\e[23m world").should == '<span class="term-italic">Hello</span> world'
+ end
+
+ it "prints underlined text" do
+ Ansi2html::convert("\e[4mHello").should == '<span class="term-underline">Hello</span>'
+ end
+
+ it "resets underlined text" do
+ Ansi2html::convert("\e[4mHello\e[24m world").should == '<span class="term-underline">Hello</span> world'
+ end
+
+ it "prints concealed text" do
+ Ansi2html::convert("\e[8mHello").should == '<span class="term-conceal">Hello</span>'
+ end
+
+ it "resets concealed text" do
+ Ansi2html::convert("\e[8mHello\e[28m world").should == '<span class="term-conceal">Hello</span> world'
+ end
+
+ it "prints crossed-out text" do
+ Ansi2html::convert("\e[9mHello").should == '<span class="term-cross">Hello</span>'
+ end
+
+ it "resets crossed-out text" do
+ Ansi2html::convert("\e[9mHello\e[29m world").should == '<span class="term-cross">Hello</span> world'
+ end
+
+ it "can print 256 xterm fg colors" do
+ Ansi2html::convert("\e[38;5;16mHello").should == '<span class="xterm-fg-16">Hello</span>'
+ end
+
+ it "can print 256 xterm fg colors on normal magenta background" do
+ Ansi2html::convert("\e[38;5;16;45mHello").should == '<span class="xterm-fg-16 term-bg-magenta">Hello</span>'
+ end
+
+ it "can print 256 xterm bg colors" do
+ Ansi2html::convert("\e[48;5;240mHello").should == '<span class="xterm-bg-240">Hello</span>'
+ end
+
+ it "can print 256 xterm bg colors on normal magenta foreground" do
+ Ansi2html::convert("\e[48;5;16;35mHello").should == '<span class="term-fg-magenta xterm-bg-16">Hello</span>'
+ end
+
+ it "prints bold colored text vividly" do
+ Ansi2html::convert("\e[1;31mHello\e[0m").should == '<span class="term-fg-l-red term-bold">Hello</span>'
+ end
+
+ it "prints bold light colored text correctly" do
+ Ansi2html::convert("\e[1;91mHello\e[0m").should == '<span class="term-fg-l-red term-bold">Hello</span>'
+ end
+end
diff --git a/spec/ci/lib/charts_spec.rb b/spec/ci/lib/charts_spec.rb
new file mode 100644
index 00000000000..236cfc2a1f6
--- /dev/null
+++ b/spec/ci/lib/charts_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe "Charts" do
+
+ context "build_times" do
+ before do
+ @project = FactoryGirl.create(:project)
+ @commit = FactoryGirl.create(:commit, project: @project)
+ FactoryGirl.create(:build, commit: @commit)
+ end
+
+ it 'should return build times in minutes' do
+ chart = Charts::BuildTime.new(@project)
+ chart.build_times.should == [2]
+ end
+ end
+end
diff --git a/spec/ci/lib/gitlab_ci_yaml_processor_spec.rb b/spec/ci/lib/gitlab_ci_yaml_processor_spec.rb
new file mode 100644
index 00000000000..ed3d4e84054
--- /dev/null
+++ b/spec/ci/lib/gitlab_ci_yaml_processor_spec.rb
@@ -0,0 +1,311 @@
+require 'spec_helper'
+
+describe GitlabCiYamlProcessor do
+
+ describe "#builds_for_ref" do
+ let (:type) { 'test' }
+
+ it "returns builds if no branch specified" do
+ config = YAML.dump({
+ before_script: ["pwd"],
+ rspec: {script: "rspec"}
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ config_processor.builds_for_stage_and_ref(type, "master").size.should == 1
+ config_processor.builds_for_stage_and_ref(type, "master").first.should == {
+ stage: "test",
+ except: nil,
+ name: :rspec,
+ only: nil,
+ script: "pwd\nrspec",
+ tags: [],
+ options: {},
+ allow_failure: false
+ }
+ end
+
+ it "does not return builds if only has another branch" do
+ config = YAML.dump({
+ before_script: ["pwd"],
+ rspec: {script: "rspec", only: ["deploy"]}
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ config_processor.builds_for_stage_and_ref(type, "master").size.should == 0
+ end
+
+ it "does not return builds if only has regexp with another branch" do
+ config = YAML.dump({
+ before_script: ["pwd"],
+ rspec: {script: "rspec", only: ["/^deploy$/"]}
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ config_processor.builds_for_stage_and_ref(type, "master").size.should == 0
+ end
+
+ it "returns builds if only has specified this branch" do
+ config = YAML.dump({
+ before_script: ["pwd"],
+ rspec: {script: "rspec", only: ["master"]}
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ config_processor.builds_for_stage_and_ref(type, "master").size.should == 1
+ end
+
+ it "does not build tags" do
+ config = YAML.dump({
+ before_script: ["pwd"],
+ rspec: {script: "rspec", except: ["tags"]}
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ config_processor.builds_for_stage_and_ref(type, "0-1", true).size.should == 0
+ end
+
+ it "returns builds if only has a list of branches including specified" do
+ config = YAML.dump({
+ before_script: ["pwd"],
+ rspec: {script: "rspec", type: type, only: ["master", "deploy"]}
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ config_processor.builds_for_stage_and_ref(type, "deploy").size.should == 1
+ end
+
+ it "returns build only for specified type" do
+
+ config = YAML.dump({
+ before_script: ["pwd"],
+ build: {script: "build", type: "build", only: ["master", "deploy"]},
+ rspec: {script: "rspec", type: type, only: ["master", "deploy"]},
+ staging: {script: "deploy", type: "deploy", only: ["master", "deploy"]},
+ production: {script: "deploy", type: "deploy", only: ["master", "deploy"]},
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ config_processor.builds_for_stage_and_ref("production", "deploy").size.should == 0
+ config_processor.builds_for_stage_and_ref(type, "deploy").size.should == 1
+ config_processor.builds_for_stage_and_ref("deploy", "deploy").size.should == 2
+ end
+ end
+
+ describe "Image and service handling" do
+ it "returns image and service when defined" do
+ config = YAML.dump({
+ image: "ruby:2.1",
+ services: ["mysql"],
+ before_script: ["pwd"],
+ rspec: {script: "rspec"}
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ config_processor.builds_for_stage_and_ref("test", "master").size.should == 1
+ config_processor.builds_for_stage_and_ref("test", "master").first.should == {
+ except: nil,
+ stage: "test",
+ name: :rspec,
+ only: nil,
+ script: "pwd\nrspec",
+ tags: [],
+ options: {
+ image: "ruby:2.1",
+ services: ["mysql"]
+ },
+ allow_failure: false
+ }
+ end
+
+ it "returns image and service when overridden for job" do
+ config = YAML.dump({
+ image: "ruby:2.1",
+ services: ["mysql"],
+ before_script: ["pwd"],
+ rspec: {image: "ruby:2.5", services: ["postgresql"], script: "rspec"}
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ config_processor.builds_for_stage_and_ref("test", "master").size.should == 1
+ config_processor.builds_for_stage_and_ref("test", "master").first.should == {
+ except: nil,
+ stage: "test",
+ name: :rspec,
+ only: nil,
+ script: "pwd\nrspec",
+ tags: [],
+ options: {
+ image: "ruby:2.5",
+ services: ["postgresql"]
+ },
+ allow_failure: false
+ }
+ end
+ end
+
+ describe "Variables" do
+ it "returns variables when defined" do
+ variables = {
+ var1: "value1",
+ var2: "value2",
+ }
+ config = YAML.dump({
+ variables: variables,
+ before_script: ["pwd"],
+ rspec: {script: "rspec"}
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+ config_processor.variables.should == variables
+ end
+ end
+
+ describe "Error handling" do
+ it "indicates that object is invalid" do
+ expect{GitlabCiYamlProcessor.new("invalid_yaml\n!ccdvlf%612334@@@@")}.to raise_error(GitlabCiYamlProcessor::ValidationError)
+ end
+
+ it "returns errors if tags parameter is invalid" do
+ config = YAML.dump({rspec: {script: "test", tags: "mysql"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: tags parameter should be an array of strings")
+ end
+
+ it "returns errors if before_script parameter is invalid" do
+ config = YAML.dump({before_script: "bundle update", rspec: {script: "test"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "before_script should be an array of strings")
+ end
+
+ it "returns errors if image parameter is invalid" do
+ config = YAML.dump({image: ["test"], rspec: {script: "test"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "image should be a string")
+ end
+
+ it "returns errors if job image parameter is invalid" do
+ config = YAML.dump({rspec: {script: "test", image: ["test"]}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: image should be a string")
+ end
+
+ it "returns errors if services parameter is not an array" do
+ config = YAML.dump({services: "test", rspec: {script: "test"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "services 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)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "services should be an array of strings")
+ end
+
+ it "returns errors if job services parameter is not an array" do
+ config = YAML.dump({rspec: {script: "test", services: "test"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: services should be an array of strings")
+ end
+
+ it "returns errors if job services parameter is not an array of strings" do
+ config = YAML.dump({rspec: {script: "test", services: [10, "test"]}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: services should be an array of strings")
+ end
+
+ it "returns errors if there are unknown parameters" do
+ config = YAML.dump({extra: "bundle update"})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "Unknown parameter: extra")
+ end
+
+ it "returns errors if there are unknown parameters that are hashes, but doesn't have a script" do
+ config = YAML.dump({extra: {services: "test"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "Unknown parameter: extra")
+ end
+
+ it "returns errors if there is no any jobs defined" do
+ config = YAML.dump({before_script: ["bundle update"]})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "Please define at least one job")
+ end
+
+ it "returns errors if job allow_failure parameter is not an boolean" do
+ config = YAML.dump({rspec: {script: "test", allow_failure: "string"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: allow_failure parameter should be an boolean")
+ end
+
+ it "returns errors if job stage is not a string" do
+ config = YAML.dump({rspec: {script: "test", type: 1, allow_failure: "string"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: stage parameter should be build, test, deploy")
+ end
+
+ it "returns errors if job stage is not a pre-defined stage" do
+ config = YAML.dump({rspec: {script: "test", type: "acceptance", allow_failure: "string"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: stage parameter should be build, test, deploy")
+ end
+
+ it "returns errors if job stage is not a defined stage" do
+ config = YAML.dump({types: ["build", "test"], rspec: {script: "test", type: "acceptance", allow_failure: "string"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: stage parameter should be build, test")
+ end
+
+ it "returns errors if stages is not an array" do
+ config = YAML.dump({types: "test", rspec: {script: "test"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "stages 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"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "stages 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)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "variables should be a map of key-valued strings")
+ end
+
+ it "returns errors if variables is not a map of key-valued strings" do
+ config = YAML.dump({variables: {test: false}, rspec: {script: "test"}})
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "variables should be a map of key-valued strings")
+ end
+ end
+end
diff --git a/spec/ci/lib/upgrader_spec.rb b/spec/ci/lib/upgrader_spec.rb
new file mode 100644
index 00000000000..40a98307ad2
--- /dev/null
+++ b/spec/ci/lib/upgrader_spec.rb
@@ -0,0 +1,39 @@
+require 'spec_helper'
+
+describe Upgrader do
+ let(:upgrader) { Upgrader.new }
+ let(:current_version) { GitlabCi::VERSION }
+
+ describe 'current_version_raw' do
+ it { upgrader.current_version_raw.should == current_version }
+ end
+
+ describe 'latest_version?' do
+ it 'should be true if newest version' do
+ upgrader.stub(latest_version_raw: current_version)
+ upgrader.latest_version?.should be_true
+ end
+ end
+
+ describe 'latest_version_raw' do
+ it 'should be latest version for GitlabCI 3' do
+ allow(upgrader).to receive(:current_version_raw).and_return('3.0.0')
+ expect(upgrader.latest_version_raw).to eq('v3.2.0')
+ end
+
+ it 'should get the latest version from tags' do
+ allow(upgrader).to receive(:fetch_git_tags).and_return([
+ '1b5bee25b51724214c7a3307ef94027ab93ec982 refs/tags/v7.8.1',
+ '424cb42e35947fa304ef83eb211ffc657e31aef3 refs/tags/v7.8.1^{}',
+ '498e5ba63be1bb99e30c6e720902d864aac4413c refs/tags/v7.9.0.rc1',
+ '96aaf45ae93bd43e8b3f5d4d353d64d3cbe1e63b refs/tags/v7.9.0.rc1^{}',
+ '94aaf45ae93bd43e8b3fad4a353d64d3cbe1e62b refs/tags/v7.1.0',
+ '96aaf45ae93ba13e8b3f5d4d353d64d3cbe1e251 refs/tags/v7.1.0^{}',
+ '29359d64442bf54b4ca1d8b439fd9e5f9cd83252 refs/tags/v7.10.0',
+ '4d9213a6378bff43a69ae099702fb81e29335e7a refs/tags/v7.10.0^{}',
+ '1d93e1626bda93622ca7a2ae2825e2e94dabf3c6 refs/tags/v7.12.0',
+ '0188a9d1c2efdc52bfad36ad303686be997de713 refs/tags/v7.12.0^{}'])
+ expect(upgrader.latest_version_raw).to eq("v7.12.0")
+ end
+ end
+end