jamie 0.1.0.alpha20 → 0.1.0.alpha21

Sign up to get free protection for your applications and to get access to all the features.
data/jamie.gemspec CHANGED
@@ -6,6 +6,7 @@ require 'jamie/version'
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "jamie"
8
8
  gem.version = Jamie::VERSION
9
+ gem.license = 'Apache 2.0'
9
10
  gem.authors = ["Fletcher Nichol"]
10
11
  gem.email = ["fnichol@nichol.ca"]
11
12
  gem.description = %q{A Chef convergence integration test harness}
data/lib/jamie/cli.rb CHANGED
@@ -16,6 +16,7 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
+ require 'benchmark'
19
20
  require 'ostruct'
20
21
  require 'thor'
21
22
 
@@ -29,6 +30,7 @@ module Jamie
29
30
  class CLI < Thor
30
31
 
31
32
  include Thor::Actions
33
+ include Logging
32
34
 
33
35
  # Constructs a new instance.
34
36
  def initialize(*args)
@@ -64,12 +66,16 @@ module Jamie
64
66
  method_option :destroy, :aliases => "-d", :default => "passing",
65
67
  :desc => "Destroy strategy to use after testing (passing, always, never)."
66
68
  def test(*args)
67
- destroy_mode = options[:destroy]
68
- if ! %w{passing always never}.include?(options[:destroy])
69
- raise ArgumentError, "Destroy mode must be passing, always, or never."
69
+ banner "Starting Jamie"
70
+ elapsed = Benchmark.measure do
71
+ destroy_mode = options[:destroy]
72
+ if ! %w{passing always never}.include?(options[:destroy])
73
+ raise ArgumentError, "Destroy mode must be passing, always, or never."
74
+ end
75
+ result = parse_subcommand(args.first)
76
+ Array(result).each { |instance| instance.test(destroy_mode.to_sym) }
70
77
  end
71
- result = parse_subcommand(args.first)
72
- Array(result).each { |instance| instance.test(destroy_mode.to_sym) }
78
+ banner "Jamie is finished. (#{elapsed.real} seconds)"
73
79
  end
74
80
 
75
81
  desc "login (['REGEX']|[INSTANCE])", "Log in to one instance"
@@ -118,10 +124,18 @@ module Jamie
118
124
 
119
125
  attr_reader :task
120
126
 
127
+ def logger
128
+ Jamie.logger
129
+ end
130
+
121
131
  def exec_action(action)
122
- @task = action
123
- result = parse_subcommand(args.first)
124
- Array(result).each { |instance| instance.send(task) }
132
+ banner "Starting Jamie"
133
+ elapsed = Benchmark.measure do
134
+ @task = action
135
+ result = parse_subcommand(args.first)
136
+ Array(result).each { |instance| instance.send(task) }
137
+ end
138
+ banner "Jamie is finished. (#{elapsed.real} seconds)"
125
139
  end
126
140
 
127
141
  def parse_subcommand(arg = nil)
@@ -27,10 +27,11 @@ module Jamie
27
27
  # @author Fletcher Nichol <fnichol@nichol.ca>
28
28
  class Dummy < Jamie::Driver::Base
29
29
 
30
- default_config 'sleep', 0
30
+ default_config :sleep, 0
31
+ default_config :random_failure, false
31
32
 
32
33
  def create(state)
33
- state['my_id'] = "#{instance.name}-#{Time.now.to_i}"
34
+ state[:my_id] = "#{instance.name}-#{Time.now.to_i}"
34
35
  report(:create, state)
35
36
  end
36
37
 
@@ -48,7 +49,7 @@ module Jamie
48
49
 
49
50
  def destroy(state)
50
51
  report(:destroy, state)
51
- state.delete('my_id')
52
+ state.delete(:my_id)
52
53
  end
53
54
 
54
55
  private
@@ -56,8 +57,12 @@ module Jamie
56
57
  def report(action, state)
57
58
  info("[Dummy] Action ##{action} called on " +
58
59
  "instance=#{instance} with state=#{state}")
59
- sleep(config['sleep'].to_f) if config['sleep'].to_f > 0.0
60
- debug("[Dummy] Action ##{action} completed (#{config['sleep']}s).")
60
+ sleep(config[:sleep].to_f) if config[:sleep].to_f > 0.0
61
+ if config[:random_failure] && [true, false].sample
62
+ debug("[Dummy] Random failure for action ##{action}.")
63
+ raise ActionFailed, "Action ##{action} failed for #{instance.to_str}."
64
+ end
65
+ debug("[Dummy] Action ##{action} completed (#{config[:sleep]}s).")
61
66
  end
62
67
  end
63
68
  end
data/lib/jamie/version.rb CHANGED
@@ -18,5 +18,5 @@
18
18
 
