firebrigade_api 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: