2015年2月25日 星期三

[ In Action ] Everyday Groovy - Unit Test : Getting started

Preface 
The section header implies that you have to do some preparation work before you can start your testing activities. But you don’t. There is no external support to download or install. Groovy treats unit testing as a first-class developer duty and ships with everything you need for that purpose. 

Even more important, it simplifies testing by making assertions part of the language, automatically executing test cases by transparently invoking its TestRunner when needed, and providing the means to run suites of test cases easily, both from the command line and through integration with your IDE or build environment. This section will show you how simple it can be and introduce you to GroovyTestCase , the base class used for most unit testing in Groovy. 

Writing tests is easy 
Assume you have a simple Groovy script that converts temperatures measured in Fahrenheit (F) to Celsius (C). To that end, you define a celsius method like so: 
  1. def celsius(fahrenheit) { (fahrenheit - 32) * 5 / 9 }  
Is this implementation correct? Probably, but you can’t be sure. You need to gain 
additional confidence in this method before the next non-US traveler uses your method to understand the US weather forecast. 

A common approach with unit testing is to call the code under test with static sample data that produces well-known results. That way, you can compare the calculated results against your expectations. 

Choosing a good set of samples is key. As a rule of thumb, having a few typical cases and all the corner cases you can think of is a good choice. 4 Typical cases would be 68° F = 20° C for having a garden party or 95° F = 35° C for going to the beach. Corner cases would be 0° F, which is between -17° C and -18° C, the coldest temperature that Gabriel Daniel Fahrenheit could create with a mixture of ice and ordinary salt in 1714. Another corner case is when water freezes at 32° F = 0° C. 

Sound complicated? It isn’t. Listing 14.1 contains the method together with inline unit tests made with the simple assertions that are built into the language itself. 
- Listing 14.1 Inline unit tests for the Fahrenheit to Celsius conversion method. 
  1. def celsius (fahrenheit) { (fahrenheit - 32) * 5 / 9 }  
  2. assert 20  == celsius(68)  
  3. assert 35  == celsius(95)  
  4. assert -17 == celsius(0).toInteger()  
  5. assert 0   == celsius(32)  
Inline tests of this kind are very useful. Just look at this book: Most listings contain such self-checking asserts to ensure the code works and to help reveal your expectations from the code at the same time. 

Whenever the environment of self-testing code changes, the inline tests assert that it is still working. Environmental changes can happen for a number of reasons: evaluating the script on a different machine, using an updated JDK or Groovy version, or running with different versions of packages that the script depends upon. 

There are circumstances when tests cannot be inlined, such as due to performance requirements. In such cases, it is conventional to pack all the tests of a given script or class into a separate class residing in a separate file. This is where GroovyTestCase appears on stage. 

GroovyTestCase: an introduction 
Groovy bundles an extended JUnit class dubbed GroovyTestCase , which facilitates unit testing in a number of ways. It includes a host of new assert methods, and it also facilitates running Groovy scripts masquerading as test cases. 

The added assertions are listed in table 14.1. We won’t go into the details of each method, mostly because they are descriptively named—where it’s not absolutely obvious what the meaning is, the description provided in the table should be sufficient. Even though we won’t discuss them explicitly, we will use them in the assertions elsewhere in this chapter, so you’ll see how useful they are. 
 

However, Groovy doesn’t force you to extend GroovyTestCase , and you are free to continue to extend the traditional TestCase class provided by JUnit. Having said that, unless you need the functionality of a different subclass of TestCase, there are plenty of reasons to use GroovyTestCase and no reasons to specifically avoid it. Along with the assertions listed in table 14.1, it’s easier to work with GroovyTestCase than TestCase , as you’ll see in the next section. 

Working with GroovyTestCase 
To utilize Groovy’s enhanced TestCase class, extend it as follows: 
  1. class SimpleUnitTest extends GroovyTestCase {  
  2.    void testSimple() {  
  3.      assertEquals("Groovy should add correctly"21 + 1)  
  4.    }  
  5. }  
Remember, you are free to extend any TestCase class you choose, so long as it is in your classpath. For example, you can easily extend JUnit’s TestCase as follows: 
  1. import junit.framework.TestCase  
  2. class AnotherSimpleUnitTest extends TestCase{  
  3.    void testSimpleAgain() {  
  4.      assertEquals("Should subtract correctly too"23 - 1)  
  5.    }  
  6. }  
GroovyTestCase has the added benefit that it also allows test cases to be run via the groovy command, which is not possible for test cases that extend the normal JUnit TestCase class. For example, the SimpleUnitTest script seen earlier, which extends GroovyTestCase , can be run by typing the command groovy SimpleUnitTest
> groovy SimpleUnitTest
.
Time: 0
OK (1 test)

If the output looks familiar to you, that’s probably because it is the standard JUnit output you’d expect to see if you ran a normal Java JUnit test using JUnit’s text-based test runner. Now that you’ve got your feet wet, let’s go back and start again from scratch, this time testing a little more methodically.

[ Java 常見問題 ] How to gracefully handle the SIGKILL signal in Java

Source From Here 
Question 
How do you handle clean up when the program receives a kill signal? 

For instance, there is an application I connect to that wants any third party app (my app) to send a finish command when logging out. What is the best say to send that finish command when my app has been destroyed with a kill -9

