Tuesday, December 17, 2013

Nice reporting tool for TestNG tests


Recently came to the point where i needed to get reports for my TestNG reports and to use them in CI. After some googling i found ReportNG . It provides both XML and HTML reports and is very easy to setup.
On original page there's an instruction for setup with ant, but Maven users can find this article very useful

Friday, December 6, 2013

Add Microsoft SQL JDBC driver to Maven

Found out today that Maven does not directly support some libraries, like Microsoft’s SQL Server JDBC. The reason for that is that this library is not open source and can be stored in global repository. Anyway, i recently was wondering how to add a library to local maven repository to use it in my automation projects. Fast search in Google got me to this blog post. It's really easy :

  1. Visit the MSDN site for SQL Server and download the latest version of the JDBC driver for your operating system. 
  2. Unzip the package 
  3. Open a command prompt and switch into the expanded directory where the jar file is located. 
  4. Execute the following command. Be sure to modify the jar file name and version as necessary:

mvn install:install-file -Dfile=sqljdbc4.jar -Dpackaging=jar -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc4 -Dversion=4.0
Then you'll get this result :
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-install-plugin:2.4:install-file (default-cli) @ standalone-pom
---
[INFO] Installing C:\sqljdbc4.jar to C:\IDEConfigs\.m2\repository\com\microsoft\
sqlserver\sqljdbc4\4.0\sqljdbc4-4.0.jar
[INFO] Installing C:\Users\AF4C0~1.ZAK\AppData\Local\Temp\mvninstall797028335566
232276.pom to C:\IDEConfigs\.m2\repository\com\microsoft\sqlserver\sqljdbc4\4.0\
sqljdbc4-4.0.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.925s
[INFO] Finished at: Fri Dec 06 15:59:40 CET 2013
[INFO] Final Memory: 5M/121M
[INFO] ------------------------------------------------------------------------
Now you have this library in your local repository. If you want to use it in your project, then just add dependancy to your pom.xml file.

    com.microsoft.sqlserver
    sqljdbc4
    4.0

That's it. Now you can create connection to SQL Server in your tests

Tuesday, November 19, 2013

Nice and simple converter of Java ResultSet into JSONArray or XML

Right now i'm working with SOAP UI and responce i get in ResultSet format. Since i preffer to work more with JSON rather then ResultSet, i found this nice solution that perfectly fits my needs.
Here's the code : Thanks to this blog

Java doesn't resolve remote dns properly and how to deal with it

I don't think that this story will be short, but it's definitely interesting. So, i got a new project where i need to cover SOAP API with automated tests written on Java. As a start point i have URL to WSDL file to work with. The "tricky" part is the environment configuration. Our test environment is hidden behind SOCKS proxy server. So, if you want to work with test environment, you need to make your requests through that proxy, otherwise you'll "talk" to another environment that we don't need right now. Not usual configuration, but it had it's own reasons in the past for doing so. My first problem was to decide how to work with WSDL and in what direction my future framework would go. After some googling and trials, i've stopped on JAX-WS lib. It's handy because with wsimport maven task it can easily generate all needed classes and objects where your stubs will be held. Here's how it looks like in maven :


                    org.jvnet.jax-ws-commons
                    jaxws-maven-plugin
                    ${jaxws.plugin.version}
                    
                        
                            {put_some_id}
                            validate
                            
                                wsimport
                            
                            
                                
                                {your_wsdl_location}
                                ${project.basedir}\src\main\java\Stubs\oop
                                
                                    ${project.basedir}\src\main\resources\wsdl\myWSDL.wsdl
                                
                                Stubs.oop
                                
                                ${project.build.directory}/jaxws/stale/wsdl.done
                            
                        
                        
                            {put_some_id}
                            validate
                            
                                wsimport
                            
                            
                                
                                {your_wsdl_location}
                                ${project.basedir}\src\main\java\Stubs\wsdl2
                                
                                    ${project.basedir}\src\main\resources\wsdl\your_wsld2.wsdl
                                
                                your_package_name
                                
                                ${project.build.directory}/jaxws/stale/wsdl.done
                            
                        
                    
                
