summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc A. Paradise <marc.paradise@gmail.com>2019-04-26 15:14:41 -0400
committerMarc A. Paradise <marc.paradise@gmail.com>2019-04-29 14:49:52 -0400
commitd5c20dd81bda4aebee2c1ed426208841a6e659bc (patch)
tree18ba15908ba14106b9984ecaa59780c5d314c39b
parent7f4509663710f942850f35d864a3c3c84f36ab3b (diff)
downloadchef-mp/train-alone.tar.gz
Add tests, and make connector more testablemp/train-alone
Signed-off-by: Marc A. Paradise <marc.paradise@gmail.com>
-rw-r--r--lib/chef/knife/bootstrap/train_connector.rb8
-rw-r--r--spec/unit/knife/bootstrap/train_connector_spec.rb133
2 files changed, 133 insertions, 8 deletions
diff --git a/lib/chef/knife/bootstrap/train_connector.rb b/lib/chef/knife/bootstrap/train_connector.rb
index 40e0c565ee..06bc2ba900 100644
--- a/lib/chef/knife/bootstrap/train_connector.rb
+++ b/lib/chef/knife/bootstrap/train_connector.rb
@@ -36,7 +36,6 @@ class Chef
MKTEMP_NIX_COMMAND = "bash -c 'd=$(mktemp -d ${TMPDIR:-/tmp}/chef_XXXXXX); echo $d'".freeze
def initialize(host_url, default_transport, opts)
-
uri_opts = opts_from_uri(host_url)
uri_opts[:backend] ||= @default_transport
@transport_type = uri_opts[:backend]
@@ -59,12 +58,7 @@ class Chef
# Specifying sudo: false ensures that attempted operations
# don't fail because the mock platform doesn't support sudo
tc = TrainConnector.new(url, protocol, { sudo: false }.merge(opts))
-
- # Don't pull in the platform-specific mixins automatically during connect
- # Otherwise, it will raise since it can't resolve the OS without the mock.
tc.connect!
- # We need to provide this mock before invoking mix_in_target_platform,
- # otherwise it will fail with an unknown OS (since we don't have a real connection).
tc.backend.mock_os(
family: family,
name: name,
@@ -72,7 +66,6 @@ class Chef
arch: arch
)
tc
-
end
def connect!
@@ -174,6 +167,7 @@ class Chef
def train
@train
end
+
def backend
@train.connection
end
diff --git a/spec/unit/knife/bootstrap/train_connector_spec.rb b/spec/unit/knife/bootstrap/train_connector_spec.rb
index 872bf5481d..b15965645f 100644
--- a/spec/unit/knife/bootstrap/train_connector_spec.rb
+++ b/spec/unit/knife/bootstrap/train_connector_spec.rb
@@ -20,5 +20,136 @@ require "ostruct"
require "chef/knife/bootstrap/train_connector"
describe Chef::Knife::Bootstrap::TrainConnector do
- # Tests in flight, will be pushed up
+ let(:protocol) { "mock" }
+ let(:family) { "unknown" }
+ let(:release) { "unknown" } # version
+ let(:name) { "unknown" }
+ let(:arch) { "x86_64" }
+ let(:host_url) { "mock://user1@example.com" }
+ let(:opts) { {} }
+ subject do
+ # Create a valid TargetHost with the backend stubbed out.
+ Chef::Knife::Bootstrap::TrainConnector.test_instance(host_url,
+ protocol: protocol,
+ family: family,
+ name: name,
+ release: release,
+ arch: arch,
+ opts: opts)
+ end
+
+ context "connect!" do
+ end
+
+ describe "platform helpers" do
+ context "on linux" do
+ let(:family) { "debian" }
+ let(:name) { "ubuntu" }
+ it "reports that it is linux and unix, because that is how train classifies it" do
+ expect(subject.unix?).to eq true
+ expect(subject.linux?).to eq true
+ expect(subject.windows?).to eq false
+ end
+ end
+ context "on unix" do
+ let(:family) { "os" }
+ let(:name) { "mac_os_x" }
+ it "reports only a unix OS" do
+ expect(subject.unix?).to eq true
+ expect(subject.linux?).to eq false
+ expect(subject.windows?).to eq false
+ end
+ end
+ context "on windows" do
+ let(:family) { "windows" }
+ let(:name) { "windows" }
+ it "reports only a windows OS" do
+ expect(subject.unix?).to eq false
+ expect(subject.linux?).to eq false
+ expect(subject.windows?).to eq true
+ end
+ end
+ end
+
+ describe "#connect!" do
+ it "establishes the connection to the remote host by waiting for it" do
+ expect(subject.backend).to receive(:wait_until_ready)
+ subject.connect!
+ end
+ end
+
+ describe "#temp_dir" do
+ context "under windows" do
+ let(:family) { "windows" }
+ let(:name) { "windows" }
+
+ it "uses the windows command to create the temp dir" do
+ expected_command = Chef::Knife::Bootstrap::TrainConnector::MKTEMP_WIN_COMMAND
+ expect(subject).to receive(:run_command!).with(expected_command)
+ .and_return double("result", stdout: "C:/a/path")
+ expect(subject.temp_dir).to eq "C:/a/path"
+ end
+
+ end
+ context "under linux and unix-like" do
+ let(:family) { "debian" }
+ let(:name) { "ubuntu" }
+ it "uses the *nix command to create the temp dir and sets ownership to logged-in user" do
+ expected_command = Chef::Knife::Bootstrap::TrainConnector::MKTEMP_NIX_COMMAND
+ expect(subject).to receive(:run_command!).with(expected_command)
+ .and_return double("result", stdout: "/a/path")
+ expect(subject).to receive(:run_command!).with("chown user1 '/a/path'")
+ expect(subject.temp_dir).to eq "/a/path"
+ end
+
+ end
+ end
+ context "#upload_file_content!" do
+ it "creates a local file with expected content and uploads it" do
+ expect(subject).to receive(:upload_file!) do |local_path, remote_path|
+ expect(File.read(local_path)).to eq "test data"
+ expect(remote_path).to eq "/target/path"
+ end
+ subject.upload_file_content!("test data", "/target/path")
+ end
+ end
+
+ context "del_file" do
+ context "on windows" do
+ let(:family) { "windows" }
+ let(:name) { "windows" }
+ it "deletes the file with a windows command" do
+ expect(subject).to receive(:run_command!) do |cmd, &_handler|
+ expect(cmd).to match(/Test-Path "deleteme\.txt".*/)
+ end
+ subject.del_file!("deleteme.txt")
+ end
+ end
+ context "on unix-like" do
+ let(:family) { "debian" }
+ let(:name) { "ubuntu" }
+ it "deletes the file with a windows command" do
+ expect(subject).to receive(:run_command!) do |cmd, &_handler|
+ expect(cmd).to match(/rm -f "deleteme\.txt".*/)
+ end
+ subject.del_file!("deleteme.txt")
+ end
+ end
+ end
+
+ context "#run_command!" do
+ it "raises a RemoteExecutionFailed when the remote execution failed" do
+ command_result = double("results", stdout: "", stderr: "failed", exit_status: 1)
+ expect(subject).to receive(:run_command).and_return command_result
+
+ expect { subject.run_command!("test") }.to raise_error do |e|
+ expect(e.hostname).to eq subject.hostname
+ expect(e.class).to eq Chef::Knife::Bootstrap::RemoteExecutionFailed
+ expect(e.stderr).to eq "failed"
+ expect(e.stdout).to eq ""
+ expect(e.exit_status).to eq 1
+ end
+ end
+ end
+
end