build_eval 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/lib/build_eval/error.rb +11 -0
  3. data/lib/build_eval/http.rb +17 -3
  4. data/lib/build_eval/result/build_result.rb +2 -2
  5. data/lib/build_eval/result/status.rb +5 -4
  6. data/lib/build_eval/server/cruise_control_response.rb +22 -0
  7. data/lib/build_eval/server/decorator.rb +1 -1
  8. data/lib/build_eval/server/invalid_selector_error.rb +13 -0
  9. data/lib/build_eval/server/jenkins.rb +23 -0
  10. data/lib/build_eval/server/team_city.rb +2 -5
  11. data/lib/build_eval/server/travis.rb +3 -6
  12. data/lib/build_eval/version.rb +1 -1
  13. data/lib/build_eval.rb +7 -1
  14. data/spec/lib/build_eval/error_spec.rb +21 -0
  15. data/spec/lib/build_eval/http_shared_context.rb +7 -0
  16. data/spec/lib/build_eval/http_spec.rb +25 -5
  17. data/spec/lib/build_eval/result/build_result_spec.rb +4 -4
  18. data/spec/lib/build_eval/result/status_spec.rb +30 -11
  19. data/spec/lib/build_eval/server/cruise_control_response_spec.rb +115 -0
  20. data/spec/lib/build_eval/server/decorator_spec.rb +6 -6
  21. data/spec/lib/build_eval/server/invalid_selector_error_spec.rb +27 -0
  22. data/spec/lib/build_eval/server/jenkins_integration_spec.rb +52 -0
  23. data/spec/lib/build_eval/server/jenkins_spec.rb +70 -0
  24. data/spec/lib/build_eval/server/server_shared_examples.rb +15 -0
  25. data/spec/lib/build_eval/server/team_city_integration_spec.rb +85 -0
  26. data/spec/lib/build_eval/server/team_city_spec.rb +24 -88
  27. data/spec/lib/build_eval/server/travis_integration_spec.rb +53 -0
  28. data/spec/lib/build_eval/server/travis_spec.rb +33 -55
  29. data/spec/lib/build_eval_smoke_spec.rb +25 -0
  30. data/spec/spec_helper.rb +14 -6
  31. metadata +42 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 582fae85bf01612ef73e180f2d762834629d5cc7
4
- data.tar.gz: 0d8fa6378adb766d1c7392dc3bbcb9c8821fdc26
3
+ metadata.gz: c9ed39e2bae3a1ef5d1ffd40242183287fae193a
4
+ data.tar.gz: bff2e6552ad2a28e5d1dbc0cea6b463cd6a82a3a
5
5
  SHA512:
6
- metadata.gz: 8ff9b48b6b4dc4073b249c87e3a9258b50a94b3e68fb1e218d4c4e9560753b131fb474d5f398f99e7f6c7e564a24d1f49385b7f4cb75136988e697f104f1c7c1
7
- data.tar.gz: 1c4c9bb4757754e7addef6326c15cc8d96a74eaa08121023330a74da3e388ebd1dfaf78d0776e33be39480202b4bb482cfe35b1e739e68382305aab9511ecbde
6
+ metadata.gz: b6006e6709284a157a71b6b48f09b0706f9112c89706e57de79faf3a40d3b46d8e998366c422420349f5d48e1e2beb6e0f6ff3cdddb59993efb5abe34bc862a6
7
+ data.tar.gz: 6c2978e0ce2095206a9086b018beef07e409f18dbf3c8e9afb5c7b8210942728b496ac04d8af499f3e9d54deb5df6435dfedef34f18d252661602afc1f1113b1
@@ -0,0 +1,11 @@
1
+ module BuildEval
2
+
3
+ class Error < ::StandardError
4
+
5
+ def initialize(message)
6
+ super(message)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -2,15 +2,29 @@ module BuildEval
2
2
 
3
3
  class Http
4
4
 
