Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Tuesday, 17 June 2014

EasyMock : Simple Tutorial

EasyMock provides an easy way to create Mock Objects for interfaces and classes generating them on the fly. It is a mock framework which can easily be used in conjunction with JUnit. It is a perfect fit for Test-Driven development.

In this post, we will see how EasyMock can be used to easily test our Java application. EasyMock is helpful in situations wherein you want to mock some of the objects in an application for testing purposes. Service layer classes which often talk to external database/server can easily be mocked. One can easily define the behavior which is expected in response to a certain event. 

I have made use of PowerMock to invoke methods in an object. We need EasyMock, Objenesis and Cglib libraries added to the classpath.You can find the complete source code here.

This is how you create a mock object and specify what is to be returned in response to a certain expected event.

Retailer retailer = EasyMock.createMock(Retailer.class);

EasyMock.expect(retailer.getPriceForProduct("101")).andReturn(220);

The createMock() creates a mock retailer object. Whenever a call is made to getPriceForProduct() with "101" as the productId argument the returned value will be 220 as set by EasyMock.

Also, we need to activate our mock object before making its use using replay() method.This replay() is to be done after specifying all the expectations and returns.

EasyMock.replay(retailer);

Here is an Example. We have a customer class which has retailer object as its member.
package com.nirman.easymock;

public class Customer {

 String name;
 Retailer retailer;

 public int getProductPrice(String productId) throws Exception{
  int price = retailer.getPriceForProduct(productId);
  return price;
 }
 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Retailer getRetailer() {
  return retailer;
 }

 public void setRetailer(Retailer retailer) {
  this.retailer = retailer;
 }

}

This is the Retailer class.
package com.nirman.easymock;

public class Retailer {

 private int taxes_in_percent = 10;

 public int getPriceForProduct(String productId) throws Exception {
  int price;
  if (productId.equals("101")) {
   price = getPrice(100);
  } else if (productId.equals("102")) {
   price = getPrice(200);
  } else if (productId.equals("103")) {
   price = getPrice(300);
  } else {
   price = 0;
  }
  return price;
 }

 private int getPrice(int basePrice) {
  int finalPrice = basePrice + ((basePrice * getTaxRate()) / 100);
  return finalPrice;
 }

 public int getTaxRate() {
  return taxes_in_percent;
 }
}

There is a method getPriceForProduct(String productId) which takes productId and returns its price after adding the taxes that are applicable. We will mock this method using EasyMock. 

This is my JUnit -
package com.nirman.easymock;

import org.easymock.EasyMock;
import org.junit.Test;
import org.powermock.reflect.Whitebox;
import static org.junit.Assert.*;

public class TestRetailer {

 // Without any mocks
 @Test
 public void testGetPriceForProduct() throws Exception {
  Customer customer = new Customer();
  Retailer retailer = new Retailer();
  customer.setRetailer(retailer);
  int actual = 0;

  String productId = "101";
  actual = Whitebox. invokeMethod(customer, "getProductPrice",
    productId);

  int expected = 110;
  assertEquals(expected, actual);
 }

 // Mocked the getPriceForProduct() in retailer
 @Test
 public void testGetPriceForProductEasyMock() throws Exception {
  Customer customer = new Customer();
  Retailer retailer = EasyMock.createMock(Retailer.class);
  customer.setRetailer(retailer);
  EasyMock.expect(retailer.getPriceForProduct("101")).andReturn(220);
  EasyMock.replay(retailer);

  int actual = 0;

  String productId = "101";
  actual = Whitebox. invokeMethod(customer, "getProductPrice",
    productId);

  int expected = 220;
  assertEquals(expected, actual);
 }

 // Assertion Error. As the mock is not activated, actual returned is 0;
 @Test
 public void testGetPriceForProductAssertionError() throws Exception {
  Customer customer = new Customer();
  Retailer retailer = EasyMock.createMock(Retailer.class);
  customer.setRetailer(retailer);
  EasyMock.expect(retailer.getPriceForProduct("401")).andReturn(220);
  int actual = 0;

  String productId = "401";
  actual = Whitebox. invokeMethod(customer, "getProductPrice",
    productId);
  int expected = 220;
  assertEquals(expected, actual);
 }

}

Note that the third Test here for testGetPriceForProductAssertionError() will result in an assertion error and will not pass as the mock was not activated in that case resulting in an unexpected behavior.

