Syspec: System Specifications & Tests using a Rake-like batch file

Posted by Mathew Abonyi Sat, 10 Feb 2007 21:45:43 GMT

Syspec lets you write a batch file a lot like a Rake file, but in common HTTP-style language, to test the existence and proper functioning of all the domains, subdomains, their pages and responses. This project is still very much in its infancy, but I decided to get it out there to get some feedback while I use it to track production servers. This is a sample Syspecfile:

check :"www.rubyonrails.org" do
  accept 200
  get "/"
  accept 404
  get "/syspec"
  get "/lacrima"
end

The above will check that http://www.rubyonrails.org/ responds with 200 and http://www.rubyonrails.org/syspec and http://www.rubyonrails.org/lacrima respond with 404. You can have multiple checks with the same domain and it does not have to be a symbol, though I prefer it that way.

Currently, Syspec features the following:
  • accept(*codes) – response code should be among these codes
  • get, post, delete, put (uses fetch(:request_method, url))
Upcoming features:
  • login “username”, “password”
  • body matching
  • forms
You can grab a copy of it directly from my SVN repository here:
  svn co http://mabs29.googlecode.com/svn/trunk/gems/syspec .
Or download the gem from within the SVN repository (later will be moved to rubyforge):
  svn export http://mabs29.googlecode.com/svn/trunk/gems/syspec/versions/syspec-0.2.1.gem .

Enjoy!

Posted in ,  | no comments | no trackbacks

ANSI Strings (2nd Edition)

Posted by Mathew Abonyi Wed, 07 Feb 2007 07:32:22 GMT

I had a couple of instances where I was adding to the ANSI_CODES constant and creating all sorts of ugly errors. Then a script of mine whispered in my ear its desire for meta-aliases. That prompted a small rewrite of the library.

Ansi codes are now dynamically defined and more easily manipulated without overcomplicating things. Also, I added an RSpec test to the repository for my own piece of mind and to help with refactoring a few things. I don’t know, should I give it a version number? Nah. Just ‘Second Edition’. I don’t envisage any other serious revisions to it any more. What I changed:

  • dumped the array structure for ansi codes
  • added a few non-colour ANSI codes
  • dynamic ansi code definitions: String.define_ansi :alias => “123m”
  • meta-aliases: String.define_ansi :clear_both => [:clear_line, :clear_screen]
  • String#method definitions only if it doesn’t exist already
  • String#method definitions on the fly
  • spec test

And here’s the code:

$ANSI ||= false

class String

  class << self

    attr_accessor :ansi_codes

    def ansi_codes
      @ansi_codes ||= {}
    end

    def define_ansi(definitions = {})
      self.ansi_codes = ansi_codes.merge(definitions)
      define_shortcuts(definitions)
    end

    def define_shortcuts(definitions = {})
      definitions.keys.each do |meth|
        unless instance_methods.include?(meth.to_s)
          define_method(meth) { with_ansi(meth) }
        end
      end
    end

  end

  define_ansi :normal         => "0m",      :bold           => "1m"
  define_ansi :underline      => "4m",      :blink          => "5m"
  define_ansi :reverse_video  => "7m",      :invisible      => "8m"
  define_ansi :black          => "30m",     :red            => "31m"
  define_ansi :green          => "32m",     :yellow         => "33m"
  define_ansi :blue           => "34m",     :magenta        => "35m"
  define_ansi :cyan           => "36m",     :white          => "37m"
  define_ansi :black_bg       => "40m",     :red_bg         => "41m"
  define_ansi :green_bg       => "42m",     :yellow_bg      => "43m"
  define_ansi :blue_bg        => "44m",     :magenta_bg     => "45m"
  define_ansi :cyan_bg        => "46m",     :white_bg       => "47m"
  define_ansi :clear_line     => "K",       :clear_screen   => "2J"
  define_ansi :go_home        => "0H",      :go_to_end      => "80L"

  # Wrap a string with an arbitrary ansi code and the ansi normal code
  def with_ansi(*codes)
    use_ansi? ? "#{sym_to_ansi(*codes)}#{self}#{sym_to_ansi(:normal)}" : self
  end

  # Just a little metaprogramming shortcut
  def ansi_codes; self.class.ansi_codes; end

  private
  def sym_to_ansi(*symbols)
    symbols.inject("") do |string, symbol|
      if code = ansi_codes[symbol]
        string << (code.is_a?(Array) ? sym_to_ansi(*code) : "\e[#{code}")
      end
      string
    end
  end

  # determine whether we have ansi support or ANSI enabled
  def use_ansi?
    $ANSI && RUBY_PLATFORM !~ /win32/i
  end

end

You can grab the new version from my ‘other’ directory at Google Code:

  svn co http://mabs29.googlecode.com/svn/trunk/other/ansi_strings .

Posted in  | no comments | no trackbacks

Older posts: 1 2 3 4 5 ... 13