You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

246 lines
13 KiB

  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. # https://stackoverflow.com/a/246128/6605742
  6. DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
  7. cd "$DIR"/modules
  8. pass=0
  9. fail=0
  10. evalConfig() {
  11. local attr=$1
  12. shift;
  13. local script="import ./default.nix { modules = [ $@ ];}"
  14. nix-instantiate --timeout 1 -E "$script" -A "$attr" --eval-only --show-trace --read-write-mode
  15. }
  16. reportFailure() {
  17. local attr=$1
  18. shift;
  19. local script="import ./default.nix { modules = [ $@ ];}"
  20. echo 2>&1 "$ nix-instantiate -E '$script' -A '$attr' --eval-only"
  21. evalConfig "$attr" "$@"
  22. fail=$((fail + 1))
  23. }
  24. checkConfigOutput() {
  25. local outputContains=$1
  26. shift;
  27. if evalConfig "$@" 2>/dev/null | grep --silent "$outputContains" ; then
  28. pass=$((pass + 1))
  29. return 0;
  30. else
  31. echo 2>&1 "error: Expected result matching '$outputContains', while evaluating"
  32. reportFailure "$@"
  33. return 1
  34. fi
  35. }
  36. checkConfigError() {
  37. local errorContains=$1
  38. local err=""
  39. shift;
  40. if err==$(evalConfig "$@" 2>&1 >/dev/null); then
  41. echo 2>&1 "error: Expected error code, got exit code 0, while evaluating"
  42. reportFailure "$@"
  43. return 1
  44. else
  45. if echo "$err" | grep --silent "$errorContains" ; then
  46. pass=$((pass + 1))
  47. return 0;
  48. else
  49. echo 2>&1 "error: Expected error matching '$errorContains', while evaluating"
  50. reportFailure "$@"
  51. return 1
  52. fi
  53. fi
  54. }
  55. # Check boolean option.
  56. checkConfigOutput "false" config.enable ./declare-enable.nix
  57. checkConfigError 'The option .* defined in .* does not exist.' config.enable ./define-enable.nix
  58. # Check integer types.
  59. # unsigned
  60. checkConfigOutput "42" config.value ./declare-int-unsigned-value.nix ./define-value-int-positive.nix
  61. checkConfigError 'The option value .* in .* is not of type.*unsigned integer.*' config.value ./declare-int-unsigned-value.nix ./define-value-int-negative.nix
  62. # positive
  63. checkConfigError 'The option value .* in .* is not of type.*positive integer.*' config.value ./declare-int-positive-value.nix ./define-value-int-zero.nix
  64. # between
  65. checkConfigOutput "42" config.value ./declare-int-between-value.nix ./define-value-int-positive.nix
  66. checkConfigError '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
  67. # Check either types
  68. # types.either
  69. checkConfigOutput "42" config.value ./declare-either.nix ./define-value-int-positive.nix
  70. checkConfigOutput "\"24\"" config.value ./declare-either.nix ./define-value-string.nix
  71. # types.oneOf
  72. checkConfigOutput "42" config.value ./declare-oneOf.nix ./define-value-int-positive.nix
  73. checkConfigOutput "[ ]" config.value ./declare-oneOf.nix ./define-value-list.nix
  74. checkConfigOutput "\"24\"" config.value ./declare-oneOf.nix ./define-value-string.nix
  75. # Check mkForce without submodules.
  76. set -- config.enable ./declare-enable.nix ./define-enable.nix
  77. checkConfigOutput "true" "$@"
  78. checkConfigOutput "false" "$@" ./define-force-enable.nix
  79. checkConfigOutput "false" "$@" ./define-enable-force.nix
  80. # Check mkForce with option and submodules.
  81. checkConfigError 'attribute .*foo.* .* not found' config.attrsOfSub.foo.enable ./declare-attrsOfSub-any-enable.nix
  82. checkConfigOutput 'false' config.attrsOfSub.foo.enable ./declare-attrsOfSub-any-enable.nix ./define-attrsOfSub-foo.nix
  83. set -- config.attrsOfSub.foo.enable ./declare-attrsOfSub-any-enable.nix ./define-attrsOfSub-foo-enable.nix
  84. checkConfigOutput 'true' "$@"
  85. checkConfigOutput 'false' "$@" ./define-force-attrsOfSub-foo-enable.nix
  86. checkConfigOutput 'false' "$@" ./define-attrsOfSub-force-foo-enable.nix
  87. checkConfigOutput 'false' "$@" ./define-attrsOfSub-foo-force-enable.nix
  88. checkConfigOutput 'false' "$@" ./define-attrsOfSub-foo-enable-force.nix
  89. # Check overriding effect of mkForce on submodule definitions.
  90. checkConfigError 'attribute .*bar.* .* not found' config.attrsOfSub.bar.enable ./declare-attrsOfSub-any-enable.nix ./define-attrsOfSub-foo.nix
  91. checkConfigOutput 'false' config.attrsOfSub.bar.enable ./declare-attrsOfSub-any-enable.nix ./define-attrsOfSub-foo.nix ./define-attrsOfSub-bar.nix
  92. set -- config.attrsOfSub.bar.enable ./declare-attrsOfSub-any-enable.nix ./define-attrsOfSub-foo.nix ./define-attrsOfSub-bar-enable.nix
  93. checkConfigOutput 'true' "$@"
  94. checkConfigError 'attribute .*bar.* .* not found' "$@" ./define-force-attrsOfSub-foo-enable.nix
  95. checkConfigError 'attribute .*bar.* .* not found' "$@" ./define-attrsOfSub-force-foo-enable.nix
  96. checkConfigOutput 'true' "$@" ./define-attrsOfSub-foo-force-enable.nix
  97. checkConfigOutput 'true' "$@" ./define-attrsOfSub-foo-enable-force.nix
  98. # Check mkIf with submodules.
  99. checkConfigError 'attribute .*foo.* .* not found' config.attrsOfSub.foo.enable ./declare-enable.nix ./declare-attrsOfSub-any-enable.nix
  100. set -- config.attrsOfSub.foo.enable ./declare-enable.nix ./declare-attrsOfSub-any-enable.nix
  101. checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-if-attrsOfSub-foo-enable.nix
  102. checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-attrsOfSub-if-foo-enable.nix
  103. checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-attrsOfSub-foo-if-enable.nix
  104. checkConfigOutput 'false' "$@" ./define-attrsOfSub-foo-enable-if.nix
  105. checkConfigOutput 'true' "$@" ./define-enable.nix ./define-if-attrsOfSub-foo-enable.nix
  106. checkConfigOutput 'true' "$@" ./define-enable.nix ./define-attrsOfSub-if-foo-enable.nix
  107. checkConfigOutput 'true' "$@" ./define-enable.nix ./define-attrsOfSub-foo-if-enable.nix
  108. checkConfigOutput 'true' "$@" ./define-enable.nix ./define-attrsOfSub-foo-enable-if.nix
  109. # Check disabledModules with config definitions and option declarations.
  110. set -- config.enable ./define-enable.nix ./declare-enable.nix
  111. checkConfigOutput "true" "$@"
  112. checkConfigOutput "false" "$@" ./disable-define-enable.nix
  113. checkConfigError "The option .*enable.* defined in .* does not exist" "$@" ./disable-declare-enable.nix
  114. checkConfigError "attribute .*enable.* in selection path .*config.enable.* not found" "$@" ./disable-define-enable.nix ./disable-declare-enable.nix
  115. checkConfigError "attribute .*enable.* in selection path .*config.enable.* not found" "$@" ./disable-enable-modules.nix
  116. # Check _module.args.
  117. set -- config.enable ./declare-enable.nix ./define-enable-with-custom-arg.nix
  118. checkConfigError 'while evaluating the module argument .*custom.* in .*define-enable-with-custom-arg.nix.*:' "$@"
  119. checkConfigOutput "true" "$@" ./define-_module-args-custom.nix
  120. # Check that using _module.args on imports cause infinite recursions, with
  121. # the proper error context.
  122. set -- "$@" ./define-_module-args-custom.nix ./import-custom-arg.nix
  123. checkConfigError 'while evaluating the module argument .*custom.* in .*import-custom-arg.nix.*:' "$@"
  124. checkConfigError 'infinite recursion encountered' "$@"
  125. # Check _module.check.
  126. set -- config.enable ./declare-enable.nix ./define-enable.nix ./define-attrsOfSub-foo.nix
  127. checkConfigError 'The option .* defined in .* does not exist.' "$@"
  128. checkConfigOutput "true" "$@" ./define-module-check.nix
  129. # Check coerced value.
  130. checkConfigOutput "\"42\"" config.value ./declare-coerced-value.nix
  131. checkConfigOutput "\"24\"" config.value ./declare-coerced-value.nix ./define-value-string.nix
  132. checkConfigError 'The option value .* in .* is not.*string or signed integer convertible to it' config.value ./declare-coerced-value.nix ./define-value-list.nix
  133. # Check coerced value with unsound coercion
  134. checkConfigOutput "12" config.value ./declare-coerced-value-unsound.nix
  135. checkConfigError 'The option value .* in .* is not.*8 bit signed integer.* or string convertible to it' config.value ./declare-coerced-value-unsound.nix ./define-value-string-bigint.nix
  136. checkConfigError 'unrecognised JSON value' config.value ./declare-coerced-value-unsound.nix ./define-value-string-arbitrary.nix
  137. # Check mkAliasOptionModule.
  138. checkConfigOutput "true" config.enable ./alias-with-priority.nix
  139. checkConfigOutput "true" config.enableAlias ./alias-with-priority.nix
  140. checkConfigOutput "false" config.enable ./alias-with-priority-can-override.nix
  141. checkConfigOutput "false" config.enableAlias ./alias-with-priority-can-override.nix
  142. # submoduleWith
  143. ## specialArgs should work
  144. checkConfigOutput "foo" config.submodule.foo ./declare-submoduleWith-special.nix
  145. ## shorthandOnlyDefines config behaves as expected
  146. checkConfigOutput "true" config.submodule.config ./declare-submoduleWith-shorthand.nix ./define-submoduleWith-shorthand.nix
  147. checkConfigError 'is not of type `boolean' config.submodule.config ./declare-submoduleWith-shorthand.nix ./define-submoduleWith-noshorthand.nix
  148. checkConfigError 'value is a boolean while a set was expected' config.submodule.config ./declare-submoduleWith-noshorthand.nix ./define-submoduleWith-shorthand.nix
  149. checkConfigOutput "true" config.submodule.config ./declare-submoduleWith-noshorthand.nix ./define-submoduleWith-noshorthand.nix
  150. ## submoduleWith should merge all modules in one swoop
  151. checkConfigOutput "true" config.submodule.inner ./declare-submoduleWith-modules.nix
  152. checkConfigOutput "true" config.submodule.outer ./declare-submoduleWith-modules.nix
  153. ## Paths should be allowed as values and work as expected
  154. checkConfigOutput "true" config.submodule.enable ./declare-submoduleWith-path.nix
  155. # Check that disabledModules works recursively and correctly
  156. checkConfigOutput "true" config.enable ./disable-recursive/main.nix
  157. checkConfigOutput "true" config.enable ./disable-recursive/{main.nix,disable-foo.nix}
  158. checkConfigOutput "true" config.enable ./disable-recursive/{main.nix,disable-bar.nix}
  159. checkConfigError 'The option .* defined in .* does not exist' config.enable ./disable-recursive/{main.nix,disable-foo.nix,disable-bar.nix}
  160. # Check that imports can depend on derivations
  161. checkConfigOutput "true" config.enable ./import-from-store.nix
  162. # Check that configs can be conditional on option existence
  163. checkConfigOutput true config.enable ./define-option-dependently.nix ./declare-enable.nix ./declare-int-positive-value.nix
  164. checkConfigOutput 360 config.value ./define-option-dependently.nix ./declare-enable.nix ./declare-int-positive-value.nix
  165. checkConfigOutput 7 config.value ./define-option-dependently.nix ./declare-int-positive-value.nix
  166. checkConfigOutput true config.set.enable ./define-option-dependently-nested.nix ./declare-enable-nested.nix ./declare-int-positive-value-nested.nix
  167. checkConfigOutput 360 config.set.value ./define-option-dependently-nested.nix ./declare-enable-nested.nix ./declare-int-positive-value-nested.nix
  168. checkConfigOutput 7 config.set.value ./define-option-dependently-nested.nix ./declare-int-positive-value-nested.nix
  169. # Check attrsOf and lazyAttrsOf. Only lazyAttrsOf should be lazy, and only
  170. # attrsOf should work with conditional definitions
  171. # In addition, lazyAttrsOf should honor an options emptyValue
  172. checkConfigError "is not lazy" config.isLazy ./declare-attrsOf.nix ./attrsOf-lazy-check.nix
  173. checkConfigOutput "true" config.isLazy ./declare-lazyAttrsOf.nix ./attrsOf-lazy-check.nix
  174. checkConfigOutput "true" config.conditionalWorks ./declare-attrsOf.nix ./attrsOf-conditional-check.nix
  175. checkConfigOutput "false" config.conditionalWorks ./declare-lazyAttrsOf.nix ./attrsOf-conditional-check.nix
  176. checkConfigOutput "empty" config.value.foo ./declare-lazyAttrsOf.nix ./attrsOf-conditional-check.nix
  177. # Even with multiple assignments, a type error should be thrown if any of them aren't valid
  178. checkConfigError 'The option value .* in .* is not of type .*' \
  179. config.value ./declare-int-unsigned-value.nix ./define-value-list.nix ./define-value-int-positive.nix
  180. ## Freeform modules
  181. # Assigning without a declared option should work
  182. checkConfigOutput 24 config.value ./freeform-attrsOf.nix ./define-value-string.nix
  183. # No freeform assigments shouldn't make it error
  184. checkConfigOutput '{ }' config ./freeform-attrsOf.nix
  185. # but only if the type matches
  186. checkConfigError 'The option value .* in .* is not of type .*' config.value ./freeform-attrsOf.nix ./define-value-list.nix
  187. # and properties should be applied
  188. checkConfigOutput yes config.value ./freeform-attrsOf.nix ./define-value-string-properties.nix
  189. # Options should still be declarable, and be able to have a type that doesn't match the freeform type
  190. checkConfigOutput false config.enable ./freeform-attrsOf.nix ./define-value-string.nix ./declare-enable.nix
  191. checkConfigOutput 24 config.value ./freeform-attrsOf.nix ./define-value-string.nix ./declare-enable.nix
  192. # and this should work too with nested values
  193. checkConfigOutput false config.nest.foo ./freeform-attrsOf.nix ./freeform-nested.nix
  194. checkConfigOutput bar config.nest.bar ./freeform-attrsOf.nix ./freeform-nested.nix
  195. # Check whether a declared option can depend on an freeform-typed one
  196. checkConfigOutput null config.foo ./freeform-attrsOf.nix ./freeform-str-dep-unstr.nix
  197. checkConfigOutput 24 config.foo ./freeform-attrsOf.nix ./freeform-str-dep-unstr.nix ./define-value-string.nix
  198. # Check whether an freeform-typed value can depend on a declared option, this can only work with lazyAttrsOf
  199. checkConfigError 'infinite recursion encountered' config.foo ./freeform-attrsOf.nix ./freeform-unstr-dep-str.nix
  200. checkConfigError 'The option .* is used but not defined' config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix
  201. checkConfigOutput 24 config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix ./define-value-string.nix
  202. cat <<EOF
  203. ====== module tests ======
  204. $pass Pass
  205. $fail Fail
  206. EOF
  207. if test $fail -ne 0; then
  208. exit 1
  209. fi
  210. exit 0