It was a bit hard for me to get WSDL from URL, so i decided to save it locally and read it from there then. Since changes are not being made frequently in API, i can easily accept this. This configuration allows to add as many WSDL sources as i want and to store stubs for each of them in separate packages in the project. First problem was solved. Now, i had to figure out how to put my requests through Proxy . My first trial was basic and most common in Java world:
System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", getProxyHost());
System.getProperties().put("proxyPort", getProxyPort());
But i kept getting errors and no successful connection. My next guess was that problem could be in SSL , since we are using https. So, i went into the browser, imported security certificate ( they were self-signed since it's a test environment), added them to java cacerts keystore and added next to my code :
System.setProperty("javax.net.ssl.keyStore", "keystore.jks");
System.setProperty("javax.net.ssl.trustStrore", "cacerts.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
I tried to debug and to make sure that JVM is using my proxy settings and it was true - everything was there. What would be the next step in debugging for me ? I decided to install local proxy and try to put my requests through it, so i could get more details. I've installed Charles - a fantastic proxy server that helped me a lot in the past with REST API automation. It has a life changing ( for me in this case) "External Proxy" option . I've set it to forward all requests to our SOCKS proxy and then told to my tests to make calls through Charles. And it worked! You can't even believe how happy i was because of it:) But now i got another problem - Charles cost 50$ for one license:)So, there were 2 questions that i needed to solve : * Why my Java calls works fine with Charles and without it they fail? * Where to find free and easy to setup http proxy with forwarding possibility?:) With help from one of our developers we could find out why Java kept getting authentification errors and didn't want to connect to test environment properly. The problem was that java was connecting to SOCKS proxy properly, but it was resolving remote dns to another environment to which i didn't have proper certificates and credentials for authorization! I found only one article on stackoverflow regarding this issue and from that point i new that i need to have local http proxy that is : * free * can forward my requests to SOCKS proxy I've spent whole day trying to find some easy to use and adequate proxy server for Windows ( it's my Workstation that i need to use) , looked over 15 different apps and still couldn't find anything that i could use. In the end of the day i've installed VirtualBox with Ubuntu and installed there squid3 proxy server. It's the most popular and common proxy server for Unix, from what i saw on Google. But, this crazy proxy has configuration file with more then 3000 lines!! It's not that easy to make it run as i want, it's not even that easy to restart it. So, after couple hours i gave up on it and started looking for alternatives. Luckily, i found Polipo - tiny, easy to install and setup proxy server. It has few main options that i had to setup and make everything work as a charm : * proxyAddress - set it to ip address of your local virtual box, or your local machine, if you use linux or mac * allowedClients - list of ip addresses from which polipo will allow to access it and forward requests towards another proxy or web directly * socksParentProxy = "host name and port of your proxy to which i needed to forward my requests" * socksProxyType = socks5 Save changes and restart - that's it! After that i pointed my Java framework to local proxy and got green tests! To set proxy for my tests i used custom MyProxySelector class :
package Base;

import java.net.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.io.IOException;


public  class MyProxySelector extends ProxySelector {
    // Keep a reference on the previous default
    public ProxySelector defsel = null;

    /**
     * Inner class representing a Proxy and a few extra data
     */
    class InnerProxy {
        Proxy proxy;
        SocketAddress addr;
        // How many times did we fail to reach this proxy?
        int failedCount = 0;

        InnerProxy(InetSocketAddress a) {
            addr = a;
            proxy = new Proxy(Proxy.Type.HTTP, a);
        }

        SocketAddress address() {
            return addr;
        }

        Proxy toProxy() {
            return proxy;
        }

        int failed() {
            return ++failedCount;
        }
    }

    /**
     * A list of proxies, indexed by their address.
     */
    HashMap proxies = new HashMap();

    public MyProxySelector(ProxySelector def, String host, int port) {
        // Save the previous default
        defsel = def;

        // Populate the HashMap (List of proxies)
        InnerProxy i = new InnerProxy(new InetSocketAddress(host, port));
        proxies.put(i.address(), i);
    }

    /**
     * This is the method that the handlers will call.
     * Returns a List of proxy.
     */
    public java.util.List select(URI uri) {
        // Let's stick to the specs. 
        if (uri == null) {
            throw new IllegalArgumentException("URI can't be null.");
        }
        /**
         * If it's a http (or https) URL, then we use our own
         * list.
         */
        String protocol = uri.getScheme();
        if ("http".equalsIgnoreCase(protocol) ||
                "https".equalsIgnoreCase(protocol)) {
            ArrayList l = new ArrayList();
            for (InnerProxy p : proxies.values()) {
                l.add(p.toProxy());
            }
            return l;
        }
        
        /**
         * Not HTTP or HTTPS (could be SOCKS or FTP)
         * defer to the default selector.
         */
        if (defsel != null) {
            return defsel.select(uri);
        } else {
            ArrayList l = new ArrayList();
            l.add(Proxy.NO_PROXY);
            return l;
        }
    }

    /**
     * Method called by the handlers when it failed to connect
     * to one of the proxies returned by select().
     */
    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
        // Let's stick to the specs again.
        if (uri == null || sa == null || ioe == null) {
            throw new IllegalArgumentException("Arguments can't be null.");
        }
        
        /**
         * Let's lookup for the proxy 
         */
        InnerProxy p = proxies.get(sa);
        if (p != null) {
                /**
                 * It's one of ours, if it failed more than 3 times
                 * let's remove it from the list.
                 */
            if (p.failed() >= 3)
                proxies.remove(sa);
        } else {
                /**
                 * Not one of ours, let's delegate to the default.
                 */
            if (defsel != null)
                defsel.connectFailed(uri, sa, ioe);
        }
    }
}
And to turn proxy on and off i wrote next switch methods :
private ProxySelector defaultProxy = ProxySelector.getDefault();
public void setLocalProxy(){
        MyProxySelector ps = new MyProxySelector(ProxySelector.getDefault(),localProxyName,localProxyPort);
        ProxySelector.setDefault(ps);

    }

public void disableProxy(){
    ProxySelector.setDefault(defaultProxy);

    }
That's it. Now i can run my tests easily with control of when to use proxy and when not. In the future i'll move my tests to CI ( Jenkins most probably) and will setup on that environment Polipo proxy in 2 minutes. It's always nice to solve such non-ordinary problems. Most probably my solution is not very elegant and "right" , but it works right now and for this moment this what matters for me, since i can start writing automated tests rather then fighting with this configuration issues. *Update* . One of my colleagues proposed me to set next settings for Java :
System.setProperty("sun.net.spi.nameservice.nameservers", "ip_here");
System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun");
 
But it didn't work for me. So will stick with my current solution for now.

Friday, September 20, 2013

Found a nice solution for monitoring selenium tests on headless linux machine

Hey guys, found today from one of my colleagues a good tip about how to debug selenium tests with gui on headless linux. Maybe someone wil find it also helpful. Here's the link

Tuesday, September 17, 2013

Comparison of python json libs in performance

I work a lot with json in python and never thought before about performance. I was using standard python json lib that goes right from the box, but today found out from one of my colleagues that there is way more faster lib called cjson. I got interested in this and googled a little bit. As a result i got a python script that shows which json lib is faster on Python. Here it is : As a result i got this metrics :
yajl        serialize: 0.308  deserialize: 0.334  total: 0.642
json        serialize: 1.245  deserialize: 1.384  total: 2.629
cjson       serialize: 0.339  deserialize: 0.244  total: 0.583
stdlib json serialize: 1.019  deserialize: 1.396  total: 2.415
ultra json  serialize: 0.170  deserialize: 0.159  total: 0.328
[Finished in 7.0s]
And the winner is ultra json! :) If you want to clone this script for yourself - here's the link  

Monday, September 16, 2013

Rotating a two-dimensional array in Python

I was solving one of the learning tasks on Python and had to rotate two dimensional array clockwise. In Java i would have to loop over array and pass values into newly created array, but in Python i could solve this with one line of code :
 template = zip(*template[::-1])
And an explanation for this line is next : Consider the following two-dimensional list:
original = [[1, 2],
            [3, 4]]
Lets break it down step by step:
original[::-1]   # elements of original are reversed
[[3, 4], [1, 2]]
This list is passed into zip() using argument unpacking, so the zip call ends up being the equivalent of this:
zip([3, 4],
    [1, 2])
#    ^  ^----column 2
#    |-------column 1
# returns [(3, 1), (4, 2)], which is a original rotated clockwise
Hopefully the comments make it clear what zip does, it will group elements from each input iterable based on index, or in other words it groups the columns.

Wednesday, September 11, 2013

Getting HTTP traffic details from tcpdump

Yestarday i had one issue to verify where i had to make sure that our backend part is sending POST requests with id's to third party server.  Server didn't have GUI , so i couldn't use Wireshark for that ( or could, but just don't know how:) ) and i googled for possible solutions.  So, here're two possible ways that could help you out in such case :
1) Basic one is simply run
 tcpdump -w output.log