19
19
  module Jamie
20
20
 
21
- VERSION = "0.1.0.alpha20"
21
+ VERSION = "0.1.0.alpha21"
22
22
  end
data/lib/jamie.rb CHANGED
@@ -88,14 +88,14 @@ module Jamie
88
88
  # convergence integration
89
89
  def platforms
90
90
  @platforms ||= Collection.new(
91
- Array(yaml["platforms"]).map { |hash| new_platform(hash) })
91
+ Array(yaml[:platforms]).map { |hash| new_platform(hash) })
92
92
  end
93
93
 
94
94
  # @return [Array<Suite>] all defined suites which will be used in
95
95
  # convergence integration
96
96
  def suites
97
97
  @suites ||= Collection.new(
98
- Array(yaml["suites"]).map { |hash| new_suite(hash) })
98
+ Array(yaml[:suites]).map { |hash| new_suite(hash) })
99
99
  end
100
100
 
101
101
  # @return [Array<Instance>] all instances, resulting from all platform and
@@ -163,12 +163,11 @@ module Jamie
163
163
  private
164
164
 
165
165
  def new_suite(hash)
166
- data_bags_path = calculate_data_bags_path(hash['name'])
167
- roles_path = calculate_roles_path(hash['name'])
168
166
  path_hash = {
169
- 'data_bags_path' => data_bags_path,
170
- 'roles_path' => roles_path
167
+ :data_bags_path => calculate_path("data_bags", hash[:name]),
168
+ :roles_path => calculate_path("roles", hash[:name]),
171
169
  }
170
+
172
171
  Suite.new(hash.rmerge(path_hash))
173
172
  end
174
173
 
@@ -177,9 +176,10 @@ module Jamie
177
176
  end
178
177
 
179
178
  def new_driver(hash)
180
- hash['driver_config'] ||= Hash.new
181
- hash['driver_config']['jamie_root'] = jamie_root
182
- Driver.for_plugin(hash['driver_plugin'], hash['driver_config'])
179
+ hash[:driver_config] ||= Hash.new
180
+ hash[:driver_config][:jamie_root] = jamie_root
181
+
182
+ Driver.for_plugin(hash[:driver_plugin], hash[:driver_config])
183
183
  end
184
184
 
185
185
  def new_instance(suite, platform)
@@ -189,18 +189,18 @@ module Jamie
189
189
  FileUtils.mkdir_p(log_root)
190
190
 
191
191
  Instance.new(
192
- 'suite' => suite,
193
- 'platform' => platform,
194
- 'driver' => driver,
195
- 'jr' => Jr.new(suite.name),
196
- 'logger' => new_instance_logger(log_root)
192
+ :suite => suite,
193
+ :platform => platform,
194
+ :driver => driver,
195
+ :jr => Jr.new(suite.name),
196
+ :logger => new_instance_logger(log_root)
197
197
  )
198
198
  end
199
199
 
200
200
  def platform_driver_hash(platform_name)
201
- h = yaml['platforms'].find { |p| p['name'] == platform_name } || Hash.new
201
+ h = yaml[:platforms].find { |p| p[:name] == platform_name } || Hash.new
202
202
 
203
- h.select { |key, value| %w(driver_plugin driver_config).include?(key) }
203
+ h.select { |key, value| [ :driver_plugin, :driver_config ].include?(key) }
204
204
  end
205
205
 
206
206
  def new_instance_logger(log_root)
@@ -215,7 +215,8 @@ module Jamie
215
215
  end
216
216
 
217
217
  def yaml
218
- @yaml ||= YAML.load(yaml_contents).rmerge(local_yaml)
218
+ @yaml ||= Util.symbolized_hash(
219
+ YAML.load(yaml_contents).rmerge(local_yaml))
219
220
  end
220
221
 
221
222
  def yaml_contents
@@ -245,44 +246,30 @@ module Jamie
245
246
  default_driver_hash.rmerge(common_driver_hash.rmerge(driver_hash))
246
247
  end
247
248
 
248
- def calculate_roles_path(suite_name)
249
- suite_roles_path = File.join(test_base_path, suite_name, "roles")
250
- common_roles_path = File.join(test_base_path, "roles")
251
- top_level_roles_path = File.join(Dir.pwd, "roles")
252
-
253
- if File.directory?(suite_roles_path)
254
- suite_roles_path
255
- elsif File.directory?(common_roles_path)
256
- common_roles_path
257
- elsif File.directory?(top_level_roles_path)
258
- top_level_roles_path
259
- else
260
- nil
261
- end
262
- end
263
-
264
- def calculate_data_bags_path(suite_name)
265
- suite_data_bags_path = File.join(test_base_path, suite_name, "data_bags")
266
- common_data_bags_path = File.join(test_base_path, "data_bags")
267
- top_level_data_bags_path = File.join(Dir.pwd, "data_bags")
249
+ def calculate_path(path, suite_name)
250
+ suite_path = File.join(test_base_path, suite_name, path)
251
+ common_path = File.join(test_base_path, path)
252
+ top_level_path = File.join(Dir.pwd, path)
268
253
 
