Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
workflow_dispatch:

env:
CMLIB_VERSION: 1.1.0
CMLIB_VERSION: 1.2.1

jobs:
examples-linux:
Expand All @@ -36,8 +36,10 @@ jobs:
git remote set-url origin "${{ github.server_url }}/${{ github.repository }}"
git clone --branch "v${CMLIB_VERSION}" https://github.com/cmakelib/cmakelib.git
export CMLIB_DIR=$(pwd)/cmakelib
export CMLIB_COMPONENT_LOCAL_BASE_PATH=$(pwd)
ln -s ./ cmakelib-component-cmconf
cd ${{ matrix.example }}
cmake -P config/CMCONF_EXAMPLEConfig.cmake
cmake -DCMCONF_INSTALL_AS_SYMLINK=ON -P config/CMCONF_EXAMPLEConfig.cmake
cmake -P CMakeLists.txt
mkdir _build && cd _build
cmake ..
Expand All @@ -59,8 +61,10 @@ jobs:
git remote set-url origin "${{ github.server_url }}/${{ github.repository }}"
git clone --branch "v$env:CMLIB_VERSION" https://github.com/cmakelib/cmakelib.git
$env:CMLIB_DIR = "$(pwd)/cmakelib"
$env:CMLIB_COMPONENT_LOCAL_BASE_PATH = "$(pwd)"
New-Item -ItemType SymbolicLink -Path "cmakelib-component-cmconf" -Target "./"
cd ${{ matrix.example }}
cmake -P config/CMCONF_EXAMPLEConfig.cmake
cmake -DCMCONF_INSTALL_AS_SYMLINK=ON -P config/CMCONF_EXAMPLEConfig.cmake
cmake -P CMakeLists.txt
mkdir build -ErrorAction SilentlyContinue
cd build
Expand All @@ -83,8 +87,10 @@ jobs:
git remote set-url origin "${{ github.server_url }}/${{ github.repository }}"
git clone --branch "v${CMLIB_VERSION}" https://github.com/cmakelib/cmakelib.git
export CMLIB_DIR=$(pwd)/cmakelib
export CMLIB_COMPONENT_LOCAL_BASE_PATH=$(pwd)
ln -s ./ cmakelib-component-cmconf
cd ${{ matrix.example }}
cmake -P config/CMCONF_EXAMPLEConfig.cmake
cmake -DCMCONF_INSTALL_AS_SYMLINK=ON -P config/CMCONF_EXAMPLEConfig.cmake
cmake -P CMakeLists.txt
mkdir _build && cd _build
cmake ..
6 changes: 5 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
workflow_dispatch:

env:
CMLIB_VERSION: 1.1.0
CMLIB_VERSION: 1.2.1

jobs:
test_linux:
Expand Down Expand Up @@ -40,6 +40,8 @@ jobs:
git remote set-url origin "${{ github.server_url }}/${{ github.repository }}"
git clone --branch "v${CMLIB_VERSION}" https://github.com/cmakelib/cmakelib.git
export CMLIB_DIR=$(pwd)/cmakelib
export CMLIB_COMPONENT_LOCAL_BASE_PATH=$(pwd)/../
ls -lsa
cd test/ && cmake .

test_macos:
Expand All @@ -54,6 +56,7 @@ jobs:
git remote set-url origin "${{ github.server_url }}/${{ github.repository }}"
git clone --branch "v${CMLIB_VERSION}" https://github.com/cmakelib/cmakelib.git
export CMLIB_DIR=$(pwd)/cmakelib
export CMLIB_COMPONENT_LOCAL_BASE_PATH=$(pwd)/../
cd test/ && cmake .

test_windows:
Expand All @@ -68,4 +71,5 @@ jobs:
git remote set-url origin "${{ github.server_url }}/${{ github.repository }}"
git clone --branch "v$Env:CMLIB_VERSION" https://github.com/cmakelib/cmakelib.git
$Env:CMLIB_DIR=$(Join-Path -Path $(Get-Location).Path -ChildPath "cmakelib")
$Env:CMLIB_COMPONENT_LOCAL_BASE_PATH=$(Join-Path -Path $(Get-Location).Path -ChildPath "../")
cd test/ && cmake .
42 changes: 31 additions & 11 deletions CMCONF.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -411,28 +411,48 @@ FUNCTION(_CMCONF_UNINSTALL system_name)

