install multiple versions of GO on the same machine [linux]

This quick tutorial shows how to do install multiple versions of go manually.

I’ll try to prepare a shell script that will do it automatically for you 🙂

  1. download selected GO releases
  2. create directories for specific version of GO
  3. unpack downloaded GO releases
  4. install `go` alternatives
  5. install `godoc` alternatives
  6. install `gofmt` alternatives
  7. configure version of go, godoc & gofmt interactively
  8. alternatively you can configured it in a non-interactive way
  9. set the GOROOT env variable to match the location of selected version of GO
# 1
wget https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz
wget https://storage.googleapis.com/golang/go1.4.3.linux-amd64.tar.gz
wget https://storage.googleapis.com/golang/go1.5.linux-amd64.tar.gz
wget https://storage.googleapis.com/golang/go1.5.1.linux-amd64.tar.gz

# 2
sudo mkdir -p /usr/local/go/1.4.2/
sudo mkdir -p /usr/local/go/1.4.3/
sudo mkdir -p /usr/local/go/1.5/
sudo mkdir -p /usr/local/go/1.5.1/

# 3
sudo tar -C /usr/local/go/1.4.2/ --strip-components=1 -xzf go1.4.2.linux-amd64.tar.gz
sudo tar -C /usr/local/go/1.4.3/ --strip-components=1 -xzf go1.4.3.linux-amd64.tar.gz
sudo tar -C /usr/local/go/1.5/ --strip-components=1 -xzf go1.5.linux-amd64.tar.gz
sudo tar -C /usr/local/go/1.5.1/ --strip-components=1 -xzf go1.5.1.linux-amd64.tar.gz

# 4
sudo update-alternatives --install /usr/bin/go go /usr/local/go/1.4.2/bin/go 2
sudo update-alternatives --install /usr/bin/go go /usr/local/go/1.4.3/bin/go 3
sudo update-alternatives --install /usr/bin/go go /usr/local/go/1.5/bin/go 4
sudo update-alternatives --install /usr/bin/go go /usr/local/go/1.5.1/bin/go 5

# 5
sudo update-alternatives --install /usr/bin/godoc godoc /usr/local/go/1.4.2/bin/godoc 2
sudo update-alternatives --install /usr/bin/godoc godoc /usr/local/go/1.4.3/bin/godoc 3
sudo update-alternatives --install /usr/bin/godoc godoc /usr/local/go/1.5/bin/godoc 4
sudo update-alternatives --install /usr/bin/godoc godoc /usr/local/go/1.5.1/bin/godoc 5

# 6
sudo update-alternatives --install /usr/bin/gofmt gofmt /usr/local/go/1.4.2/bin/gofmt 2
sudo update-alternatives --install /usr/bin/gofmt gofmt /usr/local/go/1.4.3/bin/gofmt 3
sudo update-alternatives --install /usr/bin/gofmt gofmt /usr/local/go/1.5/bin/gofmt 4
sudo update-alternatives --install /usr/bin/gofmt gofmt /usr/local/go/1.5.1/bin/gofmt 5

# 7 - If you want to configure version of go, godoc & gofmt interactively then use:
sudo update-alternatives --config go
sudo update-alternatives --config godoc
sudo update-alternatives --config gofmt

# 8 - If you want to configure version non-interactively then use:
sudo update-alternatives --set go /usr/local/go/1.4.2/bin/go
sudo update-alternatives --set godoc /usr/local/go/1.4.2/bin/godoc
sudo update-alternatives --set gofmt /usr/local/go/1.4.2/bin/gofmt

sudo update-alternatives --set go /usr/local/go/1.4.3/bin/go
sudo update-alternatives --set godoc /usr/local/go/1.4.3/bin/godoc
sudo update-alternatives --set gofmt /usr/local/go/1.4.3/bin/gofmt

sudo update-alternatives --set go /usr/local/go/1.5/bin/go
sudo update-alternatives --set godoc /usr/local/go/1.5/bin/godoc
sudo update-alternatives --set gofmt /usr/local/go/1.5/bin/gofmt

sudo update-alternatives --set go /usr/local/go/1.5.1/bin/go
sudo update-alternatives --set godoc /usr/local/go/1.5.1/bin/godoc
sudo update-alternatives --set gofmt /usr/local/go/1.5.1/bin/gofmt

# 9 - set GOROOT to your current version of GO
export GOROOT=$(dirname $(dirname $(readlink -f $(which go | cut -d" " -f3))))

How to unit test Django’s Function Based Views

