1#!/usr/bin/python
2
3# This script confirms both that the register report "adds up", and that its
4# final balance is the same as what the balance report shows.
5
6from __future__ import print_function
7
8import sys
9import re
10
11from difflib import ndiff
12
13multiproc = False
14try:
15    from multiprocessing import Pool
16    multiproc = True
17except:
18    pass
19
20args = sys.argv
21jobs = 1
22match = re.match('-j([0-9]+)?', args[1])
23if match:
24    args = [args[0]] + args[2:]
25    if match.group(1):
26        jobs = int(match.group(1))
27if jobs == 1:
28    multiproc = False
29
30from LedgerHarness import LedgerHarness
31
32harness = LedgerHarness(args)
33
34#def normalize(line):
35#    match = re.match("((\s*)([A-Za-z]+)?(\s*)([-0-9.]+)(\s*)([A-Za-z]+)?)(  (.+))?$", line)
36#    if match:
37#        if match.group(3):
38#            prefix = match.group(3) + " " + match.group(5)
39#            if match.group(8):
40#                return prefix + match.group(8)
41#            return prefix
42#        elif match.group(7):
43#            prefix = match.group(7) + " " + match.group(5)
44#            if match.group(8):
45#                return prefix + match.group(8)
46#            return prefix
47#    return line
48
49def generation_test(seed):
50    p_gen = harness.run('$ledger --seed=%d generate' % seed)
51
52    cout = harness.read(p_gen.stdout)
53
54    if not harness.wait(p_gen, msg=("Generation for seed %d failed:" % seed)):
55        return False
56
57    p_print = harness.run('$ledger --actual -f - print')
58    p_print.stdin.write(cout)
59    p_print.stdin.close()
60    p_print_out = p_print.stdout.read()
61
62    if not harness.wait(p_print, msg=("Print for seed %d failed:" % seed)):
63        return False
64
65    #p_cerr_bal = Popen("%s --args-only -f - bal" % ledger, shell=True,
66    #                   stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
67    #p_cerr_bal.stdin.write(cerr)
68    #p_cerr_bal.stdin.close()
69    #
70    #cerr_lines = [normalize(line) for line in p_cerr_bal.stdout.readlines()]
71    #
72    #if p_cerr_bal.wait() != 0:
73    #    print("Stderr balance for seed %d failed due to error:" % seed)
74    #    print(p_cerr_bal.stderr.read())
75    #    del p_cerr_bal
76    #    return False
77    #del p_cerr_bal
78
79    p_cout_bal = harness.run('$ledger -f - bal')
80    p_cout_bal.stdin.write(cout)
81    p_cout_bal.stdin.close()
82
83    cout_lines = harness.readlines(p_cout_bal.stdout)
84    if len(cout_lines) == 0:
85      return False
86    #norm_cout_lines = [normalize(line) for line in cout_lines]
87
88    if not harness.wait(p_cout_bal, msg=("Stdout balance for seed %d failed:" % seed)):
89        return False
90
91    p_print_bal = harness.run('$ledger -f - bal')
92    p_print_bal.stdin.write(p_print_out)
93    p_print_bal.stdin.close()
94
95    print_lines = harness.readlines(p_print_bal.stdout)
96    if len(print_lines) == 0:
97      return False
98
99    if not harness.wait(p_print_bal, msg=("Print balance for seed %d failed:" % seed)):
100        return False
101
102    success = True
103    #printed = False
104    #for line in ndiff(cerr_lines, norm_cout_lines, charjunk=None):
105    #    if line[:2] == "  ":
106    #        continue
107    #    if not printed:
108    #        if success: print()
109    #        print("Generation failure in output from seed %d (cerr vs. cout):" % seed)
110    #        if success: failed += 1
111    #        success = False
112    #        printed = True
113    #    print(" ", line)
114
115    printed = False
116    for line in ndiff(cout_lines, print_lines, charjunk=None):
117        if line[:2] == "  ":
118            continue
119        if not printed:
120            if success: print()
121            print("Generation failure in output from seed %d (cout vs. print):" % seed)
122            success = False
123            printed = True
124        print(" ", line)
125
126    return success
127
128beg_range = 1
129end_range = 20
130if len(args) > 4:
131    beg_range = int(args[3])
132    end_range = int(args[4])
133
134def run_gen_test(i):
135    if generation_test(i):
136        harness.success()
137    else:
138        harness.failure()
139    return harness.failed
140
141if multiproc:
142    pool = Pool(jobs*2)
143else:
144    pool = None
145
146if pool:
147    pool.map(run_gen_test, range(beg_range, end_range))
148else:
149    for i in range(beg_range, end_range):
150        run_gen_test(i)
151
152if pool:
153    pool.close()
154    pool.join()
155
156harness.exit()
157