269
- if File.directory?(suite_data_bags_path)
270
- suite_data_bags_path
271
- elsif File.directory?(common_data_bags_path)
272
- common_data_bags_path
273
- elsif File.directory?(top_level_data_bags_path)
274
- top_level_data_bags_path
254
+ if File.directory?(suite_path)
255
+ suite_path
256
+ elsif File.directory?(common_path)
257
+ common_path
258
+ elsif File.directory?(top_level_path)
259
+ top_level_path
275
260
  else
276
261
  nil
277
262
  end
278
263
  end
279
264
 
280
265
  def default_driver_hash
281
- { 'driver_plugin' => DEFAULT_DRIVER_PLUGIN, 'driver_config' => {} }
266
+ { :driver_plugin => DEFAULT_DRIVER_PLUGIN, :driver_config => {} }
282
267
  end
283
268
 
284
269
  def common_driver_hash
285
- yaml.select { |key, value| %w(driver_plugin driver_config).include?(key) }
270
+ yaml.select do |key, value|
271
+ [ :driver_plugin, :driver_config ].include?(key)
272
+ end
286
273
  end
287
274
  end
288
275
 
@@ -445,20 +432,21 @@ module Jamie
445
432
  # (**Required**)
446
433
  # @option options [Hash] :attributes Hash of Chef node attributes
447
434
  # @option options [String] :data_bags_path path to data bags
435
+ # @option options [String] :roles_path path to roles
448
436
  def initialize(options = {})
449
437
  validate_options(options)
450
438
 
451
- @name = options['name']
452
- @run_list = options['run_list']
453
- @attributes = options['attributes'] || Hash.new
454
- @data_bags_path = options['data_bags_path']
455
- @roles_path = options['roles_path']
439
+ @name = options[:name]
440
+ @run_list = options[:run_list]
441
+ @attributes = options[:attributes] || Hash.new
442
+ @data_bags_path = options[:data_bags_path]
443
+ @roles_path = options[:roles_path]
456
444
  end
457
445
 
458
446
  private
459
447
 
460
448
  def validate_options(opts)
461
- %w(name run_list).each do |k|
449
+ [ :name, :run_list ].each do |k|
462
450
  raise ArgumentError, "Attribute '#{k}' is required." if opts[k].nil?
463
451
  end
464
452
  end
@@ -491,15 +479,15 @@ module Jamie
491
479
  def initialize(options = {})
492
480
  validate_options(options)
493
481
 
494
- @name = options['name']
495
- @run_list = Array(options['run_list'])
496
- @attributes = options['attributes'] || Hash.new
482
+ @name = options[:name]
483
+ @run_list = Array(options[:run_list])
484
+ @attributes = options[:attributes] || Hash.new
497
485
  end
498
486
 
499
487
  private
500
488
 
501
489
  def validate_options(opts)
502
- %w(name).each do |k|
490
+ [ :name ].each do |k|
503
491
  raise ArgumentError, "Attribute '#{k}' is required." if opts[k].nil?
504
492
  end
505
493
  end
@@ -539,14 +527,14 @@ module Jamie
539
527
  # @option options [Jr] :jr the jr command string generator
540
528
  # @option options [Logger] :logger the instance logger
541
529
  def initialize(options = {})
542
- options = { 'logger' => Jamie.logger }.merge(options)
530
+ options = { :logger => Jamie.logger }.merge(options)
543
531
  validate_options(options)
544
- logger = options['logger']
532
+ logger = options[:logger]
545
533
 
546
- @suite = options['suite']
547
- @platform = options['platform']
548
- @driver = options['driver']
549
- @jr = options['jr']
534
+ @suite = options[:suite]
535
+ @platform = options[:platform]
536
+ @driver = options[:driver]
537
+ @jr = options[:jr]
550
538
  @logger = logger.is_a?(Proc) ? logger.call(name) : logger
551
539
 
552
540
  @driver.instance = self
@@ -557,7 +545,7 @@ module Jamie
557
545
  "#{suite.name}-#{platform.name}".gsub(/_/, '-').gsub(/\./, '')
558
546
  end
559
547
 
560
- def to_s
548
+ def to_str
561
549
  "<#{name}>"
562
550
  end
563
551
 
@@ -578,7 +566,7 @@ module Jamie
578
566
  end
579
567
 
580
568
  def dna
