1# Running the test with Python 2: 2# Be sure to install pytest version 4.6.4 (newer should also work) 3# Command in cppcheck directory: 4# python -m pytest addons/test/test-y2038.py 5# 6# Running the test with Python 3: 7# Command in cppcheck directory: 8# PYTHONPATH=./addons python3 -m pytest addons/test/test-y2038.py 9 10import sys 11import pytest 12 13from addons.y2038 import check_y2038_safe 14 15from .util import dump_create, dump_remove, convert_json_output 16 17 18TEST_SOURCE_FILES = ['./addons/test/y2038/y2038-test-1-bad-time-bits.c', 19 './addons/test/y2038/y2038-test-2-no-time-bits.c', 20 './addons/test/y2038/y2038-test-3-no-use-time-bits.c', 21 './addons/test/y2038/y2038-test-4-good.c', 22 './addons/test/y2038/y2038-test-5-good-no-time-used.c'] 23 24 25def setup_module(module): 26 sys.argv.append("--cli") 27 for f in TEST_SOURCE_FILES: 28 dump_create(f) 29 30 31def teardown_module(module): 32 sys.argv.remove("--cli") 33 for f in TEST_SOURCE_FILES: 34 dump_remove(f) 35 36 37def test_1_bad_time_bits(capsys): 38 is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-1-bad-time-bits.c.dump', quiet=True) 39 assert(is_safe is False) 40 captured = capsys.readouterr() 41 captured = captured.out.splitlines() 42 json_output = convert_json_output(captured) 43 44 # Has exactly one warnings of _TIME_BITS and _USE_TIME_BITS64 kind. 45 assert(len(json_output['type-bits-undef']) == 1) 46 assert(len(json_output['type-bits-not-64']) == 1) 47 48 # There are 2 unsafe calls in test source and 3 in y2038-in.h 49 unsafe_calls = json_output['unsafe-call'] 50 assert(len([c for c in unsafe_calls if c['file'].endswith('h')]) == 3) 51 assert(len([c for c in unsafe_calls if c['file'].endswith('c')]) == 0) 52 53 54def test_2_no_time_bits(capsys): 55 is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-2-no-time-bits.c.dump', quiet=True) 56 assert(is_safe is False) 57 captured = capsys.readouterr() 58 captured = captured.out.splitlines() 59 json_output = convert_json_output(captured) 60 61 # _USE_TIME_BITS64 defined in y2038-inc.h header, but there is not 62 # _TIME_BITS definition. Here must be appropriate warning. 63 assert(len(json_output['type-bits-undef']) == 1) 64 assert(json_output.get('type-bits-not-64') is None) 65 66 # y2038-in.h still has y2038-unsafe calls. 67 unsafe_calls = json_output['unsafe-call'] 68 assert(len([c for c in unsafe_calls if c['file'].endswith('h')]) == 3) 69 70 71def test_3_no_use_time_bits(capsys): 72 is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-3-no-use-time-bits.c.dump', quiet=True) 73 assert(is_safe is False) 74 captured = capsys.readouterr() 75 captured = captured.out.splitlines() 76 json_output = convert_json_output(captured) 77 78 # Included bad _USE_TIME_BITS64 definition must trigger the errors. 79 unsafe_calls = json_output['unsafe-call'] 80 assert(len(unsafe_calls) == 2) 81 82 83def test_4_good(capsys): 84 is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-4-good.c.dump', quiet=True) 85 # assert(is_safe is True) # FIXME: This should be a "good" example returning "True" instead of "False" 86 captured = capsys.readouterr() 87 captured = captured.out.splitlines() 88 json_output = convert_json_output(captured) 89 90 # Defined _TIME_BITS equal to 64 so that glibc knows we want Y2038 support. 91 # There are no warnings from C sources. 92 unsafe_calls = json_output['unsafe-call'] 93 assert(len([c for c in unsafe_calls if c['file'].endswith('.c')]) == 0) 94 95 96def test_5_good(capsys): 97 is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-5-good-no-time-used.c.dump', quiet=True) 98 assert(is_safe is True) 99 captured = capsys.readouterr() 100 captured = captured.out.splitlines() 101 json_output = convert_json_output(captured) 102 103 # There are no warnings from C sources. 104 if 'unsafe-call' in json_output: 105 unsafe_calls = json_output['unsafe-call'] 106 assert(len([c for c in unsafe_calls if c['file'].endswith('.c')]) == 0) 107 108 109def test_arguments_regression(): 110 args_ok = ["-t=foo", "--template=foo", 111 "-q", "--quiet", 112 "--cli"] 113 # Arguments with expected SystemExit 114 args_exit = ["--non-exists", "--non-exists-param=42", "-h", "--help"] 115 116 from addons.y2038 import get_args_parser 117 118 for arg in args_exit: 119 sys.argv.append(arg) 120 with pytest.raises(SystemExit): 121 parser = get_args_parser() 122 parser.parse_args() 123 sys.argv.remove(arg) 124 125 for arg in args_ok: 126 sys.argv.append(arg) 127 try: 128 parser = get_args_parser() 129 parser.parse_args() 130 except SystemExit: 131 pytest.fail("Unexpected SystemExit with '%s'" % arg) 132 sys.argv.remove(arg) 133