You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/12/15 14:09:49 UTC

[19/50] [abbrv] ignite git commit: IGNITE-7114: C++ node can start without example folder now

IGNITE-7114: C++ node can start without example folder now


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/bb2d59b2
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/bb2d59b2
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/bb2d59b2

Branch: refs/heads/ignite-zk-ce
Commit: bb2d59b238bbf117e1e5bb6fa5e4d0d1af3a6d82
Parents: 316feb8
Author: Igor Sapego <is...@gridgain.com>
Authored: Tue Dec 12 16:19:37 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Tue Dec 12 16:21:27 2017 +0300

----------------------------------------------------------------------
 .../include/ignite/common/platform_utils.h      |  20 ++-
 .../os/linux/src/common/platform_utils.cpp      |  34 +++--
 .../common/os/win/src/common/platform_utils.cpp |  29 +++-
 .../platforms/cpp/core-test/src/test_utils.cpp  |   8 +-
 modules/platforms/cpp/core/src/ignition.cpp     |  10 +-
 .../cpp/jni/include/ignite/jni/utils.h          |  17 +--
 .../platforms/cpp/jni/os/linux/src/utils.cpp    | 120 +++++++++--------
 modules/platforms/cpp/jni/os/win/src/utils.cpp  | 133 +++++++++++--------
 .../platforms/cpp/odbc-test/src/test_utils.cpp  |   8 +-
 9 files changed, 220 insertions(+), 159 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/bb2d59b2/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/common/platform_utils.h b/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
index 8674ce3..b8c6aa6 100644
--- a/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
+++ b/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
@@ -61,10 +61,18 @@ namespace ignite
          * Read system environment variable taking thread-safety in count.
          *
          * @param name Environment variable name.
-         * @param val Environment variable value.
-         * @return True if the environment variable with such name was found.
+         * @return Environment variable value if found and empty string otherwise.
          */
-        IGNITE_IMPORT_EXPORT bool GetEnv(const std::string& name, std::string& val);
+        IGNITE_IMPORT_EXPORT std::string GetEnv(const std::string& name);
+
+        /**
+         * Read system environment variable taking thread-safety in count.
+         *
+         * @param name Environment variable name.
+         * @param dflt Default value to return on fail.
+         * @return Environment variable value if found and @c dflt otherwise.
+         */
+        IGNITE_IMPORT_EXPORT std::string GetEnv(const std::string& name, const std::string& dflt);
 
         /**
          * Ensure that file on the given path exists in the system.
@@ -73,6 +81,12 @@ namespace ignite
          * @return True if file exists, false otherwise.
          */
         IGNITE_IMPORT_EXPORT bool FileExists(const std::string& path);
+
+        /**
+         * Check if the provided path is the valid directory.
+         * @return @c true if the provided path is the valid directory.
+         */
+        IGNITE_IMPORT_EXPORT bool IsValidDirectory(const std::string& path);
     }
 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb2d59b2/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp b/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
index 3e8d0c9..b74f11c 100644
--- a/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
+++ b/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
@@ -20,6 +20,7 @@
 #include <sys/stat.h>
 #include <dirent.h>
 #include <dlfcn.h>
+#include <glob.h>
 
 #include <ignite/common/utils.h>
 
@@ -51,25 +52,42 @@ namespace ignite
             return localtime_r(&in, &out) == 0;
         }
 
-        bool GetEnv(const std::string& name, std::string& val)
+        std::string GetEnv(const std::string& name)
+        {
+            static const std::string empty;
+
+            return GetEnv(name, empty);
+        }
+
+        std::string GetEnv(const std::string& name, const std::string& dflt)
         {
             char* val0 = std::getenv(name.c_str());
 
             if (!val0)
-                return false;
-
-            val = val0;
+                return dflt;
 
-            return true;
+            return std::string(val0);
         }
 
         bool FileExists(const std::string& path)
         {
-            struct stat s;
+            glob_t gs;
+
+            int res = glob(path.c_str(), 0, 0, &gs);
+
+            globfree(&gs);
+
+            return res == 0;
+        }
+
+        bool IsValidDirectory(const std::string& path)
+        {
+            if (path.empty())
+                return false;
 
-            int res = stat(path.c_str(), &s);
+            struct stat pathStat;
 
-            return res != -1;
+            return stat(path.c_str(), &pathStat) != -1 && S_ISDIR(pathStat.st_mode);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb2d59b2/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp b/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
index b8a445c..a0f4505 100644
--- a/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
+++ b/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
@@ -49,18 +49,23 @@ namespace ignite
             return localtime_s(&out, &in) == 0;
         }
 