Let’s assume than the URL pattern to your Function Based View is defined like that:
urls.py

urlpatterns = patterns(
    ...,
    url(r'^$', views.index, name='index'),
    ...
)

and your function based view looks like this:
views.py

@api_view(['GET'])
@permission_classes((AllowAny,))
def index(request):
    data = {
        'field': 'value'
    }
    return Response(data)

Then you can unit test such view by creating a minimal instance
of the HttpRequest and pass it to that view.
I tried to mock to test such view with the Mock library, by with no luck!!!
If case you know how to do it with Mock, then let me know!

def test_index_function_based_view():
    _request = HttpRequest()
    _request.method = 'GET'
    request = Request(_request)
    response = index(request)
    assert response.data['field'] ==  'value'

Run your Selenium driven tests in parallel using TestNG.

Sometime ago I came across this post:
http://rationaleemotions.wordpress.com/2013/07/31/parallel-webdriver-executions-using-testng/
And I thought it’d be good to have it in a repo to save you time setting up your own project.

Basically this example project runs JUnit tests in parallel using TestNG.
Tests are grouped by the browser in which they’re going to be executed (have a look at the TestNG XML Suite files in src/test/resources).
As you might have guessed to drive the browsers we use Selenium WebDriver 🙂
And of course you can run your tests locally or remotely using Selenium GRID.

You can find the repo here: https://github.com/kowalcj0/parallel-selenium-with-testng

And here’s a video showing this project in action 🙂

GEE [Jmeter-ec2] – video tutorials part 2

Hi All,

I just added few more videos showing how to configure your test environment to run your JMeter tests:

  • locally on a Vagrant box
  • using remote machines
  • and on Amazon EC2

04 – create a first test plan, run it using Gee and a vagrant box
Shows how to create a new test plan from a template project. Then how to run it using GEE on our local vagrant box.

05 – configure passwordless ssh access to a linux box
Shows how to configure a passwordless SSH access to a remote Linux box. Such access is required by Gee to run your JMeter tests on a remote machine.

06 – automatically install JMeter with plugins on a remote machine
Shows how to use download-jmeter.sh script to download JMeter and JMeter-plugins automatically on a linux host that will be used by GEE to run your load tests.

07 – run your JMeter test on remote linux hosts
Shows how to configure GEE and remote Linux hosts to run your JMeter tests. This video might come handy when you’d like to run your tests using internal network resources.

08 – run your JMeter test on Amazon EC2
Shows how to configure GEE to run your JMeter tests using Amazon EC2 services.

GEE [Jmeter-ec2] – video tutorials part 1

I finally started recording videos explaining how to use Gee.
Gee is a tool based on a JMeter-EC2 project by Oliver Lloyd.
It allows you to run JMeter tests on:

  • Amazon EC2
  • Vagrant boxes
  • Linux hosts

Running your tests using this tool is better than using the standard distributed mode in Jmeter, because it doesn’t require constant communication between the master node and slave nodes.

Here are first few videos explaining how to clone the project, spawn new vagrant box and finally how to run an example project on that virtual box.
Hope you all will find in useful 🙂

GEE [Jmeter-ec2] – 01 – cloning the project

GEE [Jmeter-ec2] – 02 – initialize vagrant box

GEE [Jmeter-ec2] – 03 – running an example test on a vagrant box

Monitoring JVM metrics via JMX managemnet interface in JMeter

What do we need:

Once you have plugins installed them in the jmeter’s/lib/ext folder, then:
1 – On the box you want to monitor, copy templates: jmxremote.password & jmxremote.access from $JAVA_HOME/lib/management to for example: /srv/play/
2 – edit them according to your liking
3 – launch your JAVA application with additional parameters:

java -jar your_application.jar -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=10006 -Dcom.sun.management.jmxremote.password.file=/srv/play/jmxremote.password -Dcom.sun.management.jmxremote.access.file=/srv/play/jmxremote.access