Thanks and Happy Coding !!

Partial Mocks using EasyMock

Often, there arises a situation where we need to mock only specific methods of a certain object and not the entire class. Such a situation can arise when we need to test some methods of a class which are dependent on other methods. We need to mock methods on which the behavior is dependent. Solution is to use partial mocks and to mock only the required methods.

In this post, we will see how this partial mock object can be created using EasyMock. To get familiar with EasyMock, you can refer here.

This is how we can create partial mock objects.
Retailer retailer = EasyMock.createMockBuilder(Retailer.class)
.addMockedMethod("getTaxRate").createMock();
EasyMock.expect(retailer.getTaxRate()).andReturn(20);

The createMockBuilder() creates a mock retailer object with 'getTaxRate' method as mocked. We can add as many methods to mock as required.The behavior of rest of the functions remains same.

We will use the same example used in my previous post. Here is the Customer class which has retailer object as its member -
package com.nirman.easymock;

public class Customer {

 String name;
 Retailer retailer;

 public int getProductPrice(String productId) throws Exception{
  int price = retailer.getPriceForProduct(productId);
  return price;
 }
 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Retailer getRetailer() {
  return retailer;
 }

 public void setRetailer(Retailer retailer) {
  this.retailer = retailer;
 }

}

This is the retailer class -
package com.nirman.easymock;

public class Retailer {

 private int taxes_in_percent = 10;

 public int getPriceForProduct(String productId) throws Exception {
  int price;
  if (productId.equals("101")) {
   price = getPrice(100);
  } else if (productId.equals("102")) {
   price = getPrice(200);
  } else if (productId.equals("103")) {
   price = getPrice(300);
  } else {
   price = 0;
  }
  return price;
 }

 private int getPrice(int basePrice) {
  int finalPrice = basePrice + ((basePrice * getTaxRate()) / 100);
  return finalPrice;
 }

 public int getTaxRate() {
  return taxes_in_percent;
 }
}

Note that the getPrice(int basePrice) internally calls getTaxRate(). We will mock this getTaxRate() and keep rest of the behaviour same.

JUnit-
package com.nirman.easymock;

import org.easymock.EasyMock;
import org.junit.Test;
import org.powermock.reflect.Whitebox;
import static org.junit.Assert.*;

public class TestRetailer {

 // Without any mocks
 @Test
 public void testGetPriceForProduct() throws Exception {
  Customer customer = new Customer();
  Retailer retailer = new Retailer();
  customer.setRetailer(retailer);
  int actual = 0;

  String productId = "101";
  actual = Whitebox. invokeMethod(customer, "getProductPrice",
    productId);

  int expected = 110;
  assertEquals(expected, actual);
 }

 // Partial Mock. Specific method getTaxRate() is mocked
 @Test
 public void testGetPriceForProductPartialMock() throws Exception {
  Customer customer = new Customer();
  Retailer retailer = EasyMock.createMockBuilder(Retailer.class)
    .addMockedMethod("getTaxRate").createMock();
  customer.setRetailer(retailer);
  EasyMock.expect(retailer.getTaxRate()).andReturn(20);
  EasyMock.replay(retailer);
  int actual = 0;

  String productId = "101";
  actual = Whitebox. invokeMethod(customer, "getProductPrice",
    productId);
  int expected = 120;
  assertEquals(expected, actual);
 }

}

You can find the complete source code from here.
Thanks !!

Invoke powershell commands through java

Yes, this is possible ! One can invoke powershell cmdlets from a java program and see the results. Possible solution is to execute the powershell process and run the powershell cmdlets from command line using the java 'Runtime' class. 

One approach is to write powershell scripts and have them executed from the program to see the output. Another way is to provide the command directly as string. This way we can create commands dynamically to execute at run-time as required.

Here is the program-
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ExecuteCommand {

 /**
  * @param args
  * @throws IOException 
  */
 public static void main(String[] args) throws IOException {
  String command = "powershell.exe  $PSVersionTable.PSVersion";
  Process powerShellProcess = Runtime.getRuntime().exec(command);
  powerShellProcess.getOutputStream().close();
  String line;
  System.out.println("Output:");
  BufferedReader stdout = new BufferedReader(new InputStreamReader(
    powerShellProcess.getInputStream()));
  while ((line = stdout.readLine()) != null) {
   System.out.println(line);
  }
  stdout.close();
  System.out.println("Error:");
  BufferedReader stderr = new BufferedReader(new InputStreamReader(
    powerShellProcess.getErrorStream()));
  while ((line = stderr.readLine()) != null) {
   System.out.println(line);
  }
  stderr.close();
  System.out.println("Done");

 }

}

