Skip to content

Commit 19b167d

Browse files
authored
Unit Tests & CI improvements (#12)
* fix GAHealth Tests * Rename * make coverage optional , improve setup script * Update cmake.yml * Update setup.py
1 parent ec878c1 commit 19b167d

File tree

7 files changed

+271
-309
lines changed

7 files changed

+271
-309
lines changed

.github/workflows/cmake.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,5 @@ jobs:
102102
with:
103103
name: ga-cpp-sdk-${{ matrix.os }}-${{ matrix.c_compiler }}-${{ matrix.build_type }}
104104
path: ${{ steps.strings.outputs.build-output-dir }}/package/
105+
retention-days: 3
105106

.github/workflows/coverage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
- name: Configure CMake
2222
shell: bash
2323
working-directory: ${{github.workspace}}/build
24-
run: cmake ..
24+
run: cmake -DENABLE_COVERAGE=ON ..
2525

2626
- name: Build
2727
working-directory: ${{github.workspace}}/build

CMakeLists.txt

Lines changed: 64 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMakeInc
1414
include("create_source_groups_macro")
1515
include("eval_condition_macro")
1616

17+
# --------------------------- Options --------------------------- #
18+
option(ENABLE_COVERAGE "Enable code coverage reporting" OFF)
1719
option(GA_SHARED_LIB "Build GA as a shared library" OFF)
1820
option(GA_UWP_BUILD "Build GA for UWP (if targeting windows)" OFF)
1921
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)
242244
target_link_libraries(${UT_PROJECT_NAME} ${PROJECT_NAME})
243245

244246
########################################
245-
246247
add_test(NAME ${UT_PROJECT_NAME} COMMAND GameAnalyticsUnitTests)
247248

248-
# --------------------------- Google Test Setup --------------------------- #
249-
250-
find_program(GCOV_PATH gcov)
251-
if (NOT GCOV_PATH)
252-
message(WARNING "program gcov not found")
253-
endif()
254-
255-
find_program(LCOV_PATH lcov)
256-
if (NOT LCOV_PATH)
257-
message(WARNING "program lcov not found")
258-
endif()
259-
260-
find_program(GENHTML_PATH genhtml)
261-
if (NOT GENHTML_PATH)
262-
message(WARNING "program genhtml not found")
263-
endif()
264-
265-
if (LCOV_PATH AND GCOV_PATH)
249+
# --------------------------- Code Coverage Setup --------------------------- #
266250

267-
target_compile_options(
268-
GameAnalytics
269-
PRIVATE
270-
-g -O0 -fprofile-arcs -ftest-coverage
271-
)
251+
if (ENABLE_COVERAGE)
252+
find_program(GCOV_PATH gcov)
253+
if (NOT GCOV_PATH)
254+
message(WARNING "program gcov not found")
255+
endif()
272256

273-
target_link_libraries(
274-
GameAnalytics
275-
PRIVATE
276-
--coverage
277-
)
257+
find_program(LCOV_PATH lcov)
258+
if (NOT LCOV_PATH)
259+
message(WARNING "program lcov not found")
260+
endif()
278261

279-
set(covname cov)
262+
find_program(GENHTML_PATH genhtml)
263+
if (NOT GENHTML_PATH)
264+
message(WARNING "program genhtml not found")
265+
endif()
280266

281-
add_custom_target(cov_data
282-
# Cleanup lcov
283-
COMMENT "Resetting code coverage counters to zero."
284-
${LCOV_PATH} --directory . --zerocounters
267+
if (LCOV_PATH AND GCOV_PATH)
285268

286-
# Run tests
287-
COMMAND GameAnalyticsUnitTests
269+
target_compile_options(
270+
GameAnalytics
271+
PRIVATE
272+
-g -O0 -fprofile-arcs -ftest-coverage
273+
)
288274

289-
# Capturing lcov counters and generating report
290-
COMMAND ${LCOV_PATH} --directory . --capture --output-file ${covname}.info
291-
COMMAND ${LCOV_PATH} --remove ${covname}.info
292-
'${CMAKE_SOURCE_DIR}/source/dependencies/*'
293-
'${CMAKE_SOURCE_DIR}/test/*'
294-
'/usr/*'
295-
'/Applications/Xcode.app/*'
296-
--output-file ${covname}.info.cleaned
297-
)
275+
target_link_libraries(
276+
GameAnalytics
277+
PRIVATE
278+
--coverage
279+
)
298280

