Files
TheRock/rocm-libraries/projects/miopen/test/gtest/db_paths.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

342 lines
12 KiB
C++

// Copyright © Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
#include <miopen/db_path.hpp>
#include <miopen/binary_cache.hpp>
#include <miopen/filesystem.hpp>
#include <miopen/filesystem_checker.hpp>
#include <miopen/version.h>
#include <miopen/stringutils.hpp>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "gtest_common.hpp"
#include <string>
#include <sstream>
using ::testing::_;
using ::testing::Return;
namespace fs = miopen::fs;
MIOPEN_LIB_ENV_VAR(MIOPEN_USER_DB_PATH)
MIOPEN_LIB_ENV_VAR(MIOPEN_CUSTOM_CACHE_DIR)
// Helper function to build expected version string
std::string GetExpectedVersionString()
{
std::ostringstream oss;
oss << MIOPEN_VERSION_MAJOR << "." << MIOPEN_VERSION_MINOR << "." << MIOPEN_VERSION_PATCH << "."
<< MIOPEN_STRINGIZE(MIOPEN_VERSION_TWEAK);
return oss.str();
}
// Helper function to check if a path contains a substring
bool PathContains(const fs::path& path, const std::string& substring)
{
return path.string().find(substring) != std::string::npos;
}
// Mock filesystem checker for testing
class MockFilesystemChecker : public miopen::IFilesystemChecker
{
public:
MOCK_METHOD(bool, IsNetworkedFilesystem, (const fs::path& path), (const, override));
};
// Test fixture for db_path tests with filesystem mocking
class CPU_DbPaths_NONE : public ::testing::Test
{
protected:
MockFilesystemChecker mock_checker;
void SetUp() override
{
// Reset cached paths to allow fresh initialization with new mock/env settings
miopen::testing::ResetCachedPaths();
miopen::testing::ResetUserDbPath();
// Install the mock checker before any path functions are called
miopen::SetFilesystemChecker(&mock_checker);
}
void TearDown() override
{
// Restore default checker
miopen::SetFilesystemChecker(nullptr);
}
};
// ============================================================================
// Tests for GetUserDbPath() - 4 scenarios
// ============================================================================
TEST_F(CPU_DbPaths_NONE, UserDbPath_LocalFS_NoEnvVar)
{
// Ensure environment variable is NOT set for this test
ScopedEnvironment<std::string> unset_user_db(MIOPEN_USER_DB_PATH, "");
// Scenario 1: Local filesystem, no environment variable set
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(false));
const auto& user_db_path = miopen::GetUserDbPath();
if(user_db_path.empty())
{
GTEST_SKIP() << "User DB is disabled (MIOPEN_DISABLE_USERDB)";
}
// Should use default path containing "miopen"
EXPECT_TRUE(PathContains(user_db_path, "miopen"))
<< "User DB path '" << user_db_path.string() << "' should contain 'miopen' folder";
}
TEST_F(CPU_DbPaths_NONE, UserDbPath_LocalFS_EnvVarSet)
{
// Scenario 2: Local filesystem, environment variable set
const std::string custom_path = "/custom/user/db/path";
ScopedEnvironment<std::string> scoped_env(MIOPEN_USER_DB_PATH, custom_path);
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(false));
const auto& user_db_path = miopen::GetUserDbPath();
if(user_db_path.empty())
{
GTEST_SKIP() << "User DB is disabled (MIOPEN_DISABLE_USERDB)";
}
// Should use the custom path from environment variable
EXPECT_TRUE(PathContains(user_db_path, custom_path))
<< "User DB path '" << user_db_path.string() << "' should contain custom path '"
<< custom_path << "'";
}
TEST_F(CPU_DbPaths_NONE, UserDbPath_NetworkFS_NoEnvVar)
{
#if MIOPEN_BUILD_DEV
GTEST_SKIP() << "Network filesystem detection is disabled in MIOPEN_BUILD_DEV mode";
#else
// Ensure environment variable is NOT set for this test
ScopedEnvironment<std::string> unset_user_db(MIOPEN_USER_DB_PATH, "");
// Scenario 3: Network filesystem, no environment variable set
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(true));
const auto& user_db_path = miopen::GetUserDbPath();
if(user_db_path.empty())
{
GTEST_SKIP() << "User DB is disabled (MIOPEN_DISABLE_USERDB)";
}
// Should fallback to temp directory
const auto temp_dir = fs::temp_directory_path();
EXPECT_TRUE(PathContains(user_db_path, temp_dir.string()))
<< "User DB path '" << user_db_path.string()
<< "' should be in temp directory for network filesystem";
// Should contain .config/miopen
EXPECT_TRUE(PathContains(user_db_path, ".config"))
<< "User DB path should contain '.config' folder";
EXPECT_TRUE(PathContains(user_db_path, "miopen"))
<< "User DB path should contain 'miopen' folder";
#endif
}
TEST_F(CPU_DbPaths_NONE, UserDbPath_NetworkFS_EnvVarSet)
{
// Scenario 4: Network filesystem, environment variable set
// Environment variable should take precedence over network detection
const std::string custom_path = "/custom/network/db/path";
ScopedEnvironment<std::string> scoped_env(MIOPEN_USER_DB_PATH, custom_path);
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(true));
const auto& user_db_path = miopen::GetUserDbPath();
if(user_db_path.empty())
{
GTEST_SKIP() << "User DB is disabled (MIOPEN_DISABLE_USERDB)";
}
// Should use the custom path from environment variable (takes precedence)
EXPECT_TRUE(PathContains(user_db_path, custom_path))
<< "User DB path '" << user_db_path.string()
<< "' should use custom path even on network filesystem";
}
// ============================================================================
// Tests for GetCachePath() - 4 scenarios
// ============================================================================
TEST_F(CPU_DbPaths_NONE, CachePath_LocalFS_NoEnvVar)
{
// Ensure environment variable is NOT set for this test
ScopedEnvironment<std::string> unset_cache(MIOPEN_CUSTOM_CACHE_DIR, "");
// Scenario 1: Local filesystem, no environment variable set
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(false));
const auto cache_path = miopen::GetCachePath(false);
if(cache_path.empty())
{
GTEST_SKIP() << "User cache is disabled (MIOPEN_DISABLE_USERDB)";
}
// Should contain version string
const std::string expected_version = GetExpectedVersionString();
EXPECT_TRUE(PathContains(cache_path, expected_version))
<< "Cache path '" << cache_path.string() << "' should contain version string '"
<< expected_version << "'";
// Should contain "miopen"
EXPECT_TRUE(PathContains(cache_path, "miopen")) << "Cache path should contain 'miopen' folder";
}
TEST_F(CPU_DbPaths_NONE, CachePath_LocalFS_EnvVarSet)
{
// Scenario 2: Local filesystem, environment variable set
const std::string custom_cache = (fs::temp_directory_path() / "custom/cache/dir").string();
ScopedEnvironment<std::string> scoped_env(MIOPEN_CUSTOM_CACHE_DIR, custom_cache);
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(false));
const auto cache_path = miopen::GetCachePath(false);
if(cache_path.empty())
{
GTEST_SKIP() << "User cache is disabled (MIOPEN_DISABLE_USERDB)";
}
// Should use the custom cache directory
EXPECT_TRUE(PathContains(cache_path, custom_cache))
<< "Cache path '" << cache_path.string() << "' should contain custom cache dir '"
<< custom_cache << "'";
}
TEST_F(CPU_DbPaths_NONE, CachePath_NetworkFS_NoEnvVar)
{
#if MIOPEN_BUILD_DEV
GTEST_SKIP() << "Network filesystem detection is disabled in MIOPEN_BUILD_DEV mode";
#else
// Ensure environment variable is NOT set for this test
ScopedEnvironment<std::string> unset_cache(MIOPEN_CUSTOM_CACHE_DIR, "");
// Scenario 3: Network filesystem, no environment variable set
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(true));
const auto cache_path = miopen::GetCachePath(false);
if(cache_path.empty())
{
GTEST_SKIP() << "User cache is disabled (MIOPEN_DISABLE_USERDB)";
}
// Should fallback to temp directory
const auto temp_dir = fs::temp_directory_path();
EXPECT_TRUE(PathContains(cache_path, temp_dir.string()))
<< "Cache path '" << cache_path.string()
<< "' should be in temp directory for network filesystem";
// Should contain .cache/miopen/<version>
EXPECT_TRUE(PathContains(cache_path, ".cache")) << "Cache path should contain '.cache' folder";
EXPECT_TRUE(PathContains(cache_path, "miopen")) << "Cache path should contain 'miopen' folder";
const std::string expected_version = GetExpectedVersionString();
EXPECT_TRUE(PathContains(cache_path, expected_version))
<< "Cache path should contain version string '" << expected_version << "'";
#endif
}
TEST_F(CPU_DbPaths_NONE, CachePath_NetworkFS_EnvVarSet)
{
// Scenario 4: Network filesystem, environment variable set
// Environment variable should take precedence over network detection
const std::string custom_cache = (fs::temp_directory_path() / "custom/network/cache").string();
ScopedEnvironment<std::string> scoped_env(MIOPEN_CUSTOM_CACHE_DIR, custom_cache);
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(true));
const auto cache_path = miopen::GetCachePath(false);
if(cache_path.empty())
{
GTEST_SKIP() << "User cache is disabled (MIOPEN_DISABLE_USERDB)";
}
// Should use the custom cache directory (takes precedence)
EXPECT_TRUE(PathContains(cache_path, custom_cache))
<< "Cache path '" << cache_path.string()
<< "' should use custom cache even on network filesystem";
}
// ============================================================================
// Additional tests
// ============================================================================
TEST_F(CPU_DbPaths_NONE, UserDbSuffix_ContainsVersionInfo)
{
const std::string suffix = miopen::GetUserDbSuffix();
EXPECT_FALSE(suffix.empty()) << "User DB suffix should not be empty";
// Suffix should contain version numbers separated by underscores
std::ostringstream expected_pattern;
expected_pattern << MIOPEN_VERSION_MAJOR << "_" << MIOPEN_VERSION_MINOR << "_"
<< MIOPEN_VERSION_PATCH;
EXPECT_TRUE(suffix.find(expected_pattern.str()) != std::string::npos)
<< "Suffix '" << suffix << "' should contain version pattern '" << expected_pattern.str()
<< "'";
}
TEST_F(CPU_DbPaths_NONE, UserAndSystemCachePaths_AreDifferent)
{
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(false));
const auto user_cache = miopen::GetCachePath(false);
const auto sys_cache = miopen::GetCachePath(true);
if(!user_cache.empty() && !sys_cache.empty())
{
EXPECT_NE(user_cache, sys_cache) << "User and system cache paths should be different";
}
}
TEST_F(CPU_DbPaths_NONE, Paths_AreValid)
{
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(false));
const auto& user_db_path = miopen::GetUserDbPath();
const auto cache_path = miopen::GetCachePath(false);
const auto sys_cache_path = miopen::GetCachePath(true);
// Paths should either be empty (if disabled) or valid filesystem paths
if(!user_db_path.empty())
{
EXPECT_FALSE(user_db_path.string().empty());
}
if(!cache_path.empty())
{
EXPECT_FALSE(cache_path.string().empty());
}
if(!sys_cache_path.empty())
{
EXPECT_FALSE(sys_cache_path.string().empty());
}
}
TEST_F(CPU_DbPaths_NONE, CacheDisabled_ReturnsCorrectly)
{
EXPECT_CALL(mock_checker, IsNetworkedFilesystem(_)).WillRepeatedly(Return(false));
const bool is_disabled = miopen::IsCacheDisabled();
// The result depends on build configuration
// Just verify it returns a valid boolean without crashing
EXPECT_TRUE(is_disabled == true || is_disabled == false);
}