Tuesday, August 14, 2012

Life in WSO2

I had lot of technical articles so I thought having two photo articles back to back will not be a problem. Going through Lasindu's (if you read my previous article you might know him by now) fb profile I saw another nice album on WSO2 internship. Now this is the photographer. Thanks dude for letting me publish them on my blog :D

Btw, I did get the permission to publish this photo. :P






Lets take a look at this album!! I think this is a tea time in WSO2.


 Talking about this photo, 4 of them are really good at playing TT :P. And below is a training time!!




WSO2 7th Anniversary Celebrations

We celebrated our 7th anniversary few days back. We had to go to the 59 to join the party. Below are some memories from that. These are captured by one of our interns, Lasindu Charith. I can call him the official photographer in WSO2, at least among interns :P

It was a little party:) But there was enough food too :D


And one lucky guy got to celebrate his birthday on the same day!!
 

Things that you should remember when test automating(best practices)


Less Hard-coding
We are always tempted to hardcode things. It make our life easy. But this can make maintaining that code a big issue. I had to change some of the places that I did hardcode due to different reasons.

Dates and times
When working with date and times you might forget that, those things are changing. I did this mistake ones in the testing. I was asked to test the service locking functionality. We can lock a service for a specific time. I just hard-corded the dates and times and did the testing. Soon I realized that, if we are going to use them in the future, test going to fail. You might think that is foolish from me, but believe me we miss those little things while cording.

Use of Constants
If you really need to hardcode something do it through a constant, at the bigging of the code. So if it get changed, it is easy for someone else to find and change it

Do not leave thing behind
When you create any objects for testing and if you have done any configuration changes to the product for testing, make sure you undone them before you leave. Those objects and changes can break other tests by other users. You can use @AfterClass for that purpose.

Avoid Test anti-patterns
Just search for the test anti-patterns and you will find lot of them that you should avoid, or at least try to avoid.

Coverage Vs Stable Product
When we are testing, we normally get blinded by the coverage. But always our goal should be to build a stable product. No matter what is the test coverage if our product is failing, all the hard work is for nothing. This is told to me by our team lead Krishantha ayya.

Good Articles

Clarity Framework


Based on the training session and the slide-set provided by Dharshana, and Krishantha.

Clarity is a easy and optimized way to do the integration testing. It can automate platform-wide scenarios , execute tests against stratos and private clouds, adopt tooling(Selenium , SoapUI , Jmeter , Ravana, WSO2 Ravana is an opensource benchmark test framework that aims to facilitate performance benchmarks of different servers. ) support to automation , do reporting and keeping historical records.

Architecture

Work similar to TestNG.


  • This is the component level view of the architecture.



More information:

Monday, August 13, 2012

Beginning the Test Automation



We got this order to freeze our current project and join the test automation project, which was lead by Krishantha Samaraweera. 23 of us were divided in to 2 groups and assigned two of our major products, ESB and GREG. I am in the GREG test automation team. Here we are using a test framework called as 'Clarity'. Clarity was wso2 built testing framework which can be used to test our own products. Clarity is still under development. I will talk more about this framework in one of my future posts.

All the tests that we are writing is submitted as patches to the public jira project 'Test Automation'. Our team lead take a look at that and apply them to the main trunk/branch as we are not having committer rights. I will elaborate more on this jira thing and patch submission in my future posts.

We have to adhere to the standard coding style that is used in wso2. I have posted on this matter earlir in this blog. How to use the style xml to configure eclipse. You can find that post here. We used the remote debugging that is available in the IDE to test or patches. You can find my article on remote debugging here.

This was a nice learning curve for all of us. We went through lot of training sessions and was informed with best practices when testing, which were great additions to our knowledge. And it was a new place I was in 59 branch and now I am in 58 branch. And I must mention that here the TT table is far better than what we had in 59. After all this is temporary, I will return to the 59 after this test automation thing is done.

Tuesday, July 10, 2012

Using OSGi console to debug things


This OSGi console was very helpful to me in finding out problems relevant to OSGi bundles. You can have lot of information about this in the Internet. In here what I am going to write is about how I used it in the debugging.

First start the server with following option

-DosgiConsole. This will start the server with OSGi console. This is very helpful in situations like, checking whether all bundles that you put in to droppings have activated. When the server starts. Put ss in console. This will give a list of all bundles.




Use it with 'like' modifier to get the relevant bundles only. Ex ss like student

