Atlas - testsuite.py

Home / ext / kconfiglib Lines: 17 | Size: 103801 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1# Copyright (c) 2011-2019, Ulf Magnusson 2# SPDX-License-Identifier: ISC 3 4# This is the Kconfiglib test suite. It runs selftests on Kconfigs provided by 5# us and tests compatibility with the C Kconfig implementation by comparing the 6# output of Kconfiglib with the output of the scripts/kconfig/*conf utilities 7# for different targets and defconfigs. It should be run from the top-level 8# kernel directory with 9# 10# $ python Kconfiglib/testsuite.py 11# 12# Some additional options can be turned on by passing them as arguments. They 13# default to off. 14# 15# - obsessive: 16# By default, only valid arch/defconfig pairs are tested. In obsessive mode, 17# every arch will be tested with every defconfig. Increases the testing time 18# by an order of magnitude. Occasionally finds (usually obscure) bugs, and I 19# make sure everything passes with it. 20# 21# - obsessive-min-config: 22# Like obsessive, for the minimal configuation (defconfig) tests. 23# 24# - log: 25# Log timestamped defconfig test failures to the file test_defconfig_fails. 26# Handy in obsessive mode. 27# 28# For example, this commands runs the test suite in obsessive mode with logging 29# enabled: 30# 31# $ python(3) Kconfiglib/testsuite.py obsessive log 32# 33# pypy works too, and runs most tests much faster than CPython. 34# 35# All tests should pass. Report regressions to ulfalizer a.t Google's email 36# service. 37 38import difflib 39import errno 40import os 41import re 42import shutil 43import subprocess 44import sys 45import tempfile 46import textwrap 47 48from kconfiglib import Kconfig, Symbol, Choice, COMMENT, MENU, MenuNode, \ 49 BOOL, TRISTATE, HEX, \ 50 TRI_TO_STR, \ 51 escape, unescape, \ 52 expr_str, expr_items, split_expr, \ 53 _ordered_unique, \ 54 OR, AND, \ 55 KconfigError 56 57 58def shell(cmd): 59 with open(os.devnull, "w") as devnull: 60 subprocess.call(cmd, shell=True, stdout=devnull, stderr=devnull) 61 62 63all_passed = True 64 65 66def fail(msg=None): 67 global all_passed 68 all_passed = False 69 if msg is not None: 70 print("fail: " + msg) 71 72 73def verify(cond, msg): 74 if not cond: 75 fail(msg) 76 77 78def verify_equal(x, y): 79 if x != y: 80 fail("'{}' does not equal '{}'".format(x, y)) 81 82 83# Prevent accidental loading of configuration files by removing 84# KCONFIG_ALLCONFIG from the environment 85os.environ.pop("KCONFIG_ALLCONFIG", None) 86 87obsessive = False 88obsessive_min_config = False 89log = False 90 91 92def run_tests(): 93 global obsessive, log 94 for s in sys.argv[1:]: 95 if s == "obsessive": 96 obsessive = True 97 print("Obsessive mode enabled") 98 elif s == "obsessive-min-config": 99 obsessive_min_config = True 100 print("Obsessive minimal config mode enabled") 101 elif s == "log": 102 log = True 103 print("Log mode enabled") 104 else: 105 print("Unrecognized option '{}'".format(s)) 106 return 107 108 run_selftests() 109 run_compatibility_tests() 110 111 112def run_selftests(): 113 # 114 # Common helper functions. These all expect 'c' to hold the current 115 # configuration. 116 # 117 118 def verify_value(sym_name, val): 119 # Verifies that a symbol has a particular value. 120 121 if isinstance(val, int): 122 val = TRI_TO_STR[val] 123 124 sym = c.syms[sym_name] 125 verify(sym.str_value == val, 126 'expected {} to have the value "{}", had the value "{}"' 127 .format(sym_name, val, sym.str_value)) 128 129 def assign_and_verify_value(sym_name, val, new_val): 130 # Assigns 'val' to a symbol and verifies that its value becomes 131 # 'new_val'. Assumes (and tests) that 'val' is valid for the 132 # symbol type. 133 134 if isinstance(new_val, int): 135 new_val = TRI_TO_STR[new_val] 136 137 sym = c.syms[sym_name] 138 old_val = sym.str_value 139 verify(sym.set_value(val), 140 "assigning '{}' to {} unexpectedly failed" 141 .format(val, sym_name)) 142 verify(sym.str_value == new_val, 143 "expected {} to have the value '{}' after being assigned the " 144 "value '{}'. Instead, the value is '{}'. The old value was " 145 "'{}'." 146 .format(sym_name, new_val, val, sym.str_value, old_val)) 147 148 def assign_and_verify(sym_name, user_val): 149 # Like assign_and_verify_value(), with the expected value being the 150 # value just set. 151 152 assign_and_verify_value(sym_name, user_val, user_val) 153 154 def assign_and_verify_user_value(sym_name, val, user_val, valid): 155 # Assigns a user value to the symbol and verifies the new user value. 156 # If valid is True, the user value is valid for the type, otherwise 157 # not. This is used to test the set_value() return value. 158 159 sym = c.syms[sym_name] 160 sym_old_user_val = sym.user_value 161 162 verify(sym.set_value(val) == valid, 163 "expected the user value '{}' to be {} for {}, was not" 164 .format(val, "valid" if valid else "invalid", sym_name)) 165 verify(sym.user_value == user_val, 166 "the assigned user value '{}' wasn't reflected in user_value " 167 "on the symbol {}. Instead, the new user_value was '{}'. The " 168 "old user value was '{}'." 169 .format(user_val, sym_name, sym.user_value, sym_old_user_val)) 170 171 # 172 # Selftests 173 # 174 175 print("Testing string literal lexing") 176 177 # Dummy empty configuration just to get a Kconfig object 178 c = Kconfig("Kconfiglib/tests/empty") 179 180 def verify_string_lex(s, expected): 181 # Verifies that a constant symbol with the name 'res' is produced from 182 # lexing 's' 183 184 res = c._tokenize("if " + s)[1].name 185 verify(res == expected, 186 "expected <{}> to produced the constant symbol <{}>, " 187 'produced <{}>'.format(s[1:-1], expected, res)) 188 189 verify_string_lex(r""" "" """, "") 190 verify_string_lex(r""" '' """, "") 191 192 verify_string_lex(r""" "a" """, "a") 193 verify_string_lex(r""" 'a' """, "a") 194 verify_string_lex(r""" "ab" """, "ab") 195 verify_string_lex(r""" 'ab' """, "ab") 196 verify_string_lex(r""" "abc" """, "abc") 197 verify_string_lex(r""" 'abc' """, "abc") 198 199 verify_string_lex(r""" "'" """, "'") 200 verify_string_lex(r""" '"' """, '"') 201 202 verify_string_lex(r""" "\"" """, '"') 203 verify_string_lex(r""" '\'' """, "'") 204 205 verify_string_lex(r""" "\"\"" """, '""') 206 verify_string_lex(r""" '\'\'' """, "''") 207 208 verify_string_lex(r""" "\'" """, "'") 209 verify_string_lex(r""" '\"' """, '"') 210 211 verify_string_lex(r""" "\\" """, "\\") 212 verify_string_lex(r""" '\\' """, "\\") 213 214 verify_string_lex(r""" "\a\\'\b\c\"'d" """, 'a\\\'bc"\'d') 215 verify_string_lex(r""" '\a\\"\b\c\'"d' """, "a\\\"bc'\"d") 216 217 def verify_string_bad(s): 218 # Verifies that tokenizing 's' throws a KconfigError. Strips the first 219 # and last characters from 's' so we can use readable raw strings as 220 # input. 221 222 try: 223 c.eval_string(s) 224 except KconfigError: 225 pass 226 else: 227 fail("expected tokenization of {} to fail, didn't".format(s[1:-1])) 228 229 verify_string_bad(r""" " """) 230 verify_string_bad(r""" ' """) 231 verify_string_bad(r""" "' """) 232 verify_string_bad(r""" '" """) 233 verify_string_bad(r""" "\" """) 234 verify_string_bad(r""" '\' """) 235 verify_string_bad(r""" "foo """) 236 verify_string_bad(r""" 'foo """) 237 238 239 print("Testing escape() and unescape()") 240 241 def verify_escape_unescape(s, sesc): 242 # Verify that 's' escapes to 'sesc' and that 'sesc' unescapes to 's' 243 verify_equal(escape(s), sesc) 244 verify_equal(unescape(sesc), s) 245 246 verify_escape_unescape(r'' , r'' ) 247 verify_escape_unescape(r'foo' , r'foo' ) 248 verify_escape_unescape(r'"' , r'\"' ) 249 verify_escape_unescape(r'""' , r'\"\"' ) 250 verify_escape_unescape('\\' , r'\\' ) 251 verify_escape_unescape(r'\\' , r'\\\\' ) 252 verify_escape_unescape(r'\"' , r'\\\"' ) 253 verify_escape_unescape(r'"ab\cd"ef"', r'\"ab\\cd\"ef\"') 254 255 # Backslashes before any character should be unescaped, not just before " 256 # and \ 257 verify_equal(unescape(r"\afoo\b\c\\d\\\e\\\\f"), r"afoobc\d\e\\f") 258 259 260 print("Testing _ordered_unique()") 261 262 verify_equal(_ordered_unique([]), []) 263 verify_equal(_ordered_unique([1]), [1]) 264 verify_equal(_ordered_unique([1, 2]), [1, 2]) 265 verify_equal(_ordered_unique([1, 1]), [1]) 266 verify_equal(_ordered_unique([1, 1, 2]), [1, 2]) 267 verify_equal(_ordered_unique([1, 2, 1]), [1, 2]) 268 verify_equal(_ordered_unique([1, 2, 2]), [1, 2]) 269 verify_equal(_ordered_unique([1, 2, 3, 2, 1, 2, 3, 4, 3, 2, 1, 0]), 270 [1, 2, 3, 4, 0]) 271 272 273 print("Testing expression evaluation") 274 275 c = Kconfig("Kconfiglib/tests/Keval", warn=False) 276 277 def verify_eval(expr, val): 278 res = c.eval_string(expr) 279 verify(res == val, 280 "'{}' evaluated to {}, expected {}".format(expr, res, val)) 281 282 # No modules 283 verify_eval("n", 0) 284 verify_eval("m", 0) 285 verify_eval("y", 2) 286 verify_eval("'n'", 0) 287 verify_eval("'m'", 0) 288 verify_eval("'y'", 2) 289 verify_eval("M", 2) 290 291 # Modules 292 c.modules.set_value(2) 293 verify_eval("n", 0) 294 verify_eval("m", 1) 295 verify_eval("y", 2) 296 verify_eval("'n'", 0) 297 verify_eval("'m'", 1) 298 verify_eval("'y'", 2) 299 verify_eval("M", 1) 300 verify_eval("(Y || N) && (m && y)", 1) 301 302 # Non-bool/non-tristate symbols are always n in a tristate sense 303 verify_eval("Y_STRING", 0) 304 verify_eval("Y_STRING || m", 1) 305 306 # As are all constants besides y and m 307 verify_eval('"foo"', 0) 308 verify_eval('"foo" || "bar"', 0) 309 verify_eval('"foo" || m', 1) 310 311 # Test equality for symbols 312 313 verify_eval("N = N", 2) 314 verify_eval("N = n", 2) 315 verify_eval("N = 'n'", 2) 316 verify_eval("N != N", 0) 317 verify_eval("N != n", 0) 318 verify_eval("N != 'n'", 0) 319 320 verify_eval("M = M", 2) 321 verify_eval("M = m", 2) 322 verify_eval("M = 'm'", 2) 323 verify_eval("M != M", 0) 324 verify_eval("M != m", 0) 325 verify_eval("M != 'm'", 0) 326 327 verify_eval("Y = Y", 2) 328 verify_eval("Y = y", 2) 329 verify_eval("Y = 'y'", 2) 330 verify_eval("Y != Y", 0) 331 verify_eval("Y != y", 0) 332 verify_eval("Y != 'y'", 0) 333 334 verify_eval("N != M", 2) 335 verify_eval("N != Y", 2) 336 verify_eval("M != Y", 2) 337 338 verify_eval("Y_STRING = y", 2) 339 verify_eval("Y_STRING = 'y'", 2) 340 verify_eval('FOO_BAR_STRING = "foo bar"', 2) 341 verify_eval('FOO_BAR_STRING != "foo bar baz"', 2) 342 verify_eval('INT_37 = 37', 2) 343 verify_eval("INT_37 = '37'", 2) 344 verify_eval('HEX_0X37 = 0x37', 2) 345 verify_eval("HEX_0X37 = '0x37'", 2) 346 347 # These should also hold after 31847b67 (kconfig: allow use of relations 348 # other than (in)equality) 349 verify_eval("HEX_0X37 = '0x037'", 2) 350 verify_eval("HEX_0X37 = '0x0037'", 2) 351 352 # Constant symbol comparisons 353 verify_eval('"foo" != "bar"', 2) 354 verify_eval('"foo" = "bar"', 0) 355 verify_eval('"foo" = "foo"', 2) 356 357 # Undefined symbols get their name as their value 358 c.warn = False 359 verify_eval("'not_defined' = not_defined", 2) 360 verify_eval("not_defined_2 = not_defined_2", 2) 361 verify_eval("not_defined_1 != not_defined_2", 2) 362 363 # Test less than/greater than 364 365 # Basic evaluation 366 verify_eval("INT_37 < 38", 2) 367 verify_eval("38 < INT_37", 0) 368 verify_eval("INT_37 < '38'", 2) 369 verify_eval("'38' < INT_37", 0) 370 verify_eval("INT_37 < 138", 2) 371 verify_eval("138 < INT_37", 0) 372 verify_eval("INT_37 < '138'", 2) 373 verify_eval("'138' < INT_37", 0) 374 verify_eval("INT_37 < -138", 0) 375 verify_eval("-138 < INT_37", 2) 376 verify_eval("INT_37 < '-138'", 0) 377 verify_eval("'-138' < INT_37", 2) 378 verify_eval("INT_37 < 37", 0) 379 verify_eval("37 < INT_37", 0) 380 verify_eval("INT_37 < 36", 0) 381 verify_eval("36 < INT_37", 2) 382 383 # Different formats in comparison 384 verify_eval("INT_37 < 0x26", 2) # 38 385 verify_eval("INT_37 < 0x25", 0) # 37 386 verify_eval("INT_37 < 0x24", 0) # 36 387 verify_eval("HEX_0X37 < 56", 2) # 0x38 388 verify_eval("HEX_0X37 < 55", 0) # 0x37 389 verify_eval("HEX_0X37 < 54", 0) # 0x36 390 391 # Other int comparisons 392 verify_eval("INT_37 <= 38", 2) 393 verify_eval("INT_37 <= 37", 2) 394 verify_eval("INT_37 <= 36", 0) 395 verify_eval("INT_37 > 38", 0) 396 verify_eval("INT_37 > 37", 0) 397 verify_eval("INT_37 > 36", 2) 398 verify_eval("INT_37 >= 38", 0) 399 verify_eval("INT_37 >= 37", 2) 400 verify_eval("INT_37 >= 36", 2) 401 402 # Other hex comparisons 403 verify_eval("HEX_0X37 <= 0x38", 2) 404 verify_eval("HEX_0X37 <= 0x37", 2) 405 verify_eval("HEX_0X37 <= 0x36", 0) 406 verify_eval("HEX_0X37 > 0x38", 0) 407 verify_eval("HEX_0X37 > 0x37", 0) 408 verify_eval("HEX_0X37 > 0x36", 2) 409 verify_eval("HEX_0X37 >= 0x38", 0) 410 verify_eval("HEX_0X37 >= 0x37", 2) 411 verify_eval("HEX_0X37 >= 0x36", 2) 412 413 # A hex holding a value without a "0x" prefix should still be treated as 414 # hexadecimal 415 verify_eval("HEX_37 < 0x38", 2) 416 verify_eval("HEX_37 < 0x37", 0) 417 verify_eval("HEX_37 < 0x36", 0) 418 419 # Symbol comparisons 420 verify_eval("INT_37 < HEX_0X37", 2) 421 verify_eval("INT_37 > HEX_0X37", 0) 422 verify_eval("HEX_0X37 < INT_37 ", 0) 423 verify_eval("HEX_0X37 > INT_37 ", 2) 424 verify_eval("INT_37 < INT_37 ", 0) 425 verify_eval("INT_37 <= INT_37 ", 2) 426 verify_eval("INT_37 > INT_37 ", 0) 427 verify_eval("INT_37 <= INT_37 ", 2) 428 429 # Tristate value comparisons 430 verify_eval("n < n", 0) 431 verify_eval("n < m", 2) 432 verify_eval("n < y", 2) 433 verify_eval("n < N", 0) 434 verify_eval("n < M", 2) 435 verify_eval("n < Y", 2) 436 verify_eval("0 > n", 0) 437 verify_eval("1 > n", 2) 438 verify_eval("2 > n", 2) 439 verify_eval("m < n", 0) 440 verify_eval("m < m", 0) 441 verify_eval("m < y", 2) 442 443 # Strings compare lexicographically 444 verify_eval("'aa' < 'ab'", 2) 445 verify_eval("'aa' > 'ab'", 0) 446 verify_eval("'ab' < 'aa'", 0) 447 verify_eval("'ab' > 'aa'", 2) 448 449 # Comparisons where one of the operands doesn't parse as a number also give 450 # a lexicographic comparison 451 verify_eval("INT_37 < '37a' ", 2) 452 verify_eval("'37a' > INT_37", 2) 453 verify_eval("INT_37 <= '37a' ", 2) 454 verify_eval("'37a' >= INT_37", 2) 455 verify_eval("INT_37 >= '37a' ", 0) 456 verify_eval("INT_37 > '37a' ", 0) 457 verify_eval("'37a' < INT_37", 0) 458 verify_eval("'37a' <= INT_37", 0) 459 460 def verify_eval_bad(expr): 461 try: 462 c.eval_string(expr) 463 except KconfigError: 464 pass 465 else: 466 fail('expected eval_string("{}") to throw KconfigError, ' 467 "didn't".format(expr)) 468 469 # Verify that some bad stuff throws KconfigError's 470 verify_eval_bad("") 471 verify_eval_bad("&") 472 verify_eval_bad("|") 473 verify_eval_bad("!") 474 verify_eval_bad("(") 475 verify_eval_bad(")") 476 verify_eval_bad("=") 477 verify_eval_bad("(X") 478 verify_eval_bad("X)") 479 verify_eval_bad("X X") 480 verify_eval_bad("!X X") 481 verify_eval_bad("X !X") 482 verify_eval_bad("(X) X") 483 verify_eval_bad("X &&") 484 verify_eval_bad("&& X") 485 verify_eval_bad("X && && X") 486 verify_eval_bad("X && !&&") 487 verify_eval_bad("X ||") 488 verify_eval_bad("|| X") 489 490 491 print("Testing Symbol.__str__()/custom_str() and def_{int,hex,string}") 492 493 def verify_str(item, s): 494 verify_equal(str(item), s[1:-1]) 495 496 def verify_custom_str(item, s): 497 verify_equal(item.custom_str(lambda sc: "[{}]".format(sc.name)), 498 s[1:-1]) 499 500 c = Kconfig("Kconfiglib/tests/Kstr", warn=False) 501 502 c.modules.set_value(2) 503 504 verify_str(c.syms["UNDEFINED"], """ 505""") 506 507 verify_str(c.syms["BASIC_NO_PROMPT"], """ 508config BASIC_NO_PROMPT 509 bool 510 help 511 blah blah 512 513 blah blah blah 514 515 blah 516""") 517 518 verify_str(c.syms["BASIC_PROMPT"], """ 519config BASIC_PROMPT 520 bool "basic" 521""") 522 523 verify_str(c.syms["ADVANCED"], """ 524config ADVANCED 525 tristate "prompt" if DEP 526 default DEFAULT_1 527 default DEFAULT_2 if DEP 528 select SELECTED_1 529 select SELECTED_2 if DEP 530 imply IMPLIED_1 531 imply IMPLIED_2 if DEP 532 help 533 first help text 534 535config ADVANCED 536 tristate "prompt 2" 537 538menuconfig ADVANCED 539 tristate "prompt 3" 540 541config ADVANCED 542 tristate 543 depends on (A || !B || (C && D) || !(E && F) || G = H || (I && !J && (K || L) && !(M || N) && O = P)) && DEP4 && DEP3 544 help 545 second help text 546 547config ADVANCED 548 tristate "prompt 4" if VIS 549 depends on DEP4 && DEP3 550""") 551 552 verify_custom_str(c.syms["ADVANCED"], """ 553config ADVANCED 554 tristate "prompt" if [DEP] 555 default [DEFAULT_1] 556 default [DEFAULT_2] if [DEP] 557 select [SELECTED_1] 558 select [SELECTED_2] if [DEP] 559 imply [IMPLIED_1] 560 imply [IMPLIED_2] if [DEP] 561 help 562 first help text 563 564config ADVANCED 565 tristate "prompt 2" 566 567menuconfig ADVANCED 568 tristate "prompt 3" 569 570config ADVANCED 571 tristate 572 depends on ([A] || ![B] || ([C] && [D]) || !([E] && [F]) || [G] = [H] || ([I] && ![J] && ([K] || [L]) && !([M] || [N]) && [O] = [P])) && [DEP4] && [DEP3] 573 help 574 second help text 575 576config ADVANCED 577 tristate "prompt 4" if [VIS] 578 depends on [DEP4] && [DEP3] 579""") 580 581 582 verify_str(c.syms["ONLY_DIRECT_DEPS"], """ 583config ONLY_DIRECT_DEPS 584 int 585 depends on DEP1 && DEP2 586""") 587 588 verify_str(c.syms["STRING"], """ 589config STRING 590 string 591 default "foo" 592 default "bar" if DEP 593 default STRING2 594 default STRING3 if DEP 595""") 596 597 verify_str(c.syms["INT"], """ 598config INT 599 int 600 range 1 2 601 range FOO BAR 602 range BAZ QAZ if DEP 603 default 7 if DEP 604""") 605 606 verify_str(c.syms["HEX"], """ 607config HEX 608 hex 609 range 0x100 0x200 610 range FOO BAR 611 range BAZ QAZ if DEP 612 default 0x123 613""") 614 615 verify_str(c.modules, """ 616config MODULES 617 bool "MODULES" 618 option modules 619""") 620 621 verify_str(c.syms["OPTIONS"], """ 622config OPTIONS 623 option allnoconfig_y 624 option defconfig_list 625 option env="ENV" 626""") 627 628 verify_str(c.syms["CORRECT_PROP_LOCS_BOOL"], """ 629config CORRECT_PROP_LOCS_BOOL 630 bool "prompt 1" 631 default DEFAULT_1 632 default DEFAULT_2 633 select SELECT_1 634 select SELECT_2 635 imply IMPLY_1 636 imply IMPLY_2 637 depends on LOC_1 638 help 639 help 1 640 641menuconfig CORRECT_PROP_LOCS_BOOL 642 bool "prompt 2" 643 default DEFAULT_3 644 default DEFAULT_4 645 select SELECT_3 646 select SELECT_4 647 imply IMPLY_3 648 imply IMPLY_4 649 depends on LOC_2 650 help 651 help 2 652 653config CORRECT_PROP_LOCS_BOOL 654 bool "prompt 3" 655 default DEFAULT_5 656 default DEFAULT_6 657 select SELECT_5 658 select SELECT_6 659 imply IMPLY_5 660 imply IMPLY_6 661 depends on LOC_3 662 help 663 help 2 664""") 665 666 verify_str(c.syms["CORRECT_PROP_LOCS_INT"], """ 667config CORRECT_PROP_LOCS_INT 668 int 669 range 1 2 670 range 3 4 671 depends on LOC_1 672 673config CORRECT_PROP_LOCS_INT 674 int 675 range 5 6 676 range 7 8 677 depends on LOC_2 678""") 679 680 verify_str(c.syms["PROMPT_ONLY"], """ 681config PROMPT_ONLY 682 prompt "prompt only" 683""") 684 685 verify_custom_str(c.syms["CORRECT_PROP_LOCS_INT"], """ 686config CORRECT_PROP_LOCS_INT 687 int 688 range [1] [2] 689 range [3] [4] 690 depends on [LOC_1] 691 692config CORRECT_PROP_LOCS_INT 693 int 694 range [5] [6] 695 range [7] [8] 696 depends on [LOC_2] 697""") 698 699 700 701 print("Testing Choice.__str__()/custom_str()") 702 703 verify_str(c.named_choices["CHOICE"], """ 704choice CHOICE 705 tristate "foo" 706 default CHOICE_1 707 default CHOICE_2 if dep 708""") 709 710 verify_str(c.named_choices["CHOICE"].nodes[0].next.item, """ 711choice 712 tristate "no name" 713 optional 714""") 715 716 verify_str(c.named_choices["CORRECT_PROP_LOCS_CHOICE"], """ 717choice CORRECT_PROP_LOCS_CHOICE 718 bool 719 default CHOICE_3 720 depends on LOC_1 721 722choice CORRECT_PROP_LOCS_CHOICE 723 bool 724 default CHOICE_4 725 depends on LOC_2 726 727choice CORRECT_PROP_LOCS_CHOICE 728 bool 729 default CHOICE_5 730 depends on LOC_3 731""") 732 733 verify_custom_str(c.named_choices["CORRECT_PROP_LOCS_CHOICE"], """ 734choice CORRECT_PROP_LOCS_CHOICE 735 bool 736 default [CHOICE_3] 737 depends on [LOC_1] 738 739choice CORRECT_PROP_LOCS_CHOICE 740 bool 741 default [CHOICE_4] 742 depends on [LOC_2] 743 744choice CORRECT_PROP_LOCS_CHOICE 745 bool 746 default [CHOICE_5] 747 depends on [LOC_3] 748""") 749 750 751 print("Testing MenuNode.__str__()/custom_str() for menus and comments") 752 753 verify_str(c.syms["SIMPLE_MENU_HOOK"].nodes[0].next, """ 754menu "simple menu" 755""") 756 757 verify_str(c.syms["ADVANCED_MENU_HOOK"].nodes[0].next, """ 758menu "advanced menu" 759 depends on A 760 visible if B && (C || D) 761""") 762 763 verify_custom_str(c.syms["ADVANCED_MENU_HOOK"].nodes[0].next, """ 764menu "advanced menu" 765 depends on [A] 766 visible if [B] && ([C] || [D]) 767""") 768 769 verify_str(c.syms["SIMPLE_COMMENT_HOOK"].nodes[0].next, """ 770comment "simple comment" 771""") 772 773 verify_str(c.syms["ADVANCED_COMMENT_HOOK"].nodes[0].next, """ 774comment "advanced comment" 775 depends on A && B 776""") 777 778 verify_custom_str(c.syms["ADVANCED_COMMENT_HOOK"].nodes[0].next, """ 779comment "advanced comment" 780 depends on [A] && [B] 781""") 782 783 784 print("Testing {MenuNode,Symbol,Choice}.orig_*") 785 786 # Just test some corner cases here re. MenuNode.orig_*. They are already 787 # indirectly tested above. Use MenuNode.__str__() as a proxy. 788 789 verify_str(c.syms["DEP_REM_CORNER_CASES"], """ 790config DEP_REM_CORNER_CASES 791 bool 792 default A 793 depends on n 794 795config DEP_REM_CORNER_CASES 796 bool 797 default B if n 798 799config DEP_REM_CORNER_CASES 800 bool 801 default C 802 depends on m && MODULES 803 804config DEP_REM_CORNER_CASES 805 bool 806 default D if A 807 808config DEP_REM_CORNER_CASES 809 bool 810 default E if !E1 811 default F if F1 = F2 812 default G if G1 || H1 813 depends on !H 814 815config DEP_REM_CORNER_CASES 816 bool 817 default H 818 depends on "foo" = "bar" 819 820config DEP_REM_CORNER_CASES 821 bool "prompt" if FOO || BAR 822 depends on BAZ && QAZ 823""") 824 825 # Test {Symbol,Choice}.orig_* 826 827 def verify_deps(elms, dep_index, expected): 828 verify_equal(" ".join(expr_str(elm[dep_index]) for elm in elms), 829 expected) 830 831 verify_deps(c.syms["BOOL_SYM_ORIG"].orig_defaults, 1, "DEP y y") 832 verify_deps(c.syms["BOOL_SYM_ORIG"].orig_selects, 1, "y DEP y") 833 verify_deps(c.syms["BOOL_SYM_ORIG"].orig_implies, 1, "y y DEP") 834 verify_deps(c.syms["INT_SYM_ORIG"].orig_ranges, 2, "DEP y DEP") 835 verify_deps(c.named_choices["CHOICE_ORIG"].orig_defaults, 1, "y DEP DEP") 836 837 838 print("Testing Symbol.__repr__()") 839 840 def verify_repr(item, s): 841 verify_equal(repr(item) + "\n", s[1:]) 842 843 c = Kconfig("Kconfiglib/tests/Krepr", warn=False) 844 845 verify_repr(c.n, """ 846<symbol n, tristate, value n, constant> 847""") 848 849 verify_repr(c.m, """ 850<symbol m, tristate, value m, constant> 851""") 852 853 verify_repr(c.y, """ 854<symbol y, tristate, value y, constant> 855""") 856 857 verify_repr(c.syms["UNDEFINED"], """ 858<symbol UNDEFINED, unknown, value "UNDEFINED", visibility n, direct deps n, undefined> 859""") 860 861 verify_repr(c.syms["BASIC"], """ 862<symbol BASIC, bool, value y, visibility n, direct deps y, Kconfiglib/tests/Krepr:9> 863""") 864 865 verify_repr(c.syms["VISIBLE"], """ 866<symbol VISIBLE, bool, "visible", value n, visibility y, direct deps y, Kconfiglib/tests/Krepr:14> 867""") 868 869 c.syms["VISIBLE"].set_value(2) 870 c.syms["STRING"].set_value("foo") 871 872 verify_repr(c.syms["VISIBLE"], """ 873<symbol VISIBLE, bool, "visible", value y, user value y, visibility y, direct deps y, Kconfiglib/tests/Krepr:14> 874""") 875 876 verify_repr(c.syms["STRING"], """ 877<symbol STRING, string, "visible", value "foo", user value "foo", visibility y, direct deps y, Kconfiglib/tests/Krepr:17> 878""") 879 880 verify_repr(c.syms["DIR_DEP_N"], """ 881<symbol DIR_DEP_N, unknown, value "DIR_DEP_N", visibility n, direct deps n, Kconfiglib/tests/Krepr:20> 882""") 883 884 verify_repr(c.syms["OPTIONS"], """ 885<symbol OPTIONS, unknown, value "OPTIONS", visibility n, allnoconfig_y, is the defconfig_list symbol, from environment variable ENV, direct deps y, Kconfiglib/tests/Krepr:23> 886""") 887 888 verify_repr(c.syms["MULTI_DEF"], """ 889<symbol MULTI_DEF, unknown, value "MULTI_DEF", visibility n, direct deps y, Kconfiglib/tests/Krepr:28, Kconfiglib/tests/Krepr:29> 890""") 891 892 verify_repr(c.syms["CHOICE_1"], """ 893<symbol CHOICE_1, tristate, "choice sym", value n, visibility m, choice symbol, direct deps m, Kconfiglib/tests/Krepr:36> 894""") 895 896 verify_repr(c.modules, """ 897<symbol MODULES, bool, value y, visibility n, is the modules symbol, direct deps y, Kconfiglib/tests/Krepr:1> 898""") 899 900 901 print("Testing Choice.__repr__()") 902 903 verify_repr(c.named_choices["CHOICE"], """ 904<choice CHOICE, tristate, "choice", mode m, visibility y, Kconfiglib/tests/Krepr:33> 905""") 906 907 c.named_choices["CHOICE"].set_value(2) 908 909 verify_repr(c.named_choices["CHOICE"], """ 910<choice CHOICE, tristate, "choice", mode y, user mode y, CHOICE_1 selected, visibility y, Kconfiglib/tests/Krepr:33> 911""") 912 913 c.syms["CHOICE_2"].set_value(2) 914 915 verify_repr(c.named_choices["CHOICE"], """ 916<choice CHOICE, tristate, "choice", mode y, user mode y, CHOICE_2 selected, CHOICE_2 selected by user, visibility y, Kconfiglib/tests/Krepr:33> 917""") 918 919 c.named_choices["CHOICE"].set_value(1) 920 921 verify_repr(c.named_choices["CHOICE"], """ 922<choice CHOICE, tristate, "choice", mode m, user mode m, CHOICE_2 selected by user (overridden), visibility y, Kconfiglib/tests/Krepr:33> 923""") 924 925 verify_repr(c.syms["CHOICE_HOOK"].nodes[0].next.item, """ 926<choice, tristate, "optional choice", mode n, visibility n, optional, Kconfiglib/tests/Krepr:46> 927""") 928 929 930 print("Testing MenuNode.__repr__()") 931 932 verify_repr(c.syms["BASIC"].nodes[0], """ 933<menu node for symbol BASIC, deps y, has help, has next, Kconfiglib/tests/Krepr:9> 934""") 935 936 verify_repr(c.syms["DIR_DEP_N"].nodes[0], """ 937<menu node for symbol DIR_DEP_N, deps n, has next, Kconfiglib/tests/Krepr:20> 938""") 939 940 verify_repr(c.syms["MULTI_DEF"].nodes[0], """ 941<menu node for symbol MULTI_DEF, deps y, has next, Kconfiglib/tests/Krepr:28> 942""") 943 944 verify_repr(c.syms["MULTI_DEF"].nodes[1], """ 945<menu node for symbol MULTI_DEF, deps y, has next, Kconfiglib/tests/Krepr:29> 946""") 947 948 verify_repr(c.syms["MENUCONFIG"].nodes[0], """ 949<menu node for symbol MENUCONFIG, is menuconfig, deps y, has next, Kconfiglib/tests/Krepr:31> 950""") 951 952 verify_repr(c.named_choices["CHOICE"].nodes[0], """ 953<menu node for choice CHOICE, prompt "choice" (visibility y), deps y, has child, has next, Kconfiglib/tests/Krepr:33> 954""") 955 956 verify_repr(c.syms["CHOICE_HOOK"].nodes[0].next, """ 957<menu node for choice, prompt "optional choice" (visibility n), deps y, has next, Kconfiglib/tests/Krepr:46> 958""") 959 960 verify_repr(c.syms["NO_VISIBLE_IF_HOOK"].nodes[0].next, """ 961<menu node for menu, prompt "no visible if" (visibility y), deps y, 'visible if' deps y, has next, Kconfiglib/tests/Krepr:53> 962""") 963 964 verify_repr(c.syms["VISIBLE_IF_HOOK"].nodes[0].next, """ 965<menu node for menu, prompt "visible if" (visibility y), deps y, 'visible if' deps m, has next, Kconfiglib/tests/Krepr:58> 966""") 967 968 verify_repr(c.syms["COMMENT_HOOK"].nodes[0].next, """ 969<menu node for comment, prompt "comment" (visibility y), deps y, Kconfiglib/tests/Krepr:64> 970""") 971 972 973 print("Testing Kconfig.__repr__()") 974 975 verify_repr(c, """ 976<configuration with 15 symbols, main menu prompt "Main menu", srctree is current directory, config symbol prefix "CONFIG_", warnings disabled, printing of warnings to stderr enabled, undef. symbol assignment warnings disabled, overriding symbol assignment warnings enabled, redundant symbol assignment warnings enabled> 977""") 978 979 os.environ["srctree"] = "Kconfiglib" 980 os.environ["CONFIG_"] = "CONFIG_ value" 981 982 c = Kconfig("tests/Krepr", warn=False) 983 c.warn = True 984 c.warn_to_stderr = False 985 c.warn_assign_override = False 986 c.warn_assign_redun = False 987 c.warn_assign_undef = True 988 989 verify_repr(c, """ 990<configuration with 15 symbols, main menu prompt "Main menu", srctree "Kconfiglib", config symbol prefix "CONFIG_ value", warnings enabled, printing of warnings to stderr disabled, undef. symbol assignment warnings enabled, overriding symbol assignment warnings disabled, redundant symbol assignment warnings disabled> 991""") 992 993 os.environ.pop("srctree", None) 994 os.environ.pop("CONFIG_", None) 995 996 997 print("Testing tricky help strings") 998 999 c = Kconfig("Kconfiglib/tests/Khelp") 1000 1001 def verify_help(node, s): 1002 verify_equal(node.help, s[1:-1]) 1003 1004 verify_help(c.syms["TWO_HELP_STRINGS"].nodes[0], """ 1005first help string 1006""") 1007 1008 verify_help(c.syms["TWO_HELP_STRINGS"].nodes[1], """ 1009second help string 1010""") 1011 1012 verify_help(c.syms["NO_BLANK_AFTER_HELP"].nodes[0], """ 1013help for 1014NO_BLANK_AFTER_HELP 1015""") 1016 1017 verify_help(c.named_choices["CHOICE_HELP"].nodes[0], """ 1018help for 1019CHOICE_HELP 1020""") 1021 1022 verify_help(c.syms["HELP_TERMINATED_BY_COMMENT"].nodes[0], """ 1023a 1024b 1025c 1026""") 1027 1028 verify_help(c.syms["TRICKY_HELP"].nodes[0], """ 1029a 1030 b 1031 c 1032 1033 d 1034 e 1035 f 1036 1037 1038g 1039 h 1040 i 1041""") 1042 1043 1044 print("Testing locations, source/rsource/gsource/grsource, and " 1045 "Kconfig.kconfig_filenames") 1046 1047 def verify_locations(nodes, *expected_locs): 1048 verify(len(nodes) == len(expected_locs), 1049 "Wrong number of locations for " + repr(nodes)) 1050 1051 for node, expected_loc in zip(nodes, expected_locs): 1052 node_loc = "{}:{}".format(node.filename, node.linenr) 1053 verify(node_loc == expected_loc, 1054 "expected {} to have the location {}, had the location {}" 1055 .format(repr(node), expected_loc, node_loc)) 1056 1057 # Expanded in the 'source' statement in Klocation 1058 1059 os.environ["TESTS_DIR_FROM_ENV"] = "tests" 1060 os.environ["SUB_DIR_FROM_ENV"] = "sub" 1061 1062 os.environ["_SOURCED"] = "_sourced" 1063 os.environ["_RSOURCED"] = "_rsourced" 1064 os.environ["_GSOURCED"] = "_gsourced" 1065 os.environ["_GRSOURCED"] = "_grsourced" 1066 1067 # Test twice, with $srctree as a relative and an absolute path, 1068 # respectively 1069 for srctree in "Kconfiglib", os.path.abspath("Kconfiglib"): 1070 os.environ["srctree"] = srctree 1071 1072 # Has symbol with empty help text, so disable warnings 1073 c = Kconfig("tests/Klocation", warn=False) 1074 1075 verify_locations(c.syms["UNDEFINED"].nodes) 1076 verify_equal(c.syms["UNDEFINED"].name_and_loc, "UNDEFINED (undefined)") 1077 1078 verify_locations(c.syms["ONE_DEF"].nodes, "tests/Klocation:4") 1079 verify_equal(c.syms["ONE_DEF"].name_and_loc, 1080 "ONE_DEF (defined at tests/Klocation:4)") 1081 1082 verify_locations(c.syms["TWO_DEF"].nodes, 1083 "tests/Klocation:7", 1084 "tests/Klocation:10") 1085 verify_equal(c.syms["TWO_DEF"].name_and_loc, 1086 "TWO_DEF (defined at tests/Klocation:7, tests/Klocation:10)") 1087 1088 verify_locations(c.syms["MANY_DEF"].nodes, 1089 "tests/Klocation:13", 1090 "tests/Klocation:43", 1091 "tests/Klocation:45", 1092 "tests/Klocation_sourced:3", 1093 "tests/sub/Klocation_rsourced:2", 1094 "tests/sub/Klocation_gsourced1:1", 1095 "tests/sub/Klocation_gsourced2:1", 1096 "tests/sub/Klocation_gsourced1:1", 1097 "tests/sub/Klocation_gsourced2:1", 1098 "tests/sub/Klocation_grsourced1:1", 1099 "tests/sub/Klocation_grsourced2:1", 1100 "tests/sub/Klocation_grsourced1:1", 1101 "tests/sub/Klocation_grsourced2:1", 1102 "tests/Klocation:78") 1103 1104 verify_locations(c.named_choices["CHOICE_ONE_DEF"].nodes, 1105 "tests/Klocation_sourced:5") 1106 verify_equal(c.named_choices["CHOICE_ONE_DEF"].name_and_loc, 1107 "<choice CHOICE_ONE_DEF> (defined at tests/Klocation_sourced:5)") 1108 1109 verify_locations(c.named_choices["CHOICE_TWO_DEF"].nodes, 1110 "tests/Klocation_sourced:9", 1111 "tests/Klocation_sourced:13") 1112 verify_equal(c.named_choices["CHOICE_TWO_DEF"].name_and_loc, 1113 "<choice CHOICE_TWO_DEF> (defined at tests/Klocation_sourced:9, tests/Klocation_sourced:13)") 1114 1115 verify_locations([c.syms["MENU_HOOK"].nodes[0].next], 1116 "tests/Klocation_sourced:20") 1117 1118 verify_locations([c.syms["COMMENT_HOOK"].nodes[0].next], 1119 "tests/Klocation_sourced:26") 1120 1121 # Test Kconfig.kconfig_filenames 1122 1123 verify_equal(c.kconfig_filenames, [ 1124 "tests/Klocation", 1125 "tests/Klocation_sourced", 1126 "tests/sub/Klocation_rsourced", 1127 "tests/sub/Klocation_gsourced1", 1128 "tests/sub/Klocation_gsourced2", 1129 "tests/sub/Klocation_gsourced1", 1130 "tests/sub/Klocation_gsourced2", 1131 "tests/sub/Klocation_grsourced1", 1132 "tests/sub/Klocation_grsourced2", 1133 "tests/sub/Klocation_grsourced1", 1134 "tests/sub/Klocation_grsourced2" 1135 ]) 1136 1137 # Test recursive 'source' detection 1138 1139 try: 1140 Kconfig("tests/Krecursive1") 1141 except KconfigError as e: 1142 verify_equal(str(e), """ 1143tests/Krecursive2:1: recursive 'source' of 'tests/Krecursive1' detected. Check that environment variables are set correctly. 1144Include path: 1145tests/Krecursive1:1 1146tests/Krecursive2:1 1147"""[:-1]) 1148 except: 1149 fail("recursive 'source' raised wrong exception") 1150 else: 1151 fail("recursive 'source' did not raise exception") 1152 1153 # Verify that source and rsource throw exceptions for missing files 1154 1155 # TODO: Make an exception test helper 1156 1157 try: 1158 Kconfig("tests/Kmissingsource") 1159 except KconfigError as e: 1160 if "not found" not in str(e): 1161 fail("'source' with missing file raised wrong KconfigError") 1162 except: 1163 fail("'source' with missing file raised wrong exception") 1164 else: 1165 fail("'source' with missing file did not raise exception") 1166 1167 try: 1168 Kconfig("tests/Kmissingrsource") 1169 except KconfigError as e: 1170 if "not found" not in str(e): 1171 fail("'rsource' with missing file raised wrong KconfigError") 1172 except: 1173 fail("'rsource' with missing file raised wrong exception") 1174 else: 1175 fail("'rsource' with missing file did not raise exception") 1176 1177 # Test a tricky case involving symlinks. $srctree is tests/symlink, which 1178 # points to tests/sub/sub, meaning tests/symlink/.. != tests/. Previously, 1179 # using 'rsource' from a file sourced with an absolute path triggered an 1180 # unsafe relpath() with tests/symlink/.. in it, crashing. 1181 1182 os.environ["srctree"] = "Kconfiglib/tests/symlink" 1183 os.environ["KCONFIG_SYMLINK_2"] = os.path.abspath( 1184 "Kconfiglib/tests/sub/Kconfig_symlink_2") 1185 if not os.path.isabs( 1186 Kconfig("Kconfig_symlink_1").syms["FOUNDME"].nodes[0].filename): 1187 1188 fail("Symlink + rsource issues") 1189 1190 1191 print("Testing Kconfig.node_iter()") 1192 1193 # Reuse tests/Klocation. The node_iter(unique_syms=True) case already gets 1194 # plenty of testing from write_config() as well. 1195 1196 os.environ["srctree"] = "Kconfiglib" 1197 c = Kconfig("tests/Klocation", warn=False) 1198 1199 verify_equal( 1200 [node.item.name for node in c.node_iter() 1201 if isinstance(node.item, Symbol)], 1202 ["ONE_DEF", "TWO_DEF", "TWO_DEF", "MANY_DEF", "HELP_1", "HELP_2", 1203 "HELP_3", "MANY_DEF", "MANY_DEF", "MANY_DEF", "MENU_HOOK", 1204 "COMMENT_HOOK"] + 10*["MANY_DEF"]) 1205 1206 verify_equal( 1207 [node.item.name for node in c.node_iter(True) 1208 if isinstance(node.item, Symbol)], 1209 ["ONE_DEF", "TWO_DEF", "MANY_DEF", "HELP_1", "HELP_2", "HELP_3", 1210 "MENU_HOOK", "COMMENT_HOOK"]) 1211 1212 verify_equal( 1213 [node.prompt[0] for node in c.node_iter() 1214 if not isinstance(node.item, Symbol)], 1215 ["one-def choice", "two-def choice 1", "two-def choice 2", 1216 "menu", "comment"]) 1217 1218 verify_equal( 1219 [node.prompt[0] for node in c.node_iter(True) 1220 if not isinstance(node.item, Symbol)], 1221 ["one-def choice", "two-def choice 1", "two-def choice 2", 1222 "menu", "comment"]) 1223 1224 1225 print("Testing MenuNode.include_path") 1226 1227 os.environ["srctree"] = "Kconfiglib/tests" 1228 1229 c = Kconfig("Kinclude_path") 1230 1231 def verify_node_path(node, *expected): 1232 if node.include_path != expected: 1233 fail("Wrong include path for node {!r}. Got {}, expected {}." 1234 .format(node, node.include_path, expected)) 1235 1236 def verify_sym_path(sym_name, node_i, *expected): 1237 verify_node_path(c.syms[sym_name].nodes[node_i], *expected) 1238 1239 verify_sym_path("TOP", 0) 1240 verify_sym_path("TOP", 1) 1241 verify_sym_path("TOP", 2) 1242 1243 verify_sym_path("ONE_DOWN", 0, ("Kinclude_path", 4)) 1244 verify_sym_path("ONE_DOWN", 1, ("Kinclude_path", 4)) 1245 verify_sym_path("ONE_DOWN", 2, ("Kinclude_path", 4)) 1246 verify_sym_path("ONE_DOWN", 3, ("Kinclude_path", 9)) 1247 verify_sym_path("ONE_DOWN", 4, ("Kinclude_path", 9)) 1248 verify_sym_path("ONE_DOWN", 5, ("Kinclude_path", 9)) 1249 1250 verify_sym_path("TWO_DOWN", 0, 1251 ("Kinclude_path", 4), ("Kinclude_path_sourced_1", 4)) 1252 verify_sym_path("TWO_DOWN", 1, 1253 ("Kinclude_path", 4), ("Kinclude_path_sourced_1", 9)) 1254 verify_sym_path("TWO_DOWN", 2, 1255 ("Kinclude_path", 9), ("Kinclude_path_sourced_1", 4)) 1256 verify_sym_path("TWO_DOWN", 3, 1257 ("Kinclude_path", 9), ("Kinclude_path_sourced_1", 9)) 1258 1259 verify_node_path(c.top_node) 1260 verify_node_path(c.menus[0], ("Kinclude_path", 4), ("Kinclude_path_sourced_1", 4)) 1261 verify_node_path(c.comments[0], ("Kinclude_path", 4), ("Kinclude_path_sourced_1", 4)) 1262 verify_node_path(c.choices[0].nodes[0], ("Kinclude_path", 4), ("Kinclude_path_sourced_1", 4)) 1263 1264 os.environ.pop("srctree", None) 1265 1266 1267 print("Testing Kconfig.choices/menus/comments") 1268 1269 c = Kconfig("Kconfiglib/tests/Kitemlists") 1270 1271 def verify_prompts(items, *expected_prompts): 1272 verify(len(items) == len(expected_prompts), 1273 "Wrong number of prompts for {}".format(items)) 1274 1275 for item, expected_prompt in zip(items, expected_prompts): 1276 if not isinstance(item, MenuNode): 1277 item = item.nodes[0] 1278 1279 verify(item.prompt[0] == expected_prompt, 1280 "Wrong prompt for {}, expected '{}'" 1281 .format(repr(item), expected_prompt)) 1282 1283 verify_prompts(c.choices, "choice 1", "choice 2", "choice 3", "choice 2") 1284 verify_prompts(c.menus, "menu 1", "menu 2", "menu 3", "menu 4", "menu 5") 1285 verify_prompts(c.comments, "comment 1", "comment 2", "comment 3") 1286 1287 1288 print("Testing Symbol/Choice.direct_dep") 1289 1290 c = Kconfig("Kconfiglib/tests/Kdirdep") 1291 1292 verify_equal(expr_str(c.syms["NO_DEP_SYM"].direct_dep), 'y') 1293 verify_equal(expr_str(c.syms["DEP_SYM"].direct_dep), "A || (B && C) || !D") 1294 1295 verify_equal(expr_str(c.named_choices["NO_DEP_CHOICE"].direct_dep), 'y') 1296 verify_equal(expr_str(c.named_choices["DEP_CHOICE"].direct_dep), 1297 "A || B || C") 1298 1299 1300 print("Testing expr_items()") 1301 1302 c = Kconfig("Kconfiglib/tests/Kexpr_items") 1303 1304 def verify_expr_items(expr, *sym_names): 1305 verify_equal(tuple(sorted(item.name for item in expr_items(expr))), 1306 sym_names) 1307 1308 verify_expr_items( 1309 c.syms["TEST"].defaults[0][0], 1310 "A", "B", "C", "D", "E", "F", "G", "H" 1311 ) 1312 1313 verify_expr_items( 1314 c.syms["TEST_CHOICE"].nodes[0].prompt[1], 1315 "A", "CHOICE" 1316 ) 1317 1318 1319 print("Testing MenuNode/Symbol/Choice.referenced") 1320 1321 c = Kconfig("Kconfiglib/tests/Kreferenced", warn=False) 1322 1323 def verify_deps(item, *dep_names): 1324 verify_equal(tuple(sorted(item.name for item in item.referenced)), 1325 dep_names) 1326 1327 verify_deps(c.top_node, "y") 1328 1329 verify_deps(c.syms["NO_REFS"].nodes[0], "y") 1330 1331 verify_deps(c.syms["JUST_DEPENDS_ON_REFS"].nodes[0], "A", "B") 1332 1333 verify_deps(c.syms["LOTS_OF_REFS"].nodes[0], 1334 *(chr(n) for n in range(ord("A"), ord("Z") + 1))) 1335 1336 verify_deps(c.syms["INT_REFS"].nodes[0], 1337 "A", "B", "C", "D", "E", "F", "G", "H", "y") 1338 1339 verify_deps(c.syms["CHOICE_REF"].nodes[0], "CHOICE") 1340 1341 verify_deps(c.menus[0], "A", "B", "C", "D") 1342 1343 verify_deps(c.comments[0], "A", "B") 1344 1345 verify_deps(c.syms["MULTI_DEF_SYM"], "A", "B", "C", "y") 1346 verify_deps(c.named_choices["MULTI_DEF_CHOICE"], "A", "B", "C") 1347 1348 1349 print("Testing split_expr()") 1350 1351 c = Kconfig("Kconfiglib/tests/empty") 1352 c.warn = False 1353 1354 def verify_split(to_split, op, operand_strs): 1355 # The same hackage as in Kconfig.eval_string() 1356 c._tokens = c._tokenize("if " + to_split)[1:] 1357 c._tokens_i = 0 1358 1359 operands = split_expr(c._parse_expr(False), op) 1360 1361 verify(len(operands) == len(operand_strs), 1362 "Wrong number of operands when {} was split by {}" 1363 .format(to_split, "OR" if op == OR else "AND")) 1364 1365 for operand, operand_str in zip(operands, operand_strs): 1366 verify_equal(expr_str(operand), operand_str) 1367 1368 verify_split("A", OR, ("A", )) 1369 verify_split("!A", OR, ("!A", )) 1370 verify_split("A = B", OR, ("A = B", )) 1371 verify_split("A && B", OR, ("A && B", )) 1372 verify_split("A || B", OR, ("A", "B" )) 1373 verify_split("(A || B) || C", OR, ("A", "B", "C" )) 1374 verify_split("A || (B || C)", OR, ("A", "B", "C" )) 1375 verify_split("A || !(B || C)", OR, ("A", "!(B || C)" )) 1376 verify_split("A || (B && (C || D))", OR, ("A", "B && (C || D)")) 1377 verify_split("(A && (B || C)) || D", OR, ("A && (B || C)", "D")) 1378 1379 verify_split("A", AND, ("A", )) 1380 verify_split("!A", AND, ("!A", )) 1381 verify_split("A = B", AND, ("A = B", )) 1382 verify_split("A || B", AND, ("A || B", )) 1383 verify_split("A && B", AND, ("A", "B" )) 1384 verify_split("(A && B) && C", AND, ("A", "B", "C" )) 1385 verify_split("A && (B && C)", AND, ("A", "B", "C" )) 1386 verify_split("A && !(B && C)", AND, ("A", "!(B && C)" )) 1387 verify_split("A && (B || (C && D))", AND, ("A", "B || (C && D)")) 1388 verify_split("(A || (B && C)) && D", AND, ("A || (B && C)", "D")) 1389 1390 1391 print("Testing visibility") 1392 1393 c = Kconfig("Kconfiglib/tests/Kvisibility") 1394 1395 def verify_visibility(item, no_module_vis, module_vis): 1396 c.modules.set_value(0) 1397 verify(item.visibility == no_module_vis, 1398 "expected {} to have visibility {} without modules, had " 1399 "visibility {}". 1400 format(repr(item), no_module_vis, item.visibility)) 1401 1402 c.modules.set_value(2) 1403 verify(item.visibility == module_vis, 1404 "expected {} to have visibility {} with modules, had " 1405 "visibility {}". 1406 format(repr(item), module_vis, item.visibility)) 1407 1408 # Symbol visibility 1409 1410 verify_visibility(c.syms["NO_PROMPT"], 0, 0) 1411 verify_visibility(c.syms["BOOL_N"], 0, 0) 1412 verify_visibility(c.syms["BOOL_M"], 0, 2) 1413 verify_visibility(c.syms["BOOL_MOD"], 2, 2) 1414 verify_visibility(c.syms["BOOL_Y"], 2, 2) 1415 verify_visibility(c.syms["TRISTATE_M"], 0, 1) 1416 verify_visibility(c.syms["TRISTATE_MOD"], 2, 1) 1417 verify_visibility(c.syms["TRISTATE_Y"], 2, 2) 1418 verify_visibility(c.syms["BOOL_IF_N"], 0, 0) 1419 verify_visibility(c.syms["BOOL_IF_M"], 0, 2) 1420 verify_visibility(c.syms["BOOL_IF_Y"], 2, 2) 1421 verify_visibility(c.syms["BOOL_MENU_N"], 0, 0) 1422 verify_visibility(c.syms["BOOL_MENU_M"], 0, 2) 1423 verify_visibility(c.syms["BOOL_MENU_Y"], 2, 2) 1424 verify_visibility(c.syms["BOOL_CHOICE_N"], 0, 0) 1425 1426 # Non-tristate symbols in tristate choices are only visible if the choice 1427 # is in y mode 1428 1429 # The choice can't be brought to y mode because of the 'if m' 1430 verify_visibility(c.syms["BOOL_CHOICE_M"], 0, 0) 1431 c.syms["BOOL_CHOICE_M"].choice.set_value(2) 1432 verify_visibility(c.syms["BOOL_CHOICE_M"], 0, 0) 1433 1434 # The choice gets y mode only when running without modules, because it 1435 # defaults to m mode 1436 verify_visibility(c.syms["BOOL_CHOICE_Y"], 2, 0) 1437 c.syms["BOOL_CHOICE_Y"].choice.set_value(2) 1438 # When set to y mode, the choice symbol becomes visible both with and 1439 # without modules 1440 verify_visibility(c.syms["BOOL_CHOICE_Y"], 2, 2) 1441 1442 verify_visibility(c.syms["TRISTATE_IF_N"], 0, 0) 1443 verify_visibility(c.syms["TRISTATE_IF_M"], 0, 1) 1444 verify_visibility(c.syms["TRISTATE_IF_Y"], 2, 2) 1445 verify_visibility(c.syms["TRISTATE_MENU_N"], 0, 0) 1446 verify_visibility(c.syms["TRISTATE_MENU_M"], 0, 1) 1447 verify_visibility(c.syms["TRISTATE_MENU_Y"], 2, 2) 1448 verify_visibility(c.syms["TRISTATE_CHOICE_N"], 0, 0) 1449 verify_visibility(c.syms["TRISTATE_CHOICE_M"], 0, 1) 1450 verify_visibility(c.syms["TRISTATE_CHOICE_Y"], 2, 2) 1451 1452 verify_visibility(c.named_choices["BOOL_CHOICE_N"], 0, 0) 1453 verify_visibility(c.named_choices["BOOL_CHOICE_M"], 0, 2) 1454 verify_visibility(c.named_choices["BOOL_CHOICE_Y"], 2, 2) 1455 verify_visibility(c.named_choices["TRISTATE_CHOICE_N"], 0, 0) 1456 verify_visibility(c.named_choices["TRISTATE_CHOICE_M"], 0, 1) 1457 verify_visibility(c.named_choices["TRISTATE_CHOICE_Y"], 2, 2) 1458 1459 verify_visibility(c.named_choices["TRISTATE_CHOICE_IF_M_AND_Y"], 0, 1) 1460 verify_visibility(c.named_choices["TRISTATE_CHOICE_MENU_N_AND_Y"], 0, 0) 1461 1462 # Verify that 'visible if' visibility gets propagated to prompts 1463 1464 verify_visibility(c.syms["VISIBLE_IF_N"], 0, 0) 1465 verify_visibility(c.syms["VISIBLE_IF_M"], 0, 1) 1466 verify_visibility(c.syms["VISIBLE_IF_Y"], 2, 2) 1467 verify_visibility(c.syms["VISIBLE_IF_M_2"], 0, 1) 1468 1469 # Verify that string/int/hex symbols with m visibility accept a user value 1470 1471 assign_and_verify("STRING_m", "foo bar") 1472 assign_and_verify("INT_m", "123") 1473 assign_and_verify("HEX_m", "0x123") 1474 1475 1476 print("Testing .assignable") 1477 1478 c = Kconfig("Kconfiglib/tests/Kassignable") 1479 1480 def verify_assignable_imp(item, assignable_no_modules, assignable_modules): 1481 # Verifies the assignable values for 'item', with and without modules. 1482 1483 for modules_val, assignable in (0, assignable_no_modules), \ 1484 (2, assignable_modules): 1485 1486 c.modules.set_value(modules_val) 1487 module_msg = "without modules" if modules_val == 0 else \ 1488 "with modules" 1489 1490 verify(item.assignable == assignable, 1491 "Incorrect assignable values for {} {}. Should be {}, " 1492 "was {}." 1493 .format(item.name, module_msg, assignable, item.assignable)) 1494 1495 # Verify that the values can actually be assigned too 1496 1497 for val in item.assignable: 1498 item.set_value(val) 1499 verify(item.tri_value == val, 1500 "Unable to set {} to {} {}, even though it was in " 1501 ".assignable".format(item.name, val, module_msg)) 1502 1503 def verify_assignable(sym_name, assignable_no_modules, assignable_modules): 1504 verify_assignable_imp(c.syms[sym_name], 1505 assignable_no_modules, 1506 assignable_modules) 1507 1508 def verify_const_unassignable(sym_name): 1509 verify_assignable_imp(c.const_syms[sym_name], (), ()) 1510 1511 # Things that shouldn't be .assignable 1512 verify_const_unassignable("n") 1513 verify_const_unassignable("m") 1514 verify_const_unassignable("y") 1515 verify_const_unassignable("const") 1516 verify_assignable("UNDEFINED", (), ()) 1517 verify_assignable("NO_PROMPT", (), ()) 1518 verify_assignable("STRING", (), ()) 1519 verify_assignable("INT", (), ()) 1520 verify_assignable("HEX", (), ()) 1521 1522 # Non-selected symbols 1523 verify_assignable("Y_VIS_BOOL", (0, 2), (0, 2)) 1524 verify_assignable("M_VIS_BOOL", ( ), (0, 2)) # Vis. promoted 1525 verify_assignable("N_VIS_BOOL", ( ), ( )) 1526 verify_assignable("Y_VIS_TRI", (0, 2), (0, 1, 2)) 1527 verify_assignable("M_VIS_TRI", ( ), (0, 1 )) 1528 verify_assignable("N_VIS_TRI", ( ), ( )) 1529 1530 # Symbols selected to y 1531 verify_assignable("Y_SEL_Y_VIS_BOOL", (2,), (2,)) 1532 verify_assignable("Y_SEL_M_VIS_BOOL", ( ), (2,)) # Vis. promoted 1533 verify_assignable("Y_SEL_N_VIS_BOOL", ( ), ( )) 1534 verify_assignable("Y_SEL_Y_VIS_TRI", (2,), (2,)) 1535 verify_assignable("Y_SEL_M_VIS_TRI", ( ), (2,)) 1536 verify_assignable("Y_SEL_N_VIS_TRI", ( ), ( )) 1537 1538 # Symbols selected to m 1539 verify_assignable("M_SEL_Y_VIS_BOOL", (2,), ( 2,)) # Value promoted 1540 verify_assignable("M_SEL_M_VIS_BOOL", ( ), ( 2,)) # Vis./value promoted 1541 verify_assignable("M_SEL_N_VIS_BOOL", ( ), ( )) 1542 verify_assignable("M_SEL_Y_VIS_TRI", (2,), (1, 2 )) 1543 verify_assignable("M_SEL_M_VIS_TRI", ( ), (1, )) 1544 verify_assignable("M_SEL_N_VIS_TRI", ( ), ( )) 1545 1546 # Symbols implied to y 1547 verify_assignable("Y_IMP_Y_VIS_BOOL", (0, 2), (0, 2)) 1548 verify_assignable("Y_IMP_M_VIS_BOOL", ( ), (0, 2)) # Vis. promoted 1549 verify_assignable("Y_IMP_N_VIS_BOOL", ( ), ( )) 1550 verify_assignable("Y_IMP_Y_VIS_TRI", (0, 2), (0, 2)) # m removed by imply 1551 verify_assignable("Y_IMP_M_VIS_TRI", ( ), (0, 2)) # m promoted to y by imply 1552 verify_assignable("Y_IMP_N_VIS_TRI", ( ), ( )) 1553 1554 # Symbols implied to m (never affects assignable values) 1555 verify_assignable("M_IMP_Y_VIS_BOOL", (0, 2), (0, 2)) 1556 verify_assignable("M_IMP_M_VIS_BOOL", ( ), (0, 2)) # Vis. promoted 1557 verify_assignable("M_IMP_N_VIS_BOOL", ( ), ( )) 1558 verify_assignable("M_IMP_Y_VIS_TRI", (0, 2), (0, 1, 2)) 1559 verify_assignable("M_IMP_M_VIS_TRI", ( ), (0, 1 )) 1560 verify_assignable("M_IMP_N_VIS_TRI", ( ), ( )) 1561 1562 # Symbols in y-mode choice 1563 verify_assignable("Y_CHOICE_BOOL", (2,), (2,)) 1564 verify_assignable("Y_CHOICE_TRISTATE", (2,), (2,)) 1565 verify_assignable("Y_CHOICE_N_VIS_TRISTATE", ( ), ( )) 1566 1567 # Symbols in m/y-mode choice, starting out in m mode, or y mode when 1568 # running without modules 1569 verify_assignable("MY_CHOICE_BOOL", (2,), ( )) 1570 verify_assignable("MY_CHOICE_TRISTATE", (2,), (0, 1)) 1571 verify_assignable("MY_CHOICE_N_VIS_TRISTATE", ( ), ( )) 1572 1573 c.named_choices["MY_CHOICE"].set_value(2) 1574 1575 # Symbols in m/y-mode choice, now in y mode 1576 verify_assignable("MY_CHOICE_BOOL", (2,), (2,)) 1577 verify_assignable("MY_CHOICE_TRISTATE", (2,), (2,)) 1578 verify_assignable("MY_CHOICE_N_VIS_TRISTATE", ( ), ( )) 1579 1580 def verify_choice_assignable(choice_name, assignable_no_modules, 1581 assignable_modules): 1582 verify_assignable_imp(c.named_choices[choice_name], 1583 assignable_no_modules, 1584 assignable_modules) 1585 1586 # Choices with various possible modes 1587 verify_choice_assignable("Y_CHOICE", (2, ), ( 2,)) 1588 verify_choice_assignable("MY_CHOICE", (2, ), ( 1, 2 )) 1589 verify_choice_assignable("NMY_CHOICE", (0, 2), (0, 1, 2 )) 1590 verify_choice_assignable("NY_CHOICE", (0, 2), (0, 2 )) 1591 verify_choice_assignable("NM_CHOICE", ( ), (0, 1 )) 1592 verify_choice_assignable("M_CHOICE", ( ), ( 1, )) 1593 verify_choice_assignable("N_CHOICE", ( ), ( )) 1594 1595 1596 print("Testing object relations") 1597 1598 c = Kconfig("Kconfiglib/tests/Krelation") 1599 1600 verify(c.syms["A"].nodes[0].parent is c.top_node, 1601 "A's parent should be the top node") 1602 1603 verify(c.syms["B"].nodes[0].parent.item is c.named_choices["CHOICE_1"], 1604 "B's parent should be the first choice") 1605 1606 verify(c.syms["C"].nodes[0].parent.item is c.syms["B"], 1607 "C's parent should be B (due to auto menus)") 1608 1609 verify(c.syms["E"].nodes[0].parent.item == MENU, 1610 "E's parent should be a menu") 1611 1612 verify(c.syms["E"].nodes[0].parent.parent is c.top_node, 1613 "E's grandparent should be the top node") 1614 1615 verify(c.syms["G"].nodes[0].parent.item is c.named_choices["CHOICE_2"], 1616 "G's parent should be the second choice") 1617 1618 verify(c.syms["G"].nodes[0].parent.parent.item == MENU, 1619 "G's grandparent should be a menu") 1620 1621 1622 print("Testing hex/int ranges") 1623 1624 c = Kconfig("Kconfiglib/tests/Krange", warn=False) 1625 1626 for sym_name in "HEX_NO_RANGE", "INT_NO_RANGE", "HEX_40", "INT_40": 1627 sym = c.syms[sym_name] 1628 verify(not sym.ranges, 1629 "{} should not have ranges".format(sym_name)) 1630 1631 for sym_name in "HEX_ALL_RANGES_DISABLED", "INT_ALL_RANGES_DISABLED", \ 1632 "HEX_RANGE_10_20_LOW_DEFAULT", \ 1633 "INT_RANGE_10_20_LOW_DEFAULT": 1634 sym = c.syms[sym_name] 1635 verify(sym.ranges, "{} should have ranges".format(sym_name)) 1636 1637 # hex/int symbols without defaults should get no default value 1638 verify_value("HEX_NO_RANGE", "") 1639 verify_value("INT_NO_RANGE", "") 1640 # And neither if all ranges are disabled 1641 verify_value("HEX_ALL_RANGES_DISABLED", "") 1642 verify_value("INT_ALL_RANGES_DISABLED", "") 1643 # Make sure they are assignable though, and test that the form of the user 1644 # value is reflected in the value for hex symbols 1645 assign_and_verify("HEX_NO_RANGE", "0x123") 1646 assign_and_verify("HEX_NO_RANGE", "123") 1647 assign_and_verify("INT_NO_RANGE", "123") 1648 1649 # Defaults outside of the valid range should be clamped 1650 verify_value("HEX_RANGE_10_20_LOW_DEFAULT", "0x10") 1651 verify_value("HEX_RANGE_10_20_HIGH_DEFAULT", "0x20") 1652 verify_value("INT_RANGE_10_20_LOW_DEFAULT", "10") 1653 verify_value("INT_RANGE_10_20_HIGH_DEFAULT", "20") 1654 # Defaults inside the valid range should be preserved. For hex symbols, 1655 # they should additionally use the same form as in the assignment. 1656 verify_value("HEX_RANGE_10_20_OK_DEFAULT", "0x15") 1657 verify_value("HEX_RANGE_10_20_OK_DEFAULT_ALTERNATE", "15") 1658 verify_value("INT_RANGE_10_20_OK_DEFAULT", "15") 1659 1660 # hex/int symbols with no defaults but valid ranges should default to the 1661 # lower end of the range if it's > 0 1662 verify_value("HEX_RANGE_10_20", "0x10") 1663 verify_value("HEX_RANGE_0_10", "") 1664 verify_value("INT_RANGE_10_20", "10") 1665 verify_value("INT_RANGE_0_10", "") 1666 verify_value("INT_RANGE_NEG_10_10", "") 1667 1668 # User values and dependent ranges 1669 1670 # Avoid warnings for assigning values outside the active range 1671 c.warn = False 1672 1673 def verify_range(sym_name, low, high, default): 1674 # Verifies that all values in the range 'low'-'high' can be assigned, 1675 # and that assigning values outside the range reverts the value back to 1676 # 'default' (None if it should revert back to ""). 1677 1678 is_hex = (c.syms[sym_name].type == HEX) 1679 1680 for i in range(low, high + 1): 1681 assign_and_verify_user_value(sym_name, str(i), str(i), True) 1682 if is_hex: 1683 # The form of the user value should be preserved for hex 1684 # symbols 1685 assign_and_verify_user_value(sym_name, hex(i), hex(i), True) 1686 1687 # Verify that assigning a user value just outside the range causes 1688 # defaults to be used 1689 1690 if default is None: 1691 default_str = "" 1692 else: 1693 default_str = hex(default) if is_hex else str(default) 1694 1695 if is_hex: 1696 too_low_str = hex(low - 1) 1697 too_high_str = hex(high + 1) 1698 else: 1699 too_low_str = str(low - 1) 1700 too_high_str = str(high + 1) 1701 1702 assign_and_verify_value(sym_name, too_low_str, default_str) 1703 assign_and_verify_value(sym_name, too_high_str, default_str) 1704 1705 verify_range("HEX_RANGE_10_20_LOW_DEFAULT", 0x10, 0x20, 0x10) 1706 verify_range("HEX_RANGE_10_20_HIGH_DEFAULT", 0x10, 0x20, 0x20) 1707 verify_range("HEX_RANGE_10_20_OK_DEFAULT", 0x10, 0x20, 0x15) 1708 1709 verify_range("INT_RANGE_10_20_LOW_DEFAULT", 10, 20, 10) 1710 verify_range("INT_RANGE_10_20_HIGH_DEFAULT", 10, 20, 20) 1711 verify_range("INT_RANGE_10_20_OK_DEFAULT", 10, 20, 15) 1712 1713 verify_range("HEX_RANGE_10_20", 0x10, 0x20, 0x10) 1714 1715 verify_range("INT_RANGE_10_20", 10, 20, 10) 1716 verify_range("INT_RANGE_0_10", 0, 10, None) 1717 verify_range("INT_RANGE_NEG_10_10", -10, 10, None) 1718 1719 # Dependent ranges 1720 1721 verify_value("HEX_40", "40") 1722 verify_value("INT_40", "40") 1723 1724 c.syms["HEX_RANGE_10_20"].unset_value() 1725 c.syms["INT_RANGE_10_20"].unset_value() 1726 verify_value("HEX_RANGE_10_40_DEPENDENT", "0x10") 1727 verify_value("INT_RANGE_10_40_DEPENDENT", "10") 1728 c.syms["HEX_RANGE_10_20"].set_value("15") 1729 c.syms["INT_RANGE_10_20"].set_value("15") 1730 verify_value("HEX_RANGE_10_40_DEPENDENT", "0x15") 1731 verify_value("INT_RANGE_10_40_DEPENDENT", "15") 1732 c.unset_values() 1733 verify_range("HEX_RANGE_10_40_DEPENDENT", 0x10, 0x40, 0x10) 1734 verify_range("INT_RANGE_10_40_DEPENDENT", 10, 40, 10) 1735 1736 # Ranges and symbols defined in multiple locations 1737 1738 verify_value("INACTIVE_RANGE", "2") 1739 verify_value("ACTIVE_RANGE", "1") 1740 1741 1742 print("Testing defconfig_filename") 1743 1744 c = Kconfig("Kconfiglib/tests/empty") 1745 verify(c.defconfig_filename is None, 1746 "defconfig_filename should be None with no defconfig_list symbol") 1747 1748 c = Kconfig("Kconfiglib/tests/Kdefconfig_nonexistent") 1749 verify(c.defconfig_filename is None, 1750 "defconfig_filename should be None when none of the files in the " 1751 "defconfig_list symbol exist") 1752 1753 # Referenced in Kdefconfig_existent(_but_n) 1754 os.environ["FOO"] = "defconfig_2" 1755 1756 c = Kconfig("Kconfiglib/tests/Kdefconfig_existent_but_n") 1757 verify(c.defconfig_filename is None, 1758 "defconfig_filename should be None when the condition is n for all " 1759 "the defaults") 1760 1761 c = Kconfig("Kconfiglib/tests/Kdefconfig_existent") 1762 verify(c.defconfig_filename == "Kconfiglib/tests/defconfig_2", 1763 "defconfig_filename should return the existing file " 1764 "Kconfiglib/tests/defconfig_2") 1765 1766 # Should also look relative to $srctree if the specified defconfig is a 1767 # relative path and can't be opened 1768 1769 c = Kconfig("Kconfiglib/tests/Kdefconfig_srctree") 1770 verify(c.defconfig_filename == "Kconfiglib/tests/defconfig_2", 1771 "defconfig_filename gave wrong file with $srctree unset") 1772 1773 os.environ["srctree"] = "Kconfiglib/tests" 1774 c = Kconfig("Kdefconfig_srctree") 1775 verify(c.defconfig_filename == "Kconfiglib/tests/sub/defconfig_in_sub", 1776 "defconfig_filename gave wrong file with $srctree set") 1777 1778 os.environ.pop("srctree", None) 1779 1780 1781 print("Testing mainmenu_text") 1782 1783 c = Kconfig("Kconfiglib/tests/empty") 1784 verify(c.mainmenu_text == "Main menu", 1785 "An empty Kconfig should get a default main menu prompt") 1786 1787 # Expanded in the mainmenu text 1788 os.environ["FOO"] = "bar baz" 1789 c = Kconfig("Kconfiglib/tests/Kmainmenu") 1790 verify(c.mainmenu_text == "---bar baz---", 1791 "Wrong mainmenu text") 1792 1793 1794 print("Testing user_value") 1795 1796 # References undefined env. var. Disable warnings. 1797 c = Kconfig("Kconfiglib/tests/Kmisc", warn=False) 1798 1799 # Avoid warnings from assigning invalid user values and assigning user 1800 # values to symbols without prompts 1801 c.warn = False 1802 1803 syms = [c.syms[name] for name in 1804 ("BOOL", "TRISTATE", "STRING", "INT", "HEX")] 1805 1806 for sym in syms: 1807 verify(sym.user_value is None, 1808 "{} should not have a user value to begin with") 1809 1810 # Assign valid values for the types 1811 1812 assign_and_verify_user_value("BOOL", 0, 0, True) 1813 assign_and_verify_user_value("BOOL", 2, 2, True) 1814 assign_and_verify_user_value("TRISTATE", 0, 0, True) 1815 assign_and_verify_user_value("TRISTATE", 1, 1, True) 1816 assign_and_verify_user_value("TRISTATE", 2, 2, True) 1817 assign_and_verify_user_value("STRING", "foo bar", "foo bar", True) 1818 assign_and_verify_user_value("INT", "123", "123", True) 1819 assign_and_verify_user_value("HEX", "0x123", "0x123", True) 1820 1821 # Assign invalid values for the types. They should retain their old user 1822 # value. 1823 1824 assign_and_verify_user_value("BOOL", 1, 2, False) 1825 assign_and_verify_user_value("BOOL", "foo", 2, False) 1826 assign_and_verify_user_value("BOOL", "1", 2, False) 1827 assign_and_verify_user_value("TRISTATE", "foo", 2, False) 1828 assign_and_verify_user_value("TRISTATE", "1", 2, False) 1829 assign_and_verify_user_value("STRING", 0, "foo bar", False) 1830 assign_and_verify_user_value("INT", "foo", "123", False) 1831 assign_and_verify_user_value("INT", 0, "123", False) 1832 assign_and_verify_user_value("HEX", "foo", "0x123", False) 1833 assign_and_verify_user_value("HEX", 0, "0x123", False) 1834 assign_and_verify_user_value("HEX", "-0x1", "0x123", False) 1835 1836 for s in syms: 1837 s.unset_value() 1838 verify(s.user_value is None, 1839 "{} should not have a user value after being reset". 1840 format(s.name)) 1841 1842 1843 print("Testing is_menuconfig") 1844 1845 c = Kconfig("Kconfiglib/tests/Kmenuconfig") 1846 1847 for not_menuconfig in c.syms["NOT_MENUCONFIG_1"].nodes[0], \ 1848 c.syms["NOT_MENUCONFIG_2"].nodes[0], \ 1849 c.syms["MENUCONFIG_MULTI_DEF"].nodes[0], \ 1850 c.syms["COMMENT_HOOK"].nodes[0].next: 1851 1852 verify(not not_menuconfig.is_menuconfig, 1853 "'{}' should have is_menuconfig False".format(not_menuconfig)) 1854 1855 for menuconfig in c.top_node, \ 1856 c.syms["MENUCONFIG_1"].nodes[0], \ 1857 c.syms["MENUCONFIG_MULTI_DEF"].nodes[1], \ 1858 c.syms["MENU_HOOK"].nodes[0].next, \ 1859 c.syms["CHOICE_HOOK"].nodes[0].next: 1860 1861 verify(menuconfig.is_menuconfig, 1862 "'{}' should have is_menuconfig True".format(menuconfig)) 1863 1864 1865 print("Testing 'option env' semantics") 1866 1867 os.environ["ENV_VAR"] = "ENV_VAR value" 1868 1869 # References undefined env. var., so disable warnings 1870 c = Kconfig("Kconfiglib/tests/Kmisc", warn=False) 1871 1872 # Verify that 'option env' is treated like a default 1873 verify_value("FROM_ENV", "ENV_VAR value") 1874 verify_value("FROM_ENV_MISSING", "missing") 1875 1876 verify_value("FROM_ENV_WEIRD", "weird") 1877 1878 1879 print("Testing defined vs undefined symbols") 1880 1881 for name in "A", "B", "C", "D", "BOOL", "TRISTATE", "STRING", "INT", "HEX": 1882 verify(c.syms[name].nodes, 1883 "{} should be defined".format(name)) 1884 1885 for name in "NOT_DEFINED_1", "NOT_DEFINED_2", "NOT_DEFINED_3", \ 1886 "NOT_DEFINED_4": 1887 sym = c.syms[name] 1888 verify(not c.syms[name].nodes, 1889 "{} should not be defined".format(name)) 1890 1891 1892 print("Testing Symbol.choice") 1893 1894 for name in "A", "B", "C", "D": 1895 verify(c.syms[name].choice is not None, 1896 "{} should be a choice symbol".format(name)) 1897 1898 for name in "Q1", "Q2", "Q3", "BOOL", "TRISTATE", "STRING", "INT", "HEX", \ 1899 "FROM_ENV", "FROM_ENV_MISSING", "NOT_DEFINED_1", \ 1900 "NOT_DEFINED_2", "NOT_DEFINED_3", "NOT_DEFINED_4": 1901 verify(c.syms[name].choice is None, 1902 "{} should not be a choice symbol".format(name)) 1903 1904 1905 print("Testing is_allnoconfig_y") 1906 1907 verify(not c.syms["NOT_ALLNOCONFIG_Y"].is_allnoconfig_y, 1908 "NOT_ALLNOCONFIG_Y should not be allnoconfig_y") 1909 verify(c.syms["ALLNOCONFIG_Y"].is_allnoconfig_y, 1910 "ALLNOCONFIG_Y should be allnoconfig_y") 1911 1912 1913 print("Testing .config reading and writing") 1914 1915 config_test_file = "Kconfiglib/tests/config_test" 1916 1917 def verify_file_contents(fname, contents): 1918 with open(fname, "r") as f: 1919 file_contents = f.read() 1920 verify(file_contents == contents, 1921 "{} contains '{}'. Expected '{}'." 1922 .format(fname, file_contents, contents)) 1923 1924 # Writing/reading strings with characters that need to be escaped 1925 1926 c = Kconfig("Kconfiglib/tests/Kescape") 1927 1928 # Test the default value 1929 c.write_config(config_test_file + "_from_def") 1930 verify_file_contents(config_test_file + "_from_def", 1931 r'''CONFIG_STRING="\"\\"''' "\n") 1932 # Write our own value 1933 c.syms["STRING"].set_value(r'''\"a'\\''') 1934 c.write_config(config_test_file + "_from_user") 1935 verify_file_contents(config_test_file + "_from_user", 1936 r'''CONFIG_STRING="\\\"a'\\\\"''' "\n") 1937 1938 # Read back the two configs and verify the respective values 1939 c.load_config(config_test_file + "_from_def") 1940 verify_value("STRING", '"\\') 1941 c.load_config(config_test_file + "_from_user") 1942 verify_value("STRING", r'''\"a'\\''') 1943 1944 # Appending values from a .config 1945 1946 c = Kconfig("Kconfiglib/tests/Kappend") 1947 1948 # Values before assigning 1949 verify_value("BOOL", "n") 1950 verify_value("STRING", "") 1951 1952 # Assign BOOL 1953 c.load_config("Kconfiglib/tests/config_set_bool", replace=False) 1954 verify_value("BOOL", "y") 1955 verify_value("STRING", "") 1956 1957 # Assign STRING 1958 c.load_config("Kconfiglib/tests/config_set_string", replace=False) 1959 verify_value("BOOL", "y") 1960 verify_value("STRING", "foo bar") 1961 1962 # Reset BOOL 1963 c.load_config("Kconfiglib/tests/config_set_string") 1964 verify_value("BOOL", "n") 1965 verify_value("STRING", "foo bar") 1966 1967 # Loading a completely empty .config should reset values 1968 c.load_config("Kconfiglib/tests/empty") 1969 verify_value("STRING", "") 1970 1971 # An indented assignment in a .config should be ignored 1972 c.load_config("Kconfiglib/tests/config_indented") 1973 verify_value("IGNOREME", "y") 1974 1975 # Symbol order in headers and minimal configuration files should match 1976 # definition order, like in .config files 1977 1978 c = Kconfig("Kconfiglib/tests/Korder") 1979 1980 c.write_autoconf(config_test_file) 1981 verify_file_contents(config_test_file, """ 1982#define CONFIG_O 0 1983#define CONFIG_R 1 1984#define CONFIG_D 2 1985#define CONFIG_E 3 1986#define CONFIG_R2 4 1987#define CONFIG_I 5 1988#define CONFIG_N 6 1989#define CONFIG_G 7 1990"""[1:]) 1991 1992 # Differs from defaults 1993 c.syms["O"].set_value("-1") 1994 c.syms["R"].set_value("-1") 1995 c.syms["E"].set_value("-1") 1996 c.syms["R2"].set_value("-1") 1997 c.syms["N"].set_value("-1") 1998 c.syms["G"].set_value("-1") 1999 c.write_min_config(config_test_file) 2000 verify_file_contents(config_test_file, """ 2001CONFIG_O=-1 2002CONFIG_R=-1 2003CONFIG_E=-1 2004CONFIG_R2=-1 2005CONFIG_N=-1 2006CONFIG_G=-1 2007"""[1:]) 2008 2009 # Test header strings in configuration files and headers 2010 2011 os.environ["KCONFIG_CONFIG_HEADER"] = "config header from env.\n" 2012 os.environ["KCONFIG_AUTOHEADER_HEADER"] = "header header from env.\n" 2013 2014 c = Kconfig("Kconfiglib/tests/Kheader") 2015 c.write_config(config_test_file, header="config header from param\n") 2016 verify_file_contents(config_test_file, """\ 2017config header from param 2018CONFIG_FOO=y 2019""") 2020 c.write_min_config(config_test_file, header="min. config header from param\n") 2021 verify_file_contents(config_test_file, """\ 2022min. config header from param 2023""") 2024 c.write_config(config_test_file) 2025 verify_file_contents(config_test_file, """\ 2026config header from env. 2027CONFIG_FOO=y 2028""") 2029 c.write_min_config(config_test_file) 2030 verify_file_contents(config_test_file, """\ 2031config header from env. 2032""") 2033 c.write_autoconf(config_test_file, header="header header from param\n") 2034 verify_file_contents(config_test_file, """\ 2035header header from param 2036#define CONFIG_FOO 1 2037""") 2038 c.write_autoconf(config_test_file) 2039 verify_file_contents(config_test_file, """\ 2040header header from env. 2041#define CONFIG_FOO 1 2042""") 2043 2044 del os.environ["KCONFIG_CONFIG_HEADER"] 2045 del os.environ["KCONFIG_AUTOHEADER_HEADER"] 2046 2047 2048 print("Testing Kconfig fetching and separation") 2049 2050 for c in Kconfig("Kconfiglib/tests/Kmisc", warn=False), \ 2051 Kconfig("Kconfiglib/tests/Kmisc", warn=False): 2052 for item in c.syms["BOOL"], \ 2053 c.syms["BOOL"].nodes[0], \ 2054 c.named_choices["OPTIONAL"], \ 2055 c.named_choices["OPTIONAL"].nodes[0], \ 2056 c.syms["MENU_HOOK"].nodes[0].next, \ 2057 c.syms["COMMENT_HOOK"].nodes[0].next: 2058 verify(item.kconfig is c, 2059 ".kconfig not properly set for " + repr(item)) 2060 2061 2062 print("Testing imply semantics") 2063 2064 c = Kconfig("Kconfiglib/tests/Kimply") 2065 2066 verify_value("IMPLY_DIRECT_DEPS", "y") 2067 verify_value("UNMET_DIRECT_1", "n") 2068 verify_value("UNMET_DIRECT_2", "n") 2069 verify_value("UNMET_DIRECT_3", "n") 2070 verify_value("MET_DIRECT_1", "y") 2071 verify_value("MET_DIRECT_2", "y") 2072 verify_value("MET_DIRECT_3", "y") 2073 verify_value("MET_DIRECT_4", "y") 2074 2075 verify_value("IMPLY_COND", "y") 2076 verify_value("IMPLIED_N_COND", "n") 2077 verify_value("IMPLIED_M_COND", "m") 2078 verify_value("IMPLIED_Y_COND", "y") 2079 2080 verify_value("IMPLY_N_1", "n") 2081 verify_value("IMPLY_N_2", "n") 2082 verify_value("IMPLIED_FROM_N_1", "n") 2083 verify_value("IMPLIED_FROM_N_2", "n") 2084 2085 verify_value("IMPLY_M", "m") 2086 verify_value("IMPLIED_M", "m") 2087 verify_value("IMPLIED_M_BOOL", "y") 2088 2089 verify_value("IMPLY_M_TO_Y", "y") 2090 verify_value("IMPLIED_M_TO_Y", "y") 2091 2092 # Test user value semantics 2093 2094 # Verify that IMPLIED_TRISTATE is invalidated if the direct 2095 # dependencies change 2096 2097 assign_and_verify("IMPLY", 2) 2098 assign_and_verify("DIRECT_DEP", 2) 2099 verify_value("IMPLIED_TRISTATE", 2) 2100 assign_and_verify("DIRECT_DEP", 0) 2101 verify_value("IMPLIED_TRISTATE", 0) 2102 # Set back for later tests 2103 assign_and_verify("DIRECT_DEP", 2) 2104 2105 # Verify that IMPLIED_TRISTATE can be set to anything when IMPLY has value 2106 # n, and that it gets the value n by default (for non-imply-related 2107 # reasons) 2108 2109 assign_and_verify("IMPLY", 0) 2110 assign_and_verify("IMPLIED_TRISTATE", 0) 2111 assign_and_verify("IMPLIED_TRISTATE", 1) 2112 assign_and_verify("IMPLIED_TRISTATE", 2) 2113 c.syms["IMPLIED_TRISTATE"].unset_value() 2114 verify_value("IMPLIED_TRISTATE", "n") 2115 2116 # Same as above for m. Anything still goes, but m by default now. 2117 2118 assign_and_verify("IMPLY", 1) 2119 assign_and_verify("IMPLIED_TRISTATE", 0) 2120 assign_and_verify("IMPLIED_TRISTATE", 1) 2121 assign_and_verify("IMPLIED_TRISTATE", 2) 2122 c.syms["IMPLIED_TRISTATE"].unset_value() 2123 verify_value("IMPLIED_TRISTATE", 1) 2124 2125 # Same as above for y. Only n and y should be accepted. m gets promoted to 2126 # y. Default should be y. 2127 2128 assign_and_verify("IMPLY", 2) 2129 assign_and_verify("IMPLIED_TRISTATE", 0) 2130 assign_and_verify_value("IMPLIED_TRISTATE", 1, 2) 2131 assign_and_verify("IMPLIED_TRISTATE", 2) 2132 c.syms["IMPLIED_TRISTATE"].unset_value() 2133 verify_value("IMPLIED_TRISTATE", 2) 2134 2135 # Being implied to either m or y should give a bool the value y 2136 2137 c.syms["IMPLY"].unset_value() 2138 verify_value("IMPLIED_BOOL", 0) 2139 assign_and_verify("IMPLY", 0) 2140 verify_value("IMPLIED_BOOL", 0) 2141 assign_and_verify("IMPLY", 1) 2142 verify_value("IMPLIED_BOOL", 2) 2143 assign_and_verify("IMPLY", 2) 2144 verify_value("IMPLIED_BOOL", 2) 2145 2146 # A bool implied to m or y can take the values n and y 2147 2148 c.syms["IMPLY"].set_value(1) 2149 assign_and_verify("IMPLIED_BOOL", 0) 2150 assign_and_verify("IMPLIED_BOOL", 2) 2151 2152 c.syms["IMPLY"].set_value(2) 2153 assign_and_verify("IMPLIED_BOOL", 0) 2154 assign_and_verify("IMPLIED_BOOL", 2) 2155 2156 2157 print("Testing choice semantics") 2158 2159 # Would warn for choice value symbols defined without a type, even 2160 # though the type is automatically derived. This is probably more 2161 # helpful than ignoring those cases, as this feature isn't used 2162 # deliberately anywhere from what I've seen. 2163 c = Kconfig("Kconfiglib/tests/Kchoice", warn=False) 2164 2165 for name in "BOOL", "BOOL_OPT", "BOOL_M", "DEFAULTS": 2166 verify(c.named_choices[name].orig_type == BOOL, 2167 "choice {} should have type bool".format(name)) 2168 2169 for name in "TRISTATE", "TRISTATE_OPT", "TRISTATE_M": 2170 verify(c.named_choices[name].orig_type == TRISTATE, 2171 "choice {} should have type tristate".format(name)) 2172 2173 def select_and_verify(sym): 2174 choice = sym.nodes[0].parent.item 2175 choice.set_value(2) 2176 2177 sym.set_value(2) 2178 2179 verify(sym.choice.selection is sym, 2180 sym.name + " should be the selected symbol") 2181 2182 verify(choice.user_selection is sym, 2183 sym.name + " should be the user selection of the choice") 2184 2185 verify(sym.tri_value == 2, 2186 sym.name + " should have value y when selected") 2187 2188 verify(sym.user_value == 2, 2189 sym.name + " should have user value y when selected") 2190 2191 for sibling in choice.syms: 2192 if sibling is not sym: 2193 verify(sibling.tri_value == 0, 2194 sibling.name + " should be n when not selected") 2195 2196 def select_and_verify_all(choice_name): 2197 choice = c.named_choices[choice_name] 2198 2199 # Select in forward order 2200 for sym in choice.syms: 2201 select_and_verify(sym) 2202 2203 # Select in reverse order 2204 for sym in reversed(choice.syms): 2205 select_and_verify(sym) 2206 2207 def verify_mode(choice_name, no_modules_mode, modules_mode): 2208 choice = c.named_choices[choice_name] 2209 2210 c.modules.set_value(0) 2211 verify(choice.tri_value == no_modules_mode, 2212 'Wrong mode for choice {} with no modules. Expected {}, got {}.' 2213 .format(choice.name, no_modules_mode, choice.tri_value)) 2214 2215 c.modules.set_value(2) 2216 verify(choice.tri_value == modules_mode, 2217 'Wrong mode for choice {} with modules. Expected {}, got {}.' 2218 .format(choice.name, modules_mode, choice.tri_value)) 2219 2220 verify_mode("BOOL", 2, 2) 2221 verify_mode("BOOL_OPT", 0, 0) 2222 verify_mode("TRISTATE", 2, 1) 2223 verify_mode("TRISTATE_OPT", 0, 0) 2224 verify_mode("BOOL_M", 0, 2) 2225 verify_mode("TRISTATE_M", 0, 1) 2226 2227 # Test defaults 2228 2229 choice = c.named_choices["DEFAULTS"] 2230 2231 c.syms["TRISTATE_SYM"].set_value(0) 2232 verify(choice.selection is c.syms["OPT_4"], 2233 "Wrong choice default with TRISTATE_SYM = n") 2234 2235 c.syms["TRISTATE_SYM"].set_value(2) 2236 verify(choice.selection is c.syms["OPT_2"], 2237 "Wrong choice default with TRISTATE_SYM = y") 2238 2239 c.syms["OPT_1"].set_value(2) 2240 verify(choice.selection is c.syms["OPT_1"], 2241 "User selection should override defaults") 2242 2243 verify(c.named_choices["DEFAULTS_NOT_VISIBLE"].selection 2244 is c.syms["OPT_8"], 2245 "Non-visible choice symbols should cause the next default to be " 2246 "considered") 2247 2248 # Test y mode selection 2249 2250 c.modules.set_value(2) 2251 2252 select_and_verify_all("BOOL") 2253 select_and_verify_all("BOOL_OPT") 2254 select_and_verify_all("TRISTATE") 2255 select_and_verify_all("TRISTATE_OPT") 2256 # For BOOL_M, the mode should have been promoted 2257 select_and_verify_all("BOOL_M") 2258 2259 # Test m mode selection 2260 2261 c.named_choices["TRISTATE"].set_value(1) 2262 2263 verify(c.named_choices["TRISTATE"].tri_value == 1, 2264 "TRISTATE choice should have mode m after explicit mode assignment") 2265 2266 assign_and_verify_value("T_1", 0, 0) 2267 assign_and_verify_value("T_2", 0, 0) 2268 assign_and_verify_value("T_1", 1, 1) 2269 assign_and_verify_value("T_2", 1, 1) 2270 assign_and_verify_value("T_1", 2, 1) 2271 assign_and_verify_value("T_2", 2, 1) 2272 2273 # Switching to y mode should cause T_2 to become selected 2274 c.named_choices["TRISTATE"].set_value(2) 2275 verify_value("T_1", 0) 2276 verify_value("T_2", 2) 2277 2278 # Verify that choices with no explicitly specified type get the type of the 2279 # first contained symbol with a type 2280 2281 verify(c.named_choices["NO_TYPE_BOOL"].orig_type == BOOL, 2282 "Expected first choice without explicit type to have type bool") 2283 2284 verify(c.named_choices["NO_TYPE_TRISTATE"].orig_type == TRISTATE, 2285 "Expected second choice without explicit type to have type " 2286 "tristate") 2287 2288 # Verify that symbols without a type in the choice get the type of the 2289 # choice 2290 2291 for name in "MMT_1", "MMT_2", "MMT_4", "MMT_5": 2292 verify(c.syms[name].orig_type == BOOL, 2293 "Expected {} to get type bool".format(name)) 2294 2295 verify(c.syms["MMT_3"].orig_type == TRISTATE, 2296 "Expected MMT_3 to have type tristate") 2297 2298 # Verify that the default selection can change depending on the 2299 # visibility of the choice symbols 2300 2301 default_with_dep_choice = c.named_choices["DEFAULT_WITH_DEP"] 2302 2303 verify(default_with_dep_choice.selection is c.syms["B"], 2304 "Wrong choice default with unsatisfied deps on default") 2305 2306 c.syms["DEP"].set_value("y") 2307 2308 verify(default_with_dep_choice.selection is c.syms["A"], 2309 "Wrong choice default with satisfied deps on default") 2310 2311 c.syms["DEP"].set_value("n") 2312 2313 verify(default_with_dep_choice.selection is c.syms["B"], 2314 "Wrong choice default with unsatisfied deps on default (round two)") 2315 2316 # Verify that symbols in choices that depend on the preceding symbol aren't 2317 # considered choice symbols 2318 2319 weird_choice = c.named_choices["WEIRD_SYMS"] 2320 2321 def verify_is_normal_choice_symbol(name): 2322 sym = c.syms[name] 2323 verify(sym.choice is not None and 2324 sym in weird_choice.syms and 2325 sym.nodes[0].parent.item is weird_choice, 2326 "{} should be a normal choice symbol".format(sym.name)) 2327 2328 def verify_is_weird_choice_symbol(name): 2329 sym = c.syms[name] 2330 verify(sym.choice is None and 2331 sym not in weird_choice.syms, 2332 "{} should be a weird (non-)choice symbol" 2333 .format(sym.name)) 2334 2335 verify_is_normal_choice_symbol("WS1") 2336 verify_is_weird_choice_symbol("WS2") 2337 verify_is_weird_choice_symbol("WS3") 2338 verify_is_weird_choice_symbol("WS4") 2339 verify_is_weird_choice_symbol("WS5") 2340 verify_is_normal_choice_symbol("WS6") 2341 verify_is_weird_choice_symbol("WS7") 2342 verify_is_weird_choice_symbol("WS8") 2343 verify_is_normal_choice_symbol("WS9") 2344 2345 2346 print("Testing 'if' node removal") 2347 2348 c = Kconfig("Kconfiglib/tests/Kifremoval", warn=False) 2349 2350 nodes = tuple(c.node_iter()) 2351 verify_equal(nodes[0].item.name, "A") 2352 verify_equal(nodes[1].item.name, "B") 2353 verify_equal(nodes[2].item.name, "C") 2354 verify_equal(nodes[3].item.name, "D") 2355 verify_equal(nodes[4].prompt[0], "E") 2356 verify_equal(nodes[5].prompt[0], "F") 2357 verify_equal(nodes[6].prompt[0], "G") 2358 verify_equal(nodes[7].item.name, "H") 2359 verify_equal(nodes[8].item.name, "I") 2360 verify_equal(nodes[9].item.name, "J") 2361 verify(len(nodes) == 10, 2362 "Wrong number of nodes after 'if' removal") 2363 2364 2365 print("Testing multi.def. property copying") 2366 2367 c = Kconfig("Kconfiglib/tests/Kdepcopy", warn=False) 2368 2369 def verify_props(desc, props, prop_names): 2370 actual = [prop[0].name for prop in props] 2371 expected = prop_names.split() 2372 2373 verify(actual == expected, 2374 "Wrong {} properties, expected '{}', got '{}'" 2375 .format(desc, expected, actual)) 2376 2377 verify_props("default", c.syms["MULTIDEF"].defaults, 2378 "A B C D E F G H I J K L M N O P Q R") 2379 2380 verify_props("select", c.syms["MULTIDEF"].selects, 2381 "AA BB CC DD EE FF GG HH II JJ") 2382 2383 verify_props("imply", c.syms["MULTIDEF"].selects, 2384 "AA BB CC DD EE FF GG HH II JJ") 2385 2386 verify_props("select", c.syms["MULTIDEF_CHOICE"].selects, 2387 "A B C") 2388 2389 verify_props("range", c.syms["MULTIDEF_RANGE"].ranges, 2390 "A B C D E F") 2391 2392 verify_props("default", c.choices[1].defaults, 2393 "A B C D E") 2394 2395 2396 print("Testing dependency loop detection") 2397 2398 # These are all expected to raise dependency loop errors 2399 for i in range(11): 2400 filename = "Kconfiglib/tests/Kdeploop" + str(i) 2401 try: 2402 Kconfig(filename) 2403 except KconfigError as e: 2404 if "Dependency loop" not in str(e): 2405 fail("dependency loop in {} raised wrong KconfigError" 2406 .format(filename)) 2407 except: 2408 fail("dependency loop in {} raised wrong exception" 2409 .format(filename)) 2410 else: 2411 fail("dependency loop in {} not detected".format(filename)) 2412 2413 # Check the most complicated message completely 2414 try: 2415 Kconfig("Kconfiglib/tests/Kdeploop10") 2416 except KconfigError as e: 2417 verify_equal(str(e), """ 2418Dependency loop 2419=============== 2420 2421A (defined at Kconfiglib/tests/Kdeploop10:1), with definition... 2422 2423config A 2424 bool 2425 depends on B 2426 2427...depends on B (defined at Kconfiglib/tests/Kdeploop10:5), with definition... 2428 2429config B 2430 bool 2431 depends on C = 7 2432 2433...depends on C (defined at Kconfiglib/tests/Kdeploop10:9), with definition... 2434 2435config C 2436 int 2437 range D 8 2438 2439...depends on D (defined at Kconfiglib/tests/Kdeploop10:13), with definition... 2440 2441config D 2442 int 2443 default 3 if E 2444 default 8 2445 2446...depends on E (defined at Kconfiglib/tests/Kdeploop10:18), with definition... 2447 2448config E 2449 bool 2450 2451(select-related dependencies: F && G) 2452 2453...depends on G (defined at Kconfiglib/tests/Kdeploop10:25), with definition... 2454 2455config G 2456 bool 2457 depends on H 2458 2459...depends on the choice symbol H (defined at Kconfiglib/tests/Kdeploop10:32), with definition... 2460 2461config H 2462 bool "H" 2463 depends on I && <choice> 2464 2465...depends on the choice symbol I (defined at Kconfiglib/tests/Kdeploop10:41), with definition... 2466 2467config I 2468 bool "I" 2469 depends on <choice> 2470 2471...depends on <choice> (defined at Kconfiglib/tests/Kdeploop10:38), with definition... 2472 2473choice 2474 bool "choice" if J 2475 2476...depends on J (defined at Kconfiglib/tests/Kdeploop10:46), with definition... 2477 2478config J 2479 bool 2480 depends on A 2481 2482...depends again on A (defined at Kconfiglib/tests/Kdeploop10:1) 2483"""[:-1]) 2484 except: 2485 fail("Loop detection message check raised wrong exception") 2486 else: 2487 fail("Loop detection message check did not raise exception") 2488 2489 2490 print("Testing preprocessor") 2491 2492 os.environ["ENV_1"] = "env_1" 2493 os.environ["ENV_2"] = "env_2" 2494 os.environ["ENV_3"] = "env_3" 2495 os.environ["ENV_4"] = "env_4" 2496 os.environ["ENV_5"] = "n" 2497 os.environ["ENV_6"] = "Kconfiglib/tests/empty" 2498 os.environ["ENV_7"] = "env_7" 2499 # We verify warnings manually 2500 c = Kconfig("Kconfiglib/tests/Kpreprocess", warn_to_stderr=False) 2501 2502 def verify_variable(name, unexp_value, exp_value, recursive, *args): 2503 var = c.variables[name] 2504 2505 verify(var.value == unexp_value, 2506 "expected variable '{}' to have the unexpanded value '{}', had " 2507 "the value '{}'".format(name, unexp_value, var.value)) 2508 2509 if not args: 2510 verify(var.expanded_value == exp_value, 2511 "expected expanded_value for {} to be '{}', was '{}'" 2512 .format(name, exp_value, var.expanded_value)) 2513 2514 verify(var.expanded_value_w_args(*args) == exp_value, 2515 "expected expanded_value_w_args() for '{}' to be '{}', was '{}'" 2516 .format(name, exp_value, var.expanded_value_w_args(*args))) 2517 2518 verify(var.is_recursive == recursive, 2519 "{} was {}, shouldn't be" 2520 .format(name, "recursive" if var.is_recursive else "simple")) 2521 2522 verify_variable("simple-recursive", "foo", "foo", True) 2523 verify_variable("simple-immediate", "bar", "bar", False) 2524 verify_variable("simple-recursive-2", "baz", "baz", True) 2525 2526 verify_variable("whitespaced", "foo", "foo", True) 2527 2528 verify_variable("preserve-recursive", "foo bar", "foo bar", True) 2529 verify_variable("preserve-immediate", "foo bar", "foo bar", False) 2530 2531 verify_variable("recursive", 2532 "$(foo) $(bar) $($(b-char)a$(z-char)) $(indir)", 2533 "abc def ghi jkl mno", 2534 True) 2535 2536 verify_variable("immediate", "foofoo", "foofoo", False) 2537 2538 verify_variable("messy-fn-res", 2539 "$($(fn-indir)-unused-arg, a b (,) , c d )", 2540 'surround-rev-quote " c d " " a b (,) " surround-rev-quote ', 2541 True) 2542 2543 verify_variable("special-chars-fn-res", 2544 "$(fn,$(comma)$(dollar)$(left-paren)foo$(right-paren))", 2545 '",$(foo)"', 2546 True) 2547 2548 verify_variable("quote", '"$(1)" "$(2)"', '"" ""', True) 2549 verify_variable("quote", '"$(1)" "$(2)"', '"one" ""', True, 2550 "one") 2551 verify_variable("quote", '"$(1)" "$(2)"', '"one" "two"', True, 2552 "one", "two") 2553 verify_variable("quote", '"$(1)" "$(2)"', '"one" "two"', True, 2554 "one", "two", "three") 2555 2556 verify_str(c.syms["PRINT_ME"], r""" 2557config PRINT_ME 2558 string "env_1" if (FOO && BAR) || !BAZ || !QAZ 2559 default "\"foo\"" if "foo \"bar\" baz" = "" 2560""") 2561 2562 verify_str(c.syms["PRINT_ME_TOO"], r""" 2563config PRINT_ME_TOO 2564 bool "foo" 2565 default FOOBARBAZQAZ if QAZ && QAZFOO && xxx 2566""") 2567 2568 def verify_repr(name, s): 2569 verify_equal(repr(c.variables[name]), s) 2570 2571 verify_repr( 2572 "simple-immediate", 2573 "<variable simple-immediate, immediate, value 'bar'>") 2574 2575 verify_repr( 2576 "messy-fn-res", 2577 "<variable messy-fn-res, recursive, value '$($(fn-indir)-unused-arg, a b (,) , c d )'>") 2578 2579 def verify_recursive(name): 2580 try: 2581 c.variables[name].expanded_value 2582 except KconfigError: 2583 pass 2584 else: 2585 fail("Expected '{}' expansion to flag recursive expansion, didn't" 2586 .format(name)) 2587 2588 verify_recursive("rec-1") 2589 # Indirectly verifies that it's not recursive 2590 verify_variable("safe-fn-rec-res", 2591 "$(safe-fn-rec,safe-fn-rec-2)", 2592 "foo", 2593 True) 2594 verify_recursive("unsafe-fn-rec") 2595 2596 verify_variable("foo-bar-baz", "$(rhs)", "value", True) 2597 2598 verify_variable("space-var-res", "$(foo bar)", "value", True) 2599 2600 verify_variable("shell-res", 2601 "$(shell,false && echo foo bar || echo baz qaz)", 2602 "baz qaz", 2603 True) 2604 2605 verify_variable("shell-stderr-res", "", "", False) 2606 2607 verify_variable("parens-res", 2608 "pre-$(shell,echo '(a,$(b-char),(c,d),e)')-post", 2609 "pre-(a,b,(c,d),e)-post", 2610 True) 2611 2612 verify_variable("location-res", 2613 "Kconfiglib/tests/Kpreprocess:129", 2614 "Kconfiglib/tests/Kpreprocess:129", 2615 False) 2616 2617 verify_variable("warning-res", "", "", False) 2618 verify_variable("error-n-res", "", "", False) 2619 2620 try: 2621 c.variables["error-y-res"].expanded_value 2622 except KconfigError: 2623 pass 2624 else: 2625 fail("expanding error-y-res didn't raise an exception") 2626 2627 # Check Kconfig.env_vars 2628 verify_equal(c.env_vars, 2629 set(("ENV_1", "ENV_2", "ENV_3", "ENV_4", "ENV_5", "ENV_6"))) 2630 2631 # Check that the expected warnings were generated 2632 verify_equal(c.warnings, [ 2633 "Kconfiglib/tests/Kpreprocess:122: warning: 'echo message on stderr >&2' wrote to stderr: message on stderr", 2634 "Kconfiglib/tests/Kpreprocess:134: warning: a warning" 2635 ]) 2636 2637 2638 print("Testing user-defined preprocessor functions") 2639 2640 # Make Kconfiglib/tests/kconfigfunctions.py importable 2641 sys.path.insert(0, "Kconfiglib/tests") 2642 2643 c = Kconfig("Kconfiglib/tests/Kuserfunctions") 2644 2645 verify_variable("add-zero", "$(add)", "0", True) 2646 verify_variable("add-one", "$(add,1)", "1", True) 2647 verify_variable("add-three", "$(add,1,-1,2,1)", "3", True) 2648 2649 verify_variable("one-one", "$(one,foo bar)", "onefoo barfoo bar", True) 2650 2651 verify_variable("one-or-more-one", "$(one-or-more,foo)", "foo + ", True) 2652 verify_variable("one-or-more-three", "$(one-or-more,foo,bar,baz)", 2653 "foo + bar,baz", True) 2654 2655 verify_variable("location-1", "Kconfiglib/tests/Kuserfunctions:13", 2656 "Kconfiglib/tests/Kuserfunctions:13", False) 2657 verify_variable("location-2", "Kconfiglib/tests/Kuserfunctions:14", 2658 "Kconfiglib/tests/Kuserfunctions:14", False) 2659 2660 def verify_bad_argno(name): 2661 try: 2662 c.variables[name].expanded_value 2663 except KconfigError: 2664 pass 2665 else: 2666 fail("Expected '{}' expansion to flag wrong number of arguments, " 2667 "didn't".format(name)) 2668 2669 verify_bad_argno("one-zero") 2670 verify_bad_argno("one-two") 2671 verify_bad_argno("one-or-more-zero") 2672 2673 sys.path.pop(0) 2674 2675 # This test can fail on older Python 3.x versions, because they don't 2676 # preserve dict insertion order during iteration. The output is still 2677 # correct, just different. 2678 if not (3, 0) <= sys.version_info <= (3, 5): 2679 print("Testing KCONFIG_WARN_UNDEF") 2680 2681 os.environ["KCONFIG_WARN_UNDEF"] = "y" 2682 c = Kconfig("Kconfiglib/tests/Kundef", warn_to_stderr=False) 2683 2684 verify_equal("\n".join(c.warnings), """ 2685warning: the int symbol INT (defined at Kconfiglib/tests/Kundef:8) has a non-int range [UNDEF_2 (undefined), 8 (undefined)] 2686warning: undefined symbol UNDEF_1: 2687 2688- Referenced at Kconfiglib/tests/Kundef:4: 2689 2690config BOOL 2691 bool "foo" if DEF || !UNDEF_1 2692 default UNDEF_2 2693 2694- Referenced at Kconfiglib/tests/Kundef:19: 2695 2696menu "menu" 2697 depends on UNDEF_1 2698 visible if UNDEF_3 2699warning: undefined symbol UNDEF_2: 2700 2701- Referenced at Kconfiglib/tests/Kundef:4: 2702 2703config BOOL 2704 bool "foo" if DEF || !UNDEF_1 2705 default UNDEF_2 2706 2707- Referenced at Kconfiglib/tests/Kundef:8: 2708 2709config INT 2710 int 2711 range UNDEF_2 8 2712 range 5 15 2713 default 10 2714warning: undefined symbol UNDEF_3: 2715 2716- Referenced at Kconfiglib/tests/Kundef:19: 2717 2718menu "menu" 2719 depends on UNDEF_1 2720 visible if UNDEF_3 2721"""[1:-1]) 2722 2723 os.environ.pop("KCONFIG_WARN_UNDEF") 2724 2725 2726 print("\nAll selftests passed\n" if all_passed else 2727 "\nSome selftests failed\n") 2728 2729 2730def run_compatibility_tests(): 2731 # Runs tests on configurations from the kernel. Tests compability with the 2732 # C implementation by comparing outputs. 2733 2734 # Referenced inside the kernel Kconfig files. 2735 # 2736 # The str() makes the type of the value 'str' on both Python 2 and Python 3, 2737 # which is nice for some later dictionary key sanity checks. 2738 2739 os.environ["KERNELVERSION"] = str( 2740 subprocess.check_output("make kernelversion", shell=True) 2741 .decode("utf-8").rstrip() 2742 ) 2743 2744 os.environ["CC_VERSION_TEXT"] = str( 2745 subprocess.check_output("gcc --version | head -n1", shell=True) 2746 .decode("utf-8").rstrip() 2747 ) 2748 2749 os.environ["srctree"] = "." 2750 os.environ["CC"] = "gcc" 2751 os.environ["LD"] = "ld" 2752 2753 2754 if not os.path.exists("scripts/kconfig/conf"): 2755 print("\nscripts/kconfig/conf does not exist -- running " 2756 "'make allnoconfig' to build it...") 2757 shell("make allnoconfig") 2758 2759 2760 print("Running compatibility tests...\n") 2761 2762 test_fns = (test_defconfig, 2763 # Fails for a few defconfigs due to a bug in the C tools. Will 2764 # be enabled once patches get in. 2765 #test_min_config, 2766 test_alldefconfig, 2767 test_allnoconfig, 2768 test_allnoconfig_walk, 2769 test_allmodconfig, 2770 test_allyesconfig, 2771 test_sanity) 2772 2773 for test_fn in test_fns: 2774 # The test description is taken from the docstring of the corresponding 2775 # function 2776 print(textwrap.dedent(test_fn.__doc__)) 2777 2778 for arch, srcarch in all_arch_srcarch(): 2779 # Referenced inside the Kconfig files 2780 os.environ["ARCH"] = arch 2781 os.environ["SRCARCH"] = srcarch 2782 2783 rm_configs() 2784 2785 test_fn(arch, srcarch) 2786 2787 if all_passed: 2788 print("All selftests and compatibility tests passed") 2789 else: 2790 sys.exit("Some tests failed") 2791 2792 2793def all_arch_srcarch(): 2794 for srcarch in os.listdir("arch"): 2795 # arc and h8300 are currently broken with the C tools on linux-next as 2796 # well. Perhaps they require cross-compilers to be installed. 2797 # 2798 # User-mode Linux has an unorthodox Kconfig setup that would require a 2799 # different testing setup. Skip it too. 2800 if srcarch in ("arc", "h8300", "um"): 2801 continue 2802 2803 if os.path.exists(os.path.join("arch", srcarch, "Kconfig")): 2804 yield (srcarch, srcarch) 2805 2806 # Some arches define additional ARCH settings with ARCH != SRCARCH 2807 # (search for "Additional ARCH settings for" in the top-level Makefile) 2808 2809 yield ("i386", "x86") 2810 yield ("x86_64", "x86") 2811 2812 yield ("sparc32", "sparc") 2813 yield ("sparc64", "sparc") 2814 2815 yield ("sh64", "sh") 2816 2817 2818def test_allnoconfig(arch, srcarch): 2819 """ 2820 Verify that allnoconfig.py generates the same .config as 2821 'make allnoconfig', for each architecture. Runs the script via 2822 'make scriptconfig'. 2823 """ 2824 shell("make scriptconfig SCRIPT=Kconfiglib/allnoconfig.py " 2825 "PYTHONCMD='{}'".format(sys.executable)) 2826 shell("mv .config ._config") 2827 shell("scripts/kconfig/conf --allnoconfig Kconfig") 2828 2829 compare_configs(arch) 2830 2831 2832def test_allnoconfig_walk(arch, srcarch): 2833 """ 2834 Verify that examples/allnoconfig_walk.py generates the same .config as 2835 'make allnoconfig', for each architecture. Runs the script via 2836 'make scriptconfig'. 2837 """ 2838 shell("make scriptconfig SCRIPT=Kconfiglib/examples/allnoconfig_walk.py " 2839 "PYTHONCMD='{}'".format(sys.executable)) 2840 shell("mv .config ._config") 2841 shell("scripts/kconfig/conf --allnoconfig Kconfig") 2842 2843 compare_configs(arch) 2844 2845 2846def test_allmodconfig(arch, srcarch): 2847 """ 2848 Verify that allmodconfig.py generates the same .config as 2849 'make allmodconfig', for each architecture. Runs the script via 2850 'make scriptconfig'. 2851 """ 2852 shell("make scriptconfig SCRIPT=Kconfiglib/allmodconfig.py " 2853 "PYTHONCMD='{}'".format(sys.executable)) 2854 shell("mv .config ._config") 2855 shell("scripts/kconfig/conf --allmodconfig Kconfig") 2856 2857 compare_configs(arch) 2858 2859 2860def test_allyesconfig(arch, srcarch): 2861 """ 2862 Verify that allyesconfig.py generates the same .config as 2863 'make allyesconfig', for each architecture. Runs the script via 2864 'make scriptconfig'. 2865 """ 2866 shell("make scriptconfig SCRIPT=Kconfiglib/allyesconfig.py " 2867 "PYTHONCMD='{}'".format(sys.executable)) 2868 shell("mv .config ._config") 2869 shell("scripts/kconfig/conf --allyesconfig Kconfig") 2870 2871 compare_configs(arch) 2872 2873 2874def test_sanity(arch, srcarch): 2875 """ 2876 Do sanity checks on each configuration and call all public methods on all 2877 symbols, choices, and menu nodes for all architectures to make sure we 2878 never crash or hang. 2879 """ 2880 print("For {}...".format(arch)) 2881 2882 kconf = Kconfig() 2883 2884 for sym in kconf.defined_syms: 2885 verify(sym._visited == 2, 2886 "{} has broken dependency loop detection (_visited = {})" 2887 .format(sym.name, sym._visited)) 2888 2889 kconf.modules 2890 kconf.defconfig_list 2891 kconf.defconfig_filename 2892 2893 # Legacy warning functions 2894 kconf.enable_redun_warnings() 2895 kconf.disable_redun_warnings() 2896 kconf.enable_undef_warnings() 2897 kconf.disable_undef_warnings() 2898 kconf.enable_warnings() 2899 kconf.disable_warnings() 2900 kconf.enable_stderr_warnings() 2901 kconf.disable_stderr_warnings() 2902 2903 kconf.mainmenu_text 2904 kconf.unset_values() 2905 2906 kconf.write_autoconf("/dev/null") 2907 2908 # No tempfile.TemporaryDirectory in Python 2 2909 tmpdir = tempfile.mkdtemp() 2910 kconf.sync_deps(os.path.join(tmpdir, "deps")) # Create 2911 kconf.sync_deps(os.path.join(tmpdir, "deps")) # Update 2912 shutil.rmtree(tmpdir) 2913 2914 # Python 2/3 compatible 2915 for key, sym in kconf.syms.items(): 2916 verify(isinstance(key, str), "weird key '{}' in syms dict".format(key)) 2917 2918 verify(not sym.is_constant, sym.name + " in 'syms' and constant") 2919 2920 verify(sym not in kconf.const_syms, 2921 sym.name + " in both 'syms' and 'const_syms'") 2922 2923 for dep in sym._dependents: 2924 verify(not dep.is_constant, 2925 "the constant symbol {} depends on {}" 2926 .format(dep.name, sym.name)) 2927 2928 sym.__repr__() 2929 sym.__str__() 2930 sym.assignable 2931 kconf.disable_warnings() 2932 sym.set_value(2) 2933 sym.set_value("foo") 2934 sym.unset_value() 2935 kconf.enable_warnings() # Legacy warning function 2936 sym.str_value 2937 sym.tri_value 2938 sym.type 2939 sym.user_value 2940 sym.visibility 2941 2942 for sym in kconf.defined_syms: 2943 verify(sym.nodes, sym.name + " is defined but lacks menu nodes") 2944 2945 verify(not (sym.orig_type not in (BOOL, TRISTATE) and sym.choice), 2946 sym.name + " is a choice symbol but not bool/tristate") 2947 2948 for key, sym in kconf.const_syms.items(): 2949 verify(isinstance(key, str), 2950 "weird key '{}' in const_syms dict".format(key)) 2951 2952 verify(sym.is_constant, 2953 '"{}" is in const_syms but not marked constant' 2954 .format(sym.name)) 2955 2956 verify(not sym.nodes, 2957 '"{}" is constant but has menu nodes'.format(sym.name)) 2958 2959 verify(not sym._dependents, 2960 '"{}" is constant but is a dependency of some symbol' 2961 .format(sym.name)) 2962 2963 verify(not sym.choice, 2964 '"{}" is constant and a choice symbol'.format(sym.name)) 2965 2966 sym.__repr__() 2967 sym.__str__() 2968 sym.assignable 2969 kconf.disable_warnings() 2970 sym.set_value(2) 2971 sym.set_value("foo") 2972 sym.unset_value() 2973 kconf.enable_warnings() # Legacy warning function 2974 sym.str_value 2975 sym.tri_value 2976 sym.type 2977 sym.visibility 2978 2979 for choice in kconf.choices: 2980 for sym in choice.syms: 2981 verify(sym.choice is choice, 2982 "{0} is in choice.syms but 'sym.choice' is not the choice" 2983 .format(sym.name)) 2984 2985 verify(sym.type in (BOOL, TRISTATE), 2986 "{} is a choice symbol but is not a bool/tristate" 2987 .format(sym.name)) 2988 2989 choice.__str__() 2990 choice.__repr__() 2991 choice.str_value 2992 choice.tri_value 2993 choice.user_value 2994 choice.assignable 2995 choice.selection 2996 choice.type 2997 choice.visibility 2998 2999 # Menu nodes 3000 3001 node = kconf.top_node 3002 3003 while 1: 3004 # Everything else should be well exercised elsewhere 3005 node.__repr__() 3006 node.__str__() 3007 verify(isinstance(node.item, (Symbol, Choice)) or \ 3008 node.item in (MENU, COMMENT), 3009 "'{}' appeared as a menu item".format(node.item)) 3010 3011 if node.list is not None: 3012 node = node.list 3013 3014 elif node.next is not None: 3015 node = node.next 3016 3017 else: 3018 while node.parent is not None: 3019 node = node.parent 3020 if node.next is not None: 3021 node = node.next 3022 break 3023 else: 3024 break 3025 3026 3027def test_alldefconfig(arch, srcarch): 3028 """ 3029 Verify that alldefconfig.py generates the same .config as 3030 'make alldefconfig', for each architecture. Runs the script via 3031 'make scriptconfig'. 3032 """ 3033 shell("make scriptconfig SCRIPT=Kconfiglib/alldefconfig.py " 3034 "PYTHONCMD='{}'".format(sys.executable)) 3035 shell("mv .config ._config") 3036 shell("scripts/kconfig/conf --alldefconfig Kconfig") 3037 3038 compare_configs(arch) 3039 3040 3041def test_defconfig(arch, srcarch): 3042 """ 3043 Verify that Kconfiglib generates the same .config as scripts/kconfig/conf, 3044 for each architecture/defconfig pair. In obsessive mode, this test includes 3045 nonsensical groupings of arches with defconfigs from other arches (every 3046 arch/defconfig combination) and takes an order of magnitude longer time to 3047 run. 3048 3049 With logging enabled, this test appends any failures to a file 3050 test_defconfig_fails in the root. 3051 """ 3052 kconf = Kconfig() 3053 3054 if obsessive: 3055 defconfigs = [] 3056 3057 # Collect all defconfigs. This could be done once instead, but it's 3058 # a speedy operation comparatively. 3059 for srcarch_ in os.listdir("arch"): 3060 defconfigs.extend(defconfig_files(srcarch_)) 3061 else: 3062 defconfigs = defconfig_files(srcarch) 3063 3064 # Test architecture for each defconfig 3065 3066 for defconfig in defconfigs: 3067 rm_configs() 3068 3069 kconf.load_config(defconfig) 3070 kconf.write_config("._config") 3071 shell("scripts/kconfig/conf --defconfig='{}' Kconfig". 3072 format(defconfig)) 3073 3074 arch_defconfig_str = " {:14}with {:60} ".format(arch, defconfig) 3075 3076 if equal_configs(): 3077 print(arch_defconfig_str + "OK") 3078 else: 3079 print(arch_defconfig_str + "FAIL") 3080 fail() 3081 if log: 3082 with open("test_defconfig_fails", "a") as fail_log: 3083 fail_log.write("{} with {} did not match\n" 3084 .format(arch, defconfig)) 3085 3086 3087def test_min_config(arch, srcarch): 3088 """ 3089 Verify that Kconfiglib generates the same .config as 'make savedefconfig' 3090 for each architecture/defconfig pair. 3091 """ 3092 kconf = Kconfig() 3093 3094 if obsessive_min_config: 3095 defconfigs = [] 3096 for srcarch_ in os.listdir("arch"): 3097 defconfigs.extend(defconfig_files(srcarch_)) 3098 else: 3099 defconfigs = defconfig_files(srcarch) 3100 3101 for defconfig in defconfigs: 3102 rm_configs() 3103 3104 kconf.load_config(defconfig) 3105 kconf.write_min_config("._config") 3106 3107 shell("cp {} .config".format(defconfig)) 3108 3109 shell("scripts/kconfig/conf --savedefconfig=.config Kconfig") 3110 3111 arch_defconfig_str = " {:14}with {:60} ".format(arch, defconfig) 3112 3113 if equal_configs(): 3114 print(arch_defconfig_str + "OK") 3115 else: 3116 print(arch_defconfig_str + "FAIL") 3117 3118 3119# 3120# Helper functions 3121# 3122 3123 3124def defconfig_files(srcarch): 3125 # Yields a list of defconfig file filenames for a particular srcarch 3126 # subdirectory (arch/<srcarch>/) 3127 3128 srcarch_dir = os.path.join("arch", srcarch) 3129 3130 # Some arches have a defconfig in the root of their arch/<arch>/ directory 3131 root_defconfig = os.path.join(srcarch_dir, "defconfig") 3132 if os.path.exists(root_defconfig): 3133 yield root_defconfig 3134 3135 # Assume all files in the arch/<arch>/configs/ directory (if it exists) are 3136 # configurations 3137 defconfigs_dir = os.path.join(srcarch_dir, "configs") 3138 3139 if not os.path.isdir(defconfigs_dir): 3140 return 3141 3142 for dirpath, _, filenames in os.walk(defconfigs_dir): 3143 for filename in filenames: 3144 yield os.path.join(dirpath, filename) 3145 3146 3147def rm_configs(): 3148 # Delete any old ".config" (generated by the C implementation) and 3149 # "._config" (generated by us), if present. 3150 3151 def rm_if_exists(f): 3152 if os.path.exists(f): 3153 os.remove(f) 3154 3155 rm_if_exists(".config") 3156 rm_if_exists("._config") 3157 3158 3159def compare_configs(arch): 3160 if equal_configs(): 3161 print("{:14}OK".format(arch)) 3162 else: 3163 print("{:14}FAIL".format(arch)) 3164 fail() 3165 3166 3167def equal_configs(): 3168 with open(".config") as f: 3169 their = f.readlines() 3170 3171 # Strip the header generated by 'conf' 3172 i = 0 3173 for line in their: 3174 if not line.startswith("#") or \ 3175 re.match(r"# CONFIG_(\w+) is not set", line): 3176 break 3177 i += 1 3178 their = their[i:] 3179 3180 try: 3181 f = open("._config") 3182 except EnvironmentError as e: 3183 if e.errno != errno.ENOENT: 3184 raise 3185 print("._config not found. Did you forget to apply the Makefile patch?") 3186 return False 3187 else: 3188 with f: 3189 our = f.readlines() 3190 3191 if their == our: 3192 return True 3193 3194 # Print a unified diff to help debugging 3195 print("Mismatched .config's! Unified diff:") 3196 sys.stdout.writelines(difflib.unified_diff(their, our, fromfile="their", 3197 tofile="our")) 3198 3199 return False 3200 3201 3202if __name__ == "__main__": 3203 run_tests() 3204
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.