5
- def self.get(uri_string, basic_auth=nil)
5
+ def initialize(config)
6
+ @username = config[:username]
7
+ @password = config[:password]
8
+ @ssl_verify_mode = config[:ssl_verify_mode]
9
+ end
10
+
11
+ def get(uri_string)
6
12
  uri = URI.parse(uri_string)
7
- Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
13
+ Net::HTTP.start(uri.host, uri.port, ssl_options(uri)) do |http|
8
14
  request = Net::HTTP::Get.new(uri.request_uri)
9
- request.basic_auth(basic_auth[:username], basic_auth[:password]) if basic_auth
15
+ request.basic_auth(@username, @password) if @username && @password
10
16
  http.request(request)
11
17
  end
12
18
  end
13
19
 
20
+ private
21
+
22
+ def ssl_options(uri)
23
+ ssl_options = { use_ssl: uri.scheme == "https" }
24
+ ssl_options[:ssl_verify_mode] = @ssl_verify_mode if @ssl_verify_mode
25
+ ssl_options
26
+ end
27
+
14
28
  end
15
29
 
16
30
  end
@@ -9,8 +9,8 @@ module BuildEval
9
9
  self.new(build_name: args[:build_name], status: BuildEval::Result::Status.find(args[:status_name]))
10
10
  end
11
11
 
12
- def unknown(build_name)
13
- self.new(build_name: build_name, status: BuildEval::Result::Status::UNKNOWN)
12
+ def indeterminate(build_name)
13
+ self.new(build_name: build_name, status: BuildEval::Result::Status::INDETERMINATE)
14
14
  end
15
15
 
16
16
  end
@@ -13,10 +13,11 @@ module BuildEval
13
13
 
14
14
  public
15
15
 
16
- SUCCESS = self.new(severity: 0, symbol: :success!, description: "succeeded")
17
- UNKNOWN = self.new(severity: 1, symbol: :warning!, description: "unknown")
18
- FAILURE = self.new(severity: 2, symbol: :failure!, description: "failed")
19
- ERROR = self.new(severity: 3, symbol: :failure!, description: "errored")
16
+ SUCCESS = self.new(severity: 0, symbol: :success!, description: "succeeded")
17
+ UNKNOWN = self.new(severity: 1, symbol: :warning!, description: "unknown")
18
+ INDETERMINATE = self.new(severity: 2, symbol: :warning!, description: "indeterminate")
19
+ FAILURE = self.new(severity: 3, symbol: :failure!, description: "failed")
20
+ ERROR = self.new(severity: 4, symbol: :failure!, description: "errored")
20
21
 
21
22
  class << self
22
23
 
@@ -0,0 +1,22 @@
1
+ module BuildEval
2
+ module Server
3
+
4
+ class CruiseControlResponse
5
+
6
+ def initialize(raw_response)
7
+ @raw_response = raw_response
8
+ end
9
+
10
+ def parse_result(project_selector)
11
+ build_element = Nokogiri::XML(@raw_response.body).xpath(project_selector).first
12
+ raise BuildEval::Server::InvalidSelectorError.new(@raw_response, project_selector) unless build_element
13
+ BuildEval::Result::BuildResult.create(
14
+ build_name: build_element.attribute("name").value.match(/[^\/]+$/)[0],
15
+ status_name: build_element.attribute("lastBuildStatus").value
16
+ )
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
@@ -11,7 +11,7 @@ module BuildEval
11
11
  begin
12
12
  @delegate.build_result(name)
13
13
  rescue Exception
14
- BuildEval::Result::BuildResult.unknown(name)
14
+ BuildEval::Result::BuildResult.indeterminate(name)
15
15
  end
16
16
  end
17
17
 