-        bool GetEnv(const std::string& name, std::string& val)
+        std::string GetEnv(const std::string& name)
         {
-            char res0[32767];
+            static const std::string empty;
 
-            DWORD envRes = GetEnvironmentVariableA(name.c_str(), res0, sizeof(res0) / sizeof(res0[0]));
+            return GetEnv(name, empty);
+        }
 
-            if (envRes == 0)
-                return false;
+        std::string GetEnv(const std::string& name, const std::string& dflt)
+        {
+            char res[32767];
 
-            val.assign(res0);
+            DWORD envRes = GetEnvironmentVariableA(name.c_str(), res, sizeof(res) / sizeof(res[0]));
 
-            return true;
+            if (envRes == 0 || envRes > sizeof(res))
+                return dflt;
+
+            return std::string(res, static_cast<size_t>(envRes));
         }
 
         bool FileExists(const std::string& path)
@@ -76,5 +81,15 @@ namespace ignite
 
             return true;
         }
+
+        bool IsValidDirectory(const std::string& path)
+        {
+            if (path.empty())
+                return false;
+
+            DWORD attrs = GetFileAttributesA(path.c_str());
+
+            return attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb2d59b2/modules/platforms/cpp/core-test/src/test_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/test_utils.cpp b/modules/platforms/cpp/core-test/src/test_utils.cpp
index ded229e..749c581 100644
--- a/modules/platforms/cpp/core-test/src/test_utils.cpp
+++ b/modules/platforms/cpp/core-test/src/test_utils.cpp
@@ -38,12 +38,8 @@ namespace ignite_test
         cfg.jvmOpts.push_back("-DIGNITE_UPDATE_NOTIFIER=false");
         cfg.jvmOpts.push_back("-Duser.language=en");
 
-        std::string home;
-        bool homeFound = jni::ResolveIgniteHome("", home);
-
-        assert(homeFound);
-
-        cfg.jvmClassPath = jni::CreateIgniteHomeClasspath(home, true);
+        cfg.igniteHome = jni::ResolveIgniteHome();
+        cfg.jvmClassPath = jni::CreateIgniteHomeClasspath(cfg.igniteHome, true);
 
 #ifdef IGNITE_TESTS_32
         cfg.jvmInitMem = 256;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb2d59b2/modules/platforms/cpp/core/src/ignition.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/ignition.cpp b/modules/platforms/cpp/core/src/ignition.cpp
index 78ddc54..7d90a52 100644
--- a/modules/platforms/cpp/core/src/ignition.cpp
+++ b/modules/platforms/cpp/core/src/ignition.cpp
@@ -226,16 +226,10 @@ namespace ignite
         }
 
         // 2. Resolve IGNITE_HOME.
-        std::string home;
-        bool homeFound = ResolveIgniteHome(cfg.igniteHome, home);
+        std::string home = ResolveIgniteHome(cfg.igniteHome);
 
         // 3. Create classpath.
-        std::string cp;
-
-        if (homeFound)
-            cp = CreateIgniteClasspath(cfg.jvmClassPath, home);
-        else
-            cp = CreateIgniteClasspath(cfg.jvmClassPath);
+        std::string cp = CreateIgniteClasspath(cfg.jvmClassPath, home);
 
         if (cp.empty())
         {

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb2d59b2/modules/platforms/cpp/jni/include/ignite/jni/utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/include/ignite/jni/utils.h b/modules/platforms/cpp/jni/include/ignite/jni/utils.h
index a6eb37a..285f587 100644
--- a/modules/platforms/cpp/jni/include/ignite/jni/utils.h
+++ b/modules/platforms/cpp/jni/include/ignite/jni/utils.h
@@ -159,14 +159,6 @@ namespace ignite
         IGNITE_IMPORT_EXPORT std::string CreateIgniteHomeClasspath(const std::string& home, bool forceTest);
 
         /**
-         * Create Ignite classpath based on user input directory.
-         *
-         * @param usrCp User's classpath.
-         * @return Classpath.
-         */
-        IGNITE_IMPORT_EXPORT std::string CreateIgniteClasspath(const std::string& usrCp);
-
-        /**
          * Create Ignite classpath based on user input and home directory.
          *
          * @param usrCp User's classpath.
@@ -181,15 +173,14 @@ namespace ignite
          * 1) Check for path provided as argument.
          * 2) Check for environment variable.
          * 3) Check for current working directory.
-         * Result of these 3 checks are evaluated based on existence of certain
-         * predefined folders inside possible GG home. If they are found, 
+         * Result of these checks are evaluated based on existence of certain
+         * predefined folders inside possible Ignite home. If they are found,
          * IGNITE_HOME is considered resolved.
          *
          * @param path Optional path to evaluate.
-         * @param home Resolved GG home.
-         * @return True if IGNITE_HOME home was found.
+         * @return Resolved Ignite home.
          */
-        IGNITE_IMPORT_EXPORT bool ResolveIgniteHome(const std::string& path, std::string& home);
+        IGNITE_IMPORT_EXPORT std::string ResolveIgniteHome(const std::string& path = "");
     }
 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb2d59b2/modules/platforms/cpp/jni/os/linux/src/utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/os/linux/src/utils.cpp b/modules/platforms/cpp/jni/os/linux/src/utils.cpp
