1+ #! /bin/bash
2+ #
3+ # Chainloop Policy Test Utilities
4+ #
5+ # This file contains shared test framework functions for policy testing.
6+ # It's designed to be shared across all policy directories.
7+ #
8+ # Usage: source ../_testutils.sh
9+ #
10+
11+ set -e
12+
13+ # Unalias grep to use standard grep instead of rg
14+ unalias grep 2> /dev/null || true
15+
16+ # Colors for output
17+ RED=' \033[0;31m'
18+ GREEN=' \033[0;32m'
19+ YELLOW=' \033[1;33m'
20+ BLUE=' \033[0;34m'
21+ NC=' \033[0m' # No Color
22+
23+ # Test counters
24+ TESTS_PASSED=0
25+ TESTS_FAILED=0
26+
27+ # Find chainloop binary - prefer PATH
28+ find_chainloop_binary () {
29+ if command -v chainloop & > /dev/null; then
30+ echo " chainloop"
31+ elif [ -f " ../../../../app/cli/bin/chainloop" ]; then
32+ echo " ../../../../app/cli/bin/chainloop"
33+ elif [ -f " ../../../../bin/chainloop" ]; then
34+ echo " ../../../../bin/chainloop"
35+ else
36+ echo -e " ${RED} Error: chainloop binary not found${NC} " >&2
37+ echo " Please build the CLI first or ensure it's in your PATH" >&2
38+ exit 1
39+ fi
40+ }
41+
42+ # Initialize test framework
43+ init_tests () {
44+ CHAINLOOP_BIN=$( find_chainloop_binary)
45+ echo -e " ${BLUE} Using Chainloop binary: ${CHAINLOOP_BIN}${NC} "
46+ echo " "
47+
48+ TESTS_PASSED=0
49+ TESTS_FAILED=0
50+ }
51+
52+ # Check if policy was actually executed (not skipped or ignored)
53+ is_policy_executed () {
54+ local output=" $1 "
55+
56+ # Check if policy was skipped
57+ if echo " $output " | command grep -q ' "skipped": *true' ; then
58+ return 1 # false - policy was skipped
59+ fi
60+
61+ # Check if policy was ignored
62+ if echo " $output " | command grep -q ' "ignored": *true' ; then
63+ return 1 # false - policy was ignored
64+ fi
65+
66+ return 0 # true - policy was executed
67+ }
68+
69+ # Check if violations exist in policy output
70+ has_violations () {
71+ local output=" $1 "
72+
73+ # Check if violations array is non-empty (not "violations": [])
74+ if echo " $output " | command grep -q ' "violations": *\[\]' ; then
75+ return 1 # false - empty violations array
76+ elif echo " $output " | command grep -q ' "violations": *\[' ; then
77+ return 0 # true - has violations
78+ else
79+ return 1 # false - no violations field found
80+ fi
81+ }
82+
83+ # Test policy linting
84+ test_policy_lint () {
85+ local policy_file=" $1 "
86+ local test_name=" ${2:- Policy Lint Check} "
87+
88+ echo -e " ${YELLOW} Testing: ${test_name}${NC} "
89+ echo " Command: $CHAINLOOP_BIN policy develop lint --policy $policy_file "
90+
91+ if output=$( $CHAINLOOP_BIN policy develop lint --policy " $policy_file " 2>&1 ) ; then
92+ echo -e " ${GREEN} ✓ PASSED${NC} "
93+ (( TESTS_PASSED++ ))
94+ else
95+ echo -e " ${RED} ✗ FAILED${NC} "
96+ echo " Output: $output "
97+ (( TESTS_FAILED++ ))
98+ fi
99+ echo " "
100+ }
101+
102+ # Test policy evaluation
103+ test_policy_eval () {
104+ local test_name=" $1 "
105+ local expected_result=" $2 " # "pass" or "fail"
106+ shift 2
107+ local args=" $@ "
108+
109+ # Extract --kind parameter from args
110+ local material_kind=" EVIDENCE" # Default fallback
111+ local remaining_args=" "
112+
113+ while [[ $# -gt 0 ]]; do
114+ case $1 in
115+ --kind)
116+ material_kind=" $2 "
117+ shift 2
118+ ;;
119+ * )
120+ remaining_args=" $remaining_args $1 "
121+ shift
122+ ;;
123+ esac
124+ done
125+
126+ echo -e " ${YELLOW} Testing: ${test_name}${NC} "
127+ echo " Command: $CHAINLOOP_BIN policy develop eval --policy policy.yaml --kind $material_kind $remaining_args "
128+
129+ # Execute the command
130+ if output=$( $CHAINLOOP_BIN policy develop eval --policy policy.yaml --kind " $material_kind " $remaining_args 2>&1 ) ; then
131+ exit_code=0
132+ else
133+ exit_code=$?
134+ fi
135+
136+ # Determine actual result
137+ if [ $exit_code -eq 0 ]; then
138+ # First check if policy was actually executed
139+ if ! is_policy_executed " $output " ; then
140+ actual_result=" fail" # Policy was skipped or ignored
141+ if echo " $output " | command grep -q ' "skipped": *true' ; then
142+ skip_reason=" Policy was skipped"
143+ elif echo " $output " | command grep -q ' "ignored": *true' ; then
144+ skip_reason=" Policy was ignored (material type mismatch)"
145+ else
146+ skip_reason=" Policy was not executed"
147+ fi
148+ elif has_violations " $output " ; then
149+ actual_result=" fail" # Has violations = test should fail
150+ else
151+ actual_result=" pass" # No violations = test should pass
152+ fi
153+ else
154+ actual_result=" fail" # Command failed
155+ fi
156+
157+ # Compare with expected result
158+ if [ " $actual_result " = " $expected_result " ]; then
159+ if [ " $expected_result " = " pass" ]; then
160+ echo -e " ${GREEN} ✓ PASSED${NC} "
161+ else
162+ echo -e " ${GREEN} ✓ FAILED (as expected)${NC} "
163+ fi
164+ (( TESTS_PASSED++ ))
165+ else
166+ if [ " $expected_result " = " pass" ]; then
167+ echo -e " ${RED} ✗ FAILED (expected to pass but failed)${NC} "
168+ else
169+ echo -e " ${RED} ✗ PASSED (expected to fail but passed)${NC} "
170+ fi
171+
172+ # Show skip reason if policy wasn't executed
173+ if [ -n " ${skip_reason:- } " ]; then
174+ echo " Reason: $skip_reason "
175+ fi
176+ echo " Output: $output "
177+ (( TESTS_FAILED++ ))
178+ fi
179+ echo " "
180+ }
181+
182+ # Print test summary and exit with appropriate code
183+ test_summary () {
184+ echo -e " ${BLUE} === Test Results Summary ===${NC} "
185+ echo " "
186+ TOTAL_TESTS=$(( TESTS_PASSED + TESTS_FAILED))
187+ echo -e " Total Tests: ${TOTAL_TESTS} "
188+ echo -e " ${GREEN} Passed: ${TESTS_PASSED}${NC} "
189+ echo -e " ${RED} Failed: ${TESTS_FAILED}${NC} "
190+ echo " "
191+
192+ if [ $TESTS_FAILED -eq 0 ]; then
193+ echo -e " ${GREEN} 🎉 All tests passed!${NC} "
194+ exit 0
195+ else
196+ echo -e " ${RED} ❌ Some tests failed. Please check the output above.${NC} "
197+ exit 1
198+ fi
199+ }
200+
201+ # Verify required files exist
202+ verify_files () {
203+ local files=(" $@ " )
204+ for file in " ${files[@]} " ; do
205+ if [ ! -f " $file " ]; then
206+ echo -e " ${RED} Error: $file not found${NC} " >&2
207+ exit 1
208+ fi
209+ done
210+ }
211+
212+ # Print a test section header
213+ test_section () {
214+ local section_name=" $1 "
215+ echo -e " ${BLUE} === ${section_name} ===${NC} "
216+ echo " "
217+ }
0 commit comments