Skip to content

Commit 2f3d8f9

Browse files
Added cfengine test, a one-stop command to lint/build/deploy/run a policy-set
First iteration of the `cfengine test`-command, with the intention of being used in a future "CFEngine testing framework" Ticket: ENT-14443 Signed-off-by: Simon Halvorsen <simon.halvorsen@northern.tech>
1 parent 1498498 commit 2f3d8f9

4 files changed

Lines changed: 76 additions & 0 deletions

File tree

‎src/cfengine_cli/cfengine_wrapper/cfengine_commands.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,18 @@ def deploy(
287287
return error
288288

289289

290+
def test(hub=None) -> int:
291+
rc = build_command()
292+
if rc != 0:
293+
return rc
294+
295+
agent = require_executable("cf-agent", hub)
296+
location = "localhost" if agent.location == "local" else agent.location
297+
298+
error = deploy_command([location], None)
299+
return error if error else agent.run("-KIf update.cf", "-KI")
300+
301+
290302
def show(target: list[str] | None = None) -> int:
291303
if target == [] or target is None:
292304
return show_command(False)

‎src/cfengine_cli/commands.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from cfengine_cli.initialize_project import init_policy_module, init_promise_type
1313
from cf_remote.paths import cf_remote_dir
1414
from cfbs.commands import init_command
15+
from cfengine_cli.cfengine_wrapper.cfengine_commands import test as _cfengine_test
1516
from pydantic import ValidationError
1617

1718

@@ -47,6 +48,17 @@ def lint(files, strict, syntax_path) -> int:
4748
return errors
4849

4950

51+
def test(files, strict, hub) -> int:
52+
errors = _lint(files, strict, None)
53+
if errors != 0:
54+
plural = "error" if errors == 1 else "errors"
55+
print(f"Lint failed, {errors} {plural} in total. Skipping build/deploy/run.")
56+
return errors
57+
58+
print("Lint passed, no errors found.")
59+
return _cfengine_test(hub)
60+
61+
5062
def dev(subcommand, args) -> int:
5163
return dispatch_dev_subcommand(subcommand, args)
5264

‎src/cfengine_cli/main.py‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,26 @@ def _get_arg_parser():
8888
)
8989
lnt.add_argument("files", nargs="*", help="Files to lint")
9090

91+
tst = subp.add_parser(
92+
"test",
93+
help="Lint, then build/deploy/run a cfbs project as one non-interactive check",
94+
description="A convenience wrapper chaining `cfengine lint` and `cfengine build` "
95+
"to quickly test a module or policy-set end-to-end. "
96+
"Without --hub HUB specified, you will be prompted, else the chosen hub will be used.",
97+
)
98+
tst.add_argument(
99+
"--strict",
100+
type=str,
101+
default="yes",
102+
help="Strict mode for linting. Default=yes, checks for undefined promise types, bundles, bodies, functions",
103+
)
104+
tst.add_argument("--hub", help="Hub to deploy to after building", type=str)
105+
tst.add_argument(
106+
"files",
107+
nargs="*",
108+
help="Files/Folder to lint (default is . (the entire project) )",
109+
)
110+
91111
dev_parser = subp.add_parser(
92112
"dev", help="Utilities intended for developers / maintainers of CFEngine"
93113
)
@@ -245,6 +265,12 @@ def run_command_with_args(args) -> int:
245265
(args.strict.lower() in ("y", "ye", "yes")),
246266
args.syntax_description,
247267
)
268+
if args.command == "test":
269+
return commands.test(
270+
args.files,
271+
(args.strict.lower() in ("y", "ye", "yes")),
272+
args.hub,
273+
)
248274
if args.command == "report":
249275
return cfengine_commands.report(
250276
target=args.hub,

‎tests/shell/006-test.sh‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
3+
set -e
4+
set -x
5+
6+
# Setup: create a temp directory for test files
7+
tmpdir=$(mktemp -d)
8+
trap "rm -rf $tmpdir" EXIT
9+
10+
cfengine test --help
11+
12+
# A file with a lint error should make `cfengine test` fail on the lint step
13+
# and not go through to build/deploy/run.
14+
printf 'bundle agent main\n{\n reports:\n "missing semicolon"\n}\n' > "$tmpdir/bad.cf"
15+
16+
output_file=$(mktemp)
17+
trap "rm -rf $tmpdir $output_file" EXIT
18+
19+
if cfengine test "$tmpdir/bad.cf" > "$output_file" 2>&1; then
20+
cat "$output_file"
21+
echo "FAIL: expected cfengine test to fail on a lint error"
22+
exit 1
23+
fi
24+
cat "$output_file"
25+
grep -q "Lint failed" "$output_file"
26+
grep -q "Skipping build/deploy/run" "$output_file"

0 commit comments

Comments
 (0)