From 0197e6c3e33ae5870436107cdb63fe56f9f45484 Mon Sep 17 00:00:00 2001 From: "James F. Carter" Date: Thu, 21 Apr 2016 13:14:42 +0100 Subject: added a simple tftp utility --- lib/custodian/util/tftp.rb | 52 +++++++++++++++++++ t/test-custodian-util-tftp.rb | 116 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 lib/custodian/util/tftp.rb create mode 100755 t/test-custodian-util-tftp.rb 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 -- cgit v1.2.1