<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5879990958708057129</id><updated>2011-08-02T11:35:54.889-07:00</updated><title type='text'>Li Xiao is on the way</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://1234533dlh.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://1234533dlh.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Li Xiao</name><uri>http://www.blogger.com/profile/05224907707575784642</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://2.bp.blogspot.com/_1Kz0H2b8lbc/SL_hmgc6E_I/AAAAAAAADe0/d5NvWbqeF00/S220/xli.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5879990958708057129.post-6545841321534550554</id><published>2009-05-29T22:06:00.000-07:00</published><updated>2009-05-30T06:02:57.390-07:00</updated><title type='text'>Tips of embedding ruby gem in Java</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:100%;"&gt;&lt;span class="Apple-style-span"  style=" line-height: 19px;font-size:13px;"&gt;&lt;span class="Apple-style-span"   style="  line-height: normal; font-family:Times;font-size:16px;"&gt;&lt;div style=" font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; font: normal normal normal 13px/19px Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; padding-top: 0.6em; padding-right: 0.6em; padding-bottom: 0.6em; padding-left: 0.6em; background-position: initial initial; "&gt;&lt;div id=""&gt;&lt;div id=""&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;I spent 2 weeks on embedding a ruby workflow engine &lt;a href="http://openwferu.rubyforge.org/" mce_href="http://openwferu.rubyforge.org/"&gt;ruote&lt;/a&gt; in Java by JRuby (will publish it later).&lt;div&gt;The followings are tips I got:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;The JRuby wiki page Getting Started (http://wiki.jruby.org/wiki/Getting_Started) is out of date. Read http://wiki.jruby.org/wiki/Direct_JRuby_Embedding instead.&lt;/li&gt;&lt;li&gt;Should not use JavaUtil.* to convert java/ruby objects, which doesn't work well; use JavaEmbedUtils instead. And you probably should read javadoc of &lt;span class="Apple-style-span"  style="font-size:85%;"&gt;JavaEmbedUtils&lt;/span&gt;&lt;span class="Apple-style-span"   style="font-family:Monaco;font-size:85%;"&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;JavaEmbedUtils#&lt;span class="Apple-style-span"&gt;invokeMethod accepts Java objects as arguments to call a method of ruby object so that you don't have to convert every Java objects to JRuby objects&lt;/span&gt;&lt;span class="Apple-style-span"   style="font-family:Monaco;font-size:85%;"&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Create adapter for ruby object and wrap the ruby object with pure Java interface. So that no more JRuby interface need to care about outside.&lt;/li&gt;&lt;li&gt;Here is a &lt;a href="http://gist.github.com/120454"&gt;JRuby IRubyObject adapter&lt;/a&gt;, which could get embedding easier.&lt;/li&gt;&lt;li&gt;A&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;org&lt;/span&gt;&lt;span class="Apple-style-span"   style="font-family:Monaco;font-size:85%;"&gt;.&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;jruby&lt;/span&gt;&lt;span class="Apple-style-span"   style="font-family:Monaco;font-size:85%;"&gt;.&lt;/span&gt;Ruby object looks like is thread safe, no matter calling &lt;span class="Apple-style-span"  style="font-size:85%;"&gt;evalScriptlet&lt;/span&gt; / callMethod. Wrote a test for it and worked well in my case.&lt;/li&gt;&lt;li&gt;Call JavaEmbedUtils#terminate to tear down a ruby runtime object and release resources, which is important in tests, otherwise you probably get out-of memory error.&lt;/li&gt;&lt;li&gt;Be careful to use YAML to dump a ruby object to string and convert the string to Java String, then load it back later. It didn't work well in my case when there is non-string ruby object attribute inside the ruby object dumped. In my case, the object attribute inside was load as string object when load the dumped string. And I failed to write a simple case to reproduce the problem. Marshal works well for me. (I use JRuby 1.3.0RC2 in my case)&lt;/li&gt;&lt;li&gt;You can package ruby gem's lib directory with your Java code as jar file to publish it. (same with jruby complete jar)&lt;/li&gt;&lt;li&gt;When package ruby code inside jar file, should be careful with using 'File.dirname(__FILE__)' to locate file location, which may doesn't work anymore (The "File.dirname(__FILE__)" will be looked like "...xx/xxx.jar!yyyy/zzzz").&lt;/li&gt;&lt;li&gt;If you are depending on another JRuby gem (e.g. ActiveRecord-jdbc-adapter) which includes a jar file in lib, you should package with the class files instead of the jar file, or put the jar file separated with your jar file. Java could not load a jar inside a jar file.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5879990958708057129-6545841321534550554?l=1234533dlh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://1234533dlh.blogspot.com/feeds/6545841321534550554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5879990958708057129&amp;postID=6545841321534550554' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/6545841321534550554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/6545841321534550554'/><link rel='alternate' type='text/html' href='http://1234533dlh.blogspot.com/2009/05/tips-of-embedding-ruby-gem-in-java.html' title='Tips of embedding ruby gem in Java'/><author><name>Li Xiao</name><uri>http://www.blogger.com/profile/05224907707575784642</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://2.bp.blogspot.com/_1Kz0H2b8lbc/SL_hmgc6E_I/AAAAAAAADe0/d5NvWbqeF00/S220/xli.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5879990958708057129.post-3949382830607987224</id><published>2009-04-25T08:57:00.000-07:00</published><updated>2009-04-25T09:18:35.249-07:00</updated><title type='text'>Fireworks is back, a tool auto run tests in IntelliJ IDEA for you</title><content type='html'>&lt;div&gt;Back to Java project currently. Kent's JUnitMax makes me miss my Fireworks, so spend some time to fix it on IntelliJ IDEA 8.1. You can find it at &lt;a href="http://plugins.intellij.net/plugin/?id=1106"&gt;here&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When I started this project, the laptop I used was not power enough to run tests in background without bothering my development, so I got a running test progress bar popup in Fireworks.&lt;/div&gt;&lt;div&gt;The hardware is faster and better now.  The progress bar may bother someone now, I am removing it and making all tests running background, next version will come soon.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think I can call back my dream: don't make me test. It's about running tests bothers me, and write script or AllTests.java for running all tests bothers me. So I need a tool to help me to run tests and keep eyes on my edited and failures tests. In ruby world, there is one called ZenTest gem is doing similar thing. And JUnitMax is on eclipse.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another thing is considering:&lt;/div&gt;&lt;div&gt;  What's you like when a tool running test in background for you? &lt;/div&gt;&lt;div&gt;         1) paralleling all tests with high cpu cost but fast feedback&lt;/div&gt;&lt;div&gt;         2) one slow process but wouldn't bother you&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;TeamCity with IntelliJ ? I just don't have resource. So it's out.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5879990958708057129-3949382830607987224?l=1234533dlh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://1234533dlh.blogspot.com/feeds/3949382830607987224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5879990958708057129&amp;postID=3949382830607987224' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/3949382830607987224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/3949382830607987224'/><link rel='alternate' type='text/html' href='http://1234533dlh.blogspot.com/2009/04/fireworks-is-back-tool-auto-run-tests.html' title='Fireworks is back, a tool auto run tests in IntelliJ IDEA for you'/><author><name>Li Xiao</name><uri>http://www.blogger.com/profile/05224907707575784642</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://2.bp.blogspot.com/_1Kz0H2b8lbc/SL_hmgc6E_I/AAAAAAAADe0/d5NvWbqeF00/S220/xli.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5879990958708057129.post-7663091363840912256</id><published>2008-12-19T01:07:00.000-08:00</published><updated>2008-12-22T05:35:30.756-08:00</updated><title type='text'>Clean your setup methods</title><content type='html'>&lt;div&gt;I don't think &lt;a href="http://blog.jayfields.com/2007/06/testing-inline-setup.html"&gt;setup methods are evil(I agree most of the points discussed in the blog)&lt;/a&gt;, but I do think:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;It's not the right place to initialize test data. It is almost impossible that all your test methods would use all the same test data in the long term.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It's not the right place to initialize expectations of mocks. Do you ever put assertions in the setup method? Expectations of mocks are similar stuff with assertions. &lt;/li&gt;&lt;li&gt;Preparing test environment is right stuff put into setup method. Test environment is different with test data. Test environment is always same for all test methods, because a clean test environment is important for isolated test. For examples: preparing an empty messaging broker; preparing controller, request &amp;amp; response objects for rails functional test.&lt;/li&gt;&lt;li&gt;Use helper methods to organize your test domain. Even the code of preparing your test environment should be organized as proprietary helper with meaningful name, which is not only keeping your code readable &amp;amp; maintainable, but also keeping your setup methods simple. Mmm... I agree sometimes it's clean and clear you just put all your need in the setup methods.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Keeping setup method simple should always be considered when you are adding new code.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I cleaned a test setup method recently, the result I got was that the time of running the test was reduced from 200+ sec to 60+ sec. I felt good, and would keep doing it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5879990958708057129-7663091363840912256?l=1234533dlh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://1234533dlh.blogspot.com/feeds/7663091363840912256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5879990958708057129&amp;postID=7663091363840912256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/7663091363840912256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/7663091363840912256'/><link rel='alternate' type='text/html' href='http://1234533dlh.blogspot.com/2008/12/clean-your-setup-methods.html' title='Clean your setup methods'/><author><name>Li Xiao</name><uri>http://www.blogger.com/profile/05224907707575784642</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://2.bp.blogspot.com/_1Kz0H2b8lbc/SL_hmgc6E_I/AAAAAAAADe0/d5NvWbqeF00/S220/xli.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5879990958708057129.post-9201811512741068519</id><published>2008-10-26T05:35:00.000-07:00</published><updated>2008-10-26T07:14:04.755-07:00</updated><title type='text'>DTR 1.0.0 released: all about test grid</title><content type='html'>DTR is not a CI tool. It was supposed to be a tool only take responsibility of running test in distributed process to fit with test framework and CI tools.&lt;br /&gt;But it was so hard to build a test grid that DTR only did job of running test in distributed process. The hard part is synchronizing codebase within grid, which I thought Distributed SCM could help.&lt;br /&gt;&lt;br /&gt;DTR is also supposed to be used in an internal network that you never need to care about the network performance when you are running test. My team member got problem with working at home for he need run a long time test suite to commit code. One idea for fixing this problem is to use a CI tool to act as him in the office, and what he need to do is push his code to the codebase monitored by the CI. Yes, a pre-commit build. This actually is good for whole team.&lt;br /&gt;&lt;br /&gt;So I get impetus to improve DTR. And &lt;a href="http://dtr.rubyforge.org/"&gt;here&lt;/a&gt; is new release which provides new features for setting up more stable and maintainable test grid.&lt;br /&gt;&lt;br /&gt;Release 1.0.0 Changes:&lt;br /&gt;* support synchronizing codebase&lt;br /&gt;* lookup agents by broadcast&lt;br /&gt;* group agents for different project or environment usage&lt;br /&gt;* no need launch dtr rinda server anymore&lt;br /&gt;* agents log would be output into master process log&lt;br /&gt;&lt;br /&gt;You can find more info at here: &lt;a href="https://github.com/xli/dtr/tree"&gt;https://github.com/xli/dtr/tree&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;-------------&lt;br /&gt;Our new test grid built on CC.rb + Git + DTR is working well for a while.&lt;br /&gt;You may like to get a try, here is WPC's branch of CC.rb which fixed some Git plugin problems: &lt;a href="http://github.com/wpc/cruisecontrol.rb/tree/master"&gt;http://github.com/wpc/cruisecontrol.rb/tree/master&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It just need:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Make your project work with CC.rb + Git&lt;/li&gt;&lt;li&gt;Change your test task to be dtr test task. Of course, you need launch some DTR agent within your local network.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create cc projects for your team members, one member one project.&lt;/li&gt;&lt;/ol&gt;-------------&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's next release&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;On &lt;a href="http://studios.thoughtworks.com/mingle-agile-project-management/"&gt;Mingle&lt;/a&gt; project, we have script to make our test run in different process with different database, so that DTR doesn't handle running test in multi-processes with independency database for Rails project. I think it is a worth work.&lt;br /&gt;You can see the progress here: &lt;a href="http://github.com/xli/dtr/tree/v1.1.0"&gt;http://github.com/xli/dtr/tree/v1.1.0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;-&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5879990958708057129-9201811512741068519?l=1234533dlh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://1234533dlh.blogspot.com/feeds/9201811512741068519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5879990958708057129&amp;postID=9201811512741068519' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/9201811512741068519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/9201811512741068519'/><link rel='alternate' type='text/html' href='http://1234533dlh.blogspot.com/2008/10/dtr-100-released-all-about-test-grid.html' title='DTR 1.0.0 released: all about test grid'/><author><name>Li Xiao</name><uri>http://www.blogger.com/profile/05224907707575784642</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://2.bp.blogspot.com/_1Kz0H2b8lbc/SL_hmgc6E_I/AAAAAAAADe0/d5NvWbqeF00/S220/xli.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5879990958708057129.post-6232415858171550007</id><published>2008-10-05T07:46:00.000-07:00</published><updated>2008-11-14T21:00:26.618-08:00</updated><title type='text'>Introduce Hickey: prepare test data simple and fast by your Rails model</title><content type='html'>&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Spending long time on preparing test data bothers me.&lt;br /&gt;Spending long time to understand test data prepared for test bathers me.&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Suppose we have the following models:&lt;br /&gt;&lt;pre&gt;% class Project &amp;lt; ActiveRecord::Base&lt;br /&gt;%   has_many :tags&lt;br /&gt;%   has_many :cards&lt;br /&gt;% end&lt;br /&gt;%&lt;br /&gt;% class Tag &amp;lt; ActiveRecord::Base&lt;br /&gt;%   has_many :taggings, :class_name =&amp;gt; '::Tagging'&lt;br /&gt;%   belongs_to :project&lt;br /&gt;% end&lt;br /&gt;%&lt;br /&gt;% class Tagging &amp;lt; ActiveRecord::Base&lt;br /&gt;%   belongs_to :tag&lt;br /&gt;%   belongs_to :taggable, :polymorphic =&amp;gt; true&lt;br /&gt;% end&lt;br /&gt;%&lt;br /&gt;% class Card &amp;lt; ActiveRecord::Base&lt;br /&gt;%   has_many :taggings, :as =&amp;gt; :taggable&lt;br /&gt;%   belongs_to :project&lt;br /&gt;% end&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="Apple-style-span" style="font-family: Georgia; font-size: 16px; white-space: normal; "&gt;And we need prepare a domain for test:&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;ul&gt;&lt;li&gt;One project has 2 cards&lt;/li&gt;&lt;li&gt;Card one is tagged as 'first_tag'&lt;/li&gt;&lt;li&gt;Card two is tagged as 'ignore me'&lt;/li&gt;&lt;/ul&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Here is my new thoughts:&lt;br /&gt;&lt;pre&gt;% Hickey.dump :project =&amp;gt; {&lt;br /&gt;%   :identifier =&amp;gt; 'hickey', :cards =&amp;gt; [&lt;br /&gt;%     {&lt;br /&gt;%       :name =&amp;gt; 'first card',&lt;br /&gt;%       :taggings =&amp;gt; [{:tag =&amp;gt; {:name =&amp;gt; 'first_tag'}}],&lt;br /&gt;%     },&lt;br /&gt;%     {&lt;br /&gt;%       :name =&amp;gt; 'dont make me think',&lt;br /&gt;%       :taggings =&amp;gt; [{:tag =&amp;gt; {:name =&amp;gt; 'ignore me'}}]&lt;br /&gt;%     }&lt;br /&gt;%   ]&lt;br /&gt;% }&lt;br /&gt;&lt;span style="font-family:Georgia,serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia; font-size: 16px; white-space: normal; "&gt;More details or if you want to give it a shot, checkout &lt;a href="http://github.com/xli/hickey/tree/master"&gt;Hickey on github&lt;/a&gt;.&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5879990958708057129-6232415858171550007?l=1234533dlh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://1234533dlh.blogspot.com/feeds/6232415858171550007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5879990958708057129&amp;postID=6232415858171550007' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/6232415858171550007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/6232415858171550007'/><link rel='alternate' type='text/html' href='http://1234533dlh.blogspot.com/2008/10/introduce-hickey-prepare-test-data.html' title='Introduce Hickey: prepare test data simple and fast by your Rails model'/><author><name>Li Xiao</name><uri>http://www.blogger.com/profile/05224907707575784642</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://2.bp.blogspot.com/_1Kz0H2b8lbc/SL_hmgc6E_I/AAAAAAAADe0/d5NvWbqeF00/S220/xli.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5879990958708057129.post-5786196816480712073</id><published>2008-09-25T08:59:00.001-07:00</published><updated>2008-09-27T18:25:23.871-07:00</updated><title type='text'>MM: Development context console integrating with Mingle</title><content type='html'>MingleMingle project was deleted because of confusing name.&lt;br /&gt;It is renamed as "MM" and moved to &lt;a href="http://github.com/xli/mm/tree/master"&gt;here on Github&lt;/a&gt;.&lt;br /&gt;It still is an example project for integrating with Mingle by REST API in ruby.&lt;br /&gt;&lt;br /&gt;MM is redesigned as a console instead of command line tool for my daily work to remember my development context.&lt;br /&gt;&lt;br /&gt;The following is a feature list:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;transition: run on card, card transition list&lt;br /&gt;  &lt;/li&gt;&lt;li&gt;view card favorite&lt;/li&gt;&lt;li&gt;view card&lt;br /&gt;  &lt;/li&gt;&lt;li&gt;simple todo tasks tool&lt;/li&gt;&lt;li&gt;card/view context&lt;/li&gt;&lt;li&gt;remember your context history&lt;/li&gt;&lt;li&gt;do job by selecting item from list&lt;/li&gt;&lt;li&gt;integrating with terminal console: run console command directly&lt;/li&gt;&lt;li&gt;commit code with running transition&lt;/li&gt;&lt;/ul&gt; &lt;span style="font-weight: bold;"&gt;GEM Installation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Run the following if you haven't already:   gem sources -a http://gems.github.com&lt;br /&gt;&lt;br /&gt;Install the gem:   sudo gem install xli-mm&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Usage&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;MM Console should be following your local project repository directory, so that every project has its own context. Go to your project directory, for example, my dtr project repository is at ~/workspace/dtr, type 'mm' in the directory to launch the console.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;For integrating with Mingle, you need setup a variable in the MM console named 'site', the value should be your mingle project url with your login name and password, see the following example log how to setup it.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The following is an example log, after you installed mm gem and type 'mm' in your project directory:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt;&lt;br /&gt;mm, version 0.0.3&lt;br /&gt;Type 'help' for usage&lt;br /&gt;&gt; &gt; site='https://xli:mypassword@myproject.mycompany.com/projects/mingle'&lt;br /&gt;https://xli:mypassword@myproject.mycompany.com/projects/mingle&lt;br /&gt;mingle&gt; &gt; #5079&lt;br /&gt;#5079 Allow admin to update transition only property values - but preserve the use of automated transitions on the grid view&lt;br /&gt;mingle&gt; story 5079&gt; help&lt;br /&gt;&lt;br /&gt;0) Basic Commands&lt;br /&gt;1) Context&lt;br /&gt;2) Integrating With Mingle&lt;br /&gt;3) Quick Start&lt;br /&gt;4) Transition&lt;br /&gt;5) Variables&lt;br /&gt;&lt;br /&gt;! &gt; Type index number to select item from list.&lt;br /&gt;&lt;br /&gt;mingle&gt; story 5079&gt; 0&lt;br /&gt;- Runtime Variables: show existed runtime variables&lt;br /&gt;How to set a variable? example: fixed = 'complete fix'&lt;br /&gt;How to unset a variable? example: fixed = ''&lt;br /&gt;MM stores most of stuff as variables so that you can easily access them.&lt;br /&gt;- command keys or match pattern: variables, v&lt;br /&gt;&lt;br /&gt;- Clean Cache: clean current cached resource objects: (no object cached)&lt;br /&gt;- command keys or match pattern: clean_cache&lt;br /&gt;&lt;br /&gt;- Tabs: show tabs in your Mingle project&lt;br /&gt;- command keys or match pattern: tabs, t&lt;br /&gt;&lt;br /&gt;- Help: show this doc&lt;br /&gt;- command keys or match pattern: help&lt;br /&gt;&lt;br /&gt;- To Do: manage your todo list based on context&lt;br /&gt;- command keys or match pattern: todo( (.+))?&lt;br /&gt;&lt;br /&gt;- Open: Open card, view or your context(card or view) in your default browser. This command sends 'open 'http:/project_url' to your Terminal, which may not work in Windows.&lt;br /&gt;- command keys or match pattern: open( (.+))?&lt;br /&gt;&lt;br /&gt;mingle&gt; story 5079&gt; 1&lt;br /&gt;Context is something MM remembered for you. There are 2 kinds of context, one is card, another is view. Context will be displayed as prompt, so that you can know what's context you have currently. For example, if your context is a card, you can simply type in 'open' to open the card in your default browser.&lt;br /&gt;mingle&gt; story 5079&gt; name&lt;br /&gt;Performance Tuning: Transition execution&lt;br /&gt;mingle&gt; story 5079&gt; tabs&lt;br /&gt;&lt;br /&gt;0) 2.1 help updates&lt;br /&gt;1) forum bugs&lt;br /&gt;2) My Work&lt;br /&gt;3) Technical Debt&lt;br /&gt;4) QA Bugs to Close&lt;br /&gt;5) 2.1 Testing&lt;br /&gt;6) Dev Bugs to Fix&lt;br /&gt;&lt;br /&gt;! &gt; Type index number to select item from list.&lt;br /&gt;&lt;br /&gt;mingle&gt; story 5079&gt; 2&lt;br /&gt;&lt;br /&gt;0) #5022 Performance Tuning: Transition execution&lt;br /&gt;&lt;br /&gt;! &gt; Type index number to select item from list.&lt;br /&gt;&lt;br /&gt;mingle&gt; My Work&gt; 0&lt;br /&gt;#5022 Performance Tuning: Transition execution&lt;br /&gt;mingle&gt; task 5022&gt; properties&lt;br /&gt;---&lt;br /&gt;:"task status": open&lt;br /&gt;:priority: low&lt;br /&gt;:release: "2.1"&lt;br /&gt;:owner: 24&lt;br /&gt;mingle&gt; task 5022&gt;&lt;br /&gt;mingle&gt; task 5022&gt; history&lt;br /&gt;&lt;br /&gt;0) story 5079&lt;br /&gt;1) My Work&lt;br /&gt;2) task 5022&lt;br /&gt;&lt;br /&gt;! &gt; Type index number to select item from list.&lt;br /&gt;&lt;br /&gt;mingle&gt; task 5022&gt; 0&lt;br /&gt;#5079 Allow admin to update transition only property values - but preserve the use of automated transitions on the grid view&lt;br /&gt;mingle&gt; story 5079&gt; owner&lt;br /&gt;Suzie&lt;br /&gt;mingle&gt; story 5079&gt; transitions&lt;br /&gt;&lt;br /&gt;0) add story to internal release theme&lt;br /&gt;1) Complete Development&lt;br /&gt;2) move to 200&lt;br /&gt;&lt;br /&gt;! &gt; Type index number to select item from list.&lt;br /&gt;&lt;br /&gt;mingle&gt; story 5079&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MM TODOS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;xli:mm(master)$ mm&lt;br /&gt;&gt;&gt;&gt;&lt;br /&gt;mm, version 0.0.3&lt;br /&gt;Type 'help' for usage&lt;br /&gt;&gt; &gt; todo&lt;br /&gt;&lt;br /&gt;&lt;div style="color: rgb(204, 102, 0);"&gt;0) Start Work: output system cmd io directly instead of at the end of command&lt;/div&gt;&lt;div style="color: rgb(204, 102, 0);"&gt;1) Start Work: find cards by mql&lt;/div&gt;&lt;div style="color: rgb(204, 102, 0);"&gt;2) Start Work: todo command: delete all deletable option&lt;br /&gt;&lt;/div&gt;&lt;div style="color: rgb(204, 102, 0);"&gt;3) Start Work: todo command: delete all option&lt;br /&gt;&lt;/div&gt;&lt;div style="color: rgb(204, 102, 0);"&gt;4) Start Work: history object doesn't update bug&lt;/div&gt;&lt;div style="color: rgb(255, 0, 0);"&gt;5) Complete: should raise error when commit with invalid transition script&lt;/div&gt;&lt;div style="color: rgb(204, 102, 0);"&gt;6) Start Work: properties of card show id of user/card obj which should be name&lt;/div&gt;&lt;div style="color: rgb(204, 102, 0);"&gt;7) Start Work: reload context command&lt;/div&gt;&lt;div style="color: rgb(204, 102, 0);"&gt;8) Start Work: todo command: remove completed task after one day&lt;/div&gt;&lt;div style="color: rgb(255, 0, 0);"&gt;9) Complete: why get story from server again?&lt;/div&gt;&lt;div style="color: rgb(204, 102, 0);"&gt;10) Start Work: daily report?&lt;/div&gt;&lt;div style="color: rgb(153, 153, 153);"&gt;11) Delete: card&amp;amp;view should use business id for comparition&lt;/div&gt;&lt;div style="color: rgb(153, 153, 153);"&gt;12) Delete: output of open command is bad&lt;/div&gt;&lt;div style="color: rgb(153, 153, 153);"&gt;13) Delete: output of transition completed is bad&lt;/div&gt;&lt;div style="color: rgb(153, 153, 153);"&gt;14) Delete: better output of properties&lt;/div&gt;&lt;br /&gt;! &gt; Type index number to select item from list.&lt;br /&gt;&lt;br /&gt;&gt; &gt;&lt;br /&gt;----------------&lt;br /&gt;&lt;br /&gt;By the way, MM is only tested on Mac OS.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5879990958708057129-5786196816480712073?l=1234533dlh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://1234533dlh.blogspot.com/feeds/5786196816480712073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5879990958708057129&amp;postID=5786196816480712073' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/5786196816480712073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/5786196816480712073'/><link rel='alternate' type='text/html' href='http://1234533dlh.blogspot.com/2008/09/mm-development-context-console.html' title='MM: Development context console integrating with Mingle'/><author><name>Li Xiao</name><uri>http://www.blogger.com/profile/05224907707575784642</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://2.bp.blogspot.com/_1Kz0H2b8lbc/SL_hmgc6E_I/AAAAAAAADe0/d5NvWbqeF00/S220/xli.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5879990958708057129.post-3421428206449757344</id><published>2008-09-18T18:56:00.000-07:00</published><updated>2008-09-25T18:52:47.887-07:00</updated><title type='text'>Stand-up, Open your mouth</title><content type='html'>Got a small tool called &lt;a href="http://tech.inhelsinki.nl/antirsi/"&gt;AntiRSI&lt;/a&gt; for forcing you take regular breaks by freezing your screen 13 seconds(as default) after 4 mins work and freezing 8 mins after 50 mins work.&lt;br /&gt;&lt;br /&gt;It became to be fun when I paired with WPC. We decided to stand-up as quickly as possible once the notification popup.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5879990958708057129-3421428206449757344?l=1234533dlh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://1234533dlh.blogspot.com/feeds/3421428206449757344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5879990958708057129&amp;postID=3421428206449757344' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/3421428206449757344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/3421428206449757344'/><link rel='alternate' type='text/html' href='http://1234533dlh.blogspot.com/2008/09/stand-up-open-your-mouth.html' title='Stand-up, Open your mouth'/><author><name>Li Xiao</name><uri>http://www.blogger.com/profile/05224907707575784642</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://2.bp.blogspot.com/_1Kz0H2b8lbc/SL_hmgc6E_I/AAAAAAAADe0/d5NvWbqeF00/S220/xli.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5879990958708057129.post-3511552537841957362</id><published>2008-09-02T04:21:00.000-07:00</published><updated>2008-09-02T06:40:07.174-07:00</updated><title type='text'>Growing Test</title><content type='html'>On my current project(&lt;a href="http://studios.thoughtworks.com/mingle-project-intelligence"&gt;Mingle&lt;/a&gt;), we need 9 mins to run pre-commit tests, which is a little bit long for you to keep eyes on the test running status. When I found a rails plugin "Growl Tests", I got it was something I need for my daily work that Growl notification could call me back if I was doing something else during test running. But I don't like install a rails plugin to involve Growl notification for my project, because it is only for developer to run test and I want keep the installer script clean. And also, I need custom notifications for that my first idea was only notifying test fault. So I started another simple project &lt;a href="http://github.com/xli/growling_test/tree/master"&gt;Growling Test&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Later, WPC added test finished notification for getting running test status back in TextMate, which made Growling Test more fun. I don't remember when it happened first time that TextMate didn't output test framework standard output while running test_unit test framework test, but we do painful for no test framework standard output while running tests in TextMate.&lt;br /&gt;&lt;br /&gt;Growling Test has 3 notifications registered: test finished, test fault and all test finished. I put test finished notification on my laptop LCD, and put test fault and test finished notification on working monitor. Here is a growling notifications screenshot:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://github.com/xli/growling_test/tree/232d9e3739c891703c679d212c3265d12c0e4ac3%2Fscreenshot.jpg?raw=true"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 320px;" src="http://github.com/xli/growling_test/tree/232d9e3739c891703c679d212c3265d12c0e4ac3%2Fscreenshot.jpg?raw=true" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To involve Growling Test in your project, you need install Growling Test gem:&lt;br /&gt;&amp;nbsp;&amp;nbsp;Run the following if you haven't already:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gem sources -a http://gems.github.com&lt;br /&gt;&amp;nbsp;&amp;nbsp;Install the gem:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sudo gem install xli-growling_test&lt;br /&gt;&lt;br /&gt;And then put the following code in your test_helper.rb:&lt;br /&gt;&amp;nbsp;&amp;nbsp;require 'rubygems'&lt;br /&gt;&amp;nbsp;&amp;nbsp;require 'growling_test'&lt;br /&gt;&lt;br /&gt;Have fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5879990958708057129-3511552537841957362?l=1234533dlh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://1234533dlh.blogspot.com/feeds/3511552537841957362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5879990958708057129&amp;postID=3511552537841957362' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/3511552537841957362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/3511552537841957362'/><link rel='alternate' type='text/html' href='http://1234533dlh.blogspot.com/2008/09/growing-test.html' title='Growing Test'/><author><name>Li Xiao</name><uri>http://www.blogger.com/profile/05224907707575784642</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://2.bp.blogspot.com/_1Kz0H2b8lbc/SL_hmgc6E_I/AAAAAAAADe0/d5NvWbqeF00/S220/xli.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5879990958708057129.post-6113487273510151402</id><published>2008-04-28T00:02:00.000-07:00</published><updated>2008-04-28T07:06:15.200-07:00</updated><title type='text'>Build Development Build Grid by DTR 0.0.3</title><content type='html'>&lt;div&gt;&lt;a href="http://dtr.rubyforge.org/"&gt;DTR 0.0.3&lt;/a&gt; was released. It is a stable version for running a build grid.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;The following is an example build grid shared within developers to run unit tests before commit code. We‘ll use Mercurial to synchronize code between Runner Agent machines and developer machine.&lt;br /&gt;&lt;h3&gt;Background&lt;/h3&gt;Suppose I am a developer working on a rails project pet_store checked out at ’~/pet_store’. I have a MacBook called M1 and another 2 Mac-minis called M2 and M3. My plan is distributing tests running on M1 to M2 and M3 before commit code. M3 also will be DTR Server. All machines are accessable in local network and IPs are M1_IP, M2_IP and M3_IP. Mercurial and DTR are installed on all machines. And for running dtr runner agent in daemons mode, you need install gem daemons. The test environment will be running on Mysql. All machines are installed Mysql accessed by the following database.yml configuration:&lt;pre&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;development:&lt;br /&gt; database: pet_store_development&lt;br /&gt; adapter: mysql&lt;br /&gt; username: root&lt;br /&gt; password:&lt;br /&gt; host: localhost&lt;br /&gt;test:&lt;br /&gt; database: pet_store_test&lt;br /&gt; adapter: mysql&lt;br /&gt; username: root&lt;br /&gt; password:&lt;br /&gt; host: localhost&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt;DTR Server&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Start DTR Server on M3: dtr -s -a M3_IP. Home directory would be fine.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Setup Mercurial repository on M1&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Init Mercurial repository in ’~/pet_store’ directory: hg init&lt;/li&gt;&lt;li&gt;Edit .hgignore file to ignore files don‘t need while running tests. In this example, we will ignore files: db/schema.rb, .dtr_env_pstore, dtr_runners.pid and dtr_server*; and directories: public, tmp and log. Commit .hgignore and then commit code into Mercurial repository.&lt;/li&gt;&lt;li&gt;Start ‘hg serve’ in ’~/pet_store’, the default port would be 8000. We‘ll use the default port in this example.&lt;/li&gt;&lt;li&gt;We‘ll clone the repository to M2 and M3 later.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Build Script&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Add an environment variable on all machines: export DEV_BUILD_SERVER=M3_IP&lt;/li&gt;&lt;li&gt;Add an environment variable on development machine M1: export DTR_MASTER_ENV=http: //M1_IP:8000/pet_store. The environment variable&lt;br /&gt;DTR_MASTER_ENV would be copied to all DTR Runner Agent for sharing information between DTR Master machine and DTR Runner Agents.&lt;/li&gt;&lt;li&gt;Create a rake file at ’~/pet_store’ directory called: dtr_tasks.rake&lt;pre&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;DEV_BUILD_SERVER = ENV['DEV_BUILD_SERVER']&lt;br /&gt;DEV_REPOSITORY_URL = ENV['DTR_MASTER_ENV']&lt;br /&gt;&lt;br /&gt;task :dtr =&amp;gt; ['hg:check', 'dtr:uf']&lt;br /&gt;&lt;br /&gt;namespace :hg do&lt;br /&gt; task :reinit do&lt;br /&gt;   Dir.glob("*").each do |f|&lt;br /&gt;     #remove all files except files start with 'dtr_' including dtr runner pid file and current file dtr_tasks.rake&lt;br /&gt;     next if f =~ /^dtr_/&lt;br /&gt;     FileUtils.rm_rf(f)&lt;br /&gt;   end&lt;br /&gt;   FileUtils.rm_rf(".hg")&lt;br /&gt;   FileUtils.rm_rf(".hgignore")&lt;br /&gt;   puts %x[hg init]&lt;br /&gt;   puts %x[hg pull -u -y #{DEV_REPOSITORY_URL}]&lt;br /&gt;   puts %x[mkdir tmp]&lt;br /&gt;   puts %x[mkdir log]&lt;br /&gt; end&lt;br /&gt; task :check do&lt;br /&gt;   http = Net::HTTP.new("localhost", "8000")&lt;br /&gt;   begin&lt;br /&gt;     http.get("/")&lt;br /&gt;   rescue Exception&lt;br /&gt;     raise "Mercurial server is not running!"&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;   raise "Please commit changes into Mercurial repository" if %x[hg st] =~ /.+/&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;namespace :dtr do&lt;br /&gt; task :runner_agent do&lt;br /&gt;   puts %x[dtr -R;dtr -r runner -a '#{DEV_BUILD_SERVER}' -i 'rake --rakefile dtr_tasks.rake hg:reinit;rake db:migrate db:test:prepare' -D]&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; require 'dtr'&lt;br /&gt;&lt;br /&gt; DTR.broadcast_list = [DEV_BUILD_SERVER]&lt;br /&gt;&lt;br /&gt; DTR::MPTask.new(:uf) do |t|&lt;br /&gt;   t.libs &amp;lt;&amp;lt; "test"&lt;br /&gt;   t.test_files = FileList['test/unit/**/*test.rb', 'test/functional/**/*test.rb']&lt;br /&gt;   t.processes = ENV['P'] || 1&lt;br /&gt;   t.runner_options = "-a '#{DEV_BUILD_SERVER}' -i 'rake db:migrate db:test:prepare'"&lt;br /&gt;   t.start_server = false&lt;br /&gt;   t.verbose = false&lt;br /&gt; end&lt;br /&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;The script above can re-init Mercurial repository. Runner Agent will run the ‘hg:reinit’ task before start Runner(see the ‘runner_agent’ task in the script above), so that Runner Agent can support any developer‘s codebase to run tests.&lt;/li&gt;&lt;li&gt;Commit dtr_tasks.rake into Mercurial repository.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Runner Agent&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Clone repository from M1 to M2 in home directory: hg clone http://M1_IP:8000/pet_store&lt;/li&gt;&lt;li&gt;Start runner agent in the directory ~/pet_store on M2: rake —rakefile dtr_tasks.rake dtr:runner_agent&lt;/li&gt;&lt;li&gt;Start runner agent on M3 same with above.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Run DTR Master on M1&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Commit all changes into Mercurial&lt;/li&gt;&lt;li&gt;rake —rakefile dtr_tasks.rake dtr&lt;/li&gt;&lt;li&gt;After you started the DTR Master, you can&lt;br /&gt;type the following to monitor the DTR&lt;br /&gt;Server status: dtr -a $DEV_BUILD_SERVER -m&lt;/li&gt;&lt;li&gt;For output into console, open the debug option: dtr -a $DEV_BUILD_SERVER -d&lt;br /&gt;-m&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;h3&gt;Notes&lt;/h3&gt;&lt;h3&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Only one developer can run tests in grid at same time.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;You can build different grid for every developers, but it maybe too many runner agents need to maintain.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Runner Agent can run 2 or more runners, but you need more powerful db:test:prepare script to setup databases need and let every process run in different database. Here is one solution: 1. setup one database, then use database dump to quick clone more databases we need. 2. change database configuration to use an idle database when test start. &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/h3&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5879990958708057129-6113487273510151402?l=1234533dlh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://1234533dlh.blogspot.com/feeds/6113487273510151402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5879990958708057129&amp;postID=6113487273510151402' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/6113487273510151402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5879990958708057129/posts/default/6113487273510151402'/><link rel='alternate' type='text/html' href='http://1234533dlh.blogspot.com/2008/04/build-development-build-grid-by-dtr-003.html' title='Build Development Build Grid by DTR 0.0.3'/><author><name>Li Xiao</name><uri>http://www.blogger.com/profile/05224907707575784642</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://2.bp.blogspot.com/_1Kz0H2b8lbc/SL_hmgc6E_I/AAAAAAAADe0/d5NvWbqeF00/S220/xli.jpg'/></author><thr:total>0</thr:total></entry></feed>
