Multiple Sinatra Apps and Cucumber
How do I test a stack of modular (multiple) Sinatra applications with Cucumber? Honestly, I was a bit baffled about how I would get my env.rb to load my config.ru the way it should be loaded. Specifically, I wanted Cucumber to run features with my Rack::Map and other middleware just the same as when my server actually starts. There’s nothing short of several thousand blog posts about Cucumber usage and setup, but I couldn’t find anything about how to do this. Here is an example of Cucumber with Capybara env.rb loading the config.ru with Rack::Builder.
ENV['RACK_ENV'] = 'test' require File.expand_path(File.dirname(__FILE__) + "/../../init") require 'capybara' require 'capybara/cucumber' require 'spec' class SinatraWorld require "selenium-webdriver" Capybara.default_driver = :selenium # use the rackup file to load the apps w/their respective URL mappings, sweet! Capybara.app = eval "Rack::Builder.new {( " + File.read(File.dirname(__FILE__) + '/../../config.ru') + "\n )}" include Capybara include Spec::Expectations include Spec::Matchers end World do SinatraWorld.new end
Since the Sinatra applications are defined in the config.ru with Rack::Map, I’m not limited to just a singular Sinatra app (as so many examples demonstrate).
Here is an example of the config.ru:
require File.expand_path(File.dirname(__FILE__) + "/init") use Rack::Static, :urls => ['/javascripts', '/stylesheets', '/images', '/html'], :root => File.join(File.dirname(__FILE__), 'public') use Rack::Lint map "/app1" do run SinatraAppOne end map "/app2" do run SinatraAppTwo end map "/app3" do run SinatraAppThree end
Silicon Valley Ruby Meetup – Sinatra
More to come…
git@github.com:techwhizbang/sinatra_slideshow_code.git
git@github.com:techwhizbang/sinatra_slideshow_code.git
Recorded audio from the presentation
Unbeknownst to me, Sinatra was once of the presenations at #RubyKaigi 2010 in Japan. What’s really amazing to me is that on the other side of the world two speakers were basically spreading the good word in a very similar way. Of the many similarities between our presentations, one was that we were reinforcing the notion of Rack being the fundamental and foundational awesomeness of Sinatra. Here is the link to Jiang Wu’s presentation http://rubykaigi.tdiary.net/20100829.html#p08.
Check out how Sinatra’s syntactic sugar is spreading in other languages. Have a look at express, it is Sinatra like framework based on node.js.
Infrastructure Automation with Chef
By now you’ve at least heard about Chef or perhaps you’ve thought about evaluating it. If you haven’t heard about Chef, no worries, let me explain. Chef is an open source infrastructure automation framework written in Ruby by the guys at OpsCode for developers. In my opinion, OpsCode has hit a grand slam home run on this one and I want to send them a thank you. So the big questions. Why Chef, why another framework, why should you be interested? It boils down to this, developer tooling and infrastructure automation is generally one of the most overlooked areas in software. Let’s be honest, developers never get the appropriate amount of time while working on a project to do this usually because management and stakeholders don’t understand the value it brings to a project. To the business it is totally intangible, or is it? You might have heard complaints about how they hate that it takes so long for a new developer to get setup and hit the ground running. Maybe you’ve gotten complaints about how long, unpredictable, or “manual” deployments have gotten. Perhaps you’ve been wondering how you could rapidly and consistently clone image clusters of servers. Chef makes this dead easy.
The Quick and Dirty
Chef has an organization structure of many cookbooks. Cookbooks are just folders for organization of a particular set of related recipes. Developers write recipes in a Ruby Chef DSL. You can write recipes to do just about anything. Directory creation, library installation, gem installation, file permissions, OS package management can be controlled via the Ruby DSL Chef provides. It gets better. There is probably a recipe or cookbook already written for what you want to do. There are a growing number of Chef cookbooks and recipes shared on Github. Want a Nginx and Passenger recipe? Already written. Want memcached installed? Already written. You name it, chances are there is a recipe waiting for you. Instantly velocity! Now while this is all fine and dandy for most, recipe support across the various flavors of *nix is growing. Right now there is fantastic cookbook and recipe support if you’re running a Debian, Ubuntu, CentOS, or RedHat Linux. If you’re running another flavor of *nix, it is really easy to do whatever you want. Chef bends and flexes to your needs. Anything you can do with the Ruby language can be used to your advantage while writing a recipe. That reminds me, I’ve got a sweet CentOS recipe for Nginx installation that I have to contribute. Without rambling further you can get the most up to date information on the Chef wiki.
Common Uses
Writing a recipe for developer machine setup is a breeze and you actually can use the Chef gem that comes with the chef-solo command to kick off the recipe.
Are you still using some sucky deployment tool or script written a million years ago? Maybe you’re using Capistrano. Try out the Chef “deploy” resource. The Chef deploy resource by default encapsulates all of the best practices for Rails deployment, it doesn’t get simpler than this. Capistrano was an excellent tool for it’s time, you must try deployment on Chef. It makes rollbacks a snap also. Not using Rails or have some custom deployment requirements? The deploy resource is still awesome. You can pick and choose what you want and configure whatever customizations you need.
Take deployment and rollback even a step further with a tool like Hudson or TeamCity. Configure a job for them to run and wire up the Chef deployment script. The “easy button” deployment and rollback.
Chef combined with some server virtualization management tool you could easily image and setup a whole cluster of servers.
Still not convinced? Community adoption is growing fast and some of the most popular hosting companies in the Ruby sphere of influence are already using Chef. In fact, EngineYard uses Chef for application deployment on their cloud platform.
magic_meta_methods
Update: I’ve made magic_meta_methods a gem available at http://rubygems.org/gems/magic_meta_methods
A while back I wrote a plugin for Rails that serializes text and data structures into a singular column called magic_meta_methods on an ActiveRecord. The plugin then makes the data readable and writable through meta-programmed methods and allows the user to save the ActiveRecord just as they would if they were modifying regular attributes. I’ve found this particularly useful for when there isn’t a need to store data that has to be queried or when you want to keep a data structure in tact like an array or hash. By reducing the number of columns and clutter on the table, you can keep the migrations to a minimum. As always I like to hear what the community thinks about it, or what types of improvements would make it more useful.
Follow me on Twitter
My github repository
My LinkedIn Profile