Monday, August 31, 2009

Syntax highlighting of blogger entries

When I was first introduced to blogging, I came across hundreds of blogs and after getting motivation from them I started my own blog. But after all this time, the only thing that worried me was that my blog doesn't look as cool and trendy( in looks ) as many other blogs out there. I finally found the answers...
  • Themes and Layouts.
  • Third party Scripts.

Themes and Layouts

Blogger allows you to customize the theme and layout of your blog using a plan ( almost ) html based template. I always wondered, it'd take me light years to come up with my own template. But luckily I don't have to put myself to such a torment after all; I found that there're thousands of templates that are available out there waiting for me to discover. I found this site very useful, it has really cool themes categorized into several categories. Now, I have limitless number of templates to choose from depending on my mood...

Third party Scripts

Since I can edit the template XML to my wish, I also started searching for code syntax highlighter to decorate my code snippets in my blog entries. I used to miss them alot as they certainly make a difference in presenting the code snippets. There's however, an open source solution available, to help us out here. Follow the guidelines in this blog and you'll have your personal code highlighter in no time.

These tools definitely going to help me continue blogging with more ease and elegance.

Monday, June 29, 2009

Experimenting Terracotta

Recently, I've been looking into several caching solutions for our product. After a little research we concluded that we use ehcache for our caching needs. But given the fact that we have a cluster of servers communicating with each others there is also a need for searching a clustering solution as well.

Luckily, Ehcache also supports clustering in its own way using either

  1. RMI
  2. JMS
  3. JGroups
All these methods work on the concept called replication. Ehcache keeps a copy in each of the cache node and replicates each and every mutable cache operation on every node in the cluster. Even though this solves the cluster problem to some extent, its in-efficient in a sense that I have a copy of cache everywhere and I've to figure out how to keep things consistent and at the same time scalable to any sizes of caches.

Alternatives for the approach mentioned above were are also available.. see here.

However, what I was looking for is a true clustered solution where a single copy of cache is made visible to all the nodes in the cluster as a single cache and at the same time I should be able to scale the cache to whichever size I want at runtime.

Terracotta is the answer to this question.

The installation worked like a breeze with absolutely no issues on windows. But I had to download the generic tar.gz file instead of a installer jar file for installing it in solaris.

I've used "The definitive Guide to Terracotta" book as a guide for my quest and I'd recommend everyone to read this book for a better understanding of how terracotta works internally. You can read it online ( a limited version ofcourse ) at google books.

The book has one HelloClusteredWorld example in it which explains the basic working of Terracotta using a simple java program. It works in the strightforward way and so I don't want to mention it here again. I want to show another experiment that I conducted my own using the ehcache integration module ( the ehcache TIM for Terracotta ) .

Following is the sample groovy program that I used for testing this.


import net.sf.ehcache.Element
import java.io.InputStreamReader
import net.sf.ehcache.CacheManager
/**
*
*/

url = getClass().getResource("ehcache-config.xml");
cacheMgr = new CacheManager(url)
def choice = "Y"
cache = cacheMgr.getCache("userCache");
inreader=new InputStreamReader(System.in)

println "Current cache size is : ${cache.getSize()}"

while ( true ){
print " what do you want to do ? "
choice = new InputStreamReader(System.in).readLine()
switch ( choice ){
case "flush":
println "Flushing the cache."
cacheMgr.flush()
break;
case "add":
print "Enter the key element you want to add : "
key = new InputStreamReader(System.in).readLine()
print "Enter the value element you want to add : "
val = new InputStreamReader(System.in).readLine()
cache.put(new Element(key, val))
break;
case "remove":
print "Enter key of the element to remove : "
key = inreader.readLine()
cache.remove(key)
case "rall":
print "Removing everything !"
cache.removeAll()
break;
case "size":
print "Current cache size is ${cache.getSize()}"
break;
default:
println "I don't understand what you're saying ? "
System.exit(0)
}

}
The purpose of this program is simple, It initializes a ehcache using its cache manager and tries to do CRUD operations in it. Without clustering this program works in a strightforward way waiting for user's input to do the corresponding action.

Following is the Ehcache XML to use...


