changeset 225:5abb11559f3b

Bug 3355: [TEST]Add unit test cases Reviewed-by: yasuenag https://github.com/HeapStats/heapstats/pull/90
author KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp>
date Tue, 11 Apr 2017 13:05:30 +0900
parents 1397192f0dc9
children e147f3d6347d
files ChangeLog agent/test/gtest/Makefile agent/test/gtest/src/dummyload-main.cpp agent/test/gtest/src/fsUtil-test.cpp agent/test/gtest/src/heapStatsEnvironment.cpp agent/test/gtest/src/heapStatsEnvironment.hpp agent/test/gtest/src/heapstats-md-test.cpp agent/test/gtest/src/heapstats-test.cpp agent/test/gtest/src/jvmInfo-test.cpp agent/test/gtest/src/jvmSockCmd-test.cpp agent/test/gtest/src/run-libjvm.cpp agent/test/gtest/src/run-libjvm.hpp agent/test/gtest/src/stub/LongSleep.java agent/test/gtest/src/stub/dummyJVMTIEntry.cpp agent/test/gtest/src/symbolFinder-test.cpp agent/test/gtest/src/test-main.cpp agent/test/gtest/testcase.sh
diffstat 17 files changed, 958 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Apr 11 11:12:20 2017 +0900
+++ b/ChangeLog	Tue Apr 11 13:05:30 2017 +0900
@@ -2,6 +2,7 @@
 
 	* Bug 3353: [TEST]Add a test runner for deadlock and thread-recording
 	* Bug 3354: [TEST]Modify test runners for testing in a similar way
+	* Bug 3355: [TEST]Add unit test cases
 
 2017-03-25 KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/Makefile	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,40 @@