index e74e4e0..52e4097 100644
--- a/modules/platforms/cpp/jni/os/linux/src/utils.cpp
+++ b/modules/platforms/cpp/jni/os/linux/src/utils.cpp
@@ -25,6 +25,7 @@
 
 #include "ignite/common/utils.h"
 #include "ignite/common/fixed_size_array.h"
+
 #include "ignite/jni/utils.h"
 #include "ignite/jni/java.h"
 
@@ -40,9 +41,6 @@ namespace ignite
 
         const char* IGNITE_HOME = "IGNITE_HOME";
 
-        const char* PROBE_BIN = "/bin";
-        const char* PROBE_EXAMPLES = "/examples";
-
         const char* IGNITE_NATIVE_TEST_CLASSPATH = "IGNITE_NATIVE_TEST_CLASSPATH";
 
         /** Key indicating that the thread is attached. */
@@ -77,55 +75,66 @@ namespace ignite
         }
 
         /**
-         * Helper function for GG home resolution. Checks whether certain folders
-         * exist in the path. Optionally goes upwards in directory hierarchy.
-         *
-         * @param path Path to evaluate.
-         * @param up Whether to go upwards.
-         * @param res Resolved directory.
-         * @return Resolution result.
+         * Checks if the path looks like binary release home directory.
+         * Internally checks for presence of some directories, that are
+         * @return @c true if the path looks like binary release home directory.
          */
-        bool ResolveIgniteHome0(const std::string& path, bool up, std::string& res)
+        bool LooksLikeBinaryReleaseHome(const std::string& path)
         {
-            struct stat pathStat;
+            static const char* PROBE_CORE_LIB = "/libs/ignite-core*.jar";
 
-            if (stat(path.c_str(), &pathStat) == -1 || !S_ISDIR(pathStat.st_mode))
-                return false;
-            
-            // Remove trailing slashes, otherwise we will have an infinite loop.
-            std::string path0;
+            std::string coreLibProbe = path + PROBE_CORE_LIB;
 
-            size_t last = path.find_last_not_of("/\\ ");
+            return FileExists(coreLibProbe);
+        }
 
-            if (last != std::string::npos)
-                path0.assign(path, 0, last + 1);
+        /**
+         * Checks if the path looks like source release home directory.
+         * Internally checks for presence of core source directory.
+         * @return @c true if the path looks like binary release home directory.
+         */
+        bool LooksLikeSourceReleaseHome(const std::string& path)
+        {
+            static const char* PROBE_CORE_SOURCE = "/modules/core/src/main/java/org/apache/ignite";
 
-            std::string binStr = path0 + PROBE_BIN;
-            struct stat binStat;
+            std::string coreSourcePath = path + PROBE_CORE_SOURCE;
 
-            std::string examplesStr = path0 + PROBE_EXAMPLES;
-            struct stat examplesStat;
+            return IsValidDirectory(coreSourcePath);
+        }
 