It just finds out the powershell version installed on your machine and displays the result on console.

To execute powershell scripts, we just need to have 
String command = "powershell.exe  \"C:\\PowerShellVersion.ps1\" ";

We need to provide location for the script file to be executed. You can get the source code from here.

Thanks.

Monday, 16 December 2013

Fork / Join Framework : RecursiveTask Example

In my previous post, I had demonstrated the use of RecursiveAction class for the Fork / Join framework. Continuing that here in this post, an example for the RecursiveTask class has been explained. 

Two methods inherited from ForkJoinTask have been used:

1. fork() - It allows a ForkJoinTask to be planned for asynchronous execution. This allows a new ForkJoinTask to be launched from an existing one.

2. join() - It returns the result of the computation when it is done

The task here is to find the sum of all the elements in an array. Let's have a look at this: 


package com.fork.join.task;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class ForkJoinSumTask {

 Random random = new Random();

 public void fillArray(int[] array) {
  for (int i = 0; i < array.length; i++) {
   array[i] = array[i] = random.nextInt(10000);
  }
 }

 public static void main(String[] args) {
  ForkJoinSumTask sum = new ForkJoinSumTask();
  int[] array = new int[20_00_00_000];
  sum.fillArray(array);

  long count;
  long start1;

  // Sequential process to get the sum of the elements in array
  for (int j = 0; j < 20; j++) {
   count = 0;
   start1 = System.currentTimeMillis();
   for (long i = 0; i < (long) array.length; i++) {
    count = (count + array[(int) i]);
   }

   System.out.println("Addition Result: " + count);
   System.out.println("Sequential processing time: "
     + (System.currentTimeMillis() - start1) + " ms");

  }
  System.out.println("Parallel processing time");
  System.out.println("Number of processors available: "
    + Runtime.getRuntime().availableProcessors());

  ForkJoinPool fjpool = new ForkJoinPool(Runtime.getRuntime().availableProcessors());
  // Default parallelism level
  // =
  // Runtime.getRuntime().availableProcessors()
  long start2;

  for (int i = 0; i < 20; i++) {
   RecursiveSumTask task = new RecursiveSumTask(array, 0, array.length);
   start2 = System.currentTimeMillis();
   System.out.println("Addition Result: " + fjpool.invoke(task));
   System.out.println("Parallel processing time: "
     + (System.currentTimeMillis() - start2) + " ms");
  }

  System.out
    .println("Number of steals: " + fjpool.getStealCount() + "\n");
 }
}

class RecursiveSumTask extends RecursiveTask {
 private static final long serialVersionUID = 1L;
 final int low;
 final int high;
 private int[] array;
 final int splitSize = 1000_00_000; // Some threshold size to spit the task

 RecursiveSumTask(int[] array, int from, int to) {
  this.low = from;
  this.high = to;
  this.array = array;
 }

 @Override
 protected Long compute() {
  long count = 0L;
  List> forks = new ArrayList<>();

  if (high - low > splitSize) {
   // task is huge so divide in half
   int mid = (low + high) / 2;

   // Divided the given task into task1 and task2
   RecursiveSumTask task1 = new RecursiveSumTask(array, low, mid);
   forks.add(task1);
   task1.fork();

   RecursiveSumTask task2 = new RecursiveSumTask(array, mid, high);
   forks.add(task2);
   task2.fork();

  } else {
   // Calculating sum of the given array range
   for (int i = (int) low; i < high; i++) {
    count = count + array[i];
   }
  }

  // Waiting for the result
  for (RecursiveTask task : forks) {
   count = count + task.join();
  }

  return count;
 }
}

Note that RecursiveSumTask extends ForkJoinTask in this case. The compute() has a return type unlike ForkJoinAction whose compute() did not have a return type.

During sequential processing, the whole array is scanned sequentially to perform addition of the elements present in it. 

