spec/kontena/cli/services/exec_command_spec.rb in kontena-cli-1.4.0.pre1 vs spec/kontena/cli/services/exec_command_spec.rb in kontena-cli-1.4.0.pre2
- old
+ new
@@ -1,59 +1,11 @@
-require 'kontena/websocket/client'
require 'kontena/cli/services/exec_command'
describe Kontena::Cli::Services::ExecCommand do
include ClientHelpers
include OutputHelpers
- let(:ws_client_class) do
- Class.new do
-
- Event = Struct.new(:data)
-
- def initialize
- @callbacks = {}
- end
-
- def on(callback, &block)
- @callbacks[callback] = block
- if callback == :open
- Thread.new {
- sleep 0.01
- @callbacks[:open].call
- }
- end
- end
-
- def connect ; end
-
- def receive_message(msg)
- @callbacks[:message].call(Event.new(JSON.dump(msg)))
- rescue => exc
- STDERR.puts exc.message
- end
- end
- end
-
- let(:ws_client) do
- ws_client_class.new
- end
-
- let(:master_url) do
- subject.require_current_master.url.gsub('http', 'ws')
- end
-
- def respond_ok(ws_client)
- ws_client.receive_message({'stream' => 'stdout', 'chunk' => "ok\n"})
- ws_client.receive_message({'exit' => 0})
- end
-
- def respond_error(ws_client)
- ws_client.receive_message({'stream' => 'stderr', 'chunk' => "error\n"})
- ws_client.receive_message({'exit' => 1})
- end
-
context "For a service with one running instance" do
let :service_containers do
{ 'containers' => [
{
'id' => 'test-grid/host/test-service.container-1',
@@ -67,25 +19,20 @@
before do
expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return(service_containers)
end
it "Executes on the running container by default" do
- expect(Kontena::Websocket::Client).to receive(:new).with("#{master_url}v1/containers/test-grid/host/test-service.container-1/exec", anything).and_return(ws_client)
- expect(ws_client).to receive(:text) do |foo|
- ws_client.receive_message({'stream' => 'stdout', 'chunk' => "ok\n"})
- ws_client.receive_message({'exit' => 0})
- end
-
- expect {
- subject.run(['test-service', 'test'])
- }.to output("ok\n").to_stdout
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-1', ['test'],
+ interactive: false, shell: false, tty: false,
+ ).and_return(0)
+ expect{subject.run(['test-service', 'test'])}.to_not exit_with_error
end
end
context "For a service with multiple running instances" do
let :service_containers do
- { 'containers' => [
+ [
{
'id' => 'test-grid/host/test-service.container-1',
'name' => 'test-service.container-1',
'instance_number' => 1,
'status' => 'running',
@@ -100,128 +47,110 @@
'id' => 'test-grid/host/test-service.container-3',
'name' => 'test-service.container-3',
'instance_number' => 3,
'status' => 'running',
},
- ] }
+ ]
end
it "Executes on the first running container by default" do
- expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return(service_containers)
- expect(Kontena::Websocket::Client).to receive(:new).with("#{master_url}v1/containers/test-grid/host/test-service.container-1/exec", anything).and_return(ws_client)
- expect(ws_client).to receive(:text) do
- respond_ok(ws_client)
+ expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return('containers' => service_containers)
+
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-1', ['test'],
+ interactive: false, shell: false, tty: false,
+ ) do
+ puts 'ok 1'
+ 0
end
- expect {
+
+ expect{
subject.run(['test-service', 'test'])
- }.to output("ok\n").to_stdout
+ }.to output_lines [ 'ok 1' ]
end
it "Executes on the first running container, even if they are ordered differently" do
- expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return({'containers' => service_containers['containers'].reverse })
- expect(Kontena::Websocket::Client).to receive(:new).with("#{master_url}v1/containers/test-grid/host/test-service.container-1/exec", anything).and_return(ws_client)
- expect(ws_client).to receive(:text) do
- respond_ok(ws_client)
- end
- expect {
- subject.run(['test-service', 'test'])
- }.to output("ok\n").to_stdout
+ expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return('containers' => service_containers.reverse)
+
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-1', ['test'],
+ interactive: false, shell: false, tty: false,
+ ).and_return(0)
+ expect{subject.run(['test-service', 'test'])}.to_not exit_with_error
end
- it "Executes on the first running container if given" do
- expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return(service_containers)
- expect(Kontena::Websocket::Client).to receive(:new).with("#{master_url}v1/containers/test-grid/host/test-service.container-1/exec", anything).and_return(ws_client)
- expect(ws_client).to receive(:text) do
- respond_ok(ws_client)
+ context do
+ before do
+ expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return('containers' => service_containers)
end
- expect {
- subject.run(['test-service', 'test'])
- }.to output("ok\n").to_stdout
- end
- it "Executes on the second running container if given" do
- expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return(service_containers)
- expect(Kontena::Websocket::Client).to receive(:new).with("#{master_url}v1/containers/test-grid/host/test-service.container-2/exec", anything).and_return(ws_client)
- expect(ws_client).to receive(:text) do
- respond_ok(ws_client)
+ it "Executes on the first running container if given" do
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-1', ['test'],
+ interactive: false, shell: false, tty: false,
+ ).and_return(0)
+ expect{subject.run(['--instance=1', 'test-service', 'test'])}.to_not exit_with_error
end
- expect {
- subject.run(['--instance', '2', 'test-service', 'test'])
- }.to output("ok\n").to_stdout
- end
- it "Errors on a nonexistant container if given" do
- expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return(service_containers)
+ it "Executes on the second running container if given" do
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-2', ['test'],
+ interactive: false, shell: false, tty: false,
+ ).and_return(0)
+ expect{subject.run(['--instance=2', 'test-service', 'test'])}.to_not exit_with_error
+ end
- expect{subject.run(['--instance=4', 'test-service', 'test'])}.to exit_with_error.and output(/Service test-service does not have container instance 4/).to_stderr
- end
+ it "Errors on a nonexistant container if given" do
+ expect{subject.run(['--instance=4', 'test-service', 'test'])}.to exit_with_error.and output(/Service test-service does not have container instance 4/).to_stderr
+ end
- it "Executes on each running container" do
- expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return(service_containers)
+ it "Executes on each running container" do
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-1', ['test'],
+ interactive: false, shell: false, tty: false,
+ ).and_return(0)
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-2', ['test'],
+ interactive: false, shell: false, tty: false,
+ ).and_return(0)
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-3', ['test'],
+ interactive: false, shell: false, tty: false,
+ ).and_return(0)
- 3.times do |i|
- ws_client = ws_client_class.new
- expect(Kontena::Websocket::Client).to receive(:new).with("#{master_url}v1/containers/test-grid/host/test-service.container-#{i + 1}/exec", anything).and_return(ws_client)
- expect(ws_client).to receive(:text) do
- ws_client.receive_message({'stream' => 'stdout', 'chunk' => "test#{i + 1}\n"})
- ws_client.receive_message({'exit' => 0})
- end
+ subject.run(['--silent', '--all', 'test-service', 'test'])
end
- expect {
- subject.run(['--silent', '--all', 'test-service', 'test'])
- }.to output("test1\ntest2\ntest3\n").to_stdout
- end
+ it "Stops if the first container fails" do
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-1', ['test'],
+ interactive: false, shell: false, tty: false,
+ ) { $stderr << 'error'; 1 }
- it "Stops if the first container fails" do
- expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return(service_containers)
- expect(Kontena::Websocket::Client).to receive(:new).with("#{master_url}v1/containers/test-grid/host/test-service.container-1/exec", anything).and_return(ws_client)
- expect(ws_client).to receive(:text) do
- respond_error(ws_client)
+ expect {
+ subject.run(['--silent', '--all', 'test-service', 'test'])
+ }.to exit_with_error.and output("error").to_stderr
end
- expect {
- subject.run(['--silent', '--all', 'test-service', 'test'])
- }.to output("error\n").to_stderr
- end
- it "Stops if the second container fails" do
- expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return(service_containers)
- i = 1
- [:ok, :err].each do |status|
- ws_client = ws_client_class.new
- expect(Kontena::Websocket::Client).to receive(:new).with("#{master_url}v1/containers/test-grid/host/test-service.container-#{i}/exec", anything).and_return(ws_client)
- expect(ws_client).to receive(:text) do
- if status == :ok
- respond_ok(ws_client)
- else
- respond_error(ws_client)
- end
- end
- i += 1
+ it "Stops if the second container fails" do
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-1', ['test'],
+ interactive: false, shell: false, tty: false,
+ ) { $stdout << 'ok 1'; 0 }
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-2', ['test'],
+ interactive: false, shell: false, tty: false,
+ ) { $stderr << 'error 2'; 1 }
+
+ expect {
+ subject.run(['--silent', '--all', 'test-service', 'test'])
+ }.to exit_with_error.and output("ok 1").to_stdout.and output("error 2").to_stderr
end
- expect {
- subject.run(['--silent', '--all', 'test-service', 'test'])
- }.to output("ok\n").to_stdout.and output("error\n").to_stderr
- end
- it "Keeps going if the second container fails when using --skip" do
- expect(client).to receive(:get).with('services/test-grid/null/test-service/containers').and_return(service_containers)
+ it "Keeps going if the second container fails when using --skip" do
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-1', ['test'],
+ interactive: false, shell: false, tty: false,
+ ) { puts 'ok 1'; 0}
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-2', ['test'],
+ interactive: false, shell: false, tty: false,
+ ) { puts 'err 2'; 2 }
+ expect(subject).to receive(:container_exec).with('test-grid/host/test-service.container-3', ['test'],
+ interactive: false, shell: false, tty: false,
+ ) { puts 'ok 3'; 0 }
- i = 1
- [:ok, :err, :ok].each do |status|
- ws_client = ws_client_class.new
- expect(Kontena::Websocket::Client).to receive(:new).with("#{master_url}v1/containers/test-grid/host/test-service.container-#{i}/exec", anything).and_return(ws_client)
- expect(ws_client).to receive(:text) do
- if status == :ok
- respond_ok(ws_client)
- else
- respond_error(ws_client)
- end
- end
- i += 1
+ expect {
+ subject.run(['--silent', '--all', '--skip', 'test-service', 'test'])
+ }.to exit_with_error.and output_lines ['ok 1', 'err 2', 'ok 3']
end
- expect {
- subject.run(['--silent', '--all', '--skip', 'test-service', 'test'])
- }.to output("ok\nok\n").to_stdout.and output("error\n").to_stderr
end
end
end