@@ -0,0 +1,13 @@
1
+ module BuildEval
2
+ module Server
3
+
4
+ class InvalidSelectorError < BuildEval::Error
5
+
6
+ def initialize(response, selector)
7
+ super("Build response did not match selector:\nResponse: #{response.message}\nSelector: #{selector}")
8
+ end
9
+
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ module BuildEval
2
+ module Server
3
+
4
+ class Jenkins
5
+
6
+ def initialize(args)
7
+ @http = BuildEval::Http.new(args)
8
+ @base_uri = args[:uri]
9
+ end
10
+
11
+ def build_result(name)
12
+ raw_response = @http.get("#{@base_uri}/cc.xml")
13
+ BuildEval::Server::CruiseControlResponse.new(raw_response).parse_result("//Project[@name=\"#{name}\"]")
14
+ end
15
+
16
+ def to_s
17
+ "Jenkins server #{@base_uri}"
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
@@ -4,15 +4,12 @@ module BuildEval
4
4
  class TeamCity
5
5
 
6
6
  def initialize(args)
7
+ @http = BuildEval::Http.new(args)
7
8
  @base_uri = args[:uri]
8
- @username = args[:username]
9
- @password = args[:password]
10
9
  end
11
10
 
12
11
  def build_result(name)
13
- response = BuildEval::Http.get(
14
- "#{@base_uri}/httpAuth/app/rest/buildTypes/id:#{name}/builds", username: @username, password: @password
15
- )
12
+ response = @http.get("#{@base_uri}/httpAuth/app/rest/buildTypes/id:#{name}/builds")
16
13
  build_element = Nokogiri::XML(response.body).xpath("//build").first
17
14
  raise "Unexpected build response: #{response.message}" unless build_element
18
15
  BuildEval::Result::BuildResult.create(build_name: name, status_name: build_element.attribute("status").value)
@@ -4,16 +4,13 @@ module BuildEval
4
4
  class Travis
5
5
 
6
6
  def initialize(args)
7
+ @http = BuildEval::Http.new(args)
7
8
  @username = args[:username]
8
9
  end
9
10
 
10
11
  def build_result(name)
11
- response = BuildEval::Http.get("https://api.travis-ci.org/repositories/#{@username}/#{name}/cc.xml")
12
- build_element = Nokogiri::XML(response.body).xpath("//Project").first
13
- raise "Unexpected build response: #{response.message}" unless build_element
14
- BuildEval::Result::BuildResult.create(
15
- build_name: name, status_name: build_element.attribute("lastBuildStatus").value
16
- )
12
+ raw_response = @http.get("https://api.travis-ci.org/repositories/#{@username}/#{name}/cc.xml")
13
+ BuildEval::Server::CruiseControlResponse.new(raw_response).parse_result("//Project")
17
14
  end
18
15
 
19
16
  def to_s
@@ -1,3 +1,3 @@
1
1
  module BuildEval
2
- VERSION = "0.0.3".freeze
2
+ VERSION = "0.0.4".freeze
3
3
  end
data/lib/build_eval.rb CHANGED
@@ -1,13 +1,19 @@
1
1
  require 'nokogiri'
2
-
2
+ require 'uri'
3
+ require 'net/http'
4
+ require 'net/https'
5
+ require_relative 'build_eval/error'
3
6
  require_relative 'build_eval/http'
4
7
  require_relative 'build_eval/result/status'
5
8
  require_relative 'build_eval/result/build_result'
6
9
  require_relative 'build_eval/result/server_result'
7
10
  require_relative 'build_eval/result/composite_result'
11
+ require_relative 'build_eval/server/invalid_selector_error'
8
12
  require_relative 'build_eval/server/decorator'
13
+ require_relative 'build_eval/server/cruise_control_response'
9
14
  require_relative 'build_eval/server/team_city'
10
15
  require_relative 'build_eval/server/travis'
16
+ require_relative 'build_eval/server/jenkins'
11
17
  require_relative 'build_eval/monitor/base'
12
18
  require_relative 'build_eval/monitor/server'
13
19
  require_relative 'build_eval/monitor/composite'