For parallel execution, again a ForkJoinPool is created. Runtime.getRuntime().availableProcessors() will return the number of available processors available with the system. fork() is performed on each recursive task and result of each such task is added using the join() function join() returns the computation result for the task. 

Some threshold value (array size in this case) is used to decide whether the computation is to be performed directly or is to be divided into sub tasks (ForkJoinTasks).


Observations: 


Addition Result: 999844939360

Sequential processing time: 122 ms
Addition Result: 999844939360
Sequential processing time: 126 ms
Addition Result: 999844939360
Sequential processing time: 120 ms
Addition Result: 999844939360
Sequential processing time: 120 ms
Addition Result: 999844939360
Sequential processing time: 120 ms
Addition Result: 999844939360
Sequential processing time: 121 ms
Addition Result: 999844939360
Sequential processing time: 120 ms
Addition Result: 999844939360
Sequential processing time: 119 ms
Addition Result: 999844939360
Sequential processing time: 120 ms
Addition Result: 999844939360
Sequential processing time: 121 ms

Parallel processing 
Number of processors available: 4

Addition Result: 999844939360
Parallel processing time: 42 ms
Addition Result: 999844939360
Parallel processing time: 49 ms
Addition Result: 999844939360
Parallel processing time: 40 ms
Addition Result: 999844939360
Parallel processing time: 38 ms
Addition Result: 999844939360
Parallel processing time: 38 ms
Addition Result: 999844939360
Parallel processing time: 38 ms
Addition Result: 999844939360
Parallel processing time: 39 ms
Addition Result: 999844939360
Parallel processing time: 38 ms
Addition Result: 999844939360
Parallel processing time: 38 ms
Addition Result: 999844939360
Parallel processing time: 38 ms
Number of steals: 30


For parallel processing, the processing time is nearly 1/3 rd of the time required for sequential processing. 

CPU Utilization: 

CPU usage was found to be around 25 % during sequential execution. 

















For parallel processing , CPU usage was on an average around 58 %
















There is a clear increase in the CPU usage for parallel processing. The computation involved in this case was pretty simple (sum of the array elements). Better results can be experienced if the tasks involved are more complex.

The Fork / Join framework is more useful in cases where sequential operations are complex and time consuming. An appropriate threshold in such situations can result in much better CPU utilization. For short tasks, Fork/Join framework is not recommended.

You can also refer my previous blog on Fork/Join Framework for more information

Thanks and Happy Coding !

Java 7 - Fork / Join Framework example

Fork / Join as the name suggests is designed for work that can be broken into smaller pieces recursively. It is a new addition to the JDK 1.7 to support parallelism. It is an implementation of the ExecutorService interface that helps you take advantage of multiple processors.The goal is to use all the available processing power to enhance the performance of your application.

The Fork/Join framework is designed to make divide-and-conquer algorithms easy to parallelize. That type of algorithms is perfect for problems that can be divided into two or more sub-problems of the same type. They use recursion to break down the problem to simple tasks until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a solution to the original problem.


The center of the fork/join framework is the ForkJoinPool class, an extension of the AbstractExecutorService class. ForkJoinPool implements the core work-stealing algorithm and can execute ForkJoinTask processes.It is similar to the MapReduce approach used to paralyze tasks. Difference is that Fork/Join tasks will subdivide themselves into smaller tasks only if necessary (if too large), whereas MapReduce algorithms divide up all the work into portions as the first step of their execution.


Basic Algorithm:


if(the job is small enough)
{
   compute directly
}
else
{
   split the work in two pieces (fork)
   invoke the pieces and join the results (join)
}


A ForkJoinTask is an abstract base class for tasks that run within a ForkJoinPool. A ForkJoinTask is a thread-like entity that is much lighter weight than a normal thread. Huge numbers of tasks and subtasks may be hosted by a small number of actual threads in a ForkJoinPool, at the price of some usage limitations.

There are two specialized subclasses of the ForkJoinTask :

1. RecursiveAction : It is to be used when you don’t need the task to return a result, for example, when the task works on positions of an array, it doesn’t return anything because it worked on the array. The method you should implement in order to do the job is compute():void, notice the void return.

2. RecursiveTask : It is to be used when your tasks return a result. For example, when computing addition of elements in an array, each task must return the number it computed in order to join them and obtain the general solution. The method you should implement in order to do the job is compute():V, where V is the type of return; for example in calculating the sum of integer elements in an array, V may be java.lang.Integer.