<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">

<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskSpoolBufferSizeMB="30"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"


/>

<cache name="userCache"
maxElementsInMemory="10"
eternal="true"
overflowToDisk="true"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
diskPersistent="false"
memoryStoreEvictionPolicy="LFU">
</cache>

</ehcache>


Now, I tried to convert this program into a cluster-aware program using terracotta. I used following tc-config.xml file.



<?xml version="1.0" encoding="UTF-8"?>
<!--

All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.



-->
<!--
This is a Terracotta configuration file that has been pre-configured
for use with DSO. All classes are included for instrumentation,
and all instrumented methods are write locked.

For more information, please see the product documentation.
-->
<tc:tc-config xmlns:tc="http://www.terracotta.org/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.terracotta.org/schema/terracotta-4.xsd">
<servers>

<!-- Tell DSO where the Terracotta server can be found. -->
<server host="localhost">
<data>%(user.home)/terracotta/server-data</data>
<logs>%(user.home)/terracotta/server-logs</logs>
<dso>
<persistence>
<mode>permanent-store</mode>
</persistence>
</dso>
</server>
</servers>

<!-- Tell DSO where to put the generated client logs -->
<clients>
<logs>%(user.home)/terracotta/client-logs</logs>
<modules>
<module name="tim-ehcache-1.4.1" version="1.3.2"/>
</modules>

</clients>

<application>
<dso>
<roots>

<root>
<field-name>SubscriberCreator.cacheMgr</field-name>
</root>
<root>
<field-name>SubscriberCreator.cache</field-name>
</root>
</roots>
<!-- Start by including just the classes you expect to get added to the shared
graph. These typically include domain classes and shared data structures.
If you miss classes, Terracotta will throw NonPortableOjectExceptions
telling you more about what needs to be added. -->
<instrumented-classes>
<include>
<class-expression>SubscriberCreator</class-expression>
</include>
</instrumented-classes>


</dso>
</application>

</tc:tc-config>


But when I ran this program, i got this error.

Starting Terracotta client...
2009-07-01 12:23:44,758 INFO - Terracotta 3.0.1, as of 20090514-130552 (Revision 12704 by cruise@su1
0mo5 from 3.0)
2009-07-01 12:23:45,476 INFO - Configuration loaded from the file at 'd:\mPortal\Workspace_research\
HelloClusteredWorld\tc-config.xml'.
2009-07-01 12:23:45,711 INFO - Log file: 'C:\Documents and Settings\Admin\terracotta\client-logs\ter
racotta-client.log'.
2009-07-01 12:23:49,320 INFO - Connection successfully established to server at 127.0.0.1:9510
2009-07-01 12:23:49,570 WARN - The root expression 'SubscriberCreator.cacheMgr' meant for the class
'SubscriberCreator' has no effect, make sure that it is a valid expression and that it is spelled co
rrectly.
2009-07-01 12:23:49,570 WARN - The root expression 'SubscriberCreator.cache' meant for the class 'Su
bscriberCreator' has no effect, make sure that it is a valid expression and that it is spelled corre
ctly.
com.tc.exception.TCNonPortableObjectError:
*******************************************************************************
Attempt to share an instance of a non-portable class by assigning it to a root. This unshareable
class is a JVM- or host machine-specific resource. Please ensure that instances of this class
don't enter the shared object graph.

For more information on this issue, please visit our Troubleshooting Guide at:
http://terracotta.org/kit/troubleshooting

Thread : main
JVM ID : VM(22)
Non-portable root name: ALL_CACHE_MANAGERS
Unshareable class : java.util.concurrent.CopyOnWriteArrayList

Action to take:

1) Change your application code
* Ensure that no instances or subclass instances of java.util.concurrent.CopyOnWriteArrayList
are assigned to the DSO root: ALL_CACHE_MANAGERS


*******************************************************************************

