cloud-toaster 1.1.5 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Gemfile +5 -45
- data/README.md +2 -2
- data/VERSION +1 -1
- data/chef/cookbooks/lxc/recipes/setup_database.rb +12 -4
- data/chef/cookbooks/toaster/recipes/testing.rb +2 -2
- data/cloud-toaster.gemspec +94 -0
- data/config.json +3 -1
- data/lib/toaster/api.rb +25 -22
- data/lib/toaster/chef/chef_listener.rb +3 -3
- data/lib/toaster/chef/chef_node_inspector.rb +6 -4
- data/lib/toaster/chef/chef_util.rb +26 -8
- data/lib/toaster/chef/failsafe_resource_parser.rb +1 -0
- data/lib/toaster/chef/resource_inspector.rb +1 -1
- data/lib/toaster/model/automation.rb +26 -7
- data/lib/toaster/model/automation_run.rb +2 -11
- data/lib/toaster/model/key_value_pair.rb +13 -1
- data/lib/toaster/model/task.rb +3 -3
- data/lib/toaster/model/task_execution.rb +3 -2
- data/lib/toaster/model/task_parameter.rb +17 -24
- data/lib/toaster/state/convergence.rb +2 -2
- data/lib/toaster/state/idempotence.rb +13 -7
- data/lib/toaster/state/system_state.rb +1 -0
- data/lib/toaster/test/test_case.rb +10 -5
- data/lib/toaster/test/test_runner.rb +131 -124
- data/lib/toaster/test/test_suite.rb +1 -1
- data/lib/toaster/test_manager.rb +3 -9
- data/lib/toaster/toaster_app_service.rb +0 -4
- data/lib/toaster/util/config.rb +6 -1
- data/lib/toaster/util/lxc.rb +1 -1
- data/webapp/app/assets/javascripts/jstree.util.js +2 -1
- data/webapp/app/assets/stylesheets/application.css +21 -1
- data/webapp/app/assets/stylesheets/layout.css +1 -1
- data/webapp/app/controllers/analysis_controller.rb +12 -0
- data/webapp/app/controllers/application_controller.rb +11 -3
- data/webapp/app/controllers/base_controller.rb +1 -0
- data/webapp/app/controllers/execs_controller.rb +12 -4
- data/webapp/app/controllers/scripts_controller.rb +91 -52
- data/webapp/app/controllers/test_controller.rb +4 -4
- data/webapp/app/views/analysis/convergence.html.erb +14 -11
- data/webapp/app/views/analysis/idempotence.html.erb +40 -1
- data/webapp/app/views/analysis/index.html.erb +117 -0
- data/webapp/app/views/execs/automation_runs.html.erb +10 -4
- data/webapp/app/views/execs/task_executions.html.erb +20 -16
- data/webapp/app/views/layouts/application.html.erb +22 -9
- data/webapp/app/views/scripts/graph.html.erb +1 -1
- data/webapp/app/views/scripts/import_chef.html.erb +4 -0
- data/webapp/app/views/scripts/scripts.html.erb +5 -17
- data/webapp/app/views/settings/{index.html.erb → config.html.erb} +4 -6
- data/webapp/app/views/settings/containers.html.erb +7 -9
- data/webapp/app/views/test/gen.html.erb +1 -0
- data/webapp/app/views/test/suites.html.erb +1 -1
- data/webapp/app/views/util/chef.html.erb +2 -2
- data/webapp/config/initializers/devise.rb +4 -1
- data/webapp/config/routes.rb +15 -8
- data/webapp/log/development.log +39521 -0
- data/webapp/tmp/cache/assets/development/sprockets/0dc0562647e703ca0535da3b9fcad796 +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/72cbfd5bf33945bcce154f7a4feaf04d +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/7b2b7d9034fc7b77daf5da1436667e6f +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/b6f1534bcdbff92a16c85487f363235a +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/bfac6cd2984fbd5e0d762389e3c37164 +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/c5907cfd07b24ad19b8c80e8af618a57 +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/webapp/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- metadata +53 -51
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YWY2YTE5NDFmNjYyZjMwZmYzNjI0ZjQ0NGU1ZTJkNTRmNmJjNDRmMA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YWE5ZjQzNzE5YTNhYWRkN2UwOTNiNDg0NjFjM2QwNTIyODc0MGZjMw==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NWVjNmM3ZTcwOGMxM2YyZDAzYzY3MDhkOWU5YmQ3OGZhNzJmOTQ5NzFiYzgw
|
10
|
+
ODdmMzMzZmExYzA3ZDcxYzU2ZDg5NGJhNzM1MDk1OTM4MTVkNDczNjhjNmQ4
|
11
|
+
OTY0MzUzZGM0MmE0NzExMjBlNGMxZDRjODc5NGQ1YzI2Y2EwZmE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZGY3NTg4YWY2ZjBlNTg3YmQ3NDE5MTJlZDRkNTRmMjQ4MzE4YWMzMjdjOTJl
|
14
|
+
Mzc2MGViYTFhN2NjYTU0ZWM3NTRkMDQxYTZjYThkNTAwMDFmM2MwNzU5NmE5
|
15
|
+
Mzc4N2RlYmI3MDczM2FmNmNiZjNjNDk3NmUyZThjZThlMTMzY2M=
|
data/Gemfile
CHANGED
@@ -1,51 +1,11 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
gem
|
7
|
-
# Use sqlite3 as the database for Active Record
|
8
|
-
gem 'sqlite3'
|
9
|
-
# Use SCSS for stylesheets
|
10
|
-
gem 'sass-rails' #, '~> 4.0.0'
|
11
|
-
# Use Uglifier as compressor for JavaScript assets
|
12
|
-
gem 'uglifier' #, '>= 1.3.0'
|
13
|
-
# Use CoffeeScript for .js.coffee assets and views
|
14
|
-
gem 'coffee-rails' #, '~> 4.0.0'
|
15
|
-
# Use jquery as the JavaScript library
|
16
|
-
gem 'jquery-rails'
|
17
|
-
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
|
18
|
-
gem 'turbolinks'
|
19
|
-
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
|
20
|
-
gem 'jbuilder' #, '~> 1.2'
|
21
|
-
group :doc do
|
22
|
-
# bundle exec rake doc:rails generates the API under doc/api.
|
23
|
-
gem 'sdoc', require: false
|
3
|
+
# load gem dependencies from cloud-toaster.gemspec
|
4
|
+
deps = gemspec :name => 'cloud-toaster'
|
5
|
+
deps.each do |dep|
|
6
|
+
gem dep.name, dep.requirement
|
24
7
|
end
|
25
|
-
# Authentication module
|
26
|
-
gem 'devise'
|
27
|
-
# Use thin server (faster; prints less rails output/warnings)
|
28
|
-
gem 'thin', '~> 1.6' # 14-07-08: default version 2.0.0.pre is incompatible
|
29
|
-
# http://stackoverflow.com/questions/19579984/sinatra-server-wont-start-wrong-number-of-arguments
|
30
8
|
|
31
|
-
#
|
32
|
-
gem 'hashdiff' # diff hashes
|
33
|
-
gem 'json'
|
34
|
-
gem 'aquarium'
|
35
|
-
gem 'jsonpath'
|
36
|
-
gem 'open4' # open processes with stdin/stdout
|
37
|
-
gem 'chef'
|
38
|
-
gem 'ohai'
|
39
|
-
gem 'rspec' # tests
|
40
|
-
gem 'ruby_parser' # parse Ruby code
|
41
|
-
gem 'bson'
|
42
|
-
gem 'bson_ext'
|
43
|
-
gem 'logger'
|
44
|
-
gem 'thor' # CLI generator
|
45
|
-
gem 'tidy' # tidy XML library
|
46
|
-
gem 'diffy' # comparing source files
|
47
|
-
gem 'mysql2' # for DB access
|
48
|
-
gem 'therubyracer' # required by execjs
|
49
|
-
gem 'railties'
|
9
|
+
# some overrides
|
50
10
|
gem 'activesupport', :require => "active_support"
|
51
11
|
gem 'activerecord', :require => "active_record"
|
data/README.md
CHANGED
@@ -21,13 +21,13 @@ Automated testing of Infrastructure as Code automation scripts (e.g., Chef).
|
|
21
21
|
sudo su -
|
22
22
|
|
23
23
|
# prerequisites:
|
24
|
-
apt-get -y install wget make bzip2 curl patch screen libgdbm-dev libyaml-dev libxml2-dev libxslt-dev libmysqlclient-dev libsqlite3-dev
|
24
|
+
apt-get -y install wget make bzip2 curl patch screen libgdbm-dev libyaml-dev libxml2-dev libxslt-dev libmysqlclient-dev libsqlite3-dev g++
|
25
25
|
curl -L https://get.rvm.io | bash -s stable --ruby
|
26
26
|
# (OR: install stable ruby versions from repo: apt-get install -y ruby ruby-dev)
|
27
27
|
source /usr/local/rvm/scripts/rvm
|
28
28
|
|
29
29
|
# install toaster gem:
|
30
|
-
gem build toaster.gemspec
|
30
|
+
gem build cloud-toaster.gemspec
|
31
31
|
gem install --no-ri --no-rdoc cloud-toaster-*version*.gem
|
32
32
|
|
33
33
|
# (OR: install directly using rubygems.org: gem install cloud-toaster)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.6
|
@@ -1,14 +1,22 @@
|
|
1
1
|
|
2
2
|
if platform_family?("debian")
|
3
3
|
|
4
|
-
node.set['mysql']['server_root_password'] = "root"
|
5
|
-
include_recipe "mysql::server"
|
6
|
-
|
7
4
|
root_dir = File.join(File.dirname(__FILE__), "..","..","..","..")
|
5
|
+
$LOAD_PATH << File.join(root_dir, "lib")
|
6
|
+
require 'toaster/util/config'
|
7
|
+
|
8
|
+
cfg_db_pass = Toaster::Config.get("db.password")
|
9
|
+
cfg_db_pass = "root" if "#{cfg_db_pass}".empty?
|
10
|
+
node.set['mysql']['server_root_password'] = cfg_db_pass
|
11
|
+
include_recipe "mysql::server"
|
8
12
|
|
9
13
|
bash 'db_create' do
|
10
14
|
code <<-EOH
|
11
|
-
|
15
|
+
db_pass=#{node['mysql']['server_root_password']}
|
16
|
+
ip_pattern=#{node["network"]["ip_pattern"].gsub('*','%')}
|
17
|
+
echo 'create database toaster;' | mysql -u root -p$db_pass
|
18
|
+
echo "GRANT ALL ON toaster.* TO 'root'@'$ip_pattern' IDENTIFIED BY '$db_pass';" | mysql -u root -p$db_pass
|
19
|
+
echo "FLUSH PRIVILEGES;" | mysql -u root -p$db_pass
|
12
20
|
cd #{root_dir}/webapp && ./bin/rake db:migrate RAILS_ENV=development
|
13
21
|
EOH
|
14
22
|
not_if "echo \"show databases;\" | mysql -u root -p#{node['mysql']['server_root_password']} | grep toaster"
|
@@ -156,8 +156,8 @@ ruby_block $last_toaster_resource_name do
|
|
156
156
|
{
|
157
157
|
"db_type" => db_type,
|
158
158
|
db_type => node['toaster'][db_type],
|
159
|
-
"user_id" => node['user_id'],
|
160
|
-
"automation_uuid" => node['automation_uuid'],
|
159
|
+
"user_id" => node['toaster']['user_id'],
|
160
|
+
"automation_uuid" => node['toaster']['automation_uuid'],
|
161
161
|
"cookbook_paths" => node['toaster']['cookbook_paths'],
|
162
162
|
"skip_tasks" => node['toaster']['skip_tasks'],
|
163
163
|
"repeat_tasks" => node['toaster']['repeat_tasks'],
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{cloud-toaster}
|
5
|
+
s.version = File.exist?('VERSION') ? File.read('VERSION').strip : ""
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = [ %q{Waldemar Hummer} ]
|
9
|
+
s.date = DateTime.now.strftime("%Y-%m-%d")
|
10
|
+
s.description = %q{A tool for automated testing and debugging of automation scripts (e.g., Chef).}
|
11
|
+
s.email = [%q{hummer@infosys.tuwien.ac.at}]
|
12
|
+
s.extra_rdoc_files = [
|
13
|
+
"LICENSE",
|
14
|
+
"Rakefile",
|
15
|
+
"README.md",
|
16
|
+
"VERSION"
|
17
|
+
]
|
18
|
+
s.files = Dir.glob("lib/**/*") + Dir.glob("bin/*") +
|
19
|
+
Dir.glob("bin/strace-4.8_patched/strace-x86_64") +
|
20
|
+
Dir.glob("bin/strace-4.8_patched/strace-i686") +
|
21
|
+
Dir.glob("chef/**/*") + Dir.glob("webapp/**/*") +
|
22
|
+
Dir.glob("config.json") + Dir.glob("Gemfile") +
|
23
|
+
Dir.glob("cloud-toaster.gemspec")
|
24
|
+
|
25
|
+
deps = {
|
26
|
+
'bundler' => '~> 1.3',
|
27
|
+
# RUBY ON RAILS DEPENDENCIES
|
28
|
+
'rails' => '>= 0', #, '4.0.2'
|
29
|
+
'sqlite3' => '>= 0',
|
30
|
+
'sass-rails' => '>= 0', #, '~> 4.0.0'
|
31
|
+
'uglifier' => '>= 0', #, '>= 1.3.0'
|
32
|
+
'coffee-rails' => '>= 0', #, '~> 4.0.0'
|
33
|
+
'jquery-rails' => '>= 0',
|
34
|
+
'turbolinks' => '>= 0',
|
35
|
+
'jbuilder' => '>= 0', #, '~> 1.2'
|
36
|
+
'devise' => '>= 0',
|
37
|
+
'thin' => '~> 1.6', # 14-07-08: default version 2.0.0.pre is incompatible
|
38
|
+
# http://stackoverflow.com/questions/19579984/sinatra-server-wont-start-wrong-number-of-arguments
|
39
|
+
|
40
|
+
# TOASTER DEPENDENCIES
|
41
|
+
'hashdiff' => '>= 0', # diff hashes
|
42
|
+
'json' => '>= 0',
|
43
|
+
'aquarium' => '>= 0',
|
44
|
+
'jsonpath' => '>= 0',
|
45
|
+
'open4' => '>= 0', # open processes with stdin/stdout
|
46
|
+
'chef' => '>= 0',
|
47
|
+
'ohai' => '>= 0',
|
48
|
+
'rspec' => '>= 0', # tests
|
49
|
+
'ruby_parser' => '>= 0', # parse Ruby code
|
50
|
+
'bson' => '>= 0',
|
51
|
+
'bson_ext' => '>= 0',
|
52
|
+
'logger' => '>= 0',
|
53
|
+
'thor' => '>= 0', # CLI generator
|
54
|
+
'tidy' => '>= 0', # tidy XML library
|
55
|
+
'diffy' => '>= 0', # comparing source files
|
56
|
+
'mysql2' => '>= 0', # for DB access
|
57
|
+
'therubyracer' => '>= 0', # required by execjs
|
58
|
+
'railties' => '>= 0',
|
59
|
+
'activesupport' => '>= 0',
|
60
|
+
'activerecord' => '>= 0'
|
61
|
+
}
|
62
|
+
|
63
|
+
#deps = File.read('Gemfile').scan(/^\s*gem\s*['"]([^'"]+)['"]/).uniq
|
64
|
+
|
65
|
+
deps.each do |dep,version|
|
66
|
+
#dep = matched_dep[0]
|
67
|
+
#version = matched_dep[2]
|
68
|
+
#puts "#{dep} - #{version}"
|
69
|
+
if version && !version.empty?
|
70
|
+
#s.add_runtime_dependency dep, version
|
71
|
+
s.add_development_dependency dep, version
|
72
|
+
else
|
73
|
+
#s.add_runtime_dependency dep
|
74
|
+
s.add_development_dependency dep
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
# further project dependencies:
|
80
|
+
# * MySQL server
|
81
|
+
# * Squid proxy server # License: GNU GPL v2.0
|
82
|
+
# * docker.io # License: Apache v2.0
|
83
|
+
# * strace # License: BSD
|
84
|
+
|
85
|
+
|
86
|
+
s.homepage = %q{https://github.com/whummer/toaster}
|
87
|
+
s.licenses = [%q{Apache v2.0}]
|
88
|
+
s.require_paths = [%q{lib}]
|
89
|
+
s.rubygems_version = %q{1.8.9}
|
90
|
+
s.summary = %q{Automated Testing/Debugging of Automation Scripts.}
|
91
|
+
s.executables << "toaster"
|
92
|
+
|
93
|
+
end
|
94
|
+
|
data/config.json
CHANGED
@@ -19,10 +19,12 @@
|
|
19
19
|
|
20
20
|
"testing": {
|
21
21
|
"timeservice_url" : "http://www.infosys.tuwien.ac.at/staff/hummer/tmp/time.php",
|
22
|
-
"test_hosts" : ["localhost"]
|
22
|
+
"test_hosts" : ["localhost"],
|
23
|
+
"max_threads" : 8
|
23
24
|
},
|
24
25
|
"db": {
|
25
26
|
"host": "localhost",
|
27
|
+
"host_from_container": "192.168.100.2",
|
26
28
|
"port": 3306,
|
27
29
|
"database": "toaster",
|
28
30
|
"username": "root",
|
data/lib/toaster/api.rb
CHANGED
@@ -182,14 +182,14 @@ module Toaster
|
|
182
182
|
else
|
183
183
|
puts "INFO: Running/continuing tests for test suite '#{test_suite_uuid}'"
|
184
184
|
test_suite = test_suites[0]
|
185
|
-
test_suite.coverage_goal.idempotence = idem_N if idem_N
|
186
|
-
test_suite.coverage_goal.combinations[Toaster::CombinationCoverage::SKIP_N] = skip_N if skip_N
|
187
|
-
test_suite.coverage_goal.combinations[Toaster::CombinationCoverage::SKIP_N_SUCCESSIVE] = skip_N_succ if skip_N_succ
|
188
|
-
test_suite.coverage_goal.combinations[Toaster::CombinationCoverage::COMBINE_N] = combine_N if combine_N
|
189
|
-
test_suite.coverage_goal.combinations[Toaster::CombinationCoverage::COMBINE_N_SUCCESSIVE] = combine_N_succ if combine_N_succ
|
190
|
-
test_suite.save()
|
185
|
+
# test_suite.coverage_goal.idempotence = idem_N if idem_N
|
186
|
+
# test_suite.coverage_goal.combinations[Toaster::CombinationCoverage::SKIP_N] = skip_N if skip_N
|
187
|
+
# test_suite.coverage_goal.combinations[Toaster::CombinationCoverage::SKIP_N_SUCCESSIVE] = skip_N_succ if skip_N_succ
|
188
|
+
# test_suite.coverage_goal.combinations[Toaster::CombinationCoverage::COMBINE_N] = combine_N if combine_N
|
189
|
+
# test_suite.coverage_goal.combinations[Toaster::CombinationCoverage::COMBINE_N_SUCCESSIVE] = combine_N_succ if combine_N_succ
|
190
|
+
# test_suite.save()
|
191
191
|
orch = Toaster::TestOrchestrator.new
|
192
|
-
orch.generate_tests_for_suite(test_suite)
|
192
|
+
# orch.generate_tests_for_suite(test_suite)
|
193
193
|
if Config.get("testing.test_hosts").kind_of?(Array)
|
194
194
|
Config.get("testing.test_hosts").each do |test_host|
|
195
195
|
orch.add_host(test_host)
|
@@ -264,7 +264,7 @@ module Toaster
|
|
264
264
|
require "toaster/toaster_app_service"
|
265
265
|
ToasterAppService.start_service()
|
266
266
|
end
|
267
|
-
|
267
|
+
|
268
268
|
# Clean spawned containers
|
269
269
|
desc "clean", "Clean all spawned containers (prototypes will be preserved)."
|
270
270
|
def clean()
|
@@ -272,15 +272,25 @@ module Toaster
|
|
272
272
|
Toaster::LXC.clean()
|
273
273
|
end
|
274
274
|
|
275
|
+
# Print version information
|
276
|
+
desc "version", "Print version of ToASTER."
|
277
|
+
def version()
|
278
|
+
file = File.join(File.dirname(__FILE__), "..", "..", "VERSION")
|
279
|
+
version = File.read(file)
|
280
|
+
puts version
|
281
|
+
return "#{version}".strip
|
282
|
+
end
|
283
|
+
|
275
284
|
# Start web app
|
276
285
|
desc "web", "Start the Web application. (params: --detached=false)"
|
277
|
-
|
286
|
+
option :detached, :type => :boolean, :aliases => ["-d"]
|
278
287
|
def web(detached=false)
|
279
288
|
puts "INFO: Starting Web application on port 8080"
|
280
289
|
dir = File.join(File.dirname(__FILE__), "..", "..")
|
281
290
|
cmd = "cd \"#{dir}\" && #{dir}/webapp/bin/rails server thin"
|
291
|
+
detached ||= options[:detached]
|
282
292
|
if detached
|
283
|
-
Kernel::exec("screen -d -m #{cmd}")
|
293
|
+
Kernel::exec("screen -d -m bash -c '#{cmd}'")
|
284
294
|
else
|
285
295
|
Kernel::exec("#{cmd}")
|
286
296
|
end
|
@@ -305,8 +315,7 @@ module Toaster
|
|
305
315
|
test_case_uuids = test_case_uuid.split(/[ ;,]+/)
|
306
316
|
test_cases = TestCase.find(:uuid => test_case_uuids[0]).to_a
|
307
317
|
if !test_cases || test_cases.empty?
|
308
|
-
puts "ERROR: Invalid test case id(s) specified: '#{test_case_uuid}'"
|
309
|
-
puts "database: #{Toaster::Config.get("db.host")}"
|
318
|
+
puts "ERROR: Invalid test case id(s) specified: '#{test_case_uuid}' (DB host: #{Toaster::Config.get("db.host")})"
|
310
319
|
else
|
311
320
|
|
312
321
|
# set the start time of all test cases. This is important
|
@@ -328,15 +337,8 @@ module Toaster
|
|
328
337
|
TestRunner.execute_test(test_case, destroy_container, print_output)
|
329
338
|
else
|
330
339
|
puts "INFO: Scheduling test cases #{test_case_uuids} for test suite uuid '#{test_suite_uuid}'"
|
331
|
-
|
332
|
-
|
333
|
-
runner.schedule_tests(test_suite, test_case_uuids)
|
334
|
-
else
|
335
|
-
runner = TestRunner.new(test_suite, num_threads, true)
|
336
|
-
runner.schedule_tests(test_suite, test_case_uuids)
|
337
|
-
runner.start_worker_threads()
|
338
|
-
$test_runners[test_suite_uuid] = runner
|
339
|
-
end
|
340
|
+
runner = TestRunner.instance
|
341
|
+
runner.schedule_tests(test_suite, test_case_uuids)
|
340
342
|
end
|
341
343
|
end
|
342
344
|
end
|
@@ -366,8 +368,9 @@ module Toaster
|
|
366
368
|
EOF
|
367
369
|
)
|
368
370
|
end
|
369
|
-
puts "INFO: Running Chef scripts..."
|
370
371
|
require "toaster/chef/chef_util"
|
372
|
+
Toaster::ChefUtil.create_chef_config(CHEF_TMP_SOLO_FILE)
|
373
|
+
puts "INFO: Running Chef scripts..."
|
371
374
|
Toaster::ChefUtil.run_chef(CHEF_TMP_SOLO_FILE, CHEF_TMP_NODE_FILE, print_output)
|
372
375
|
end
|
373
376
|
def parse_recipes(arg)
|
@@ -148,9 +148,9 @@ module Toaster
|
|
148
148
|
# try to retrieve automation from DB, if it exists..
|
149
149
|
if File.exist?(json_file)
|
150
150
|
attribs = JSON.parse(File.read(json_file))
|
151
|
-
if attribs["automation_uuid"]
|
151
|
+
if attribs["toaster"] && attribs["toaster"]["automation_uuid"]
|
152
152
|
autos = Toaster::Automation.find(
|
153
|
-
:uuid => attribs["automation_uuid"]).to_a
|
153
|
+
:uuid => attribs["toaster"]["automation_uuid"]).to_a
|
154
154
|
if !autos.empty?
|
155
155
|
run.automation = autos[0]
|
156
156
|
return
|
@@ -432,7 +432,7 @@ module Toaster
|
|
432
432
|
end
|
433
433
|
end
|
434
434
|
task = get_task_from_sourcecode_line(resource, action, source_line_spec)
|
435
|
-
puts "get task #{resource} #{action} #{source_line_spec}: #{task}"
|
435
|
+
#puts "get task #{resource} #{action} #{source_line_spec}: #{task}"
|
436
436
|
end
|
437
437
|
|
438
438
|
# check if we execute within an "immediate notification"
|
@@ -110,7 +110,8 @@ module Toaster
|
|
110
110
|
public
|
111
111
|
|
112
112
|
# * chef_paths - Chef dirs on local filesystem
|
113
|
-
def initialize(chef_paths
|
113
|
+
def initialize(chef_paths = [ChefUtil.DEFAULT_OPSCODE_TMP_DIR,
|
114
|
+
ChefUtil.DEFAULT_COOKBOOKS_DIR], processor = nil, &error_reporting)
|
114
115
|
@chef_paths = chef_paths
|
115
116
|
@processor = processor
|
116
117
|
raise "Invalid 'error_reporting'" if error_reporting.nil?
|
@@ -125,10 +126,11 @@ module Toaster
|
|
125
126
|
return {}
|
126
127
|
end
|
127
128
|
|
128
|
-
|
129
|
+
file_name = cookbook_name + "/attributes/#{recipe_name}.rb"
|
130
|
+
default_file = get_filename(file_name)
|
129
131
|
|
130
132
|
if default_file.nil?
|
131
|
-
@error_reporting.call(Logger::INFO, "Unknown
|
133
|
+
@error_reporting.call(Logger::INFO, "Unknown attribute file '#{file_name.inspect}'")
|
132
134
|
return {}
|
133
135
|
end
|
134
136
|
|
@@ -156,7 +158,7 @@ module Toaster
|
|
156
158
|
end
|
157
159
|
|
158
160
|
# No such file
|
159
|
-
@@logger.info "File not found '#{filename}'"
|
161
|
+
@@logger.info "File not found '#{filename}' in paths #{@chef_paths}"
|
160
162
|
return nil
|
161
163
|
end
|
162
164
|
|
@@ -43,6 +43,17 @@ module Toaster
|
|
43
43
|
|
44
44
|
@@DEFAULT_CHEF_DIR = "/tmp/toaster_cookbooks/"
|
45
45
|
@@DEFAULT_COOKBOOKS_DIR = "#{@@DEFAULT_CHEF_DIR}/cookbooks/"
|
46
|
+
@@DEFAULT_OPSCODE_TMP_DIR = "/tmp/opscode_cookbooks/" # TODO merge with above?
|
47
|
+
|
48
|
+
def self.DEFAULT_CHEF_DIR
|
49
|
+
@@DEFAULT_CHEF_DIR
|
50
|
+
end
|
51
|
+
def self.DEFAULT_COOKBOOKS_DIR
|
52
|
+
@@DEFAULT_COOKBOOKS_DIR
|
53
|
+
end
|
54
|
+
def self.DEFAULT_OPSCODE_TMP_DIR
|
55
|
+
@@DEFAULT_OPSCODE_TMP_DIR
|
56
|
+
end
|
46
57
|
|
47
58
|
def self.guess_cookbook_from_runlist(runlist)
|
48
59
|
guess_cookbook_or_recipe_from_runlist(runlist, "cookbook")
|
@@ -322,7 +333,7 @@ module Toaster
|
|
322
333
|
|
323
334
|
cookbooks_after = Dir.entries(target_dir)
|
324
335
|
new_cb = cookbooks_after - cookbooks_before
|
325
|
-
puts "INFO: Downloaded and installed new cookbooks: #{new_cb}"
|
336
|
+
puts "INFO: Downloaded and installed new cookbooks: #{new_cb}" if !new_cb.empty?
|
326
337
|
|
327
338
|
# download dependencies
|
328
339
|
new_cb.each do |cb|
|
@@ -591,7 +602,7 @@ module Toaster
|
|
591
602
|
end
|
592
603
|
|
593
604
|
def self.available_recipes_from_opscode(cookbook_name, version="latest",
|
594
|
-
overwrite_downloads=false, target_dir
|
605
|
+
overwrite_downloads=false, target_dir=@@DEFAULT_OPSCODE_TMP_DIR)
|
595
606
|
if target_dir
|
596
607
|
FileUtils.mkpath(target_dir) if !File.directory?(target_dir)
|
597
608
|
# check if cookbook folder already exists
|
@@ -699,6 +710,12 @@ module Toaster
|
|
699
710
|
url = "#{OPSCODE_API_URL}cookbooks/#{cookbook_name}/"
|
700
711
|
json = `curl '#{url}' 2> /dev/null`
|
701
712
|
details = MarkupUtil.parse_json(json.strip)
|
713
|
+
if !details['latest_version']
|
714
|
+
if details['error_code']
|
715
|
+
raise "WARN: Unable to fetch cookbook metadata from #{url}: " +
|
716
|
+
"#{details['error_code']} - #{details['error_messages']}"
|
717
|
+
end
|
718
|
+
end
|
702
719
|
latest_version = details['latest_version'].gsub(/.*\/([^\/]+)/, '\1')
|
703
720
|
cbook['_latest_version'] = latest_version
|
704
721
|
versions = []
|
@@ -747,7 +764,7 @@ module Toaster
|
|
747
764
|
fetch_cookbook_details(cookbook_name)["_versions"].uniq
|
748
765
|
end
|
749
766
|
|
750
|
-
def self.download_all_from_opscode(target_dir
|
767
|
+
def self.download_all_from_opscode(target_dir=@@DEFAULT_OPSCODE_TMP_DIR, overwrite_downloads=false)
|
751
768
|
target_dir = "/tmp/opscode_cookbooks/" if !target_dir
|
752
769
|
if overwrite_downloads || !File.exist?(target_dir)
|
753
770
|
`mkdir -p "#{target_dir}"`
|
@@ -760,7 +777,8 @@ module Toaster
|
|
760
777
|
end
|
761
778
|
end
|
762
779
|
|
763
|
-
def self.parse_resources(cookbook, recipe_name, version="latest",
|
780
|
+
def self.parse_resources(cookbook, recipe_name, version="latest",
|
781
|
+
result = {}, cookbook_dir=@@DEFAULT_OPSCODE_TMP_DIR)
|
764
782
|
recipe_file = "#{cookbook_dir}/#{cookbook}/recipes/#{recipe_name}.rb"
|
765
783
|
attributes_file = "#{cookbook_dir}/#{cookbook}/attributes/#{recipe_name}.rb"
|
766
784
|
recipe_file_relative = "#{cookbook}/recipes/#{recipe_name}.rb"
|
@@ -795,7 +813,7 @@ module Toaster
|
|
795
813
|
|
796
814
|
File.open(recipe_file) do |io|
|
797
815
|
io.each_with_index { |line,idx|
|
798
|
-
#
|
816
|
+
idx += 1 # index is 0-based, line should be 1-based
|
799
817
|
if line.match(/^(\s*[0-9a-zA-Z_]+\s*=\s*)?\s*((#{resource_names.join(")|(")}))((\s+)|($)|(\s*\())/)
|
800
818
|
resource_lines << idx
|
801
819
|
elsif line.match(/execute.*do/) && !line.match(/^\s*#/)
|
@@ -803,9 +821,9 @@ module Toaster
|
|
803
821
|
end
|
804
822
|
}
|
805
823
|
resource_lines.each do |line|
|
806
|
-
code = read_sourcecode_from_line(recipe_file, line
|
824
|
+
code = read_sourcecode_from_line(recipe_file, line)
|
807
825
|
if !code
|
808
|
-
puts "WARN: Could not parse code file #{recipe_file} : #{line
|
826
|
+
puts "WARN: Could not parse code file #{recipe_file} : #{line}"
|
809
827
|
else
|
810
828
|
resource_obj = ResourceInspector.get_resource_from_source(code, attributes_source)
|
811
829
|
result[cookbook][recipe_name]["resources"][line] = code
|
@@ -822,7 +840,7 @@ module Toaster
|
|
822
840
|
return result
|
823
841
|
end
|
824
842
|
|
825
|
-
def self.parse_all_resources(recipe_pattern="default.rb", cookbook_dir
|
843
|
+
def self.parse_all_resources(recipe_pattern="default.rb", cookbook_dir=@@DEFAULT_OPSCODE_TMP_DIR)
|
826
844
|
# cookbook_name -> recipe_file -> line_no -> resource_code
|
827
845
|
result = {}
|
828
846
|
scanned_files = 0
|