581
- attributes.rmerge({ 'run_list' => run_list })
569
+ attributes.rmerge({ :run_list => run_list })
582
570
  end
583
571
 
584
572
  # Creates this instance.
@@ -648,13 +636,13 @@ module Jamie
648
636
  # to gracfully stop action chaining
649
637
  def test(destroy_mode = :passing)
650
638
  elapsed = Benchmark.measure do
651
- banner "Cleaning up any prior instances of #{self}"
639
+ banner "Cleaning up any prior instances of #{to_str}"
652
640
  destroy
653
- banner "Testing #{self}"
641
+ banner "Testing #{to_str}"
654
642
  verify
655
643
  destroy if destroy_mode == :passing
656
644
  end
657
- info "Testing of #{self} complete (#{elapsed.real} seconds)."
645
+ info "Finished testing #{to_str} (#{elapsed.real} seconds)."
658
646
  self
659
647
  ensure
660
648
  destroy if destroy_mode == :always
@@ -677,7 +665,7 @@ module Jamie
677
665
  private
678
666
 
679
667
  def validate_options(opts)
680
- %w(suite platform driver jr logger).each do |k|
668
+ [ :suite, :platform, :driver, :jr, :logger ].each do |k|
681
669
  raise ArgumentError, "Attribute '#{k}' is required." if opts[k].nil?
682
670
  end
683
671
  end
@@ -691,38 +679,31 @@ module Jamie
691
679
  end
692
680
 
693
681
  def create_action
694
- banner "Creating #{self}"
695
- elapsed = action(:create) { |state| driver.create(state) }
696
- info "Creation of #{self} complete (#{elapsed.real} seconds)."
697
- self
682
+ perform_action(:create, "Creating")
698
683
  end
699
684
 
700
685
  def converge_action
701
- banner "Converging #{self}"
702
- elapsed = action(:converge) { |state| driver.converge(state) }
703
- info "Convergence of #{self} complete (#{elapsed.real} seconds)."
704
- self
686
+ perform_action(:converge, "Converging")
705
687
  end
706
688
 
707
689
  def setup_action
708
- banner "Setting up #{self}"
709
- elapsed = action(:setup) { |state| driver.setup(state) }
710
- info "Setup of #{self} complete (#{elapsed.real} seconds)."
711
- self
690
+ perform_action(:setup, "Setting up")
712
691
  end
713
692
 
714
693
  def verify_action
715
- banner "Verifying #{self}"
716
- elapsed = action(:verify) { |state| driver.verify(state) }
717
- info "Verification of #{self} complete (#{elapsed.real} seconds)."
718
- self
694
+ perform_action(:verify, "Verifying")
719
695
  end
720
696
 
721
697
  def destroy_action
722
- banner "Destroying #{self}"
723
- elapsed = action(:destroy) { |state| driver.destroy(state) }
724
- destroy_state
725
- info "Destruction of #{self} complete (#{elapsed.real} seconds)."
698
+ perform_action(:destroy, "Destroying") { destroy_state }
699
+ end
700
+
701
+ def perform_action(verb, output_verb)
702
+ banner "#{output_verb} #{to_str}"
703
+ elapsed = action(verb) { |state| driver.public_send(verb, state) }
704
+ info("Finished #{output_verb.downcase} #{to_str}" +
705
+ " (#{elapsed.real} seconds).")
706
+ yield if block_given?
726
707
  self
727
708
  end
728
709
 
@@ -731,14 +712,18 @@ module Jamie
731
712
  elapsed = Benchmark.measure do
732
713
  yield state if block_given?
733
714
  end
734
- state['last_action'] = what.to_s
715
+ state[:last_action] = what.to_s
735
716
  elapsed
736
717
  ensure
737
718
  dump_state(state)
738
719
  end
739
720
 
740
721
  def load_state
741
- File.exists?(statefile) ? YAML.load_file(statefile) : Hash.new
722
+ if File.exists?(statefile)
723
+ Util.symbolized_hash(YAML.load_file(statefile))
724
+ else
725
+ Hash.new
726
+ end
742
727
  end
743
728
 
744
729
  def dump_state(state)
@@ -754,12 +739,12 @@ module Jamie
754
739
 
755
740
  def statefile
756
741
  File.expand_path(File.join(
757
- driver['jamie_root'], ".jamie", "#{name}.yml"
742
+ driver[:jamie_root], ".jamie", "#{name}.yml"
758
743
  ))
759
744
  end
760
745
 
761
746
  def last_action
762
- load_state['last_action']
747
+ load_state[:last_action]
763
748
  end
764
749
 
765
750
  # The simplest finite state machine pseudo-implementation needed to manage
@@ -974,6 +959,16 @@ module Jamie
974
959
  else :fatal
975
960
  end
976
961
  end