@@ -0,0 +1,21 @@
1
+ describe BuildEval::Error do
2
+
3
+ let(:message) { "some message" }
4
+
5
+ let(:error) { described_class.new(message) }
6
+
7
+ it "is a standard error" do
8
+ expect(error).to be_a(::StandardError)
9
+ end
10
+
11
+ describe "#messsage" do
12
+
13
+ subject { error.message }
14
+
15
+ it "returns the provided message" do
16
+ expect(subject).to eql(message)
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,7 @@
1
+ shared_context "stubbed http interactions" do
2
+
3
+ let(:http) { instance_double(BuildEval::Http) }
4
+
5
+ before(:example) { allow(BuildEval::Http).to receive(:new).and_return(http) }
6
+
7
+ end
@@ -1,5 +1,9 @@
1
1
  describe BuildEval::Http do
2
2
 
3
+ let(:config) { {} }
4
+
5
+ let(:http) { described_class.new(config) }
6
+
3
7
  shared_examples_for "a http method returning a response" do
4
8
 
5
9
  let(:response_status) { [ "200", "OK" ] }
@@ -19,14 +23,14 @@ describe BuildEval::Http do
19
23
 
20
24
  end
21
25
 
22
- describe "::get" do
26
+ describe "#get" do
23
27
 
24
28
  let(:scheme) { "http" }
25
29
  let(:host) { "a.host" }
26
30
  let(:path) { "some/path" }
27
31
  let(:uri_string) { "#{scheme}://#{host}/#{path}" }
28
32
 
29
- subject { described_class.get(uri_string) }
33
+ subject { http.get(uri_string) }
30
34
 
31
35
  context "when the uri is valid" do
32
36
 
@@ -52,15 +56,31 @@ describe BuildEval::Http do
52
56
 
53
57
  end
54
58
 
55
- context "and basic authentication is provided" do
59
+ context "and an ssl verification mode configuration option was established" do
60
+
61
+ let(:ssl_verification_mode) { OpenSSL::SSL::VERIFY_NONE }
62
+ let(:config) { { ssl_verify_mode: ssl_verification_mode } }
63
+
64
+ it_behaves_like "a http method returning a response"
65
+
66
+ end
67
+
68
+ context "and partial authentication configuration options were established" do
69
+
70
+ let(:config) { { username: "some_username" } }
71
+
72
+ it_behaves_like "a http method returning a response"
73
+
74
+ end
75
+
76
+ context "and basic authentication configuration options were established" do
56
77
 
57
78
  let(:username) { "some_username" }
58
79
  let(:password) { "some_password" }
80
+ let(:config) { { username: username, password: password } }
59
81
 
60
82
  let(:expected_request_uri) { "#{scheme}://#{username}:#{password}@#{host}/#{path}" }
61
83
 
62
- subject { described_class.get(uri_string, basic_authentication: { username: username, password: password }) }
63
-
64
84
  it_behaves_like "a http method returning a response"
65
85
 
66
86
  end
@@ -27,18 +27,18 @@ describe BuildEval::Result::BuildResult do
27
27
 
28
28
  end
29
29
 
30
- describe "::unknown" do
30
+ describe "::indeterminate" do
31
31
 
32
32
  let(:build_name) { "Some build name" }
33
33
 
34
- subject { described_class.unknown(build_name) }
34
+ subject { described_class.indeterminate(build_name) }
35
35
 
36
36
  it "returns a result with the provided build name" do
37
37
  expect(subject.build_name).to eql(build_name)
38
38
  end
39
39
 
40
- it "returns a result with an unknown status" do
41
- expect(subject.status).to eql(BuildEval::Result::Status::UNKNOWN)
40
+ it "returns a result with an indeterminate status" do
41
+ expect(subject.status).to eql(BuildEval::Result::Status::INDETERMINATE)
42
42
  end
43
43
 
44
44
  end
@@ -50,13 +50,16 @@ describe BuildEval::Result::Status do
50
50
 
51
51
  end
52
52
 
53
- context "when the statuses are ordered in descending severity" do
53
+ context "when the statuses are ordered in ascending severity" do
54
54
 
55
55
  let(:statuses) do
