Performance testing, slow clients, and how to simulate slow connections.

In general, performance testing is a set of methods, tools, and metrics with a target goal of knowing of how our service performs under the load. Managers come to the performance testers saying, guys we developed a pretty fast performed super duper service and want to know, of how it actually works under the load or in another words, if terabyte traffic hits us, would we be able to keep responding within milliseconds, microseconds, nanoseconds, etc .

That is generally translates to the set of the metrics more or less similar to these:

– Latency, or response time as a function of the number of the requests (transactions) per second that service generates over the time interval
– availability, or percentage of the positive/negative responses that service generates as a function of the number of the requests (transactions) per second over the time interval

Generally, these metrics should be generated for different type of the load separately, for set and get requests, for example, or for the mix of the requests in certain representations.

That are great metrics, no doubts about them, however, that is not it. Load can be absolutely different.

And now we are talking about fast and slow load. Slow clients generates much more problems for the services compare to the fast clients.

It takes time to open the connection, takes more time to transfer data as a request, and takes much more time to get a response back. It would literally take an hour 🙂 🙂 🙂 and during this hour resources are allocated, and cannot be released. Resources, both application resources (service itself) and system core resources (amount of the memory, number of the connections, etc) are used, but used much quickly. Compare to the fast client who do it fast and close the connection (or connection will timeout, eventually). Service can simply stop processing requests generated by slow clients or literally die while processing them.

Compare, for example 200 fast requests generated every second ( and took milliseconds to execute, respond, and disconnect) and 200 slow requests generate every same every second each, will use system resources for 10 seconds.

So, ideally, performance tests should be execute using both fast and slow clients. I would add the following metrics to the original list of metrics above

– memory usage as a function of the number of the connections per second
– CPU utilization as a function of the number of the connections per second

You can try running these tests with different slowness, and get much more metrics.

You can always timeout or dtrottle slow connections and defense your service, but that is not a scope of this post.

The question left is of how to simulate running performance test using slow clients. Well, you can always buy 10000 phone modems with speed from 2400 to 9600 bits per second on eBay, subscribe to tons of the phone lines, and job is done. It would actually a great solution, it will help to utilize old modems, lift the sales of pc-recycles sellers on eBay, etc. However, there is another solution, using the software.

Apache JMeter, has some Slow*.java classes simulating the given functionality. They were developed to simulate modems – exactly what we need.

SlowHttpClientSocketFactory.java
SlowSocket.java

This functionality is implemented in the sample class showing the usage of Slow connections (slow call, and normal call) in the following code. You just need to use the following jars from Apache JMeter: ApacheJMeter_core.jar, ApacheJMeter_http.jar, commons-codec-1.6.jar, commons-httpclient-3.1.jar, commons-logging-1.1.1.jar

Ant script to execute it and overall zipped solution is provided here.

Enjoy using it

Java code:

package example;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.jmeter.protocol.http.util.SlowHttpClientSocketFactory;

import java.io.IOException;

public class SlowConnectionSample {
    /*
    http://jmeter.512774.n5.nabble.com/Is-jmeter-can-be-used-to-simulate-network-bandwidth-td533487.html
    To emulate a bandwidth of, say 100 kbps, define a CPS of
    ( 100 * 1024 ) / 8, i.e. 100kB divided by 8, so, that would be
    httpclient.socket.http.cps=12800.

    @param kbpsRate, rate in *kilobits per second*
     */
    private static int calculateBandwidth(int kbpsRate) throws Exception {
        if (kbpsRate <= 0)
            throw new IllegalArgumentException("Rate (kbps) <= 0");

        return (kbpsRate * 1024) / 8;
    }

    public static void main(String args[]) throws Exception {

        /*
        Only the first call goes through the slow connection factory
         */
        int cps = SlowConnectionSample.calculateBandwidth(2);
        for (int i = 0; i < 2; i++) {
            if (0 == i)
                Protocol.registerProtocol("http", new Protocol("http", new SlowHttpClientSocketFactory(cps), 80));
            HttpClient httpClient = new HttpClient();
            GetMethod httpGet = new GetMethod("http://www.google.com");

            try {
                long timerBefore = System.currentTimeMillis();
                httpClient.executeMethod(httpGet);
                long timerAfter = System.currentTimeMillis();

                System.out.println("Call #" + i + "\tResponse: " + httpGet.getStatusLine() + "\tLatency: " + (double) (timerAfter - timerBefore) / 1000 + " sec.");
            } catch (IOException e) {
                System.out.println("Error: " + e.getMessage());
            } finally {
                httpGet.releaseConnection();
            }
            if (0 == i)
                Protocol.unregisterProtocol("http");
        }
    }
}

Output:

d:\etc\SlowConnection>ant -f build.xml
Buildfile: build.xml

....
run:
     [java] Call #0     Response: HTTP/1.1 200 OK       Latency: 8.406 sec.
     [java] Call #1     Response: HTTP/1.1 200 OK       Latency: 0.048 sec.

BUILD SUCCESSFUL
Total time: 1 minute 5 seconds

1 Comment

Filed under technology

Installing and configuring rsync server on CentOS 5 and use rsync client.

Sometimes you need to copy some files to one or number of the remote hosts and keep them updated with the latest version. In my example, I will be running performance tests and want to make sure each agent has the latest version. So, I am making changes on my Linux desktop and need to update all clients with the last changes. Yea, yea, I am aware about source control systems, however there are number of the reasons you can NOT to use them. As an example, you load generation machine may be located in the network sub-set where you should not have any code. So, there is some type of the deploying the code on certain machine. In the same time, and it is obvious you cannot use your Linux desktop in the corpnet to start any tests.

So, syncing the remote load generators with the certain libraries on your local machine may be done using rsync.

Configuring the server:

Install xinetd and rsync packages and make sure xinetd is running on levels 3, 4 and 5
$> sudo yum -y install xinetd rsync
$> sudo /sbin/chkconfig --level 345 xinetd on

Modify rsync xinetd configuration, and change disable = yes to disable = no
$> sudo vim /etc/xinetd.d/rsync

Create rsync secrets file for passwords with format of username:password.
$> sudo vim /etc/rsyncd.secrets

Create configuration for rsync shares
$> sudo vim /etc/rsyncd.conf

Example of using rsyncd.conf. Use man rsync or samba documentation for more details

## rsyncd.conf
secrets file = /etc/rsyncd.secrets
motd file = /etc/rsyncd.motd
read only = yes
list = yes
uid = nobody
gid = nobody

[out]
comment = IDML Perf code
path = /home/path/to/your/code/to/rsync

[confidential]
comment = For your eyes only
path = /home/rsync/secret-out
auth users =
hosts allow = *
hosts deny = *.microsoft.com
list = false

Fix up permissions and ownership, and restart xinetd service
$> sudo chown root.root /etc/rsyncd.*
$> sudo chmod 600 /etc/rsyncd.*
$> sudo /sbin/service xinetd restart

Test it out locally, you should get @RSYNCD:
$> telnet 127.0.0.1 873

IPTables Firewall

Add an iptables entry for rsync’s port.
$> sudo vim /etc/sysconfig/iptables

Add the following entry somewhere near the other protocols, but before the final drop line.

#
# rsync - add entry to allow 192.168.0.* to connect to our rsync server.
#
-A INPUT -s 192.168.0.0/255.255.255.0 -p tcp -m tcp --dport 873 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 873 -j DROP

Or use the GUI:

Start -> run command
Type system-config-selinux there and click Run
In the Security level dialog, escape "Other ports"
add port 873 for both TCP and UDP
Click Ok, confirm it by clicking Yes and start using it

Running the client:

On the remote machine:
$> rsync -arv your-user-name@host-with-code-to-sync:/home/path/to/your/code/to/rsync ./

And process has been started.

Enjoy !!!!

7 Comments

Filed under technology

Using Sinatra inside the Ruby Class and keep configuration data separately

Sinatra, http://www.sinatrarb.com is the very useful framework in Ruby if you need to build a web-service processing various requests – I suggest to use it to every team as a Mock QA environment where you can SIMPLY generate any type of the responses with any headers, cookies, http response codes, etc. I will write more about it, with examples, later. Anyway, let’ talk about setting sinatra.

You can find tons of the samples, something simular to this one showing that a couple lines of the code,a nd everything is up and running. Actually sinatra doc showing this examples:

## hi.rb
require 'sinatra'

get '/hi' do
"Hello World!"
end

and run it as
ruby -rubygems hi.rb
== Sinatra has taken the stage ...
>> Listening on 0.0.0.0:4567

And if you open a browser, type there http://localhost:4567/hi, you will see there “Hello World!”. Simple? yep, simple.

However, these days nobody develops simple applications. Majority of the applications are developed using classes/modules/etc. Plus, that is a good idea to split actual code from the configuration parameters. My post is mostly of how to do it. As usual, you can find tons of the examples, but in order to glue all of the examples into one simple workable solution, you need to apply some work. That is the result of this work.

That is a class MyAppClass, that needs
a) to be inherited from Sinatra::Base
b) should have port and bind setup

$ cat site-simple.rb
#!/usr/bin/env ruby

