pennyworth-tool 0.0.1

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.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.hound.yml +3 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +18 -0
  6. data/CONTRIBUTING.md +67 -0
  7. data/COPYING +674 -0
  8. data/Gemfile +28 -0
  9. data/README.md +339 -0
  10. data/Rakefile +33 -0
  11. data/bin/pennyworth +26 -0
  12. data/config/setup.yml +17 -0
  13. data/examples/README.md +23 -0
  14. data/examples/kiwi/definitions/base_opensuse13.1_kvm/config.sh +87 -0
  15. data/examples/kiwi/definitions/base_opensuse13.1_kvm/config.xml +64 -0
  16. data/examples/kiwi/definitions/base_opensuse13.1_kvm/root/etc/sysconfig/network/ifcfg-eth0 +2 -0
  17. data/examples/kiwi/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
  18. data/examples/vagrant/Vagrantfile +14 -0
  19. data/files/99-libvirt.rules +2 -0
  20. data/files/image_test-template.xml +43 -0
  21. data/files/pool-default.xml +6 -0
  22. data/lib/image_runner.rb +89 -0
  23. data/lib/pennyworth.rb +65 -0
  24. data/lib/pennyworth/cli.rb +339 -0
  25. data/lib/pennyworth/cli_host_controller.rb +107 -0
  26. data/lib/pennyworth/commands/base_command.rb +96 -0
  27. data/lib/pennyworth/commands/boot_command.rb +29 -0
  28. data/lib/pennyworth/commands/build_base_command.rb +103 -0
  29. data/lib/pennyworth/commands/command.rb +43 -0
  30. data/lib/pennyworth/commands/down_command.rb +25 -0
  31. data/lib/pennyworth/commands/import_base_command.rb +112 -0
  32. data/lib/pennyworth/commands/import_ssh_keys_command.rb +27 -0
  33. data/lib/pennyworth/commands/list_command.rb +41 -0
  34. data/lib/pennyworth/commands/setup_command.rb +209 -0
  35. data/lib/pennyworth/commands/shutdown_command.rb +28 -0
  36. data/lib/pennyworth/commands/status_command.rb +26 -0
  37. data/lib/pennyworth/commands/up_command.rb +27 -0
  38. data/lib/pennyworth/exceptions.rb +39 -0
  39. data/lib/pennyworth/helper.rb +39 -0
  40. data/lib/pennyworth/host_config.rb +86 -0
  41. data/lib/pennyworth/host_runner.rb +133 -0
  42. data/lib/pennyworth/image_runner.rb +89 -0
  43. data/lib/pennyworth/libvirt.rb +93 -0
  44. data/lib/pennyworth/local_command_runner.rb +77 -0
  45. data/lib/pennyworth/local_runner.rb +34 -0
  46. data/lib/pennyworth/lock_service.rb +87 -0
  47. data/lib/pennyworth/remote_command_runner.rb +144 -0
  48. data/lib/pennyworth/runner.rb +27 -0
  49. data/lib/pennyworth/settings.rb +42 -0
  50. data/lib/pennyworth/spec.rb +96 -0
  51. data/lib/pennyworth/spec_profiler.rb +85 -0
  52. data/lib/pennyworth/ssh_keys_importer.rb +107 -0
  53. data/lib/pennyworth/urls.rb +28 -0
  54. data/lib/pennyworth/vagrant.rb +81 -0
  55. data/lib/pennyworth/vagrant_command.rb +120 -0
  56. data/lib/pennyworth/vagrant_runner.rb +44 -0
  57. data/lib/pennyworth/version.rb +22 -0
  58. data/lib/pennyworth/vm.rb +62 -0
  59. data/man/.gitignore +2 -0
  60. data/man/pennyworth.1.md +28 -0
  61. data/pennyworth.gemspec +57 -0
  62. data/prophet/Gemfile +3 -0
  63. data/prophet/prophet.rb +82 -0
  64. data/spec/base_command_spec.rb +30 -0
  65. data/spec/build_base_command_spec.rb +147 -0
  66. data/spec/cli_host_controller_spec.rb +113 -0
  67. data/spec/data/hosts.yaml +10 -0
  68. data/spec/data/kiwi/base_opensuse12.3_kvm.box +1 -0
  69. data/spec/data/kiwi/base_opensuse13.1_kvm.box +1 -0
  70. data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/config.sh +1 -0
  71. data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/config.xml +1 -0
  72. data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
  73. data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/config.sh +1 -0
  74. data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/config.xml +1 -0
  75. data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
  76. data/spec/data/kiwi2/box_state.yaml +14 -0
  77. data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/config.sh +1 -0
  78. data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/config.xml +1 -0
  79. data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
  80. data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/config.sh +1 -0
  81. data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/config.xml +1 -0
  82. data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
  83. data/spec/data/kiwi3/box_state.yaml +13 -0
  84. data/spec/data/kiwi3/definitions/base_opensuse12.3_kvm/.gitkeep +0 -0
  85. data/spec/data/kiwi3/definitions/base_opensuse13.1_kvm/.gitkeep +0 -0
  86. data/spec/data/kiwi3/import_state.yaml +3 -0
  87. data/spec/data/kiwi4/definitions/base_opensuse12.3_kvm/.gitkeep +0 -0
  88. data/spec/data/kiwi4/definitions/base_opensuse13.1_kvm/.gitkeep +0 -0
  89. data/spec/data/kiwi4/import_state.yaml +3 -0
  90. data/spec/data/kiwi5/import_state.yaml +3 -0
  91. data/spec/data/vagrant/.gitkeep +0 -0
  92. data/spec/host_config_spec.rb +197 -0
  93. data/spec/host_runner_spec.rb +112 -0
  94. data/spec/image_runner_spec.rb +62 -0
  95. data/spec/import_base_command_spec.rb +189 -0
  96. data/spec/local_command_runner_spec.rb +117 -0
  97. data/spec/local_runner_spec.rb +42 -0
  98. data/spec/lock_service_spec.rb +95 -0
  99. data/spec/remote_command_runner_spec.rb +115 -0
  100. data/spec/settings_spec.rb +26 -0
  101. data/spec/setup_command_spec.rb +49 -0
  102. data/spec/spec_helper.rb +50 -0
  103. data/spec/spec_profiler_spec.rb +63 -0
  104. data/spec/spec_spec.rb +99 -0
  105. data/spec/support/command_runner_examples.rb +29 -0
  106. data/spec/support/runner_examples.rb +34 -0
  107. data/spec/urls_spec.rb +46 -0
  108. data/spec/vagrant_command_spec.rb +51 -0
  109. data/spec/vagrant_runner_spec.rb +40 -0
  110. data/spec/vagrant_spec.rb +288 -0
  111. data/spec/vm_spec.rb +56 -0
  112. metadata +257 -0