-            if (stat(binStr.c_str(), &binStat) != -1 && S_ISDIR(binStat.st_mode) &&
-                stat(examplesStr.c_str(), &examplesStat) != -1 && S_ISDIR(examplesStat.st_mode))
-            {
-                res = path0;
+        /**
+         * Helper function for Ignite home resolution.
+         * Goes upwards in directory hierarchy and checks whether certain
+         * folders exist in the path.
+         *
+         * @param path Path to evaluate.
+         * @return res Resolved directory. Empty string if not found.
+         */
+        std::string ResolveIgniteHome0(const std::string& path)
+        {
+            if (!IsValidDirectory(path))
+                return std::string();
 
-                return true;
-            }
+            // Remove trailing slashes, otherwise we will have an infinite loop.
+            size_t last = path.find_last_not_of("/ ");
+
+            if (last == std::string::npos)
+                return std::string();
+
+            std::string path0(path, 0, last + 1);
 
-            if (!up)
-                return false;
+            if (LooksLikeBinaryReleaseHome(path0) || LooksLikeSourceReleaseHome(path0))
+                return path0;
 
             // Evaluate parent directory.
             size_t slashPos = path0.find_last_of("/");
 
             if (slashPos == std::string::npos)
-                return false;
+                return std::string();
 
             std::string parent(path0, 0, slashPos);
 
-            return ResolveIgniteHome0(parent, true, res);
+            return ResolveIgniteHome0(parent);
         }
 
         /**
@@ -298,9 +307,9 @@ namespace ignite
             if (!path.empty() && FileExists(path))
                 return path;
 
-            std::string javaEnv;
+            std::string javaEnv = GetEnv(JAVA_HOME);
 
-            if (GetEnv(JAVA_HOME, javaEnv))
+            if (!javaEnv.empty())
             {
                 std::string javaDll = javaEnv + JAVA_DLL;
 
@@ -351,7 +360,12 @@ namespace ignite
             return cp;
         }
 
-        std::string CreateIgniteClasspath(const std::string& usrCp)
+        /**
+         * Adds semicolon at the end of the path if needed.
+         * @param usrCp Classpath provided by user.
+         * @return Normalized classpath.
+         */
+        std::string NormalizeClasspath(const std::string& usrCp)
         {
             if (usrCp.empty() || *usrCp.rbegin() == ';')
                 return usrCp;
@@ -362,33 +376,35 @@ namespace ignite
         std::string CreateIgniteClasspath(const std::string& usrCp, const std::string& home)
         {
             // 1. Append user classpath if it exists.
-            std::string cp = CreateIgniteClasspath(usrCp);
+            std::string cp = NormalizeClasspath(usrCp);
 
             // 2. Append home classpath
-            std::string env;
-            bool envFound = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, env);
+            if (!home.empty())
+            {
+                std::string env = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, "false");
 
-            bool forceTest = envFound && env.compare("true") == 0;
+                bool forceTest = ToLower(env) == "true";
 
-            std::string homeCp = CreateIgniteHomeClasspath(home, forceTest);
+                std::string homeCp = CreateIgniteHomeClasspath(home, forceTest);
 
-            cp.append(homeCp);
+                cp.append(homeCp);
+            }
 
             // 3. Return.
             return cp;
         }
 