require 'rubygems'
require 'sinatra'
require 'sinatra/base'

class MyAppClass< Sinatra::Base set :logging, true set :dump_error, true set :raise_errors, true set :show_exceptions, true ## set :bind, '0.0.0.0' ## set :port, 8080 def do_something_used_in_sinatra_app(var) end get '/hi' do puts("Inside Hi") return [200, {}, 'Hi, we are inside Hello World!!'] end end
There is a config file for the MyAppClass above
$ cat config.ru
require './site-simple.rb'
MyAppClass.run! :port => 8080, :bind => '0.0.0.0'

Now you can run this as
$ ruby ./config.ru

and that is what you see in the logs:
== Sinatra/1.3.1 has taken the stage on 8080 for development with backup from Thin
>> Thin web server (v1.3.1 codename Triple Espresso)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:8080, CTRL+C to stop

and when you type http://localhost:8080/hi in the browser, you will see "Hi, we are inside Hello World!!" in it, and the following entry on the logs
Inside Hi
192.168.10.224 - - [20/Jan/2012 20:14:07] "GET /hi HTTP/1.1" 200 31 0.0019

3 Comments

Filed under technology

Sample of using log4r with Ruby classes, local and global loggers.

That is a very popular family of the loggers, people use when they develop a code in various languages like log4j for Java,. Today we will be talking about log4r, logger for Ruby, and I will show you of how to use them in the Ruby classes.

It seems that an official documentation mentions it very clear:

require 'log4r'
include Log4r

# create a logger named 'mylog' that logs to stdout
mylog = Logger.new 'mylog'
mylog.outputters = Outputter.stdout

# Now we can log.
def do_log(log)
log.debug "This is a message with level DEBUG"
end
do_log(mylog)

The output will look something like this:

DEBUG mylog: This is a message with level DEBUG

However, when you try to add it into you Ruby class, using so Java concepts and/or your experience with log4j, and you write a code similar to this one, you figure out that this code simply does not work:

require 'log4r'
include Log4r

class MyClass
mylog = Logger.new 'mylog'
mylog.outputters = Outputter.stdout
def my_method
log.debug "This is a message with level DEBUG"
end
end

cl = MyClass.new
cl.my_method

You are expecting that adding loggers into the existed code is a simple procedure, however, you should write some “wrapper” code. That is a code for Global (project wide) and Local (class wide) log4r loggers and their usage in different classes. As usual you can download these files from my repository.


$> cat log4r_loggers.rb
#!/usr/bin/env ruby

require 'rubygems'
require 'log4r'
include Log4r
require 'singleton'

## Global, project wide logger. May be called from any place of the project w/o
## any additional includes
## Usage sample:
## gloggerCF.debug "Logging to console and File: myHash: #{myHash}"
##
## It is currently implements three functions:
## gloggerC() - logging to STDOUT
## gloggerF() - logging to FILE
## gloggerCF() - logging to both STDOUT and FILE
##

GLOBAL_LOGGER_LOG_FILE = "/tmp/conn_pool.log"

class GlobalLogger
include Singleton
attr_reader :gloggerC
attr_reader :gloggerF
attr_reader :gloggerCF

def initialize
@gloggerC= Logger.new("GlobalLoggerConsole")
@gloggerF = Logger.new("GlobalLoggerFile")
@gloggerCF = Logger.new("GlobalLoggerConsoleAndFile")

pf = PatternFormatter.new(:pattern => "%C: #{self.class} %d %l %m Trace: %t")

so = StdoutOutputter.new("console", :formatter => pf)
@gloggerC.outputters << so @gloggerC.level = DEBUG fo = FileOutputter.new("f1", :filename => GLOBAL_LOGGER_LOG_FILE, :trunc => false, :formatter => pf)
@gloggerF.outputters << fo @gloggerF.level = DEBUG @gloggerCF.outputters << so @gloggerCF.outputters << fo @gloggerCF.level = DEBUG end end module Kernel def gloggerC GlobalLogger.instance.gloggerC end def gloggerF GlobalLogger.instance.gloggerF end def gloggerCF GlobalLogger.instance.gloggerCF end end ## Local, class wide logger. Should have include LocalLogger added to the class, logger is used ## Usage sample: ## class A ## include LocalLogger ## def method ## loggerCF.debug "Logging to console and File: myHash: #{myHash}" ## end ## end ## ## It is currently implements three functions: ## loggerC() - logging to STDOUT ## loggerF() - logging to FILE ## loggerCF() - logging to both STDOUT and FILE ## ## if LOCAL_LOGGER_LOG_FILE not specified, "/tmp/" + self.class.to_s + "./log" will be used ## LOCAL_LOGGER_LOG_FILE = nil module LocalLogger def loggerC @logger = Logger.new("LocalLoggerConsole") pf = PatternFormatter.new(:pattern => "%C: #{self.class} %d %l %m Trace: %t")

so = StdoutOutputter.new("console", :formatter => pf)
@logger.outputters << so @logger.level = DEBUG @logger end def loggerF logFile = (LOCAL_LOGGER_LOG_FILE.nil?) ? "/tmp/" + self.class.to_s + ".log" : LOCAL_LOGGER_LOG_FILE @logger = Logger.new("LocalLoggerFile") pf = PatternFormatter.new(:pattern => "%C: #{self.class} %d %l %m Trace: %t")

fo = FileOutputter.new("f1", :filename => logFile, :trunc => false, :formatter => pf)
@logger.outputters << fo @logger.level = DEBUG @logger end def loggerCF logFile = (LOCAL_LOGGER_LOG_FILE.nil?) ? "/tmp/" + self.class.to_s + ".log" : LOCAL_LOGGER_LOG_FILE @logger = Logger.new("LocalLoggerConsoleAndFile") pf = PatternFormatter.new(:pattern => "%C: #{self.class} %d %l %m Trace: %t")

so = StdoutOutputter.new("console", :formatter => pf)
fo = FileOutputter.new("f1", :filename => logFile, :trunc => false, :formatter => pf)

@logger.outputters << so @logger.outputters << fo @logger.level = DEBUG @logger end end

Usage:


$> cat use_log4r_loggers.rb
#!/usr/bin/env ruby

require 'rubygems'
require './log4r_loggers.rb'

class MyGlobalClass
def fname
gloggerC.debug "Inside MyGlobalClass, debug message to console"
gloggerF.debug "Inside MyGlobalClass, debug message to file"
mySm = {'key1' => 22, 'key2' => 56}
myHash = {'a' => 1, 'b' => 5, 'c' => mySm}
gloggerC.debug "Inside MyGlobalClass, debug message to console: #{myHash}"
gloggerF.debug "Inside MyGlobalClass, debug message to file: #{myHash}"
gloggerCF.debug "Inside MyGlobalClass, debug message to console/file: #{myHash}"
end
end

class MyWomanClass
include LocalLogger
def fname
loggerC.debug "Inside MyWomanClass, debug message to console"
loggerF.debug "Inside MyWomanClass, debug message to file"
loggerCF.debug "Inside MyWomanClass, debug message to console/file"
end
end

class MyManClass
include LocalLogger
def fname
loggerC.debug "Inside MyManClass, debug message to console"
loggerF.debug "Inside MyManClass, debug message to file"
loggerCF.debug "Inside MyManClass, debug message to console/file"
end
end

myG = MyGlobalClass.new
myG.fname
myM = MyManClass.new
myM.fname
myW = MyWomanClass.new

Leave a Comment

Filed under technology

Simple connection pool for MySQL implemented in Ruby

I needed a simple mysql connection pool in Ruby supporting get/release connection from/to pool and delete a connection pool on the end.

That is the code, together with unit tests – samples of the usage, and test runner

#!/usr/bin/env ruby

require 'test/unit'
require 'thread'
require 'mysql'

module ConnectionPool

Database = {: User => 'root',
: Password => 'pass',
: Host => 'localhost',
: Database => 'tra_db',
: ConnString => 'DBI:Mysql:tra_db:localhost',
: Connections => 10,
: Timeout => 1, }

class ConnectionPoolClass

CONN_POOL_RETURN_SLEEP = 0.001
CONN_POOL_DELETE_SLEEP = 0.001

@@instance = nil
@@instance_mutex = Mutex.new

def self.get_instance(config = Database)
@@instance_mutex.synchronize {
@@instance ||= self.new(config)
}
end

def initialize(config = Database)
@config = Database.dup.update(config)
@free_connections = []
@used_connections = []
@num_busy = 0
@max_allowed = @config[:Connections]
@monitor_mutex = Mutex.new
@free_mutex = Mutex.new

@max_allowed.times do |i|
new_conn = create_connection
@free_connections.push new_conn unless (nil == new_conn)
end
raise "Errors creating connection pool, expected #{@max_allowed} conn, but created #{free_pool_size}" unless (@max_allowed == free_pool_size)
end

## return the number of free connections in the pool
public
def free_pool_size
@monitor_mutex.synchronize {
@free_connections.size
}
end

## return the number of used connections in the pool
public
def use_pool_size
@monitor_mutex.synchronize {
@used_connections.size
}
end

## get a connection from the pool
public
def get_connection
yield(connection = get_conn_from_pool)
release_connection(connection)
return connection
end

