Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Commit

Permalink
cmdrunner tests
Browse files Browse the repository at this point in the history
  • Loading branch information
davidsiaw committed May 22, 2024
1 parent 628b745 commit 1a822a5
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 11 deletions.
1 change: 0 additions & 1 deletion exe/kaiser
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ require 'optimist'
require 'fileutils'
require 'yaml'
require 'json'
require 'pty'
require 'erb'

require 'kaiser'
Expand Down
6 changes: 4 additions & 2 deletions lib/kaiser/cmds/up.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ def build_cmd
build_args = docker_build_args.map { |k, v| "--build-arg #{k}=#{v}" }
[
'docker build',
"--progress=plain",
"-t kaiser:#{envname}-#{current_branch}",
"-f #{tmp_dockerfile_name} #{Config.work_dir}",
platform_args,
Expand All @@ -46,7 +45,10 @@ def setup_app
Config.info_out.puts 'Setting up application'
File.write(tmp_dockerfile_name, docker_file_contents)

CommandRunner.run! Config.out, build_cmd.join("\n\t")
CommandRunner.run! Config.out, build_cmd.join("\n\t"), env_vars: {
'DOCKER_BUILDKIT' => '1',
'BUILDKIT_PROGRESS' => 'plain'
}
FileUtils.rm(tmp_dockerfile_name)
end
end
Expand Down
20 changes: 12 additions & 8 deletions lib/kaiser/command_runner.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
# frozen_string_literal: true

require 'pty'
require 'English'

# This is the command runner
module Kaiser
# Make running easy
# This is the command runner
# it abstracts away the complicated syntax required to deal with
# PTY and to pass the lines programmatically to the host application
# as well as to capture the return code at the end.
class CommandRunner
def self.run(out, cmd, &block)
def self.run(out, cmd, env_vars:, &block)
out.puts "> #{cmd}"
CommandRunner.new(out, cmd).run_command(&block)
CommandRunner.new(out, cmd, env_vars).run_command(&block)
end

def self.run!(out, cmd, &block)
status = run(out, cmd, &block)
def self.run!(out, cmd, env_vars: {}, &block)
status = run(out, cmd, env_vars: env_vars, &block)
raise Kaiser::CmdError.new(cmd, status) if status.to_s != '0'
end

def initialize(out, cmd)
def initialize(out, cmd, env_vars)
@out = out
@cmd = cmd.tr "\n", ' '
@env_vars = env_vars
end

def print_and_return_status(status = 0)
Expand All @@ -38,7 +42,7 @@ def print_lines(lines)
end

def run_command(&block)
PTY.spawn("#{@cmd} 2>&1") do |stdout, _stdin, pid|
PTY.spawn(@env_vars, "#{@cmd} 2>&1") do |stdout, _stdin, pid|
print_lines(stdout, &block)
Process.wait(pid)
end
Expand Down
109 changes: 109 additions & 0 deletions spec/command_runner_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# frozen_string_literal: true

require 'kaiser/command_runner'

RSpec.describe Kaiser::CommandRunner do
# this is the core function of this class
describe '#run_command' do
it 'runs a simple command' do
# out can also be $stderr or $stdout
out = StringIO.new
described_class.new(out, 'echo hello', {}).run_command
expect(out.string).to eq <<~OUTPUT
hello\r
$? = 0
OUTPUT
end

it 'can capture lines' do
lines = []
out = StringIO.new
described_class.new(out, 'echo hello', {}).run_command do |line|
lines << line
end

expect(lines).to eq ['hello']
end

it 'returns the 0 status if the command succeeds' do
out = StringIO.new
retval = described_class.new(out, 'true', {}).run_command
expect(retval).to eq 0
end

it 'returns the 1 status if the command returns 1' do
out = StringIO.new
retval = described_class.new(out, 'false', {}).run_command
expect(retval).to eq 1
end

it 'allows application of environment variables' do
lines = []
out = StringIO.new
described_class.new(out, 'echo $HELLO', { 'HELLO' => 'WORLD' }).run_command do |line|
lines << line
end

expect(lines).to eq ['WORLD']
end

it 'can capture lines' do
lines = []
out = StringIO.new
described_class.new(out, 'echo hello', {}).run_command do |line|
lines << line
end

expect(lines).to eq ['hello']
end
end

describe '.run' do
it 'adds the appropriate lines to output' do
out = StringIO.new
described_class.run(out, 'echo hello', env_vars: {})

expect(out.string).to eq <<~OUTPUT
> echo hello
hello\r
$? = 0
OUTPUT
end

it 'yields lines approprately' do
lines = []
out = StringIO.new
described_class.run(out, 'echo hello', env_vars: {}) do |line|
lines << line
end

expect(lines).to eq ['hello']
end

it 'handles env vars' do
lines = []
out = StringIO.new
described_class.run(out, 'echo $HELLO', env_vars: { 'HELLO' => 'world' }) do |line|
lines << line
end

expect(lines).to eq ['world']
end
end

describe '.run!' do
out = StringIO.new
it 'does whatever run does' do
expect(described_class).to receive(:run).with(out, 'meow', env_vars: { 'FOO' => 'bar' }).and_return('0')

described_class.run!(out, 'meow', env_vars: { 'FOO' => 'bar' })
end

it 'throws when the return code is not 0' do
allow(described_class).to receive(:run).with(out, 'woof', env_vars: { 'FOO' => 'bar' }).and_return('1')

expect { described_class.run!(out, 'woof', env_vars: { 'FOO' => 'bar' }) }
.to raise_error Kaiser::CmdError
end
end
end

0 comments on commit 1a822a5

Please sign in to comment.