diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-03 19:28:01 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-03 19:28:01 -0400 |
| commit | 147a89bc71e7db40f011454a40add7ff2d10f8d8 (patch) | |
| tree | 72f2f1355c6121c40124206c7d4ac82632f1690d /scripts/kconfig/tests | |
| parent | 3b24b83763e72a6c1e728100104fd99aa83a7b3b (diff) | |
| parent | 18492685e479fd4d8e1dca836f57c11b6800f083 (diff) | |
Merge tag 'kconfig-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild
Pull Kconfig updates from Masahiro Yamada:
- improve checkpatch for more precise Kconfig code checking
- clarify effective selects by grouping reverse dependencies in help
- do not write out '# CONFIG_FOO is not set' from invisible symbols
- make oldconfig as silent as it should be
- rename 'silentoldconfig' to 'syncconfig'
- add unit-test framework and several test cases
- warn unmet dependency of tristate symbols
- make unmet dependency warnings readable, removing false positives
- improve recursive include detection
- use yylineno to simplify the line number tracking
- misc cleanups
* tag 'kconfig-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (30 commits)
kconfig: use yylineno option instead of manual lineno increments
kconfig: detect recursive inclusion earlier
kconfig: remove duplicated file name and lineno of recursive inclusion
kconfig: do not include both curses.h and ncurses.h for nconfig
kconfig: make unmet dependency warnings readable
kconfig: warn unmet direct dependency of tristate symbols selected by y
kconfig: tests: test if recursive inclusion is detected
kconfig: tests: test if recursive dependencies are detected
kconfig: tests: test randconfig for choice in choice
kconfig: tests: test defconfig when two choices interact
kconfig: tests: check visibility of tristate choice values in y choice
kconfig: tests: check unneeded "is not set" with unmet dependency
kconfig: tests: test if new symbols in choice are asked
kconfig: tests: test automatic submenu creation
kconfig: tests: add basic choice tests
kconfig: tests: add framework for Kconfig unit testing
kbuild: add PYTHON2 and PYTHON3 variables
kconfig: remove redundant streamline_config.pl prerequisite
kconfig: rename silentoldconfig to syncconfig
kconfig: invoke oldconfig instead of silentoldconfig from local*config
...
Diffstat (limited to 'scripts/kconfig/tests')
45 files changed, 893 insertions, 0 deletions
diff --git a/scripts/kconfig/tests/auto_submenu/Kconfig b/scripts/kconfig/tests/auto_submenu/Kconfig new file mode 100644 index 000000000000..c17bf2caa7e6 --- /dev/null +++ b/scripts/kconfig/tests/auto_submenu/Kconfig | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | config A | ||
| 2 | bool "A" | ||
| 3 | default y | ||
| 4 | |||
| 5 | config A0 | ||
| 6 | bool "A0" | ||
| 7 | depends on A | ||
| 8 | default y | ||
| 9 | help | ||
| 10 | This depends on A, so should be a submenu of A. | ||
| 11 | |||
| 12 | config A0_0 | ||
| 13 | bool "A1_0" | ||
| 14 | depends on A0 | ||
| 15 | help | ||
| 16 | Submenus are created recursively. | ||
| 17 | This should be a submenu of A0. | ||
| 18 | |||
| 19 | config A1 | ||
| 20 | bool "A1" | ||
| 21 | depends on A | ||
| 22 | default y | ||
| 23 | help | ||
| 24 | This should line up with A0. | ||
| 25 | |||
| 26 | choice | ||
| 27 | prompt "choice" | ||
| 28 | depends on A1 | ||
| 29 | help | ||
| 30 | Choice should become a submenu as well. | ||
| 31 | |||
| 32 | config A1_0 | ||
| 33 | bool "A1_0" | ||
| 34 | |||
| 35 | config A1_1 | ||
| 36 | bool "A1_1" | ||
| 37 | |||
| 38 | endchoice | ||
| 39 | |||
| 40 | config B | ||
| 41 | bool "B" | ||
| 42 | help | ||
| 43 | This is independent of A. | ||
| 44 | |||
| 45 | config C | ||
| 46 | bool "C" | ||
| 47 | depends on A | ||
| 48 | help | ||
| 49 | This depends on A, but not a consecutive item, so can/should not | ||
| 50 | be a submenu. | ||
diff --git a/scripts/kconfig/tests/auto_submenu/__init__.py b/scripts/kconfig/tests/auto_submenu/__init__.py new file mode 100644 index 000000000000..32e79b85faeb --- /dev/null +++ b/scripts/kconfig/tests/auto_submenu/__init__.py | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | """ | ||
| 2 | Create submenu for symbols that depend on the preceding one. | ||
| 3 | |||
| 4 | If a symbols has dependency on the preceding symbol, the menu entry | ||
| 5 | should become the submenu of the preceding one, and displayed with | ||
| 6 | deeper indentation. | ||
| 7 | """ | ||
| 8 | |||
| 9 | |||
| 10 | def test(conf): | ||
| 11 | assert conf.oldaskconfig() == 0 | ||
| 12 | assert conf.stdout_contains('expected_stdout') | ||
diff --git a/scripts/kconfig/tests/auto_submenu/expected_stdout b/scripts/kconfig/tests/auto_submenu/expected_stdout new file mode 100644 index 000000000000..bf5236f39a56 --- /dev/null +++ b/scripts/kconfig/tests/auto_submenu/expected_stdout | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | A (A) [Y/n/?] (NEW) | ||
| 2 | A0 (A0) [Y/n/?] (NEW) | ||
| 3 | A1_0 (A0_0) [N/y/?] (NEW) | ||
| 4 | A1 (A1) [Y/n/?] (NEW) | ||
| 5 | choice | ||
| 6 | > 1. A1_0 (A1_0) (NEW) | ||
| 7 | 2. A1_1 (A1_1) (NEW) | ||
| 8 | choice[1-2?]: | ||
| 9 | B (B) [N/y/?] (NEW) | ||
| 10 | C (C) [N/y/?] (NEW) | ||
diff --git a/scripts/kconfig/tests/choice/Kconfig b/scripts/kconfig/tests/choice/Kconfig new file mode 100644 index 000000000000..cc60e9ce2c03 --- /dev/null +++ b/scripts/kconfig/tests/choice/Kconfig | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | config MODULES | ||
| 2 | bool "Enable loadable module support" | ||
| 3 | option modules | ||
| 4 | default y | ||
| 5 | |||
| 6 | choice | ||
| 7 | prompt "boolean choice" | ||
| 8 | default BOOL_CHOICE1 | ||
| 9 | |||
| 10 | config BOOL_CHOICE0 | ||
| 11 | bool "choice 0" | ||
| 12 | |||
| 13 | config BOOL_CHOICE1 | ||
| 14 | bool "choice 1" | ||
| 15 | |||
| 16 | endchoice | ||
| 17 | |||
| 18 | choice | ||
| 19 | prompt "optional boolean choice" | ||
| 20 | optional | ||
| 21 | default OPT_BOOL_CHOICE1 | ||
| 22 | |||
| 23 | config OPT_BOOL_CHOICE0 | ||
| 24 | bool "choice 0" | ||
| 25 | |||
| 26 | config OPT_BOOL_CHOICE1 | ||
| 27 | bool "choice 1" | ||
| 28 | |||
| 29 | endchoice | ||
| 30 | |||
| 31 | choice | ||
| 32 | prompt "tristate choice" | ||
| 33 | default TRI_CHOICE1 | ||
| 34 | |||
| 35 | config TRI_CHOICE0 | ||
| 36 | tristate "choice 0" | ||
| 37 | |||
| 38 | config TRI_CHOICE1 | ||
| 39 | tristate "choice 1" | ||
| 40 | |||
| 41 | endchoice | ||
| 42 | |||
| 43 | choice | ||
| 44 | prompt "optional tristate choice" | ||
| 45 | optional | ||
| 46 | default OPT_TRI_CHOICE1 | ||
| 47 | |||
| 48 | config OPT_TRI_CHOICE0 | ||
| 49 | tristate "choice 0" | ||
| 50 | |||
| 51 | config OPT_TRI_CHOICE1 | ||
| 52 | tristate "choice 1" | ||
| 53 | |||
| 54 | endchoice | ||
diff --git a/scripts/kconfig/tests/choice/__init__.py b/scripts/kconfig/tests/choice/__init__.py new file mode 100644 index 000000000000..9edcc5262134 --- /dev/null +++ b/scripts/kconfig/tests/choice/__init__.py | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | """ | ||
| 2 | Basic choice tests. | ||
| 3 | |||
| 4 | The handling of 'choice' is a bit complicated part in Kconfig. | ||
| 5 | |||
| 6 | The behavior of 'y' choice is intuitive. If choice values are tristate, | ||
| 7 | the choice can be 'm' where each value can be enabled independently. | ||
| 8 | Also, if a choice is marked as 'optional', the whole choice can be | ||
| 9 | invisible. | ||
| 10 | """ | ||
| 11 | |||
| 12 | |||
| 13 | def test_oldask0(conf): | ||
| 14 | assert conf.oldaskconfig() == 0 | ||
| 15 | assert conf.stdout_contains('oldask0_expected_stdout') | ||
| 16 | |||
| 17 | |||
| 18 | def test_oldask1(conf): | ||
| 19 | assert conf.oldaskconfig('oldask1_config') == 0 | ||
| 20 | assert conf.stdout_contains('oldask1_expected_stdout') | ||
| 21 | |||
| 22 | |||
| 23 | def test_allyes(conf): | ||
| 24 | assert conf.allyesconfig() == 0 | ||
| 25 | assert conf.config_contains('allyes_expected_config') | ||
| 26 | |||
| 27 | |||
| 28 | def test_allmod(conf): | ||
| 29 | assert conf.allmodconfig() == 0 | ||
| 30 | assert conf.config_contains('allmod_expected_config') | ||
| 31 | |||
| 32 | |||
| 33 | def test_allno(conf): | ||
| 34 | assert conf.allnoconfig() == 0 | ||
| 35 | assert conf.config_contains('allno_expected_config') | ||
| 36 | |||
| 37 | |||
| 38 | def test_alldef(conf): | ||
| 39 | assert conf.alldefconfig() == 0 | ||
| 40 | assert conf.config_contains('alldef_expected_config') | ||
diff --git a/scripts/kconfig/tests/choice/alldef_expected_config b/scripts/kconfig/tests/choice/alldef_expected_config new file mode 100644 index 000000000000..7a754bf4be94 --- /dev/null +++ b/scripts/kconfig/tests/choice/alldef_expected_config | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | CONFIG_MODULES=y | ||
| 2 | # CONFIG_BOOL_CHOICE0 is not set | ||
| 3 | CONFIG_BOOL_CHOICE1=y | ||
| 4 | # CONFIG_TRI_CHOICE0 is not set | ||
| 5 | # CONFIG_TRI_CHOICE1 is not set | ||
diff --git a/scripts/kconfig/tests/choice/allmod_expected_config b/scripts/kconfig/tests/choice/allmod_expected_config new file mode 100644 index 000000000000..f1f5dcdb7923 --- /dev/null +++ b/scripts/kconfig/tests/choice/allmod_expected_config | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | CONFIG_MODULES=y | ||
| 2 | # CONFIG_BOOL_CHOICE0 is not set | ||
| 3 | CONFIG_BOOL_CHOICE1=y | ||
| 4 | # CONFIG_OPT_BOOL_CHOICE0 is not set | ||
| 5 | CONFIG_OPT_BOOL_CHOICE1=y | ||
| 6 | CONFIG_TRI_CHOICE0=m | ||
| 7 | CONFIG_TRI_CHOICE1=m | ||
| 8 | CONFIG_OPT_TRI_CHOICE0=m | ||
| 9 | CONFIG_OPT_TRI_CHOICE1=m | ||
diff --git a/scripts/kconfig/tests/choice/allno_expected_config b/scripts/kconfig/tests/choice/allno_expected_config new file mode 100644 index 000000000000..b88ee7a43136 --- /dev/null +++ b/scripts/kconfig/tests/choice/allno_expected_config | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # CONFIG_MODULES is not set | ||
| 2 | # CONFIG_BOOL_CHOICE0 is not set | ||
| 3 | CONFIG_BOOL_CHOICE1=y | ||
| 4 | # CONFIG_TRI_CHOICE0 is not set | ||
| 5 | CONFIG_TRI_CHOICE1=y | ||
diff --git a/scripts/kconfig/tests/choice/allyes_expected_config b/scripts/kconfig/tests/choice/allyes_expected_config new file mode 100644 index 000000000000..e5a062a1157c --- /dev/null +++ b/scripts/kconfig/tests/choice/allyes_expected_config | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | CONFIG_MODULES=y | ||
| 2 | # CONFIG_BOOL_CHOICE0 is not set | ||
| 3 | CONFIG_BOOL_CHOICE1=y | ||
| 4 | # CONFIG_OPT_BOOL_CHOICE0 is not set | ||
| 5 | CONFIG_OPT_BOOL_CHOICE1=y | ||
| 6 | # CONFIG_TRI_CHOICE0 is not set | ||
| 7 | CONFIG_TRI_CHOICE1=y | ||
| 8 | # CONFIG_OPT_TRI_CHOICE0 is not set | ||
| 9 | CONFIG_OPT_TRI_CHOICE1=y | ||
diff --git a/scripts/kconfig/tests/choice/oldask0_expected_stdout b/scripts/kconfig/tests/choice/oldask0_expected_stdout new file mode 100644 index 000000000000..b251bba9698b --- /dev/null +++ b/scripts/kconfig/tests/choice/oldask0_expected_stdout | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | Enable loadable module support (MODULES) [Y/n/?] (NEW) | ||
| 2 | boolean choice | ||
| 3 | 1. choice 0 (BOOL_CHOICE0) (NEW) | ||
| 4 | > 2. choice 1 (BOOL_CHOICE1) (NEW) | ||
| 5 | choice[1-2?]: | ||
| 6 | optional boolean choice [N/y/?] (NEW) | ||
| 7 | tristate choice [M/y/?] (NEW) | ||
| 8 | choice 0 (TRI_CHOICE0) [N/m/?] (NEW) | ||
| 9 | choice 1 (TRI_CHOICE1) [N/m/?] (NEW) | ||
| 10 | optional tristate choice [N/m/y/?] (NEW) | ||
diff --git a/scripts/kconfig/tests/choice/oldask1_config b/scripts/kconfig/tests/choice/oldask1_config new file mode 100644 index 000000000000..b67bfe3c641f --- /dev/null +++ b/scripts/kconfig/tests/choice/oldask1_config | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | # CONFIG_MODULES is not set | ||
| 2 | CONFIG_OPT_BOOL_CHOICE0=y | ||
diff --git a/scripts/kconfig/tests/choice/oldask1_expected_stdout b/scripts/kconfig/tests/choice/oldask1_expected_stdout new file mode 100644 index 000000000000..c2125e9bf96a --- /dev/null +++ b/scripts/kconfig/tests/choice/oldask1_expected_stdout | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | Enable loadable module support (MODULES) [N/y/?] | ||
| 2 | boolean choice | ||
| 3 | 1. choice 0 (BOOL_CHOICE0) (NEW) | ||
| 4 | > 2. choice 1 (BOOL_CHOICE1) (NEW) | ||
| 5 | choice[1-2?]: | ||
| 6 | optional boolean choice [Y/n/?] (NEW) | ||
| 7 | optional boolean choice | ||
| 8 | > 1. choice 0 (OPT_BOOL_CHOICE0) | ||
| 9 | 2. choice 1 (OPT_BOOL_CHOICE1) (NEW) | ||
| 10 | choice[1-2?]: | ||
| 11 | tristate choice | ||
| 12 | 1. choice 0 (TRI_CHOICE0) (NEW) | ||
| 13 | > 2. choice 1 (TRI_CHOICE1) (NEW) | ||
| 14 | choice[1-2?]: | ||
| 15 | optional tristate choice [N/y/?] | ||
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig new file mode 100644 index 000000000000..11ac25c26040 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | config MODULES | ||
| 2 | def_bool y | ||
| 3 | option modules | ||
| 4 | |||
| 5 | config DEP | ||
| 6 | tristate | ||
| 7 | default m | ||
| 8 | |||
| 9 | choice | ||
| 10 | prompt "Tristate Choice" | ||
| 11 | |||
| 12 | config CHOICE0 | ||
| 13 | tristate "Choice 0" | ||
| 14 | |||
| 15 | config CHOICE1 | ||
| 16 | tristate "Choice 1" | ||
| 17 | depends on DEP | ||
| 18 | |||
| 19 | endchoice | ||
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py new file mode 100644 index 000000000000..f8d728c7b101 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | """ | ||
| 2 | Hide tristate choice values with mod dependency in y choice. | ||
| 3 | |||
| 4 | If tristate choice values depend on symbols set to 'm', they should be | ||
| 5 | hidden when the choice containing them is changed from 'm' to 'y' | ||
| 6 | (i.e. exclusive choice). | ||
| 7 | |||
| 8 | Related Linux commit: fa64e5f6a35efd5e77d639125d973077ca506074 | ||
| 9 | """ | ||
| 10 | |||
| 11 | |||
| 12 | def test(conf): | ||
| 13 | assert conf.oldaskconfig('config', 'y') == 0 | ||
| 14 | assert conf.config_contains('expected_config') | ||
| 15 | assert conf.stdout_contains('expected_stdout') | ||
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/config b/scripts/kconfig/tests/choice_value_with_m_dep/config new file mode 100644 index 000000000000..3a126b7a2546 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/config | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | CONFIG_CHOICE0=m | ||
| 2 | CONFIG_CHOICE1=m | ||
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/expected_config b/scripts/kconfig/tests/choice_value_with_m_dep/expected_config new file mode 100644 index 000000000000..4d07b449540e --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/expected_config | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | CONFIG_MODULES=y | ||
| 2 | CONFIG_DEP=m | ||
| 3 | CONFIG_CHOICE0=y | ||
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout b/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout new file mode 100644 index 000000000000..2b50ab65c86a --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | Tristate Choice [M/y/?] y | ||
| 2 | Tristate Choice | ||
| 3 | > 1. Choice 0 (CHOICE0) | ||
| 4 | choice[1]: 1 | ||
diff --git a/scripts/kconfig/tests/conftest.py b/scripts/kconfig/tests/conftest.py new file mode 100644 index 000000000000..0345ef6e3273 --- /dev/null +++ b/scripts/kconfig/tests/conftest.py | |||
| @@ -0,0 +1,291 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | # | ||
| 3 | # Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com> | ||
| 4 | # | ||
| 5 | |||
| 6 | """ | ||
| 7 | Kconfig unit testing framework. | ||
| 8 | |||
| 9 | This provides fixture functions commonly used from test files. | ||
| 10 | """ | ||
| 11 | |||
| 12 | import os | ||
| 13 | import pytest | ||
| 14 | import shutil | ||
| 15 | import subprocess | ||
| 16 | import tempfile | ||
| 17 | |||
| 18 | CONF_PATH = os.path.abspath(os.path.join('scripts', 'kconfig', 'conf')) | ||
| 19 | |||
| 20 | |||
| 21 | class Conf: | ||
| 22 | """Kconfig runner and result checker. | ||
| 23 | |||
| 24 | This class provides methods to run text-based interface of Kconfig | ||
| 25 | (scripts/kconfig/conf) and retrieve the resulted configuration, | ||
| 26 | stdout, and stderr. It also provides methods to compare those | ||
| 27 | results with expectations. | ||
| 28 | """ | ||
| 29 | |||
| 30 | def __init__(self, request): | ||
| 31 | """Create a new Conf instance. | ||
| 32 | |||
| 33 | request: object to introspect the requesting test module | ||
| 34 | """ | ||
| 35 | # the directory of the test being run | ||
| 36 | self._test_dir = os.path.dirname(str(request.fspath)) | ||
| 37 | |||
| 38 | # runners | ||
| 39 | def _run_conf(self, mode, dot_config=None, out_file='.config', | ||
| 40 | interactive=False, in_keys=None, extra_env={}): | ||
| 41 | """Run text-based Kconfig executable and save the result. | ||
| 42 | |||
| 43 | mode: input mode option (--oldaskconfig, --defconfig=<file> etc.) | ||
| 44 | dot_config: .config file to use for configuration base | ||
| 45 | out_file: file name to contain the output config data | ||
| 46 | interactive: flag to specify the interactive mode | ||
| 47 | in_keys: key inputs for interactive modes | ||
| 48 | extra_env: additional environments | ||
| 49 | returncode: exit status of the Kconfig executable | ||
| 50 | """ | ||
| 51 | command = [CONF_PATH, mode, 'Kconfig'] | ||
| 52 | |||
| 53 | # Override 'srctree' environment to make the test as the top directory | ||
| 54 | extra_env['srctree'] = self._test_dir | ||
| 55 | |||
| 56 | # Run Kconfig in a temporary directory. | ||
| 57 | # This directory is automatically removed when done. | ||
| 58 | with tempfile.TemporaryDirectory() as temp_dir: | ||
| 59 | |||
| 60 | # if .config is given, copy it to the working directory | ||
| 61 | if dot_config: | ||
| 62 | shutil.copyfile(os.path.join(self._test_dir, dot_config), | ||
| 63 | os.path.join(temp_dir, '.config')) | ||
| 64 | |||
| 65 | ps = subprocess.Popen(command, | ||
| 66 | stdin=subprocess.PIPE, | ||
| 67 | stdout=subprocess.PIPE, | ||
| 68 | stderr=subprocess.PIPE, | ||
| 69 | cwd=temp_dir, | ||
| 70 | env=dict(os.environ, **extra_env)) | ||
| 71 | |||
| 72 | # If input key sequence is given, feed it to stdin. | ||
| 73 | if in_keys: | ||
| 74 | ps.stdin.write(in_keys.encode('utf-8')) | ||
| 75 | |||
| 76 | while ps.poll() is None: | ||
| 77 | # For interactive modes such as oldaskconfig, oldconfig, | ||
| 78 | # send 'Enter' key until the program finishes. | ||
| 79 | if interactive: | ||
| 80 | ps.stdin.write(b'\n') | ||
| 81 | |||
| 82 | self.retcode = ps.returncode | ||
| 83 | self.stdout = ps.stdout.read().decode() | ||
| 84 | self.stderr = ps.stderr.read().decode() | ||
| 85 | |||
| 86 | # Retrieve the resulted config data only when .config is supposed | ||
| 87 | # to exist. If the command fails, the .config does not exist. | ||
| 88 | # 'listnewconfig' does not produce .config in the first place. | ||
| 89 | if self.retcode == 0 and out_file: | ||
| 90 | with open(os.path.join(temp_dir, out_file)) as f: | ||
| 91 | self.config = f.read() | ||
| 92 | else: | ||
| 93 | self.config = None | ||
| 94 | |||
| 95 | # Logging: | ||
| 96 | # Pytest captures the following information by default. In failure | ||
| 97 | # of tests, the captured log will be displayed. This will be useful to | ||
| 98 | # figure out what has happened. | ||
| 99 | |||
| 100 | print("[command]\n{}\n".format(' '.join(command))) | ||
| 101 | |||
| 102 | print("[retcode]\n{}\n".format(self.retcode)) | ||
| 103 | |||
| 104 | print("[stdout]") | ||
| 105 | print(self.stdout) | ||
| 106 | |||
| 107 | print("[stderr]") | ||
| 108 | print(self.stderr) | ||
| 109 | |||
| 110 | if self.config is not None: | ||
| 111 | print("[output for '{}']".format(out_file)) | ||
| 112 | print(self.config) | ||
| 113 | |||
| 114 | return self.retcode | ||
| 115 | |||
| 116 | def oldaskconfig(self, dot_config=None, in_keys=None): | ||
| 117 | """Run oldaskconfig. | ||
| 118 | |||
| 119 | dot_config: .config file to use for configuration base (optional) | ||
| 120 | in_key: key inputs (optional) | ||
| 121 | returncode: exit status of the Kconfig executable | ||
| 122 | """ | ||
| 123 | return self._run_conf('--oldaskconfig', dot_config=dot_config, | ||
| 124 | interactive=True, in_keys=in_keys) | ||
| 125 | |||
| 126 | def oldconfig(self, dot_config=None, in_keys=None): | ||
| 127 | """Run oldconfig. | ||
| 128 | |||
| 129 | dot_config: .config file to use for configuration base (optional) | ||
| 130 | in_key: key inputs (optional) | ||
| 131 | returncode: exit status of the Kconfig executable | ||
| 132 | """ | ||
| 133 | return self._run_conf('--oldconfig', dot_config=dot_config, | ||
| 134 | interactive=True, in_keys=in_keys) | ||
| 135 | |||
| 136 | def olddefconfig(self, dot_config=None): | ||
| 137 | """Run olddefconfig. | ||
| 138 | |||
| 139 | dot_config: .config file to use for configuration base (optional) | ||
| 140 | returncode: exit status of the Kconfig executable | ||
| 141 | """ | ||
| 142 | return self._run_conf('--olddefconfig', dot_config=dot_config) | ||
| 143 | |||
| 144 | def defconfig(self, defconfig): | ||
| 145 | """Run defconfig. | ||
| 146 | |||
| 147 | defconfig: defconfig file for input | ||
| 148 | returncode: exit status of the Kconfig executable | ||
| 149 | """ | ||
| 150 | defconfig_path = os.path.join(self._test_dir, defconfig) | ||
| 151 | return self._run_conf('--defconfig={}'.format(defconfig_path)) | ||
| 152 | |||
| 153 | def _allconfig(self, mode, all_config): | ||
| 154 | if all_config: | ||
| 155 | all_config_path = os.path.join(self._test_dir, all_config) | ||
| 156 | extra_env = {'KCONFIG_ALLCONFIG': all_config_path} | ||
| 157 | else: | ||
| 158 | extra_env = {} | ||
| 159 | |||
| 160 | return self._run_conf('--{}config'.format(mode), extra_env=extra_env) | ||
| 161 | |||
| 162 | def allyesconfig(self, all_config=None): | ||
| 163 | """Run allyesconfig. | ||
| 164 | |||
| 165 | all_config: fragment config file for KCONFIG_ALLCONFIG (optional) | ||
| 166 | returncode: exit status of the Kconfig executable | ||
| 167 | """ | ||
| 168 | return self._allconfig('allyes', all_config) | ||
| 169 | |||
| 170 | def allmodconfig(self, all_config=None): | ||
| 171 | """Run allmodconfig. | ||
| 172 | |||
| 173 | all_config: fragment config file for KCONFIG_ALLCONFIG (optional) | ||
| 174 | returncode: exit status of the Kconfig executable | ||
| 175 | """ | ||
| 176 | return self._allconfig('allmod', all_config) | ||
| 177 | |||
| 178 | def allnoconfig(self, all_config=None): | ||
| 179 | """Run allnoconfig. | ||
| 180 | |||
| 181 | all_config: fragment config file for KCONFIG_ALLCONFIG (optional) | ||
| 182 | returncode: exit status of the Kconfig executable | ||
| 183 | """ | ||
| 184 | return self._allconfig('allno', all_config) | ||
| 185 | |||
| 186 | def alldefconfig(self, all_config=None): | ||
| 187 | """Run alldefconfig. | ||
| 188 | |||
| 189 | all_config: fragment config file for KCONFIG_ALLCONFIG (optional) | ||
| 190 | returncode: exit status of the Kconfig executable | ||
| 191 | """ | ||
| 192 | return self._allconfig('alldef', all_config) | ||
| 193 | |||
| 194 | def randconfig(self, all_config=None): | ||
| 195 | """Run randconfig. | ||
| 196 | |||
| 197 | all_config: fragment config file for KCONFIG_ALLCONFIG (optional) | ||
| 198 | returncode: exit status of the Kconfig executable | ||
| 199 | """ | ||
| 200 | return self._allconfig('rand', all_config) | ||
| 201 | |||
| 202 | def savedefconfig(self, dot_config): | ||
| 203 | """Run savedefconfig. | ||
| 204 | |||
| 205 | dot_config: .config file for input | ||
| 206 | returncode: exit status of the Kconfig executable | ||
| 207 | """ | ||
| 208 | return self._run_conf('--savedefconfig', out_file='defconfig') | ||
| 209 | |||
| 210 | def listnewconfig(self, dot_config=None): | ||
| 211 | """Run listnewconfig. | ||
| 212 | |||
| 213 | dot_config: .config file to use for configuration base (optional) | ||
| 214 | returncode: exit status of the Kconfig executable | ||
| 215 | """ | ||
| 216 | return self._run_conf('--listnewconfig', dot_config=dot_config, | ||
| 217 | out_file=None) | ||
| 218 | |||
| 219 | # checkers | ||
| 220 | def _read_and_compare(self, compare, expected): | ||
| 221 | """Compare the result with expectation. | ||
| 222 | |||
| 223 | compare: function to compare the result with expectation | ||
| 224 | expected: file that contains the expected data | ||
| 225 | """ | ||
| 226 | with open(os.path.join(self._test_dir, expected)) as f: | ||
| 227 | expected_data = f.read() | ||
| 228 | return compare(self, expected_data) | ||
| 229 | |||
| 230 | def _contains(self, attr, expected): | ||
| 231 | return self._read_and_compare( | ||
| 232 | lambda s, e: getattr(s, attr).find(e) >= 0, | ||
| 233 | expected) | ||
| 234 | |||
| 235 | def _matches(self, attr, expected): | ||
| 236 | return self._read_and_compare(lambda s, e: getattr(s, attr) == e, | ||
| 237 | expected) | ||
| 238 | |||
| 239 | def config_contains(self, expected): | ||
| 240 | """Check if resulted configuration contains expected data. | ||
| 241 | |||
| 242 | expected: file that contains the expected data | ||
| 243 | returncode: True if result contains the expected data, False otherwise | ||
| 244 | """ | ||
| 245 | return self._contains('config', expected) | ||
| 246 | |||
| 247 | def config_matches(self, expected): | ||
| 248 | """Check if resulted configuration exactly matches expected data. | ||
| 249 | |||
| 250 | expected: file that contains the expected data | ||
| 251 | returncode: True if result matches the expected data, False otherwise | ||
| 252 | """ | ||
| 253 | return self._matches('config', expected) | ||
| 254 | |||
| 255 | def stdout_contains(self, expected): | ||
| 256 | """Check if resulted stdout contains expected data. | ||
| 257 | |||
| 258 | expected: file that contains the expected data | ||
| 259 | returncode: True if result contains the expected data, False otherwise | ||
| 260 | """ | ||
| 261 | return self._contains('stdout', expected) | ||
| 262 | |||
| 263 | def stdout_matches(self, expected): | ||
| 264 | """Check if resulted stdout exactly matches expected data. | ||
| 265 | |||
| 266 | expected: file that contains the expected data | ||
| 267 | returncode: True if result matches the expected data, False otherwise | ||
| 268 | """ | ||
| 269 | return self._matches('stdout', expected) | ||
| 270 | |||
| 271 | def stderr_contains(self, expected): | ||
| 272 | """Check if resulted stderr contains expected data. | ||
| 273 | |||
| 274 | expected: file that contains the expected data | ||
| 275 | returncode: True if result contains the expected data, False otherwise | ||
| 276 | """ | ||
| 277 | return self._contains('stderr', expected) | ||
| 278 | |||
| 279 | def stderr_matches(self, expected): | ||
| 280 | """Check if resulted stderr exactly matches expected data. | ||
| 281 | |||
| 282 | expected: file that contains the expected data | ||
| 283 | returncode: True if result matches the expected data, False otherwise | ||
| 284 | """ | ||
| 285 | return self._matches('stderr', expected) | ||
| 286 | |||
| 287 | |||
| 288 | @pytest.fixture(scope="module") | ||
| 289 | def conf(request): | ||
| 290 | """Create a Conf instance and provide it to test functions.""" | ||
| 291 | return Conf(request) | ||
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig b/scripts/kconfig/tests/err_recursive_inc/Kconfig new file mode 100644 index 000000000000..0e4c8750ab65 --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig | |||
| @@ -0,0 +1 @@ | |||
| source "Kconfig.inc1" | |||
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 new file mode 100644 index 000000000000..00e408d653fc --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | source "Kconfig.inc2" | ||
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 new file mode 100644 index 000000000000..349ea2db15dc --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | |||
| 2 | |||
| 3 | source "Kconfig.inc3" | ||
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 new file mode 100644 index 000000000000..0e4c8750ab65 --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 | |||
| @@ -0,0 +1 @@ | |||
| source "Kconfig.inc1" | |||
diff --git a/scripts/kconfig/tests/err_recursive_inc/__init__.py b/scripts/kconfig/tests/err_recursive_inc/__init__.py new file mode 100644 index 000000000000..0e4c839c54aa --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/__init__.py | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | """ | ||
| 2 | Detect recursive inclusion error. | ||
| 3 | |||
| 4 | If recursive inclusion is detected, it should fail with error messages. | ||
| 5 | """ | ||
| 6 | |||
| 7 | |||
| 8 | def test(conf): | ||
| 9 | assert conf.oldaskconfig() != 0 | ||
| 10 | assert conf.stderr_contains('expected_stderr') | ||
diff --git a/scripts/kconfig/tests/err_recursive_inc/expected_stderr b/scripts/kconfig/tests/err_recursive_inc/expected_stderr new file mode 100644 index 000000000000..6b582eee2176 --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/expected_stderr | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | Recursive inclusion detected. | ||
| 2 | Inclusion path: | ||
| 3 | current file : Kconfig.inc1 | ||
| 4 | included from: Kconfig.inc3:1 | ||
| 5 | included from: Kconfig.inc2:3 | ||
| 6 | included from: Kconfig.inc1:4 | ||
diff --git a/scripts/kconfig/tests/inter_choice/Kconfig b/scripts/kconfig/tests/inter_choice/Kconfig new file mode 100644 index 000000000000..e44449f075df --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/Kconfig | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | config MODULES | ||
| 2 | def_bool y | ||
| 3 | option modules | ||
| 4 | |||
| 5 | choice | ||
| 6 | prompt "Choice" | ||
| 7 | |||
| 8 | config CHOICE_VAL0 | ||
| 9 | tristate "Choice 0" | ||
| 10 | |||
| 11 | config CHOIVE_VAL1 | ||
| 12 | tristate "Choice 1" | ||
| 13 | |||
| 14 | endchoice | ||
| 15 | |||
| 16 | choice | ||
| 17 | prompt "Another choice" | ||
| 18 | depends on CHOICE_VAL0 | ||
| 19 | |||
| 20 | config DUMMY | ||
| 21 | bool "dummy" | ||
| 22 | |||
| 23 | endchoice | ||
diff --git a/scripts/kconfig/tests/inter_choice/__init__.py b/scripts/kconfig/tests/inter_choice/__init__.py new file mode 100644 index 000000000000..5c7fc365ed40 --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/__init__.py | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | """ | ||
| 2 | Do not affect user-assigned choice value by another choice. | ||
| 3 | |||
| 4 | Handling of state flags for choices is complecated. In old days, | ||
| 5 | the defconfig result of a choice could be affected by another choice | ||
| 6 | if those choices interact by 'depends on', 'select', etc. | ||
| 7 | |||
| 8 | Related Linux commit: fbe98bb9ed3dae23e320c6b113e35f129538d14a | ||
| 9 | """ | ||
| 10 | |||
| 11 | |||
| 12 | def test(conf): | ||
| 13 | assert conf.defconfig('defconfig') == 0 | ||
| 14 | assert conf.config_contains('expected_config') | ||
diff --git a/scripts/kconfig/tests/inter_choice/defconfig b/scripts/kconfig/tests/inter_choice/defconfig new file mode 100644 index 000000000000..162c4148e2a5 --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/defconfig | |||
| @@ -0,0 +1 @@ | |||
| CONFIG_CHOICE_VAL0=y | |||
diff --git a/scripts/kconfig/tests/inter_choice/expected_config b/scripts/kconfig/tests/inter_choice/expected_config new file mode 100644 index 000000000000..5dceefb054e3 --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/expected_config | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | CONFIG_MODULES=y | ||
| 2 | CONFIG_CHOICE_VAL0=y | ||
| 3 | # CONFIG_CHOIVE_VAL1 is not set | ||
| 4 | CONFIG_DUMMY=y | ||
diff --git a/scripts/kconfig/tests/new_choice_with_dep/Kconfig b/scripts/kconfig/tests/new_choice_with_dep/Kconfig new file mode 100644 index 000000000000..53ef1b86e7bf --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/Kconfig | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | config A | ||
| 2 | bool "A" | ||
| 3 | help | ||
| 4 | This is a new symbol. | ||
| 5 | |||
| 6 | choice | ||
| 7 | prompt "Choice ?" | ||
| 8 | depends on A | ||
| 9 | help | ||
| 10 | "depends on A" has been newly added. | ||
| 11 | |||
| 12 | config CHOICE_B | ||
| 13 | bool "Choice B" | ||
| 14 | |||
| 15 | config CHOICE_C | ||
| 16 | bool "Choice C" | ||
| 17 | help | ||
| 18 | This is a new symbol, so should be asked. | ||
| 19 | |||
| 20 | endchoice | ||
| 21 | |||
| 22 | choice | ||
| 23 | prompt "Choice2 ?" | ||
| 24 | |||
| 25 | config CHOICE_D | ||
| 26 | bool "Choice D" | ||
| 27 | |||
| 28 | config CHOICE_E | ||
| 29 | bool "Choice E" | ||
| 30 | |||
| 31 | config CHOICE_F | ||
| 32 | bool "Choice F" | ||
| 33 | depends on A | ||
| 34 | help | ||
| 35 | This is a new symbol, so should be asked. | ||
| 36 | |||
| 37 | endchoice | ||
diff --git a/scripts/kconfig/tests/new_choice_with_dep/__init__.py b/scripts/kconfig/tests/new_choice_with_dep/__init__.py new file mode 100644 index 000000000000..f0e0ead0f32f --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/__init__.py | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | """ | ||
| 2 | Ask new choice values when they become visible. | ||
| 3 | |||
| 4 | If new choice values are added with new dependency, and they become | ||
| 5 | visible during user configuration, oldconfig should recognize them | ||
| 6 | as (NEW), and ask the user for choice. | ||
| 7 | |||
| 8 | Related Linux commit: 5d09598d488f081e3be23f885ed65cbbe2d073b5 | ||
| 9 | """ | ||
| 10 | |||
| 11 | |||
| 12 | def test(conf): | ||
| 13 | assert conf.oldconfig('config', 'y') == 0 | ||
| 14 | assert conf.stdout_contains('expected_stdout') | ||
diff --git a/scripts/kconfig/tests/new_choice_with_dep/config b/scripts/kconfig/tests/new_choice_with_dep/config new file mode 100644 index 000000000000..47ef95d567fd --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/config | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | CONFIG_CHOICE_B=y | ||
| 2 | # CONFIG_CHOICE_D is not set | ||
| 3 | CONFIG_CHOICE_E=y | ||
diff --git a/scripts/kconfig/tests/new_choice_with_dep/expected_stdout b/scripts/kconfig/tests/new_choice_with_dep/expected_stdout new file mode 100644 index 000000000000..74dc0bcb22bc --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/expected_stdout | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | A (A) [N/y/?] (NEW) y | ||
| 2 | Choice ? | ||
| 3 | > 1. Choice B (CHOICE_B) | ||
| 4 | 2. Choice C (CHOICE_C) (NEW) | ||
| 5 | choice[1-2?]: | ||
| 6 | Choice2 ? | ||
| 7 | 1. Choice D (CHOICE_D) | ||
| 8 | > 2. Choice E (CHOICE_E) | ||
| 9 | 3. Choice F (CHOICE_F) (NEW) | ||
| 10 | choice[1-3?]: | ||
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig new file mode 100644 index 000000000000..c00b8fe54f45 --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | config A | ||
| 2 | bool "A" | ||
| 3 | |||
| 4 | choice | ||
| 5 | prompt "Choice ?" | ||
| 6 | depends on A | ||
| 7 | |||
| 8 | config CHOICE_B | ||
| 9 | bool "Choice B" | ||
| 10 | |||
| 11 | config CHOICE_C | ||
| 12 | bool "Choice C" | ||
| 13 | |||
| 14 | endchoice | ||
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py new file mode 100644 index 000000000000..207261b0fe00 --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | """ | ||
| 2 | Do not write choice values to .config if the dependency is unmet. | ||
| 3 | |||
| 4 | "# CONFIG_... is not set" should not be written into the .config file | ||
| 5 | for symbols with unmet dependency. | ||
| 6 | |||
| 7 | This was not working correctly for choice values because choice needs | ||
| 8 | a bit different symbol computation. | ||
| 9 | |||
| 10 | This checks that no unneeded "# COFIG_... is not set" is contained in | ||
| 11 | the .config file. | ||
| 12 | |||
| 13 | Related Linux commit: cb67ab2cd2b8abd9650292c986c79901e3073a59 | ||
| 14 | """ | ||
| 15 | |||
| 16 | |||
| 17 | def test(conf): | ||
| 18 | assert conf.oldaskconfig('config', 'n') == 0 | ||
| 19 | assert conf.config_matches('expected_config') | ||
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/config b/scripts/kconfig/tests/no_write_if_dep_unmet/config new file mode 100644 index 000000000000..abd280e2f616 --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/config | |||
| @@ -0,0 +1 @@ | |||
| CONFIG_A=y | |||
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config new file mode 100644 index 000000000000..0d15e41da475 --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated file; DO NOT EDIT. | ||
| 3 | # Linux Kernel Configuration | ||
| 4 | # | ||
| 5 | # CONFIG_A is not set | ||
diff --git a/scripts/kconfig/tests/pytest.ini b/scripts/kconfig/tests/pytest.ini new file mode 100644 index 000000000000..85d7ce8e448b --- /dev/null +++ b/scripts/kconfig/tests/pytest.ini | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | [pytest] | ||
| 2 | addopts = --verbose | ||
| 3 | |||
| 4 | # Pytest requires that test files have unique names, because pytest imports | ||
| 5 | # them as top-level modules. It is silly to prefix or suffix a test file with | ||
| 6 | # the directory name that contains it. Use __init__.py for all test files. | ||
| 7 | python_files = __init__.py | ||
diff --git a/scripts/kconfig/tests/rand_nested_choice/Kconfig b/scripts/kconfig/tests/rand_nested_choice/Kconfig new file mode 100644 index 000000000000..c591d512929f --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/Kconfig | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | choice | ||
| 2 | prompt "choice" | ||
| 3 | |||
| 4 | config A | ||
| 5 | bool "A" | ||
| 6 | |||
| 7 | config B | ||
| 8 | bool "B" | ||
| 9 | |||
| 10 | if B | ||
| 11 | choice | ||
| 12 | prompt "sub choice" | ||
| 13 | |||
| 14 | config C | ||
| 15 | bool "C" | ||
| 16 | |||
| 17 | config D | ||
| 18 | bool "D" | ||
| 19 | |||
| 20 | if D | ||
| 21 | choice | ||
| 22 | prompt "subsub choice" | ||
| 23 | |||
| 24 | config E | ||
| 25 | bool "E" | ||
| 26 | |||
| 27 | endchoice | ||
| 28 | endif # D | ||
| 29 | |||
| 30 | endchoice | ||
| 31 | endif # B | ||
| 32 | |||
| 33 | endchoice | ||
diff --git a/scripts/kconfig/tests/rand_nested_choice/__init__.py b/scripts/kconfig/tests/rand_nested_choice/__init__.py new file mode 100644 index 000000000000..e729a4e85218 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/__init__.py | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | """ | ||
| 2 | Set random values recursively in nested choices. | ||
| 3 | |||
| 4 | Kconfig can create a choice-in-choice structure by using 'if' statement. | ||
| 5 | randconfig should correctly set random choice values. | ||
| 6 | |||
| 7 | Related Linux commit: 3b9a19e08960e5cdad5253998637653e592a3c29 | ||
| 8 | """ | ||
| 9 | |||
| 10 | |||
| 11 | def test(conf): | ||
| 12 | for i in range(20): | ||
| 13 | assert conf.randconfig() == 0 | ||
| 14 | assert (conf.config_contains('expected_stdout0') or | ||
| 15 | conf.config_contains('expected_stdout1') or | ||
| 16 | conf.config_contains('expected_stdout2')) | ||
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 new file mode 100644 index 000000000000..05450f3d4eb5 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | CONFIG_A=y | ||
| 2 | # CONFIG_B is not set | ||
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 new file mode 100644 index 000000000000..37ab29584157 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | # CONFIG_A is not set | ||
| 2 | CONFIG_B=y | ||
| 3 | CONFIG_C=y | ||
| 4 | # CONFIG_D is not set | ||
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 new file mode 100644 index 000000000000..849ff47e9848 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # CONFIG_A is not set | ||
| 2 | CONFIG_B=y | ||
| 3 | # CONFIG_C is not set | ||
| 4 | CONFIG_D=y | ||
| 5 | CONFIG_E=y | ||
diff --git a/scripts/kconfig/tests/warn_recursive_dep/Kconfig b/scripts/kconfig/tests/warn_recursive_dep/Kconfig new file mode 100644 index 000000000000..a65bfcb7137e --- /dev/null +++ b/scripts/kconfig/tests/warn_recursive_dep/Kconfig | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | # depends on itself | ||
| 2 | |||
| 3 | config A | ||
| 4 | bool "A" | ||
| 5 | depends on A | ||
| 6 | |||
| 7 | # select itself | ||
| 8 | |||
| 9 | config B | ||
| 10 | bool | ||
| 11 | select B | ||
| 12 | |||
| 13 | # depends on each other | ||
| 14 | |||
| 15 | config C1 | ||
| 16 | bool "C1" | ||
| 17 | depends on C2 | ||
| 18 | |||
| 19 | config C2 | ||
| 20 | bool "C2" | ||
| 21 | depends on C1 | ||
| 22 | |||
| 23 | # depends on and select | ||
| 24 | |||
| 25 | config D1 | ||
| 26 | bool "D1" | ||
| 27 | depends on D2 | ||
| 28 | select D2 | ||
| 29 | |||
| 30 | config D2 | ||
| 31 | bool | ||
| 32 | |||
| 33 | # depends on and imply | ||
| 34 | # This is not recursive dependency | ||
| 35 | |||
| 36 | config E1 | ||
| 37 | bool "E1" | ||
| 38 | depends on E2 | ||
| 39 | imply E2 | ||
| 40 | |||
| 41 | config E2 | ||
| 42 | bool "E2" | ||
| 43 | |||
| 44 | # property | ||
| 45 | |||
| 46 | config F1 | ||
| 47 | bool "F1" | ||
| 48 | default F2 | ||
| 49 | |||
| 50 | config F2 | ||
| 51 | bool "F2" | ||
| 52 | depends on F1 | ||
| 53 | |||
| 54 | # menu | ||
| 55 | |||
| 56 | menu "menu depending on its content" | ||
| 57 | depends on G | ||
| 58 | |||
| 59 | config G | ||
| 60 | bool "G" | ||
| 61 | |||
| 62 | endmenu | ||
diff --git a/scripts/kconfig/tests/warn_recursive_dep/__init__.py b/scripts/kconfig/tests/warn_recursive_dep/__init__.py new file mode 100644 index 000000000000..adb21951ba41 --- /dev/null +++ b/scripts/kconfig/tests/warn_recursive_dep/__init__.py | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | """ | ||
| 2 | Warn recursive inclusion. | ||
| 3 | |||
| 4 | Recursive dependency should be warned. | ||
| 5 | """ | ||
| 6 | |||
| 7 | def test(conf): | ||
| 8 | assert conf.oldaskconfig() == 0 | ||
| 9 | assert conf.stderr_contains('expected_stderr') | ||
diff --git a/scripts/kconfig/tests/warn_recursive_dep/expected_stderr b/scripts/kconfig/tests/warn_recursive_dep/expected_stderr new file mode 100644 index 000000000000..3de807dd9cb2 --- /dev/null +++ b/scripts/kconfig/tests/warn_recursive_dep/expected_stderr | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | Kconfig:9:error: recursive dependency detected! | ||
| 2 | Kconfig:9: symbol B is selected by B | ||
| 3 | For a resolution refer to Documentation/kbuild/kconfig-language.txt | ||
| 4 | subsection "Kconfig recursive dependency limitations" | ||
| 5 | |||
| 6 | Kconfig:3:error: recursive dependency detected! | ||
| 7 | Kconfig:3: symbol A depends on A | ||
| 8 | For a resolution refer to Documentation/kbuild/kconfig-language.txt | ||
| 9 | subsection "Kconfig recursive dependency limitations" | ||
| 10 | |||
| 11 | Kconfig:15:error: recursive dependency detected! | ||
| 12 | Kconfig:15: symbol C1 depends on C2 | ||
| 13 | Kconfig:19: symbol C2 depends on C1 | ||
| 14 | For a resolution refer to Documentation/kbuild/kconfig-language.txt | ||
| 15 | subsection "Kconfig recursive dependency limitations" | ||
| 16 | |||
| 17 | Kconfig:30:error: recursive dependency detected! | ||
| 18 | Kconfig:30: symbol D2 is selected by D1 | ||
| 19 | Kconfig:25: symbol D1 depends on D2 | ||
| 20 | For a resolution refer to Documentation/kbuild/kconfig-language.txt | ||
| 21 | subsection "Kconfig recursive dependency limitations" | ||
| 22 | |||
| 23 | Kconfig:59:error: recursive dependency detected! | ||
| 24 | Kconfig:59: symbol G depends on G | ||
| 25 | For a resolution refer to Documentation/kbuild/kconfig-language.txt | ||
| 26 | subsection "Kconfig recursive dependency limitations" | ||
| 27 | |||
| 28 | Kconfig:50:error: recursive dependency detected! | ||
| 29 | Kconfig:50: symbol F2 depends on F1 | ||
| 30 | Kconfig:48: symbol F1 default value contains F2 | ||