SET(package_registry_path)
IF(WIN32)
SET(userprofile "$ENV{USERPROFILE}")
IF(NOT userprofile)
_CMCONF_MESSAGE(FATAL_ERROR "Cannot uninstall configuration. USERPROFILE environment variable is not set.")
SET(winreg_path "HKCU\\Software\\Kitware\\CMake\\Packages\\${package_name}")
FIND_PROGRAM(reg_exe reg)
IF(NOT reg_exe)
_CMCONF_MESSAGE(FATAL_ERROR "Cannot uninstall configuration. 'reg' executable not found.")
ENDIF()
EXECUTE_PROCESS(
COMMAND "${reg_exe}" query "${winreg_path}"
RESULT_VARIABLE winreg_exist
ERROR_VARIABLE errout
OUTPUT_VARIABLE stdout
)
IF(NOT winreg_exist EQUAL 0)
_CMCONF_MESSAGE(WARNING "No need to uninstall configuration for ${system_name}. It is not installed.")
RETURN()
ENDIF()
EXECUTE_PROCESS(
COMMAND "${reg_exe}" delete "${winreg_path}" /f
RESULT_VARIABLE result_var
ERROR_VARIABLE errout
OUTPUT_VARIABLE stdout
)
IF(NOT result_var EQUAL 0)
_CMCONF_MESSAGE(FATAL_ERROR "Failed to uninstall configuration for system ${system_name}: ${errout}\n${stdout}")
ENDIF()
FILE(TO_CMAKE_PATH "${userprofile}" userprofile)
SET(package_registry_path "${userprofile}/.cmake/packages/${package_name}")
ELSEIF(UNIX)
SET(userhome "$ENV{HOME}")
IF(NOT userhome)
_CMCONF_MESSAGE(FATAL_ERROR "Cannot uninstall configuration. HOME environment variable is not set.")
ENDIF()
FILE(TO_CMAKE_PATH "${userhome}" userhome)
SET(package_registry_path "${userhome}/.cmake/packages/${package_name}")
ENDIF()

FIND_PACKAGE(${package_name} QUIET)
IF(NOT ${package_name}_FOUND)
_CMCONF_MESSAGE(WARNING "No need to uninstall configuration for ${system_name}. It is not installed.")
RETURN()
FIND_PACKAGE(${package_name} QUIET)
IF(NOT ${package_name}_FOUND)
_CMCONF_MESSAGE(WARNING "No need to uninstall configuration for ${system_name}. It is not installed.")
RETURN()
ENDIF()
FILE(REMOVE_RECURSE "${package_registry_path}")
ELSE()
_CMCONF_MESSAGE(FATAL_ERROR "Cannot uninstall configuration. Unsupported platform.")
ENDIF()

FILE(REMOVE_RECURSE "${package_registry_path}")
_CMCONF_MESSAGE(STATUS "Uninstalled configuration for system ${system_name} succeeded.")
ENDFUNCTION()

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ Every function has comprehensive documentation written as part of the function d

Context documentation is located at [CMCONF.cmake]

## Tests

For test go to the [test/] and read the attached [test/README.md].

## License

Project is licensed under [MIT](LICENSE)
Expand Down
5 changes: 1 addition & 4 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/pass/cache_variable_behavior")
TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/pass/case_insensitive")
TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/pass/different_system_names")
TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/pass/multiple_variables")
TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/pass/uninstall_verification")

TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/fail/config_not_installed")
TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/fail/config_already_installed")
Expand All @@ -38,10 +39,6 @@ TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/fail/variable_already_exists")
TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/fail/variable_not_defined")
TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/fail/wrong_filename")

IF(WIN32)
TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/fail/windows_userprofile_missing")
ENDIF()

IF(UNIX)
TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/fail/unix_home_missing")
ENDIF()
Expand Down
81 changes: 81 additions & 0 deletions test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# CMCONF Test Suite

Comprehensive test suite for the CMCONF (CMake Configuration Framework) component library.

## Test Modules

Currently tested functionality

- **`CMCONF_SET`** - Configuration variable setting
- **`CMCONF_GET`** - Configuration variable retrieval
- **`CMCONF_INIT_SYSTEM`** - System name configuration
- **`INSTALL Feature`** - Configuration installation
- **`UNINSTALL Feature`** - Configuration uninstallation

Not covered functionality

- Edge cases for Windows OS regard of `reg` command behaviour.
It is expected that this command is available on Windows be default.
If not, not only CMake but also Windows itself is broken.

### Test Structure

Tests are organized into subdirectories within `test_cases`, separated into:

- **`pass/`** - Tests that verify correct functionality and expected behavior
- **`fail/`** - Tests that verify proper error handling and validation

Each test case directory contains a `CMakeLists.txt` file that tests specific functionality.

Configuration templates and test resources are placed in the `config_templates` directory.

## Test Framework

- `TEST.cmake` - Common test macros. It is reused from CMLIB.
- `cache_var.cmake` - Macros to force set and restore cache variables. It is reused from CMLIB.
- `test_cmconf_helpers.cmake` - CMCONF-specific test helper functions and macros

