diff --git a/.travis.yml b/.travis.yml
index 435095e..769b970 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,19 +1,11 @@
+dist: trusty
 language: java
-
 before_install:
   - sudo apt-get -qq update
   - sudo apt-get install -y libblkid-dev
 
-compiler:
-  - gcc
-  - clang
-install:
-- if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi
-addons:
-  apt:
-    sources:
-    - ubuntu-toolchain-r-test
-    packages:
-    - gcc-4.8
-    - g++-4.8
-    - clang
+script:
+  - ./gradlew check
+  - ./gradlew _setup
+  - ./gradlew unpack
+  - ./gradlew pack
diff --git a/README.md b/README.md
index 85b6677..9abba3e 100644
--- a/README.md
+++ b/README.md
@@ -6,3 +6,10 @@ edit boot.img for Nexus Devices
 
 ## [usage]
 TBD
+
+
+## test
+filename: src/test/resources/boot.img
+
+extracted from Nexus 5x(code: bullhead) factory images from [Google](https://dl.google.com/dl/android/aosp/bullhead-mda89e-factory-29247942.tgz)
+
diff --git a/build.gradle b/build.gradle
index 60d8366..b6984e9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,10 +9,6 @@ import java.util.zip.GZIPOutputStream;
 
 def workdir='build/unzip_boot'
 
-task wrapper(type: Wrapper) {
-    gradleVersion = '2.12'
-}
-
 model {
     buildTypes {
         release
@@ -50,7 +46,11 @@ model {
 
 task unpack_bootimg(type: Exec, dependsOn: 'abootimgExecutable') {
     doFirst {
-        new File(workdir + '/root').mkdirs()
+        def rootdir = new File(workdir)
+        if (rootdir.exists()) {
+            rootdir.deleteDir()
+        }
+        rootdir.mkdirs()
     }
     workingDir '.'
     executable 'build/exe/abootimg/abootimg'
@@ -63,6 +63,13 @@ task unpack_ramdisk_gz << {
 unpack_ramdisk_gz.dependsOn(unpack_bootimg)
 
 task unpack_cpio(type: Exec, dependsOn: unpack_ramdisk_gz) {
+    doFirst {
+        def rootdir = new File(workdir+ "/root")
+        if (rootdir.exists()) {
+            rootdir.deleteDir()
+        }
+        rootdir.mkdirs()
+    }
     workingDir workdir + "/root"
     executable 'cpio'
     args = ['-i', '-F', '../ramdisk.img']
@@ -77,9 +84,7 @@ task pack_ramdisk_and_gz { Task task ->
     doLast {
         ByteArrayOutputStream mkbootfs_out = new ByteArrayOutputStream()
         task.project.exec {
-            commandLine = [
-                'build/exe/mkbootfs/mkbootfs', workdir + "/root"
-            ]
+            commandLine = [ 'build/exe/mkbootfs/mkbootfs', workdir + "/root" ]
             standardOutput = mkbootfs_out
         }
         def ByteArrayInputStream gzip_in = new ByteArrayInputStream(mkbootfs_out.buf)
@@ -88,13 +93,20 @@ task pack_ramdisk_and_gz { Task task ->
 }
 pack_ramdisk_and_gz.dependsOn('mkbootfsExecutable')
 
-task pack_clear(type: Exec, dependsOn: [pack_ramdisk_and_gz, 'mkbootimgExecutable']) << {
-    commandLine 'build/exe/mkbootimg/mkbootimg',
+task pack_clear(type: Exec, dependsOn: [pack_ramdisk_and_gz, 'mkbootimgExecutable']) {
+    def theCmdLine = getRamdiskConfig(workdir, 'cmdline')
+    def theBaseAddr = getBaseAddress(workdir)
+    workingDir '.'
+    executable 'build/exe/mkbootimg/mkbootimg'
+    args = [
         '--kernel', workdir + "/kernel",
         '--ramdisk', workdir + "/ramdisk.img.gz",
-        '--cmdline', getRamdiskConfig(workdir, 'cmdline'),
-        '--base', getBaseAddress(workdir),
-        '--output', 'boot.img.clear'
+        '--cmdline', theCmdLine,
+        '--base', theBaseAddr,
+        '--output', 'boot.img.clear']
+}
+if (!new File(workdir + "/bootimg.cfg").exists()) {
+    pack_clear.enabled = false;
 }
 
 void unGnuzipFile(String compressedFile, String decompressedFile) throws IOException {
@@ -154,12 +166,20 @@ void gnuZipFile(String compressedFile, String decompressedFile) throws IOExcepti
 }
 
 String getBaseAddress(String inWorkdir) {
-    Long ret = Long.parseLong(getRamdiskConfig(inWorkdir, "kerneladdr").substring(2), 16) - 0x8000L;
+    Long ret;
+    try {
+        ret = Long.parseLong(getRamdiskConfig(inWorkdir, "kerneladdr").substring(2), 16) - 0x8000L;
+    } catch (NumberFormatException e) {
+        throw new RuntimeException("NumberFormatException: invalid kerneladdr value")
+    }
     return Long.toHexString(ret);
 }
 
 String getRamdiskConfig(String inWorkdir, String inKey) {
     String ret;
+    if (!new File(inWorkdir+ "/bootimg.cfg").exists()) {
+        return "0x0";
+    }
     try {
         Properties prop = new Properties();
         InputStream fis = new FileInputStream(inWorkdir+ "/bootimg.cfg")
@@ -169,16 +189,20 @@ String getRamdiskConfig(String inWorkdir, String inKey) {
             fis.close();
         }
     } catch (IOException e) {
-        e.printStackTrace();
-        throw e;
+        throw new RuntimeException("IOException");
     }
     return ret;
 }
 
-task pack(type: JavaExec, dependsOn: pack_clear) {
+task pack(type: JavaExec, dependsOn: [pack_clear, 'boot_signer:jar']) {
     main = 'com.android.verity.BootSignature'
     classpath = files("boot_signer/build/libs/boot_signer.jar")
     maxHeapSize '512m'
     args '/boot','boot.img.clear', 'security/verity.pk8', 'security/verity.x509.pem', 'boot.img.signed'
 }
-pack.dependsOn('boot_signer:jar')
+
+task _setup(type: Copy) {
+    from 'src/test/resources/boot.img'
+    into '.'
+}
+
diff --git a/src/test/resources/boot.img b/src/test/resources/boot.img
new file mode 100644
index 0000000..1f068f4
Binary files /dev/null and b/src/test/resources/boot.img differ