Now you can see state of all bundles. With the installation of a bundle in the OSGi runtime this bundle is persisted in a local bundle cache. The OSGi runtime then tries to resolve all dependencies of the bundle.If all required dependencies are resolved the bundle is in the status RESOLVED otherwise it is in the status INSTALLED.
If several bundles exist which would satisfy the dependency, then the bundle with the highest version is used. If the versions are the same, then the bundle with the lowest ID will be used. If the bundle is started, its status is STARTING. Afterwards it gets the ACTIVE status. - (http://www.vogella.com/articles/OSGi/article.html#osgiarch_bundles good reference)

You have to have all your bundles acticvated. If not check what is wrong with them using 'bundle <bundle number>' command. If there is no error, try starting it manually using 'start <bundle number>'



Monday, July 9, 2012

Publishing to BAM


I created this just to publish data I collect to BAM, so this do not adhere to good programming practices.

package org.wso2.carbon.usage.agent.util;

import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.UnknownHostException;

import javax.security.sasl.AuthenticationException;

import org.wso2.carbon.eventbridge.agent.thrift.Agent;
import org.wso2.carbon.eventbridge.agent.thrift.DataPublisher;
import org.wso2.carbon.eventbridge.agent.thrift.conf.AgentConfiguration;
import org.wso2.carbon.eventbridge.agent.thrift.exception.AgentException;
import org.wso2.carbon.eventbridge.commons.Event;
import org.wso2.carbon.eventbridge.commons.exception.DifferentStreamDefinitionAlreadyDefinedException;
import org.wso2.carbon.eventbridge.commons.exception.MalformedStreamDefinitionException;
import org.wso2.carbon.eventbridge.commons.exception.NoStreamDefinitionExistException;
import org.wso2.carbon.eventbridge.commons.exception.StreamDefinitionException;
import org.wso2.carbon.eventbridge.commons.exception.TransportException;

public class PublishUtil2 {
    public static final String STREAM_NAME1 = "org.wso2.db6.kpiii";
    public static final String VERSION1 = "1.0.6";
    private static String streamId1;
    private static DataPublisher dataPublisher = null;
    
    

    public static void publish(long exceededBytes, long databasesize, String tenentdomain) throws AgentException, MalformedStreamDefinitionException,
    StreamDefinitionException, DifferentStreamDefinitionAlreadyDefinedException, MalformedURLException,
    AuthenticationException, NoStreamDefinitionExistException,
    org.wso2.carbon.eventbridge.commons.exception.AuthenticationException, TransportException, SocketException, UnknownHostException{
        
     System.out.println("Starting BAM KPI Agent");
        AgentConfiguration agentConfiguration = new AgentConfiguration();
        String currentDir = System.getProperty("user.dir");
        System.setProperty("javax.net.ssl.trustStore", currentDir + "/repository/resources/security/client-truststore.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
        Agent agent = new Agent(agentConfiguration);
        
     dataPublisher = null;
        try {
        dataPublisher = new DataPublisher("tcp://10.100.3.80:7613", "admin", "admin", agent);
        } catch (Throwable e){
         e.printStackTrace();
        }

        streamId1 = null;


        try {
            streamId1 = dataPublisher.findEventStream(STREAM_NAME1, VERSION1);
            System.out.println("Stream already defined");

        } catch (NoStreamDefinitionExistException e) {
            streamId1 = dataPublisher.defineEventStream("{" +
                    "  'name':'" + STREAM_NAME1 + "'," +
                    "  'version':'" + VERSION1 + "'," +
                    "  'nickName': 'DSSUsage'," +
                    "  'description': 'Exceeded DB Use'," +
                    "  'metaData':[" +
                    "          {'name':'clientType','type':'STRING'}" +
                    "  ]," +
                    "  'payloadData':[" +
                    "          {'name':'exceededBytes','type':'LONG'}," +
                    "          {'name':'databasesize','type':'LONG'}," +
                    "          {'name':'tenentdomain','type':'STRING'}" +
                    "  ]" +
                    "}");
        }
        //Publish event for a valid stream
        if (!streamId1.isEmpty()) {
            System.out.println("Stream ID: " + streamId1);
            publishEvents(tenentdomain, exceededBytes, databasesize);

//            for (int i = 0; i < 1; i++) {
//                publishEvents("malinga");
//                System.out.println("Events published : " + (i + 1) * 2);
//            }
//            try {
//                Thread.sleep(3000);
//            } catch (InterruptedException e) {
//            }

            dataPublisher.stop();
        }
    }
    
    public static void publishEvents(String name, long exceededBytes, long databasesize) throws AgentException {
     System.out.println(name);
     publishEvents(dataPublisher, streamId1, name, exceededBytes, databasesize);

    }

    
    public static void publishEvents(DataPublisher dataPublisher, String streamId, String name, long exceededBytes, long databasesize) throws AgentException {
        Event eventOne = new Event(streamId, System.currentTimeMillis(), new Object[]{"external"}, null,
                new Object[]{exceededBytes, databasesize, 3600.0, name});
        dataPublisher.publish(eventOne);

    }

}

Problems I had to face.

I tried to change the streamId1, but it was not possible. It gave a error in BAM side. Then I got to know that schema is saved under the STREAM_NAME1, and if I want to change it, I have to do that with a change in STREAM_NAME1 too.

There was no way to check the the published data as it would show some rubbish, in the data viewer in BAM. I got a nice client for one of my mentors that can get the data from Cassandra cluster. This is written by 'Shariq Muhammed', he is a software engineer at WSO2. This is also written just to read the data and he haven't thought much about adhering to good programming practices. You can have it from below link


First I couldn't sent long, It took me a while to figure that out. It was because the number I send was taken as a int. I had to add the 'L' to end of it to get it working.