4 – start a server-agent (http://jmeter-plugins.org/wiki/PerfMonAgent/) on the host which JVM metrics you want to monitor using command like:

cd ${jmeter_folder}/lib/ext/
java -jar ./CMDRunner.jar --tool PerfMonAgent --udp-port 0 --tcp-port 7777

You can also run it as background process and detach from your session, so it will continue to work even if you disconnect from the server.

cd ${jmeter_folder}/lib/ext/
nohup java -jar ./CMDRunner.jar --tool PerfMonAgent --udp-port 0 --tcp-port 7777 &

5 – add “PerfMon Metrics Collector” to your test plan
6 – provide the hostname/IP address of the box running server-agent in the “Host/IP” field (don’t forget about the port 🙂 )
7 – select JMX as the “Metric to collect”
8 – double click on “Metric parameter” field and then click on the “…” button to the right
9 – enter all the credentials that the server-agent will use to connect to the local JVM via JMX port. Here’s an example config:

url=localhost\:10006:user=role:password=password:gc-time

where role & password are of course defined in the jmxremote.password & jmxremote.access files

btw. Here’s an example test plan with preconfigured PerfMon listener.

If everything was configured properly the you should see something like that on the PerfMon graph:

example PerfMon graph with JVM Metrics

example PerfMon graph with JVM Metrics

How to selectively run, in jBehave, stories tagged with multiple words in a meta field.

Prerequisites:
1) a working jBehave based project
This short tutorial is based on an jbehave-tutorial project available on github: https://github.com/jbehave/jbehave-tutorial.
To be precise I used the “java-spring” submodule from the “etsy-selenium” module, available here: https://github.com/jbehave/jbehave-tutorial/tree/master/etsy-selenium/java-spring, to run the modified story presented below.
2) Maven

OK, let’s consider a situation when we have stories belonging to multiple features, categories etc.
Below is an example story, tagged with multiple categories and features:

anExampleStoryWithMultipleWordsInAMetaKeyword.story

Meta:
@categories category1 category2 category3
@features feature1 feature2 feature3 feature_4

Scenario: scenario description
Given I'm on the homepage
....

Now, we’d like to run stories only for a selected category or a feature.
To accomplish this we’ll use the value pattern matching mechanism implemented in the jBehave meta matcher and described here.

Examples:
Run stories covering only category3:

mvn clean install -Dmeta.filter="+categories *category3*"

Run stories covering only feature_4:

mvn clean install -Dmeta.filter="+features *feature_4*"

And finally, run stories matching feature2 and category1:

mvn clean install -Dmeta.filter="+features *feature2* +categories *category1*"

Notice:
It seems that jBehave is not handling “-” hyphens in the keyword value properly, but it works fine with “_” underscores, separate words and camelCase notation 🙂

SoapUI & Soapy tutorial part 01 – how to install soapy

I’ve decided to prepare a SoapUI video tutorial. Maybe some of you will find it useful.

In the first video I’m showing how to install Soapy library in the free version of SoapUI.
Soapy is a helper library that I’ve created in my current company. It basically is a bunch of helpers that can ease the pain of SoapUI user 🙂
In upcoming videos I’ll try to introduce some of new ones and also few that were already mentioned on my blog 🙂

How to generate a cURL command out of SoapUI Pro REST request

After few attempts I finally made it working properly 🙂

To make use it, simply add a new script assertion to your REST request, then paste those two lines:

import com.yelllabs.soapy.helpers.CurlGenerator;
new CurlGenerator(context, messageExchange, log);

and check what will come up in the Script log tab 🙂
A nicely formatted cURL command with all the query parameters, headers and msg body.

ps. of course before that create a CurlGenerator.groovy file in {script_bibrary}/com/yelllabs/soapy/helpers/ directory 🙂

package com.yelllabs.soapy.helpers;

import com.eviware.soapui.impl.wsdl.teststeps.RestResponseMessageExchange;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
import com.eviware.soapui.support.types.StringToStringsMap;
import org.apache.log4j.Logger;


/**
* @brief can create cURL command out of REST request.
* @author Janusz Kowalczyk
* @created 2012-07-04
* @updated 2012-11-14 Janusz Kowalczyk
*/
class CurlGenerator{

    private def context;
    private def messageExchange;
    private def request;
    private Logger log;
    private String testCaseName;
    private String reqHttpMethod;
    private String reqContent;
    private String reqContext;
    private String reqEndpoint;
    private byte[] reqRawData;
    private StringToStringsMap reqHeaders;
    private def reqParams;

    /**
    * @brief Default constructor
    *
    * @param context - test run context
    * @param messageExchange - message exchange availabe in a assertion script
    * @param log - Logger
    * @param curlParams - cURL params that will be placed at the begining of cmd
    */
    CurlGenerator( WsdlTestRunContext context, RestResponseMessageExchange messageExchange, Logger log, String curlParams ) {
        this.context = context;
        this.messageExchange = messageExchange;
        this.log = log;

        if ( this.context.getCurrentStep().isDisabled() == false ) {
            init();
            log.info getCurlCmd(curlParams);
        }
    }