962
+
963
+ def self.symbolized_hash(obj)
964
+ if obj.is_a?(Hash)
965
+ obj.inject({}) { |h, (k,v)| h[k.to_sym] = symbolized_hash(v) ; h }
966
+ elsif obj.is_a?(Array)
967
+ obj.inject([]) { |a, v| a << symbolized_hash(v) ; a }
968
+ else
969
+ obj
970
+ end
971
+ end
977
972
  end
978
973
 
979
974
  # Mixin that wraps a command shell out invocation, providing a #run_command
@@ -1114,7 +1109,7 @@ module Jamie
1114
1109
  end
1115
1110
 
1116
1111
  def run_command(cmd, use_sudo = nil, log_subject = nil)
1117
- use_sudo = config['use_sudo'] if use_sudo.nil?
1112
+ use_sudo = config[:use_sudo] if use_sudo.nil?
1118
1113
  log_subject = Util.to_snake_case(self.class.to_s)
1119
1114
 
1120
1115
  super(cmd, use_sudo, log_subject)
@@ -1144,7 +1139,7 @@ module Jamie
1144
1139
  def converge(state)
1145
1140
  ssh_args = build_ssh_args(state)
1146
1141
 
1147
- install_omnibus(ssh_args) if config['require_chef_omnibus']
1142
+ install_omnibus(ssh_args) if config[:require_chef_omnibus]
1148
1143
  prepare_chef_home(ssh_args)
1149
1144
  upload_chef_data(ssh_args)
1150
1145
  run_chef_solo(ssh_args)
@@ -1174,8 +1169,8 @@ module Jamie
1174
1169
  def login_command(state)
1175
1170
  args = %W{ -o UserKnownHostsFile=/dev/null }
1176
1171
  args += %W{ -o StrictHostKeyChecking=no }
