xref: /third_party/python/Tools/iobench/iobench.py (revision 7db96d56)
17db96d56Sopenharmony_ci# -*- coding: utf-8 -*-
27db96d56Sopenharmony_ci# This file should be kept compatible with both Python 2.6 and Python >= 3.0.
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ciimport itertools
57db96d56Sopenharmony_ciimport os
67db96d56Sopenharmony_ciimport platform
77db96d56Sopenharmony_ciimport re
87db96d56Sopenharmony_ciimport sys
97db96d56Sopenharmony_ciimport time
107db96d56Sopenharmony_cifrom optparse import OptionParser
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ciout = sys.stdout
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_ciTEXT_ENCODING = 'utf8'
157db96d56Sopenharmony_ciNEWLINES = 'lf'
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci# Compatibility
187db96d56Sopenharmony_citry:
197db96d56Sopenharmony_ci    xrange
207db96d56Sopenharmony_ciexcept NameError:
217db96d56Sopenharmony_ci    xrange = range
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_cidef text_open(fn, mode, encoding=None):
247db96d56Sopenharmony_ci    try:
257db96d56Sopenharmony_ci        return open(fn, mode, encoding=encoding or TEXT_ENCODING)
267db96d56Sopenharmony_ci    except TypeError:
277db96d56Sopenharmony_ci        if 'r' in mode:
287db96d56Sopenharmony_ci            mode += 'U' # 'U' mode is needed only in Python 2.x
297db96d56Sopenharmony_ci        return open(fn, mode)
307db96d56Sopenharmony_ci
317db96d56Sopenharmony_cidef get_file_sizes():
327db96d56Sopenharmony_ci    for s in ['20 KiB', '400 KiB', '10 MiB']:
337db96d56Sopenharmony_ci        size, unit = s.split()
347db96d56Sopenharmony_ci        size = int(size) * {'KiB': 1024, 'MiB': 1024 ** 2}[unit]
357db96d56Sopenharmony_ci        yield s.replace(' ', ''), size
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_cidef get_binary_files():
387db96d56Sopenharmony_ci    return ((name + ".bin", size) for name, size in get_file_sizes())
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_cidef get_text_files():
417db96d56Sopenharmony_ci    return (("%s-%s-%s.txt" % (name, TEXT_ENCODING, NEWLINES), size)
427db96d56Sopenharmony_ci        for name, size in get_file_sizes())
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_cidef with_open_mode(mode):
457db96d56Sopenharmony_ci    def decorate(f):
467db96d56Sopenharmony_ci        f.file_open_mode = mode
477db96d56Sopenharmony_ci        return f
487db96d56Sopenharmony_ci    return decorate
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_cidef with_sizes(*sizes):
517db96d56Sopenharmony_ci    def decorate(f):
527db96d56Sopenharmony_ci        f.file_sizes = sizes
537db96d56Sopenharmony_ci        return f
547db96d56Sopenharmony_ci    return decorate
557db96d56Sopenharmony_ci
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci# Here begin the tests
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ci@with_open_mode("r")
607db96d56Sopenharmony_ci@with_sizes("medium")
617db96d56Sopenharmony_cidef read_bytewise(f):
627db96d56Sopenharmony_ci    """ read one unit at a time """
637db96d56Sopenharmony_ci    f.seek(0)
647db96d56Sopenharmony_ci    while f.read(1):
657db96d56Sopenharmony_ci        pass
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci@with_open_mode("r")
687db96d56Sopenharmony_ci@with_sizes("medium")
697db96d56Sopenharmony_cidef read_small_chunks(f):
707db96d56Sopenharmony_ci    """ read 20 units at a time """
717db96d56Sopenharmony_ci    f.seek(0)
727db96d56Sopenharmony_ci    while f.read(20):
737db96d56Sopenharmony_ci        pass
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_ci@with_open_mode("r")
767db96d56Sopenharmony_ci@with_sizes("medium")
777db96d56Sopenharmony_cidef read_big_chunks(f):
787db96d56Sopenharmony_ci    """ read 4096 units at a time """
797db96d56Sopenharmony_ci    f.seek(0)
807db96d56Sopenharmony_ci    while f.read(4096):
817db96d56Sopenharmony_ci        pass
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci@with_open_mode("r")
847db96d56Sopenharmony_ci@with_sizes("small", "medium", "large")
857db96d56Sopenharmony_cidef read_whole_file(f):
867db96d56Sopenharmony_ci    """ read whole contents at once """
877db96d56Sopenharmony_ci    f.seek(0)
887db96d56Sopenharmony_ci    while f.read():
897db96d56Sopenharmony_ci        pass
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci@with_open_mode("rt")
927db96d56Sopenharmony_ci@with_sizes("medium")
937db96d56Sopenharmony_cidef read_lines(f):
947db96d56Sopenharmony_ci    """ read one line at a time """
957db96d56Sopenharmony_ci    f.seek(0)
967db96d56Sopenharmony_ci    for line in f:
977db96d56Sopenharmony_ci        pass
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_ci@with_open_mode("r")
1007db96d56Sopenharmony_ci@with_sizes("medium")
1017db96d56Sopenharmony_cidef seek_forward_bytewise(f):
1027db96d56Sopenharmony_ci    """ seek forward one unit at a time """
1037db96d56Sopenharmony_ci    f.seek(0, 2)
1047db96d56Sopenharmony_ci    size = f.tell()
1057db96d56Sopenharmony_ci    f.seek(0, 0)
1067db96d56Sopenharmony_ci    for i in xrange(0, size - 1):
1077db96d56Sopenharmony_ci        f.seek(i, 0)
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ci@with_open_mode("r")
1107db96d56Sopenharmony_ci@with_sizes("medium")
1117db96d56Sopenharmony_cidef seek_forward_blockwise(f):
1127db96d56Sopenharmony_ci    """ seek forward 1000 units at a time """
1137db96d56Sopenharmony_ci    f.seek(0, 2)
1147db96d56Sopenharmony_ci    size = f.tell()
1157db96d56Sopenharmony_ci    f.seek(0, 0)
1167db96d56Sopenharmony_ci    for i in xrange(0, size - 1, 1000):
1177db96d56Sopenharmony_ci        f.seek(i, 0)
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci@with_open_mode("rb")
1207db96d56Sopenharmony_ci@with_sizes("medium")
1217db96d56Sopenharmony_cidef read_seek_bytewise(f):
1227db96d56Sopenharmony_ci    """ alternate read & seek one unit """
1237db96d56Sopenharmony_ci    f.seek(0)
1247db96d56Sopenharmony_ci    while f.read(1):
1257db96d56Sopenharmony_ci        f.seek(1, 1)
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_ci@with_open_mode("rb")
1287db96d56Sopenharmony_ci@with_sizes("medium")
1297db96d56Sopenharmony_cidef read_seek_blockwise(f):
1307db96d56Sopenharmony_ci    """ alternate read & seek 1000 units """
1317db96d56Sopenharmony_ci    f.seek(0)
1327db96d56Sopenharmony_ci    while f.read(1000):
1337db96d56Sopenharmony_ci        f.seek(1000, 1)
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci
1367db96d56Sopenharmony_ci@with_open_mode("w")
1377db96d56Sopenharmony_ci@with_sizes("small")
1387db96d56Sopenharmony_cidef write_bytewise(f, source):
1397db96d56Sopenharmony_ci    """ write one unit at a time """
1407db96d56Sopenharmony_ci    for i in xrange(0, len(source)):
1417db96d56Sopenharmony_ci        f.write(source[i:i+1])
1427db96d56Sopenharmony_ci
1437db96d56Sopenharmony_ci@with_open_mode("w")
1447db96d56Sopenharmony_ci@with_sizes("medium")
1457db96d56Sopenharmony_cidef write_small_chunks(f, source):
1467db96d56Sopenharmony_ci    """ write 20 units at a time """
1477db96d56Sopenharmony_ci    for i in xrange(0, len(source), 20):
1487db96d56Sopenharmony_ci        f.write(source[i:i+20])
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_ci@with_open_mode("w")
1517db96d56Sopenharmony_ci@with_sizes("medium")
1527db96d56Sopenharmony_cidef write_medium_chunks(f, source):
1537db96d56Sopenharmony_ci    """ write 4096 units at a time """
1547db96d56Sopenharmony_ci    for i in xrange(0, len(source), 4096):
1557db96d56Sopenharmony_ci        f.write(source[i:i+4096])
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ci@with_open_mode("w")
1587db96d56Sopenharmony_ci@with_sizes("large")
1597db96d56Sopenharmony_cidef write_large_chunks(f, source):
1607db96d56Sopenharmony_ci    """ write 1e6 units at a time """
1617db96d56Sopenharmony_ci    for i in xrange(0, len(source), 1000000):
1627db96d56Sopenharmony_ci        f.write(source[i:i+1000000])
1637db96d56Sopenharmony_ci
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ci@with_open_mode("w+")
1667db96d56Sopenharmony_ci@with_sizes("small")
1677db96d56Sopenharmony_cidef modify_bytewise(f, source):
1687db96d56Sopenharmony_ci    """ modify one unit at a time """
1697db96d56Sopenharmony_ci    f.seek(0)
1707db96d56Sopenharmony_ci    for i in xrange(0, len(source)):
1717db96d56Sopenharmony_ci        f.write(source[i:i+1])
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ci@with_open_mode("w+")
1747db96d56Sopenharmony_ci@with_sizes("medium")
1757db96d56Sopenharmony_cidef modify_small_chunks(f, source):
1767db96d56Sopenharmony_ci    """ modify 20 units at a time """
1777db96d56Sopenharmony_ci    f.seek(0)
1787db96d56Sopenharmony_ci    for i in xrange(0, len(source), 20):
1797db96d56Sopenharmony_ci        f.write(source[i:i+20])
1807db96d56Sopenharmony_ci
1817db96d56Sopenharmony_ci@with_open_mode("w+")
1827db96d56Sopenharmony_ci@with_sizes("medium")
1837db96d56Sopenharmony_cidef modify_medium_chunks(f, source):
1847db96d56Sopenharmony_ci    """ modify 4096 units at a time """
1857db96d56Sopenharmony_ci    f.seek(0)
1867db96d56Sopenharmony_ci    for i in xrange(0, len(source), 4096):
1877db96d56Sopenharmony_ci        f.write(source[i:i+4096])
1887db96d56Sopenharmony_ci
1897db96d56Sopenharmony_ci@with_open_mode("wb+")
1907db96d56Sopenharmony_ci@with_sizes("medium")
1917db96d56Sopenharmony_cidef modify_seek_forward_bytewise(f, source):
1927db96d56Sopenharmony_ci    """ alternate write & seek one unit """
1937db96d56Sopenharmony_ci    f.seek(0)
1947db96d56Sopenharmony_ci    for i in xrange(0, len(source), 2):
1957db96d56Sopenharmony_ci        f.write(source[i:i+1])
1967db96d56Sopenharmony_ci        f.seek(i+2)
1977db96d56Sopenharmony_ci
1987db96d56Sopenharmony_ci@with_open_mode("wb+")
1997db96d56Sopenharmony_ci@with_sizes("medium")
2007db96d56Sopenharmony_cidef modify_seek_forward_blockwise(f, source):
2017db96d56Sopenharmony_ci    """ alternate write & seek 1000 units """
2027db96d56Sopenharmony_ci    f.seek(0)
2037db96d56Sopenharmony_ci    for i in xrange(0, len(source), 2000):
2047db96d56Sopenharmony_ci        f.write(source[i:i+1000])
2057db96d56Sopenharmony_ci        f.seek(i+2000)
2067db96d56Sopenharmony_ci
2077db96d56Sopenharmony_ci# XXX the 2 following tests don't work with py3k's text IO
2087db96d56Sopenharmony_ci@with_open_mode("wb+")
2097db96d56Sopenharmony_ci@with_sizes("medium")
2107db96d56Sopenharmony_cidef read_modify_bytewise(f, source):
2117db96d56Sopenharmony_ci    """ alternate read & write one unit """
2127db96d56Sopenharmony_ci    f.seek(0)
2137db96d56Sopenharmony_ci    for i in xrange(0, len(source), 2):
2147db96d56Sopenharmony_ci        f.read(1)
2157db96d56Sopenharmony_ci        f.write(source[i+1:i+2])
2167db96d56Sopenharmony_ci
2177db96d56Sopenharmony_ci@with_open_mode("wb+")
2187db96d56Sopenharmony_ci@with_sizes("medium")
2197db96d56Sopenharmony_cidef read_modify_blockwise(f, source):
2207db96d56Sopenharmony_ci    """ alternate read & write 1000 units """
2217db96d56Sopenharmony_ci    f.seek(0)
2227db96d56Sopenharmony_ci    for i in xrange(0, len(source), 2000):
2237db96d56Sopenharmony_ci        f.read(1000)
2247db96d56Sopenharmony_ci        f.write(source[i+1000:i+2000])
2257db96d56Sopenharmony_ci
2267db96d56Sopenharmony_ci
2277db96d56Sopenharmony_ciread_tests = [
2287db96d56Sopenharmony_ci    read_bytewise, read_small_chunks, read_lines, read_big_chunks,
2297db96d56Sopenharmony_ci    None, read_whole_file, None,
2307db96d56Sopenharmony_ci    seek_forward_bytewise, seek_forward_blockwise,
2317db96d56Sopenharmony_ci    read_seek_bytewise, read_seek_blockwise,
2327db96d56Sopenharmony_ci]
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ciwrite_tests = [
2357db96d56Sopenharmony_ci    write_bytewise, write_small_chunks, write_medium_chunks, write_large_chunks,
2367db96d56Sopenharmony_ci]
2377db96d56Sopenharmony_ci
2387db96d56Sopenharmony_cimodify_tests = [
2397db96d56Sopenharmony_ci    modify_bytewise, modify_small_chunks, modify_medium_chunks,
2407db96d56Sopenharmony_ci    None,
2417db96d56Sopenharmony_ci    modify_seek_forward_bytewise, modify_seek_forward_blockwise,
2427db96d56Sopenharmony_ci    read_modify_bytewise, read_modify_blockwise,
2437db96d56Sopenharmony_ci]
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_cidef run_during(duration, func):
2467db96d56Sopenharmony_ci    _t = time.time
2477db96d56Sopenharmony_ci    n = 0
2487db96d56Sopenharmony_ci    start = os.times()
2497db96d56Sopenharmony_ci    start_timestamp = _t()
2507db96d56Sopenharmony_ci    real_start = start[4] or start_timestamp
2517db96d56Sopenharmony_ci    while True:
2527db96d56Sopenharmony_ci        func()
2537db96d56Sopenharmony_ci        n += 1
2547db96d56Sopenharmony_ci        if _t() - start_timestamp > duration:
2557db96d56Sopenharmony_ci            break
2567db96d56Sopenharmony_ci    end = os.times()
2577db96d56Sopenharmony_ci    real = (end[4] if start[4] else time.time()) - real_start
2587db96d56Sopenharmony_ci    return n, real, sum(end[0:2]) - sum(start[0:2])
2597db96d56Sopenharmony_ci
2607db96d56Sopenharmony_cidef warm_cache(filename):
2617db96d56Sopenharmony_ci    with open(filename, "rb") as f:
2627db96d56Sopenharmony_ci        f.read()
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ci
2657db96d56Sopenharmony_cidef run_all_tests(options):
2667db96d56Sopenharmony_ci    def print_label(filename, func):
2677db96d56Sopenharmony_ci        name = re.split(r'[-.]', filename)[0]
2687db96d56Sopenharmony_ci        out.write(
2697db96d56Sopenharmony_ci            ("[%s] %s... "
2707db96d56Sopenharmony_ci                % (name.center(7), func.__doc__.strip())
2717db96d56Sopenharmony_ci            ).ljust(52))
2727db96d56Sopenharmony_ci        out.flush()
2737db96d56Sopenharmony_ci
2747db96d56Sopenharmony_ci    def print_results(size, n, real, cpu):
2757db96d56Sopenharmony_ci        bw = n * float(size) / 1024 ** 2 / real
2767db96d56Sopenharmony_ci        bw = ("%4d MiB/s" if bw > 100 else "%.3g MiB/s") % bw
2777db96d56Sopenharmony_ci        out.write(bw.rjust(12) + "\n")
2787db96d56Sopenharmony_ci        if cpu < 0.90 * real:
2797db96d56Sopenharmony_ci            out.write("   warning: test above used only %d%% CPU, "
2807db96d56Sopenharmony_ci                "result may be flawed!\n" % (100.0 * cpu / real))
2817db96d56Sopenharmony_ci
2827db96d56Sopenharmony_ci    def run_one_test(name, size, open_func, test_func, *args):
2837db96d56Sopenharmony_ci        mode = test_func.file_open_mode
2847db96d56Sopenharmony_ci        print_label(name, test_func)
2857db96d56Sopenharmony_ci        if "w" not in mode or "+" in mode:
2867db96d56Sopenharmony_ci            warm_cache(name)
2877db96d56Sopenharmony_ci        with open_func(name) as f:
2887db96d56Sopenharmony_ci            n, real, cpu = run_during(1.5, lambda: test_func(f, *args))
2897db96d56Sopenharmony_ci        print_results(size, n, real, cpu)
2907db96d56Sopenharmony_ci
2917db96d56Sopenharmony_ci    def run_test_family(tests, mode_filter, files, open_func, *make_args):
2927db96d56Sopenharmony_ci        for test_func in tests:
2937db96d56Sopenharmony_ci            if test_func is None:
2947db96d56Sopenharmony_ci                out.write("\n")
2957db96d56Sopenharmony_ci                continue
2967db96d56Sopenharmony_ci            if mode_filter in test_func.file_open_mode:
2977db96d56Sopenharmony_ci                continue
2987db96d56Sopenharmony_ci            for s in test_func.file_sizes:
2997db96d56Sopenharmony_ci                name, size = files[size_names[s]]
3007db96d56Sopenharmony_ci                #name += file_ext
3017db96d56Sopenharmony_ci                args = tuple(f(name, size) for f in make_args)
3027db96d56Sopenharmony_ci                run_one_test(name, size,
3037db96d56Sopenharmony_ci                    open_func, test_func, *args)
3047db96d56Sopenharmony_ci
3057db96d56Sopenharmony_ci    size_names = {
3067db96d56Sopenharmony_ci        "small": 0,
3077db96d56Sopenharmony_ci        "medium": 1,
3087db96d56Sopenharmony_ci        "large": 2,
3097db96d56Sopenharmony_ci    }
3107db96d56Sopenharmony_ci
3117db96d56Sopenharmony_ci    print("Python %s" % sys.version)
3127db96d56Sopenharmony_ci    if sys.version_info < (3, 3):
3137db96d56Sopenharmony_ci        if sys.maxunicode > 0xffff:
3147db96d56Sopenharmony_ci            text = "UCS-4 (wide build)"
3157db96d56Sopenharmony_ci        else:
3167db96d56Sopenharmony_ci            text = "UTF-16 (narrow build)"
3177db96d56Sopenharmony_ci    else:
3187db96d56Sopenharmony_ci        text = "PEP 393"
3197db96d56Sopenharmony_ci    print("Unicode: %s" % text)
3207db96d56Sopenharmony_ci    print(platform.platform())
3217db96d56Sopenharmony_ci    binary_files = list(get_binary_files())
3227db96d56Sopenharmony_ci    text_files = list(get_text_files())
3237db96d56Sopenharmony_ci    if "b" in options:
3247db96d56Sopenharmony_ci        print("Binary unit = one byte")
3257db96d56Sopenharmony_ci    if "t" in options:
3267db96d56Sopenharmony_ci        print("Text unit = one character (%s-decoded)" % TEXT_ENCODING)
3277db96d56Sopenharmony_ci
3287db96d56Sopenharmony_ci    # Binary reads
3297db96d56Sopenharmony_ci    if "b" in options and "r" in options:
3307db96d56Sopenharmony_ci        print("\n** Binary input **\n")
3317db96d56Sopenharmony_ci        run_test_family(read_tests, "t", binary_files, lambda fn: open(fn, "rb"))
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci    # Text reads
3347db96d56Sopenharmony_ci    if "t" in options and "r" in options:
3357db96d56Sopenharmony_ci        print("\n** Text input **\n")
3367db96d56Sopenharmony_ci        run_test_family(read_tests, "b", text_files, lambda fn: text_open(fn, "r"))
3377db96d56Sopenharmony_ci
3387db96d56Sopenharmony_ci    # Binary writes
3397db96d56Sopenharmony_ci    if "b" in options and "w" in options:
3407db96d56Sopenharmony_ci        print("\n** Binary append **\n")
3417db96d56Sopenharmony_ci        def make_test_source(name, size):
3427db96d56Sopenharmony_ci            with open(name, "rb") as f:
3437db96d56Sopenharmony_ci                return f.read()
3447db96d56Sopenharmony_ci        run_test_family(write_tests, "t", binary_files,
3457db96d56Sopenharmony_ci            lambda fn: open(os.devnull, "wb"), make_test_source)
3467db96d56Sopenharmony_ci
3477db96d56Sopenharmony_ci    # Text writes
3487db96d56Sopenharmony_ci    if "t" in options and "w" in options:
3497db96d56Sopenharmony_ci        print("\n** Text append **\n")
3507db96d56Sopenharmony_ci        def make_test_source(name, size):
3517db96d56Sopenharmony_ci            with text_open(name, "r") as f:
3527db96d56Sopenharmony_ci                return f.read()
3537db96d56Sopenharmony_ci        run_test_family(write_tests, "b", text_files,
3547db96d56Sopenharmony_ci            lambda fn: text_open(os.devnull, "w"), make_test_source)
3557db96d56Sopenharmony_ci
3567db96d56Sopenharmony_ci    # Binary overwrites
3577db96d56Sopenharmony_ci    if "b" in options and "w" in options:
3587db96d56Sopenharmony_ci        print("\n** Binary overwrite **\n")
3597db96d56Sopenharmony_ci        def make_test_source(name, size):
3607db96d56Sopenharmony_ci            with open(name, "rb") as f:
3617db96d56Sopenharmony_ci                return f.read()
3627db96d56Sopenharmony_ci        run_test_family(modify_tests, "t", binary_files,
3637db96d56Sopenharmony_ci            lambda fn: open(fn, "r+b"), make_test_source)
3647db96d56Sopenharmony_ci
3657db96d56Sopenharmony_ci    # Text overwrites
3667db96d56Sopenharmony_ci    if "t" in options and "w" in options:
3677db96d56Sopenharmony_ci        print("\n** Text overwrite **\n")
3687db96d56Sopenharmony_ci        def make_test_source(name, size):
3697db96d56Sopenharmony_ci            with text_open(name, "r") as f:
3707db96d56Sopenharmony_ci                return f.read()
3717db96d56Sopenharmony_ci        run_test_family(modify_tests, "b", text_files,
3727db96d56Sopenharmony_ci            lambda fn: text_open(fn, "r+"), make_test_source)
3737db96d56Sopenharmony_ci
3747db96d56Sopenharmony_ci
3757db96d56Sopenharmony_cidef prepare_files():
3767db96d56Sopenharmony_ci    print("Preparing files...")
3777db96d56Sopenharmony_ci    # Binary files
3787db96d56Sopenharmony_ci    for name, size in get_binary_files():
3797db96d56Sopenharmony_ci        if os.path.isfile(name) and os.path.getsize(name) == size:
3807db96d56Sopenharmony_ci            continue
3817db96d56Sopenharmony_ci        with open(name, "wb") as f:
3827db96d56Sopenharmony_ci            f.write(os.urandom(size))
3837db96d56Sopenharmony_ci    # Text files
3847db96d56Sopenharmony_ci    chunk = []
3857db96d56Sopenharmony_ci    with text_open(__file__, "r", encoding='utf8') as f:
3867db96d56Sopenharmony_ci        for line in f:
3877db96d56Sopenharmony_ci            if line.startswith("# <iobench text chunk marker>"):
3887db96d56Sopenharmony_ci                break
3897db96d56Sopenharmony_ci        else:
3907db96d56Sopenharmony_ci            raise RuntimeError(
3917db96d56Sopenharmony_ci                "Couldn't find chunk marker in %s !" % __file__)
3927db96d56Sopenharmony_ci        if NEWLINES == "all":
3937db96d56Sopenharmony_ci            it = itertools.cycle(["\n", "\r", "\r\n"])
3947db96d56Sopenharmony_ci        else:
3957db96d56Sopenharmony_ci            it = itertools.repeat(
3967db96d56Sopenharmony_ci                {"cr": "\r", "lf": "\n", "crlf": "\r\n"}[NEWLINES])
3977db96d56Sopenharmony_ci        chunk = "".join(line.replace("\n", next(it)) for line in f)
3987db96d56Sopenharmony_ci        if isinstance(chunk, bytes):
3997db96d56Sopenharmony_ci            chunk = chunk.decode('utf8')
4007db96d56Sopenharmony_ci        chunk = chunk.encode(TEXT_ENCODING)
4017db96d56Sopenharmony_ci    for name, size in get_text_files():
4027db96d56Sopenharmony_ci        if os.path.isfile(name) and os.path.getsize(name) == size:
4037db96d56Sopenharmony_ci            continue
4047db96d56Sopenharmony_ci        head = chunk * (size // len(chunk))
4057db96d56Sopenharmony_ci        tail = chunk[:size % len(chunk)]
4067db96d56Sopenharmony_ci        # Adjust tail to end on a character boundary
4077db96d56Sopenharmony_ci        while True:
4087db96d56Sopenharmony_ci            try:
4097db96d56Sopenharmony_ci                tail.decode(TEXT_ENCODING)
4107db96d56Sopenharmony_ci                break
4117db96d56Sopenharmony_ci            except UnicodeDecodeError:
4127db96d56Sopenharmony_ci                tail = tail[:-1]
4137db96d56Sopenharmony_ci        with open(name, "wb") as f:
4147db96d56Sopenharmony_ci            f.write(head)
4157db96d56Sopenharmony_ci            f.write(tail)
4167db96d56Sopenharmony_ci
4177db96d56Sopenharmony_cidef main():
4187db96d56Sopenharmony_ci    global TEXT_ENCODING, NEWLINES
4197db96d56Sopenharmony_ci
4207db96d56Sopenharmony_ci    usage = "usage: %prog [-h|--help] [options]"
4217db96d56Sopenharmony_ci    parser = OptionParser(usage=usage)
4227db96d56Sopenharmony_ci    parser.add_option("-b", "--binary",
4237db96d56Sopenharmony_ci                      action="store_true", dest="binary", default=False,
4247db96d56Sopenharmony_ci                      help="run binary I/O tests")
4257db96d56Sopenharmony_ci    parser.add_option("-t", "--text",
4267db96d56Sopenharmony_ci                      action="store_true", dest="text", default=False,
4277db96d56Sopenharmony_ci                      help="run text I/O tests")
4287db96d56Sopenharmony_ci    parser.add_option("-r", "--read",
4297db96d56Sopenharmony_ci                      action="store_true", dest="read", default=False,
4307db96d56Sopenharmony_ci                      help="run read tests")
4317db96d56Sopenharmony_ci    parser.add_option("-w", "--write",
4327db96d56Sopenharmony_ci                      action="store_true", dest="write", default=False,
4337db96d56Sopenharmony_ci                      help="run write & modify tests")
4347db96d56Sopenharmony_ci    parser.add_option("-E", "--encoding",
4357db96d56Sopenharmony_ci                      action="store", dest="encoding", default=None,
4367db96d56Sopenharmony_ci                      help="encoding for text tests (default: %s)" % TEXT_ENCODING)
4377db96d56Sopenharmony_ci    parser.add_option("-N", "--newlines",
4387db96d56Sopenharmony_ci                      action="store", dest="newlines", default='lf',
4397db96d56Sopenharmony_ci                      help="line endings for text tests "
4407db96d56Sopenharmony_ci                           "(one of: {lf (default), cr, crlf, all})")
4417db96d56Sopenharmony_ci    parser.add_option("-m", "--io-module",
4427db96d56Sopenharmony_ci                      action="store", dest="io_module", default=None,
4437db96d56Sopenharmony_ci                      help="io module to test (default: builtin open())")
4447db96d56Sopenharmony_ci    options, args = parser.parse_args()
4457db96d56Sopenharmony_ci    if args:
4467db96d56Sopenharmony_ci        parser.error("unexpected arguments")
4477db96d56Sopenharmony_ci    NEWLINES = options.newlines.lower()
4487db96d56Sopenharmony_ci    if NEWLINES not in ('lf', 'cr', 'crlf', 'all'):
4497db96d56Sopenharmony_ci        parser.error("invalid 'newlines' option: %r" % NEWLINES)
4507db96d56Sopenharmony_ci
4517db96d56Sopenharmony_ci    test_options = ""
4527db96d56Sopenharmony_ci    if options.read:
4537db96d56Sopenharmony_ci        test_options += "r"
4547db96d56Sopenharmony_ci    if options.write:
4557db96d56Sopenharmony_ci        test_options += "w"
4567db96d56Sopenharmony_ci    elif not options.read:
4577db96d56Sopenharmony_ci        test_options += "rw"
4587db96d56Sopenharmony_ci    if options.text:
4597db96d56Sopenharmony_ci        test_options += "t"
4607db96d56Sopenharmony_ci    if options.binary:
4617db96d56Sopenharmony_ci        test_options += "b"
4627db96d56Sopenharmony_ci    elif not options.text:
4637db96d56Sopenharmony_ci        test_options += "tb"
4647db96d56Sopenharmony_ci
4657db96d56Sopenharmony_ci    if options.encoding:
4667db96d56Sopenharmony_ci        TEXT_ENCODING = options.encoding
4677db96d56Sopenharmony_ci
4687db96d56Sopenharmony_ci    if options.io_module:
4697db96d56Sopenharmony_ci        globals()['open'] = __import__(options.io_module, {}, {}, ['open']).open
4707db96d56Sopenharmony_ci
4717db96d56Sopenharmony_ci    prepare_files()
4727db96d56Sopenharmony_ci    run_all_tests(test_options)
4737db96d56Sopenharmony_ci
4747db96d56Sopenharmony_ciif __name__ == "__main__":
4757db96d56Sopenharmony_ci    main()
4767db96d56Sopenharmony_ci
4777db96d56Sopenharmony_ci
4787db96d56Sopenharmony_ci# -- This part to exercise text reading. Don't change anything! --
4797db96d56Sopenharmony_ci# <iobench text chunk marker>
4807db96d56Sopenharmony_ci
4817db96d56Sopenharmony_ci"""
4827db96d56Sopenharmony_ci1.
4837db96d56Sopenharmony_ciGáttir allar,
4847db96d56Sopenharmony_ciáðr gangi fram,
4857db96d56Sopenharmony_cium skoðask skyli,
4867db96d56Sopenharmony_cium skyggnast skyli,
4877db96d56Sopenharmony_ciþví at óvíst er at vita,
4887db96d56Sopenharmony_cihvar óvinir
4897db96d56Sopenharmony_cisitja á fleti fyrir.
4907db96d56Sopenharmony_ci
4917db96d56Sopenharmony_ci2.
4927db96d56Sopenharmony_ciGefendr heilir!
4937db96d56Sopenharmony_ciGestr er inn kominn,
4947db96d56Sopenharmony_cihvar skal sitja sjá?
4957db96d56Sopenharmony_ciMjök er bráðr,
4967db96d56Sopenharmony_cisá er á bröndum skal
4977db96d56Sopenharmony_cisíns of freista frama.
4987db96d56Sopenharmony_ci
4997db96d56Sopenharmony_ci3.
5007db96d56Sopenharmony_ciElds er þörf,
5017db96d56Sopenharmony_ciþeims inn er kominn
5027db96d56Sopenharmony_ciok á kné kalinn;
5037db96d56Sopenharmony_cimatar ok váða
5047db96d56Sopenharmony_cier manni þörf,
5057db96d56Sopenharmony_ciþeim er hefr um fjall farit.
5067db96d56Sopenharmony_ci
5077db96d56Sopenharmony_ci4.
5087db96d56Sopenharmony_ciVatns er þörf,
5097db96d56Sopenharmony_ciþeim er til verðar kemr,
5107db96d56Sopenharmony_ciþerru ok þjóðlaðar,
5117db96d56Sopenharmony_cigóðs of æðis,
5127db96d56Sopenharmony_cief sér geta mætti,
5137db96d56Sopenharmony_ciorðs ok endrþögu.
5147db96d56Sopenharmony_ci
5157db96d56Sopenharmony_ci5.
5167db96d56Sopenharmony_ciVits er þörf,
5177db96d56Sopenharmony_ciþeim er víða ratar;
5187db96d56Sopenharmony_cidælt er heima hvat;
5197db96d56Sopenharmony_ciat augabragði verðr,
5207db96d56Sopenharmony_cisá er ekki kann
5217db96d56Sopenharmony_ciok með snotrum sitr.
5227db96d56Sopenharmony_ci
5237db96d56Sopenharmony_ci6.
5247db96d56Sopenharmony_ciAt hyggjandi sinni
5257db96d56Sopenharmony_ciskyli-t maðr hræsinn vera,
5267db96d56Sopenharmony_ciheldr gætinn at geði;
5277db96d56Sopenharmony_ciþá er horskr ok þögull
5287db96d56Sopenharmony_cikemr heimisgarða til,
5297db96d56Sopenharmony_cisjaldan verðr víti vörum,
5307db96d56Sopenharmony_ciþví at óbrigðra vin
5317db96d56Sopenharmony_cifær maðr aldregi
5327db96d56Sopenharmony_cien mannvit mikit.
5337db96d56Sopenharmony_ci
5347db96d56Sopenharmony_ci7.
5357db96d56Sopenharmony_ciInn vari gestr,
5367db96d56Sopenharmony_cier til verðar kemr,
5377db96d56Sopenharmony_ciþunnu hljóði þegir,
5387db96d56Sopenharmony_cieyrum hlýðir,
5397db96d56Sopenharmony_cien augum skoðar;
5407db96d56Sopenharmony_cisvá nýsisk fróðra hverr fyrir.
5417db96d56Sopenharmony_ci
5427db96d56Sopenharmony_ci8.
5437db96d56Sopenharmony_ciHinn er sæll,
5447db96d56Sopenharmony_cier sér of getr
5457db96d56Sopenharmony_cilof ok líknstafi;
5467db96d56Sopenharmony_ciódælla er við þat,
5477db96d56Sopenharmony_cier maðr eiga skal
5487db96d56Sopenharmony_ciannars brjóstum í.
5497db96d56Sopenharmony_ci"""
5507db96d56Sopenharmony_ci
5517db96d56Sopenharmony_ci"""
5527db96d56Sopenharmony_ciC'est revenir tard, je le sens, sur un sujet trop rebattu et déjà presque oublié. Mon état, qui ne me permet plus aucun travail suivi, mon aversion pour le genre polémique, ont causé ma lenteur à écrire et ma répugnance à publier. J'aurais même tout à fait supprimé ces Lettres, ou plutôt je lie les aurais point écrites, s'il n'eût été question que de moi : Mais ma patrie ne m'est pas tellement devenue étrangère que je puisse voir tranquillement opprimer ses citoyens, surtout lorsqu'ils n'ont compromis leurs droits qu'en défendant ma cause. Je serais le dernier des hommes si dans une telle occasion j'écoutais un sentiment qui n'est plus ni douceur ni patience, mais faiblesse et lâcheté, dans celui qu'il empêche de remplir son devoir.
5537db96d56Sopenharmony_ciRien de moins important pour le public, j'en conviens, que la matière de ces lettres. La constitution d'une petite République, le sort d'un petit particulier, l'exposé de quelques injustices, la réfutation de quelques sophismes ; tout cela n'a rien en soi d'assez considérable pour mériter beaucoup de lecteurs : mais si mes sujets sont petits mes objets sont grands, et dignes de l'attention de tout honnête homme. Laissons Genève à sa place, et Rousseau dans sa dépression ; mais la religion, mais la liberté, la justice ! voilà, qui que vous soyez, ce qui n'est pas au-dessous de vous.
5547db96d56Sopenharmony_ciQu'on ne cherche pas même ici dans le style le dédommagement de l'aridité de la matière. Ceux que quelques traits heureux de ma plume ont si fort irrités trouveront de quoi s'apaiser dans ces lettres, L'honneur de défendre un opprimé eût enflammé mon coeur si j'avais parlé pour un autre. Réduit au triste emploi de me défendre moi-même, j'ai dû me borner à raisonner ; m'échauffer eût été m'avilir. J'aurai donc trouvé grâce en ce point devant ceux qui s'imaginent qu'il est essentiel à la vérité d'être dite froidement ; opinion que pourtant j'ai peine à comprendre. Lorsqu'une vive persuasion nous anime, le moyen d'employer un langage glacé ? Quand Archimède tout transporté courait nu dans les rues de Syracuse, en avait-il moins trouvé la vérité parce qu'il se passionnait pour elle ? Tout au contraire, celui qui la sent ne peut s'abstenir de l'adorer ; celui qui demeure froid ne l'a pas vue.
5557db96d56Sopenharmony_ciQuoi qu'il en soit, je prie les lecteurs de vouloir bien mettre à part mon beau style, et d'examiner seulement si je raisonne bien ou mal ; car enfin, de cela seul qu'un auteur s'exprime en bons termes, je ne vois pas comment il peut s'ensuivre que cet auteur ne sait ce qu'il dit.
5567db96d56Sopenharmony_ci"""
557