build_eval 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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