### Test Resource Creation and Maintenance

When external resources are needed to test functionality:

- Configuration templates are provided in the `config_templates` directory
- Test configurations are created from predefined templates
- There are no external dependencies to download or install
- There shall be no dynamic creation of test resources during a test run (exceptions can apply if reasoned)

## Running Tests

**All tests are designed to be run from a clean source tree.**

CMCONF is consistent and functional only when all tests pass.

Any test failure indicates CMCONF is not working as expected, even if the failure seems unrelated to required functionality. Complete system consistency is essential for reliable operation.

### Run All Tests

Tests shall be run in Project and Script mode.

```bash
# Project mode
git clean -xfd .
cmake .

# Script mode
git clean -xfd .
cmake -P ./test/CMakeLists.txt
```

### Clean Up

```bash
git clean -xfd .
```

## Platform Considerations

Tests are designed to run on Linux-based systems as the main development platform. Platform-specific behavior is tested where applicable, particularly for:

- Unix home directory handling
- System-specific configuration paths (windows vs unix)
- Platform-specific variable behaviors
15 changes: 13 additions & 2 deletions test/test_cases/fail/unix_home_missing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,18 @@ INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../test_cmconf_helpers.cmake")
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../config_templates/config_template.cmake")

TEST_CMCONF_CHECK_AND_INSTALL_CONFIG("${CMCONF_TEST_CONFIG_FILE}" "TEST")
TEST_RUN_AND_CHECK_OUTPUT("test_config"
FATAL_ERROR_MESSAGE "CMCONF\\\\[TEST\\\\] - Cannot uninstall configuration\\..*HOME environment variable.*is not set\\."

EXECUTE_PROCESS(
COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/test_config/CMakeLists.txt"
RESULT_VARIABLE result
ERROR_VARIABLE error_output
OUTPUT_VARIABLE output
)
IF(result EQUAL 0)
MESSAGE(FATAL_ERROR "Expected test to fail but it succeeded")
ENDIF()
IF(NOT error_output MATCHES "CMCONF\\[TEST\\] - Cannot uninstall configuration\\..*HOME environment variable.*is not set\\.")
MESSAGE(FATAL_ERROR "Expected error message not found in output: ${error_output}")
ENDIF()

TEST_CMCONF_UNINSTALL_CONFIG("${CMCONF_TEST_CONFIG_FILE}" "TEST")
21 changes: 0 additions & 21 deletions test/test_cases/fail/windows_userprofile_missing/CMakeLists.txt

This file was deleted.

This file was deleted.

45 changes: 45 additions & 0 deletions test/test_cases/pass/uninstall_verification/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
## Main
#
# Test that CMCONF uninstallation actually removes the package from registry
#
# Strategy: Single file for sequential state-dependent test
# Steps must execute in exact order with shared state.
# Splitting would require complex state passing and risk inconsistent cleanup on failures.
#

IF(NOT DEFINED CMAKE_SCRIPT_MODE_FILE)
CMAKE_MINIMUM_REQUIRED(VERSION 3.22)
PROJECT(CMCONF_UNINSTALL_VERIFICATION_TEST)
ENDIF()

FIND_PACKAGE(CMLIB REQUIRED)

INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake")
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake")
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMCONF.cmake")
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../test_cmconf_helpers.cmake")
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../config_templates/config_template.cmake")

TEST_CMCONF_CHECK_AND_INSTALL_CONFIG("${CMCONF_TEST_CONFIG_FILE}" "TEST")

SET(package_name "CMCONF_TEST")
FIND_PACKAGE(${package_name} QUIET)
IF(NOT ${package_name}_FOUND)
MESSAGE(FATAL_ERROR "Package ${package_name} should be found after installation, but it was not found")
ENDIF()

CMCONF_INIT_SYSTEM(TEST)
CMCONF_GET(VARIABLE_A)
TEST_VAR_DEFINED(VARIABLE_A)
TEST_VAR_EQUALS_LITERAL(VARIABLE_A "test_value_a")

TEST_CMCONF_UNINSTALL_CONFIG("${CMCONF_TEST_CONFIG_FILE}" "TEST")

UNSET(${package_name}_FOUND CACHE)
UNSET(${package_name}_DIR CACHE)
UNSET(${package_name}_CONFIG CACHE)

FIND_PACKAGE(${package_name} QUIET)
IF(${package_name}_FOUND)
MESSAGE(FATAL_ERROR "Package ${package_name} should NOT be found after uninstallation, but it was still found at: ${${package_name}_DIR}")
ENDIF()
Loading