1177
- args += %W{ -i #{config['ssh_key']}} if config['ssh_key']
1178
- args += %W{ #{config['username']}@#{state['hostname']}}
1172
+ args += %W{ -i #{config[:ssh_key]}} if config[:ssh_key]
1173
+ args += %W{ #{config[:username]}@#{state[:hostname]}}
1179
1174
 
1180
1175
  ["ssh", *args]
1181
1176
  end
@@ -1186,10 +1181,10 @@ module Jamie
1186
1181
  opts = Hash.new
1187
1182
  opts[:user_known_hosts_file] = "/dev/null"
1188
1183
  opts[:paranoid] = false
1189
- opts[:password] = config['password'] if config['password']
1190
- opts[:keys] = Array(config['ssh_key']) if config['ssh_key']
1184
+ opts[:password] = config[:password] if config[:password]
1185
+ opts[:keys] = Array(config[:ssh_key]) if config[:ssh_key]
1191
1186
 
1192
- [ state['hostname'], config['username'], opts ]
1187
+ [ state[:hostname], config[:username], opts ]
1193
1188
  end
1194
1189
 
1195
1190
  def chef_home
@@ -1210,7 +1205,7 @@ module Jamie
1210
1205
 
1211
1206
  def upload_chef_data(ssh_args)
1212
1207
  Jamie::ChefDataUploader.new(
1213
- instance, ssh_args, config['jamie_root'], chef_home
1208
+ instance, ssh_args, config[:jamie_root], chef_home
1214
1209
  ).upload
1215
1210
  end
1216
1211
 
@@ -1262,7 +1257,7 @@ module Jamie
1262
1257
  end
1263
1258
 
1264
1259
  def test_ssh(hostname)
1265
- socket = TCPSocket.new(hostname, config['port'])
1260
+ socket = TCPSocket.new(hostname, config[:port])
1266
1261
  IO.select([socket], nil, nil, 5)
1267
1262
  rescue SocketError, Errno::ECONNREFUSED,
1268
1263
  Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError
@@ -1321,36 +1316,25 @@ module Jamie
1321
1316
  end
1322
1317
 
1323
1318
  def upload_cookbooks(scp)
1324
- ckbks_dir = local_cookbooks
1325
- scp.upload!(ckbks_dir, "#{chef_home}/cookbooks",
1326
- :recursive => true
1327
- ) do |ch, name, sent, total|
1328
- if sent == total
1329
- info("Uploaded #{name.sub(%r{^#{ckbks_dir}/}, '')} (#{total} bytes)")
1330
- end
1331
- end
1319
+ cookbooks_dir = local_cookbooks
1320
+ upload_path(scp, cookbooks_dir, "cookbooks")
1332
1321
  ensure
1333
- FileUtils.rmtree(ckbks_dir)
1322
+ FileUtils.rmtree(cookbooks_dir)
1334
1323
  end
1335
1324
 
1336
1325
  def upload_data_bags(scp)
1337
- dbags_dir = instance.suite.data_bags_path
1338
- scp.upload!(dbags_dir, "#{chef_home}/data_bags",
1339
- :recursive => true
1340
- ) do |ch, name, sent, total|
1341
- if sent == total
1342
- info("Uploaded #{name.sub(%r{^#{dbags_dir}/}, '')} (#{total} bytes)")
1343
- end
1344
- end
1326
+ upload_path(scp, instance.suite.data_bags_path)
1345
1327
  end
1346
1328
 
1347
1329
  def upload_roles(scp)
1348
- roles_dir = instance.suite.roles_path
1349
- scp.upload!(roles_dir, "#{chef_home}/roles",
1350
- :recursive => true
1330
+ upload_path(scp, instance.suite.roles_path)
1331
+ end
1332
+
1333
+ def upload_path(scp, path, dir = File.basename(path))
1334
+ scp.upload!(path, "#{chef_home}/#{dir}", :recursive => true
1351
1335
  ) do |ch, name, sent, total|
1352
1336
  if sent == total
1353
- info("Uploaded #{name.sub(%r{^#{roles_dir}/}, '')} (#{total} bytes)")
1337
+ info("Uploaded #{name.sub(%r{^#{path}/}, '')} (#{total} bytes)")
1354
1338
  end
1355
1339
  end
1356
1340
  end
@@ -1389,7 +1373,7 @@ module Jamie
1389
1373
  def run_berks(tmpdir)
1390
1374
  begin
1391
1375
  run_command "if ! command -v berks >/dev/null; then exit 1; fi"
1392
- rescue Mixlib::ShellOut::ShellCommandFailed
1376
+ rescue Jamie::ShellOut::ShellCommandFailed
1393
1377
  abort ">>>>>> Berkshelf must be installed, add it to your Gemfile."
1394
1378
  end
1395
1379
  run_command "berks install --path #{tmpdir}"
@@ -1398,7 +1382,7 @@ module Jamie
1398
1382
  def run_librarian(tmpdir)
1399
1383
  begin
1400
1384
  run_command "if ! command -v librarian-chef >/dev/null; then exit 1; fi"
1401
- rescue Mixlib::ShellOut::ShellCommandFailed
1385
+ rescue Jamie::ShellOut::ShellCommandFailed
1402
1386
  abort ">>>>>> Librarian must be installed, add it to your Gemfile."
1403
1387
  end
1404
1388
  run_command "librarian-chef install --path #{tmpdir}"
data/spec/jamie_spec.rb CHANGED
@@ -151,7 +151,7 @@ describe Jamie::Config do
151
151
  'platforms' => [ { 'name' => 'platform', 'driver_plugin' => 'dummy' } ],
152
152
  'suites' => [ { 'name' => 'suite', 'run_list' => [] }]
153
153
  })
154
- config.instances.first.driver['jamie_root'].must_equal "/tmp"
154
+ config.instances.first.driver[:jamie_root].must_equal "/tmp"
155
155
  end
156
156
 
157
157
  it "returns an instance with a driver initialized with passed in config" do
@@ -162,7 +162,7 @@ describe Jamie::Config do
162
162
  ],
163
163
  'suites' => [ { 'name' => 'suite', 'run_list' => [] }]
164
164
  })
165
- config.instances.first.driver['foo'].must_equal "bar"
165
+ config.instances.first.driver[:foo].must_equal "bar"
166
166
  end
167
167
  end
168
168
 
@@ -176,7 +176,7 @@ describe Jamie::Config do
176
176
  stub_yaml!(".jamie.local.yml", {
177
177
  'driver_config' => { 'foo' => 'bar' }
178
178
  })
179
- config.instances.first.driver['foo'].must_equal 'bar'
179
+ config.instances.first.driver[:foo].must_equal 'bar'
180
180
  end
181
181
 
182
182
  it "merges over configuration in jamie.yml" do
@@ -188,7 +188,7 @@ describe Jamie::Config do
188
188
  stub_yaml!(".jamie.local.yml", {
189
189
  'driver_config' => { 'foo' => 'bar' }
190
190
  })
191
- config.instances.first.driver['foo'].must_equal 'bar'
191
+ config.instances.first.driver[:foo].must_equal 'bar'
192
192
  end
193
193
  end
194
194
 
@@ -222,8 +222,8 @@ describe Jamie::Config do
222
222
  <% end %>
223
223
  YAML
224
224
  end
225
- config.instances.first.driver['noodle'].must_equal "soup"
226
- config.instances.first.driver['mushroom'].must_equal "soup"
225
+ config.instances.first.driver[:noodle].must_equal "soup"
226
+ config.instances.first.driver[:mushroom].must_equal "soup"
227
227
  end
228
228
  end
229
229
 
@@ -307,16 +307,16 @@ end
307
307
 