+.PHONY: test clean agent
+
+ifndef HEAPSTATS_PATH
+HEAPSTATS_PATH = ../../..
+endif
+
+all: agent
+
+	$(MAKE) -C src/
+
+	if [ ! -d test-bin/stub ]; then \
+		mkdir -p test-bin/stub; \
+	fi
+
+	if [ ! -d test-bin/results ]; then \
+		mkdir test-bin/results; \
+	fi
+
+	cp -f src/heapstats-test src/jvmti-load-test test-bin/
+	cp -f src/stub/*.so test-bin/stub/
+	cp -f src/stub/*.class test-bin/stub/
+
+agent:
+
+	$(MAKE) -C $(HEAPSTATS_PATH)/agent
+
+	if [ ! -d test-bin/heapstats-engines ]; then \
+		mkdir -p test-bin/heapstats-engines; \
+	fi
+
+	cp -f $(HEAPSTATS_PATH)/agent/src/heapstats-engines/libheapstats-*.so \
+	                                    test-bin/heapstats-engines/
+
+test: all
+	./testcase.sh
+
+clean:
+	$(MAKE) -C src clean
+	$(RM) -r heapstats-engines test-bin
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/dummyload-main.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,27 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <gtest/gtest.h>
+
+int main(int argc, char *argv[]){
+  testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/fsUtil-test.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,168 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <gtest/gtest.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <openssl/md5.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <heapstats-engines/globals.hpp>
+#include <heapstats-engines/fsUtil.hpp>
+
+
+#define RESULT_DIR "results"
+#define COPY_SRC "heapstats-test"
+
+
+class FSUtilTest : public testing::Test{
+
+  protected:
+
+    bool GetMD5(const char *fname, unsigned char *md){
+      int fd = open(fname, O_RDONLY);
+      if(fd == -1){
+        return false;
+      }
+
+      struct stat st;
+      fstat(fd, &st);
+      void *data = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+
+      MD5_CTX c;
+
+      MD5_Init(&c);
+      MD5_Update(&c, data, st.st_size);
+      MD5_Final(md, &c);
+
+      munmap(data, st.st_size);
+      close(fd);
+
+      return true;
+    }
+
+};
+
+
+TEST_F(FSUtilTest, copyFile){
+  ASSERT_EQ(copyFile(COPY_SRC, RESULT_DIR), 0);
+
+  unsigned char src_md5[MD5_DIGEST_LENGTH];
+  unsigned char dst_md5[MD5_DIGEST_LENGTH];
+  GetMD5(COPY_SRC, src_md5);
+  ASSERT_TRUE(GetMD5(RESULT_DIR "/" COPY_SRC, dst_md5));
+
+  ASSERT_EQ(0, memcmp(src_md5, dst_md5, MD5_DIGEST_LENGTH));
+}
+
+TEST_F(FSUtilTest, copyFileWithRename){
+  ASSERT_EQ(0, copyFile(COPY_SRC, RESULT_DIR, "renamed_copy"));
+
+  unsigned char src_md5[MD5_DIGEST_LENGTH];
+  unsigned char dst_md5[MD5_DIGEST_LENGTH];
+  GetMD5(COPY_SRC, src_md5);
+  ASSERT_TRUE(GetMD5(RESULT_DIR "/renamed_copy", dst_md5));
+
+  ASSERT_EQ(0, memcmp(src_md5, dst_md5, MD5_DIGEST_LENGTH));
+}
+
+TEST_F(FSUtilTest, tempDir){
+  char *tmp = NULL;
+  ASSERT_EQ(0, createTempDir(&tmp, "heapstats-test-tmp"));
+  ASSERT_FALSE(tmp == NULL);
+
+  struct stat st;
+  ASSERT_EQ(0, stat(tmp, &st));
+
+  ASSERT_TRUE(S_ISDIR(st.st_mode));
+
+  removeTempDir(tmp);
+  errno = 0;
+  stat(tmp, &st);
+  ASSERT_EQ(errno, ENOENT);
+
+  free(tmp);
+}
+
+TEST_F(FSUtilTest, getParentDirectoryPath){
+  char *result;
+
+  result = getParentDirectoryPath("test");
+  ASSERT_STREQ("./", result);
+  free(result);
+
+  result = getParentDirectoryPath("/test");
+  ASSERT_STREQ("/", result);
+  free(result);
+
+  result = getParentDirectoryPath("./test");
+  ASSERT_STREQ(".", result);
+  free(result);
+
+  result = getParentDirectoryPath("./path/to/file");
+  ASSERT_STREQ("./path/to", result);
+  free(result);
+
+  result = getParentDirectoryPath("/path/to/file");
+  ASSERT_STREQ("/path/to", result);
+  free(result);
+
+  result = getParentDirectoryPath("path/to/file");
+  ASSERT_STREQ("path/to", result);
+  free(result);
+}
+
+TEST_F(FSUtilTest, isAccessibleDirectory){
+  const char *dirname = RESULT_DIR "/access_test";
+  mkdir(dirname, S_IRUSR | S_IWUSR);
+
+  ASSERT_EQ(0, isAccessibleDirectory(dirname, true, true));
+  ASSERT_EQ(0, isAccessibleDirectory(dirname, true, false));
+  ASSERT_EQ(0, isAccessibleDirectory(dirname, false, true));
+
+  chmod(dirname, S_IRUSR);
+  ASSERT_NE(0, isAccessibleDirectory(dirname, true, true));
+  ASSERT_EQ(0, isAccessibleDirectory(dirname, true, false));
+  ASSERT_NE(0, isAccessibleDirectory(dirname, false, true));
+
+  chmod(dirname, S_IWUSR);
+  ASSERT_NE(0, isAccessibleDirectory(dirname, true, true));
+  ASSERT_NE(0, isAccessibleDirectory(dirname, true, false));
+  ASSERT_EQ(0, isAccessibleDirectory(dirname, false, true));
+
+  rmdir(dirname);
+}
+
+TEST_F(FSUtilTest, isValidPath){
+  ASSERT_TRUE(isValidPath("./"));
+  ASSERT_TRUE(isValidPath(COPY_SRC));
+  ASSERT_FALSE(isValidPath("./does/not/exist"));
+}
+
+TEST_F(FSUtilTest, checkDiskFull){
+  ASSERT_TRUE(checkDiskFull(ENOSPC, "testcase"));
+  ASSERT_FALSE(checkDiskFull(0, "testcase"));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/heapStatsEnvironment.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,59 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <gtest/gtest.h>
+#include <jni.h>
+
+#include <heapstats-engines/globals.hpp>
+
+#include "heapStatsEnvironment.hpp"
+
+#define CLASSPATH "./stub"
+
+void HeapStatsEnvironment::SetUp(){
+  logger = new TLogger();
+
+  JavaVMInitArgs args;
+  args.version = JNI_VERSION_1_6;
+  JNI_GetDefaultJavaVMInitArgs(&args);
+
+  JavaVMOption opt;
+  opt.optionString = (char *)"-Djava.class.path=" CLASSPATH;
+  args.nOptions = 1;
+  args.options = &opt;
+
+  JavaVM *vm;
+  JNIEnv *env;
+
+  if(JNI_CreateJavaVM(&vm, (void **)&env, &args) != JNI_OK){
+    throw "Could not create JavaVM";
+  }
+
+}
+
+void HeapStatsEnvironment::TearDown(){
+  JavaVM *vm;
+  jsize numVMs;
+
+  if(JNI_GetCreatedJavaVMs(&vm, 1, &numVMs) == JNI_OK){
+    vm->DestroyJavaVM();
+  }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/heapStatsEnvironment.hpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,30 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <gtest/gtest.h>
+
+#include <heapstats-engines/globals.hpp>
+
+class HeapStatsEnvironment : public testing::Environment{
+  public:
+    virtual ~HeapStatsEnvironment(){};
+    virtual void SetUp();
+    virtual void TearDown();
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/heapstats-md-test.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,37 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <dlfcn.h>
+#include <gtest/gtest.h>
+
+#include <heapstats_md.hpp>
+
+class HeapStatsMDTest : public testing::Test {};
+
+TEST_F(HeapStatsMDTest, loadHeapStatsEngine){
+  void *hHandle = loadHeapStatsEngine();
+
+  ASSERT_TRUE(hHandle != NULL);
+
+  if(hHandle != NULL){
+    dlclose(hHandle);
+  }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/heapstats-test.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,41 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <dlfcn.h>
+#include <gtest/gtest.h>
+
+#include <heapstats.hpp>
+
+/* This function will be called from heapstats.cpp . */
+void *loadHeapStatsEngine(){
+  return dlopen("stub/libdummyJVMTI.so", RTLD_LAZY);
+}
+
+TEST(HeapStatsTest, Agent_OnLoad){
+  ASSERT_EQ(Agent_OnLoad(NULL, NULL, NULL), JNI_OK);
+}
+
+TEST(HeapStatsTest, Agent_OnUnload){
+  Agent_OnUnload(NULL);
+}
+
+TEST(HeapStatsTest, Agent_OnAttach){
+  ASSERT_EQ(Agent_OnAttach(NULL, NULL, NULL), JNI_OK);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/jvmInfo-test.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,166 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <jvmti.h>
+#include <gtest/gtest.h>
+
+#include <heapstats-engines/jvmInfo.hpp>
+
+#include "run-libjvm.hpp"
+
+class JvmInfoTest : public RunLibJVMTest{
+  private:
+    static jvmtiEnv *jvmti;
+
+  protected:
+    static TJvmInfo info;
+    static void SetUpTestCase();
+};
+
+jvmtiEnv *JvmInfoTest::jvmti;
+TJvmInfo JvmInfoTest::info;
+
+void JvmInfoTest::SetUpTestCase(){
+  RunLibJVMTest::SetUpTestCase();
+
+  JavaVM *vm;
+  JNIEnv *env;
+  GetJVM(&vm, &env);
+  vm->GetEnv((void **)&jvmti, JVMTI_VERSION_1);
+
+  info.setHSVersion(jvmti);
+  info.detectInfoAddress(env);
+  info.detectDelayInfoAddress();
+
+  vm->DetachCurrentThread();
+}
+
+TEST_F(JvmInfoTest, GetMaxMemory){
+  JavaVM *vm;
+  JNIEnv *env;
+  GetJVM(&vm, &env);
+
+  ASSERT_NE(info.getMaxMemory(), -1);
+
+  vm->DetachCurrentThread();
+}
+
+TEST_F(JvmInfoTest, GetTotalMemory){
+  JavaVM *vm;
+  JNIEnv *env;
+  GetJVM(&vm, &env);
+
+  ASSERT_NE(info.getTotalMemory(), -1);
+
+  vm->DetachCurrentThread();
+}
+
+TEST_F(JvmInfoTest, GetNewAreaSize){
+  ASSERT_NE(info.getNewAreaSize(), -1);
+}
+
+TEST_F(JvmInfoTest, GetOldAreaSize){
+  ASSERT_NE(info.getOldAreaSize(), -1);
+}
+
+TEST_F(JvmInfoTest, GetMetaspaceUsage){
+  ASSERT_NE(info.getMetaspaceUsage(), -1);
+}
+
+TEST_F(JvmInfoTest, GetMetaspaceCapacity){
+  ASSERT_NE(info.getMetaspaceCapacity(), -1);
+}
+
+TEST_F(JvmInfoTest, GetFGCCount){
+  ASSERT_NE(info.getFGCCount(), -1);
+}
+
+TEST_F(JvmInfoTest, GetYGCCount){
+  ASSERT_NE(info.getYGCCount(), -1);
+}
+
+TEST_F(JvmInfoTest, GetGCCause){
+  ASSERT_STRNE(info.getGCCause(), NULL);
+}
+
+TEST_F(JvmInfoTest, GetGCWorktime){
+  info.getGCWorktime();
+}
+
+TEST_F(JvmInfoTest, GetSyncPark){
+  ASSERT_NE(info.getSyncPark(), -1);
+}
+
+TEST_F(JvmInfoTest, GetThreadLive){
+  ASSERT_NE(info.getThreadLive(), -1);
+}
+
+TEST_F(JvmInfoTest, GetSafepointTime){
+  ASSERT_NE(info.getSafepointTime(), -1);
+}
+
+TEST_F(JvmInfoTest, GetSafepoints){
+  ASSERT_NE(info.getSafepoints(), -1);
+}
+
+TEST_F(JvmInfoTest, GetVmVersion){
+  ASSERT_STREQ(info.getVmVersion(), GetSystemProperty("java.vm.version"));
+}
+
+TEST_F(JvmInfoTest, GetVmName){
+  ASSERT_STREQ(info.getVmName(), GetSystemProperty("java.vm.name"));
+}
+
+TEST_F(JvmInfoTest, GetClassPath){
+  ASSERT_STREQ(info.getClassPath(), GetSystemProperty("java.class.path"));
+}
+
+TEST_F(JvmInfoTest, GetEndorsedPath){
+  ASSERT_STREQ(info.getEndorsedPath(), GetSystemProperty("java.endorsed.dirs"));
+}
+
+TEST_F(JvmInfoTest, GetJavaVersion){
+  ASSERT_STREQ(info.getJavaVersion(), GetSystemProperty("java.version"));
+}
+
+TEST_F(JvmInfoTest, GetBootClassPath){
+  ASSERT_STREQ(info.getBootClassPath(),
+               GetSystemProperty("sun.boot.class.path"));
+}
+
+TEST_F(JvmInfoTest, GetVmArgs){
+  ASSERT_STRNE(info.getVmArgs(), NULL);
+}
+
+TEST_F(JvmInfoTest, GetVmFlags){
+  ASSERT_STRNE(info.getVmFlags(), NULL);
+}
+
+TEST_F(JvmInfoTest, GetJavaCommand){
+  ASSERT_STRNE(info.getJavaCommand(), NULL);
+}
+
+TEST_F(JvmInfoTest, GetTickTime){
+  ASSERT_NE(info.getTickTime(), -1);
+}
+
+TEST_F(JvmInfoTest, LoadGCCause){
+  info.loadGCCause();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/jvmSockCmd-test.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,47 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <gtest/gtest.h>
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <heapstats-engines/jvmSockCmd.hpp>
+
+#include "run-libjvm.hpp"
+
+#define RESULT_FILE "results/jvmsockcmd-results.txt"
+
+class JVMSockCmdTest : public RunLibJVMTest{};
+
+TEST_F(JVMSockCmdTest, runAttachListener){
+  char *tmpdir = GetSystemProperty("java.io.tmpdir");
+  TJVMSockCmd jvmCmd(tmpdir);
+  free(tmpdir);
+
+  ASSERT_EQ(jvmCmd.exec("properties", RESULT_FILE), 0);
+
+  struct stat buf;
+  int ret = stat(RESULT_FILE, &buf);
+  ASSERT_EQ(ret, 0);
+  ASSERT_TRUE(S_ISREG(buf.st_mode));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/run-libjvm.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,133 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <pthread.h>
+#include <string.h>
+
+#include <jni.h>
+
+#include "run-libjvm.hpp"
+
+pthread_t RunLibJVMTest::java_driver;
+
+void RunLibJVMTest::GetJVM(JavaVM **vm, JNIEnv **env){
+  jsize numVMs;
+
+  if(JNI_GetCreatedJavaVMs(vm, 1, &numVMs) != JNI_OK){
+    throw "Could not get JavaVMs.";
+  }
+
+  if(numVMs < 1){
+    throw "Could not get JavaVMs.";
+  }
+
+  (*vm)->AttachCurrentThread((void **)env, NULL);
+}
+
+void *RunLibJVMTest::java_driver_main(void *data){
+  JavaVM *vm;
+  JNIEnv *env;
+  GetJVM(&vm, &env);
+
+  jclass LongSleepClass = env->FindClass("LongSleep");
+  if(LongSleepClass == NULL){
+    throw "Could not find LongSleep class.";
+  }
+
+  jmethodID mainMethod = env->GetStaticMethodID(LongSleepClass, "main",
+                                                      "([Ljava/lang/String;)V");
+  if(mainMethod == NULL){
+    throw "Could not find LongSleep#main() .";
+  }
+
+  env->CallStaticVoidMethod(LongSleepClass, mainMethod, NULL);
+
+  vm->DetachCurrentThread();
+  return NULL;
+}
+
+void RunLibJVMTest::SetUpTestCase(){
+  java_driver = 0;
+
+  if(pthread_create(&java_driver, NULL, &java_driver_main, NULL) != 0){
+    throw "Could not create Java driver thread!";
+  }
+
+}
+
+void RunLibJVMTest::TearDownTestCase(){
+  JavaVM *vm;
+  JNIEnv *env;
+  GetJVM(&vm, &env);
+
+  if(java_driver != 0){
+    jclass LongSleepClass = env->FindClass("LongSleep");
+    jfieldID lockObjField = env->GetStaticFieldID(LongSleepClass,
+                                                  "lock", "Ljava/lang/Object;");
+    if(lockObjField == NULL){
+      throw "Could not find LongSleep#lock .";
+    }
+
+    jobject lockObj = env->GetStaticObjectField(
+                                           LongSleepClass, lockObjField);
+    if(lockObj == NULL){
+      throw "Could not find lock object.";
+    }
+
+    jclass objClass = env->FindClass("java/lang/Object");
+    jmethodID notifyMethod = env->GetMethodID(objClass, "notifyAll", "()V");
+
+    env->MonitorEnter(lockObj);
+    env->CallVoidMethod(lockObj, notifyMethod);
+    env->MonitorExit(lockObj);
+
+    if(env->ExceptionOccurred()){
+      env->ExceptionDescribe();
+      env->ExceptionClear();
+    }
+
+    pthread_join(java_driver, NULL);
+  }
+
+  if(vm != NULL){
+    vm->DetachCurrentThread();
+  }
+
+}
+
+char *RunLibJVMTest::GetSystemProperty(const char *key){
+  JavaVM *vm;
+  JNIEnv *env;
+  GetJVM(&vm, &env);
+
+  jstring key_str = env->NewStringUTF(key);
+  jclass sysClass = env->FindClass("Ljava/lang/System;");
+  jmethodID getProperty = env->GetStaticMethodID(sysClass,
+                       "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
+
+  jstring value = (jstring)env->CallStaticObjectMethod(sysClass,
+                                                  getProperty, key_str);
+  const char *ret_utf8 = env->GetStringUTFChars(value, NULL);
+  char *ret = strdup(ret_utf8);
+
+  env->ReleaseStringUTFChars(value, ret_utf8);
+  vm->DetachCurrentThread();
+  return ret;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/run-libjvm.hpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,38 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <pthread.h>
+#include <jni.h>
+
+#include <gtest/gtest.h>
+
+class RunLibJVMTest : public testing::Test{
+  private:
+    static pthread_t java_driver;
+
+  protected:
+    static void GetJVM(JavaVM **vm, JNIEnv **env);
+    static void SetUpTestCase();
+    static void TearDownTestCase();
+
+  public:
+    static void *java_driver_main(void *data);
+    char *GetSystemProperty(const char *key);
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/stub/LongSleep.java	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,44 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+public class LongSleep implements Runnable{
+
+  public static Object lock = new Object();
+
+  public void run(){
+    try{
+      synchronized(lock){
+        lock.notify();
+        lock.wait();
+      }
+    }
+    catch(Exception e){
+      e.printStackTrace();
+    }
+  }
+
+  public static void main(String[] args) throws Exception{
+    synchronized(lock){
+      Thread th = new Thread(new LongSleep());
+      th.start();
+      lock.wait();
+    }
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/stub/dummyJVMTIEntry.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,35 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <jni.h>
+#include <jvmti.h>
+
+JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved){
+  return JNI_OK;
+}
+
+JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm){
+  /* Do nothing */
+}
+
+JNIEXPORT jint JNICALL
+                   Agent_OnAttach(JavaVM *vm, char *options, void *reserved){
+  return JNI_OK;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/symbolFinder-test.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,40 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+#include <dlfcn.h>
+#include <gtest/gtest.h>
+
+#include <heapstats-engines/symbolFinder.hpp>
+
+#define LIBJVM_PATH_PATTERN "/usr/lib/jvm/java-"
+#define LIBJVM_NAME "libjvm.so"
+#define FIND_SYMBOL "JNI_CreateJavaVM"
+
+class SymbolFinderTest : public testing::Test{};
+
+TEST_F(SymbolFinderTest, findSymbol){
+  TSymbolFinder symFinder;
+
+  ASSERT_TRUE(symFinder.loadLibrary(LIBJVM_PATH_PATTERN, LIBJVM_NAME));
+
+  void *fromSymFinder = symFinder.findSymbol(FIND_SYMBOL);
+  void *fromDlsym = dlsym(RTLD_DEFAULT, FIND_SYMBOL);
+
+  ASSERT_TRUE(fromSymFinder == fromDlsym);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/src/test-main.cpp	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,30 @@
+/*!
+ * Copyright (C) 2017 Nippon Telegraph and Telephone Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <gtest/gtest.h>
+
+#include "heapStatsEnvironment.hpp"
+
+int main(int argc, char *argv[]){
+  testing::InitGoogleTest(&argc, argv);
+  testing::AddGlobalTestEnvironment(new HeapStatsEnvironment());
+
+  return RUN_ALL_TESTS();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/test/gtest/testcase.sh	Tue Apr 11 13:05:30 2017 +0900
@@ -0,0 +1,22 @@
+#!/bin/sh
+set -e
+
+pushd $(dirname $0) >/dev/null
+
+if [[ $1 == "--clean" ]]; then
+  make clean
+  exit
+fi
+
+export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${JAVA_HOME:-/usr/lib/jvm/java-openjdk}/jre/lib/amd64/server"
+
+if [[ ! -d test-bin ]]; then
+  make
+fi
+
+pushd test-bin
+./jvmti-load-test
+./heapstats-test
+popd
+
+popd >/dev/null