and then download this file on your computer, open it in Wireshark and analize with it

2) Or you could try to analyze it in console with this commands :) :
# tcpdump filter for HTTP GET 
sudo tcpdump -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'

# tcpdump filter for HTTP POST 
sudo tcpdump -s 0 -A 'tcp dst port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354)'

# monitor HTTP traffic including request and response headers and message body
# cf. https://sites.google.com/site/jimmyxu101/testing/use-tcpdump-to-monitor-http-traffic
tcpdump -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2 data-blogger-escaped--="" data-blogger-escaped-tcp="" data-blogger-escaped-xf0="">>2)) != 0)'
tcpdump -X -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2 data-blogger-escaped--="" data-blogger-escaped-tcp="" data-blogger-escaped-xf0="">>2)) != 0)'

2) But the easiest and way more better looking option is to use Chaosreader . The script is called chaosreader0.94. See here for more details.  So, you just need to :

  1. Run this

  2.  tcpdump host 93.23.40.50 -s 9000 -w outputfile; perl chaosreader0.94 outputfile
  3. You can use both IP address of the server or it's direct http url
  4. Generate traffic
  5. Hit Ctrl+C and look for resuls in html file that chaosreader0.94 will generate for us.

Sunday, September 1, 2013

The Hamming distance task solution

I was going through new interesting tasks on http://www.checkio.org/ and faced with bytes task about Hamming distance calculation. Here's some theory about this : 
The Hamming distance between two binary integers is the number of bit positions that differs (http://en.wikipedia.org/wiki/Hamming_distance). For example: 
117 = 0 1 1 1 0 1 0 1 17 = 0 0 0 1 0 0 0 1 H = 0+1+1+0+0+1+0+0 = 3 
And the task was : 

Given two positive integers in decimal form. You should calculate the Hamming distance between these two numbers in binary form.

I don't like tasks with bytes because i don't understand them fully:) So, i started googling and playing around with different solutions. In the end i got my code running and completing the task as it was required : 

And then i got access to other people solutions. Well, it was very surprising and exciting to see this nice, clean and short solution for my problem:) 
def checkio(data):
    a, b = data
    return str(bin(a^b)).count('1')
 
#These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
    assert checkio([117, 17]) == 3, "First example"
    assert checkio([1, 2]) == 2, "Second example"
    assert checkio([16, 15]) == 5, "Third example"

Which, we all have to admit, is cool and looks really good. For the one who just start studying python here's some short description of how this cool algorithm works : According to python docs :
Bitwise operator works on bits and perform bit by bit operation. Assume if a = 60; and b = 13; Now in binary format they will be as follows: a = 0011 1100 b = 0000 1101 ----------------- a&b = 0000 1100 a|b = 0011 1101 a^b = 0011 0001 ~a  = 1100 0011
So,
  1. bin() - converts ints into bytes
  2. a^b - Binary XOR Operator copies the bit if it is set in one operand but not both
  3. .count("1") - counts how many 1 in result
Nice and easy:)
P.S. while i was googling about this convertation from int into bytes and back, i found useful python script which i used for my method :

Another cool website for beginners who want to learn Python

Found this today - http://www.checkio.org/ . From my experience i've noticed that learning in a gaming mode goes much better and faster. Besides it's a great motivator to continue studying and getting new perks for successfully finished tasks.  I've already passed all lessons for ruby, python on Codeacademy , finished all tasks on http://codingbat.com and now going to finish this checkio game and win it :) you should try it for youself - python is awesome and fun to learn. 

Needed to make Google think that i'm from US

Since i live in Ukraine right now, sometimes i want to use services that are working only for US citizens. For example Spotify will work for you only if you live in US or in some european countries. I used to user Tunnelbear on my macbook Air and it worked like a charm until some point where it stopped logging in for me:( Since that moment i forgot about this issue and found some alternatives for Spotify. However, yesterday one of my friends asked me about how she can buy Google Nexus 4. I found some articles for her, but before sending it, i decided to check myself how well they work and whether i can get access to Google play where i can order this Nexus 4 device. First solution was to use Firefox + anonymousX plugin, but it didn't worked for me even when i set timezone on my laptop to US and cleared all cookies and cache in Firefox. Second option was to register on one of the web tunnels which can become a VPN provider for you and mask you as a US citizen. I was too lazy for registering on one more web service, that will most likely spam me with e-mails afterwards, and i kept looking. My third and final option was to use Tor browser. I've heard about this project before and it was interesting for me to try it out. Here's what you gonna need  to do: 
  • Download it
  • Install:)
  • Launch at first time, so it will create all needed config files and will connect to Tor network at first time
  • Then you're gonna need to open Terminal ( i'm a Mac user) and run next command :
  • nano /Applications/TorBrowser_en-US.app/Contents/MacOS/Vidalia.app/Contents/MacOS/../../../../../Library/Vidalia/torrc
  • In the end of the file paste this 2 values :
  • ExitNodes {US}
    StrictExitNodes 1
  • Save it, stop Tor and then start it again
  • Now go to https://play.google.com/store and you'll see that devices section is available for you and you can actually select and purchase one of them:) 

You can actually specify any country you need and "simulate" situation when you're accessing your application from another country. I believe that for more simpler tasks you can use both Tor and Firefox + anonymousX plugin, but Tor can be considered as a backup when Firefox fails you. 

Simple HTTP Server that will give serve simple files and can emulate delay before giving response

On one of my projects i had a task where i needed to make a  simple http server that would give one xml file for our service (Trying to emulate and verify sync between two services). But besides that i had also to check that application behaves properly when you get timeout from the server on the other end. So, i've started googling and found really nice and fast solution with python SimpleHTTPServer. I found it here and modified it a little bit for my purposes with delay emulation. Here's the code : 



You can save it as server.py and they simple run it on your server as:
python server.py 8081 0&

It will run this server on 8081 port ( you can change it to any free port you want) . Second value is for delay - 0 if you want server to respond right away, !=0 - set how many seconds you want server to wait before responding.

It's very fast and easy way to check this things, and i'm pretty sure i will use it in the future and maybe will modify and improve it when it will be needed. The beauty of this method is that you don't have to setup any server and launch it. All you need is installed Python ( which is already preinstalled on any Unix machine) and this file.