at com.tc.object.ClientObjectManagerImpl.throwNonPortableException(ClientObjectManagerImpl.java:786)
at com.tc.object.ClientObjectManagerImpl.checkPortabilityOfRoot(ClientObjectManagerImpl.java:690)
at com.tc.object.ClientObjectManagerImpl.lookupOrCreateRoot(ClientObjectManagerImpl.java:656)
at com.tc.object.ClientObjectManagerImpl.lookupOrCreateRoot(ClientObjectManagerImpl.java:642)
at com.tc.object.bytecode.ManagerImpl.lookupOrCreateRoot(ManagerImpl.java:321)
at com.tc.object.bytecode.ManagerImpl.lookupOrCreateRoot(ManagerImpl.java:300)
at com.tc.object.bytecode.ManagerUtil.lookupOrCreateRoot(ManagerUtil.java:96)
at net.sf.ehcache.CacheManager.__tc_setALL_CACHE_MANAGERS(CacheManager.java)
at net.sf.ehcache.CacheManager.(CacheManager.java:61)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at SubscriberCreator.class$(SubscriberCreator.groovy)
at SubscriberCreator.$get$$class$net$sf$ehcache$CacheManager(SubscriberCreator.groovy)
at SubscriberCreator.run(SubscriberCreator.groovy:9)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1062)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:893)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:744)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:727)
at org.codehaus.groovy.runtime.InvokerHelper.runScript(InvokerHelper.java:383)
at org.codehaus.groovy.runtime.InvokerHelper$runScript.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:129)
at SubscriberCreator.main(SubscriberCreator.groovy)
Exception in thread "main" com.tc.exception.TCNonPortableObjectError:
*******************************************************************************
Attempt to share an instance of a non-portable class by assigning it to a root. This unshareable
class is a JVM- or host machine-specific resource. Please ensure that instances of this class
don't enter the shared object graph.

For more information on this issue, please visit our Troubleshooting Guide at:
http://terracotta.org/kit/troubleshooting

Thread : main
JVM ID : VM(22)
Non-portable root name: ALL_CACHE_MANAGERS
Unshareable class : java.util.concurrent.CopyOnWriteArrayList

Action to take:

1) Change your application code
* Ensure that no instances or subclass instances of java.util.concurrent.CopyOnWriteArrayList
are assigned to the DSO root: ALL_CACHE_MANAGERS


*******************************************************************************

at com.tc.object.ClientObjectManagerImpl.throwNonPortableException(ClientObjectManagerImpl.java:786)
at com.tc.object.ClientObjectManagerImpl.checkPortabilityOfRoot(ClientObjectManagerImpl.java:690)
at com.tc.object.ClientObjectManagerImpl.lookupOrCreateRoot(ClientObjectManagerImpl.java:656)
at com.tc.object.ClientObjectManagerImpl.lookupOrCreateRoot(ClientObjectManagerImpl.java:642)
at com.tc.object.bytecode.ManagerImpl.lookupOrCreateRoot(ManagerImpl.java:321)
at com.tc.object.bytecode.ManagerImpl.lookupOrCreateRoot(ManagerImpl.java:300)
at com.tc.object.bytecode.ManagerUtil.lookupOrCreateRoot(ManagerUtil.java:96)
at net.sf.ehcache.CacheManager.__tc_setALL_CACHE_MANAGERS(CacheManager.java)
at net.sf.ehcache.CacheManager.(CacheManager.java:61)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at SubscriberCreator.class$(SubscriberCreator.groovy)
at SubscriberCreator.$get$$class$net$sf$ehcache$CacheManager(SubscriberCreator.groovy)
at SubscriberCreator.run(SubscriberCreator.groovy:9)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1062)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:893)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:744)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:727)
at org.codehaus.groovy.runtime.InvokerHelper.runScript(InvokerHelper.java:383)
at org.codehaus.groovy.runtime.InvokerHelper$runScript.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:129)
at SubscriberCreator.main(SubscriberCreator.groovy)



Okay, so there're two errors in the trace I pasted above. The first one is kind of a warning message from terracotta that it is unable to identify the member variables I declared in the XML file in the SubscriberCreator class file.

2009-07-01 12:23:49,570 WARN - The root expression 'SubscriberCreator.cacheMgr' meant for the class
'SubscriberCreator' has no effect, make sure that it is a valid expression and that it is spelled correctly.
2009-07-01 12:23:49,570 WARN - The root expression 'SubscriberCreator.cache' meant for the class 'Su
bscriberCreator' has no effect, make sure that it is a valid expression and that it is spelled correctly.