56
- [ BuildEval::Result::Status::ERROR,
56
+ [
57
+ BuildEval::Result::Status::ERROR,
57
58
  BuildEval::Result::Status::FAILURE,
58
59
  BuildEval::Result::Status::UNKNOWN,
59
- BuildEval::Result::Status::SUCCESS ]
60
+ BuildEval::Result::Status::INDETERMINATE,
61
+ BuildEval::Result::Status::SUCCESS
62
+ ]
60
63
  end
61
64
 
62
65
  it "returns the most severe status" do
@@ -65,13 +68,16 @@ describe BuildEval::Result::Status do
65
68
 
66
69
  end
67
70
 
68
- context "when the statuses are ordered in ascending severity" do
71
+ context "when the statuses are ordered in descending severity" do
69
72
 
70
73
  let(:statuses) do
71
- [ BuildEval::Result::Status::SUCCESS,
74
+ [
75
+ BuildEval::Result::Status::SUCCESS,
72
76
  BuildEval::Result::Status::UNKNOWN,
77
+ BuildEval::Result::Status::INDETERMINATE,
73
78
  BuildEval::Result::Status::FAILURE,
74
- BuildEval::Result::Status::ERROR ]
79
+ BuildEval::Result::Status::ERROR
80
+ ]
75
81
  end
76
82
 
77
83
  it "returns the most severe status" do
@@ -97,9 +103,10 @@ describe BuildEval::Result::Status do
97
103
  end
98
104
 
99
105
  {
100
- "UNKNOWN" => BuildEval::Result::Status::UNKNOWN,
101
- "FAILURE" => BuildEval::Result::Status::FAILURE,
102
- "ERROR" => BuildEval::Result::Status::ERROR
106
+ "UNKNOWN" => BuildEval::Result::Status::UNKNOWN,
107
+ "FAILURE" => BuildEval::Result::Status::FAILURE,
108
+ "ERROR" => BuildEval::Result::Status::ERROR,
109
+ "INDETERMINATE" => BuildEval::Result::Status::INDETERMINATE
103
110
  }.each do |name, status|
104
111
 
105
112
  context "when the status is #{name}" do
@@ -120,7 +127,13 @@ describe BuildEval::Result::Status do
120
127
 
121
128
  subject { status.to_sym }
122
129
 
123
- { SUCCESS: :success!, UNKNOWN: :warning!, FAILURE: :failure!, ERROR: :failure! }.each do |name, expected_symbol|
130
+ {
131
+ SUCCESS: :success!,
132
+ UNKNOWN: :warning!,
133
+ INDETERMINATE: :warning!,
134
+ FAILURE: :failure!,
135
+ ERROR: :failure!
136
+ }.each do |name, expected_symbol|
124
137
 
125
138
  context "when the status is #{name}" do
126
139
 
@@ -140,7 +153,13 @@ describe BuildEval::Result::Status do
140
153
 
141
154
  subject { status.to_s }
142
155
 
143
- { SUCCESS: "succeeded", UNKNOWN: "unknown", FAILURE: "failed", ERROR: "errored" }.each do |name, expected_string|
156
+ {
157
+ SUCCESS: "succeeded",
158
+ UNKNOWN: "unknown",
159
+ INDETERMINATE: "indeterminate",
160
+ FAILURE: "failed",
161
+ ERROR: "errored"
162
+ }.each do |name, expected_string|
144
163
 
145
164
  context "when the status is #{name}" do
146
165
 