In this post, I ll be demonstrating you an example for the RecursiveAction. The task here is to fill the array elements with a random value. Here's the code :

package com.fork.join.action;

import static java.util.Arrays.asList;

import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class ForkJoinRandomFillAction {
 Random random = new Random();

 public void loadArray(int[] array) {
  for (int i = 0; i < array.length; i++) {
   array[i] = random.nextInt(10000); // Generates numbers from 0 to
            // 10000
  }
 }

 public static void main(String[] args) {

  ForkJoinRandomFillAction sort = new ForkJoinRandomFillAction();

  int arrayLength = 2_00_00_0000;
  int array[] = new int[arrayLength];

  // No. of times sequential & Parallel operation should be performed
  final int iterations = 10;

  for (int i = 0; i < iterations; i++) {
   long start = System.currentTimeMillis();
   sort.loadArray(array);

   System.out.println("Sequential processing time: "
     + (System.currentTimeMillis() - start) + " ms");

  }

  System.out.println("Number of processor available: "
    + Runtime.getRuntime().availableProcessors());

  ForkJoinPool fjpool = new ForkJoinPool();
  // Default parallelism level
  // Runtime.getRuntime().availableProcessors()

  for (int i = 0; i < iterations; i++) {
   // Create a task with the complete array
   RecursiveAction task = new RandomFillAction(array, 0, array.length);
   long start = System.currentTimeMillis();
   fjpool.invoke(task);

   System.out.println("Parallel processing time: "
     + (System.currentTimeMillis() - start) + " ms");
  }

  System.out
    .println("Number of steals: " + fjpool.getStealCount() + "\n");
 }
}

class RandomFillAction extends RecursiveAction {
 private static final long serialVersionUID = 1L;
 final int low;
 final int high;
 private int[] array;
 final int splitSize = 2000000; // Some threshold size to spit the task

 public RandomFillAction(int[] array, int low, int high) {
  this.low = low;
  this.high = high;
  this.array = array;
 }

 @Override
 protected void compute() {
  if (high - low > splitSize) {
   // task is huge so divide in half
   int mid = (low + high) / 2;
   invokeAll(asList(new RandomFillAction(array, low, mid),
     new RandomFillAction(array, mid, high)));
  } else {
   // Some calculation logic
   Random random = new Random();
   for (int i = low; i < high; i++) {
    array[i] = random.nextInt(10000);
   }
  }
 }
}

For sequential processing the whole array is filled sequentially with random values. During parallel processing,
we first create a ForkJoinPool which will execute the ForkJoinTask. The default parallelism level for the ForkJoinPool is set to the no. of processors available with the system.Runtime.getRuntime().availableProcessors() will get this value.

Note that the RandomFillAction extends the RecursiveAction class and hence it needs to overwrite the default compute function which has the logic to either split the task or to perform the computation.

Some threshold value (array size in this case) is used to decide whether the computation is to be performed directly or is to be divided into sub tasks (ForkJoinTasks).


Observations:


Sequential processing time: 2316 ms
Sequential processing time: 2287 ms
Sequential processing time: 2287 ms
Sequential processing time: 2293 ms
Sequential processing time: 2287 ms
Sequential processing time: 2295 ms
Sequential processing time: 2292 ms
Sequential processing time: 2291 ms
Sequential processing time: 2291 ms
Sequential processing time: 2292 ms
Number of processor available: 4
Parallel processing time: 705 ms
Parallel processing time: 650 ms
Parallel processing time: 684 ms
Parallel processing time: 602 ms
Parallel processing time: 659 ms
Parallel processing time: 737 ms
Parallel processing time: 605 ms
Parallel processing time: 604 ms
Parallel processing time: 602 ms
Parallel processing time: 628 ms

Number of steals: 63

The paralell processing time is only about 30 % of the sequential processing time.


CPU Utilization

Sequential processing - The total CPU usage remained low close to 25 %, never went above 28 %.





















Parallel processing - CPU usage this time around was very attractive, on an average 96 %, hit 100 % at times and never fell below the 90 % mark. 


















This clearly demonstrates the power of Fork / Join framework and its ability to better utilize the CPU processors. 

In my next post, I will be demonstrating an example for the RecursiveTask class.

Thanks and Happy coding !