-        bool ResolveIgniteHome(const std::string& path, std::string& home)
+        std::string ResolveIgniteHome(const std::string& path)
         {
-            if (!path.empty())
-                // 1. Check passed argument.
-                return ResolveIgniteHome0(path, false, home);
+            // 1. Check passed argument.
+            if (IsValidDirectory(path))
+                return path;
 
             // 2. Check environment variable.
-            std::string env;
+            std::string home = GetEnv(IGNITE_HOME);
 
-            if (GetEnv(IGNITE_HOME, env))
-                return ResolveIgniteHome0(env, false, home);
+            if (IsValidDirectory(home))
+                return home;
 
             // 3. Check current work dir.
             FixedSizeArray<char> curDir(1024 * 16);
@@ -396,11 +412,11 @@ namespace ignite
             char* res = getcwd(curDir.GetData(), curDir.GetSize());
 
             if (!res)
-                return false;
+				return std::string();
 
             std::string curDirStr(curDir.GetData());
 
-            return ResolveIgniteHome0(curDirStr, true, home);
+            return ResolveIgniteHome0(curDirStr);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb2d59b2/modules/platforms/cpp/jni/os/win/src/utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/os/win/src/utils.cpp b/modules/platforms/cpp/jni/os/win/src/utils.cpp
index 17ab6c3..4d0c197 100644
--- a/modules/platforms/cpp/jni/os/win/src/utils.cpp
+++ b/modules/platforms/cpp/jni/os/win/src/utils.cpp
@@ -33,6 +33,13 @@ namespace ignite
 {
     namespace jni
     {
+        const char* JAVA_HOME = "JAVA_HOME";
+        const char* JAVA_DLL = "\\jre\\bin\\server\\jvm.dll";
+
+        const char* IGNITE_HOME = "IGNITE_HOME";
+
+        const char* IGNITE_NATIVE_TEST_CLASSPATH = "IGNITE_NATIVE_TEST_CLASSPATH";
+
         AttachHelper::~AttachHelper()
         {
             // No-op.
@@ -43,66 +50,67 @@ namespace ignite
             // No-op.
         }
 
-        const char* JAVA_HOME = "JAVA_HOME";
-        const char* JAVA_DLL = "\\jre\\bin\\server\\jvm.dll";
+        /**
+         * Checks if the path looks like binary release home directory.
+         * Internally checks for presence of core library.
+         * @return @c true if the path looks like binary release home directory.
+         */
+        bool LooksLikeBinaryReleaseHome(const std::string& path)
+        {
+            static const char* PROBE_CORE_LIB = "\\libs\\ignite-core*.jar";
 
-        const char* IGNITE_HOME = "IGNITE_HOME";
+            std::string coreLibProbe = path + PROBE_CORE_LIB;
 
-        const char* PROBE_BIN = "\\bin";
-        const char* PROBE_EXAMPLES = "\\examples";
+            return FileExists(coreLibProbe);
+        }
 
-        const char* IGNITE_NATIVE_TEST_CLASSPATH = "IGNITE_NATIVE_TEST_CLASSPATH";
+        /**
+         * Checks if the path looks like source release home directory.
+         * Internally checks for presence of core source directory.
+         * @return @c true if the path looks like binary release home directory.
+         */
+        bool LooksLikeSourceReleaseHome(const std::string& path)
+        {
+            static const char* PROBE_CORE_SOURCE = "\\modules\\core\\src\\main\\java\\org\\apache\\ignite";
+
+            std::string coreSourcePath = path + PROBE_CORE_SOURCE;
+
+            return IsValidDirectory(coreSourcePath);
+        }
 
         /**
-         * Helper function for GG home resolution. Checks whether certain folders
-         * exist in the path. Optionally goes upwards in directory hierarchy.
+         * Helper function for Ignite home resolution.
+         * Goes upwards in directory hierarchy and checks whether certain
+         * folders exist in the path.
          *
          * @param path Path to evaluate.
-         * @param up Whether to go upwards.
-         * @param res Resolved directory.
-         * @return Resolution result.
+         * @return res Resolved directory. Empty string if not found.
          */
-        bool ResolveIgniteHome0(const std::string& path, bool up, std::string& res)
+        std::string ResolveIgniteHome0(const std::string& path)
         {
-            DWORD attrs = GetFileAttributesA(path.c_str());
-
-            if (attrs == INVALID_FILE_ATTRIBUTES || !(attrs & FILE_ATTRIBUTE_DIRECTORY))
-                return false;
+            if (!IsValidDirectory(path))
+                return std::string();
 
             // Remove trailing slashes, otherwise we will have an infinite loop.
-            std::string path0;
-
             size_t last = path.find_last_not_of("/\\ ");
 
-            if (last != std::string::npos)
-                path0.assign(path, 0, last + 1);
-
-            std::string binStr = path0 + PROBE_BIN;
-            DWORD binAttrs = GetFileAttributesA(binStr.c_str());
-
-            std::string examplesStr = path0 + PROBE_EXAMPLES;
-            DWORD examplesAttrs = GetFileAttributesA(examplesStr.c_str());
+            if (last == std::string::npos)
+                return std::string();
 
-            if (binAttrs != INVALID_FILE_ATTRIBUTES && (binAttrs & FILE_ATTRIBUTE_DIRECTORY) &&
-                examplesAttrs != INVALID_FILE_ATTRIBUTES && (examplesAttrs & FILE_ATTRIBUTE_DIRECTORY))
-            {
-                res = path0;
+            std::string path0(path, 0, last + 1);
 
-                return true;
-            }
-
-            if (!up)
-                return false;
+            if (LooksLikeBinaryReleaseHome(path0) || LooksLikeSourceReleaseHome(path0))
+                return path0;
 
             // Evaluate parent directory.
             size_t slashPos = path0.find_last_of("/\\");
 
             if (slashPos == std::string::npos)
-                return false;
+                return std::string();
 
             std::string parent(path0, 0, slashPos);
 
-            return ResolveIgniteHome0(parent, true, res);
+            return ResolveIgniteHome0(parent);
         }
 
         /**
@@ -271,9 +279,9 @@ namespace ignite
             if (!path.empty() && FileExists(path))
                 return path;
 
-            std::string javaEnv;
+            std::string javaEnv = GetEnv(JAVA_HOME);
 
-            if (GetEnv(JAVA_HOME, javaEnv))
+            if (!javaEnv.empty())
             {
                 std::string javaDll = javaEnv + JAVA_DLL;
 
@@ -324,7 +332,12 @@ namespace ignite
             return cp;
         }
 
-        std::string CreateIgniteClasspath(const std::string& usrCp)
+        /**
+         * Adds semicolon at the end of the path if needed.
+         * @param usrCp Classpath provided by user.
+         * @return Normalized classpath.
+         */
+        std::string NormalizeClasspath(const std::string& usrCp)
         {
             if (usrCp.empty() || *usrCp.rbegin() == ';')
                 return usrCp;
@@ -335,44 +348,52 @@ namespace ignite
         std::string CreateIgniteClasspath(const std::string& usrCp, const std::string& home)
         {
             // 1. Append user classpath if it exists.
-            std::string cp = CreateIgniteClasspath(usrCp);
+            std::string cp = NormalizeClasspath(usrCp);
 
             // 2. Append home classpath
-            std::string env;
-            bool envFound = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, env);
+            if (!home.empty())
+            {
+                std::string env = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, "false");
 
-            bool forceTest = envFound && env.compare("true") == 0;
+                bool forceTest = ToLower(env) == "true";
 
-            std::string homeCp = CreateIgniteHomeClasspath(home, forceTest);
+                std::string homeCp = CreateIgniteHomeClasspath(home, forceTest);
 
-            cp.append(homeCp);
+                cp.append(homeCp);
+            }
 
             // 3. Return.
             return cp;
         }
 
-        bool ResolveIgniteHome(const std::string& path, std::string& home)
+        std::string ResolveIgniteHome(const std::string& path)
         {
-            if (!path.empty())
-                // 1. Check passed argument.
-                return ResolveIgniteHome0(path, false, home);
+            // 1. Check passed argument.
+            if (IsValidDirectory(path))
+                return path;
 
             // 2. Check environment variable.
-            std::string env;
+            std::string home = GetEnv(IGNITE_HOME);
 
-            if (GetEnv(IGNITE_HOME, env))
-                return ResolveIgniteHome0(env, false, home);
+            if (IsValidDirectory(home))
+                return home;
 
             // 3. Check current work dir.
-            const DWORD curDirLen = GetCurrentDirectory(0, NULL);
+            DWORD curDirLen = GetCurrentDirectoryA(0, NULL);
+
+            if (!curDirLen)
+                return std::string();
 
             FixedSizeArray<char> curDir(curDirLen);
 
-            GetCurrentDirectoryA(curDir.GetSize(), curDir.GetData());
+            curDirLen = GetCurrentDirectoryA(curDir.GetSize(), curDir.GetData());
+
+            if (!curDirLen)
+                return std::string();
 
             std::string curDirStr(curDir.GetData());
 
-            return ResolveIgniteHome0(curDirStr, true, home);
+            return ResolveIgniteHome0(curDirStr);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb2d59b2/modules/platforms/cpp/odbc-test/src/test_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/test_utils.cpp b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
index 6e8fe6a..3e1a9d7 100644
--- a/modules/platforms/cpp/odbc-test/src/test_utils.cpp
+++ b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
@@ -65,12 +65,8 @@ namespace ignite_test
         cfg.jvmOpts.push_back("-DIGNITE_UPDATE_NOTIFIER=false");
         cfg.jvmOpts.push_back("-Duser.language=en");
 
-        std::string home;
-        bool homeFound = jni::ResolveIgniteHome("", home);
-
-        assert(homeFound);
-
-        cfg.jvmClassPath = jni::CreateIgniteHomeClasspath(home, true);
+        cfg.igniteHome = jni::ResolveIgniteHome();
+        cfg.jvmClassPath = jni::CreateIgniteHomeClasspath(cfg.igniteHome, true);
 
 #ifdef IGNITE_TESTS_32
         cfg.jvmInitMem = 256;