## get a connection from the pool
protected
def get_conn_from_pool
@free_mutex.synchronize do |i|
while @free_connections.empty?
sleep(CONN_POOL_RETURN_SLEEP)
end
conn = @free_connections.pop
@used_connections.push(conn)
return conn
end
end

## release a connection back to the pool to use by somebody else
public
def release_connection(connection)
@monitor_mutex.synchronize do |i|
@free_connections.push connection
conn_idx = @used_connections.index connection
@used_connections.pop conn_idx unless (nil == conn_idx)
end
end

## creates a connection and return its handler or return nil. Used by initialize() only
private
def create_connection
dbh = Mysql.init
dbh.real_connect(@config[:Host], @config[:User], @config[:Password], @config[:Database])
return dbh
rescue Mysql::Error => e
puts e.errno
puts e.error
return nil
end

## close a particular given connection. Should stay private since it is used by
## delete_connection_pool() method only
private
def close_connection (dbh)
dbh.close if dbh
rescue Mysql::Error => e
puts e.errno
puts e.error
end

## Entirely delete connection pool. Close all connections and empty all arrays
public
def delete_connection_pool
@used_connections.each do |conn|
release_connection(conn)
end
@free_connections.each do |conn|
close_connection(conn)
sleep(CONN_POOL_DELETE_SLEEP)
end
@used_connections.clear
@free_connections.clear
end
end

end

Ideas are received here

1 Comment

Filed under technology

Linux equivalent of prstat

I was intently used prstat Unix command on Sun Solaris trying to gather the information of number of the threads per process trying to audit the software fired threads per request to perform an action (need to skip details of the project).

That is just small helper that does the same on Linux

ps -o nlwp -p 7447

In addition, you might want (sorry, habits) to look for a Linux equivalent to Sun Solaris prstat -a command, that returns something like that:

 NPROC USERNAME  SWAP   RSS MEMORY      TIME  CPU
    24 root      211M  218M   2.7%  65:36:22 0.1%
     3 azarutin 6672K   13M   0.2%   0:00:00 0.0%
     1 abcd     4312K 7664K   0.1%   0:00:19 0.0%
     1 nagios    496K 4440K   0.1%   0:16:31 0.0%
     7 daemon   8840K 9832K   0.1%   0:20:18 0.0%<

The following Perl code does almost the same:

#!/usr/bin/env perl

my @ps = `/bin/ps aux`;
my @headers = split(/\s+/, shift(@ps));
my %users;