    /**
    * @brief Another constructor, this one will use "-ki" as default cURL params
    *
    */
    CurlGenerator( WsdlTestRunContext context, RestResponseMessageExchange messageExchange, Logger log) {
        this(context, messageExchange, log, "ki");
    }


    /**
    * @brief Init method that gets all the needed data from context and msgExchng
    *
    */
    private void init() {
        this.request = messageExchange.getRestRequest();
        this.testCaseName = this.context.getCurrentStep().getLabel();
        this.reqHttpMethod = this.request.getMethod();
        
        // gets the req body if there's one
        // if not the an empty List is returned
        this.reqContent = (this.request.hasRequestBody()) ? this.context.expand(this.request.getRequestContent()) : ""; 

        this.reqParams = this.request.getProperties();

        this.reqContext = this.context.expand(this.request.getResource().getFullPath());
        this.reqEndpoint = this.context.expand(this.request.getEndpoint());

        // get request headers
        // works only when request is made manually for the second time, in other case it will be always [:]
        this.reqHeaders = (request.getResponse() != null) ? request.getResponse().getRequestHeaders() : [:];
        this.reqRawData = (request.getResponse() != null) ? request.getResponse().getRawRequestData() : [];
    }


    /**
     * @brief Will use "-ki" as default curl parameters
     * 
     * @return a cURL command with "-ki" set as default parameters
     */
    public String getCurlCmd() {
        return getCurl("ki");
    }


    /**
     * @brief 
     * 
     * @param String curlParams - Pass the curl parameters. If "" is used then no params will be added to the command line
     *
     * @return A cURL command with custom parameters
     */
    public String getCurlCmd(String curlParams) {
        return getCurl(curlParams);
    }


    /**
    * @brief Will create a cURL command with provided params
    *
    * @param curlParams custom cURL params
    *
    * @return a cURL command with custom params
    */
    private String getCurl(String curlParams)
    {
        String params = ( curlParams.isEmpty() ) ? "" : "-" + curlParams;
        String cmd = "curl %s %s \"%s%s\" %s %s";
        return String.format(cmd, params, getMethod(), getUri(), getParams(), getHeaders(), getContent());
    }


    public byte[] getRawRequestData(){
        return this.reqRawData;
    }

    /**
    * @brief return a list of maps of sent non-empty query parameters
    *
    * @return return a list of maps of sent non-empty query parameters
    */
    private List getSentParams(){
        List params = [];
        this.reqParams.each{
            k,v ->
                if ( !v.getValue().isEmpty() )  {
                    def param = [ "name": v.getName(), "val" :  context.expand( v.getValue() ) ]
                    params.push( param )
            }
        }
        return params;
    }

    /**
    * @brief Converts list of query params into a nicely formatted string
    *
    * @return A string representing all the query params
    */
    private String getParams(){
        String qp = "";
        if ( false == getSentParams().isEmpty() ) {
            getSentParams().each{
                p ->
                // insert ? when processing first param, else insert & 
                    qp += ( qp  == "" ) ? "?" + p.name + "=" + p.val : "&" + p.name + "=" + p.val;
            }
        }
        return qp;
    }

    private String getMethod(){
        return "-X" + reqHttpMethod;
    }

    private String getUri() {
        if ( this.reqContext.toString().toLowerCase().contains( this.reqEndpoint.toString().toLowerCase() ) ){
            return this.reqContext;
        } else {
            return this.reqEndpoint + reqContext;
        }
    }

    private String getHeaders() {
        if ( this.reqHeaders.isEmpty()) {
            return "";
        } else {
            String H = "";
            reqHeaders.each{
                key, val ->
                    H += ' -H "' +key + ':' + val[0] +'"'
            }
            return H;
        }
    }

    private String getContent() {
        if ( this.reqContent.isEmpty() ) {
            return "";
        } else {
            return "-d '" + this.reqContent+"'";
        }
    } 

}//end

How to randomly inject or not something to the request in JMeter

Nothing really special today, but maybe someone will find it handy 🙂

Sometimes when I want to test if my script is handling various server responses properly, I’m preparing a request that will randomly malform itself or not.
This can be accomplished by randomly injecting something into the URL or msg body.

A simple way to do that is to use a JS or BeanShell script, like this one:

${__javaScript(if(!! Math.round(Math.random() * 1)) {"injectedText";} else {"";} )}

An example HTTP request that will randomly malform itself 🙂

Randomly Inject Something To The URL

Randomly Inject Something To The URL