1#!/bin/sh
2#
3# This script is used to test that the module system is working as expected.
4# By default it test the version of nixpkgs which is defined in the NIX_PATH.
5
6cd ./modules
7
8pass=0
9fail=0
10
11evalConfig() {
12 local attr=$1
13 shift;
14 local script="import ./default.nix { modules = [ $@ ];}"
15 nix-instantiate --timeout 1 -E "$script" -A "$attr" --eval-only --show-trace
16}
17
18reportFailure() {
19 local attr=$1
20 shift;
21 local script="import ./default.nix { modules = [ $@ ];}"
22 echo 2>&1 "$ nix-instantiate -E '$script' -A '$attr' --eval-only"
23 evalConfig "$attr" "$@"
24 fail=$((fail + 1))
25}
26
27checkConfigOutput() {
28 local outputContains=$1
29 shift;
30 if evalConfig "$@" 2>/dev/null | grep --silent "$outputContains" ; then
31 pass=$((pass + 1))
32 return 0;
33 else
34 echo 2>&1 "error: Expected result matching '$outputContains', while evaluating"
35 reportFailure "$@"
36 return 1
37 fi
38}
39
40checkConfigError() {
41 local errorContains=$1
42 local err=""
43 shift;
44 if err==$(evalConfig "$@" 2>&1 >/dev/null); then
45 echo 2>&1 "error: Expected error code, got exit code 0, while evaluating"
46 reportFailure "$@"
47 return 1
48 else
49 if echo "$err" | grep --silent "$errorContains" ; then
50 pass=$((pass + 1))
51 return 0;
52 else
53 echo 2>&1 "error: Expected error matching '$errorContains', while evaluating"
54 reportFailure "$@"
55 return 1
56 fi
57 fi
58}
59
60# Check boolean option.
61checkConfigOutput "false" config.enable ./declare-enable.nix
62checkConfigError 'The option .* defined in .* does not exist.' config.enable ./define-enable.nix
63
64# Check integer types.
65# unsigned
66checkConfigOutput "42" config.value ./declare-int-unsigned-value.nix ./define-value-int-positive.nix
67checkConfigError 'The option value .* in .* is not of type.*unsigned integer.*' config.value ./declare-int-unsigned-value.nix ./define-value-int-negative.nix
68# positive
69checkConfigError 'The option value .* in .* is not of type.*positive integer.*' config.value ./declare-int-positive-value.nix ./define-value-int-zero.nix
70# between
71checkConfigOutput "42" config.value ./declare-int-between-value.nix ./define-value-int-positive.nix
72checkConfigError 'The option value .* in .* is not of type.*between.*-21 and 43.*inclusive.*' config.value ./declare-int-between-value.nix ./define-value-int-negative.nix
73
74# Check mkForce without submodules.
75set -- config.enable ./declare-enable.nix ./define-enable.nix
76checkConfigOutput "true" "$@"
77checkConfigOutput "false" "$@" ./define-force-enable.nix
78checkConfigOutput "false" "$@" ./define-enable-force.nix
79
80# Check mkForce with option and submodules.
81checkConfigError 'attribute .*foo.* .* not found' config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix
82checkConfigOutput 'false' config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix
83set -- config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo-enable.nix
84checkConfigOutput 'true' "$@"
85checkConfigOutput 'false' "$@" ./define-force-loaOfSub-foo-enable.nix
86checkConfigOutput 'false' "$@" ./define-loaOfSub-force-foo-enable.nix
87checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-force-enable.nix
88checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-enable-force.nix
89
90# Check overriding effect of mkForce on submodule definitions.
91checkConfigError 'attribute .*bar.* .* not found' config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix
92checkConfigOutput 'false' config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix ./define-loaOfSub-bar.nix
93set -- config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix ./define-loaOfSub-bar-enable.nix
94checkConfigOutput 'true' "$@"
95checkConfigError 'attribute .*bar.* .* not found' "$@" ./define-force-loaOfSub-foo-enable.nix
96checkConfigError 'attribute .*bar.* .* not found' "$@" ./define-loaOfSub-force-foo-enable.nix
97checkConfigOutput 'true' "$@" ./define-loaOfSub-foo-force-enable.nix
98checkConfigOutput 'true' "$@" ./define-loaOfSub-foo-enable-force.nix
99
100# Check mkIf with submodules.
101checkConfigError 'attribute .*foo.* .* not found' config.loaOfSub.foo.enable ./declare-enable.nix ./declare-loaOfSub-any-enable.nix
102set -- config.loaOfSub.foo.enable ./declare-enable.nix ./declare-loaOfSub-any-enable.nix
103checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-if-loaOfSub-foo-enable.nix
104checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-loaOfSub-if-foo-enable.nix
105checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-loaOfSub-foo-if-enable.nix
106checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-enable-if.nix
107checkConfigOutput 'true' "$@" ./define-enable.nix ./define-if-loaOfSub-foo-enable.nix
108checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-if-foo-enable.nix
109checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-foo-if-enable.nix
110checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-foo-enable-if.nix
111
112# Check disabledModules with config definitions and option declarations.
113set -- config.enable ./define-enable.nix ./declare-enable.nix
114checkConfigOutput "true" "$@"
115checkConfigOutput "false" "$@" ./disable-define-enable.nix
116checkConfigError "The option .*enable.* defined in .* does not exist" "$@" ./disable-declare-enable.nix
117checkConfigError "attribute .*enable.* in selection path .*config.enable.* not found" "$@" ./disable-define-enable.nix ./disable-declare-enable.nix
118checkConfigError "attribute .*enable.* in selection path .*config.enable.* not found" "$@" ./disable-enable-modules.nix
119
120# Check _module.args.
121set -- config.enable ./declare-enable.nix ./define-enable-with-custom-arg.nix
122checkConfigError 'while evaluating the module argument .*custom.* in .*define-enable-with-custom-arg.nix.*:' "$@"
123checkConfigOutput "true" "$@" ./define-_module-args-custom.nix
124
125# Check that using _module.args on imports cause infinite recursions, with
126# the proper error context.
127set -- "$@" ./define-_module-args-custom.nix ./import-custom-arg.nix
128checkConfigError 'while evaluating the module argument .*custom.* in .*import-custom-arg.nix.*:' "$@"
129checkConfigError 'infinite recursion encountered' "$@"
130
131# Check _module.check.
132set -- config.enable ./declare-enable.nix ./define-enable.nix ./define-loaOfSub-foo.nix
133checkConfigError 'The option .* defined in .* does not exist.' "$@"
134checkConfigOutput "true" "$@" ./define-module-check.nix
135
136# Check coerced value.
137checkConfigOutput "\"42\"" config.value ./declare-coerced-value.nix
138checkConfigOutput "\"24\"" config.value ./declare-coerced-value.nix ./define-value-string.nix
139checkConfigError 'The option value .* in .* is not.*string or signed integer.*' config.value ./declare-coerced-value.nix ./define-value-list.nix
140
141cat <<EOF
142====== module tests ======
143$pass Pass
144$fail Fail
145EOF
146
147if test $fail -ne 0; then
148 exit 1
149fi
150exit 0