foreach (@ps) {
  chomp;
  my $col = 0;
  my %ps_entry;
  foreach (split(/\s+/, $_, $#headers + 1)) {
    $ps_entry{$headers[$col]} = $_;
    $col++;
  }

  next unless exists $ps_entry{USER};
  $users{$ps_entry{USER}} = { nproc=>0, size=>0, rss=>0, mem=>0, time=>0, cpu=>0 } unless exists $users{$ps_entry{USER}};
  my $user = $users{$ps_entry{USER}};

  $user->{nproc}++;
  $user->{size} += $ps_entry{VSZ} if exists $ps_entry{VSZ};
  $user->{rss} += $ps_entry{RSS} if exists $ps_entry{RSS};
  $user->{mem} += $ps_entry{'%MEM'} if exists $ps_entry{'%MEM'};
  $user->{cpu} += $ps_entry{'%CPU'} if exists $ps_entry{'%CPU'};
  $user->{time} += ($1 * 60) + $2 if (exists $ps_entry{'TIME'} && $ps_entry{'TIME'} =~ /^([0-9]+):([0-9]+)$/);
}

print "NPROC\tUSER\tSIZE\tRSS\tMEMORY\tTIME\tCPU\n";
foreach (sort { $users{$b}{cpu} <=> $users{$a}{cpu} } keys(%users)) {
  printf("%d\t%s\t%d\t%d\t%.1f\%\t%.2d:%.2d\t%.1f\%\n", $users{$_}{nproc}, $_, $users{$_}{size}, $users{$_}{rss}, $users{$_}{mem}, ($users{$_}{time} / 60), ($users{$_}{time} % 60), $users{$_}{cpu});
}

and returns the following result:

[azarutin@hope server]$ ./prstat.pl
NPROC   USER    SIZE    RSS     MEMORY  TIME    CPU
62      azarutin        3955900 2308224 41.1%   82:07   1.1%
1       ntp     4420    4416    0.0%    00:00   0.0%
1       rpc     1924    524     0.0%    00:00   0.0%
1       smmsp   8300    1516    0.0%    00:00   0.0%
1       ricci   8288    1048    0.0%    00:00   0.0%
3       68      10596   3016    0.0%    00:10   0.0%
1       nobody  1932    432     0.0%    00:00   0.0%
1       dbus    3320    1332    0.0%    00:10   0.0%
1       rpcuser 2084    840     0.0%    00:00   0.0%
1       mysql   135408  23004   0.4%    00:01   0.0%
1       xfs     4360    2244    0.0%    00:01   0.0%
117     root    681476  101284  0.8%    21:31   0.0%
2       avahi   6456    1672    0.0%    00:41   0.0%

Enjoy !!!

12 Comments

Filed under technology

Grinder, a Java Load Testing Framework. Using custom headers, cookies and payload in GET, PUT, POST, DELETE, OPTIONS HTTP methods

Adding headers, cookies, and payload for various HTTP methods in Grinder, a Java Load Testing Framework, is unfortunately, is not intuitively clear. So the following sample should make life much easier: we specify custom header, cookies, and payload for the mentioned HTTP methods.

Link to the Grinder: http://grinder.sourceforge.net/

# Sample of using custom headers and cookies for GET, PUT, POST, DELETE, OPTIONS HTTP
# methods for Grinder Load Framework

from net.grinder.script.Grinder import grinder
from net.grinder.script import Test, Statistics
from net.grinder.plugin.http import HTTPRequest, HTTPPluginControl
from HTTPClient import NVPair, Cookie, CookieModule, CookiePolicyHandler, HTTPResponse

from java.util import Date

log = grinder.logger.output

globalDebugOutput = True
filename = "/tmp/cookies.log"

# We declare a default URL for the HTTPRequest.
getRequest = HTTPRequest(url = "http://localhost:8080")
putRequest = HTTPRequest(url = "http://localhost:8080")
postRequest = HTTPRequest(url = "http://localhost:8080")
deleteRequest = HTTPRequest(url = "http://localhost:8080")
optionsRequest = HTTPRequest(url = "http://localhost:8080")

payload = [NVPair('param', 'that is a custom payload')]

## We declare various cookies sets for each type of the request
expiryDate = Date()
expiryDate.year += 10

cookieGetOne = Cookie("keyGetOne", "12345","localhost", "/", expiryDate, 0)
cookieGetTwo = Cookie("keyGetTwo", "10000","localhost", "/", expiryDate, 0)
cookiePutOne = Cookie("keyPutOne", "12345","localhost", "/", expiryDate, 0)
cookiePutTwo = Cookie("keyPutTwo", "10000","localhost", "/", expiryDate, 0)
cookiePostOne = Cookie("keyPostOne", "12345","localhost", "/", expiryDate, 0)
cookiePostTwo = Cookie("keyPostTwo", "10000","localhost", "/", expiryDate, 0)
cookieDeleteOne = Cookie("keyDeleteOne", "12345","localhost", "/", expiryDate, 0)
cookieDeleteTwo = Cookie("keyDeleteTwo", "10000","localhost", "/", expiryDate, 0)
cookieOptionsOne = Cookie("keyOptionsOne", "12345","localhost", "/", expiryDate, 0)
cookieOptionsTwo = Cookie("keyOptionsTwo", "10000","localhost", "/", expiryDate, 0)

# Set up a cookie handler to log all cookies that are sent and received.
class MyCookiePolicyHandler(CookiePolicyHandler):
def acceptCookie(self, cookie, request, response):
log("accept cookie: %s" % cookie)
return 1

def sendCookie(self, cookie, request):
log("send cookie: %s" % cookie)
return 1

CookieModule.setCookiePolicyHandler(MyCookiePolicyHandler())

def printCookiesIntoFile(cookies, logFileName):
if (globalDebugOutput):
FILE = open(logFileName,"a+")
for c in cookies: FILE.write("retrieved cookie: %s\n" % c)
FILE.close()

# GET
def page1Get():
# Now let's add a new cookie.
threadContextGet = HTTPPluginControl.getThreadHTTPClientContext()

CookieModule.addCookie(cookieGetOne, threadContextGet)
CookieModule.addCookie(cookieGetTwo, threadContextGet)

headersGet = \
( NVPair('Custom_Header_One', 'Any tests GET'),
NVPair('Accept-Language', 'en-us,en;q=0.5'),
NVPair('User-Agent', 'Grinder HTTP-GET Mozilla/5.0'), )
getRequest.setHeaders(headersGet)

httpResp = getRequest.GET('/get?param=22¶m2=papa')
if ( 500 == httpResp.getStatusCode() ):
statistics = grinder.statistics.getForCurrentTest()
statistics.success = 0 # Mark test as bad.

# Get all cookies for the current thread and write them to the log
cookies = CookieModule.listAllCookies(threadContextGet)
printCookiesIntoFile(cookies, filename)

# PUT
def page2Put():
threadContextPut = HTTPPluginControl.getThreadHTTPClientContext()

CookieModule.addCookie(cookiePutOne, threadContextPut)
CookieModule.addCookie(cookiePutTwo, threadContextPut)

headersPut = \
( NVPair('Custom_Header_One', 'Any tests PUT'),
NVPair('Accept-Language', 'en-us,en;q=0.5'),
NVPair('User-Agent', 'Grinder HTTP-PUT Mozilla/5.0'), )

putRequest.setHeaders(headersPut)
putRequest.setFormData(payload)
httpResp = putRequest.PUT('/put')
if ( 500 == httpResp.getStatusCode() ):
statistics = grinder.statistics.getForCurrentTest()
statistics.success = 0 # Mark test as bad.

cookies = CookieModule.listAllCookies(threadContextPut)
printCookiesIntoFile(cookies, filename)

# POST
def page3Post():
threadContextPost = HTTPPluginControl.getThreadHTTPClientContext()

CookieModule.addCookie(cookiePostOne, threadContextPost)
CookieModule.addCookie(cookiePostTwo, threadContextPost)

headersPost = \
( NVPair('Custom_Header_One', 'Any tests POST'),
NVPair('Accept-Language', 'en-us,en;q=0.5'),
NVPair('User-Agent', 'Grinder HTTP-POST Mozilla/5.0'), )
postRequest.setHeaders(headersPost)
postRequest.setFormData(payload);
httpResp = postRequest.POST('/post')
if ( 500 == httpResp.getStatusCode() ):
statistics = grinder.statistics.getForCurrentTest()
statistics.success = 0 # Mark test as bad.

cookies = CookieModule.listAllCookies(threadContextPost)
printCookiesIntoFile(cookies, filename)

# DELETE
def page4Delete():
threadContextDelete = HTTPPluginControl.getThreadHTTPClientContext()

CookieModule.addCookie(cookieDeleteOne, threadContextDelete)
CookieModule.addCookie(cookieDeleteTwo, threadContextDelete)

headersDelete = \
( NVPair('Custom_Header_One', 'Any tests DELETE'),
NVPair('Accept-Language', 'en-us,en;q=0.5'),
NVPair('User-Agent', 'Grinder HTTP-DELETE Mozilla/5.0'), )

deleteRequest.setHeaders(headersDelete)
deleteRequest.setFormData(payload);
httpResp = deleteRequest.DELETE('/delete')
if ( 500 == httpResp.getStatusCode() ):
statistics = grinder.statistics.getForCurrentTest()
statistics.success = 0 # Mark test as bad.

cookies = CookieModule.listAllCookies(threadContextDelete)
printCookiesIntoFile(cookies, filename)

# OPTIONS
def page5Options():
threadContextOptions = HTTPPluginControl.getThreadHTTPClientContext()

CookieModule.addCookie(cookieOptionsOne, threadContextOptions)
CookieModule.addCookie(cookieOptionsTwo, threadContextOptions)

headersOptions = \
( NVPair('Custom_Header_One', 'Any tests OPTIONS'),
NVPair('Accept-Language', 'en-us,en;q=0.5'),
NVPair('User-Agent', 'Grinder HTTP-OPTIONS Mozilla/5.0'), )
optionsRequest.setHeaders(headersOptions)
optionsRequest.setFormData(payload);
httpResp = optionsRequest.OPTIONS('/options')
if ( 500 == httpResp.getStatusCode() ):
statistics = grinder.statistics.getForCurrentTest()
statistics.success = 0 # Mark test as bad.

cookies = CookieModule.listAllCookies(threadContextOptions)
printCookiesIntoFile(cookies, filename)

page1GetTest = Test(1, "HTTP-GET").wrap(page1Get)
page2PutTest = Test(2, "HTTP-PUT").wrap(page2Put)
page3PostTest = Test(3, "HTTP-POST").wrap(page3Post)
page4DeleteTest = Test(4, "HTTP-DELETE").wrap(page4Delete)
page5OptionsTest = Test(5, "HTTP-OPTIONS").wrap(page5Options)

class TestRunner:
def __call__(self):
page1GetTest()
page2PutTest()
page3PostTest()
page4DeleteTest()
page5OptionsTest()

7 Comments

Filed under technology

Installing Ruby, RVM, JRuby on CentOS 5

Ruby RVM, or Ruby Version Manager is a very convenient way of running multiple versions of ruby/jruby on the same machine without install/uninstall it every time. It also applies with using different ruby gem verionsets.

You should be aware, that ruby gems used with RVM are not transparent. It means that once you installed gem for ruby 1.9.3 and change the usage to ruby 1.6.3, you have to install all ruby gems for the given ruby version again.

Unfortunately, its installation is a little bit tricky as well as its usage.

I. Installing ruby

There are number of the ways of how ruby is installed, yum, from the the source, etc, so I skip this part. I personally, prefer an installation from the source

$> /usr/bin/env ruby -v
ruby 1.9.3p0 (2011-10-30 revision 33570) [i686-linux]

II. Installing GIT, that it is required for RVM installation:

It seems that there is no GIT available through base CentOS 5 repository, so I found a third-party repository, that seems works pretty good. They operate a term of “latest”, that on the time of writing the article is GIT 1.7.6.

$> sudo rpm -Uvh http://repo.webtatic.com/yum/centos/5/latest.rpm

Retrieving http://repo.webtatic.com/yum/centos/5/latest.rpm
warning: /var/tmp/rpm-xfer.54Xo8g: Header V3 DSA signature: NOKEY, key ID cf4c4ff9
Preparing... ########################################### [100%]
1:webtatic-release ########################################### [100%]

$> sudo yum install --enablerepo=webtatic git-all

Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.ecvps.com
* extras: mirrors.cat.pdx.edu
* updates: mirror.nwresd.org
webtatic | 951 B 00:00
webtatic/primary | 51 kB 00:00
webtatic 318/318
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package git-all.i386 0:1.7.6.1-1.w5 set to be updated
--> Processing Dependency: gitk = 1.7.6.1-1.w5 for package: git-all
--> Processing Dependency: git = 1.7.6.1-1.w5 for package: git-all
--> Processing Dependency: git-cvs = 1.7.6.1-1.w5 for package: git-all
--> Processing Dependency: git-gui = 1.7.6.1-1.w5 for package: git-all
--> Processing Dependency: emacs-git = 1.7.6.1-1.w5 for package: git-all
--> Processing Dependency: git-email = 1.7.6.1-1.w5 for package: git-all
--> Processing Dependency: perl-Git = 1.7.6.1-1.w5 for package: git-all
--> Processing Dependency: git-svn = 1.7.6.1-1.w5 for package: git-all
--> Running transaction check
---> Package emacs-git.i386 0:1.7.6.1-1.w5 set to be updated
--> Processing Dependency: emacs-common for package: emacs-git
---> Package git.i386 0:1.7.6.1-1.w5 set to be updated
--> Processing Dependency: perl(Error) for package: git
---> Package git-cvs.i386 0:1.7.6.1-1.w5 set to be updated
--> Processing Dependency: cvsps for package: git-cvs
---> Package git-email.i386 0:1.7.6.1-1.w5 set to be updated
--> Processing Dependency: perl(Authen::SASL) for package: git-email
--> Processing Dependency: perl(Net::SMTP::SSL) for package: git-email
---> Package git-gui.i386 0:1.7.6.1-1.w5 set to be updated
---> Package git-svn.i386 0:1.7.6.1-1.w5 set to be updated
--> Processing Dependency: perl(SVN::Core) for package: git-svn
--> Processing Dependency: perl(Term::ReadKey) for package: git-svn
---> Package gitk.i386 0:1.7.6.1-1.w5 set to be updated
---> Package perl-Git.i386 0:1.7.6.1-1.w5 set to be updated
--> Running transaction check
---> Package cvsps.i386 0:2.1-7.el5 set to be updated
---> Package emacs-common.i386 0:21.4-24.el5 set to be updated
---> Package perl-Authen-SASL.noarch 0:2.13-1.el5.rf set to be updated
---> Package perl-Error.noarch 1:0.17010-1.el5 set to be updated
---> Package perl-Net-SMTP-SSL.noarch 0:1.01-1.el5.rf set to be updated
---> Package perl-TermReadKey.i386 0:2.30-4.el5 set to be updated
---> Package subversion-perl.i386 0:1.6.13-0.1.el5.rf set to be updated
--> Processing Dependency: subversion = 1.6.13-0.1.el5.rf for package: subversion-perl
--> Running transaction check
--> Processing Dependency: libsvn_ra_dav-1.so.0 for package: subversion-devel
--> Processing Dependency: subversion = 1.6.11-7.el5_6.4 for package: subversion-devel
---> Package subversion.i386 0:1.6.13-0.1.el5.rf set to be updated
--> Running transaction check
---> Package subversion-devel.i386 0:1.6.13-0.1.el5.rf set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================
Package Arch Version Repository Size
============================================================================================================================================
Installing:
git-all i386 1.7.6.1-1.w5 webtatic 13 k
Installing for dependencies:
cvsps i386 2.1-7.el5 webtatic 56 k
emacs-common i386 21.4-24.el5 base 10 M
emacs-git i386 1.7.6.1-1.w5 webtatic 41 k
git i386 1.7.6.1-1.w5 webtatic 4.6 M
git-cvs i386 1.7.6.1-1.w5 webtatic 82 k
git-email i386 1.7.6.1-1.w5 webtatic 41 k
git-gui i386 1.7.6.1-1.w5 webtatic 265 k
git-svn i386 1.7.6.1-1.w5 webtatic 104 k
gitk i386 1.7.6.1-1.w5 webtatic 141 k
perl-Authen-SASL noarch 2.13-1.el5.rf webtatic 53 k
perl-Error noarch 1:0.17010-1.el5 webtatic 26 k
perl-Git i386 1.7.6.1-1.w5 webtatic 25 k
perl-Net-SMTP-SSL noarch 1.01-1.el5.rf webtatic 7.4 k
perl-TermReadKey i386 2.30-4.el5 webtatic 32 k
subversion-perl i386 1.6.13-0.1.el5.rf webtatic 2.3 M
Updating for dependencies:
subversion i386 1.6.13-0.1.el5.rf webtatic 6.5 M
subversion-devel i386 1.6.13-0.1.el5.rf webtatic 257 k

Transaction Summary
============================================================================================================================================
Install 16 Package(s)
Upgrade 2 Package(s)

Total download size: 25 M
Is this ok [y/N]: y
Downloading Packages:
(1/18): perl-Net-SMTP-SSL-1.01-1.el5.rf.noarch.rpm | 7.4 kB 00:00
(2/18): git-all-1.7.6.1-1.w5.i386.rpm | 13 kB 00:00
(3/18): perl-Git-1.7.6.1-1.w5.i386.rpm | 25 kB 00:00
(4/18): perl-Error-0.17010-1.el5.noarch.rpm | 26 kB 00:00
(5/18): perl-TermReadKey-2.30-4.el5.i386.rpm | 32 kB 00:00
(6/18): emacs-git-1.7.6.1-1.w5.i386.rpm | 41 kB 00:00
(7/18): git-email-1.7.6.1-1.w5.i386.rpm | 41 kB 00:00
(8/18): perl-Authen-SASL-2.13-1.el5.rf.noarch.rpm | 53 kB 00:00
(9/18): cvsps-2.1-7.el5.i386.rpm | 56 kB 00:00
(10/18): git-cvs-1.7.6.1-1.w5.i386.rpm | 82 kB 00:00
(11/18): git-svn-1.7.6.1-1.w5.i386.rpm | 104 kB 00:00
(12/18): gitk-1.7.6.1-1.w5.i386.rpm | 141 kB 00:00
(13/18): subversion-devel-1.6.13-0.1.el5.rf.i386.rpm | 257 kB 00:00
(14/18): git-gui-1.7.6.1-1.w5.i386.rpm | 265 kB 00:00
(15/18): subversion-perl-1.6.13-0.1.el5.rf.i386.rpm | 2.3 MB 00:00
(16/18): git-1.7.6.1-1.w5.i386.rpm | 4.6 MB 00:02
(17/18): subversion-1.6.13-0.1.el5.rf.i386.rpm | 6.5 MB 00:03
(18/18): emacs-common-21.4-24.el5.i386.rpm | 10 MB 00:04
--------------------------------------------------------------------------------------------------------------------------------------------
Total 1.8 MB/s | 25 MB 00:13
warning: rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID cf4c4ff9
webtatic/gpgkey | 1.6 kB 00:00
Importing GPG key 0xCF4C4FF9 "Andy Thompson " from /etc/pki/rpm-gpg/RPM-GPG-KEY-webtatic-andy
Is this ok [y/N]: y
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Updating : subversion 1/20
Installing : subversion-perl 2/20
Installing : cvsps 3/20
Installing : emacs-common 4/20
Installing : perl-TermReadKey 5/20
Installing : perl-Error 6/20
Installing : perl-Net-SMTP-SSL 7/20
Installing : perl-Authen-SASL 8/20
Updating : subversion-devel 9/20
Installing : git 10/20
Installing : perl-Git 11/20
Installing : gitk 12/20
Installing : git-gui 13/20
Installing : git-email 14/20
Installing : git-cvs 15/20
Installing : git-svn 16/20
Installing : emacs-git 17/20
Installing : git-all 18/20
Cleanup : subversion 19/20
Cleanup : subversion-devel 20/20

Installed:
git-all.i386 0:1.7.6.1-1.w5

Dependency Installed:
cvsps.i386 0:2.1-7.el5 emacs-common.i386 0:21.4-24.el5 emacs-git.i386 0:1.7.6.1-1.w5
git.i386 0:1.7.6.1-1.w5 git-cvs.i386 0:1.7.6.1-1.w5 git-email.i386 0:1.7.6.1-1.w5
git-gui.i386 0:1.7.6.1-1.w5 git-svn.i386 0:1.7.6.1-1.w5 gitk.i386 0:1.7.6.1-1.w5
perl-Authen-SASL.noarch 0:2.13-1.el5.rf perl-Error.noarch 1:0.17010-1.el5 perl-Git.i386 0:1.7.6.1-1.w5
perl-Net-SMTP-SSL.noarch 0:1.01-1.el5.rf perl-TermReadKey.i386 0:2.30-4.el5 subversion-perl.i386 0:1.6.13-0.1.el5.rf

Dependency Updated:
subversion.i386 0:1.6.13-0.1.el5.rf subversion-devel.i386 0:1.6.13-0.1.el5.rf

Complete!

III. Install RVM gem

$> sudo gem install rvm
/usr/local/lib/ruby/1.9.1/yaml.rb:56:in `':
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
Fetching: rvm-1.9.2.gem (100%)
********************************************************************************

This gem contains only the Ruby libraries for the RVM Ruby API.

In order to install RVM please use one of the methods listed in the
documentation:

https://rvm.beginrescueend.com/rvm/install/

such as,

bash < <(curl -s -B https://rvm.beginrescueend.com/install/rvm) followed by placing the sourcing line in your ~/.bash_profile or wherever may be appropriate for your setup (example, .zshenv, /etc/profile, ...): # Load RVM into a shell session *as a function* [[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" After completing setup please open a new shell to use RVM and be sure to run 'rvm notes' to gain a list of dependencies to install before installing the first Ruby. You can read more details about this process on the above mentioned install page as well as the basics page: https://rvm.beginrescueend.com/rvm/basics/ Enjoy! ~Wayne ******************************************************************************** Successfully installed rvm-1.9.2 1 gem installed Installing ri documentation for rvm-1.9.2... Installing RDoc documentation for rvm-1.9.2...

IV. Perform RVM install

$> curl -s -B https://rvm.beginrescueend.com/install/rvm > rvm.bash
$> bash << rvm.bash $> cat rvm.bash | bash

bash: line 154: git: command not found
bash: line 156: git: command not found

That is what you WOULD see if you do NOT have GIT installed (see #II above)

$> cat rvm.bash | bash

Cloning into rvm...
remote: Counting objects: 5866, done.
remote: Compressing objects: 100% (2808/2808), done.
remote: Total 5866 (delta 3855), reused 4138 (delta 2302)
Receiving objects: 100% (5866/5866), 1.95 MiB | 728 KiB/s, done.
Resolving deltas: 100% (3855/3855), done.

RVM: Shell scripts enabling management of multiple ruby environments.
RTFM: https://rvm.beginrescueend.com/
HELP: http://webchat.freenode.net/?channels=rvm (#rvm on irc.freenode.net)

Installing RVM to /home/$USER/.rvm/
Correct permissions for base binaries in /home/$USER/.rvm/bin...
Copying manpages into place.
Recording config files for rubies.

$USER,

If you have any questions, issues and/or ideas for improvement please
fork the project and issue a pull request.

If you wish to disable the project .rvmrc file functionality, set
rvm_project_rvmrc=0 in either /etc/rvmrc or ~/.rvmrc.

NOTE: To Multi-User installers, please do NOT forget to add your users to the 'rvm'.
The installer no longer auto-adds root or users to the rvm group. Admins must do this.
Also, please note that group memberships are ONLY evaluated at login time.
This means that users must log out then back in before group membership takes effect!

Thank you for using RVM!

I sincerely hope that RVM helps to make your life easier and more enjoyable!!!

~Wayne

SYSTEM NOTES:

If you do not wish to enable reading of per-project .rvmrc files, simply set:
export rvm_project_rvmrc=0
within either your /etc/rvmrc or $HOME/.rvmrc file, then log out and back in.

You _must_ read 'rvm requirements' for additional OS specific requirements for
various rubies, and native-extension gems. Expect failures until those are met!

You must now complete the install by loading RVM in new shells.

If you wish to use RVM in an interactive fashion in your shells then
Place the following line at the end of your shell's loading files
(.bashrc or .bash_profile for bash and .zshrc for zsh),
after all PATH/variable settings:

[[ -s "/home/$USER/.rvm/scripts/rvm" ]] && source "/home/$USER/.rvm/scripts/rvm" # This loads RVM into a shell session.

You only need to add this line the first time you install RVM.

If you are choosing to source RVM into your environment to switch current
shell environments, be sure to close this shell and open a new one so that
the RVM functions load.

Installation of RVM to /home/$USER/.rvm/ is complete.

Requirements for Linux ( CentOS release 5.7 (Final) )

NOTE: 'ruby' represents Matz's Ruby Interpreter (MRI) (1.8.X, 1.9.X)
This is the *original* / standard Ruby Language Interpreter
'ree' represents Ruby Enterprise Edition
'rbx' represents Rubinius

bash >= 4.1 required
curl is required
git is required (>= 1.7 recommended)
patch is required (for ree and some ruby-head's).

To install rbx and/or Ruby 1.9 head (MRI) (eg. 1.9.2-head),
then you must install and use rvm 1.8.7 first.

NOTE: To all Multi-User installers - DO NOT forget to add your users to the 'rvm' group.
The installer does not auto-add any users to the rvm group. Admins must do this.
Group memberships are ONLY evaluated at login time. Log them out, then back in.

Additional Dependencies:
# For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following:
ruby: yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison iconv-devel ## NOTE: For centos >= 5.4 iconv-devel is provided by glibc

# For JRuby, install the following:
jruby: yum install -y java

V. Install addition dependencies, for RUBY

$> sudo yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison iconv-devel

Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.ecvps.com
* extras: mirrors.cat.pdx.edu
* updates: mirror.nwresd.org
Setting up Install Process
Package gcc-c++-4.1.2-51.el5.i386 already installed and latest version
Package patch-2.5.4-31.el5.i386 already installed and latest version
Package readline-5.1-3.el5.i386 already installed and latest version
Package readline-devel-5.1-3.el5.i386 already installed and latest version
Package zlib-1.2.3-4.el5.i386 already installed and latest version
Package zlib-devel-1.2.3-4.el5.i386 already installed and latest version
No package libyaml-devel available.
No package libffi-devel available.
Package openssl-devel-0.9.8e-20.el5.i386 already installed and latest version
Package 1:make-3.81-3.el5.i386 already installed and latest version
Package bzip2-1.0.3-6.el5_5.i386 already installed and latest version
Package autoconf-2.59-12.noarch already installed and latest version
Package automake-1.9.6-2.3.el5.noarch already installed and latest version
Package libtool-1.5.22-7.el5_4.i386 already installed and latest version
Package bison-2.3-2.1.i386 already installed and latest version
No package iconv-devel available.
Nothing to do

VI. Install addition dependencies, for JRUBY

$> sudo yum install -y java

Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.ecvps.com
* extras: mirrors.cat.pdx.edu
* updates: mirror.nwresd.org
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package java-1.6.0-openjdk.i386 1:1.6.0.0-1.23.1.9.10.el5_7 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

Dependencies Resolved

============================================================================================================================================
Package Arch Version Repository Size
============================================================================================================================================
Updating:
java-1.6.0-openjdk i386 1:1.6.0.0-1.23.1.9.10.el5_7 updates 38 M

Transaction Summary
============================================================================================================================================
Install 0 Package(s)
Upgrade 1 Package(s)

Total download size: 38 M
Downloading Packages:
java-1.6.0-openjdk-1.6.0.0-1.23.1.9.10.el5_7.i386.rpm | 38 MB 00:20
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Updating : java-1.6.0-openjdk 1/2
Cleanup : java-1.6.0-openjdk 2/2

Updated:
java-1.6.0-openjdk.i386 1:1.6.0.0-1.23.1.9.10.el5_7

Complete!

VII. Continue the installation process

$> chmod +x rvm.bash
$> ./rvm.bash

Successfully checked out branch ''
Current branch master is up to date.
Successfully pulled (rebased) from origin

RVM: Shell scripts enabling management of multiple ruby environments.
RTFM: https://rvm.beginrescueend.com/
HELP: http://webchat.freenode.net/?channels=rvm (#rvm on irc.freenode.net)

Upgrading the RVM installation in /home/$USER/.rvm/
Correct permissions for base binaries in /home/$USER/.rvm/bin...
Copying manpages into place.
Recording config files for rubies.

$USER,

If you have any questions, issues and/or ideas for improvement please
fork the project and issue a pull request.

If you wish to disable the project .rvmrc file functionality, set
rvm_project_rvmrc=0 in either /etc/rvmrc or ~/.rvmrc.

NOTE: To Multi-User installers, please do NOT forget to add your users to the 'rvm'.
The installer no longer auto-adds root or users to the rvm group. Admins must do this.
Also, please note that group memberships are ONLY evaluated at login time.
This means that users must log out then back in before group membership takes effect!

Thank you for using RVM!

I sincerely hope that RVM helps to make your life easier and more enjoyable!!!

~Wayne

Upgrade Notes

* rvm_trust_rvmrcs has been changed to rvm_trust_rvmrcs_flag for consistency

* Project rvmrc files are now checked for trust whenever they change, as
promised by the note displayed during the review process

* Ruby package dependency list for your OS is given by:
rvm notes

* If you encounter any issues with a ruby 'X' your best bet is to:
rvm remove X ; rvm install X

* If you see the following error message: Unknown alias name: 'default'
re-set your default ruby, this is due to a change in how default works.

* after_use and after_cd hook now supports multiple files with after_*_*
the custom hooks can be easily turned on/off by:
chmod +x /home/$USER/.rvm/hooks/after_cd_[hook_name]
chmod -x /home/$USER/.rvm/hooks/after_use_[hook_name]

Upgrade of RVM in /home/$USER/.rvm/ is complete.

VIII. Run RVM installer

$> ~/.rvm/bin/rvm-installer

Successfully checked out branch ''
Current branch master is up to date.
Successfully pulled (rebased) from origin

RVM: Shell scripts enabling management of multiple ruby environments.
RTFM: https://rvm.beginrescueend.com/
HELP: http://webchat.freenode.net/?channels=rvm (#rvm on irc.freenode.net)

Upgrading the RVM installation in /home/$USER/.rvm/
Correct permissions for base binaries in /home/$USER/.rvm/bin...
Copying manpages into place.
Recording config files for rubies.

$USER,

If you have any questions, issues and/or ideas for improvement please
fork the project and issue a pull request.

If you wish to disable the project .rvmrc file functionality, set
rvm_project_rvmrc=0 in either /etc/rvmrc or ~/.rvmrc.

NOTE: To Multi-User installers, please do NOT forget to add your users to the 'rvm'.
The installer no longer auto-adds root or users to the rvm group. Admins must do this.
Also, please note that group memberships are ONLY evaluated at login time.
This means that users must log out then back in before group membership takes effect!

Thank you for using RVM!

I sincerely hope that RVM helps to make your life easier and more enjoyable!!!

~Wayne

Upgrade Notes

* rvm_trust_rvmrcs has been changed to rvm_trust_rvmrcs_flag for consistency

* Project rvmrc files are now checked for trust whenever they change, as
promised by the note displayed during the review process

* Ruby package dependency list for your OS is given by:
rvm notes

* If you encounter any issues with a ruby 'X' your best bet is to:
rvm remove X ; rvm install X

* If you see the following error message: Unknown alias name: 'default'
re-set your default ruby, this is due to a change in how default works.

* after_use and after_cd hook now supports multiple files with after_*_*
the custom hooks can be easily turned on/off by:
chmod +x /home/$USER/.rvm/hooks/after_cd_[hook_name]
chmod -x /home/$USER/.rvm/hooks/after_use_[hook_name]

Upgrade of RVM in /home/$USER/.rvm/ is complete.

IX. Add JRUBY_OPTS into ~/.bash_profile

JRUBY_OPTS="--1.9"

and source it

$> source ~/.bash_profile

X. Install JRUBY under RVM

$> rvm install jruby

jruby-1.6.5 - #fetching
jruby-1.6.5 - #downloading jruby-bin-1.6.5, this may take a while depending on your connection...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 14.6M 100 14.6M 0 0 1346k 0 0:00:11 0:00:11 --:--:-- 1534k
jruby-1.6.5 - #extracting jruby-bin-1.6.5 to /home/$USER/.rvm/src/jruby-1.6.5
jruby-1.6.5 - #extracted to /home/$USER/.rvm/src/jruby-1.6.5
Building Nailgun
jruby-1.6.5 - #installing to /home/$USER/.rvm/rubies/jruby-1.6.5
jruby-1.6.5 - #importing default gemsets (/home/$USER/.rvm/gemsets/)
Copying across included gems
Fetching: jruby-launcher-1.0.9-java.gem (100%)
Building native extensions. This could take a while...
Successfully installed jruby-launcher-1.0.9-java
1 gem installed

XI. Using RVM

$> rvm use
Now using system ruby.

$> rvm use jruby-1.6.5
Using /home/$USER/.rvm/gems/jruby-1.6.5

$> rvm use jruby
Using /home/$USER/.rvm/gems/jruby-1.6.5

$> ruby -v
jruby 1.6.5 (ruby-1.8.7-p330) (2011-10-25 9dcd388) (Java HotSpot(TM) Server VM 1.6.0_25) [linux-i386-java]

$> /usr/bin/env ruby -v
jruby 1.6.5 (ruby-1.8.7-p330) (2011-10-25 9dcd388) (Java HotSpot(TM) Server VM 1.6.0_25) [linux-i386-java]

XII. Install missed gems under choosen RUBY version

In general, it is done the following way (skip "sudo" for $USER wide installation)

Ruby: $> sudo gem install
JRuby: $> jruby gem install

$> gem install awesome_print simplecov minitest

Fetching: awesome_print-0.4.0.gem (100%)
Successfully installed awesome_print-0.4.0
Fetching: multi_json-1.0.3.gem (100%)
Fetching: simplecov-html-0.5.3.gem (100%)
Fetching: simplecov-0.5.4.gem (100%)
Successfully installed multi_json-1.0.3
Successfully installed simplecov-html-0.5.3
Successfully installed simplecov-0.5.4
Fetching: minitest-2.7.0.gem (100%)
Successfully installed minitest-2.7.0
5 gems installed

$> gem list

*** LOCAL GEMS ***

awesome_print (0.4.0)
bouncy-castle-java (1.5.0146.1)
bundler (1.0.21 ruby)
jruby-launcher (1.0.9 java)
jruby-openssl (0.7.4)
minitest (2.7.0)
multi_json (1.0.3)
rake (0.9.2, 0.8.7)
simplecov (0.5.4)
simplecov-html (0.5.3)

1 Comment

Filed under technology

Native Data class in Ruby 1.8 is much slower than Date::Performance – class Data, partially re-written to C

http://blog.pluron.com/2009/04/ruby-date-class.html
https://github.com/rtomayko/date-performance

Unfortunately, it is for 1.8 only. It will not compile on 1.9

rtomayko commented

January 15, 2010
Oh, now that I think about it, it's going to take a lot of work to get date-performance running under 1.9. They've changed a ton of stuff with Date. I'm not sure when/if I'll get around to it.
This may be a 1.8.x only library unless someone wants to take a crack at porting to 1.9.

https://github.com/rtomayko/date-performance/issues/1#issuecomment-110638

1 Comment

Filed under technology

Running Grinder console on EC2 cloud or fixing “java.lang.Error: Probable fatal error:No fonts found”

I was trying to run Grinder console on EC2 cloud, and that is my log of what happened.

1. Yes, I setup the “X” forwarding, and you can read it here of how it was setup.

2. However, trying to run Grinder java/swing based Console on the remote EC2 box, expecting to actually see the output on the local box, I got the following error:

Exception in thread "main" java.lang.Error: Probable fatal error:No fonts found.

That is the full output:

[ec2-user@ip-10-10-6-238 Grinder_Harness]$ ./run_grinder_console_ec2.sh
+ set -v

ROOT=$HOME/Grinder_Harness
+ ROOT=/home/ec2-user/Grinder_Harness

CLASSPATH=$CLASSPATH:$ROOT/grinder-3.4-bin/lib/grinder.jar
+ CLASSPATH=:/home/ec2-user/Grinder_Harness/grinder-3.4-bin/lib/grinder.jar
CLASSPATH=$CLASSPATH:$ROOT/jython2.5.2-bin/jython.jar
+ CLASSPATH=:/home/ec2-user/Grinder_Harness/grinder-3.4-bin/lib/grinder.jar:/home/ec2-user/Grinder_Harness/jython2.5.2-bin/jython.jar

java -cp $CLASSPATH net.grinder.Console
+ java -cp :/home/ec2-user/Grinder_Harness/grinder-3.4-bin/lib/grinder.jar:/home/ec2-user/Grinder_Harness/jython2.5.2-bin/jython.jar net.grinder.Console
Exception in thread "main" java.lang.Error: Probable fatal error:No fonts found.
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1088)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:960)
at sun.font.FontManager.findOtherDeferredFont(FontManager.java:899)
at sun.font.FontManager.findDeferredFont(FontManager.java:916)
at sun.font.FontManager.findFont2D(FontManager.java:1904)
at sun.font.FontManager.findFont2D(FontManager.java:1865)
at sun.font.FontManager.getDefaultPhysicalFont(FontManager.java:1071)
at sun.font.FontManager.initialiseDeferredFont(FontManager.java:967)
at sun.font.CompositeFont.doDeferredInitialisation(CompositeFont.java:254)
at sun.font.CompositeFont.getSlotFont(CompositeFont.java:334)
at sun.font.CompositeStrike.getStrikeForSlot(CompositeStrike.java:77)
at sun.font.CompositeStrike.getFontMetrics(CompositeStrike.java:93)
at sun.font.FontDesignMetrics.initMatrixAndMetrics(FontDesignMetrics.java:358)
at sun.font.FontDesignMetrics.(FontDesignMetrics.java:349)
at sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:301)
at sun.swing.SwingUtilities2.getFontMetrics(SwingUtilities2.java:999)
at javax.swing.JComponent.getFontMetrics(JComponent.java:1599)
at javax.swing.plaf.basic.BasicGraphicsUtils.getPreferredButtonSize(BasicGraphicsUtils.java:273)
at javax.swing.plaf.basic.BasicButtonUI.getPreferredSize(BasicButtonUI.java:376)
at javax.swing.plaf.basic.BasicButtonUI.getMinimumSize(BasicButtonUI.java:366)
at javax.swing.JComponent.getMinimumSize(JComponent.java:1714)
at javax.swing.plaf.basic.BasicOptionPaneUI.addButtonComponents(BasicOptionPaneUI.java:692)
at javax.swing.plaf.basic.BasicOptionPaneUI.createButtonArea(BasicOptionPaneUI.java:630)
at javax.swing.plaf.basic.BasicOptionPaneUI.installComponents(BasicOptionPaneUI.java:178)
at javax.swing.plaf.basic.BasicOptionPaneUI.installUI(BasicOptionPaneUI.java:141)
at javax.swing.JComponent.setUI(JComponent.java:651)
at javax.swing.JOptionPane.setUI(JOptionPane.java:1856)
at javax.swing.JOptionPane.updateUI(JOptionPane.java:1878)
at javax.swing.JOptionPane.(JOptionPane.java:1841)
at javax.swing.JOptionPane.(JOptionPane.java:1804)
at net.grinder.console.swingui.ErrorDialogHandler.(ErrorDialogHandler.java:52)
at net.grinder.console.swingui.ErrorDialogHandler.(ErrorDialogHandler.java:73)
at net.grinder.console.swingui.ConsoleUI.(ConsoleUI.java:183)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at org.picocontainer.defaults.InstantiatingComponentAdapter.newInstance(InstantiatingComponentAdapter.java:193)
at org.picocontainer.defaults.ConstructorInjectionComponentAdapter$1.run(ConstructorInjectionComponentAdapter.java:220)
at org.picocontainer.defaults.ThreadLocalCyclicDependencyGuard.observe(ThreadLocalCyclicDependencyGuard.java:53)
at org.picocontainer.defaults.ConstructorInjectionComponentAdapter.getComponentInstance(ConstructorInjectionComponentAdapter.java:248)
at org.picocontainer.defaults.DecoratingComponentAdapter.getComponentInstance(DecoratingComponentAdapter.java:60)
at org.picocontainer.defaults.CachingComponentAdapter.getComponentInstance(CachingComponentAdapter.java:58)
at org.picocontainer.defaults.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:393)
at org.picocontainer.defaults.DefaultPicoContainer.getComponentInstanceOfType(DefaultPicoContainer.java:382)
at net.grinder.console.ConsoleFoundation.createUI(ConsoleFoundation.java:173)
at net.grinder.Console.(Console.java:70)
at net.grinder.Console.main(Console.java:92)

3. You would need to sudo yum install java-1.6.0-sun-fonts, however, you will not be too successful:

[ec2-user@ip-10-10-6-238 Grinder_Harness]$ sudo yum install java-1.6.0-sun-fonts
Loaded plugins: fastestmirror, priorities, security, update-motd
Loading mirror speeds from cached hostfile
* amzn-main: packages.us-east-1.amazonaws.com
* amzn-updates: packages.us-east-1.amazonaws.com
amzn-main | 2.1 kB 00:00
amzn-updates | 2.1 kB 00:00
Setting up Install Process
No package java-1.6.0-sun-fonts available.
Error: Nothing to do

4. Download them from my development/java-1.6.0-sun-fonts repo or from pbone.net


[ec2-user@ip-10-10-6-238 tools]$ wget http://www.zorranlabs.com/development/java-1.6.0-sun-fonts/java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpm
## [ec2-user@ip-10-10-6-238 tools]$ wget ftp://ftp.pbone.net/mirror/apt.unl.edu/apt/jpackage/all/RPMS.testing/java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpm
--2011-10-05 10:51:25-- ftp://ftp.pbone.net/mirror/apt.unl.edu/apt/jpackage/all/RPMS.testing/java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpm
=> âjava-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpmâ
esolving ftp.pbone.net... 85.14.85.4
Connecting to ftp.pbone.net|85.14.85.4|:21... connected.
Logging in as anonymous ... Logged in!
==> SYST ... done. ==> PWD ... done.
==> TYPE I ... done. ==> CWD (1) /mirror/apt.unl.edu/apt/jpackage/all/RPMS.testing ... done.
==> SIZE java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpm ... 1252568
==> PASV ... done. ==> RETR java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpm ... done.
Length: 1252568 (1.2M) (unauthoritative)

100%[============================================================================================================>] 1,252,568 757K/s in 1.6s

2011-10-05 10:51:28 (757 KB/s) - âjava-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpmâ

5. Install it using yum localinstall. Most likely, you will get some of the dependences:

[ec2-user@ip-10-10-6-238 tools]$ sudo yum localinstall java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpm
Loaded plugins: fastestmirror, priorities, security, update-motd
Setting up Local Package Process
Examining java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpm: java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586
Marking java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpm to be installed
Loading mirror speeds from cached hostfile
* amzn-main: packages.us-east-1.amazonaws.com
* amzn-updates: packages.us-east-1.amazonaws.com
amzn-main | 2.1 kB 00:00
amzn-updates | 2.1 kB 00:00
Resolving Dependencies
--> Running transaction check
---> Package java-1.6.0-sun-fonts.i586 0:1.6.0.19-1jpp will be installed
--> Processing Dependency: /usr/sbin/chkfontpath for package: java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586
--> Processing Dependency: /usr/bin/xsltproc for package: java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586
--> Running transaction check
---> Package chkfontpath.x86_64 0:1.10.1-1.7.amzn1 will be installed
--> Processing Dependency: xfs for package: chkfontpath-1.10.1-1.7.amzn1.x86_64
---> Package libxslt.x86_64 0:1.1.26-2.6.amzn1 will be installed
--> Running transaction check
---> Package xorg-x11-xfs.x86_64 1:1.0.2-4.7.amzn1 will be installed
--> Processing Dependency: libXfont >= 0.99.2-3 for package: 1:xorg-x11-xfs-1.0.2-4.7.amzn1.x86_64
--> Processing Dependency: ttmkfdir for package: 1:xorg-x11-xfs-1.0.2-4.7.amzn1.x86_64
--> Processing Dependency: mkfontdir for package: 1:xorg-x11-xfs-1.0.2-4.7.amzn1.x86_64
--> Processing Dependency: mkfontscale for package: 1:xorg-x11-xfs-1.0.2-4.7.amzn1.x86_64
--> Processing Dependency: libXfont.so.1()(64bit) for package: 1:xorg-x11-xfs-1.0.2-4.7.amzn1.x86_64
--> Processing Dependency: libFS.so.6()(64bit) for package: 1:xorg-x11-xfs-1.0.2-4.7.amzn1.x86_64
--> Running transaction check
---> Package libFS.x86_64 0:1.0.0-3.5.amzn1 will be installed
---> Package libXfont.x86_64 0:1.4.1-2.6.amzn1 will be installed
--> Processing Dependency: libfontenc.so.1()(64bit) for package: libXfont-1.4.1-2.6.amzn1.x86_64
---> Package ttmkfdir.x86_64 0:3.0.9-32.1.5.amzn1 will be installed
---> Package xorg-x11-font-utils.x86_64 1:7.2-10.4.amzn1 will be installed
--> Processing Dependency: /usr/bin/pkg-config for package: 1:xorg-x11-font-utils-7.2-10.4.amzn1.x86_64
--> Running transaction check
---> Package libfontenc.x86_64 0:1.0.5-2.6.amzn1 will be installed
---> Package pkgconfig.x86_64 1:0.23-9.1.6.amzn1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

======================================================================================================================================================
Package Arch Version Repository Size
======================================================================================================================================================
Installing:
java-1.6.0-sun-fonts i586 1.6.0.19-1jpp /java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586 2.0 M
Installing for dependencies:
chkfontpath x86_64 1.10.1-1.7.amzn1 amzn-main 12 k
libFS x86_64 1.0.0-3.5.amzn1 amzn-main 28 k
libXfont x86_64 1.4.1-2.6.amzn1 amzn-main 135 k
libfontenc x86_64 1.0.5-2.6.amzn1 amzn-main 21 k
libxslt x86_64 1.1.26-2.6.amzn1 amzn-main 551 k
pkgconfig x86_64 1:0.23-9.1.6.amzn1 amzn-main 71 k
ttmkfdir x86_64 3.0.9-32.1.5.amzn1 amzn-main 42 k
xorg-x11-font-utils x86_64 1:7.2-10.4.amzn1 amzn-main 77 k
xorg-x11-xfs x86_64 1:1.0.2-4.7.amzn1 amzn-main 70 k

Transaction Summary
======================================================================================================================================================
Install 10 Package(s)

Total size: 3.0 M
Total download size: 1.0 M
Installed size: 5.1 M
Is this ok [y/N]: y
Downloading Packages:
(1/9): chkfontpath-1.10.1-1.7.amzn1.x86_64.rpm | 12 kB 00:00
(2/9): libFS-1.0.0-3.5.amzn1.x86_64.rpm | 28 kB 00:00
(3/9): libXfont-1.4.1-2.6.amzn1.x86_64.rpm | 135 kB 00:00
(4/9): libfontenc-1.0.5-2.6.amzn1.x86_64.rpm | 21 kB 00:00
(5/9): libxslt-1.1.26-2.6.amzn1.x86_64.rpm | 551 kB 00:00
(6/9): pkgconfig-0.23-9.1.6.amzn1.x86_64.rpm | 71 kB 00:00
(7/9): ttmkfdir-3.0.9-32.1.5.amzn1.x86_64.rpm | 42 kB 00:00
(8/9): xorg-x11-font-utils-7.2-10.4.amzn1.x86_64.rpm | 77 kB 00:00
(9/9): xorg-x11-xfs-1.0.2-4.7.amzn1.x86_64.rpm | 70 kB 00:00
------------------------------------------------------------------------------------------------------------------------------------------------------
Total 2.1 MB/s | 1.0 MB 00:00
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : libfontenc-1.0.5-2.6.amzn1.x86_64 1/10
Installing : libXfont-1.4.1-2.6.amzn1.x86_64 2/10
Installing : libFS-1.0.0-3.5.amzn1.x86_64 3/10
Installing : libxslt-1.1.26-2.6.amzn1.x86_64 4/10
Installing : 1:pkgconfig-0.23-9.1.6.amzn1.x86_64 5/10
Installing : 1:xorg-x11-font-utils-7.2-10.4.amzn1.x86_64 6/10
Installing : ttmkfdir-3.0.9-32.1.5.amzn1.x86_64 7/10
Installing : chkfontpath-1.10.1-1.7.amzn1.x86_64 8/10
Installing : 1:xorg-x11-xfs-1.0.2-4.7.amzn1.x86_64 9/10
Installing : java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586 10/10

Installed:
java-1.6.0-sun-fonts.i586 0:1.6.0.19-1jpp

Dependency Installed:
chkfontpath.x86_64 0:1.10.1-1.7.amzn1 libFS.x86_64 0:1.0.0-3.5.amzn1 libXfont.x86_64 0:1.4.1-2.6.amzn1
libfontenc.x86_64 0:1.0.5-2.6.amzn1 libxslt.x86_64 0:1.1.26-2.6.amzn1 pkgconfig.x86_64 1:0.23-9.1.6.amzn1
ttmkfdir.x86_64 0:3.0.9-32.1.5.amzn1 xorg-x11-font-utils.x86_64 1:7.2-10.4.amzn1 xorg-x11-xfs.x86_64 1:1.0.2-4.7.amzn1

Complete!

6. Run the Grinder Console, and it should run w/o errors and it should appear on the remote box

[ec2-user@ip-10-10-6-238 Grinder_Harness]$ ./run_grinder_console_ec2.sh
+ set -v

ROOT=$HOME/Grinder_Harness
+ ROOT=/home/ec2-user/Grinder_Harness

CLASSPATH=$CLASSPATH:$ROOT/grinder-3.4-bin/lib/grinder.jar
+ CLASSPATH=:/home/ec2-user/Grinder_Harness/grinder-3.4-bin/lib/grinder.jar
CLASSPATH=$CLASSPATH:$ROOT/jython2.5.2-bin/jython.jar
+ CLASSPATH=:/home/ec2-user/Grinder_Harness/grinder-3.4-bin/lib/grinder.jar:/home/ec2-user/Grinder_Harness/jython2.5.2-bin/jython.jar

java -cp $CLASSPATH net.grinder.Console
+ java -cp :/home/ec2-user/Grinder_Harness/grinder-3.4-bin/lib/grinder.jar:/home/ec2-user/Grinder_Harness/jython2.5.2-bin/jython.jar net.grinder.Console

Good luck !!!

Thanks varipus authors for the ideas and guides

http://www.krisbuytaert.be/blog/node/159
http://track.sipfoundry.org/browse/XX-5738
http://rpm.pbone.net/index.php3/stat/4/idpl/15553152/dir/other/com/java-1.6.0-sun-fonts-1.6.0.19-1jpp.i586.rpm.html
http://www.centos.org/modules/newbb/viewtopic.php?topic_id=12749

Leave a Comment

Filed under technology