Skip to content

Commit

Permalink
Add cache connection to train
Browse files Browse the repository at this point in the history
Signed-off-by: Jared Quick <jquick@chef.io>
  • Loading branch information
jquick committed Nov 17, 2017
1 parent 3ed2adb commit 9fa599f
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 32 deletions.
4 changes: 0 additions & 4 deletions lib/train/plugins/base_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,13 @@ class Train::Plugins::Transport
class BaseConnection
include Train::Extras

# Provide access to the files cache.
attr_reader :files

# Create a new Connection instance.
#
# @param options [Hash] connection options
# @yield [self] yields itself for block-style invocation
def initialize(options = nil)
@options = options || {}
@logger = @options.delete(:logger) || Logger.new(STDOUT)
@files = {}
Train::Platforms::Detect::Specifications::OS.load
end

Expand Down
38 changes: 38 additions & 0 deletions lib/train/plugins/cache_connection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# encoding: utf-8

class Train::Plugins::Transport
class CacheConnection < BaseConnection
# Create a new CacheConnection instance. This instance will cache
# file and command operations on the underline connection.
#
# @param connection [Connection] connection object
def initialize(connection)
@connection = connection
@file_cache = {}
@cmd_cache = {}

@connection.class.instance_methods(false).each do |m|
next if %i(run_command file).include?(m)
define_singleton_method m do |*args|
@connection.send(m, *args)
end
end
end

def file(path)
if @file_cache.key?(path)
@file_cache[path]
else
@file_cache[path] = @connection.file(path)
end
end

def run_command(cmd)
if @cmd_cache.key?(cmd)
@cmd_cache[cmd]
else
@cmd_cache[cmd] = @connection.run_command(cmd)
end
end
end
end
11 changes: 8 additions & 3 deletions lib/train/plugins/transport.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
# encoding: utf-8
#
# Author:: Dominik Richter (<dominik.richter@gmail.com>)
# Author:: Christoph Hartmann (<chris@lollyrock.com>)

require 'logger'
require 'train/errors'
Expand All @@ -14,6 +11,7 @@ class Transport
Train::Options.attach(self)

require 'train/plugins/base_connection'
require 'train/plugins/cache_connection'

# Initialize a new Transport object
#
Expand Down Expand Up @@ -41,6 +39,13 @@ def self.name(name)
Train::Plugins.registry[name] = self
end

# Create a cache connection to the target.
#
# @return [CacheConnection]
def cache_connection
CacheConnection.new(connection)
end

private

# @return [Logger] logger for reporting information
Expand Down
15 changes: 7 additions & 8 deletions lib/train/transports/docker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,13 @@ def close
end

def file(path)
@files[path] ||=\
if os.aix?
Train::File::Remote::Aix.new(self, path)
elsif os.solaris?
Train::File::Remote::Unix.new(self, path)
else
Train::File::Remote::Linux.new(self, path)
end
if os.aix?
Train::File::Remote::Aix.new(self, path)
elsif os.solaris?
Train::File::Remote::Unix.new(self, path)
else
Train::File::Remote::Linux.new(self, path)
end
end

def run_command(cmd)
Expand Down
11 changes: 5 additions & 6 deletions lib/train/transports/local.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,11 @@ def local?
end

def file(path)
@files[path] ||= \
if os.windows?
Train::File::Local::Windows.new(self, path)
else
Train::File::Local::Unix.new(self, path)
end
if os.windows?
Train::File::Local::Windows.new(self, path)
else
Train::File::Local::Unix.new(self, path)
end
end

def login_command
Expand Down
1 change: 1 addition & 0 deletions lib/train/transports/mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def initialize(conf = nil)
super(conf)
mock_os
@commands = {}
@files = {}
end

def uri
Expand Down
19 changes: 9 additions & 10 deletions lib/train/transports/ssh_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,15 @@ def close
end

def file(path)
@files[path] ||= \
if os.aix?
Train::File::Remote::Aix.new(self, path)
elsif os.solaris?
Train::File::Remote::Unix.new(self, path)
elsif os[:name] == 'qnx'
Train::File::Remote::Qnx.new(self, path)
else
Train::File::Remote::Linux.new(self, path)
end
if os.aix?
Train::File::Remote::Aix.new(self, path)
elsif os.solaris?
Train::File::Remote::Unix.new(self, path)
elsif os[:name] == 'qnx'
Train::File::Remote::Qnx.new(self, path)
else
Train::File::Remote::Linux.new(self, path)
end
end

# (see Base::Connection#run_command)
Expand Down
2 changes: 1 addition & 1 deletion lib/train/transports/winrm_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def close
end

def file(path)
@files[path] ||= Train::File::Remote::Windows.new(self, path)
Train::File::Remote::Windows.new(self, path)
end

def run_command(command)
Expand Down
46 changes: 46 additions & 0 deletions test/unit/plugins/cache_connection_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# encoding: utf-8
require 'helper'

describe 'train cache connection' do
let(:cls) { Train::Plugins::Transport::BaseConnection }
let(:connection) { cls.new({}) }
let(:cache_connection) { Train::Plugins::Transport::CacheConnection.new(connection) }

describe 'create cache connection' do
it 'return new cache connection' do
cache_connection.must_be_kind_of Train::Plugins::Transport::CacheConnection
cache_connection.respond_to?(:run_command).must_equal true
end
end

describe 'check instance method fallback' do
it 'check os method' do
cache_connection.respond_to?(:os).must_equal true
cache_connection.respond_to?(:platform).must_equal true
end

it 'check close method' do
cache_connection.respond_to?(:close).must_equal true
end
end

describe 'load file' do
it 'load file with caching' do
connection.expects(:file).once.returns('test_file')
cache_connection.file('/tmp/test').must_equal('test_file')
cache_connection.file('/tmp/test').must_equal('test_file')
assert = { '/tmp/test' => 'test_file' }
cache_connection.instance_variable_get(:@file_cache).must_equal(assert)
end
end

describe 'run command' do
it 'run command with caching' do
connection.expects(:run_command).once.returns('test_user')
cache_connection.run_command('whoami').must_equal('test_user')
cache_connection.run_command('whoami').must_equal('test_user')
assert = { 'whoami' => 'test_user' }
cache_connection.instance_variable_get(:@cmd_cache).must_equal(assert)
end
end
end

0 comments on commit 9fa599f

Please sign in to comment.