@@ -0,0 +1,115 @@
1
+ describe BuildEval::Server::CruiseControlResponse do
2
+
3
+ let(:raw_response) { double("RawResponse", body: response_body) }
4
+
5
+ let(:cruise_control_response) { described_class.new(raw_response) }
6
+
7
+ describe "#parse_result" do
8
+
9
+ let(:build_name) { "some_build_name" }
10
+ let(:response_build_name) { build_name }
11
+ let(:project_selector) { "//Project[2]" }
12
+
13
+ subject { cruise_control_response.parse_result(project_selector) }
14
+
15
+ context "when the response is successful, containing projects" do
16
+
17
+ let(:latest_build_status) { "Success" }
18
+ let(:response_body) do
19
+ <<-RESPONSE
20
+ <Projects>
21
+ <Project name="another_build_name" activity="Sleeping" lastBuildStatus="Unknown" lastBuildLabel="2" lastBuildTime="2015-08-02T00:00:00.000+0000" webUrl="https://my.build.server/another_build_name" />
22
+ <Project name="#{response_build_name}" activity="Sleeping" lastBuildStatus="#{latest_build_status}" lastBuildLabel="1" lastBuildTime="2015-08-01T00:00:00.000+0000" webUrl="https://my.build.server/#{build_name}" />
23
+ <Project name="yet_another_build_name" activity="Sleeping" lastBuildStatus="Error" lastBuildLabel="3" lastBuildTime="2015-08-03T00:00:00.000+0000" webUrl="https://my.build.server/yet_another_build_name" />
24
+ </Projects>
25
+ RESPONSE
26
+ end
27
+
28
+ context "and the selector matches a project" do
29
+
30
+ context "and the build name in the response is not a path" do
31
+
32
+ it "creates a build result with the build name from the response" do
33
+ expect(BuildEval::Result::BuildResult).to receive(:create).with(hash_including(build_name: build_name))
34
+
35
+ subject
36
+ end
37
+
38
+ end
39
+
40
+ context "and the build name in the response is a path" do
41
+
42
+ let(:response_build_name) { "some/path/to/#{build_name}" }
43
+
44
+ it "creates a build result with the build name from the response with the path omitted" do
45
+ expect(BuildEval::Result::BuildResult).to receive(:create).with(hash_including(build_name: build_name))
46
+
47
+ subject
48
+ end
49
+
50
+ end
51
+
52
+ it "creates a build result containing the latest build status" do
53
+ expect(BuildEval::Result::BuildResult).to(
54
+ receive(:create).with(hash_including(status_name: latest_build_status))
55
+ )
56
+
57
+ subject
58
+ end
59
+
60
+ it "returns the created result" do
61
+ build_result = instance_double(BuildEval::Result::BuildResult)
62
+ allow(BuildEval::Result::BuildResult).to receive(:create).and_return(build_result)
63
+
64
+ expect(subject).to eql(build_result)
65
+ end
66
+
67
+ end
68
+
69
+ context "and the selector does not match a project" do
70
+
71
+ let(:project_selector) { "does_not_match" }
72
+ let(:error) { "an error" }
73
+
74
+ before(:example) { allow(BuildEval::Server::InvalidSelectorError).to receive(:new).and_return(error) }
75
+
76
+ it "creates an invalid selector error" do
77
+ expect(BuildEval::Server::InvalidSelectorError).to(
78
+ receive(:new).with(raw_response, project_selector).and_return(error)
79
+ )
80
+
81
+ subject rescue Exception
82
+ end
83
+
84
+ it "raises the error" do
85
+ expect { subject }.to raise_error(error)
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
92
+ context "when the response is in error" do
93
+
94
+ let(:response_body) { { "file" => "not found" }.to_json }
95
+ let(:error) { "an error" }
96
+
97
+ before(:example) { allow(BuildEval::Server::InvalidSelectorError).to receive(:new).and_return(error) }
98
+
99
+ it "creates an invalid selector error" do
100
+ expect(BuildEval::Server::InvalidSelectorError).to(
101
+ receive(:new).with(raw_response, project_selector).and_return(error)
102
+ )
103
+
104
+ subject rescue Exception
105
+ end
106
+
107
+ it "raises an invalid selector error" do
108
+ expect { subject }.to raise_error(error)
109
+ end
110
+
111
+ end
112
+
113
+ end
114
+
115
+ end
@@ -32,17 +32,17 @@ describe BuildEval::Server::Decorator do
32
32
 
33
33
  before(:example) { allow(server).to receive(:build_result).and_raise("Forced error") }
34
34
 
35
- it "creates an unknown result" do
36
- expect(BuildEval::Result::BuildResult).to receive(:unknown).with(build_name)
35
+ it "creates an indeterminate result" do
36
+ expect(BuildEval::Result::BuildResult).to receive(:indeterminate).with(build_name)
37
37
 
