Having explained what TLB is and isn't, here are the steps to follow to incorporate test-load-balancing on your project's test-suite
$ gem install tlb-testunit19
for test::unit test suite on Ruby 1.9.x$ gem install tlb-testunit18
for test::unit test suite on Ruby 1.8.x$ gem install tlb-cucumber
for Cucumber test suite$ gem install tlb-rspec1
for RSpec-1.x (1.2.x, or 1.3.x etc) test suite$ gem install tlb-rspec2
for RSpec-2.x (2.4, or 2.3 etc) test suite$ tlb-x.x/server.sh start
For Windows:> tlb-x.x/server.bat start
Example of TLB balancer configuration for some of the supported frameworks
Feel free to copy the build task fragment relevant to the platform and tool-set your project uses into your build script and tweak the details to fit your project needs. In addition to project specific changes, you'll need to make other changes as suggested by the inline comments in relevant fragment(s).<!-- Change the 'load.balanced.classpath' so that it is your test classpath along with the TLB jar and its dependencies. You can also tweak the 'depends' to fix the task dependencies of your build. You can change the fileset's includes pattern to include your tests. --> <target name="test.balanced" depends="compile, compile-tests"> <typedef name="load-balanced-fileset" classname="tlb.ant.LoadBalancedFileSet" classpathref="load.balanced.classpath"/> <junit failureproperty="test.failure" printsummary="yes" haltonfailure="true" haltonerror="true" showoutput="true" fork="true"> <classpath refid="load.balanced.classpath"/> <batchtest todir="${reports.dir}"> <load-balanced-fileset dir="${test-classes.dir}" includes="**/*Test.class"/> <formatter classname="tlb.ant.JunitDataRecorder"/> <formatter type="plain"/> </batchtest> </junit> </target>
require 'rake' require 'rubygems' if RUBY_VERSION =~ /^1\.9/ gem 'tlb-testunit19' else gem 'tlb-testunit18' end require 'tlb/test_unit/test_task' Tlb::TestUnit::TestTask.new(:test_balanced) do |t| t.libs << "test" t.test_files = FileList['test/**/*_test.rb'] t.verbose = true end load 'tasks/tlb.rake' task :bal => ['tlb:start', :test_balanced]
#Use the task :bal to run balanced test suite. You can change the FileSet to match whatever tests you need #to run. require 'rubygems' gem 'tlb-rspec1' require 'tlb/spec/spec_task' Tlb::SpecTask.new(:balanced_specs) do |t| t.spec_files = FileList['spec/**/*_spec.rb'] t.spec_opts << "--format progress" end load 'tasks/tlb.rake' desc "run specs load-balanced(based on environment variables)" task :bal => ['tlb:start', :balanced_specs]
#Use the task :bal to run balanced test suite. You can change the t.pattern to match whatever tests you need #to run. require 'rubygems' gem 'tlb-rspec2' require 'tlb/rspec/spec_task' Tlb::RSpec::SpecTask.new(:run_balanced) do |t| t.pattern = 'spec/**/*_spec.rb' end load 'tasks/tlb.rake' desc "run specs load-balanced(based on environment variables)" task :bal => ['tlb:start', :run_balanced]
require 'rubygems' require 'cucumber' gem 'tlb-cucumber' require 'tlb/cucumber/rake/cucumber_task' Tlb::Cucumber::Rake::CucumberTask.new(:cucumber_tests) do |t| t.cucumber_opts = ["--format", "pretty"] end load 'tasks/tlb.rake' desc "Run Cucumber features in a load-balanced fashion (based on environment variables)" task :bal => ['tlb:start', :cucumber_tests]
TLB_BASE_URL=http://tlb-server-host.my-domain.com:7019
This tells TLB balancer where to obtain the test data from and post data to. Replace the use the appropriate hostname and port.
TLB_TOTAL_PARTITIONS=2
Total number of subsets/splits to be made. This should be equal to the number of machines/processes that are going to execute in this test-task parallely.
TLB_PARTITION_NUMBER=1
Controls which of the $TLB_TOTAL_PARTITIONS is the current partition. It decides which of all the computed subsets needs to be given to the current process's test-runner to execute. Assuming you have decided to go with 2 partitions, this variable will need to be set to 1 for the first partition, and 2 for the second. Its the one-based index of current subset.
TLB_JOB_NAME=sample_job
The same TLB server can be used by different builds from different projects at the same time. In order for the server to identify them uniquely, TLB uses a notion of name-space(we call it 'job name'). Make sure all job names are unique.
For instance, if you want to configure two projects, one that has a JUnit suite and is a Java project called 'foo', and other that is a Ruby project called 'bar' that is using TLB to balance Test::Unit based tests. The value for TLB_JOB_NAME can be 'foo' for the former and 'bar' for the later. However, if 'foo' in the subject has two different test suites, one that is a unit test suite, and another that is a JUnit functional test suite, you'd want to distinguish between those as well. Sensible job-names for the current scenario would probably be 'foo-unit' and 'foo-functional'. Of course, you can choose to name it anything.
TLB_JOB_VERSION=foo-project-${build_number}
Sometimes you may end up with multiple builds running at the same time, executing the same test-suite (i.e. has the same TLB_JOB_NAME). Now, when the test data is to be sent to the server, there needs to be a way for the server to identify the instance of the build that is reporting. All partitions running the same build instance should have the same value of TLB_JOB_VERSION and each build instance should use a unique TLB_JOB_VERSION. Here is a scenario that will help understand the importance of this variable, and the contract it enforces:
For a list of all the configuration variables and more details on configuration options refer to Configuring TLB.