The reason for this error is because the class file I used to launch the terracotta client was generated from a groovy program. When Groovy compiler compiles the groovy file it converts the fields that we declare in the class as properties inside the class. So, whatever member variables that we declare in the groovy file is not in fact a member variable but internally its represented as a key in a HashTable.

Instead of worrying about fixing this, I just converted the groovy program into a java program and this problem has vanished since then. Following is the equivalent java program...


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

public class SubscriberCreator {

private URL url;
private CacheManager cacheMgr;
private Cache cache;


public SubscriberCreator() {
url = getClass().getResource("ehcache-config.xml");
cacheMgr = new CacheManager(url);
cache = cacheMgr.getCache("userCache");
}


public static void main(String[] args) throws IOException {

SubscriberCreator creator = new SubscriberCreator();
System.out.println("Current cache size is : "+creator.cache.getSize());

do {
System.out.println("\nWhat do you want to do ? \n\t 1) Add \n\t 2) remove \n\t 3) flush \n\t 4) clear cache \n\t 5) get \n\t 6) size");
System.out.print("Enter your choice : ");
String choice = new BufferedReader(new InputStreamReader(System.in)).readLine();

if ( choice == null ){
System.out.println (" Bye Bye ");
System.exit(0);
}

int choiceint;
try {
choiceint = Integer.parseInt(choice);
} catch (NumberFormatException e) {
System.out.println("Bye bye ");
break;
}
String key;
String val;
switch (choiceint){
case 1:
System.out.print ("Enter the key element you want to add : ");
key = new BufferedReader(new InputStreamReader(System.in)).readLine();
System.out.print("Enter the value element you want to add : ");
val = new BufferedReader(new InputStreamReader(System.in)).readLine();
creator.cache.put(new Element(key, val));
break;
case 2:
System.out.print ("Enter the key element you want to remove : ");
key = new BufferedReader(new InputStreamReader(System.in)).readLine();
creator.cache.remove(key);
System.out.println("key '"+key+"' removed Successfully !");
break;
case 3:
System.out.println("Flushing the cache now !");
creator.cache.flush();
System.out.println("Flushed the cache successfully ");
break;
case 4:
System.out.println("Clearning the cache !");
creator.cache.removeAll();
System.out.println("Cleared the cache successfully ");
break;
case 5:
System.out.print ("Enter the key element you want to retrieve : ");
key = new BufferedReader(new InputStreamReader(System.in)).readLine();
System.out.println("Element requested is : "+creator.cache.get(key));
break;
case 6:
System.out.println ("Cache size is : "+creator.cache.getSize());
break;
default:
{
System.out.println("I don't understand your request..");
System.exit(0);
}
}
}while ( true );

}

}



Coming to the next half of the problem, it complains about a JDK class called java.util.concurrent.CopyOnWriteArrayList. It appears that terracotta 3.1 or earlier versions of it doesn't have the ability to instrument all the classes in the java.util.concurrent package.

I later realized that from ehcache 1.6 beta3 they have migrated to the JDK concurrent package from the third party concurrent package. So, I had to go down the ehcache release line and re-tried the same example with ehcache 1.5 stable release. It works like a charm !


What did I learnt from this exercise ? Terracotta is a well tested software , but there's definitely a learning curve involved in order to understand what to share/monitor/instrument etc. Without this the whole concept looks unclear and likely to confuse you than do any better.

Here're the minimum requirements for the terracotta 3.1