299-
if (GENHTML_PATH)
300-
add_custom_target(cov
281+
set(covname cov)
301282

283+
add_custom_target(cov_data
302284
# Cleanup lcov
285+
COMMENT "Resetting code coverage counters to zero."
303286
${LCOV_PATH} --directory . --zerocounters
304287

305288
# Run tests
306289
COMMAND GameAnalyticsUnitTests
307290

308291
# Capturing lcov counters and generating report
309-
COMMAND ${LCOV_PATH} --directory . --capture --output-file ${covname}.info --rc lcov_branch_coverage=1 --rc derive_function_end_line=0
292+
COMMAND ${LCOV_PATH} --directory . --capture --output-file ${covname}.info
310293
COMMAND ${LCOV_PATH} --remove ${covname}.info
311-
'${CMAKE_SOURCE_DIR}/source/dependencies/*'
312-
'/usr/*'
313-
--output-file ${covname}.info.cleaned
314-
--rc lcov_branch_coverage=1
315-
--rc derive_function_end_line=0
316-
COMMAND ${GENHTML_PATH} -o ${covname} ${covname}.info.cleaned --rc lcov_branch_coverage=1 --rc derive_function_end_line=0
317-
COMMAND ${CMAKE_COMMAND} -E remove ${covname}.info ${covname}.info.cleaned
318-
319-
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
294+
'${CMAKE_SOURCE_DIR}/source/dependencies/*'
295+
'${CMAKE_SOURCE_DIR}/test/*'
296+
'/usr/*'
297+
'/Applications/Xcode.app/*'
298+
--output-file ${covname}.info.cleaned
320299
)
300+
301+
if (GENHTML_PATH)
302+
add_custom_target(cov
303+
304+
# Cleanup lcov
305+
${LCOV_PATH} --directory . --zerocounters
306+
307+
# Run tests
308+
COMMAND GameAnalyticsUnitTests
309+
310+
# Capturing lcov counters and generating report
311+
COMMAND ${LCOV_PATH} --directory . --capture --output-file ${covname}.info --rc lcov_branch_coverage=1 --rc derive_function_end_line=0
312+
COMMAND ${LCOV_PATH} --remove ${covname}.info
313+
'${CMAKE_SOURCE_DIR}/source/dependencies/*'
314+
'/usr/*'
315+
--output-file ${covname}.info.cleaned
316+
--rc lcov_branch_coverage=1
317+
--rc derive_function_end_line=0
318+
COMMAND ${GENHTML_PATH} -o ${covname} ${covname}.info.cleaned --rc lcov_branch_coverage=1 --rc derive_function_end_line=0
319+
COMMAND ${CMAKE_COMMAND} -E remove ${covname}.info ${covname}.info.cleaned
320+
321+
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
322+
)
323+
else()
324+
message(WARNING "unable to generate coverage report: missing genhtml")
325+
endif()
326+
321327
else()
322-
message(WARNING "unable to generate coverage report: missing genhtml")
328+
message(WARNING "unable to add coverage targets: missing coverage tools")
323329
endif()
324-
325-
else()
326-
message(WARNING "unable to add coverage targets: missing coverage tools")
327330
endif()
328-

setup.py

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,73 +7,67 @@
77
def run_command(command, shell=True, cwd=None):
88
if os.name == 'nt': # Check if the OS is Windows
99
command = f'powershell.exe -Command "{command}"'
10-
result = subprocess.run(command, shell=shell, check=True, text=True)
10+
11+
result = subprocess.run(command, shell=shell, check=True, text=True, cwd=cwd)
1112
return result
1213

1314
def main():
1415
parser = argparse.ArgumentParser(description="CMake Build and Test Script")
15-
parser.add_argument('--os', required=True, choices=['linux', 'windows', 'macos'], help='Operating System')
16-
parser.add_argument('--build_type', default='Debug', choices=['Release', 'Debug'], help='Build Type')
17-
parser.add_argument('--platform', choices=['linux_x64', 'linux_x86', 'osx', 'win32', 'win64', 'uwp'], help='Platform string for CMake')
16+
parser.add_argument('--platform', required=True, choices=['linux_x64', 'linux_x86', 'osx', 'win32', 'win64', 'uwp'], help='Platform to build for')
17+
parser.add_argument('--cfg', default='Debug', choices=['Release', 'Debug'], help='Configuration Type')
1818
parser.add_argument('--build', action='store_true', help='Execute the build step')
1919
parser.add_argument('--test', action='store_true', help='Execute the test step')
20+
parser.add_argument('--coverage', action='store_true', help='Generate code coverage report')
21+
2022
args = parser.parse_args()
2123

2224
build_output_dir = os.path.join(os.getcwd(), 'build')
2325
os.makedirs(build_output_dir, exist_ok=True)
2426

25-
if args.os == 'windows':
26-
c_compiler = 'cl'
27-
cpp_compiler = 'cl'
28-
elif args.os == 'linux':
29-
c_compiler = 'gcc'
30-
cpp_compiler = 'g++'
31-
elif args.os == 'macos':
32-
c_compiler = 'clang'
33-
cpp_compiler = 'clang++'
34-
35-
# Configure CMake
36-
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()}'
37-
if args.os == 'macos':
27+
# Configure
28+
cmake_command = f'cmake -B {build_output_dir} -S {os.getcwd()}'
29+
if args.platform == 'osx':
3830
cmake_command += ' -G "Xcode"'
3931
if args.platform:
4032
cmake_command += f' -DPLATFORM:STRING={args.platform}'
33+
if args.coverage:
34+
cmake_command += ' -DENABLE_COVERAGE=ON'
35+
4136
run_command(cmake_command)
4237

