From 651c1f142d6a0885fae11d7dca26b76ad59fd198 Mon Sep 17 00:00:00 2001 From: Andrei Dabija Date: Sat, 12 Oct 2024 04:46:40 +0300 Subject: [PATCH 1/5] fix GAHealth Tests --- source/gameanalytics/GAHealth.cpp | 13 +- test/GAHealth_test.cpp | 272 +++++++++++++----------------- 2 files changed, 125 insertions(+), 160 deletions(-) diff --git a/source/gameanalytics/GAHealth.cpp b/source/gameanalytics/GAHealth.cpp index b3cdbb8e..6edab39e 100644 --- a/source/gameanalytics/GAHealth.cpp +++ b/source/gameanalytics/GAHealth.cpp @@ -32,14 +32,13 @@ namespace gameanalytics int GAHealth::getMemoryPercent(int64_t memory) { - if((memory > 0) && (_totalMemory > 0)) - { - int memoryPercent = std::round(static_cast(memory) / static_cast(_totalMemory) * 100.0); - return std::min(memoryPercent, 100); - } - - return 0; + if((memory > 0) && (_totalMemory > 0)) + { + int memoryPercent = std::round(static_cast(memory) / static_cast(_totalMemory) * 100.0); + return memoryPercent; + } + return -1; } void GAHealth::doAppMemoryReading(int64_t memory) diff --git a/test/GAHealth_test.cpp b/test/GAHealth_test.cpp index 43807dd5..d0d4a026 100644 --- a/test/GAHealth_test.cpp +++ b/test/GAHealth_test.cpp @@ -3,207 +3,173 @@ #include #include +using json = nlohmann::json; using namespace gameanalytics; -using ::testing::Return; -namespace gameanalytics -{ - class MockGAPlatform : public GAPlatform - { - public: - MOCK_METHOD(std::string, getOSVersion, (), (override)); - MOCK_METHOD(std::string, getDeviceManufacturer, (), (override)); - MOCK_METHOD(std::string, getBuildPlatform, (), (override)); - MOCK_METHOD(std::string, getPersistentPath, (), (override)); - MOCK_METHOD(std::string, getDeviceModel, (), (override)); - MOCK_METHOD(std::string, getConnectionType, (), (override)); - - // Mocking non-pure virtual methods - MOCK_METHOD(std::string, getAdvertisingId, (), (override)); - MOCK_METHOD(std::string, getDeviceId, (), (override)); - MOCK_METHOD(void, setupUncaughtExceptionHandler, (), (override)); - MOCK_METHOD(void, onInit, (), (override)); - - // Mocking const methods - MOCK_METHOD(std::string, getCpuModel, (), (const, override)); - MOCK_METHOD(std::string, getGpuModel, (), (const, override)); - MOCK_METHOD(int, getNumCpuCores, (), (const, override)); - MOCK_METHOD(int64_t, getTotalDeviceMemory, (), (const, override)); - MOCK_METHOD(int64_t, getAppMemoryUsage, (), (const, override)); - MOCK_METHOD(int64_t, getSysMemoryUsage, (), (const, override)); - MOCK_METHOD(int64_t, getBootTime, (), (const, override)); - - MockGAPlatform() - { - ON_CALL(*this, getOSVersion).WillByDefault(Return("10.0")); - ON_CALL(*this, getDeviceManufacturer).WillByDefault(Return("GenericManufacturer")); - ON_CALL(*this, getBuildPlatform).WillByDefault(Return("Windows")); - ON_CALL(*this, getPersistentPath).WillByDefault(Return("/persistent/path")); - ON_CALL(*this, getDeviceModel).WillByDefault(Return("DeviceModelX")); - ON_CALL(*this, getConnectionType).WillByDefault(Return("WiFi")); - - ON_CALL(*this, getAdvertisingId).WillByDefault(Return("ad-id-123")); - ON_CALL(*this, getDeviceId).WillByDefault(Return("device-id-456")); - ON_CALL(*this, setupUncaughtExceptionHandler).WillByDefault(Return()); - ON_CALL(*this, onInit).WillByDefault(Return()); - - ON_CALL(*this, getCpuModel).WillByDefault(Return("Intel Core i7")); - ON_CALL(*this, getGpuModel).WillByDefault(Return("Nvidia GTX 1080")); - ON_CALL(*this, getNumCpuCores).WillByDefault(Return(8)); - ON_CALL(*this, getTotalDeviceMemory).WillByDefault(Return(16384)); // 16GB - ON_CALL(*this, getAppMemoryUsage).WillByDefault(Return(1024)); // 1GB - ON_CALL(*this, getSysMemoryUsage).WillByDefault(Return(2048)); // 2GB - ON_CALL(*this, getBootTime).WillByDefault(Return(30000)); // 30 seconds - } - }; -} +class MockGAPlatform : public GAPlatform +{ +public: + // Mock the pure virtual methods + MOCK_METHOD(std::string, getOSVersion, (), (override)); + MOCK_METHOD(std::string, getDeviceManufacturer, (), (override)); + MOCK_METHOD(std::string, getBuildPlatform, (), (override)); + MOCK_METHOD(std::string, getPersistentPath, (), (override)); + MOCK_METHOD(std::string, getDeviceModel, (), (override)); + MOCK_METHOD(std::string, getConnectionType, (), (override)); + + MOCK_METHOD(std::string, getAdvertisingId, (), (override)); + MOCK_METHOD(std::string, getDeviceId, (), (override)); + MOCK_METHOD(void, setupUncaughtExceptionHandler, (), (override)); + MOCK_METHOD(void, onInit, (), (override)); + + MOCK_METHOD(std::string, getCpuModel, (), (const, override)); + MOCK_METHOD(std::string, getGpuModel, (), (const, override)); + MOCK_METHOD(int, getNumCpuCores, (), (const, override)); + MOCK_METHOD(int64_t, getTotalDeviceMemory, (), (const, override)); + MOCK_METHOD(int64_t, getAppMemoryUsage, (), (const, override)); + MOCK_METHOD(int64_t, getSysMemoryUsage, (), (const, override)); + MOCK_METHOD(int64_t, getBootTime, (), (const, override)); +}; // Test subclass to access protected members -class GAHealthTestable : public gameanalytics::GAHealth +class TestableGAHealth : public GAHealth { public: - using gameanalytics::GAHealth::GAHealth; // Inherit constructor - using gameanalytics::GAHealth::_fpsReadings; // Expose protected member for testing - using gameanalytics::GAHealth::_appMemoryUsage; // Expose protected memory usage for testing - using gameanalytics::GAHealth::_sysMemoryUsage; // Expose system memory usage for testing - using gameanalytics::GAHealth::getMemoryPercent; + using GAHealth::GAHealth; + + // Expose protected members for testing + using gameanalytics::GAHealth::_cpuModel; + using gameanalytics::GAHealth::_numCores; + using gameanalytics::GAHealth::_hardware; + using gameanalytics::GAHealth::_gpuModel; + using gameanalytics::GAHealth::_fpsReadings; + using gameanalytics::GAHealth::_appMemoryUsage; + using gameanalytics::GAHealth::_sysMemoryUsage; using gameanalytics::GAHealth::_totalMemory; + + // Expose protected methods for testing + using gameanalytics::GAHealth::getMemoryPercent; }; class GAHealthTest : public ::testing::Test { protected: - MockGAPlatform* mockPlatform; - GAHealthTestable* gaHealth; - - virtual void SetUp() override + void SetUp() override { - mockPlatform = new MockGAPlatform(); - gaHealth = new GAHealthTestable(mockPlatform); + platform = new MockGAPlatform(); + EXPECT_CALL(*platform, getCpuModel()).WillOnce(::testing::Return("Mock CPU")); + EXPECT_CALL(*platform, getNumCpuCores()).WillOnce(::testing::Return(8)); + EXPECT_CALL(*platform, getDeviceModel()).WillOnce(::testing::Return("Mock Device")); + EXPECT_CALL(*platform, getGpuModel()).WillOnce(::testing::Return("Mock GPU")); + EXPECT_CALL(*platform, getTotalDeviceMemory()).WillOnce(::testing::Return(16000)); + + health = new TestableGAHealth(platform); } - virtual void TearDown() override + void TearDown() override { - delete gaHealth; - delete mockPlatform; + delete health; + delete platform; } + + TestableGAHealth* health; + MockGAPlatform* platform; }; -TEST_F(GAHealthTest, ConstructorInitializesPlatform) +// Test 1: Constructor Initialization +TEST_F(GAHealthTest, ConstructorInitializesPlatformValues) { - EXPECT_CALL(*mockPlatform, getCpuModel()).WillOnce(Return("Intel")); - EXPECT_CALL(*mockPlatform, getNumCpuCores()).WillOnce(Return(4)); - EXPECT_CALL(*mockPlatform, getDeviceModel()).WillOnce(Return("Device123")); - EXPECT_CALL(*mockPlatform, getGpuModel()).WillOnce(Return("Nvidia")); - EXPECT_CALL(*mockPlatform, getTotalDeviceMemory()).WillOnce(Return(8192)); - - gameanalytics::GAHealth health(mockPlatform); - health.enableHardwareTracking = true; - - json out; - health.addHealthAnnotations(out); - - std::cout << std::setw(4) << out << '\n'; - - EXPECT_EQ(out["cpu_model"], "Intel"); - EXPECT_EQ(out["cpu_num_cores"], 4); - EXPECT_EQ(out["hardware"], "Device123"); + EXPECT_EQ(health->_cpuModel, "Mock CPU"); + EXPECT_EQ(health->_numCores, 8); + EXPECT_EQ(health->_hardware, "Mock Device"); + EXPECT_EQ(health->_gpuModel, "Mock GPU"); + EXPECT_EQ(health->_totalMemory, 16000); } -TEST_F(GAHealthTest, AddHealthAnnotationsIncludesHardwareTracking) +// Test 2: doFpsReading Method +TEST_F(GAHealthTest, DoFpsReadingAddsToBucket) { - EXPECT_CALL(*mockPlatform, getCpuModel()).WillOnce(Return("Intel")); - EXPECT_CALL(*mockPlatform, getNumCpuCores()).WillOnce(Return(4)); - EXPECT_CALL(*mockPlatform, getDeviceModel()).WillOnce(Return("Device123")); + health->doFpsReading(30.0f); + health->doFpsReading(30.4f); - GAHealthTestable* _localHealthTracker = new GAHealthTestable(mockPlatform); - - _localHealthTracker->enableHardwareTracking = true; - - json healthEvent; - _localHealthTracker->addHealthAnnotations(healthEvent); - - std::cout << std::setw(4) << healthEvent["cpu_model"] << '\n'; - - EXPECT_EQ(healthEvent["cpu_model"], "Intel"); - EXPECT_EQ(healthEvent["cpu_num_cores"], 4); - EXPECT_EQ(healthEvent["hardware"], "Device123"); + EXPECT_EQ(health->_fpsReadings[30], 2); } -TEST_F(GAHealthTest, DoFpsReadingIncrementsBucketCorrectly) +// Test 3: doAppMemoryReading Method +TEST_F(GAHealthTest, DoAppMemoryReadingIncrementsAppMemoryUsage) { - float testFps = 60.0f; + health->doAppMemoryReading(4000); + int memoryPercent = health->getMemoryPercent(4000); - gaHealth->doFpsReading(testFps); - - EXPECT_EQ(gaHealth->_fpsReadings[60], 1); + EXPECT_EQ(health->_appMemoryUsage[memoryPercent], 1); } -TEST_F(GAHealthTest, GetMemoryPercentReturnsCorrectValue) +// Test 4: addHealthAnnotations Method +TEST_F(GAHealthTest, AddHealthAnnotations) { - int percent = gaHealth->getMemoryPercent(4096); - EXPECT_EQ(percent, 25); // 25% memory usage + json healthEvent; + + health->enableHardwareTracking = true; + health->enableMemoryTracking = true; + + health->addHealthAnnotations(healthEvent); + + EXPECT_EQ(healthEvent["cpu_model"], "Mock CPU"); + EXPECT_EQ(healthEvent["hardware"], "Mock Device"); + EXPECT_EQ(healthEvent["cpu_num_cores"], 8); + EXPECT_EQ(healthEvent["memory_sys_total"], 16000); } -// Test getMemoryPercent with various inputs -TEST_F(GAHealthTest, GetMemoryPercentReturnsCorrectValues) +// Test 5: getMemoryPercent Method +TEST_F(GAHealthTest, GetMemoryPercentCorrectValue) { - // Case 1: 50% memory usage - int64_t totalMemory = 1000; - gaHealth->_totalMemory = totalMemory; - int memory = 500; - int expectedPercent = 50; - EXPECT_EQ(gaHealth->getMemoryPercent(memory), expectedPercent); - - // Case 2: 100% memory usage - memory = 1000; - expectedPercent = 100; - EXPECT_EQ(gaHealth->getMemoryPercent(memory), expectedPercent); - - // Case 3: 0% memory usage - memory = 1; - expectedPercent = 0; - EXPECT_EQ(gaHealth->getMemoryPercent(memory), expectedPercent); - - // Case 4: More than 100% memory usage (should not happen, but edge case) - memory = 2000; - expectedPercent = 100; // Assuming 100% cap - EXPECT_EQ(gaHealth->getMemoryPercent(memory), expectedPercent); - - // Case 5: Negative memory value (should return 0 or handle gracefully) - memory = -100; - expectedPercent = 0; // Assuming a negative value will result in 0% - EXPECT_EQ(gaHealth->getMemoryPercent(memory), expectedPercent); + EXPECT_EQ(health->getMemoryPercent(8000), 50); // Half of 16000 + EXPECT_EQ(health->getMemoryPercent(16000), 100); // Full memory + + EXPECT_EQ(health->getMemoryPercent(1), 0); // Very small usage } -TEST_F(GAHealthTest, AddPerformanceDataIncludesFPSTracking) -{ - gaHealth->enableFPSTracking = true; +// Test group for edge cases +TEST_F(GAHealthTest, GetMemoryPercentEdgeCases) { + // Test when memory is exactly 0 + EXPECT_EQ(health->getMemoryPercent(0), -1); - // Fill FPS readings with some values - gaHealth->_fpsReadings[60] = 5; - gaHealth->_fpsReadings[30] = 2; + // Test negative memory values + EXPECT_EQ(health->getMemoryPercent(-1), -1); + EXPECT_EQ(health->getMemoryPercent(-500), -1); - json performanceData; - gaHealth->addPerformanceData(performanceData); +} + +// Test 6: addPerformanceData Method +TEST_F(GAHealthTest, AddPerformanceData) +{ + health->enableFPSTracking = true; + health->enableMemoryTracking = true; + health->doFpsReading(30); + health->doAppMemoryReading(4000); + health->doSysMemoryReading(8000); - json expectedFpsData; - expectedFpsData["fps_data_table"] = gaHealth->_fpsReadings; + json healthEvent; + health->addPerformanceData(healthEvent); - EXPECT_EQ(performanceData["fps_data_table"], expectedFpsData["fps_data_table"]); + EXPECT_EQ(healthEvent["fps_data_table"][30], 1); + EXPECT_EQ(healthEvent["memory_sys_data_table"][50], 1); // 8000 out of 16000 + EXPECT_EQ(healthEvent["memory_app_data_table"][25], 1); // 4000 out of 16000 } -TEST_F(GAHealthTest, AddSDKInitDataIncludesBootTime) +// Test 7: addSDKInitData Method +TEST_F(GAHealthTest, AddSDKInitData) { - gaHealth->enableAppBootTimeTracking = true; - - EXPECT_CALL(*mockPlatform, getBootTime()).WillOnce(Return(5000)); + EXPECT_CALL(*platform, getBootTime()).WillOnce(::testing::Return(5000)); + health->enableAppBootTimeTracking = true; json sdkInitEvent; - gaHealth->addSDKInitData(sdkInitEvent); + health->addSDKInitData(sdkInitEvent); EXPECT_EQ(sdkInitEvent["app_boot_time"], 5000); } + + From 438199b2c1362b9769e55c93dcedeb1f7015ffeb Mon Sep 17 00:00:00 2001 From: Andrei Dabija Date: Sat, 12 Oct 2024 04:48:45 +0300 Subject: [PATCH 2/5] Rename --- test/{GAHealth_test.cpp => GAHealthTests.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{GAHealth_test.cpp => GAHealthTests.cpp} (100%) diff --git a/test/GAHealth_test.cpp b/test/GAHealthTests.cpp similarity index 100% rename from test/GAHealth_test.cpp rename to test/GAHealthTests.cpp From 549e5cadbd964e636d372780a714a7593597c5a4 Mon Sep 17 00:00:00 2001 From: Andrei Dabija Date: Sat, 12 Oct 2024 05:16:42 +0300 Subject: [PATCH 3/5] make coverage optional , improve setup script --- .github/workflows/coverage.yml | 2 +- CMakeLists.txt | 126 +++++++++++++++++---------------- setup.py | 53 ++++++-------- 3 files changed, 88 insertions(+), 93 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 2d0eb104..9215da07 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -21,7 +21,7 @@ jobs: - name: Configure CMake shell: bash working-directory: ${{github.workspace}}/build - run: cmake .. + run: cmake -DENABLE_COVERAGE=ON .. - name: Build working-directory: ${{github.workspace}}/build diff --git a/CMakeLists.txt b/CMakeLists.txt index e8fc3716..b5d0e0f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMakeInc include("create_source_groups_macro") include("eval_condition_macro") +# --------------------------- Options --------------------------- # +option(ENABLE_COVERAGE "Enable code coverage reporting" OFF) option(GA_SHARED_LIB "Build GA as a shared library" OFF) option(GA_UWP_BUILD "Build GA for UWP (if targeting windows)" OFF) option(GA_BUILD_SAMPLE "Builds the GA Sample app" ON) @@ -242,87 +244,87 @@ target_link_libraries(${UT_PROJECT_NAME} gtest gtest_main gmock_main) target_link_libraries(${UT_PROJECT_NAME} ${PROJECT_NAME}) ######################################## - add_test(NAME ${UT_PROJECT_NAME} COMMAND GameAnalyticsUnitTests) -# --------------------------- Google Test Setup --------------------------- # - -find_program(GCOV_PATH gcov) -if (NOT GCOV_PATH) - message(WARNING "program gcov not found") -endif() - -find_program(LCOV_PATH lcov) -if (NOT LCOV_PATH) - message(WARNING "program lcov not found") -endif() - -find_program(GENHTML_PATH genhtml) -if (NOT GENHTML_PATH) - message(WARNING "program genhtml not found") -endif() - -if (LCOV_PATH AND GCOV_PATH) +# --------------------------- Code Coverage Setup --------------------------- # - target_compile_options( - GameAnalytics - PRIVATE - -g -O0 -fprofile-arcs -ftest-coverage - ) +if (ENABLE_COVERAGE) + find_program(GCOV_PATH gcov) + if (NOT GCOV_PATH) + message(WARNING "program gcov not found") + endif() - target_link_libraries( - GameAnalytics - PRIVATE - --coverage - ) + find_program(LCOV_PATH lcov) + if (NOT LCOV_PATH) + message(WARNING "program lcov not found") + endif() - set(covname cov) + find_program(GENHTML_PATH genhtml) + if (NOT GENHTML_PATH) + message(WARNING "program genhtml not found") + endif() - add_custom_target(cov_data - # Cleanup lcov - COMMENT "Resetting code coverage counters to zero." - ${LCOV_PATH} --directory . --zerocounters + if (LCOV_PATH AND GCOV_PATH) - # Run tests - COMMAND GameAnalyticsUnitTests + target_compile_options( + GameAnalytics + PRIVATE + -g -O0 -fprofile-arcs -ftest-coverage + ) - # Capturing lcov counters and generating report - COMMAND ${LCOV_PATH} --directory . --capture --output-file ${covname}.info - COMMAND ${LCOV_PATH} --remove ${covname}.info - '${CMAKE_SOURCE_DIR}/source/dependencies/*' - '${CMAKE_SOURCE_DIR}/test/*' - '/usr/*' - '/Applications/Xcode.app/*' - --output-file ${covname}.info.cleaned - ) + target_link_libraries( + GameAnalytics + PRIVATE + --coverage + ) - if (GENHTML_PATH) - add_custom_target(cov + set(covname cov) + add_custom_target(cov_data # Cleanup lcov + COMMENT "Resetting code coverage counters to zero." ${LCOV_PATH} --directory . --zerocounters # Run tests COMMAND GameAnalyticsUnitTests # Capturing lcov counters and generating report - COMMAND ${LCOV_PATH} --directory . --capture --output-file ${covname}.info --rc lcov_branch_coverage=1 --rc derive_function_end_line=0 + COMMAND ${LCOV_PATH} --directory . --capture --output-file ${covname}.info COMMAND ${LCOV_PATH} --remove ${covname}.info - '${CMAKE_SOURCE_DIR}/source/dependencies/*' - '/usr/*' - --output-file ${covname}.info.cleaned - --rc lcov_branch_coverage=1 - --rc derive_function_end_line=0 - COMMAND ${GENHTML_PATH} -o ${covname} ${covname}.info.cleaned --rc lcov_branch_coverage=1 --rc derive_function_end_line=0 - COMMAND ${CMAKE_COMMAND} -E remove ${covname}.info ${covname}.info.cleaned - - COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." + '${CMAKE_SOURCE_DIR}/source/dependencies/*' + '${CMAKE_SOURCE_DIR}/test/*' + '/usr/*' + '/Applications/Xcode.app/*' + --output-file ${covname}.info.cleaned ) + + if (GENHTML_PATH) + add_custom_target(cov + + # Cleanup lcov + ${LCOV_PATH} --directory . --zerocounters + + # Run tests + COMMAND GameAnalyticsUnitTests + + # Capturing lcov counters and generating report + COMMAND ${LCOV_PATH} --directory . --capture --output-file ${covname}.info --rc lcov_branch_coverage=1 --rc derive_function_end_line=0 + COMMAND ${LCOV_PATH} --remove ${covname}.info + '${CMAKE_SOURCE_DIR}/source/dependencies/*' + '/usr/*' + --output-file ${covname}.info.cleaned + --rc lcov_branch_coverage=1 + --rc derive_function_end_line=0 + COMMAND ${GENHTML_PATH} -o ${covname} ${covname}.info.cleaned --rc lcov_branch_coverage=1 --rc derive_function_end_line=0 + COMMAND ${CMAKE_COMMAND} -E remove ${covname}.info ${covname}.info.cleaned + + COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." + ) + else() + message(WARNING "unable to generate coverage report: missing genhtml") + endif() + else() - message(WARNING "unable to generate coverage report: missing genhtml") + message(WARNING "unable to add coverage targets: missing coverage tools") endif() - -else() - message(WARNING "unable to add coverage targets: missing coverage tools") endif() - diff --git a/setup.py b/setup.py index 58438a26..1e77fd7e 100644 --- a/setup.py +++ b/setup.py @@ -7,73 +7,66 @@ def run_command(command, shell=True, cwd=None): if os.name == 'nt': # Check if the OS is Windows command = f'powershell.exe -Command "{command}"' - result = subprocess.run(command, shell=shell, check=True, text=True) + result = subprocess.run(command, shell=shell, check=True, text=True, cwd=cwd) return result def main(): parser = argparse.ArgumentParser(description="CMake Build and Test Script") - parser.add_argument('--os', required=True, choices=['linux', 'windows', 'macos'], help='Operating System') - parser.add_argument('--build_type', default='Debug', choices=['Release', 'Debug'], help='Build Type') - parser.add_argument('--platform', choices=['linux_x64', 'linux_x86', 'osx', 'win32', 'win64', 'uwp'], help='Platform string for CMake') + parser.add_argument('--platform', required=True, choices=['linux_x64', 'linux_x86', 'osx', 'win32', 'win64', 'uwp'], help='Platform to build for') + parser.add_argument('--cfg', default='Debug', choices=['Release', 'Debug'], help='Configuration Type') parser.add_argument('--build', action='store_true', help='Execute the build step') parser.add_argument('--test', action='store_true', help='Execute the test step') + parser.add_argument('--coverage', action='store_true', help='Generate code coverage report') + args = parser.parse_args() build_output_dir = os.path.join(os.getcwd(), 'build') os.makedirs(build_output_dir, exist_ok=True) - if args.os == 'windows': - c_compiler = 'cl' - cpp_compiler = 'cl' - elif args.os == 'linux': - c_compiler = 'gcc' - cpp_compiler = 'g++' - elif args.os == 'macos': - c_compiler = 'clang' - cpp_compiler = 'clang++' - - # Configure CMake - cmake_command = f'cmake -B {build_output_dir} -DCMAKE_CXX_COMPILER={cpp_compiler} -DCMAKE_C_COMPILER={c_compiler} -DCMAKE_BUILD_TYPE={args.build_type} -S {os.getcwd()}' - if args.os == 'macos': + # Configure + cmake_command = f'cmake -B {build_output_dir} -S {os.getcwd()}' + if args.platform == 'osx': cmake_command += ' -G "Xcode"' if args.platform: cmake_command += f' -DPLATFORM:STRING={args.platform}' + if args.coverage: + cmake_command += ' -DENABLE_COVERAGE=ON' + run_command(cmake_command) # Build if args.build: - run_command(f'cmake --build {build_output_dir} --config {args.build_type}') + run_command(f'cmake --build {build_output_dir} --config {args.cfg}') else: exit(0) # Test if args.test: - run_command(f'ctest --build-config {args.build_type} --verbose --output-on-failure', cwd=build_output_dir) + run_command(f'ctest --build-config {args.cfg} --verbose --output-on-failure', cwd=build_output_dir) + else: + exit(0) + # Code Coverage + if args.coverage: + # Prepare coverage data + run_command(f'cmake --build {build_output_dir} --target cov_data', cwd=build_output_dir) # Package Build Artifacts package_dir = os.path.join(build_output_dir, 'package') os.makedirs(package_dir, exist_ok=True) - files_to_copy = glob.glob(f'{build_output_dir}/{args.build_type}/*GameAnalytics.*') + files_to_copy = glob.glob(f'{build_output_dir}/{args.cfg}/*GameAnalytics.*') for file in files_to_copy: shutil.copy(file, package_dir) shutil.copytree(os.path.join(os.getcwd(), 'include'), os.path.join(package_dir, 'include'), dirs_exist_ok=True) # Print Package Contents - if args.os == 'windows': + if args.platform.startswith('win'): run_command(f'dir {package_dir}', shell=True) else: run_command(f'ls -la {package_dir}', shell=True) - # Print architecture information - #use lipo on macos and linux and dumpbin on windows - if args.os == 'macos': + if args.platform == 'osx': run_command(f'lipo -info {package_dir}/*GameAnalytics.*') - elif args.os == 'linux': - run_command(f'file {package_dir}/*GameAnalytics.*') - elif args.os == 'windows': - run_command(f'dumpbin /headers {package_dir}/GameAnalytics.lib | findstr machine') - if __name__ == "__main__": - main() \ No newline at end of file + main() From 4b0dc8fd8796e646c948e63b78010b01306f740f Mon Sep 17 00:00:00 2001 From: Andrei Dabija Date: Sat, 12 Oct 2024 05:40:11 +0300 Subject: [PATCH 4/5] Update cmake.yml --- .github/workflows/cmake.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 0b152e67..f8d5dec2 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -102,4 +102,5 @@ jobs: with: name: ga-cpp-sdk-${{ matrix.os }}-${{ matrix.c_compiler }}-${{ matrix.build_type }} path: ${{ steps.strings.outputs.build-output-dir }}/package/ + retention-days: 3 From 7ea612b331a4ad486a871031d12351221f0e0bfe Mon Sep 17 00:00:00 2001 From: Andrei Dabija Date: Sat, 12 Oct 2024 05:57:19 +0300 Subject: [PATCH 5/5] Update setup.py --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1e77fd7e..5d4d400a 100644 --- a/setup.py +++ b/setup.py @@ -7,6 +7,7 @@ def run_command(command, shell=True, cwd=None): if os.name == 'nt': # Check if the OS is Windows command = f'powershell.exe -Command "{command}"' + result = subprocess.run(command, shell=shell, check=True, text=True, cwd=cwd) return result @@ -49,7 +50,7 @@ def main(): # Code Coverage if args.coverage: # Prepare coverage data - run_command(f'cmake --build {build_output_dir} --target cov_data', cwd=build_output_dir) + run_command(f'cmake --build {build_output_dir} --target cov', cwd=build_output_dir) # Package Build Artifacts package_dir = os.path.join(build_output_dir, 'package')