308
308
  describe Jamie::Suite do
309
309
 
310
- let(:opts) do ; { 'name' => 'suitezy', 'run_list' => [ 'doowah' ] } ; end
310
+ let(:opts) do ; { :name => 'suitezy', :run_list => [ 'doowah' ] } ; end
311
311
  let(:suite) { Jamie::Suite.new(opts) }
312
312
 
313
313
  it "raises an ArgumentError if name is missing" do
314
- opts.delete('name')
314
+ opts.delete(:name)
315
315
  proc { Jamie::Suite.new(opts) }.must_raise ArgumentError
316
316
  end
317
317
 
318
318
  it "raises an ArgumentError if run_list is missing" do
319
- opts.delete('run_list')
319
+ opts.delete(:run_list)
320
320
  proc { Jamie::Suite.new(opts) }.must_raise ArgumentError
321
321
  end
322
322
 
@@ -333,11 +333,11 @@ describe Jamie::Suite do
333
333
  end
334
334
 
335
335
  it "returns attributes from constructor" do
336
- opts.merge!({ 'attributes' => { 'a' => 'b' }, 'data_bags_path' => 'crazy',
337
- 'roles_path' => 'town' })
336
+ opts.merge!({ :attributes => { :a => 'b' }, :data_bags_path => 'crazy',
337
+ :roles_path => 'town' })
338
338
  suite.name.must_equal 'suitezy'
339
339
  suite.run_list.must_equal [ 'doowah' ]
340
- suite.attributes.must_equal({ 'a' => 'b' })
340
+ suite.attributes.must_equal({ :a => 'b' })
341
341
  suite.data_bags_path.must_equal 'crazy'
342
342
  suite.roles_path.must_equal 'town'
343
343
  end
@@ -345,11 +345,11 @@ end
345
345
 
346
346
  describe Jamie::Platform do
347
347
 
348
- let(:opts) do ; { 'name' => 'plata' } ; end
348
+ let(:opts) do ; { :name => 'plata' } ; end
349
349
  let(:platform) { Jamie::Platform.new(opts) }
350
350
 
351
351
  it "raises an ArgumentError if name is missing" do
352
- opts.delete('name')
352
+ opts.delete(:name)
353
353
  proc { Jamie::Platform.new(opts) }.must_raise ArgumentError
354
354
  end
355
355
 
@@ -362,23 +362,23 @@ describe Jamie::Platform do
362
362
  end
363
363
 
364
364
  it "returns attributes from constructor" do
365
- opts.merge!({ 'run_list' => [ 'a', 'b' ], 'attributes' => { 'c' => 'd' }})
365
+ opts.merge!({ :run_list => [ 'a', 'b' ], :attributes => { :c => 'd' }})
366
366
  platform.name.must_equal 'plata'
367
367
  platform.run_list.must_equal [ 'a', 'b' ]
368
- platform.attributes.must_equal({ 'c' => 'd' })
368
+ platform.attributes.must_equal({ :c => 'd' })
369
369
  end
370
370
  end
371
371
 
372
372
  describe Jamie::Instance do
373
373
 
374
374
  let(:suite) do
375
- Jamie::Suite.new({ 'name' => 'suite',
376
- 'run_list' => 'suite_list', 'attributes' => { 's' => 'ss' } })
375
+ Jamie::Suite.new({ :name => 'suite',
376
+ :run_list => 'suite_list', :attributes => { :s => 'ss' } })
377
377
  end
378
378
 
379
379
  let(:platform) do
380
- Jamie::Platform.new({ 'name' => 'platform',
381
- 'run_list' => 'platform_list', 'attributes' => { 'p' => 'pp' } })
380
+ Jamie::Platform.new({ :name => 'platform',
381
+ :run_list => 'platform_list', :attributes => { :p => 'pp' } })
382
382
  end
383
383
 
384
384
  let(:driver) { Jamie::Driver::Dummy.new({}) }
@@ -386,18 +386,18 @@ describe Jamie::Instance do
386
386
  let(:jr) { Jamie::Jr.new(suite.name) }
387
387
 
388
388
  let(:opts) do
389
- { 'suite' => suite, 'platform' => platform, 'driver' => driver, 'jr' => jr }
389
+ { :suite => suite, :platform => platform, :driver => driver, :jr => jr }
390
390
  end
391
391
 
392
392
  let(:instance) { Jamie::Instance.new(opts) }
393
393
 
394
394
  it "raises an ArgumentError if suite is missing" do
395
- opts.delete('suite')
395
+ opts.delete(:suite)
396
396
  proc { Jamie::Instance.new(opts) }.must_raise ArgumentError
397
397
  end
398
398
 
399
399
  it "raises an ArgumentError if platform is missing" do
