bellows 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "bundler", "~> 1.0.0"
10
+ gem "jeweler", "~> 1.6.4"
11
+ gem "thor", "~> 0.14.6"
12
+ gem "json", "~> 1.4.6"
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Dan Prince
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ Bellows
2
+ =======
3
+
4
+ Description
5
+ -----------
6
+
7
+ Fire it up! SmokeStack automation w/ Gerrit.
8
+
9
+ CLI to drive SmokeStack test creation and maintenance based on Gerrit reviews.
10
+
11
+ Installation
12
+ ------------
13
+
14
+ gem install bellows
15
+
16
+ #create the bellows config in your $HOME dir:
17
+ cat > ~/.bellows.conf <<"EOF_CAT"
18
+ smokestack_url: http://localhost:3000
19
+ smokestack_username: admin
20
+ smokestack_password: cloud
21
+
22
+ config_template_ids:
23
+ - 1
24
+ - 2
25
+
26
+ test_suite_ids:
27
+ - 1
28
+ EOF_CAT
29
+
30
+
31
+ Examples
32
+ --------
33
+
34
+ Available bellows tasks:
35
+
36
+ Tasks:
37
+ bellows help [TASK] # Describe available tasks or one specific task
38
+ bellows purge PROJECT # Purge merged reviews from SmokeStack
39
+ bellows sync PROJECT # Create tests & update refspecs for active reviews.
40
+ bellows update PROJECT # Update tests suite and configuration selections.
41
+
42
+ Run bellows sync to create smokestack test configurations and update refspecs for active reviews:
43
+
44
+ bellows sync nova
45
+
46
+ Purge 'merged' reviews from SmokeStack:
47
+
48
+ bellows purge nova
49
+
50
+ Update the selected configuration template and test suite choices for active reviews in SmokeStack (based on the selections in your .bellows.conf file):
51
+
52
+ bellows update nova
53
+
54
+ All commands support creating and maintaining test configs for nova, glance, and keystone.
55
+
56
+ License
57
+ -------
58
+ Copyright (c) 2011 Dan Prince. See LICENSE.txt for further details.
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "bellows"
18
+ gem.executables = "bellows"
19
+ gem.homepage = "http://github.com/dprince/bellows"
20
+ gem.license = "MIT"
21
+ gem.summary = %Q{Fire it up! SmokeStack automation w/ Gerrit.}
22
+ gem.description = %Q{CLI to drive SmokeStack test creation and maintenance based on Gerrit reviews.}
23
+ gem.email = "dan.prince@rackspace.com"
24
+ gem.authors = ["Dan Prince"]
25
+ # dependencies defined in Gemfile
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ #test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ =begin
37
+ require 'rcov/rcovtask'
38
+ Rcov::RcovTask.new do |test|
39
+ test.libs << 'test'
40
+ test.pattern = 'test/**/test_*.rb'
41
+ test.verbose = true
42
+ test.rcov_opts << '--exclude "gems/*"'
43
+ end
44
+ =end
45
+
46
+ task :default => :test
47
+
48
+ require 'rake/rdoctask'
49
+ Rake::RDocTask.new do |rdoc|
50
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "bellows #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/bellows.gemspec ADDED
@@ -0,0 +1,65 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{bellows}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Dan Prince"]
12
+ s.date = %q{2011-10-13}
13
+ s.default_executable = %q{bellows}
14
+ s.description = %q{CLI to drive SmokeStack test creation and maintenance based on Gerrit reviews.}
15
+ s.email = %q{dan.prince@rackspace.com}
16
+ s.executables = ["bellows"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE.txt",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ "Gemfile",
24
+ "LICENSE.txt",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "bin/bellows",
28
+ "lib/bellows.rb",
29
+ "lib/bellows/gerrit.rb",
30
+ "lib/bellows/http.rb",
31
+ "lib/bellows/smoke_stack.rb",
32
+ "lib/bellows/tasks.rb",
33
+ "lib/bellows/util.rb",
34
+ "test/helper.rb",
35
+ "test/test_util.rb"
36
+ ]
37
+ s.homepage = %q{http://github.com/dprince/bellows}
38
+ s.licenses = ["MIT"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.3.7}
41
+ s.summary = %q{Fire it up! SmokeStack automation w/ Gerrit.}
42
+
43
+ if s.respond_to? :specification_version then
44
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
45
+ s.specification_version = 3
46
+
47
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
48
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
49
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
50
+ s.add_development_dependency(%q<thor>, ["~> 0.14.6"])
51
+ s.add_development_dependency(%q<json>, ["~> 1.4.6"])
52
+ else
53
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
54
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
55
+ s.add_dependency(%q<thor>, ["~> 0.14.6"])
56
+ s.add_dependency(%q<json>, ["~> 1.4.6"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
60
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
61
+ s.add_dependency(%q<thor>, ["~> 0.14.6"])
62
+ s.add_dependency(%q<json>, ["~> 1.4.6"])
63
+ end
64
+ end
65
+
data/bin/bellows ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "thor"
5
+ #if not $release
6
+ #$:.unshift File.dirname(__FILE__) + "/../lib"
7
+ #end
8
+ require "bellows"
9
+
10
+ Bellows::Tasks.start
@@ -0,0 +1,23 @@
1
+ require 'json'
2
+
3
+ module Bellows
4
+ class Gerrit
5
+
6
+ def self.reviews(project, status="open")
7
+ reviews = []
8
+ out=%x{ssh review gerrit query "status: #{status}" --current-patch-set --format JSON}
9
+ out.each_line do |line|
10
+ data = JSON.parse(line)
11
+ if data['project'] and data['project'] == "openstack/#{project}"
12
+ if block_given?
13
+ yield data
14
+ else
15
+ reviews << data
16
+ end
17
+ end
18
+ end
19
+ reviews
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,205 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'net/https'
4
+ require 'openssl'
5
+ require 'openssl/x509'
6
+ require 'bellows/util'
7
+
8
+ module Net
9
+ module HTTPHeader
10
+
11
+ def set_form_data(params, sep = '&')
12
+ query = URI.encode_www_form(params)
13
+ query.gsub!(/&/, sep) if sep != '&'
14
+ self.body = query
15
+ self.content_type = 'application/x-www-form-urlencoded'
16
+ end
17
+ alias form_data= set_form_data
18
+
19
+ end
20
+ end
21
+
22
+ module URI
23
+
24
+ def self.encode_www_form(enum)
25
+ enum.map do |k,v|
26
+ if v.nil?
27
+ k
28
+ elsif v.respond_to?(:to_ary)
29
+ v.to_ary.map do |w|
30
+ str = k.dup
31
+ unless w.nil?
32
+ str << '='
33
+ str << w
34
+ end
35
+ end.join('&')
36
+ else
37
+ str = k.dup
38
+ str << '='
39
+ str << v.to_s
40
+ end
41
+ end.join('&')
42
+ end
43
+
44
+ end
45
+
46
+ module Bellows
47
+ class HTTP
48
+
49
+ MULTI_PART_BOUNDARY="jtZ!pZ1973um"
50
+
51
+ @@http=nil
52
+ @@auth_user=nil
53
+ @@auth_password=nil
54
+
55
+ def self.init_connection
56
+
57
+ configs=Util.load_configs
58
+
59
+ base_url = configs["smokestack_url"]
60
+ @@auth_user = configs["smokestack_username"]
61
+ @@auth_password = configs["smokestack_password"]
62
+
63
+ ssl_key = configs["ssl_key"]
64
+ ssl_cert = configs["ssl_cert"]
65
+ ssl_ca_cert = configs["ssl_ca_cert"]
66
+
67
+ url=URI.parse(base_url)
68
+ @@http = Net::HTTP.new(url.host,url.port)
69
+
70
+ if base_url =~ /^https/
71
+ @@http.use_ssl = true
72
+ if ssl_ca_cert then
73
+ @@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
74
+ else
75
+ @@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
76
+ end
77
+
78
+ if ssl_key then
79
+ pkey_data=IO.read(ssl_key)
80
+ if pkey_data =~ /^-----BEGIN RSA PRIVATE KEY-----/
81
+ @@http.key=OpenSSL::PKey::RSA.new(pkey_data)
82
+ else
83
+ @@http.key=OpenSSL::PKey::DSA.new(pkey_data)
84
+ end
85
+ end
86
+ @@http.cert=OpenSSL::X509::Certificate.new(IO.read(ssl_cert)) if ssl_cert
87
+ @@http.ca_file=ssl_ca_cert if ssl_ca_cert
88
+ end
89
+
90
+ end
91
+
92
+ def self.file_upload(url_path, file_data={}, post_data={})
93
+ init_connection if @@http.nil?
94
+ req = Net::HTTP::Post.new(url_path)
95
+
96
+ post_arr=[]
97
+ post_data.each_pair do |key, value|
98
+ post_arr << "--#{MULTI_PART_BOUNDARY}\r\n"
99
+ post_arr << "Content-Disposition: form-data; name=\"#{key}\"\r\n"
100
+ post_arr << "\r\n"
101
+ post_arr << value
102
+ post_arr << "\r\n"
103
+ end
104
+
105
+ file_data.each_pair do |name, file|
106
+ post_arr << "--#{MULTI_PART_BOUNDARY}\r\n"
107
+ post_arr << "Content-Disposition: form-data; name=\"#{name}\"; filename=\"#{File.basename(file)}\"\r\n"
108
+ post_arr << "Content-Type: text/plain\r\n"
109
+ post_arr << "\r\n"
110
+ post_arr << File.read(file)
111
+ post_arr << "\r\n--#{MULTI_PART_BOUNDARY}--\r\n"
112
+ end
113
+ post_arr << "--#{MULTI_PART_BOUNDARY}--\r\n\r\n"
114
+
115
+ req.body=post_arr.join
116
+
117
+ req.basic_auth @@auth_user, @@auth_password if @@auth_user and @@auth_password
118
+ req["Content-Type"] = "multipart/form-data, boundary=#{MULTI_PART_BOUNDARY}"
119
+
120
+ response = @@http.request(req)
121
+ case response
122
+ when Net::HTTPSuccess
123
+ return response.body
124
+ else
125
+ puts response.body
126
+ response.error!
127
+ end
128
+ end
129
+
130
+ def self.post(url_path, post_data)
131
+ init_connection if @@http.nil?
132
+ req = Net::HTTP::Post.new(url_path)
133
+ if post_data.kind_of?(String) then
134
+ req.body=post_data
135
+ elsif post_data.kind_of?(Hash) then
136
+ req.form_data=post_data
137
+ else
138
+ raise "Invalid post data type."
139
+ end
140
+ req.basic_auth @@auth_user, @@auth_password if @@auth_user and @@auth_password
141
+ response = @@http.request(req)
142
+ case response
143
+ when Net::HTTPSuccess
144
+ return response.body
145
+ when Net::HTTPRedirection
146
+ return response['location']
147
+ else
148
+ puts response.body
149
+ response.error!
150
+ end
151
+ end
152
+
153
+ def self.put(url_path, put_data)
154
+ init_connection if @@http.nil?
155
+ req = Net::HTTP::Put.new(url_path)
156
+ if put_data.kind_of?(String) then
157
+ req.body=put_data
158
+ elsif put_data.kind_of?(Hash) then
159
+ req.form_data=put_data
160
+ else
161
+ raise "Invalid put data type."
162
+ end
163
+ req.basic_auth @@auth_user, @@auth_password if @@auth_user and @@auth_password
164
+ response = @@http.request(req)
165
+ case response
166
+ when Net::HTTPSuccess
167
+ return response.body
168
+ when Net::HTTPRedirection
169
+ return response['location']
170
+ else
171
+ puts response.body
172
+ response.error!
173
+ end
174
+ end
175
+
176
+ def self.get(url_path)
177
+ init_connection if @@http.nil?
178
+ req = Net::HTTP::Get.new(url_path)
179
+ req.basic_auth @@auth_user, @@auth_password if @@auth_user and @@auth_password
180
+ response = @@http.request(req)
181
+ case response
182
+ when Net::HTTPSuccess
183
+ return response.body
184
+ else
185
+ response.error!
186
+ end
187
+ end
188
+
189
+ def self.delete(url_path)
190
+ init_connection if @@http.nil?
191
+ req = Net::HTTP::Delete.new(url_path)
192
+ req.basic_auth @@auth_user, @@auth_password if @@auth_user and @@auth_password
193
+ response = @@http.request(req)
194
+ case response
195
+ when Net::HTTPSuccess
196
+ return response.body
197
+ when Net::HTTPRedirection
198
+ return response['location']
199
+ else
200
+ response.error!
201
+ end
202
+ end
203
+
204
+ end
205
+ end
@@ -0,0 +1,83 @@
1
+ require 'json'
2
+ require 'bellows/http'
3
+ require 'bellows/util'
4
+
5
+ module Bellows
6
+ class SmokeStack
7
+
8
+ def self.get_smoke_tests(project)
9
+ smoke_tests = {}
10
+ data = JSON.parse(Bellows::HTTP.get("/smoke_tests.json"))
11
+ data.each do |item|
12
+ branch = item['smoke_test']["#{project}_package_builder"]['branch']
13
+ if branch and not branch.empty? then
14
+ smoke_tests.store(Bellows::Util.short_spec(branch), item['smoke_test'])
15
+ end
16
+ end
17
+ smoke_tests
18
+ end
19
+
20
+ def self.format_request(smoke_test)
21
+ req={}
22
+ smoke_test.each_pair do |name, item|
23
+ #only builders should be hashes
24
+ if item.kind_of?(Hash) then
25
+ item.each_pair do |builder_name, builder|
26
+ req.store("smoke_test[#{name}_attributes][#{builder_name}]", builder)
27
+ end
28
+ elsif item.kind_of?(Array) then
29
+ req.store("smoke_test[#{name}][]", item)
30
+ else
31
+ req.store("smoke_test[#{name}]", item)
32
+ end
33
+ end
34
+ req.delete("smoke_test['id']")
35
+ req
36
+ end
37
+
38
+ def self.update_smoke_test(id, updates={})
39
+
40
+ data = JSON.parse(Bellows::HTTP.get("/smoke_tests/#{id}.json"))
41
+ ['nova', 'glance', 'keystone'].each do |proj|
42
+ if updates["#{proj}_package_builder"]
43
+ data["smoke_test"]["#{proj}_package_builder"].merge!(updates["#{proj}_package_builder"])
44
+ updates.delete("#{proj}_package_builder")
45
+ end
46
+ end
47
+ data['smoke_test'].merge!(updates)
48
+ post_data = format_request(data['smoke_test'])
49
+ Bellows::HTTP.put("/smoke_tests/#{id}", post_data)
50
+
51
+ end
52
+
53
+ def self.create_smoke_test(project, description, refspec, config_template_ids, test_suite_ids)
54
+
55
+ post_data = { "smoke_test[description]" => description }
56
+
57
+ ['nova', 'glance', 'keystone'].each do |proj|
58
+ base_name="smoke_test[#{proj}_package_builder_attributes]"
59
+ if project == proj then
60
+ post_data.store("#{base_name}[url]", "https://review.openstack.org/p/openstack/#{project}")
61
+ post_data.store("#{base_name}[branch]", refspec)
62
+ post_data.store("#{base_name}[merge_trunk]", "1")
63
+ else
64
+ post_data.store("#{base_name}[url]", "git://github.com/openstack/#{proj}.git")
65
+ post_data.store("#{base_name}[branch]", "master")
66
+ post_data.store("#{base_name}[merge_trunk]", "0")
67
+ end
68
+ end
69
+
70
+ configurations = []
71
+ config_template_ids.each {|id| configurations << id.to_s}
72
+ post_data.store("smoke_test[config_template_ids][]", configurations)
73
+
74
+ test_suites = []
75
+ test_suite_ids.each {|id| test_suites << id.to_s}
76
+ post_data.store("smoke_test[test_suite_ids][]", test_suites)
77
+
78
+ Bellows::HTTP.post("/smoke_tests", post_data)
79
+
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,85 @@
1
+ require 'json'
2
+ require 'bellows/http'
3
+ require 'bellows/util'
4
+ require 'bellows/gerrit'
5
+ require 'bellows/smoke_stack'
6
+
7
+ module Bellows
8
+ class Tasks < Thor
9
+
10
+ desc "sync PROJECT", "Create tests & update refspecs for active reviews."
11
+ method_options :test => :boolean
12
+ def sync(project)
13
+ if not ['nova', 'glance', 'keystone'].include?(project) then
14
+ puts "ERROR: Please specify a valid project name."
15
+ exit 1
16
+ end
17
+ test = options[:test]
18
+ smoke_tests = Bellows::SmokeStack.get_smoke_tests(project)
19
+ configs=Util.load_configs
20
+ test_suite_ids = configs['test_suite_ids'].collect {|x| x.to_s }
21
+ config_template_ids = configs['config_template_ids'].collect {|x| x.to_s }
22
+
23
+ Bellows::Gerrit.reviews(project) do |review|
24
+ owner = review['owner']['name']
25
+ refspec = review['currentPatchSet']['ref']
26
+ review_id = Bellows::Util.short_spec(refspec)
27
+ smoke_test = smoke_tests[review_id]
28
+ desc = owner + ": " +review['subject']
29
+ if not smoke_test
30
+ puts "Creating... " + desc
31
+ Bellows::SmokeStack.create_smoke_test(project, desc, refspec, config_template_ids, test_suite_ids) if not test
32
+ else
33
+ if smoke_test["#{project}_package_builder"]['branch'] != refspec then
34
+ puts "Updating... " + desc
35
+ puts "refspec: " + refspec
36
+ Bellows::SmokeStack.update_smoke_test(smoke_test['id'], {"#{project}_package_builder" => { "branch" => refspec}}) if not test
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ desc "purge PROJECT", "Purge merged reviews from SmokeStack"
43
+ method_options :test => :boolean
44
+ def purge(project)
45
+ if not ['nova', 'glance', 'keystone'].include?(project) then
46
+ puts "ERROR: Please specify a valid project name."
47
+ exit 1
48
+ end
49
+ test = options[:test]
50
+ smoke_tests = Bellows::SmokeStack.get_smoke_tests(project)
51
+ Bellows::Gerrit.reviews(project, "merged") do |review|
52
+ refspec = review['currentPatchSet']['ref']
53
+ review_id = Bellows::Util.short_spec(refspec)
54
+ smoke_test = smoke_tests[review_id]
55
+ desc = review['owner']['name'] + ": " +review['subject']
56
+ if smoke_test
57
+ puts "Deleting... " + desc
58
+ Bellows::HTTP.delete("/smoke_tests/#{smoke_test['id']}") if not test
59
+ end
60
+ end
61
+ end
62
+
63
+ desc "update PROJECT", "Update tests suite and configuration selections."
64
+ def update(project)
65
+ if not ['nova', 'glance', 'keystone'].include?(project) then
66
+ puts "ERROR: Please specify a valid project name."
67
+ exit 1
68
+ end
69
+ test = options[:test]
70
+ smoke_tests = Bellows::SmokeStack.get_smoke_tests(project)
71
+ configs=Util.load_configs
72
+ test_suite_ids = configs['test_suite_ids'].collect {|x| x.to_s }
73
+ config_template_ids = configs['config_template_ids'].collect {|x| x.to_s }
74
+ Bellows::Gerrit.reviews(project) do |review|
75
+ refspec = review['currentPatchSet']['ref']
76
+ review_id = Bellows::Util.short_spec(refspec)
77
+ smoke_test = smoke_tests[review_id]
78
+ if smoke_test
79
+ Bellows::SmokeStack.update_smoke_test(smoke_test['id'], {"test_suite_ids" => test_suite_ids, "config_template_ids" => config_template_ids})
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,48 @@
1
+ require 'yaml'
2
+ require 'socket'
3
+
4
+ module Bellows
5
+ module Util
6
+
7
+ @@configs=nil
8
+
9
+ def self.load_configs
10
+
11
+ return @@configs if not @@configs.nil?
12
+
13
+ config_file=ENV['BELLOWS_CONFIG_FILE']
14
+ if config_file.nil? then
15
+
16
+ config_file=ENV['HOME']+File::SEPARATOR+".bellows.conf"
17
+ if not File.exists?(config_file) then
18
+ config_file="/etc/bellows.conf"
19
+ end
20
+
21
+ end
22
+
23
+ if File.exists?(config_file) then
24
+ configs=YAML.load_file(config_file)
25
+ raise_if_nil_or_empty(configs, "smokestack_url")
26
+ raise_if_nil_or_empty(configs, "smokestack_username")
27
+ raise_if_nil_or_empty(configs, "smokestack_password")
28
+ @@configs=configs
29
+ else
30
+ raise "Failed to load bellows config file. Please configure /etc/bellows.conf or create a .bellows.conf config file in your HOME directory."
31
+ end
32
+
33
+ @@configs
34
+
35
+ end
36
+
37
+ def self.raise_if_nil_or_empty(options, key)
38
+ if not options or options[key].nil? or options[key].empty? then
39
+ raise "Please specify a valid #{key.to_s} parameter."
40
+ end
41
+ end
42
+
43
+ def self.short_spec(refspec)
44
+ refspec.sub(/\/[^\/]*$/, "")
45
+ end
46
+
47
+ end
48
+ end
data/lib/bellows.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bellows/util'
3
+ require 'bellows/http'
4
+ require 'bellows/tasks'
5
+
6
+ module Bellows
7
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'thor'
4
+ begin
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+ require 'test/unit'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'bellows'
16
+
17
+ class Test::Unit::TestCase
18
+ end
data/test/test_util.rb ADDED
@@ -0,0 +1,10 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require 'helper'
3
+
4
+ class UtilTest < Test::Unit::TestCase
5
+
6
+ def test_short_spec
7
+ assert_equal "123/123", Bellows::Util.short_spec("123/123/123")
8
+ end
9
+
10
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bellows
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Dan Prince
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-10-13 00:00:00 -04:00
19
+ default_executable: bellows
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ name: bundler
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 0
34
+ version: 1.0.0
35
+ requirement: *id001
36
+ type: :development
37
+ - !ruby/object:Gem::Dependency
38
+ prerelease: false
39
+ name: jeweler
40
+ version_requirements: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 7
46
+ segments:
47
+ - 1
48
+ - 6
49
+ - 4
50
+ version: 1.6.4
51
+ requirement: *id002
52
+ type: :development
53
+ - !ruby/object:Gem::Dependency
54
+ prerelease: false
55
+ name: thor
56
+ version_requirements: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 43
62
+ segments:
63
+ - 0
64
+ - 14
65
+ - 6
66
+ version: 0.14.6
67
+ requirement: *id003
68
+ type: :development
69
+ - !ruby/object:Gem::Dependency
70
+ prerelease: false
71
+ name: json
72
+ version_requirements: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ hash: 11
78
+ segments:
79
+ - 1
80
+ - 4
81
+ - 6
82
+ version: 1.4.6
83
+ requirement: *id004
84
+ type: :development
85
+ description: CLI to drive SmokeStack test creation and maintenance based on Gerrit reviews.
86
+ email: dan.prince@rackspace.com
87
+ executables:
88
+ - bellows
89
+ extensions: []
90
+
91
+ extra_rdoc_files:
92
+ - LICENSE.txt
93
+ - README.md
94
+ files:
95
+ - .document
96
+ - Gemfile
97
+ - LICENSE.txt
98
+ - README.md
99
+ - Rakefile
100
+ - VERSION
101
+ - bellows.gemspec
102
+ - bin/bellows
103
+ - lib/bellows.rb
104
+ - lib/bellows/gerrit.rb
105
+ - lib/bellows/http.rb
106
+ - lib/bellows/smoke_stack.rb
107
+ - lib/bellows/tasks.rb
108
+ - lib/bellows/util.rb
109
+ - test/helper.rb
110
+ - test/test_util.rb
111
+ has_rdoc: true
112
+ homepage: http://github.com/dprince/bellows
113
+ licenses:
114
+ - MIT
115
+ post_install_message:
116
+ rdoc_options: []
117
+
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ hash: 3
126
+ segments:
127
+ - 0
128
+ version: "0"
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ hash: 3
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ requirements: []
139
+
140
+ rubyforge_project:
141
+ rubygems_version: 1.3.7
142
+ signing_key:
143
+ specification_version: 3
144
+ summary: Fire it up! SmokeStack automation w/ Gerrit.
145
+ test_files: []
146
+