Notes from Chirb Dojo — Game of Life Kata

datePosted on 13:48, November 6th, 2009 by Peter Fitzgibbons

The code was not much to look at.  We mostly rspec’d a few methods and learned that just because you ‘def to_s’ doesn’t mean the implicit string conversion uses it!
I think the real issue we uncovered was that the implicit string conversion produces escaped string and calling #to_s produces unescaped strings.

Ruby Gems we used to setup the environment.

  • rspec
  • ZenTest
  • redgreen (for windows users)

heredocs — we talked about how to produce heredocs   You can either use multi-line double-quoted, or <<-eot

text = <<-eot
This is the heredoc text
It can even include evaluations #{Time.now} !!
eot

More about heredocs : http://blog.jayfields.com/2006/12/ruby-multiline-strings-here-doc-or.html

A windows-implementation of textmate : http://www.e-texteditor.com/

The Ruby Way — Hal Fulton

http://www.google.com/url?sa=t&source=web&ct=res&cd=1&ved=0CAwQFjAA&url=http%3A%2F%2Fwww.amazon.com%2FRuby-Way-Second-Techniques-Programming%2Fdp%2F0672328844&ei=OuLwSsj_PIa1tgf59N26Cw&usg=AFQjCNHhpmT3C35Xiianfordqb21_DsWIA&sig2=Pb631QnepV_sAD8wmRuPTA

The Rails Way — Obie Fernandez

http://www.google.com/url?sa=t&source=web&ct=res&cd=3&ved=0CBYQFjAC&url=http%3A%2F%2Fwww.amazon.com%2FRails-Way-Obie-Fernandez%2Fdp%2F0321445619&ei=V-LwSunCEYeVtgfWib26Cw&usg=AFQjCNGpPcvEJDxIOGEwWZZIp9HXnbPC0A&sig2=0ofdwEJfrMOm7U3bR7c5OQ

The Rails Way Blog therailsway.com

Enumerable Module

How to build an ActiveRecord Adapter — Part 1 – Initialization

datePosted on 14:54, September 10th, 2009 by Peter Fitzgibbons

In this chapter, I’ll discuss the adapter initialization; how Rails 2.x reads from database.yml and launches the database initialization.

Rails Boot

Here is a condensation of the Rails boot process from Rails Guts.  As Mike Gunderloy suggests, it will be really helpful to have a blank rails app open with

 rake gems:freeze 

invoked :

  1. script/server (vendor/rails/railties/lib/commands/server.rb) requires environment.rb from the local path (./)
  2. in environment.rb
     Rails::Initializer.run do |config| 
  3. Initializer.run has a default parameter
     configuration = Configuration.new 

    (that’s Rails::Configuration in railties/lib/initializer.rb)

  4. Configuration#initialize is long, including
     self.database_configuration_file = default_database_configuration_file 
  5. Configuration#default_database_configuration_file is :
    def default_database_configuration_file
     File.join(root_path, 'config', 'database.yml')
     end
    
  6. Notice that the default command on Rails::Initializer#run was :process, so Initializer#process is now called, which includes #initialize_database …
    def initialize_database
     if configuration.frameworks.include?(:active_record)
     ActiveRecord::Base.configurations = configuration.database_configuration
     ActiveRecord::Base.establish_connection
     end
     end
    
    1. Configuration#database_configuration is where the database.yml is loaded and returned to ActiveRecord::Base.configurations :
      def database_configuration
       require 'erb'
       YAML::load(ERB.new(IO.read(database_configuration_file)).result)
       end
      
  7. Now were getting somewhere!!  AR::Base#establish_connection(nil) :
    1. because the call is with spec = nil, #establish_connection is re-executed with RAILS_ENV
    2. this time through, spec = RAILS_ENV (ie, :development), so #establish_connection is called again, this time with the database.yml hash-key of RAILS_ENV (from Configuration#database_configuration)
    3. 3rd time’s a charm!  Now, with spec set to config hash, require the adapter gem,
       gem "activerecord-#{spec[:adapter]}-adapter" 

      and execute the adapter-method (which is expected to be def’d from the adapter’s gem) :

       adapter_method = "#{spec[:adapter]}_connection" 

