cloud-toaster 1.1.5 → 1.1.6
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.
- 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
|