38
38
  subject
39
39
  end
40
40
 
41
- it "returns the unknown result" do
42
- unknown_build_result = instance_double(BuildEval::Result::BuildResult)
43
- allow(BuildEval::Result::BuildResult).to receive(:unknown).and_return(unknown_build_result)
41
+ it "returns the indeterminate result" do
42
+ indeterminate_result = instance_double(BuildEval::Result::BuildResult)
43
+ allow(BuildEval::Result::BuildResult).to receive(:indeterminate).and_return(indeterminate_result)
44
44
 
45
- expect(subject).to eql(unknown_build_result)
45
+ expect(subject).to eql(indeterminate_result)
46
46
  end
47
47
 
48
48
  end
@@ -0,0 +1,27 @@
1
+ describe BuildEval::Server::InvalidSelectorError do
2
+
3
+ let(:response_message) { "Some response message" }
4
+ let(:response) { double("HttpResponse", message: response_message) }
5
+ let(:selector) { "some/selector" }
6
+
7
+ let(:error) { described_class.new(response, selector) }
8
+
9
+ describe "#message" do
10
+
11
+ subject { error.message }
12
+
13
+ it "indicates the selector was not matched" do
14
+ expect(subject).to match(/response did not match selector/i)
15
+ end
16
+
17
+ it "contains a message describing the response" do
18
+ expect(subject).to include(response_message)
19
+ end
20
+
21
+ it "contains the selector that was invalid" do
22
+ expect(subject).to include(selector)
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,52 @@
1
+ describe BuildEval::Server::Jenkins, "integrating with a response parser", integration: true do
2
+ include_context "stubbed http interactions"
3
+
4
+ let(:uri) { "https://some.jenkins.server" }
5
+
6
+ let(:jenkins) { described_class.new(uri: uri) }
7
+
8
+ describe "#build_result" do
9
+
10
+ let(:build_name) { "some_build_name" }
11
+ let(:response) { instance_double(Net::HTTPResponse, body: response_body) }
12
+
13
+ subject { jenkins.build_result(build_name) }
14
+
15
+ before(:example) { allow(http).to receive(:get).and_return(response) }
16
+
17
+ context "when the server responds successfully with build results" do
18
+
19
+ let(:latest_build_status) { "Failure" }
20
+ let(:response_body) do
21
+ <<-RESPONSE
22
+ <Projects>
23
+ <Project webUrl="#{uri}/job/#{build_name}/" name="#{build_name}" lastBuildLabel="190" lastBuildTime="2015-10-09T02:39:36Z" lastBuildStatus="#{latest_build_status}" activity="Sleeping"/>
24
+ <Project webUrl="#{uri}/job/another_build_name/" name="another_build_name" lastBuildLabel="71" lastBuildTime="2015-10-12T17:07:00Z" lastBuildStatus="Success" activity="Sleeping"/>
25
+ <Project webUrl="#{uri}/job/yet_another_build_name/" name="yet_another_build_name" lastBuildLabel="15" lastBuildTime="2015-10-13T01:40:32Z" lastBuildStatus="Success" activity="Sleeping"/>
26
+ </Projects>
27
+ RESPONSE
28
+ end
29
+
30
+ it "creates a build result containing the build name" do
31
+ expect(BuildEval::Result::BuildResult).to receive(:create).with(hash_including(build_name: build_name))
32
+
33
+ subject
34
+ end
35
+
36
+ it "creates a build result containing the latest build status" do
37
+ expect(BuildEval::Result::BuildResult).to receive(:create).with(hash_including(status_name: latest_build_status))
38
+ subject
39
+ end
40
+
41
+ it "returns the created result" do
42
+ build_result = instance_double(BuildEval::Result::BuildResult)
43
+ allow(BuildEval::Result::BuildResult).to receive(:create).and_return(build_result)
44
+
45
+ expect(subject).to eql(build_result)
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+
52
+ end