How-To 
The way to handle this for anything other than kill -9 would be to register a shutdown hook. If you can use (SIGTERMkill -15 the shutdown hook will work. (SIGINTkill -2 DOES cause the program to gracefully exit and run the shutdown hooks. 

Regarding to registering a new virtual-machine shutdown hook, the Java virtual machine shuts down in response to two kinds of events: 
* The program exits normally, when the last non-daemon thread exits or 
when the exit (equivalently, System.exit) method is invoked, or

* The virtual machine is terminated in response to a user 
interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.

On a kill -15 it DOES run the shutdown hook every time with below sample code: 
  1. package test;  
  2.   
  3. public class TestShutdownHook {  
  4.     public static void main(final String[] args) throws InterruptedException  
  5.     {  
  6.         Runtime.getRuntime().addShutdownHook(new Thread()  
  7.         {  
  8.             @Override  
  9.             public void run()  
  10.             {  
  11.                 System.out.println("Shutdown hook ran!");  
  12.             }  
  13.         });  
  14.   
  15.         while (true)  
  16.         {  
  17.             Thread.sleep(1000);  
  18.         }  
  19.     }  
  20. }  
There are ways to handle your own signals in certain JVMs -- see this article about the HotSpot JVM for example

By using the Sun internal sun.misc.Signal.handle(Signal, SignalHandler) method call you are also able to register a signal handler, but probably not for signals like INT or TERM as they are used by the JVM. To be able to handle any signal you would have to jump out of the JVM and into Operating System territory. 

What I generally do to (for instance) detect abnormal termination is to launch my JVM inside a Perl script, but have the script wait for the JVM using thewaitpid system call. I am then informed whenever the JVM exits, and why it exited, and can take the necessary action. 

Below are sample code to catch signal SIGHUP(1) and SIGABRT(6) by calling Signal.handle(Signal, SignalHandler)
  1. package test;  
  2.   
  3. import sun.misc.Signal;  
  4. import sun.misc.SignalHandler;  
  5.   
  6. public class SignalTest {  
  7.     public static class TestSignalHandler implements SignalHandler  
  8.     {  
  9.         @Override  
  10.         public void handle(Signal sig) {  
  11.             System.out.printf("\t[Info] Handle Signal: %s(%d)\n", sig, sig.getNumber());              
  12.         }         
  13.     }  
  14.       
  15.     public static void main(String args[]) throws Exception  
  16.     {  
  17.         TestSignalHandler handler = new TestSignalHandler();  
  18.         Signal.handle(new Signal("ABRT"), handler);  
  19.         Signal.handle(new Signal("HUP"), handler);  
  20.         while(true)  
  21.         {  
  22.             Thread.sleep(1000);  
  23.         }  
  24.     }  
  25. }  
Supposed you wrap this class into Test.jar. You can run it in Linux machine to test the functionality: 
$ java -jar Test.jar &
[1] 19034
$ kill -6 19034 # Send signal SIGABRT
[Info] Handle Signal: SIGABRT(6)
$ kill -1 19034 # Send signal SIGHUP
[Info] Handle Signal: SIGHUP(1)
$ kill -2 19034 # Stop program
[1]+ Exit 130 java -jar Test.jar

Supplement 
Wiki - Unix Signal 
Signals are a limited form of inter-process communication used in Unix, Unix-like, and other POSIX-compliant operating systems. A signal is an asynchronous notification sent to a process or to a specific thread within the same process in order to notify it of an event that occurred. Signals have been around since the 1970s Bell Labs Unix and have been more recently specified in the POSIX standard.

Java Code Examples for sun.misc.SignalHandler 
Oracle Document - Integrating Signal and Exception Handling

2015年2月24日 星期二

[ GroovyGN ] Turn Methods into Closures

Source From Here
Preface
Groovy supports closures and they are very useful when we create Groovy applications. For example we can pass closures as arguments to methods to execute them. We can create closures ourselves, but we can also convert a method to a closure with the .& operator. And we can use the converted method just like a normal closure. Because Groovy can use Java objects we can also convert a Java method into a closure.

How-To
Let's start with a simple Java class:
  1. public class JavaObject {  
  2. public static void javaSays(final String s) {  
  3.   System.out.println("Java says: Hello " + s + "!");  
  4. }  
  5. }  
With the following script we use this Java class and convert the javaSays method to a closure:
  1. // Simple list with names.  
  2. def names = ['groovy''grails''mrhaki']  
  3.   
  4. // Simple closure.  
  5. names.each { println 'Normal closure says: Hello ' + it + '!' }  
  6.   
  7. // Groovy method to convert to closure.  
  8. def groovySays(s) {  
  9.     printf("Groovy says: Hello ${s}!\n")  
  10. }  
  11. // Use .& syntax to convert method to closure.  
  12. names.each(this.&groovySays)  
  13.   
  14. // Convert Java method to closure and use it.  
  15. def javaSays = JavaObject.&javaSays  
  16. names.each javaSays  
If we run this script we get the following output:
Normal closure says: Hello groovy!
Normal closure says: Hello grails!
Normal closure says: Hello mrhaki!
Groovy says: Hello groovy!
Groovy says: Hello grails!
Groovy says: Hello mrhaki!
Java says: Hello groovy!
Java says: Hello grails!
Java says: Hello mrhaki!

Supplement
[ User Guide ] Closure
[ In Action ] Working with closures - The case for closures
[ In Action ] Working with closures - Declaring closures
The third way of declaring a closure is to reuse something that is already declared: a method. Methods have a body, optionally return values, can take parameters, and can be called. The similarities with closures are obvious, so Groovy lets you reuse the code you already have in methods, but as a closure. Referencing a method as a closure is performed using the reference .& operator...


[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...