summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames F. Carter <james.carter@bytemark.co.uk>2016-04-21 13:14:42 +0100
committerJames F. Carter <james.carter@bytemark.co.uk>2016-04-21 13:14:42 +0100
commit0197e6c3e33ae5870436107cdb63fe56f9f45484 (patch)
treef8bf368e70df92a25c9a1bfae3f3840489b2f391
parente33455736a49b95876b77552df9c130ad687c5fd (diff)
added a simple tftp utility
-rw-r--r--lib/custodian/util/tftp.rb52
-rwxr-xr-xt/test-custodian-util-tftp.rb116
2 files changed, 168 insertions, 0 deletions
diff --git a/lib/custodian/util/tftp.rb b/lib/custodian/util/tftp.rb
new file mode 100644
index 0000000..3028874
--- /dev/null
+++ b/lib/custodian/util/tftp.rb
@@ -0,0 +1,52 @@
+require 'tmpdir'
+require 'fileutils'
+
+module Custodian
+
+ module Util
+
+ class Tftp
+
+ attr_reader :hostname, :port, :filename
+
+ #
+ # Store hostname and port
+ #
+ def initialize(hostname, port=69)
+
+ raise ArgumentError, 'Hostname must not be nil' if hostname.nil?
+ raise ArgumentError, 'Hostname must be a String' unless hostname.kind_of?(String)
+ raise ArgumentError, 'Port must be a number' unless port.to_i > 0
+
+ @hostname = hostname
+ @port = port.to_i
+ end
+
+ #
+ # Returns true only if the file can be downloaded and is not zero-length.
+ #
+ def test(file)
+ target = Dir::Tmpname.make_tmpname('/tmp/', nil)
+
+ return false unless fetch(file, target)
+ return false unless File.size?(target)
+ return true
+ ensure
+ FileUtils.rm_f(target)
+ end
+
+ def fetch(file, target=nil)
+ # HPA's tftp client appears to have a 25s timeout that it is
+ # not possible to change on the command line.
+ return tftp("-m binary #{@hostname} #{@port} -c get #{file} #{target}")
+ end
+
+ def tftp(args)
+ return system("tftp #{args}") == true
+ end
+
+ end
+
+ end
+
+end
diff --git a/t/test-custodian-util-tftp.rb b/t/test-custodian-util-tftp.rb
new file mode 100755
index 0000000..0774124
--- /dev/null
+++ b/t/test-custodian-util-tftp.rb
@@ -0,0 +1,116 @@
+#!/usr/bin/ruby -I./lib/ -I../lib/
+
+require 'custodian/util/tftp'
+require 'test/unit'
+
+#
+# Unit test for our tftp utility class.
+#
+class TestTftpUtil < Test::Unit::TestCase
+
+
+ #
+ # Create the test suite environment: NOP.
+ #
+ def setup
+ end
+
+ #
+ # Destroy the test suite environment: NOP.
+ #
+ def teardown
+ end
+
+
+ #
+ # Test we can construct new objects.
+ #
+ def test_init
+
+ #
+ # Normal construction works.
+ #
+ assert_nothing_raised do
+ Custodian::Util::Tftp.new('foo')
+ end
+ assert_nothing_raised do
+ Custodian::Util::Tftp.new('foo', 123)
+ end
+ assert_nothing_raised do
+ Custodian::Util::Tftp.new('foo', '123')
+ end
+
+
+ #
+ # A hostname must be supplied
+ #
+ assert_raise ArgumentError do
+ Custodian::Util::Tftp.new(nil)
+ end
+
+ #
+ # A hostname is a string, not an array, hash, or similar.
+ #
+ assert_raise ArgumentError do
+ Custodian::Util::Tftp.new({})
+ end
+ assert_raise ArgumentError do
+ Custodian::Util::Tftp.new([])
+ end
+
+ #
+ # A port, if supplied, must be a number
+ #
+ assert_raise ArgumentError do
+ Custodian::Util::Tftp.new('foo', 'bar')
+ end
+
+ #
+ # The default port is 69
+ #
+ assert_equal(Custodian::Util::Tftp.new('foo').port, 69)
+
+
+ end
+
+ #
+ # Test a tftp successful fetch
+ #
+ def test_tftp_suceeds
+ helper = Custodian::Util::Tftp.new('foo')
+ def helper.tftp(args)
+ filename = args.split(' ').last
+ File.open(filename, 'w') { |w| w.puts 'stuff' }
+ return true
+ end
+
+ assert(helper.test('file'))
+ end
+
+ #
+ # Test a tftp failed fetch
+ #
+ def test_tftp_failed_fetch
+ helper = Custodian::Util::Tftp.new('foo')
+ def helper.tftp(args)
+ return false
+ end
+
+ assert(!helper.test('file'))
+ end
+
+ #
+ # Test a tftp fetch of empty file
+ #
+ def test_tftp_empty_file
+ helper = Custodian::Util::Tftp.new('foo')
+ def helper.tftp(args)
+ filename = args.split(' ').last
+ File.open(filename, 'w') { |w| }
+ return true
+ end
+
+ assert(!helper.test('file'))
+ end
+
+end