# HG changeset patch # User KUBOTA Yuji # Date 1491883530 -32400 # Node ID 5abb11559f3bfcb52c3bbffcde35aaa74e24887a # Parent 1397192f0dc9503e8c2a5cee97b6fc3b71c23cc1 Bug 3355: [TEST]Add unit test cases Reviewed-by: yasuenag https://github.com/HeapStats/heapstats/pull/90 diff -r 1397192f0dc9 -r 5abb11559f3b ChangeLog --- 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 diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/Makefile --- /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 + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/dummyload-main.cpp --- /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 + +int main(int argc, char *argv[]){ + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/fsUtil-test.cpp --- /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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +#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")); +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/heapStatsEnvironment.cpp --- /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 +#include + +#include + +#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(); + } + +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/heapStatsEnvironment.hpp --- /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 + +#include + +class HeapStatsEnvironment : public testing::Environment{ + public: + virtual ~HeapStatsEnvironment(){}; + virtual void SetUp(); + virtual void TearDown(); +}; + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/heapstats-md-test.cpp --- /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 +#include + +#include + +class HeapStatsMDTest : public testing::Test {}; + +TEST_F(HeapStatsMDTest, loadHeapStatsEngine){ + void *hHandle = loadHeapStatsEngine(); + + ASSERT_TRUE(hHandle != NULL); + + if(hHandle != NULL){ + dlclose(hHandle); + } + +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/heapstats-test.cpp --- /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 +#include + +#include + +/* 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); +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/jvmInfo-test.cpp --- /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 +#include + +#include + +#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(); +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/jvmSockCmd-test.cpp --- /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 + +#include +#include +#include +#include + +#include + +#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)); +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/run-libjvm.cpp --- /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 +#include + +#include + +#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; +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/run-libjvm.hpp --- /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 +#include + +#include + +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); +}; + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/stub/LongSleep.java --- /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(); + } + } + +} diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/stub/dummyJVMTIEntry.cpp --- /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 +#include + +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; +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/symbolFinder-test.cpp --- /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 +#include + +#include + +#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); +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/src/test-main.cpp --- /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 + +#include "heapStatsEnvironment.hpp" + +int main(int argc, char *argv[]){ + testing::InitGoogleTest(&argc, argv); + testing::AddGlobalTestEnvironment(new HeapStatsEnvironment()); + + return RUN_ALL_TESTS(); +} + diff -r 1397192f0dc9 -r 5abb11559f3b agent/test/gtest/testcase.sh --- /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