The adapter-method is the entry-point of our new adapter, so in my next post I’ll pick-apart the #establish_connection process and prepare for our multi-connection pooling adapter’s version.



How to build an ActiveRecord Adapter — Introduction

datePosted on 14:18, August 19th, 2009 by Peter Fitzgibbons

Well, I don’t know how many parts this will have… so lets just say 5 until I re-edit the introduction.

Inspiration and Perspiration

Thomas Edison told us how to invent.  So let’s get to it.  The Adapter we’ll build will assist in handling the problem of database-failover in Rails 2.3.2 applications

Inspired – Seamless Database Pool

Seamless Database Pool gem provides us with a template to follow.  The SDP is focused purely on connection logic.  The true db adapter is used within the pool connections.  Our Adapter, like SDP, will simply serve as a proxy to handle the event when an ActiveRecord method (#select, #create, #update, #delete) encounters a DatabaseConnectionError.

Perspired – Activerecord Failover Adapter

Ok, we’re going to have to work for it this time.  Event though we have SDP as a template, there is A LOT of logic in there that is really not useful to us.  SDP is a load-balancing pool based upon a weighted one-write/many-read database cluster / replication group.

Requirements

Ahh, the real meat of our cookout.

  1. Configure Master + Slaves(multiple) in database.yml just like SDP
  2. Use Master Always.  Well, until failover.
  3. Use periodic timeouts to attempt re-connect to master
  4. Retry db queries on alternate connection
  5. Rollback transactions upon connection failure… then retry them?
    1. Re-try the transaction in the alternate connection
  6. Allow #establish_connection to target master/slave (especially needed for targeted migrations)
  7. Allow db:migrate to target master/slave through use of RAILS_ENV

In my next post, we’ll start with #1 Configure Master + Slavees in database.yml

I recently completed configuration of continuous-integration between two servers.

Here’s the steps and notes that I have for the move.

System Layout

The system of servers/services comes together like this :

Git / Redmine

Git and Redmine run on server ‘redmine-server’, which is a CentOS 5 Intel box.  OpenSSH is installed, Redmine runs on Ruby 1.8.7, yum package install.
User on this server is ‘git’

Cerberus continuous integration

Cerberus runs on an OSX box named ‘ci-server’, Leopard.
Ruby on this box is installed using ruby-switcher, with 1.8.7p173 and 1.9.1p129r23412.
My customization of that ruby-switcher is here ruby_switcher.sh.
User on this server is ‘cerberus’

SSH setup Git -> Cerberus

The Git repository lives on a different server, so SSH is employed to protect passwords-cleartext over the wire.

There is an additional constraint in that Git hooks are “non-interactive”, so ssh keys must be configured to not challenge.  There are [security implications] to this.  The option I have chosen is passwordless “backup keys” for specific purposes.

git@redmine-server $ ssh-keygen -t rsa -C git_ci_server@redmine_server
Generating public/private rsa key pair.
Enter file in which to save the key (/home/git/.ssh/id_rsa): \
  .ssh/id_rsa_git_ci_server
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in .ssh/id_rsa_git_ci_server.
Your public key has been saved in .ssh/id_rsa_git_ci_server.pub.
The key fingerprint is:
42:62:16:4c:00:74:7c:a9:96:90:5a:75:5d:08:c5:f9 git_ci_server@redmine_server

Move the key to the target server ci-server

[git@redmine-server]$ scp .ssh/id_rsa_git_ci_server.pub \
  cerberus@ci-server:id_rsa_git_ci_server.redmine-server
Password:
id_rsa_git_ci_server.pub                     100%  410     0.4KB/s   00:00
[git@redmine-server]$ ssh deployer@web-ci
Password:
Last login: Mon Jun 15 09:20:00 2009 from redmine-server

[cerberus@ci-server]$ cat id_rsa_git_ci_server.redmine-server
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtOVHRlhLmUI/9XglQs6u9F1reUwAq2U0clJI2l
j5kAX5XkVW7FoiiGo4BfAqP3j69ynMBnLx/eUtcYcxHUKZfikwQbXnUdAUd8mIXoNhOfVZ/gqr
i0yS0XHpkGU2lJve3soqEIyYu2gxf5QPP18ibJeyFZ5QRTPUATfi1c6Pb12tsr4O9H+b5T08cU
ejvQP5ISyYH3ysPZwLQ3d1Ods9ZItm7h9/eoZQxgXpVLxUkQ3NO+JoktKlruGajTRgm5xP7NBd
gUZsC2vs84/mW64RWSzbl8fA5oKUhKQIDt7QSOGx2UVGYAoarFGTsvps5g9WnXTJ37XRT+ORHI
cpmO90mQ== git_ci_server@redmine_server
[cerberus@ci-server]$ cat id_rsa_git_ci_server.redmine-server >> .ssh/authorized_keys
[cerberus@ci-server]$ exit

SSH Backup-Key

From ‘man ssh’ :

 -i identity_file
    Selects a file from which the identity (private key) for RSA or DSA authentication is read.  The default is
    ~/.ssh/identity for protocol version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa for protocol version 2.  Identity files
    may also be specified on a per-host basis in the configuration file.  It is possible to have multiple -i options
    (and multiple identities specified in configuration files).

This Git server does not have ssh-agent running, so using -i will cause the indicated file to be the only identity used in the ssh session.

Now test the login using the backup-key switch of ’ssh’

[git@redmine-server]$ ssh -i .ssh/id_rsa_git_ci_server cerberus@ci-server
Last login: Mon Jun 15 10:53:38 2009 from redmine-server
[cerberus@ci-server]$

The backup-key switch will be used in the Git post-receive hook for executing Cerberus build upon Git Push

Git Post-Receive

Simple.  Use ssh to call a build script on ci-server, which we’ll build after the break…

#!/bin/sh
#
# An example hook script for the post-receive event
#
# This script is run after receive-pack has accepted a pack and the
# repository has been updated.  It is passed arguments in through stdin
# in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
#
# see contrib/hooks/ for an sample, or uncomment the next line (on debian)
#

ssh -i ~/.ssh/id_rsa_git_ci_server cerberus@ci-server \
 bin/cerberus-build racc-webapp

NOTE: the use of the -i switch

This hook is applied to each repository that will be monitored by Cerberus Continuous Integration.  It must be made executable so Git will execute it!

[git@redmine-server]$ cp post-receieve repos/my_app/.git/hooks/post-receive
[git@redmine-server]$ chmod +x repos/my_app/.git/hooks/post-receive

Cerberus configuration

Using the ruby-switcher, install the ruby of your choice (’install_ruby_187p173′).  The use it (’use_ruby_187′).

Install cerberus gem (note we are using local gem storage to accomodate ruby-switcher):

[cerberus@ci-server]$ gem install cerberus

Configure cerberus globals, especially email server config (for SMTP send).

I also configured the builder/rake to handle new migrations (Rails 2.3) and Rspec (rake spec)

[cerberus@ci-server]$ cat .cerberus/config.yml
publisher:
#  active: mail jabber rss campfire
  mail:
    address: smtp.test.com
    port: 25
    domain: test.com
    authentication: :none
    sender: Cerberus CI <cerberus@test.com>
#    address: smtp.gmail.com
#    port: 587
#    domain: gmail.com
#    authentication: plain
#    user_name: someuser
#    password: somepassword
#    on_event: all
#  jabber:
#    jid: somemailbox@gmail.com/cerberus
#    password: somepassword
#  twitter:
#    login: twitter_username
#    password: twitter_password
#  irc:
#    nick: cerb
#    server: irc.freenode.net
#    channel: cerberus
#  campfire:
#    url: http://someemail:password@cerberustool.campfirenow.com/room/51660
#  rss:
#    file: /usr/www/rss.xml
builder:
  rake:
    task: db:migrate spec
#changeset_url: POINT_TO_YOUR_TRAC/changeset/
#hook:
#  rcov:
#    on_event: successful, setup #by default - run hook for any state
#    action: 'export CERBERUS_HOME=/home/anatol && sudo chown www-data -R /home/anatol/cerberus && rcov' #Add here any hook you want

Configure the cerberus project. Note how the config points back to the repository

[cerberus@ci-server]$ cerberus add git@redmine-server:my_app/.git \
  APPLICATION_NAME=my-app SCM=git

Edit the configuration of the project to add project-level mailing addresses.  The BUILD WILL FAIL WITHOUT THIS!!!

[cerberus@ci-server]$ cat .cerberus/config/my-app.yml
---
publisher:
  mail:
    recipients: someuser@test.com
scm:
  url: git@redmine-server:repos/my_app/.git
  type: git

An initial build ‘cerberus build my-app’ is required to set the sources.  This one will likely fail, as it is necessary to configure non-SCM files like ‘database.yml’.

You should receive email from “Cerberus CI” declaring your failure.

You have completed config.  Now FIX YOUR BROKEN CHECKIN FTW!!

Tic Tac Toe 2 – Initial code and story-driven class.

datePosted on 02:30, March 19th, 2009 by Peter Fitzgibbons

Episode 2: Using the story from the ground up.

I could go into great detail… but I’m beat.  Creating the dev environment from the ground up was a lot of work.  I also needed to get some project details under way.

Here is what I needed to get Features and Specs to load up the library properly

Cucumber

Create a cucumber.yml.  This is necessary to set the default profile, which I wanted to get a little more pretty printing during the cucumber command.

In a step definition (grid_steps.rb), I needed the $LOAD_PATH to point to the lib, so I added the following to the top of support/env.rb

$:.unshift File.expand_path(File.dirname(__FILE__) + "/../../lib")

Also support RSpec expectations/matchers within the steps, so

require 'spec/expectations'

RSpec

Update the $LOAD_PATH here from a different location in the tree than features, from ./spec

$:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")

Autotest integration

In order to get cucumber integrated with autotest, add this to cucumber.yml

autotest: --format pretty features
autotest-all: --format pretty features

Also autospec requires an environment switch, which I have added to ./bashrc for convenience

export AUTOFEATURE=true

Amber to Red to Green to Amber to Red to Green…

With all the prettyness set up with cucumber and RSpec, we now have a new color in the Red-Green cycle.

Cucumber Features’ Given/When/Then lines are displayed in Amber until each is properly trapped by a defined Given/When/Then in a steps definition file (./features/step_definitions/*.rb).

RSpec specs are displayed in amber if the spec is not defined (name only) like this

it "this spec is not defined yet"

Well, that’s about all I can handle for now.

I will make an attempt to trap the Amber-Red-Green cycle in git commits during my work tomorrow.

TicTacToe 1- Dev Environment

datePosted on 03:20, March 18th, 2009 by Peter Fitzgibbons

Here’s the entirement development environment for TicTacToe.  This was actually rebuilt for this project as I deleted my last dev environment (A VirtualBox instance) during a system-repair process (wipe-drive-reinstall of Vista ;)

  • Ubuntu 8.10 Desktop as VirtualBox Guest on Vista Home Premium on Compaq C771.  NAT, 1gb ram, 16gb vhd, shared folders
  • Ruby 1.8 + dependencies from Apt
  • Rubygems 1.3.1 installed from .tgz (Ubuntu 8.10 has trouble with Apt’s rubygems install)
  • Rails, RSpec, RSpec-Rails, Cucumber gems installed
  • NetBeans 6.5.1 / All Modules.  NBGit installed for Git integration.

Tic Tac Toe Kata

datePosted on 12:39, March 17th, 2009 by Peter Fitzgibbons

This week I am starting a Tic Tac Toe Kata in response to a programming exercise by a future employer.  (Wave to you!)

Here are my rules for performance of the kata:

  • Blog after every long session developing – discuss progress and response about the “kata” of the kata
  • Track time for every session.  Report will be posted at kata completion
  • Use Story-driven-development.  Using Cucumber.  And thusly Behavior-driven-development through RSpec.
  • Document api via RDoc

And here is the kata:

What we have in mind is a simple Tic-Tac-Toe program.
At the least this program should:

  1. Allow for a human player.
  2. Play against a human.
  3. Have some user interface, text is fine.
  4. Never lose. Furthermore, it should win whenever possible.

We would like you to use Ruby as the programming language.  (My Pleasure!)

So, in my next posting I’ll be into project setup, prerequisites, and the first story or two.

Update 3/17/09: Add RDoc to expected deliverables.

Downtime and Lost Data

datePosted on 20:09, February 6th, 2009 by Peter Fitzgibbons

Yo All Followers.

This blog has had downtime and lost data due to my hosting provider’s server move and my own error in choosing a custom DNS config within my virtually-hosted node.

What does that mean to you?

  • Some posts may be missing. (please tell me if you know)
  • Comments are gone.  Sorry those of you who took the time to write.
  • Formatting may be futzed.  I don’t know which formatters I had running, will have to re-do formatting.  Give me a say-so if you have a favorite post that you’d like to love first.
  • new URL.  This is the most painful, as I wasn’t able to post a “moving to x.y.z” before the change.

I hope you all like to follow me again.  More Ruby goodness up and coming.

Regards,

Pete the Ruby Evangelist.

FUD all over again… This time with Testing!

datePosted on 09:15, June 1st, 2007 by Peter Fitzgibbons

Well, Jamie Cansdale has been getting heat over time from M$ over TestDriven.Net, formerly NUnitAddin.

M$ turned up the heat over the last week, and seemingly put it to HIGH yesterday.

Ian Ringrose simplified the discussion :

“Is it safe for me as a developer without a large legal department to work with Microsoft technology? “

FransBouma says : “Nail on the head.”

Yes… Nail on the head.

categoryPosted in Uncategorized | commentsNo Comments | moreRead More »

Pros & Cons – Rails vs. .NET Study

datePosted on 08:48, June 1st, 2007 by Peter Fitzgibbons

I’m debating between moving my career in one of two ways :

Rails

Study ruby on rails, leave Microsoft development, move my career in a new direction. I feel immediate happiness in this endeavor.

Pros

  • Test-driven development “baked in” to the development software
  • Installation and environment setup is free. No extra computer is required.
  • Ruby language contains “best-practices” of multiple languages and is “modern”. Ruby applies “LOLA” (Law of least astonishment), which makes it easier to apply “best-practices” to written code.
  • Community is VERY robust. Meetings are regular. IRC and listservs have heavy message traffic
  • My current skills apply to Ruby/Rails, even when from a different language/framework (IE Microsoft)
  • Best practices of Ruby/Rails align with current software-development industry research on best way to structure project management, design software, and build maintainable large-scale web systems.
  • By writing code in a system that aligns with best practices, I feel like I’m doing “the right thing” when I’m writing software.

Cons

  • Job Market is “currently” limited.
  • I need time to develop the skills/experience to support current income
  • Achieving experience appears to be a catch-22

.NET

Study Microsoft Certified Professional Developer (MCPD) / .NET 2.0. Give in to “the state”, admit that a governmentally structured certification machine also has a thriving job market. Join a Microsoft Consulting Firm full time and be a valuable contributor to their technologies.

Pros

  • Easy Job Market
  • I have valued skills (according to last job-seeking process)

Cons

  • Cost of Entry (Need new computer ($1000) + Software + Certification Testing $)
  • I don’t agree with Microsoft attitude toward developer community
  • I don’t agree with Microsoft attitude toward open-source / linux
  • Developer community is not robust (Few user group meetings in Chi, Forums/Elists don’t answer questions)
  • Microsoft web-development software (ASP.NET 2.0) does not support test-driven development
  • Microsoft development software is often confusing to read and confusing to use. Microsoft does not apply “LOLA” (Law of least astonishment).

Updated: 20 June 2007 12:35:00. This rounds out the pro/con list to more clearly present my perspective on what direction to take my career.

categoryPosted in Uncategorized | comments2 Comments | moreRead More »
1234Next