java version : JDK 1.5 +
ehcache TIM version : 1.4.1 or 1.3 both works fine.
ehcache core version : ehcache 1.5.x ( 1.6 is not yet supported, hope the new version of terracotta fixes these short comings )
Operating systems : Windows XP or higher, Solaris ( I tested only on these machines, I see no reason it doesn't work on other operating systems. )

Sunday, March 16, 2008

3 'fantastic' static code analysis tools for eclipse

Its always a hard task to review one's code to make sure it follows some pre-defined coding standards. The reason its hard is not because its difficult to do, but its because its often boring and repetitive task to do. Adhering to 'Coding standards' while we write a piece of code is undoubtedly a very important responsibility for a programmer. Sometimes its as good as testing our functionality to check if it actually works properly or not.

There're are many advantages that come in as a bonus for writing code as per the 'Coding standards'.
  • Our code looks beautiful and easy to understand
  • Its very easy to introduce new people into the projects as they can understand the code quickly.
  • Its easy to modify the code for further changes.
Writing code as per the coding standards is like 'testing' an application. Both the tasks share the same qualities...
  1. They both have pre-defined set of rules ( test cases ) that we should follow every time we want to perform the task
  2. Both the tasks require execution of a sequence of checks/validations on the piece of code.
Since we always have to execute a sequence of steps and verifications in order to finish the task successfully, this is where automation comes into picture. We have several tools available outside to automate the testing process and similarly we have tools to verify 'coding standards' in our code. These tools are normally termed as 'Static code analysis tools' outside.

In this article i'll discuss about the static source code analysis tools that are available as plug-ins to famous 'Eclipse' IDE.

FindBugs:

Findbugs is a static code analysis tool available for eclipse IDE as a plug-in. We can use this tool against a whole eclipse project or just a simple java program to find out trivial issues like 'Possible null pointer exceptions' etc. This plug-in is available as download from the eclipse update site itself. Its easy to install and it takes no time to test it against any java project.

PMD:

PMD is another plug-in that is available for several IDEs including eclipse. The functionality of PMD is pretty much the same as 'Findbugs' except that when we apply the tool against a project, all the code violations are integrated into the code and will be shown as errors and warnings in the code itself. It'll be very easy to use this tool as we don't need to goto any seperate eclipse 'view' to check the list of errors. They'll be shown directly in the code itself. PMD also allows us to extend or customize the validation functionality as per our requirements. If you want to extend the functionality of a validation you might need to override the API that comes along with this and plug-it into the PMD itself. Most of the times, the default set of validations that come pre-packaged with this plug-in itself would be sufficient to solve most of the commonly occurring problems. You can install the plug-in through its update site here.

Check Style:

Check style plug-in is another static code analysis plug-in available for eclipse. This is so far the most configurable plug-in that I come across lately. It comes pre-packaged with lot of rules with it and still it supports overrides for literally every rule that it defines in its modules. You can optionally include any module you want for running check style in your project. You can also use regular expressions for refining/tuning each rule. You can download this as a standalone program from its site itself. If you want to download it as a plug-in to your eclipse you can find a nice one here.

Conclusion :

Nobody's perfect, each plug-in listed above works very well in very specific situations and hence can't be applied in the generic sense. We can't apply the same rules in all the situation without customizing the tool for our requirement. So, in order to get the best results suggestible to use a combination of these plug-ins in our code.


Wednesday, January 16, 2008

How to Mock an object ?

In today's article, we'll see how to build Mock objects from a normal object and what are the rules that we should follow while creating objects so that they can be mocked.

Mock objects are meant for replacing the actual domain object or an object collaborator with an 'expected' functionality. Basically here are the things we can do with a mock object.
  • We can set expectations about the object's behavior.
  • We can simulate error conditions that might occur in real life situations.
  • We can eliminate the dependency on the domain object so that we don't have
    to worry about setting up a separate environment for testing our small
    piece of code.
With that said, lets also see things we aren't supposed to do with mock object. Mock object's behavior should be restricted to its expectations. The number of objects we mock for testing a given piece of code should not be more than a small value like 2 to 3. If we have to mock too many objects to make our code work then we need to seriously consider re-factoring our code into small pieces so that we can test them using less number of mock objects.

There're again two cases you should consider while writing a mock object they are..
  • Mocking an Interface.
  • Mocking a Class

Mocking an Interface:

Creating a mock object out of a interface is very simple and straight forward. Your mock object can simply implement the interface and behave the way exactly as you expected. Lets look at an example on how to do it with a sample Interface.

Public interface Request
{

public String getParameter(String paramName);

}

Now, lets try to mock this interface

public class MockRequest implements Request
{

String _expectedValue = null;

public void setExpectedResult(String pVal)
{
this._expectedValue = pVal;
}

public String getParameter(String pName)
{
return _expectedValue;
}
}


At the first glance, you will know that my mock object has nothing to do with how the actual implementation of the Request interface gets its values from. It can get it from a simple hashmap or get it using a complex logic like going to DB, we don't care ! All we care about is what is the result that we expect from this object. This is exactly what we're doing by adding a method 'setExpectedResult()'. We just describe what we need from the mock object and nothing more.

Now in our test class we can simply write the code like this ..

public class SomeTest extends TestCase
{
public void testOneMethod()
{

MockRequest req = new MockRequest();
req.setExpectedResult("PURCHASE");

DomainObjectToTest test = new DomainObjectToTest(req);
test.callMethodTotest();

}
}

Lets assume that 'callMethodToTest()' method invokes getParameter() of the request object that is passed as a parameter to the constructor. With the mock object, we have control over what values that our code receives when it eventually calls the 'getParameter()' method on the request object.

Mocking a Class:

Mocking a class is done in pretty much the same manner as interfaces. The mock object is created by extending from the actual domain object instead of implementing an interface. The pattern to wrap a behavior around a given method remains the same as described above.

There're some rules we should follow while creating the actual domain object before we start mocking it.

  • The Domain object should be extensible. It can't be a final class.
  • The Domain object's default constructor should be visible atleast to its sub classes. So, the allowable access modifier to a default constructor is 'protected'.
  • We should not mock the very object we're trying to test in the first place.

The first two points are intuitive but I wanted to stress more on the third point here. You can check my previous article "Testing using Mock Objects using Junit", in the article I have mentioned two methods for abstracting away the singleton invocations from a given class. In one of the methods I've said that we can move the singleton invocations to a separate methods so that we can override them by returning our mock objects instead of actual singletons. This method is clearly not suggestible according to the third point I specified above. I mentioned that approach there because its easy to start off as a beginner, but the ideal way to handle that situation is always by using 'Dependency Ingestion'.

There're many other things that we can achieve and verify using the mock objects, but all those implementations are too tedious to implement manually, so we leave that to mock object generators. Mock object generators are tools to create mock objects out of real time objects, they come particularly handy while mocking interfaces. We'll discuss more about these tools in my coming articles.

Going further we'll also discuss about some famous design principles which could help us write de-coupled code while implementing a functionality. Till then, keep glued to my blog for updates !!



Powered by ScribeFire.

Tuesday, January 15, 2008

Testing using Mock objects using Junit

In today's article,we'll talk about how to test our code using Mock objects using a small example.

Lets assume a class which uses lot of singleton classes for implementing the functionality. Singleton classes if used unwisely can clutter our program with too many static invocations and make our code hard to test. For this reason we should always de-couple these singleton instances to other objects/functions. For Example consider this class...

Public class AuthorizeAdapterImpl
{

LoggerManager _logMgr = null;
DataManager _dataMgr = null;
PlanManager _planMgr = null;

public AuthorizeAdapterImpl()
{ // constructor.
}

public boolean authorizeEverything()
{
_logMgr = LoggerManager.getInstance();
_dataMgr = DataManager.getInstance();
_planMgr = PlanManager.getInstance();

....
....
....
.... // code that extensively uses these variables.

}
}

Now, if you look closely at this class it is directly dependent on three Manager classes. So in order to run/test this class we need to make sure the other Manager classes which it depends on are initialized properly, which is totally unnecessary as we wanted to test logic in only this class.

We can address this in two possible ways..
  • Replace static invocations with simple getXXXInstance methods.
  • Dependency ingestion.
Lets look at the first alternative...

Replace static invocations with simple getXXXInstance methods :

The idea behind this is to move the singleton invocations into a separate private methods so that our function doesn't directly depend on those static methods directly. Look at the code below..

Public class AuthorizeAdapterImpl

{
LoggerManager _logMgr = null;
DataManager _dataMgr = null;
PlanManager _planMgr = null;

public AuthorizeAdapterImpl()

{ // constructor.

}

public boolean authorizeEverything()
{
_logMgr = getLoggerManagerInstance();
_dataMgr = getDataManagerInstance();
_planMgr = getPlanManagerInstance();
....
....
....
.... // code that extensively uses these variables.
}

protected LoggerManager getLoggerManagerInstance()
{
return LoggerManager.getInstance();
}

protected DataManager getDataManagerInstance()
{
return DataManager.getInstance();
}

protected PlanManager getPlanManagerInstance()
{
return PlanManager.getInstance();
}
}

Now, our 'authorizeEverything()' method doesn't depend on any of the singleton classes. This class now becomes testable because we can extend this class and override the getXXXInstance() methods to return our 'Mock' objects instead of actual collaborating objects like DataManager, LoggerManager etc..

public class MockAuthorizeAdapterImpl extends AuthorizeAdapterImpl
{
protected LoggerManager getLoggerManagerInstance()
{
return new MockLoggerManager();
}

protected DataManager getDataManagerInstance()
{
return new MockDataManager();
}

protected PlanManager getPlanManagerInstance()
{
return new MockPlanManager();
}
}

Now that we have replaced the collaborating objects with our mock objects we can use this class for testing the method
'authorizeEverything()'. This works because when we call this method we're actually invoking the method in the super class which is AuthorizeAdapterImpl in this case.

Dependency Ingestion :

Dependency ingestion is a refactoring technique that allows to do the things in a more nicer and efficient way. The basic way how this differs from the above given approach is that instead of abstracting away the singleton invocations into a seperate methods in the same class, we provide the instances of these classes as 'parameters' to this method/class. The choice is again left to the developer but in this case since all the singleton objects are class level variables it makes sense to inject them at the class level instead of passing them to each method.

Public class AuthorizeAdapterImpl
{
LoggerManager _logMgr = null;
DataManager _dataMgr = null;
PlanManager _planMgr = null;

public AuthorizeAdapterImpl(LoggerManager logger, DataManager dMgr , PlanManager pMgr)

{ // constructor.
this._logMgr = logger;
this._dataMgr = dMgr;
this._planMgr = pMgr;
}

public boolean authorizeEverything()
{
//_logMgr = LoggerManager.getInstance(); We don't need this !!
//_dataMgr = DataManager.getInstance();
//_planMgr = PlanManager.getInstance();

....
....
....
.... // code that extensively uses these variables.
}

}

With this change, the code has to be changed all the invocation points where we create the object for AuthorizeAdapterImpl class to send the required objects to this class.

This makes our test class very easy to write..

public class AuthorizeAdapterImplTest
{
public void testAuthorizeEverything()
{
AuthorizeAdapterImpl impl = new AuthorizeAdapterImpl(new MockLogger(), new MockdataMgr(), new MockPlanMgr());
impl.authorizeEverything();
// assertion code to verify our test case.
}
}

There's one disadvantage with this approach...

if our AuthorizeAdapterImpl class has to use a new singleton object, then we've to change the constructor to inject that object too which may not be feasible all the times. What we can do in this case is that we'll move all these singleton objects into a container and pass the reference to the container to this class. Lets call the container DLMSubSystem. The AuthorizeAdapterImpl class becomes like this.

public class AuthorizeAdapterImpl
{

DLMSubSystem _dlmSubSystem = null;

public AuthorizeAdapterImpl(DLMSubSystem subSystem)
{
this._dlmSubSystem = subSystem;
}

public boolean authorizeEverything()
{
LoggerManager logger = _dlmSubSystem.getLogger();
DataManager dataMgr = _dlmSubSystem.getDataManager();
....
...
}
}

Well, i hope you got the basic idea behind how to use refactoring and mock objects for unit testing code. In my next article i'll tell you more about what constitutes a Mock object and how to define behavior of mock object as per our requirement.



Powered by ScribeFire.

Friday, January 11, 2008

Policies and AntiPatterns in Junit

Now that you took the first step towards the automation testing, its time to know the rules and play by them… Today, I’ll try to list down the policies that we should follow and what are the antipatterns available in Junit.

Policies:

1) Write Unit tests only for the code which is visible to other classes. You can just write tests for only the complex methods in a class, but there’s no rule of thumb for determining whether the given method is a complex method to test or not. But we can get a viable answer from the C.R.A.P formula used in Crap4J plug-in.