data/man/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.1
2
+ *.html
@@ -0,0 +1,28 @@
1
+ # Pennyworth -- Tool for controlling a network of machines for integration tests
2
+
3
+ ## SYNOPSIS
4
+
5
+ `pennyworth` [options]
6
+
7
+ `pennyworth` help [command]
8
+
9
+
10
+ ## DESCRIPTION
11
+
12
+ **Pennyworth** is a tool for controlling a network of machines for
13
+ integration testing. It helps to control virtual and real machines to provide a
14
+ well-defined test environment for automated tests.
15
+
16
+ Use the `help` command to get documentation about the individual commands.
17
+ Find more documentation at https://github.com/SUSE/pennyworth.
18
+
19
+
20
+ ## BUGS
21
+
22
+ If you find bugs please report them at
23
+ https://github.com/SUSE/pennyworth/issues/new.
24
+
25
+
26
+ ## COPYRIGHT
27
+
28
+ Pennyworth is Copyright (c) 2013-2015 SUSE LLC
@@ -0,0 +1,57 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # Copyright (c) 2013-2014 SUSE LLC
4
+ #
5
+ # This program is free software; you can redistribute it and/or
6
+ # modify it under the terms of version 3 of the GNU General Public License as
7
+ # published by the Free Software Foundation.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, contact SUSE LLC.
16
+ #
17
+ # To contact SUSE about this file by physical or electronic mail,
18
+ # you may find current contact information at www.suse.com
19
+
20
+ require File.expand_path("../lib/pennyworth/version", __FILE__)
21
+
22
+ Gem::Specification.new do |s|
23
+ s.name = "pennyworth-tool"
24
+ s.version = Pennyworth::VERSION
25
+ s.license = 'GPL-3.0'
26
+ s.platform = Gem::Platform::RUBY
27
+ s.authors = ['SUSE']
28
+ s.email = ['machinery@lists.suse.com']
29
+ s.homepage = "https://github.com/SUSE/pennyworth"
30
+ s.summary = "A tool for running integration tests inside a network of virtual machines"
31
+ s.description = <<-EOT.split("\n").map(&:strip).join(" ")
32
+ Pennyworth is a tool for running integration tests inside a network of
33
+ virtual machines. It allows to define virtual machines, build them as
34
+ Vagrant boxes and run them using libvirt and kvm in coordinated fashion in
35
+ order to run the tests. These tests can be written in any
36
+ language/framework, but the preferred combination is Ruby/RSpec, for which
37
+ helpers are provided.
38
+ EOT
39
+
40
+ s.required_rubygems_version = ">= 1.3.6"
41
+ s.rubyforge_project = "pennyworth"
42
+
43
+ s.add_dependency "gli", "~> 2.11.0"
44
+ s.add_dependency "cheetah"
45
+ s.add_dependency "colorize"
46
+ s.add_dependency "nokogiri"
47
+ s.add_dependency "ruby-libvirt", "~> 0.4.0"
48
+
49
+ s.files = `git ls-files`.split("\n")
50
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
51
+ s.require_path = 'lib'
52
+
53
+ s.files += Dir['man/*.?'] # UNIX man pages
54
+ s.files += Dir['man/*.{html,css,js}'] # HTML man pages
55
+ s.add_development_dependency 'ronn', '>=0.7.3'
56
+ s.add_development_dependency 'rake'
57
+ end
data/prophet/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "prophet"
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright (c) 2013-2014 SUSE LLC
4
+ #
5
+ # This program is free software; you can redistribute it and/or
6
+ # modify it under the terms of version 3 of the GNU General Public License as
7
+ # published by the Free Software Foundation.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, contact SUSE LLC.
16
+ #
17
+ # To contact SUSE about this file by physical or electronic mail,
18
+ # you may find current contact information at www.suse.com
19
+
20
+ require 'prophet'
21
+ require 'logger'
22
+ require 'yaml'
23
+
24
+ Prophet.setup do |config|
25
+
26
+ # Setup custom logger.
27
+ config.logger = log = Logger.new(STDOUT)
28
+ log.level = Logger::INFO
29
+
30
+ CONFIG_FILE = "config/options-local.yml"
31
+ if File.exists?(CONFIG_FILE)
32
+ options = YAML.load_file(CONFIG_FILE)
33
+ # The GitHub (GH) username/password to use for commenting on a successful run.
34
+ config.username = options["default"]["git_username"]
35
+ config.password = options["default"]["git_password"]
36
+ end
37
+
38
+ config.status_context = "prophet/unit"
39
+ config.disable_comments = true
40
+
41
+ # Add Jenkins URL if available.
42
+ jenkins_url = `echo $BUILD_URL`.chomp
43
+ unless jenkins_url.empty?
44
+ config.status_target_url = "#{jenkins_url}console"
45
+ end
46
+
47
+ # Specify when to run your code.
48
+ # By default your code will run every time either the pull request or its
49
+ # target (i.e. master) changes.
50
+ config.rerun_on_source_change = true
51
+ config.rerun_on_target_change = true
52
+
53
+ # Add custom messages for comments and statuses.
54
+ config.status_pending = 'Tests are still running.'
55
+ config.status_success = 'Tests are passing.'
56
+ config.status_failure = 'Tests are failing.'
57
+
58
+ # If you need to make some system calls before looping through the pull requests,
59
+ # you specify them here. This block will only be executed once and defaults to an
60
+ # empty block.
61
+ #config.preparation do
62
+ # # Example: Setup jenkins.
63
+ # `rake -f /usr/lib/ruby/gems/1.9.1/gems/ci_reporter-1.7.0/stub.rake`
64
+ # `rake ci:setup:testunit`
65
+ #end
66
+
67
+ # Finally, specify which code to run. (Defaults to `rake`.)
68
+ # NOTE: If you don't set config.success manually to a boolean value,Prophet
69
+ # will try to determine it by looking at whether the last system call returned
70
+ # 0 (= success).
71
+ config.execution do
72
+ log.info 'Running tests ...'
73
+
74
+ system("cd ..; rspec")
75
+ config.success = ($? == 0)
76
+
77
+ log.info "Tests are #{config.success ? 'passing' : 'failing'}."
78
+ end
79
+
80
+ end
81
+
82
+ Prophet.run
@@ -0,0 +1,30 @@
1
+ # Copyright (c) 2013-2014 SUSE LLC
2
+ #
3
+ # This program is free software; you can redistribute it and/or
4
+ # modify it under the terms of version 3 of the GNU General Public License as
5
+ # published by the Free Software Foundation.
6
+ #
7
+ # This program is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ # GNU General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU General Public License
13
+ # along with this program; if not, contact SUSE LLC.
14
+ #
15
+ # To contact SUSE about this file by physical or electronic mail,
16
+ # you may find current contact information at www.suse.com
17
+
18
+ require "spec_helper.rb"
19
+
20
+ describe Pennyworth::BaseCommand do
21
+ it "processes the base image parameter" do
22
+ c = Pennyworth::BaseCommand.new("/foo")
23
+
24
+ all_base_images = ["aaa", "bbb", "ccc"]
25
+
26
+ expect(c.process_base_image_parameter(all_base_images, "bbb")).to eq ["bbb"]
27
+ expect { c.process_base_image_parameter(all_base_images, "xxx") }.to raise_error
28
+ expect(c.process_base_image_parameter(all_base_images, nil)).to eq ["aaa", "bbb", "ccc"]
29
+ end
30
+ end
@@ -0,0 +1,147 @@
1
+ # Copyright (c) 2013-2014 SUSE LLC
2
+ #
3
+ # This program is free software; you can redistribute it and/or
4
+ # modify it under the terms of version 3 of the GNU General Public License as
5
+ # published by the Free Software Foundation.
6
+ #
7
+ # This program is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ # GNU General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU General Public License
13
+ # along with this program; if not, contact SUSE LLC.
14
+ #
15
+ # To contact SUSE about this file by physical or electronic mail,
16
+ # you may find current contact information at www.suse.com
17
+
18
+ require "spec_helper.rb"
19
+
20
+ describe Pennyworth::BuildBaseCommand do
21
+
22
+ let(:tmp_dir) { "/tmp/kiwi-vagrant-build-environment" }
23
+ let(:expected_content) {
24
+ <<-EOT
25
+ ---
26
+ base_opensuse13.1_kvm:
27
+ sources:
28
+ config.sh: 00cd92ac20df539d7d6f7930a339c622
29
+ config.xml: 43dd3b9cd11bc9d882f8f82ac108b74a
30
+ root/home/vagrant/.ssh/authorized_keys: b440b5086dd12c3fd8abb762476b9f40
31
+ target: 115469c104dcc69455f321eb086ffb11
32
+ base_opensuse12.3_kvm:
33
+ sources:
34
+ config.sh: c6640ba00ab345b7491b836d517a637b
35
+ config.xml: a3d3de67d84f7792bf2755f7a3ae4e3f
36
+ root/home/vagrant/.ssh/authorized_keys: b440b5086dd12c3fd8abb762476b9f40
37
+ target: e4e743b5340686d8488dbce54b5644d8
38
+ EOT
39
+ }
40
+
41
+ context "with non-existing box state file" do
42
+ before(:each) do
43
+ Pennyworth::Cli.settings = Pennyworth::Settings.new
44
+ @kiwi_dir = File.join(test_data_dir, "kiwi")
45
+ @cmd = Pennyworth::BuildBaseCommand.new(@kiwi_dir)
46
+ end
47
+
48
+ it "reads box sources state of one box" do
49
+ source_state = @cmd.read_box_sources_state("base_opensuse12.3_kvm")
50
+
51
+ expect(source_state.count).to eq 3
52
+ expect(source_state["config.sh"]).to eq "c6640ba00ab345b7491b836d517a637b"
53
+ end
54
+
55
+ it "reads box target state of one box" do
56
+ target_state = @cmd.read_box_target_state("base_opensuse13.1_kvm")
57
+
58
+ expect(target_state).to eq "115469c104dcc69455f321eb086ffb11"
59
+ end
60
+
61
+ it "writes box state file" do
62
+ box_state_file = File.join(@kiwi_dir, "box_state.yaml")
63
+
64
+ box_state = {}
65
+ [ "base_opensuse13.1_kvm", "base_opensuse12.3_kvm" ].each do |box|
66
+ box_state[box] = {}
67
+ box_state[box]["sources"] = @cmd.read_box_sources_state(box)
68
+ target_state = @cmd.read_box_target_state(box)
69
+ if target_state
70
+ box_state[box]["target"] = target_state
71
+ end
72
+ end
73
+
74
+ FileUtils.rm(box_state_file) if File.exist?(box_state_file)
75
+
76
+ @cmd.write_box_state_file(box_state)
77
+
78
+ expect(File.read(box_state_file)).to eq expected_content
79
+
80
+ FileUtils.rm(box_state_file) if File.exist?(box_state_file)
81
+ end
82
+
83
+ it "doesn't fail reading box state file" do
84
+ box_state = @cmd.read_local_box_state_file
85
+
86
+ expect(box_state).to eq({})
87
+ end
88
+
89
+ it "preserves the state data of other boxes on build-base" do
90
+ allow(Pennyworth::Libvirt).to receive(:ensure_libvirt_env_started)
91
+
92
+ # Don't actually build
93
+ allow(@cmd).to receive(:base_image_create)
94
+ allow(@cmd).to receive(:base_image_export)
95
+ allow(@cmd).to receive(:base_image_cleanup_build)
96
+
97
+ allow(@cmd).to receive(:log) # Don't print to stdout
98
+
99
+ @cmd.execute(tmp_dir, "base_opensuse13.1_kvm")
100
+ @cmd.execute(tmp_dir, "base_opensuse12.3_kvm")
101
+
102
+ box_state_file = File.join(@kiwi_dir, "box_state.yaml")
103
+
104
+ expect(File.read(box_state_file)).to eq expected_content
105
+
106
+ FileUtils.rm(box_state_file) if File.exist?(box_state_file)
107
+ end
108
+ end
109
+
110
+ context "with existing box state file" do
111
+ before(:each) do
112
+ Pennyworth::Cli.settings = Pennyworth::Settings.new
113
+ @kiwi_dir = File.join(test_data_dir, "kiwi2")
114
+ @cmd = Pennyworth::BuildBaseCommand.new(@kiwi_dir)
115
+ end
116
+
117
+ it "reads box state file" do
118
+ box_state = @cmd.read_local_box_state_file
119
+
120
+ expect(box_state["base_opensuse12.3_kvm"]["sources"]["config.sh"]).to eq(
121
+ "c6640ba00ab345b7491b836d517a637b")
122
+ expect(box_state["base_opensuse13.1_kvm"]["target"]).to eq(
123
+ "115469c104dcc69455f321eb086ffb11")
124
+ end
125
+
126
+ it "rebuilds box with changed sources" do
127
+ allow(Pennyworth::Libvirt).to receive(:ensure_libvirt_env_started)
128
+ allow(@cmd).to receive(:log) # Don't print to stdout
129
+ allow(@cmd).to receive(:write_box_state_file) # Don't actually write data
130
+
131
+ expect(@cmd).to receive(:base_image_create)
132
+ expect(@cmd).to receive(:base_image_export)
133
+ expect(@cmd).to receive(:base_image_cleanup_build)
134
+ @cmd.execute(tmp_dir, "base_opensuse13.1_kvm")
135
+ end
136
+
137
+ it "doesn't rebuild box with unchanged sources" do
138
+ allow(Pennyworth::Libvirt).to receive(:ensure_libvirt_env_started)
139
+ allow(@cmd).to receive(:log) # Don't print to stdout
140
+ allow(@cmd).to receive(:write_box_state_file) # Don't actually write data
141
+
142
+ expect(@cmd).to_not receive(:base_image_create)
143
+ @cmd.execute(tmp_dir, "base_opensuse12.3_kvm")
144
+ end
145
+ end
146
+
147
+ end
@@ -0,0 +1,113 @@
1
+ # Copyright (c) 2013-2015 SUSE LLC
2
+ #
3
+ # This program is free software; you can redistribute it and/or
4
+ # modify it under the terms of version 3 of the GNU General Public License as
5
+ # published by the Free Software Foundation.
6
+ #
7
+ # This program is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ # GNU General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU General Public License
13
+ # along with this program; if not, contact SUSE LLC.
14
+ #
15
+ # To contact SUSE about this file by physical or electronic mail,
16
+ # you may find current contact information at www.suse.com
17
+
18
+ require "spec_helper"
19
+
20
+ include GivenFilesystemSpecHelpers
21
+
22
+ describe Pennyworth::CliHostController do
23
+ use_given_filesystem
24
+
25
+ context "no configuration" do
26
+ before(:each) do
27
+ @config_dir = given_directory
28
+ out = double
29
+ allow(out).to receive(:puts)
30
+ @controller = Pennyworth::CliHostController.new(@config_dir, out)
31
+ end
32
+
33
+ describe "#setup" do
34
+ it "raises error when no argument is given" do
35
+ expect {
36
+ @controller.setup(nil)
37
+ }.to raise_error(GLI::BadCommandLine)
38
+ end
39
+
40
+ it "fetches configuration file" do
41
+ stub_request(:get, "http://remote.example.com/pennyworth/hosts.yaml").
42
+ with(:headers => {
43
+ "Accept" => "*/*",
44
+ "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
45
+ "User-Agent" => "Ruby"
46
+ }).
47
+ to_return(status: 200, body: "xx", headers: {})
48
+
49
+ config_file = File.join(@config_dir, "hosts.yaml")
50
+ expect(File.exist?(config_file)).to be(false)
51
+ @controller.setup("http://remote.example.com")
52
+ expect(File.exist?(config_file)).to be(true)
53
+ end
54
+ end
55
+ end
56
+
57
+ context "existing configuration" do
58
+ before(:each) do
59
+ @config_dir = given_directory do
60
+ given_file("hosts.yaml")
61
+ end
62
+ @out = double
63
+ @controller = Pennyworth::CliHostController.new(@config_dir, @out)
64
+ end
65
+
66
+ describe "#list" do
67
+ it "lists host" do
68
+ expect(@out).to receive(:puts).
69
+ with("test_host (address: host.example.com, base snapshot id: 5)")
70
+ expect(@out).to receive(:puts).
71
+ with("missing_address (base snapshot id: 5)")
72
+ expect(@out).to receive(:puts).
73
+ with("missing_snapshot_id (address: host.example.com)")
74
+
75
+ @controller.list
76
+ end
77
+ end
78
+
79
+ describe "#lock" do
80
+ it "raises error when no argument is given" do
81
+ expect {
82
+ @controller.lock(nil)
83
+ }.to raise_error(GLI::BadCommandLine)
84
+ end
85
+
86
+ it "raises error when host is not in configuration file" do
87
+ expect {
88
+ @controller.lock("invalid name")
89
+ }.to raise_error(Pennyworth::LockError)
90
+ end
91
+
92
+ it "acquires lock for host" do
93
+ expect_any_instance_of(Pennyworth::LockService).to receive(:request_lock).
94
+ with("test_host").and_return(true)
95
+ expect(@out).to receive(:puts).with(/test_host/)
96
+ expect_any_instance_of(Pennyworth::LockService).to receive(:keep_lock)
97
+
98
+ @controller.lock("test_host")
99
+ end
100
+
101
+ it "fails to acquire lock for host" do
102
+ expect_any_instance_of(Pennyworth::LockService).to receive(:request_lock).
103
+ with("test_host").and_return(false)
104
+ expect_any_instance_of(Pennyworth::LockService).to receive(:info).
105
+ with("test_host").and_return("'test_host' locked by 1.2.3.4")
106
+ expect(@out).to receive(:puts).with(/test_host/)
107
+ expect_any_instance_of(Pennyworth::LockService).to_not receive(:keep_lock)
108
+
109
+ @controller.lock("test_host")
110
+ end
111
+ end
112
+ end
113
+ end