400
- opts.delete('platform')
400
+ opts.delete(:platform)
401
401
  proc { Jamie::Instance.new(opts) }.must_raise ArgumentError
402
402
  end
403
403
 
@@ -416,11 +416,11 @@ describe Jamie::Instance do
416
416
  describe "#name" do
417
417
 
418
418
  def combo(suite_name, platform_name)
419
- opts['suite'] = Jamie::Suite.new(
420
- 'name' => suite_name, 'run_list' => []
419
+ opts[:suite] = Jamie::Suite.new(
420
+ :name => suite_name, :run_list => []
421
421
  )
422
- opts['platform'] = Jamie::Platform.new(
423
- 'name' => platform_name
422
+ opts[:platform] = Jamie::Platform.new(
423
+ :name => platform_name
424
424
  )
425
425
  Jamie::Instance.new(opts)
426
426
  end
@@ -445,11 +445,11 @@ describe Jamie::Instance do
445
445
  describe "#run_list" do
446
446
 
447
447
  def combo(suite_list, platform_list)
448
- opts['suite'] = Jamie::Suite.new(
449
- 'name' => 'suite', 'run_list' => suite_list
448
+ opts[:suite] = Jamie::Suite.new(
449
+ :name => 'suite', :run_list => suite_list
450
450
  )
451
- opts['platform'] = Jamie::Platform.new(
452
- 'name' => 'platform', 'run_list' => platform_list
451
+ opts[:platform] = Jamie::Platform.new(
452
+ :name => 'platform', :run_list => platform_list
453
453
  )
454
454
  Jamie::Instance.new(opts)
455
455
  end
@@ -470,37 +470,37 @@ describe Jamie::Instance do
470
470
  describe "#attributes" do
471
471
 
472
472
  def combo(suite_attrs, platform_attrs)
473
- opts['suite'] = Jamie::Suite.new(
474
- 'name' => 'suite', 'run_list' => [], 'attributes' => suite_attrs
473
+ opts[:suite] = Jamie::Suite.new(
474
+ :name => 'suite', :run_list => [], :attributes => suite_attrs
475
475
  )
476
- opts['platform'] = Jamie::Platform.new(
477
- 'name' => 'platform', 'attributes' => platform_attrs
476
+ opts[:platform] = Jamie::Platform.new(
477
+ :name => 'platform', :attributes => platform_attrs
478
478
  )
479
479
  Jamie::Instance.new(opts)
480
480
  end
481
481
 
482
482
  it "merges suite and platform hashes together" do
483
483
  combo(
484
- { 'suite' => { 's1' => 'sv1' } },
485
- { 'suite' => { 'p1' => 'pv1' }, 'platform' => 'pp' }
484
+ { :suite => { :s1 => 'sv1' } },
485
+ { :suite => { :p1 => 'pv1' }, :platform => 'pp' }
486
486
  ).attributes.must_equal({
487
- 'suite' => { 's1' => 'sv1', 'p1' => 'pv1' },
488
- 'platform' => 'pp'
487
+ :suite => { :s1 => 'sv1', :p1 => 'pv1' },
488
+ :platform => 'pp'
489
489
  })
490
490
  end
491
491
 
492
492
  it "merges suite values over platform values" do
493
493
  combo(
494
- { 'common' => { 'c1' => 'xxx' } },
495
- { 'common' => { 'c1' => 'cv1', 'c2' => 'cv2' } },
494
+ { :common => { :c1 => 'xxx' } },
495
+ { :common => { :c1 => 'cv1', :c2 => 'cv2' } },
496
496
  ).attributes.must_equal({
497
- 'common' => { 'c1' => 'xxx', 'c2' => 'cv2' }
497
+ :common => { :c1 => 'xxx', :c2 => 'cv2' }
498
498
  })
499
499
  end
500
500
  end
501
501
 
502
502
  it "#dna combines attributes with the run_list" do
503
- instance.dna.must_equal({ 's' => 'ss', 'p' => 'pp',
504
- 'run_list' => [ 'platform_list', 'suite_list' ] })
503
+ instance.dna.must_equal({ :s => 'ss', :p => 'pp',
504
+ :run_list => [ 'platform_list', 'suite_list' ] })
505
505
  end
506
506
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jamie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.alpha20
4
+ version: 0.1.0.alpha21
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-04 00:00:00.000000000 Z
12
+ date: 2013-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -253,7 +253,8 @@ files:
253
253
  - templates/plugin/license_reserved.erb
254
254
  - templates/plugin/version.rb.erb
255
255
  homepage: https://github.com/jamie-ci/jamie
256
- licenses: []
256
+ licenses:
257
+ - Apache 2.0
257
258
  post_install_message:
258
259
  rdoc_options: []
259
260
  require_paths: