firebrigade_api 1.0.0

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.
@@ -0,0 +1,6 @@
1
+ == 1.0.0 / 2007-01-30
2
+
3
+ * Birthday!
4
+ * Ruby interface to http://firebrigade.seattlerb.org
5
+ * User-friendly cache for implementing Tinderbox
6
+
@@ -0,0 +1,27 @@
1
+ Copyright 2006 Eric Hodel. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ 3. Neither the names of the authors nor the names of their contributors
13
+ may be used to endorse or promote products derived from this software
14
+ without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
17
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
20
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
22
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
@@ -0,0 +1,10 @@
1
+ History.txt
2
+ LICENSE.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ lib/firebrigade.rb
7
+ lib/firebrigade/api.rb
8
+ lib/firebrigade/cache.rb
9
+ test/test_firebrigade_api.rb
10
+ test/test_firebrigade_cache.rb
@@ -0,0 +1,33 @@
1
+ Firebrigade API
2
+
3
+ by Eric Hodel
4
+
5
+ http://seattlerb.rubyforge.org/firebrigade_api
6
+
7
+ == DESCRIPTION
8
+
9
+ An API wrapper for http://firebrigade.seattlerb.org
10
+
11
+ == FEATURES/PROBLEMS
12
+
13
+ * Fully wraps Firebrigade API
14
+ * Provides friendly cache for implementing applications like Tinderbox
15
+ * No way to retrieve build log (easy with OpenURI)
16
+ * No way to query for owners/projects/etc. (Not implemented in API.)
17
+
18
+ == SYNOPSYS
19
+
20
+ require 'rubygems'
21
+ require 'firebrigade/api'
22
+
23
+ fa = Firebrigade::API.new 'firebrigade.seattlerb.org', 'username', 'password'
24
+
25
+ == REQUIREMENTS
26
+
27
+ * rc-rest
28
+ * Connection to firebrigade.seattlerb.org
29
+
30
+ == INSTALL
31
+
32
+ * sudo gem install firebrigade_api
33
+
@@ -0,0 +1,20 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ $LOAD_PATH.unshift 'lib'
6
+ require 'firebrigade/api'
7
+
8
+ Hoe.new 'firebrigade_api', Firebrigade::API::VERSION do |p|
9
+ p.rubyforge_name = 'seattlerb'
10
+ p.author = 'Eric Hodel'
11
+ p.email = 'drbrain@segment7.net'
12
+ p.summary = 'API for Firebrigade'
13
+ p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
14
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
15
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
16
+
17
+ p.extra_deps << ['rc-rest', '>= 2.1.0']
18
+ end
19
+
20
+ # vim: syntax=Ruby
@@ -0,0 +1,3 @@
1
+ module Firebrigade # :nodoc:
2
+ end
3
+
@@ -0,0 +1,265 @@
1
+ require 'digest/md5'
2
+
3
+ require 'rubygems'
4
+ require 'rc_rest'
5
+ require 'firebrigade'
6
+
7
+ ##
8
+ # Firebrigade::API is an API for submitting build information to
9
+ # http://firebrigade.seattlerb.org/
10
+ #
11
+ # All #get_ and #add_ methods return an instance of the Object fetched or
12
+ # created, so get_target will return a Target object.
13
+ #
14
+ # All #add_ methods will return an instance of a pre-existing Object if one
15
+ # already exists.
16
+
17
+ class Firebrigade::API < RCRest
18
+
19
+ ##
20
+ # API error base class
21
+
22
+ class Error < RCRest::Error; end
23
+
24
+ ##
25
+ # Raised when you supply bad login information.
26
+
27
+ class InvalidLogin < Error; end
28
+
29
+ ##
30
+ # Raised when the thing you're looking for isn't there.
31
+
32
+ class NotFound < Error; end
33
+
34
+ ##
35
+ # Raised when your API version is incompatible with Firebrigade's
36
+
37
+ class WrongAPIVersion < Error; end
38
+
39
+ ##
40
+ # The version of Firebrigade::API you are using
41
+
42
+ VERSION = '1.0.0'
43
+
44
+ ##
45
+ # Supported Firebrigade API version.
46
+
47
+ API_VERSION = '1.0.0'
48
+
49
+ ##
50
+ # A Build contains information on a test run.
51
+
52
+ Build = Struct.new :id, :successful, :duration, :created_on, :version_id,
53
+ :target_id
54
+
55
+ ##
56
+ # An Owner contains information on a Project's owner. (A project in
57
+ # seattlerb's firebrigade.)
58
+
59
+ Owner = Struct.new :id, :name
60
+
61
+ ##
62
+ # A Project contains information about a project. (A gem in seattlerb's
63
+ # firebrigade.)
64
+
65
+ Project = Struct.new :id, :name, :owner_id
66
+
67
+ ##
68
+ # A Target contains information about the test platform.
69
+
70
+ Target = Struct.new :id, :version, :release_date, :platform, :username
71
+
72
+ ##
73
+ # A Version contains the version information for a Project.
74
+
75
+ Version = Struct.new :id, :name, :project_id
76
+
77
+ ##
78
+ # Creates a new Firebrigade::API that will connect to +host+ with +username+
79
+ # and +password+.
80
+
81
+ def initialize(host, username, password)
82
+ @username = username
83
+ @password = password
84
+ @url = URI.parse "http://#{host}/api/REST/"
85
+ end
86
+
87
+ ##
88
+ # Adds a Build with +version_id+ and +target_id+, reporting the +successful+
89
+ # status, the +duration+ taken, and the +log+.
90
+
91
+ def add_build(version_id, target_id, successful, duration, log)
92
+ post_multipart :add_build, :version_id => version_id,
93
+ :target_id => target_id,
94
+ :successful => successful, :duration => duration,
95
+ :log => log
96
+ end
97
+
98
+ ##
99
+ # Adds an Owner with +name+.
100
+
101
+ def add_owner(name)
102
+ post :add_owner, :name => name
103
+ end
104
+
105
+ ##
106
+ # Adds a Project with +name+ owned by +owner_id+.
107
+
108
+ def add_project(name, owner_id)
109
+ post :add_project, :name => name, :owner_id => owner_id
110
+ end
111
+
112
+ ##
113
+ # Adds a Target with a Ruby +version+, Ruby +release_date+ and Ruby
114
+ # +platform+.
115
+
116
+ def add_target(version, release_date, platform)
117
+ post :add_target, :version => version, :release_date => release_date,
118
+ :platform => platform, :api_version => API_VERSION
119
+ end
120
+
121
+ ##
122
+ # Adds Version +name+ to +project_id+.
123
+
124
+ def add_version(name, project_id)
125
+ post :add_version, :name => name, :project_id => project_id
126
+ end
127
+
128
+ ##
129
+ # Checks for errors in +xml+ and raises an appropriate Exception.
130
+
131
+ def check_error(xml) # :nodoc:
132
+ error = xml.elements['/error/message']
133
+ return unless error
134
+
135
+ case error.text
136
+ when /No such \w+ exists/ then raise NotFound, error.text
137
+ when 'Invalid login' then raise InvalidLogin, error.text
138
+ when /Your API version/ then raise WrongAPIVersion, error.text
139
+ else raise Error, error.text
140
+ end
141
+ end
142
+
143
+ ##
144
+ # Retrieves a Build for +version_id+ and +target_id+.
145
+
146
+ def get_build(version_id, target_id)
147
+ get :get_build, :version_id => version_id, :target_id => target_id
148
+ end
149
+
150
+ ##
151
+ # Retrieves an Owner matching +name+.
152
+
153
+ def get_owner(name)
154
+ get :get_owner, :name => name
155
+ end
156
+
157
+ ##
158
+ # Retrieves a Project matching +name+ and +owner_id+.
159
+
160
+ def get_project(name, owner_id)
161
+ get :get_project, :name => name, :owner_id => owner_id
162
+ end
163
+
164
+ ##
165
+ # Retrieves a Target matching +version+, +release_date+ and +platform+.
166
+
167
+ def get_target(version, release_date, platform)
168
+ get :get_target, :version => version, :release_date => release_date,
169
+ :platform => platform, :username => @username,
170
+ :api_version => API_VERSION
171
+ end
172
+
173
+ ##
174
+ # Retrieves a Version matching +name+ nad +project_id+.
175
+
176
+ def get_version(name, project_id)
177
+ get :get_version, :name => name, :project_id => project_id
178
+ end
179
+
180
+ ##
181
+ # Makes a multipart POST from +params+.
182
+
183
+ def make_multipart(params) # :nodoc:
184
+ set_hash params
185
+
186
+ super params
187
+ end
188
+
189
+ ##
190
+ # Makes a URL for +method+ and +params+.
191
+
192
+ def make_url(method, params) # :nodoc:
193
+ set_hash params if method.to_s =~ /^add_/
194
+
195
+ super method, params
196
+ end
197
+
198
+ ##
199
+ # Creates an Object from +xml+.
200
+
201
+ def parse_response(xml) # :nodoc:
202
+ ok = xml.elements['/ok']
203
+ raise RCRest::Error, xml.to_s if ok.nil?
204
+ child = ok.elements[1]
205
+ obj = nil
206
+
207
+ case child.name
208
+ when 'build' then
209
+ obj = Build.new
210
+ obj.id = child.elements['id'].text.to_i
211
+ obj.successful = child.elements['successful'].text == 'true'
212
+ obj.duration = child.elements['duration'].text.to_f
213
+ obj.target_id = child.elements['target_id'].text.to_i
214
+ obj.version_id = child.elements['version_id'].text.to_i
215
+ obj.created_on = Time.parse child.elements['created_on'].text
216
+ when 'owner' then
217
+ obj = Owner.new
218
+ obj.id = child.elements['id'].text.to_i
219
+ obj.name = child.elements['name'].text
220
+ when 'project' then
221
+ obj = Project.new
222
+ obj.id = child.elements['id'].text.to_i
223
+ obj.name = child.elements['name'].text
224
+ obj.owner_id = child.elements['owner_id'].text.to_i
225
+ when 'target' then
226
+ obj = Target.new
227
+ obj.id = child.elements['id'].text.to_i
228
+ obj.platform = child.elements['platform'].text
229
+ obj.release_date = child.elements['release_date'].text
230
+ obj.username = child.elements['username'].text
231
+ obj.version = child.elements['version'].text
232
+ when 'version' then
233
+ obj = Version.new
234
+ obj.id = child.elements['id'].text.to_i
235
+ obj.name = child.elements['name'].text
236
+ obj.project_id = child.elements['project_id'].text.to_i
237
+ else
238
+ raise "don't know how to create a #{child.name}"
239
+ end
240
+
241
+ obj
242
+ rescue NoMethodError
243
+ puts $!
244
+ puts $!.backtrace.join("\n\t")
245
+ puts
246
+ puts xml
247
+ raise
248
+ end
249
+
250
+ ##
251
+ # Sets the request hash value for +params+.
252
+
253
+ def set_hash(params)
254
+ param_values = params.sort_by { |n| n.to_s }.map do |name, value|
255
+ "#{name}=#{URI.escape value.to_s}"
256
+ end.join '&'
257
+
258
+ hash = Digest::MD5.hexdigest "#{param_values}:#{@username}:#{@password}"
259
+
260
+ params[:hash] = hash
261
+ params[:user] = @username
262
+ end
263
+
264
+ end
265
+
@@ -0,0 +1,89 @@
1
+ require 'rubygems'
2
+ require 'firebrigade/api'
3
+
4
+ ##
5
+ # Firebrigade::Cache is a wrapper around Firebrigade::API that caches lookups
6
+ # so you don't hammer the web server unnecessarily. It handles the most
7
+ # common operations for Tinderbox::GemTinderbox and Tinderbox::Build.
8
+
9
+ class Firebrigade::Cache
10
+
11
+ ##
12
+ # Creates a new Firebrigade::Cache that will connect to +host+ with
13
+ # +username+ and +password+.
14
+
15
+ def initialize(host, username, password)
16
+ @fa = Firebrigade::API.new host, username, password
17
+
18
+ @owners = {} # owner => owner_id
19
+ @projects = {} # [project, owner_id] => project_id
20
+ @versions = {} # [version, project_id] => version_id
21
+
22
+ @targets = {} # [version, release_date, platform] => target_id
23
+ @builds = {} # [version_id, target_id] => build_id
24
+ end
25
+
26
+ ##
27
+ # Retrieves the id for a build matching +version_id+ and +target_id+.
28
+
29
+ def get_build_id(version_id, target_id)
30
+ build_args = [version_id, target_id]
31
+ return @builds[build_args] if @builds.include? build_args
32
+
33
+ begin
34
+ build = @fa.get_build(*build_args)
35
+ @builds[build_args] = build.id
36
+ rescue Firebrigade::API::NotFound
37
+ nil
38
+ end
39
+ end
40
+
41
+ ##
42
+ # Retrieves or creates a target matching +version+, +release_date+ and
43
+ # +platform+. Returns the target's id.
44
+
45
+ def get_target_id(version = RUBY_VERSION, release_date = RUBY_RELEASE_DATE,
46
+ platform = RUBY_PLATFORM)
47
+ target_args = [version, release_date, platform]
48
+ return @targets[target_args] if @targets.include? target_args
49
+
50
+ target = @fa.add_target(*target_args)
51
+
52
+ @targets[target_args] = target.id
53
+ end
54
+
55
+ ##
56
+ # Fetches or creates a version (including project and owner) for the
57
+ # Gem::Specification +spec+ and returns the version's id.
58
+
59
+ def get_version_id(spec)
60
+ owner = spec.rubyforge_project
61
+ project = spec.name
62
+ version = spec.version.to_s
63
+
64
+ owner_id = @owners[owner]
65
+
66
+ if owner_id.nil? then
67
+ owner_id = @fa.add_owner(owner).id
68
+ @owners[owner] = owner_id
69
+ end
70
+
71
+ project_id = @projects[[owner_id, project]]
72
+
73
+ if project_id.nil? then
74
+ project_id = @fa.add_project(project, owner_id).id
75
+ @projects[[owner_id, project]] = project_id
76
+ end
77
+
78
+ version_id = @versions[[project_id, version]]
79
+
80
+ if version_id.nil? then
81
+ version_id = @fa.add_version(version, project_id).id
82
+ @versions[[project_id, version]] = version_id
83
+ end
84
+
85
+ version_id
86
+ end
87
+
88
+ end
89
+
@@ -0,0 +1,446 @@
1
+ require 'test/unit'
2
+
3
+ require 'rubygems'
4
+ require 'rc_rest/uri_stub'
5
+ require 'rc_rest/net_http_stub'
6
+
7
+ require 'firebrigade/api'
8
+
9
+ class TestFirebrigadeAPI < Test::Unit::TestCase
10
+
11
+ def setup
12
+ URI::HTTP.responses = []
13
+ URI::HTTP.uris = []
14
+
15
+ Net::HTTP.params = []
16
+ Net::HTTP.paths = []
17
+ Net::HTTP.responses = []
18
+
19
+ @fa = Firebrigade::API.new 'firebrigade.example.com', 'username', 'password'
20
+ end
21
+
22
+ def test_add_build
23
+ now = Time.at Time.now.to_i
24
+
25
+ Net::HTTP.responses << <<-EOF.strip
26
+ <ok>
27
+ <build>
28
+ <id>100</id>
29
+ <created_on>#{now}</created_on>
30
+ <duration>1.5</duration>
31
+ <successful>true</successful>
32
+ <target_id>100</target_id>
33
+ <version_id>101</version_id>
34
+ </build>
35
+ </ok>
36
+ EOF
37
+
38
+ build = Firebrigade::API::Build.new
39
+ build.id = 100
40
+ build.successful = true
41
+ build.duration = 1.5
42
+ build.target_id = 100
43
+ build.created_on = now
44
+ build.version_id = 101
45
+
46
+ srand 0
47
+
48
+ assert_equal build, @fa.add_build(101, 100, true, 1.5, 'did the stuff')
49
+
50
+ assert_equal true, Net::HTTP.responses.empty?
51
+
52
+ assert_equal 1, Net::HTTP.paths.length
53
+ assert_equal '/api/REST/add_build', Net::HTTP.paths.first
54
+
55
+ assert_equal 1, Net::HTTP.params.length
56
+
57
+ expected = <<-EOF.strip
58
+ --ac_2f_75_c0_43_fb_c3_67\r
59
+ Content-Disposition: form-data; name="duration"\r
60
+ \r
61
+ 1.5\r
62
+ --ac_2f_75_c0_43_fb_c3_67\r
63
+ Content-Disposition: form-data; name="hash"\r
64
+ \r
65
+ 1a905df729030146910ddac44e6b0d67\r
66
+ --ac_2f_75_c0_43_fb_c3_67\r
67
+ Content-Disposition: form-data; name="log"\r
68
+ \r
69
+ did the stuff\r
70
+ --ac_2f_75_c0_43_fb_c3_67\r
71
+ Content-Disposition: form-data; name="successful"\r
72
+ \r
73
+ true\r
74
+ --ac_2f_75_c0_43_fb_c3_67\r
75
+ Content-Disposition: form-data; name="target_id"\r
76
+ \r
77
+ 100\r
78
+ --ac_2f_75_c0_43_fb_c3_67\r
79
+ Content-Disposition: form-data; name="user"\r
80
+ \r
81
+ username\r
82
+ --ac_2f_75_c0_43_fb_c3_67\r
83
+ Content-Disposition: form-data; name="version_id"\r
84
+ \r
85
+ 101\r
86
+ --ac_2f_75_c0_43_fb_c3_67--
87
+ EOF
88
+
89
+ assert_equal expected, Net::HTTP.params.first
90
+ end
91
+
92
+ def test_add_owner
93
+ Net::HTTP.responses << <<-EOF.strip
94
+ <ok>
95
+ <owner>
96
+ <id>100</id>
97
+ <name>foo</name>
98
+ </owner>
99
+ </ok>
100
+ EOF
101
+
102
+ owner = Firebrigade::API::Owner.new
103
+ owner.id = 100
104
+ owner.name = 'foo'
105
+
106
+ assert_equal owner, @fa.add_owner('foo')
107
+
108
+ assert_equal true, Net::HTTP.responses.empty?
109
+
110
+ assert_equal 1, Net::HTTP.paths.length
111
+ assert_equal '/api/REST/add_owner', Net::HTTP.paths.first
112
+
113
+ assert_equal 1, Net::HTTP.params.length
114
+ assert_equal 'hash=9c5fbef18346fb68d632b625067a368a&name=foo&user=username',
115
+ Net::HTTP.params.first
116
+ end
117
+
118
+ def test_add_project
119
+ Net::HTTP.responses << <<-EOF.strip
120
+ <ok>
121
+ <project>
122
+ <id>100</id>
123
+ <name>foo</name>
124
+ <owner_id>101</owner_id>
125
+ </project>
126
+ </ok>
127
+ EOF
128
+
129
+ project = Firebrigade::API::Project.new
130
+ project.id = 100
131
+ project.name = 'foo'
132
+ project.owner_id = 101
133
+
134
+ assert_equal project, @fa.add_project('foo', 101)
135
+
136
+ assert_equal true, Net::HTTP.responses.empty?
137
+
138
+ assert_equal 1, Net::HTTP.paths.length
139
+ assert_equal '/api/REST/add_project', Net::HTTP.paths.first
140
+
141
+ assert_equal 1, Net::HTTP.params.length
142
+ assert_equal 'hash=a623ed5872e79e8d3bede063c95a4aef&name=foo&owner_id=101&user=username',
143
+ Net::HTTP.params.first
144
+ end
145
+
146
+ def test_add_target
147
+ Net::HTTP.responses << <<-EOF.strip
148
+ <ok>
149
+ <target>
150
+ <id>100</id>
151
+ <platform>powerpc-darwin8.7.0</platform>
152
+ <release_date>2006-08-25</release_date>
153
+ <username>drbrain</username>
154
+ <version>1.8.5</version>
155
+ </target>
156
+ </ok>
157
+ EOF
158
+
159
+ target_platform = 'powerpc-darwin8.7.0'
160
+ target_release_date = '2006-08-25'
161
+ target_version = '1.8.5'
162
+
163
+ target = Firebrigade::API::Target.new
164
+ target.id = 100
165
+ target.platform = 'powerpc-darwin8.7.0'
166
+ target.release_date = '2006-08-25'
167
+ target.version = '1.8.5'
168
+ target.username = 'drbrain'
169
+
170
+ assert_equal target, @fa.add_target(target_version, target_release_date,
171
+ target_platform)
172
+
173
+ assert_equal true, Net::HTTP.responses.empty?
174
+
175
+ assert_equal 1, Net::HTTP.paths.length
176
+ assert_equal '/api/REST/add_target', Net::HTTP.paths.first
177
+
178
+ assert_equal 1, Net::HTTP.params.length
179
+ assert_equal 'api_version=1.0.0&hash=c600c401ac061e996ee3cfc87493ca85&platform=powerpc-darwin8.7.0&release_date=2006-08-25&user=username&version=1.8.5',
180
+ Net::HTTP.params.first
181
+ end
182
+
183
+ def test_add_target_bad_hash
184
+ Net::HTTP.responses << <<-EOF.strip
185
+ <error>
186
+ <message>Invalid login</message>
187
+ </error>
188
+ EOF
189
+
190
+ e = assert_raise Firebrigade::API::InvalidLogin do
191
+ @fa.add_target 'a', 'b', 'c'
192
+ end
193
+
194
+ assert_equal true, Net::HTTP.responses.empty?
195
+
196
+ assert_equal 1, Net::HTTP.paths.length
197
+ assert_equal '/api/REST/add_target', Net::HTTP.paths.first
198
+
199
+ assert_equal 1, Net::HTTP.params.length
200
+ assert_equal 'api_version=1.0.0&hash=f873667a60f58a38b82a38ba585a0a36&platform=c&release_date=b&user=username&version=a',
201
+ Net::HTTP.params.first
202
+
203
+ assert_equal 'Invalid login', e.message
204
+ end
205
+
206
+ def test_add_target_wrong_version
207
+ Net::HTTP.responses << <<-EOF.strip
208
+ <error>
209
+ <message>Your API version 1.0.0 is not compatible with this Firebrigade API, = 2.0.0</message>
210
+ </error>
211
+ EOF
212
+
213
+ e = assert_raise Firebrigade::API::WrongAPIVersion do
214
+ @fa.add_target 'a', 'b', 'c'
215
+ end
216
+
217
+ assert_equal true, Net::HTTP.responses.empty?
218
+
219
+ assert_equal 1, Net::HTTP.paths.length
220
+ assert_equal '/api/REST/add_target', Net::HTTP.paths.first
221
+
222
+ assert_equal 1, Net::HTTP.params.length
223
+ assert_equal 'api_version=1.0.0&hash=f873667a60f58a38b82a38ba585a0a36&platform=c&release_date=b&user=username&version=a',
224
+ Net::HTTP.params.first
225
+
226
+ assert_equal 'Your API version 1.0.0 is not compatible with this Firebrigade API, = 2.0.0',
227
+ e.message
228
+ end
229
+
230
+ def test_add_version
231
+ Net::HTTP.responses << <<-EOF.strip
232
+ <ok>
233
+ <version>
234
+ <id>100</id>
235
+ <name>1.0.0</name>
236
+ <project_id>101</project_id>
237
+ </version>
238
+ </ok>
239
+ EOF
240
+
241
+ version_name = '1.0.0'
242
+
243
+ version = Firebrigade::API::Version.new
244
+ version.id = 100
245
+ version.name = version_name
246
+ version.project_id = 101
247
+
248
+ assert_equal version, @fa.add_version(version_name, 101)
249
+
250
+ assert_equal true, Net::HTTP.responses.empty?
251
+
252
+ assert_equal 1, Net::HTTP.paths.length
253
+ assert_equal '/api/REST/add_version', Net::HTTP.paths.first
254
+
255
+ assert_equal 1, Net::HTTP.params.length
256
+ assert_equal 'hash=db2a1eecd0492a141b186ec5f21fea61&name=1.0.0&project_id=101&user=username',
257
+ Net::HTTP.params.first
258
+ end
259
+
260
+ def test_get_build
261
+ now = Time.at Time.now.to_i
262
+
263
+ URI::HTTP.responses << <<-EOF.strip
264
+ <ok>
265
+ <build>
266
+ <id>100</id>
267
+ <created_on>#{now}</created_on>
268
+ <duration>1.5</duration>
269
+ <successful>true</successful>
270
+ <target_id>100</target_id>
271
+ <version_id>101</version_id>
272
+ </build>
273
+ </ok>
274
+ EOF
275
+
276
+ build = Firebrigade::API::Build.new
277
+ build.id = 100
278
+ build.successful = true
279
+ build.duration = 1.5
280
+ build.target_id = 100
281
+ build.created_on = now
282
+ build.version_id = 101
283
+
284
+ assert_equal build, @fa.get_build(101, 100)
285
+
286
+ assert_equal true, URI::HTTP.responses.empty?
287
+
288
+ assert_equal 1, URI::HTTP.uris.length
289
+ assert_equal 'http://firebrigade.example.com/api/REST/get_build?target_id=100&version_id=101',
290
+ URI::HTTP.uris.first
291
+ end
292
+
293
+ def test_get_owner
294
+ URI::HTTP.responses << <<-EOF.strip
295
+ <ok>
296
+ <owner>
297
+ <id>100</id>
298
+ <name>foo</name>
299
+ </owner>
300
+ </ok>
301
+ EOF
302
+
303
+ owner_name = 'foo'
304
+ owner_version = '0.0.2'
305
+
306
+ owner = Firebrigade::API::Owner.new
307
+ owner.id = 100
308
+ owner.name = owner_name
309
+
310
+ assert_equal owner, @fa.get_owner(owner_name)
311
+
312
+ assert_equal true, URI::HTTP.responses.empty?
313
+ assert_equal 1, URI::HTTP.uris.length
314
+ assert_equal 'http://firebrigade.example.com/api/REST/get_owner?name=foo',
315
+ URI::HTTP.uris.first
316
+ end
317
+
318
+ def test_get_project
319
+ URI::HTTP.responses << <<-EOF.strip
320
+ <ok>
321
+ <project>
322
+ <id>100</id>
323
+ <name>foo</name>
324
+ <owner_id>101</owner_id>
325
+ </project>
326
+ </ok>
327
+ EOF
328
+
329
+ project_name = 'foo'
330
+ project_version = '0.0.2'
331
+ project_owner_id = 101
332
+
333
+ project = Firebrigade::API::Project.new
334
+ project.id = 100
335
+ project.name = project_name
336
+ project.owner_id = project_owner_id
337
+
338
+ assert_equal project, @fa.get_project(project_name, project_owner_id)
339
+
340
+ assert_equal true, URI::HTTP.responses.empty?
341
+ assert_equal 1, URI::HTTP.uris.length
342
+ assert_equal 'http://firebrigade.example.com/api/REST/get_project?name=foo&owner_id=101',
343
+ URI::HTTP.uris.first
344
+ end
345
+
346
+ def test_get_target
347
+ URI::HTTP.responses << <<-EOF.strip
348
+ <ok>
349
+ <target>
350
+ <id>100</id>
351
+ <platform>powerpc-darwin8.7.0</platform>
352
+ <release_date>2006-08-25</release_date>
353
+ <username>drbrain</username>
354
+ <version>1.8.5</version>
355
+ </target>
356
+ </ok>
357
+ EOF
358
+
359
+ target_platform = 'powerpc-darwin8.7.0'
360
+ target_release_date = '2006-08-25'
361
+ target_username = 'drbrain'
362
+ target_version = '1.8.5'
363
+
364
+ target = Firebrigade::API::Target.new
365
+ target.id = 100
366
+ target.platform = target_platform
367
+ target.release_date = target_release_date
368
+ target.username = target_username
369
+ target.version = target_version
370
+
371
+ assert_equal target, @fa.get_target(target_version, target_release_date,
372
+ target_platform)
373
+
374
+ assert_equal true, URI::HTTP.responses.empty?
375
+ assert_equal 1, URI::HTTP.uris.length
376
+ assert_equal 'http://firebrigade.example.com/api/REST/get_target?api_version=1.0.0&platform=powerpc-darwin8.7.0&release_date=2006-08-25&username=username&version=1.8.5',
377
+ URI::HTTP.uris.first
378
+ end
379
+
380
+ def test_get_target_wrong_version
381
+ URI::HTTP.responses << <<-EOF.strip
382
+ <error>
383
+ <message>Your API version 1.0.0 is not compatible with this Firebrigade API, = 2.0.0</message>
384
+ </error>
385
+ EOF
386
+
387
+ e = assert_raises Firebrigade::API::WrongAPIVersion do
388
+ @fa.get_target 'a', 'b', 'c'
389
+ end
390
+
391
+ assert_equal true, URI::HTTP.responses.empty?
392
+ assert_equal 1, URI::HTTP.uris.length
393
+ assert_equal 'http://firebrigade.example.com/api/REST/get_target?api_version=1.0.0&platform=c&release_date=b&username=username&version=a',
394
+ URI::HTTP.uris.first
395
+
396
+ assert_equal 'Your API version 1.0.0 is not compatible with this Firebrigade API, = 2.0.0',
397
+ e.message
398
+ end
399
+
400
+ def test_get_target_nonexistent
401
+ URI::HTTP.responses << <<-EOF.strip
402
+ <error>
403
+ <message>No such target exists</message>
404
+ </error>
405
+ EOF
406
+
407
+ e = assert_raises Firebrigade::API::NotFound do
408
+ @fa.get_target 'a', 'b', 'c'
409
+ end
410
+
411
+ assert_equal true, URI::HTTP.responses.empty?
412
+ assert_equal 1, URI::HTTP.uris.length
413
+ assert_equal 'http://firebrigade.example.com/api/REST/get_target?api_version=1.0.0&platform=c&release_date=b&username=username&version=a',
414
+ URI::HTTP.uris.first
415
+
416
+ assert_equal 'No such target exists', e.message
417
+ end
418
+
419
+ def test_get_version
420
+ URI::HTTP.responses << <<-EOF.strip
421
+ <ok>
422
+ <version>
423
+ <id>100</id>
424
+ <name>1.0.0</name>
425
+ <project_id>101</project_id>
426
+ </version>
427
+ </ok>
428
+ EOF
429
+
430
+ version_name = '1.0.0'
431
+
432
+ version = Firebrigade::API::Version.new
433
+ version.id = 100
434
+ version.name = version_name
435
+ version.project_id = 101
436
+
437
+ assert_equal version, @fa.get_version(version_name, 101)
438
+
439
+ assert_equal true, URI::HTTP.responses.empty?
440
+ assert_equal 1, URI::HTTP.uris.length
441
+ assert_equal 'http://firebrigade.example.com/api/REST/get_version?name=1.0.0&project_id=101',
442
+ URI::HTTP.uris.first
443
+ end
444
+
445
+ end
446
+
@@ -0,0 +1,141 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'rc_rest/net_http_stub'
4
+ require 'rc_rest/uri_stub'
5
+
6
+ require 'firebrigade/cache'
7
+
8
+ class Firebrigade::Cache
9
+ attr_accessor :owners, :projects, :versions
10
+ end
11
+
12
+ class TestFirebrigadeCache < Test::Unit::TestCase
13
+
14
+ def setup
15
+ Net::HTTP.params = []
16
+ Net::HTTP.paths = []
17
+ Net::HTTP.responses = []
18
+
19
+ URI::HTTP.uris = []
20
+ URI::HTTP.responses = []
21
+
22
+ @spec = Gem::Specification.new
23
+ @spec.name = 'gem_one'
24
+ @spec.version = '0.0.2'
25
+ @spec.rubyforge_project = 'gem'
26
+
27
+ @fc = Firebrigade::Cache.new 'firebrigade.example.com', 'username',
28
+ 'password'
29
+ end
30
+
31
+ def test_get_build_id
32
+ URI::HTTP.responses << <<-EOF
33
+ <ok>
34
+ <build>
35
+ <id>5</id>
36
+ <created_on>#{Time.now}</created_on>
37
+ <duration>1.5</duration>
38
+ <successful>true</successful>
39
+ <target_id>4</target_id>
40
+ <version_id>3</version_id>
41
+ </build>
42
+ </ok>
43
+ EOF
44
+
45
+ assert_equal 5, @fc.get_build_id(3, 4)
46
+
47
+ assert_equal 'http://firebrigade.example.com/api/REST/get_build?target_id=4&version_id=3',
48
+ URI::HTTP.uris.shift
49
+
50
+ URI::HTTP.responses << <<-EOF
51
+ <error>
52
+ <message>No such build exists</message>
53
+ </error>
54
+ EOF
55
+
56
+ assert_equal nil, @fc.get_build_id(-1, 4)
57
+
58
+ assert_equal 'http://firebrigade.example.com/api/REST/get_build?target_id=4&version_id=-1',
59
+ URI::HTTP.uris.shift
60
+ end
61
+
62
+ def test_get_target_id
63
+ Net::HTTP.responses << <<-EOF
64
+ <ok>
65
+ <target>
66
+ <id>5</id>
67
+ <platform>fake platform</platform>
68
+ <release_date>fake release_date</release_date>
69
+ <username>fake username</username>
70
+ <version>fake version</version>
71
+ </target>
72
+ </ok>
73
+ EOF
74
+
75
+ assert_equal 5, @fc.get_target_id
76
+ end
77
+
78
+ def test_get_version_id_cached
79
+ @fc.owners['gem'] = 1
80
+ @fc.projects[[1, 'gem_one']] = 2
81
+ @fc.versions[[2, '0.0.2']] = 3
82
+
83
+ version_id = @fc.get_version_id @spec
84
+ assert_equal 3, version_id
85
+ end
86
+
87
+ def test_get_version_id_no_data
88
+ Net::HTTP.responses << <<-EOF
89
+ <ok>
90
+ <owner>
91
+ <id>1</id>
92
+ <name>gem</name>
93
+ </owner>
94
+ </ok>
95
+ EOF
96
+
97
+ Net::HTTP.responses << <<-EOF
98
+ <ok>
99
+ <project>
100
+ <id>2</id>
101
+ <name>gem_one</name>
102
+ <owner_id>1</owner_id>
103
+ </project>
104
+ </ok>
105
+ EOF
106
+
107
+ Net::HTTP.responses << <<-EOF
108
+ <ok>
109
+ <version>
110
+ <id>3</id>
111
+ <name>0.0.2</name>
112
+ <project_id>2</project_id>
113
+ </version>
114
+ </ok>
115
+ EOF
116
+
117
+ version_id = @fc.get_version_id @spec
118
+ assert_equal 3, version_id
119
+
120
+ assert_equal 1, @fc.owners['gem']
121
+ assert_equal 2, @fc.projects[[1, 'gem_one']]
122
+ assert_equal 3, @fc.versions[[2, '0.0.2']]
123
+
124
+ assert_equal 3, Net::HTTP.paths.length
125
+
126
+ assert_equal '/api/REST/add_owner', Net::HTTP.paths.shift
127
+ assert_equal '/api/REST/add_project', Net::HTTP.paths.shift
128
+ assert_equal '/api/REST/add_version', Net::HTTP.paths.shift
129
+
130
+ assert_equal 3, Net::HTTP.params.length
131
+
132
+ assert_equal 'hash=6e434d0379ccd7ac7d22dbd7923b5ea6&name=gem&user=username',
133
+ Net::HTTP.params.shift
134
+ assert_equal 'hash=749f7b36b1cf1a274bbcd805c3a42a50&name=gem_one&owner_id=1&user=username',
135
+ Net::HTTP.params.shift
136
+ assert_equal 'hash=67467aef2fdc65b98c80778301e2eff1&name=0.0.2&project_id=2&user=username',
137
+ Net::HTTP.params.shift
138
+ end
139
+
140
+ end
141
+
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.1
3
+ specification_version: 1
4
+ name: firebrigade_api
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-01-30 00:00:00 -08:00
8
+ summary: API for Firebrigade
9
+ require_paths:
10
+ - lib
11
+ email: drbrain@segment7.net
12
+ homepage:
13
+ rubyforge_project: seattlerb
14
+ description: http://seattlerb.rubyforge.org/firebrigade_api == DESCRIPTION An API wrapper for http://firebrigade.seattlerb.org == FEATURES/PROBLEMS
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Eric Hodel
31
+ files:
32
+ - History.txt
33
+ - LICENSE.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ - Rakefile
37
+ - lib/firebrigade.rb
38
+ - lib/firebrigade/api.rb
39
+ - lib/firebrigade/cache.rb
40
+ - test/test_firebrigade_api.rb
41
+ - test/test_firebrigade_cache.rb
42
+ test_files:
43
+ - test/test_firebrigade_api.rb
44
+ - test/test_firebrigade_cache.rb
45
+ rdoc_options: []
46
+
47
+ extra_rdoc_files: []
48
+
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ requirements: []
54
+
55
+ dependencies:
56
+ - !ruby/object:Gem::Dependency
57
+ name: rc-rest
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Version::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 2.1.0
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: hoe
67
+ version_requirement:
68
+ version_requirements: !ruby/object:Gem::Version::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 1.1.7
73
+ version: