Powered By Blogger

Friday, January 31, 2014

Multipart Fitnesse fixture for Restful Apis

Fitnesse Fixture to handle Multipart/mixed Requests



Just wrote a fitnesse fixture for multipart mixed content types.
The already existing smartrics rest fixtures can handle only multipart/form-data not multipart/mixed.

It is also strange that the Httpcomponent 3.2  does not support multipart/mixed, but only multipart/form-data. Worse enough, I see no documentation that it does not support multipart/mixed. Going through the source code, I could see that the 'multipart/form-data' content type is hard-coded all over the place.

My fixture is written using :
Http component 4.3 : I have added additional support for multipart/mixed, apart from the already existing multipart/form-data
Smartrics rest fixutre 3.0 : Extended the already existing restfixture class and the partfactory class to support multipart/mixed

See my Google code Repository

Sample request to handle Multipart Mixed :


!|smartrics.rest.fitnesse.fixture.RestFixtureConfig|
|http.client.connection.timeout|55000|
|restfixture.display.actual.on.right|true|
|restfixture.default.headers|defHeader : 1|
|restfixture.xml.namespace.context|!-xsalias=${namespace1}
ysalias=${namespace2}
-!|
|restfixture.content.handlers.map|application/xml=XML|
!|com.goraksh.fitnesse.fixture.FitMultipartRestFixture|http://${BASE_URI}|
|setBody|....|
|uploadFile|D:\testcase\hello.txt|
|setHeader|X-session-header : %sessionId%|
|POST|/${RESOURCE_PATH}?${QUERY_PARAMS}|201|!-Cache-Control : no-cache
pragma : no-cache
Content-Type : application/xml-!||

Sample Request to handle Multipart/form-data


!|smartrics.rest.fitnesse.fixture.RestFixtureConfig|
|http.client.connection.timeout|55000|
|restfixture.display.actual.on.right|true|
|restfixture.default.headers|defHeader : 1|
|restfixture.xml.namespace.context|!-xsalias=${namespace1}
ysalias=${namespace2}
-!|
|restfixture.content.handlers.map|application/x-www-form-urlencoded=FORM-DATA|
!|com.goraksh.fitnesse.fixture.FitMultipartRestFixture|http://${BASE_URI}|
|setBody|....
|uploadFile|D:\testcase\hello.txt|
|setHeader|X-session-header : %sessionId%|
|POST|/${RESOURCE_PATH}?${QUERY_PARAMS}|201|!-Cache-Control : no-cache
pragma : no-cache
Content-Type : application/xml-!||

Thursday, January 23, 2014

Fitnesse Generic Fixture


Fitnesse Generic Fixture:


1. Use genericfixture.jar in the classpath, at the beginning of the script as:

classpath: C:\Fitnesse\RestFixture-2.0.beta.2_29th NOV_II\lib\genericfixture.jar

2. Write the Java code for Fixture. It may or may not extend fit.Fixture class
Create  a jar and used in the script classpath as:
classpath: D:\MyFit\myfit.jar

Here name of the jar is myfit.jar that contains the required code for Generic Fixtures

Like AdderTest: class.


It has fw public methods:
a.) getUrl ==> This method is a setter method.
b.) add(a,b) ==> This method takes two arguments and returns the sum
c.) getId() ==> This method does not take any arguemnt. It parses the Url and the returns a substring, the trailing ID.

Now how to use this class as generic fixture:

A fitnesse script :

 Do a Http get

!|smartrics.rest.fitnesse.fixture.RestFixtureConfig|
|restfixture.xml.namespace.context|!-xsalias=http://bindings.egain.com/ws/model/v12/gen/kb
ysalias=http://bindings.egain.com/ws/model/v12/gen/common
zsalias=http://bindings.egain.com/ws/model/v12/gen/platform
-!|
!|smartrics.rest.fitnesse.fixture.RestFixture|http://${mname}/system/ws/v12/kb|
|setHeader|X-egain-session : %agent1sessionId%|
|GET|/attachment?article=${articleId}&version=${versionId}&$attribute=all|200|Content-Type:application/xml||
|let| contentUrl |body|/xsalias:Attachments/xsalias:attachment/xsalias:contentUrl[text()]||
|let | a | body |/xsalias:Attachments/xsalias:attachment/xsalias:type[text()]| |

Use of Generic fixture

!| Generic Fixture | myfit.AdderTest |
| getUrl | contentUrl  |
| var=getId|   | 0b5cd3c5-c070-4bfc-a748-920aa5e0feb7  |


Use of variable 'var'

!|smartrics.rest.fitnesse.fixture.RestFixtureConfig|
|restfixture.xml.namespace.context|!-xsalias=http://bindings.egain.com/ws/model/v12/gen/kb
ysalias=http://bindings.egain.com/ws/model/v12/gen/common
zsalias=http://bindings.egain.com/ws/model/v12/gen/platform
-!|
!|smartrics.rest.fitnesse.fixture.RestFixture|http://${mname}/system/ws/v11/internal|
|setHeader|X-egain-session : %agent1sessionId%|
|GET|/stream/%var%|200|Content-Type:text/plain||

Explanation


Generic Fixture must start with the name: Generic Fixture. Use ! mark to start.
Second column is the name of the Class( AdderTest )
This class does not have a constructor. Incase it had one, there should be a third column like:
!| Generic Fixture | myfit.AdderTest | constructorArg1 | constructorArgs2 |

Now the second row, third row start wth method name:

Second Row: Here getUrl is the name of the method. Second column is the value passed to the method getUrl.
This value must match the type of the method argument type. Also this value is passed statically.i.e the value accessible in the getUrl method is actually "contentUrl", not the one extracted by the RextFixture.

To reflect the dynamic value in the getUrl method, it needs to be processed like:

String newVal = "";
   if (Fixture.hasSymbol(val))
        newVal = Fixture.getSymbol(val).toString();
return newVal;

There is no third column for second row. The column has to be left blank to denote that the method returns at this point. Next column after this blank will match the return string.

Like 
| getUrl | contentUrl  |   |    /system/ws/v12/internal/stream/0b5cd3c5-c070-4bfc-a748-920aa5e0feb7 |

Here third column is blank because it denotes a return from method. Next column is the value to be matches. So this test case expects the value returned from getUrl method to be "/system/ws/v12/internal/stream/0b5cd3c5-c070-4bfc-a748-920aa5e0feb7"

It's like : assert getUrl() equals "/system/ws/v12/internal/stream/0b5cd3c5-c070-4bfc-a748-920aa5e0feb7"

Third Row: 
Here again  the first column is the method name. It intends to call getId method. But this testcase also intends to assign the value returned by getId to a variable so that it can be used in further test cases. Hence var=getId. Value is stored in variable 'var'. 
Column two is blank, which denotes a return from method getId. Column three is an assertion i.e this test case expects '0b5cd3c5-c070-4bfc-a748-920aa5e0feb7 ' to be returned from the getId method.

Code


package myfit;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;

import fit.Fixture;

public class AdderTest extends fit.Fixture {
private String url ;
public AdderTest (  ) {
        String sampleUrl = "/system/ws/v12/internal/stream/0b5cd3c5-c070-4bfc-a748-920aa5e0feb7";
System.out.println( s.substring( s.indexOf("eam/") + 4 )); // prints 0b5cd3c5-c070-4bfc-a748-920aa5e0feb7
}
public void getUrl( String ss ) {
this.url = getStringVal(ss );
}
public String getStringVal(String val){
String newVal = "";
  if (Fixture.hasSymbol(val))
       newVal = Fixture.getSymbol(val).toString();
return newVal;
}

public int add( int a , int b ) {
return a+b;
}
public String getId() {
if ( url == null ) return "null";
if ( url.indexOf("eam/") == -1  ) return "-1";
return url.substring( url.indexOf("eam/") + 4 );
}
}

Command line to compile , run and create jar:

javac -classpath lib\fitnesse.jar  src\myfit\*.java -d .\bin
@REM java -cp D:\MyFit\bin fit.Adder

cd bin
jar cvf D:\MyFit\myfit.jar myfit/*

@REM  java -classpath lib\fitnesse.jar;myfit.jar myfit.AdderTest

Now myfit.jar can be used in the import statements of the script


Example # 1

Use java.lang.sleep to cause a delay between tests:

!| Generic Fixture |
| java.lang.Thread.sleep | 1000 |



Friday, September 20, 2013

Sort A linked List with N numbers. Range of Numbers in ( 0, 1, 2 )

Sort a Linked List with N numbers. Range of Numbers in this Linked List in ( 0, 1, 2 )

For exmaple:
A Linked List with numbers : { 0, 0, 1, 2, 2, 1, 1, 0, 0, 1, 2 } OR { 2,0, 0, 1, 2, 2, 1, 1, 0, 0, 1, 2 }, etc

Below is the Program to sort this:

public class SortALinkedList {

    public Link sort(Link head) {
     
        if (head == null)
            return head;
        if (head.next == null)
            return head;

        Link k = head;
        Link _0 = null;
        Link _1 = null;

        if (head.value() == 0)
            _0 = k;
        else if (head.value() == 1)
            _1 = k;

        Link iter = head.next;
        Link iter_before = head;

        while (iter != null) {

            if (iter.value() == 2) {
                iter_before = iter;
                iter = iter.next;
                continue;
            }

            Link p = iter;
            iter = iter.next;
            iter_before.next = iter;

            if (p.value() == 1) {

                if (_1 == null) {
                    _1 = p;

                    if (_0 != null) {
                        p.next = _0.next;
                        _0.next = p;
                    } else {
                        p.next = head;
                    }
                } else {
                    p.next = _1.next;
                    _1.next = p;
                }

            } else if (p.value() == 0) {

                if (_0 == null) {
                    _0 = p;
                    p.next = (_1 == null ? head : _1);
                } else {
                    p.next = k;
                }
                k = p;
            }

        }

        return k;
    }

    public static void main(String[] args) {

        int[] arr0 = new int[] { 0, 0, 1, 2, 2, 1, 1, 0, 0, 1, 2 };
       
        int[] arr1 = new int[] {  1,0, 2, 2, 1, 1, 0, 0, 1, 2 };
       
        int[] arr2 = new int[] { 2,1, 0, 1, 2, 2, 1, 1, 0, 0, 1, 2 };
       
        int[] arr3 = new int[] { 2,0, 0, 1, 2, 2, 1, 1, 0, 0, 1, 2 };
       
        int[] arr4 = new int[] { 2,2,0, 0, 1, 2, 2, 1, 1, 0, 0, 1, 2 };
       
        int[] arr5 = new int[] {  1, 1, 0, 2, 2, 1, 1, 0, 0, 1, 2 };
       
        Link head = Link.build(arr0);

        SortALinkedList srt = new SortALinkedList();
        Link k = srt.sort(head);

        k.print(k);
   
    }

}

Tuesday, September 10, 2013

Eclipse Remote Debugging:

Failed to connect to remote VM. Connection timed out

 

The above error is the most frequently encountered by Developers working with different eclipse version.
It is almost too irritating all to get this error and spend a substantial portion of the day debugging it.

Some things to try to get past this error:

1. First check the network connection settings ( Assuming you can ping to the remote machine successfully )

Go to Window -> Preferences -> General -> Network Connections, and check if there is any proxy set here, change the 'Active Provider' to be 'Direct' and try again

For more see the below link:
http://stackoverflow.com/questions/9034147/getting-launch-error-failed-to-connect-to-remote-vm-connection-timed-out-whic

2. Increase the Debug timeout paramters:
http://stackoverflow.com/questions/5990438/eclipse-remote-debug-timeout-problem

3. Check the remote server Debug settings:
My Java debug options configured on the remote server:

set "JAVA_OPTS=%JAVA_OPTS% -Xrunjdwp:transport=dt_socket,address=8788,server=y,suspend=n"

where 8788 is the port to connect to for remote debugging.

This port, 8788 must be provided in the ecliipse settings

See this link for how to add the remote server name and remote server debug port:
http://java.dzone.com/articles/how-debug-remote-java-applicat

4. For more general information, see link:
http://javarevisited.blogspot.in/2011/02/how-to-setup-remote-debugging-in.html

 

Friday, September 6, 2013

QuickSort on an Array

Implement a QuickSort on an Array


public class QuickSort {
   
    int partition( int[] in ) {
        if ( in.length == 1) return 0;
   
        if ( in.length == 2 ) {
            if ( in[0] > in[1]) {
                swap(in , 0 ,1);
                return 1;
            }else if( in[0] == in[1])
                return 1;
            else return 0;
               
        }
       
        int pivot = in[0];
        int down = 1;
        int up = in.length - 1;
        int ele = -1;
       
        while ( up > down ) {
            // move down pointer
            while( in[down] <= pivot && down < in.length -1)
                ++down;
                   
            while( in[up] > pivot && up > 0)
                --up;
               
            if ( up > down) {
                swap(in, down, up);
                ele = down;
               
                ++down;
                --up;
            }
        }

        if ( in[up] > pivot) {
            swap(in, 0, ele);
        }else{
            swap(in, 0, up);
            ele = up;
        }

        return ele;
    }
   
    private void swap( int[] in, int lb, int ub ) {
        int tmp = in[lb];
        in[lb] = in[ub];
        in[ub] = tmp;
    }
   
    void print(int[] in) {
        for( int i: in )
            System.out.println(i);
    }
   
    public static void main( String[] args ) {
       
        int[] in = new int[] {57,25, 36, 69, 22, 99, 48, 98, 88, 79, 62 };
       
        int[] in1 = new int[] {25, 22, 21, 23, 24 };
       
        int[] in2 = new int[] { 21, 24, 26, 28, 49 };
       
        int[] in3 = new int[] { 25, 57, 48, 37, 12, 92, 86, 33};
       
        int[] in4 = new int[]{2,1,3,-2,0};
       
        int[] in5 = new int[]{2,1,0,6,-7};
       
        int[] in6 = new int[]{25,35,49,50,21,22,25};
       
        int[] in7 = new int[]  {2,1,2};
       
        int[] in8 = new int[]  {2,2};
       
        QuickSort sort = new QuickSort();
   
        System.out.println("--------------------");
       
        System.out.println(sort.partition(in));
        sort.print(in);
       
        System.out.println("-------------------------------");
        System.out.println(sort.partition(in1));
        sort.print(in1);
   
        System.out.println("-------------------------");
        System.out.println(sort.partition(in2));
        sort.print(in2);
       
        System.out.println("-------------------------------");
        System.out.println(sort.partition(in3));
        sort.print(in3);
       
        System.out.println("-------------------------------");
        System.out.println(sort.partition(in4));
        sort.print(in4);
       
        System.out.println("----------------------");
        System.out.println(sort.partition(in5));
        sort.print(in5);
       
        System.out.println("-------------------------");
        System.out.println(sort.partition(in6));
        sort.print(in6);
       
        System.out.println("---------------------------");
        System.out.println(sort.partition(in7));
        sort.print(in7);
       
        System.out.println("---------------------------");
        System.out.println(sort.partition(in8));
        sort.print(in8);
       
       
    }

}