2) The purpose of the unit test is only to test a particular piece of code, it doesn’t make sense to implement anything more than that in a junit test case so, it should not involve complex logic like connecting to Database or setting up property files etc. You can make use of Mock objects to avoid the situations mentioned above.

3) Your unit testing code should clean you actual functionality with effective refactoring techniques, but in any case you actual code should not be changed just to make work with your Unit testing code. We should always try to make it more testable in nature, but not directly rely up on the unit testing code.

For example : You can not have logic something like this in the core part of our code..

If (isTestingMode)

//do following…

Else

// do following…

4) Mock object should be only used as a substitute of an existing object, it SHOULD NOT contain any application specific code inside it. ( Is this what we’re trying to simulate using this object ? )

For example : Lets say we've an object in the actual code that we use to fetch various property values from a property file. The method you wanted to test is written something like this...

public void methodToTest()
{
// Some application specific code
PropertyManager mgr = PropertyManager.getInstance();
String propertyName = "SomePropertyName";
String propValue = mgr.getPropertyWithName(propertyName);
// manipulating the property value here.
}

For unit testing this method, you don't need to have MyBundle.properties in the classpath, you can pull out the code which reads the property from the property file and instead pass it as an argument like this.

public void methodToTest(PropertyManager propMgr)
{
// Some application specific code
String propertyName = "SomePropertyName";
String propValue =
propMgr.getPropertyWithName(propertyName);
// manipulating the property value here.
}