4338
# Build
4439
if args.build:
45-
run_command(f'cmake --build {build_output_dir} --config {args.build_type}')
40+
run_command(f'cmake --build {build_output_dir} --config {args.cfg}')
4641
else:
4742
exit(0)
4843

4944
# Test
5045
if args.test:
51-
run_command(f'ctest --build-config {args.build_type} --verbose --output-on-failure', cwd=build_output_dir)
46+
run_command(f'ctest --build-config {args.cfg} --verbose --output-on-failure', cwd=build_output_dir)
47+
else:
48+
exit(0)
5249

50+
# Code Coverage
51+
if args.coverage:
52+
# Prepare coverage data
53+
run_command(f'cmake --build {build_output_dir} --target cov', cwd=build_output_dir)
5354

5455
# Package Build Artifacts
5556
package_dir = os.path.join(build_output_dir, 'package')
5657
os.makedirs(package_dir, exist_ok=True)
57-
files_to_copy = glob.glob(f'{build_output_dir}/{args.build_type}/*GameAnalytics.*')
58+
files_to_copy = glob.glob(f'{build_output_dir}/{args.cfg}/*GameAnalytics.*')
5859
for file in files_to_copy:
5960
shutil.copy(file, package_dir)
6061
shutil.copytree(os.path.join(os.getcwd(), 'include'), os.path.join(package_dir, 'include'), dirs_exist_ok=True)
6162

6263
# Print Package Contents
63-
if args.os == 'windows':
64+
if args.platform.startswith('win'):
6465
run_command(f'dir {package_dir}', shell=True)
6566
else:
6667
run_command(f'ls -la {package_dir}', shell=True)
6768

68-
# Print architecture information
69-
#use lipo on macos and linux and dumpbin on windows
70-
if args.os == 'macos':
69+
if args.platform == 'osx':
7170
run_command(f'lipo -info {package_dir}/*GameAnalytics.*')
72-
elif args.os == 'linux':
73-
run_command(f'file {package_dir}/*GameAnalytics.*')
74-
elif args.os == 'windows':
75-
run_command(f'dumpbin /headers {package_dir}/GameAnalytics.lib | findstr machine')
76-
7771

7872
if __name__ == "__main__":
79-
main()
73+
main()

source/gameanalytics/GAHealth.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,13 @@ namespace gameanalytics
3232

3333
int GAHealth::getMemoryPercent(int64_t memory)
3434
{
35-
if((memory > 0) && (_totalMemory > 0))
36-
{
37-
int memoryPercent = std::round(static_cast<double>(memory) / static_cast<double>(_totalMemory) * 100.0);
38-
return std::min(memoryPercent, 100);
39-
}
40-
41-
return 0;
35+
if((memory > 0) && (_totalMemory > 0))
36+
{
37+
int memoryPercent = std::round(static_cast<double>(memory) / static_cast<double>(_totalMemory) * 100.0);
38+
return memoryPercent;
39+
}
4240

41+
return -1;
4342
}
4443

4544
void GAHealth::doAppMemoryReading(int64_t memory)

0 commit comments

Comments
 (0)