Skip to content

Commit 81af006

Browse files
committed
create features test
1 parent a4b3614 commit 81af006

File tree

11 files changed

+422
-0
lines changed

11 files changed

+422
-0
lines changed

ci/run_tests.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,5 +369,9 @@ popd
369369
# Test custom build directory functionality
370370
bash "../ci/test_custom_build_dir.sh" "$fpm" hello_world
371371

372+
# Test FPM features functionality
373+
echo "=== Testing FPM Features Functionality ==="
374+
bash "../ci/test_features.sh" "$fpm"
375+
372376
# Cleanup
373377
rm -rf ./*/build

ci/test_features.sh

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#!/usr/bin/env bash
2+
set -ex
3+
4+
# Test script for FPM features functionality
5+
# Usage: ./test_features.sh [fpm_executable]
6+
# Note: This script should be run from the repo root or integrated into run_tests.sh
7+
8+
if [ "$1" ]; then
9+
fpm="$1"
10+
else
11+
# Default to the fpm passed from run_tests.sh or system fpm
12+
fpm="${fpm:-fpm}"
13+
fi
14+
15+
echo "Testing FPM features functionality"
16+
17+
echo "=== Testing features_demo package ==="
18+
19+
# Test 1: Basic features - debug feature
20+
pushd "features_demo"
21+
echo "Test 1: Basic debug feature"
22+
rm -rf build
23+
"$fpm" run --features debug | tee output.txt
24+
grep -q "DEBUG mode enabled" output.txt
25+
grep -q "✓ DEBUG mode enabled" output.txt
26+
echo "✓ Debug feature works"
27+
28+
# Test 2: Profile usage - development profile (includes debug)
29+
echo "Test 2: Development profile (debug feature)"
30+
rm -rf build
31+
"$fpm" run --profile development --target features_demo | tee output.txt
32+
grep -q "DEBUG mode enabled" output.txt
33+
echo "✓ Development profile works"
34+
35+
# Test 3: Multiple features
36+
echo "Test 3: Multiple features (debug + openmp)"
37+
rm -rf build
38+
"$fpm" run --features debug,openmp --target features_demo | tee output.txt
39+
grep -q "DEBUG mode enabled" output.txt
40+
grep -q "OpenMP support enabled" output.txt
41+
echo "✓ Multiple features work"
42+
43+
# Test 4: Feature-specific executable (debug_demo only available with debug feature)
44+
echo "Test 4: Feature-specific executable"
45+
rm -rf build
46+
"$fpm" run --feature debug --target debug_demo | tee output.txt
47+
grep -q "Debug Demo Program" output.txt
48+
grep -q "Debug mode: ON" output.txt
49+
echo "✓ Feature-specific executable works"
50+
51+
# Test 5: Profile with multiple features - production profile (release + openmp)
52+
echo "Test 5: Production profile (release + openmp)"
53+
rm -rf build
54+
"$fpm" run --profile production --target features_demo | tee output.txt
55+
grep -q "RELEASE mode enabled" output.txt
56+
grep -q "OpenMP support enabled" output.txt
57+
# Should NOT have debug
58+
! grep -q "DEBUG mode enabled" output.txt
59+
echo "✓ Production profile works"
60+
61+
# Test 6: No features - baseline behavior
62+
echo "Test 6: No features (baseline)"
63+
rm -rf build
64+
"$fpm" run --target features_demo | tee output.txt
65+
# Should have neither DEBUG nor RELEASE without explicit features
66+
! grep -q "DEBUG mode enabled" output.txt || true
67+
! grep -q "RELEASE mode enabled" output.txt || true
68+
grep -q "Features: NONE" output.txt || grep -q "Demo completed successfully" output.txt
69+
echo "✓ Baseline (no features) works"
70+
71+
# Test 7: Build listing with features
72+
echo "Test 7: Build listing with features"
73+
rm -rf build
74+
"$fpm" build --feature debug --list | tee build_list.txt
75+
grep -q "debug_demo" build_list.txt
76+
grep -q "features_demo" build_list.txt
77+
echo "✓ Build listing with features works"
78+
79+
# Test 8: Error handling - invalid feature
80+
echo "Test 8: Error handling for invalid feature"
81+
rm -rf build
82+
if "$fpm" run --feature nonexistent --target features_demo 2>&1 | grep -q "undefined feature"; then
83+
echo "✓ Correctly rejected invalid feature"
84+
else
85+
echo "ERROR: Should reject invalid feature" && exit 1
86+
fi
87+
88+
# Test 9: Error handling - invalid profile
89+
echo "Test 9: Error handling for invalid profile"
90+
rm -rf build
91+
if "$fpm" run --profile nonexistent --target features_demo 2>&1 | grep -q "undefined profile"; then
92+
echo "✓ Correctly rejected invalid profile"
93+
else
94+
echo "ERROR: Should reject invalid profile" && exit 1
95+
fi
96+
97+
# Test 10: Features and profile mutual exclusion
98+
echo "Test 10: Features and profile mutual exclusion"
99+
rm -rf build
100+
if "$fpm" run --feature debug --profile development --target features_demo 2>&1 | grep -q "cannot specify both"; then
101+
echo "✓ Correctly rejected features + profile combination"
102+
else
103+
echo "ERROR: Should reject features + profile combination" && exit 1
104+
fi
105+
106+
# Cleanup
107+
rm -rf build output.txt build_list.txt
108+
popd
109+
110+
echo "=== Testing features_with_dependency package ==="
111+
112+
# Test dependency features
113+
pushd "features_with_dependency"
114+
115+
# Test 11: No features - should show NONE for both local and dependency
116+
echo "Test 11: Dependency package without features"
117+
rm -rf build
118+
"$fpm" run | tee output.txt
119+
grep -q "NONE - no local features active" output.txt
120+
grep -q "Features: NONE" output.txt
121+
echo "✓ Dependency package baseline works"
122+
123+
# Test 12: Debug dependency feature
124+
echo "Test 12: Debug dependency feature"
125+
rm -rf build
126+
"$fpm" run --features with_feat_debug | tee output.txt
127+
grep -q "WITH_DEBUG_DEPENDENCY" output.txt
128+
grep -q "DEBUG mode enabled" output.txt
129+
echo "✓ Debug dependency feature works"
130+
131+
# Test 13: Release dependency feature
132+
echo "Test 13: Release dependency feature"
133+
rm -rf build
134+
"$fpm" run --features with_feat_release | tee output.txt
135+
grep -q "WITH_RELEASE_DEPENDENCY" output.txt
136+
grep -q "RELEASE mode enabled" output.txt
137+
echo "✓ Release dependency feature works"
138+
139+
# Test 14: Multi dependency feature
140+
echo "Test 14: Multi dependency feature"
141+
rm -rf build
142+
"$fpm" run --features with_feat_multi | tee output.txt
143+
grep -q "WITH_MULTI_DEPENDENCY" output.txt
144+
grep -q "DEBUG mode enabled" output.txt
145+
grep -q "MPI support enabled" output.txt
146+
echo "✓ Multi dependency feature works"
147+
148+
# Test 15: Profile with dependency features
149+
echo "Test 15: Debug dependency profile"
150+
rm -rf build
151+
"$fpm" run --profile debug_dep | tee output.txt
152+
grep -q "WITH_DEBUG_DEPENDENCY" output.txt
153+
grep -q "DEBUG mode enabled" output.txt
154+
echo "✓ Debug dependency profile works"
155+
156+
# Cleanup
157+
rm -rf build output.txt
158+
popd
159+
160+
echo "All FPM features tests passed!"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
program debug_demo
2+
use features_demo
3+
implicit none
4+
5+
write(*,*) 'Debug Demo Program'
6+
write(*,*) '=================='
7+
8+
#ifdef DEBUG
9+
write(*,*) 'Debug mode: ON'
10+
#else
11+
write(*,*) 'Debug mode: OFF'
12+
#endif
13+
14+
call show_features()
15+
16+
end program debug_demo
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
program main
2+
use features_demo
3+
implicit none
4+
5+
call show_features()
6+
7+
write(*,*) ''
8+
write(*,*) get_build_info()
9+
write(*,*) ''
10+
write(*,*) 'Demo completed successfully!'
11+
12+
end program main
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name = "features_demo"
2+
version = "0.1.0"
3+
license = "MIT"
4+
description = "Demo package for FPM features functionality"
5+
6+
[[executable]]
7+
name = "features_demo"
8+
source-dir = "app"
9+
main = "main.f90"
10+
11+
[features]
12+
# Base debug feature
13+
debug.flags = "-g"
14+
debug.preprocess.cpp.macros = "DEBUG"
15+
16+
# Release feature
17+
release.flags = "-O3"
18+
release.preprocess.cpp.macros = "RELEASE"
19+
20+
# Compiler-specific features
21+
debug.gfortran.flags = "-Wall -fcheck=bounds"
22+
release.gfortran.flags = "-march=native"
23+
24+
# Platform-specific features
25+
linux.preprocess.cpp.macros = "LINUX_BUILD"
26+
27+
# Parallel features
28+
mpi.preprocess.cpp.macros = "USE_MPI"
29+
mpi.dependencies.mpi = "*"
30+
openmp.preprocess.cpp.macros = "USE_OPENMP"
31+
openmp.dependencies.openmp = "*"
32+
33+
[profiles]
34+
development = ["debug"]
35+
production = ["release", "openmp"]
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
module features_demo
2+
implicit none
3+
private
4+
public :: show_features, get_build_info
5+
6+
contains
7+
8+
!> Display which features are enabled
9+
subroutine show_features()
10+
write(*,*) 'FPM Features Demo'
11+
write(*,*) '================='
12+
13+
! Debug/Release flags
14+
#ifdef DEBUG
15+
write(*,*) '✓ DEBUG mode enabled'
16+
#endif
17+
#ifdef RELEASE
18+
write(*,*) '✓ RELEASE mode enabled'
19+
#endif
20+
21+
! Platform detection
22+
#ifdef LINUX_BUILD
23+
write(*,*) '✓ Linux platform detected'
24+
#endif
25+
#ifdef WINDOWS_BUILD
26+
write(*,*) '✓ Windows platform detected'
27+
#endif
28+
29+
! Parallel features
30+
#ifdef USE_MPI
31+
write(*,*) '✓ MPI support enabled'
32+
#endif
33+
#ifdef USE_OPENMP
34+
write(*,*) '✓ OpenMP support enabled'
35+
#endif
36+
37+
! Compiler info (if available)
38+
write(*,*) 'Build configuration:'
39+
call show_compiler_info()
40+
41+
end subroutine show_features
42+
43+
!> Show compiler information
44+
subroutine show_compiler_info()
45+
#ifdef __GFORTRAN__
46+
write(*,*) ' - Compiler: GNU Fortran'
47+
#endif
48+
#ifdef __INTEL_COMPILER
49+
write(*,*) ' - Compiler: Intel Fortran'
50+
#endif
51+
end subroutine show_compiler_info
52+
53+
!> Get build information as a string
54+
function get_build_info() result(info)
55+
character(len=200) :: info
56+
57+
info = 'Features: '
58+
59+
#ifdef DEBUG
60+
info = trim(info) // 'DEBUG '
61+
#endif
62+
#ifdef RELEASE
63+
info = trim(info) // 'RELEASE '
64+
#endif
65+
#ifdef USE_MPI
66+
info = trim(info) // 'MPI '
67+
#endif
68+
#ifdef USE_OPENMP
69+
info = trim(info) // 'OPENMP '
70+
#endif
71+
72+
if (len_trim(info) == 10) then ! Only "Features: "
73+
info = trim(info) // 'NONE'
74+
end if
75+
76+
end function get_build_info
77+
78+
end module features_demo
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
program features_with_dependency
2+
use features_with_dependency, only: show_features
3+
implicit none
4+
5+
print *, "=== Features with Dependency Demo ==="
6+
print *, ""
7+
8+
call show_features()
9+
10+
print *, ""
11+
print *, "This demonstrates feature propagation to dependencies."
12+
13+
end program features_with_dependency
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name = "features_with_dependency"
2+
version = "0.1.0"
3+
license = "MIT"
4+
description = "Demo package testing dependency features"
5+
6+
[[executable]]
7+
name = "features_with_dependency"
8+
source-dir = "app"
9+
main = "main.f90"
10+
11+
# Enable cpp preprocessing on the main program
12+
[preprocess.cpp]
13+
14+
[dependencies]
15+
# Base dependencies (none for this demo - features will add them)
16+
17+
[features]
18+
# Feature that enables debug mode in the dependency
19+
with_feat_debug.dependencies.features_demo = { path = "../features_demo", features = ["debug"] }
20+
with_feat_debug.preprocess.cpp.macros = "WITH_DEBUG_DEPENDENCY"
21+
22+
# Feature that enables release mode in the dependency
23+
with_feat_release.dependencies.features_demo = { path = "../features_demo", features = ["release"] }
24+
with_feat_release.preprocess.cpp.macros = "WITH_RELEASE_DEPENDENCY"
25+
26+
# Feature that enables multiple dependency features
27+
with_feat_multi.dependencies.features_demo = { path = "../features_demo", features = ["debug", "mpi"] }
28+
with_feat_multi.preprocess.cpp.macros = "WITH_MULTI_DEPENDENCY"
29+
30+
# Feature for platform-specific dependency features
31+
linux_specific.linux.dependencies.features_demo = { path = "../features_demo", features = ["linux"] }
32+
linux_specific.preprocess.cpp.macros = "LINUX_FEATURES"
33+
34+
# Feature combining compiler and dependency features
35+
gfortran_optimized.gfortran.dependencies.features_demo = { path = "../features_demo", features = ["release", "gfortran"] }
36+
gfortran_optimized.gfortran.flags = "-O3 -march=native"
37+
38+
[profiles]
39+
debug_dep = ["with_feat_debug"]
40+
release_dep = ["with_feat_release"]
41+
full_test = ["with_feat_multi", "linux_specific"]

0 commit comments

Comments
 (0)