The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Spiking with reckless abandon

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Kurtis Seebaldt

Posts: 10
Nickname: kseebaldt
Registered: Nov, 2007

Kurtis Seebaldt is a Ruby developer at ThoughtWorks
Spiking with reckless abandon Posted: Feb 23, 2008 9:21 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Kurtis Seebaldt.
Original Post: Spiking with reckless abandon
Feed Title: Kurtis Seebaldt
Feed URL: http://kseebaldt.blogspot.com/feeds/posts/default
Feed Description: Ruby, consulting, smiting
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Kurtis Seebaldt
Latest Posts From Kurtis Seebaldt

Advertisement


A couple months ago, we were trying to improve our build process to better reflect our production environment. Our application runs on Oracle and the database schema is owned by one Oracle user, and our application logs in as another. The application user is granted rights to the tables it needs to use. There are also synonyms defined for all the tables our app uses.

Our builds only used a single database user for all our tests. If we forgot to update our database scripts to add new grants or synonyms, we wouldn't know it until we deployed to our QA environment. So, our goal was to have our build run with the same user split that the production environment did.

One problem with that scenario is our functional tests inserted data into tables that the app user didn't have insert rights to. We decided to spike switching to the schema owner for insertion of test data and go back to the regular app user for the rest of the test. We came up with this crazy bit of code to hijack our ActiveRecord models and reuse them to insert test data:

module TestData
def self.const_missing(name)
klass = Kernel.const_get(name)
new_klass = Class.new(klass)
const_set(name, new_klass)

new_klass.class_eval do
establish_connection "test_db_owner"

def ==(comparison_object)
comparison_object.equal?(self) ||
(comparison_object.instance_of?(self.class.superclass) &&
comparison_object.id == id &&
!comparison_object.new_record?)
end

def instance_of?(klass)
self.class == klass || self.class.superclass == klass
end
end

new_klass
end
end



This bit of code defines a new module called TestData. It overrides const_missing? and looks for an existing constant in the root namespace. It creates a new class in the TestData module that is a subclass of the original class. It then tells ActiveRecord to connect as the schema owner. There is some stuff in there to patch == and instance_of? to allow the new object to be compared to the original one.

Now, code like this is quite dangerous and is nothing I'd ever use in real production code. The real point of the spike however, was not figuring out how to connect as a different user, but to see how feasible it would be to modify our tests to use two database users. This little hack only took about 20 minutes to write and allowed us to attack our main problem. Since this was a spike, we knew we were going to throw it all away after we learned what we needed to know.

It turned out that we ran we couldn't use two seperate users easily, because all our test methods ran in transactions. We relied on the transaction rollback to clean up all our inserted test data. We could work around this, but it would take a lot more rework than we had originally planned. Our little TestData module was promptly deleted from our code base.

I am a big fan of any language that gives power to the developer. I don't like to be shackled because some language designer thinks that developers should be protected from themselves. Features like Ruby's const_missing? can be horribly misused and can cause code that is extremely difficult to debug, but it can also be really useful. Our little experiment only took a couple of hours, because we were able to use a powerful, but possibly dangerous feature of Ruby. That module was the quickest way for us to get to the meat of the problem without wasting a lot of time on technical details that we could figure out once we committed to doing the work.

I believe in smart tools for smart developers. Making a language overly safe doesn't really enforce code quality. Bad programmers will write bad code no matter the language. All it does is keep the good ones from accomplishing what they need to do.

Read: Spiking with reckless abandon

Topic: Rails and ProxyPreserveHost Previous Topic   Next Topic Topic: Rails from the Edge

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use