Now, our code is ready for unit testing and we can mock the Propertymanager by asking it to emulate the call to 'getPropertyWithName(...)' method by returning our required values ( or behavior ). So, our mock object should look like this.

MockPropertyManager extends PropertyManager
{
public String getPropertyWithName(propertyName)
{
if(propertyName == "SomePropertyName") return "correspondingValue";
}
}

At this point, we've removed the dependency of a property file from our code. Now,we can test this code without worrying about setting up the whole environment around it.

I'll elaborate more about using mock objects in my coming articles...

Anti patterns :

Anti patterns are things we shouldn’t do or against the standard while writing any piece of code/work. We’ve antipatterns for Junit as well, and internet is filled with numerous number of articles discussing about these. As you can see, this topic is pretty dynamic in nature and new patterns are kept on adding every day.. ( well, don’t know where exactly they add, but they mention all these new items in blogs and there’re ppl who’d like to archive all these things and keep them at one single place)…

When I started looking for these things, I stumbled across one interesting article which talks especially about “Junit antipatterns”. You can just go through it and you’ll know what I’m talking about.


Friday, November 30, 2007

Remote Desktop access using dynammic IP address

Every one knows that if we've to access our machine remotely from a different location we need to have a static IP address for the system we'd like to connect. But its not always that we get one static address for 'Free' of cost. I've figured out way to achieve the same using dynammic addresses that your ISP assigns to your computer when ever u log in to use internet.

The basic idea behind these softwares is that they try to remove the 'dynammic' nature of your IP address using a client software that you have to install on your system. The client software basically informs their server when ever your IP address changes to a different value and all this happens seamlessly without the user's notice ( all the techies can find out abt this easily by looking at the console, but for ordinary users its of no concern).

I have found two choices for this approach
  • NO-IP.com : This is freely available service, where you can create a account and map your desktop computer to a domain name. After configuring this we can use the XP's built in 'Remote Desktop Connection' utility to access your computer remotely from anywhere in the world.
The major problem with this service is that you need to make sure your ISP is not blocking 'Remote access' port for
accessing your system. You can check that at http://www.canyouseeme.org/
  • LogMeIn : This is another alternative, which is far more superior than the first choice. Using this, you can access your computer from your favorite web browser like Internet explorer or Firefox. Its very easy to install and very easy to configure. But all this convenience comes with a cost ;-) , you can still use the basic remote access after evaluating the pro version of the software.


Powered by ScribeFire.