xref: /dflybsd-src/contrib/cryptsetup/tests/fileDiffer.py (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino#!/usr/bin/env python
2*86d7f5d3SJohn Marino
3*86d7f5d3SJohn Marino#
4*86d7f5d3SJohn Marino# Usage: fileDiffer <afile> <bfile> <list of disk changes>
5*86d7f5d3SJohn Marino#
6*86d7f5d3SJohn Marino
7*86d7f5d3SJohn Marino# LUKS
8*86d7f5d3SJohn Marino# quick regression test suite
9*86d7f5d3SJohn Marino# Tests LUKS images for changes at certain disk offsets
10*86d7f5d3SJohn Marino#
11*86d7f5d3SJohn Marino# Does fast python code has to look ugly or is it just me?
12*86d7f5d3SJohn Marino
13*86d7f5d3SJohn Marinoimport sys
14*86d7f5d3SJohn Marino
15*86d7f5d3SJohn Marinoclass changes:
16*86d7f5d3SJohn Marino	pass
17*86d7f5d3SJohn Marino
18*86d7f5d3SJohn Marinodef parseArgs(args):
19*86d7f5d3SJohn Marino	aFileName = args[1]
20*86d7f5d3SJohn Marino	bFileName = args[2]
21*86d7f5d3SJohn Marino	changelist = []
22*86d7f5d3SJohn Marino	args[0:3] = []
23*86d7f5d3SJohn Marino	for i in args:
24*86d7f5d3SJohn Marino		mychanges = changes();
25*86d7f5d3SJohn Marino		if i.startswith('A'):
26*86d7f5d3SJohn Marino			mychanges.mode = 'ALLOWED'
27*86d7f5d3SJohn Marino		if i.startswith('R'):
28*86d7f5d3SJohn Marino			mychanges.mode = 'REQUIRED'
29*86d7f5d3SJohn Marino			mychanges.strictness = 'RANDOM'
30*86d7f5d3SJohn Marino		if i.startswith('S'):
31*86d7f5d3SJohn Marino			mychanges.mode = 'REQUIRED'
32*86d7f5d3SJohn Marino			mychanges.strictness = 'SEMANTIC'
33*86d7f5d3SJohn Marino
34*86d7f5d3SJohn Marino		dashIndex = i.find('-')
35*86d7f5d3SJohn Marino		if dashIndex == -1:
36*86d7f5d3SJohn Marino			mychanges.starts = int(i[1:])
37*86d7f5d3SJohn Marino			mychanges.ends = mychanges.starts
38*86d7f5d3SJohn Marino		else:
39*86d7f5d3SJohn Marino			mychanges.starts = int(i[1:dashIndex])
40*86d7f5d3SJohn Marino			mychanges.ends = int(i[dashIndex+1:])
41*86d7f5d3SJohn Marino		mychanges.miss = 0
42*86d7f5d3SJohn Marino		changelist.append(mychanges)
43*86d7f5d3SJohn Marino	mychanges = changes();
44*86d7f5d3SJohn Marino	mychanges.starts = 0
45*86d7f5d3SJohn Marino#	mychanges.ends will be fixed later
46*86d7f5d3SJohn Marino	mychanges.mode = 'FORBIDDEN'
47*86d7f5d3SJohn Marino	changelist.append(mychanges)
48*86d7f5d3SJohn Marino	return [aFileName, bFileName, changelist]
49*86d7f5d3SJohn Marino
50*86d7f5d3SJohn Marinodef mode(i):
51*86d7f5d3SJohn Marino	for c in changelist:
52*86d7f5d3SJohn Marino		if i >= c.starts and i<=c.ends:
53*86d7f5d3SJohn Marino			return c
54*86d7f5d3SJohn Marinodef cleanchanges(i):
55*86d7f5d3SJohn Marino	newchangelist=[]
56*86d7f5d3SJohn Marino	for c in changelist:
57*86d7f5d3SJohn Marino		if i <= c.starts or i <= c.ends:
58*86d7f5d3SJohn Marino			newchangelist.append(c)
59*86d7f5d3SJohn Marino	return newchangelist
60*86d7f5d3SJohn Marino
61*86d7f5d3SJohn Marino[aFileName, bFileName, changelist] = parseArgs(sys.argv)
62*86d7f5d3SJohn Marino
63*86d7f5d3SJohn MarinoaFile = open(aFileName,'r')
64*86d7f5d3SJohn MarinobFile = open(bFileName,'r')
65*86d7f5d3SJohn Marino
66*86d7f5d3SJohn MarinoaString = aFile.read()
67*86d7f5d3SJohn MarinobString = bFile.read()
68*86d7f5d3SJohn Marino
69*86d7f5d3SJohn Marinoif len(aString) != len(bString):
70*86d7f5d3SJohn Marino	sys.exit("Mismatch different file sizes")
71*86d7f5d3SJohn Marino
72*86d7f5d3SJohn MarinofileLen = len(aString)
73*86d7f5d3SJohn MarinofileLen10th = fileLen/10
74*86d7f5d3SJohn Marino
75*86d7f5d3SJohn Marino# Create a catch all entry
76*86d7f5d3SJohn Marinochangelist[-1].ends = fileLen
77*86d7f5d3SJohn Marino
78*86d7f5d3SJohn Marinoprint "Changes list: (FORBIDDEN default)"
79*86d7f5d3SJohn Marinoprint "start\tend\tmode\t\tstrictness"
80*86d7f5d3SJohn Marinofor i in changelist:
81*86d7f5d3SJohn Marino	if i.mode == 'REQUIRED':
82*86d7f5d3SJohn Marino		print "%d\t%d\t%s\t%s" % (i.starts, i.ends, i.mode, i.strictness)
83*86d7f5d3SJohn Marino	else:
84*86d7f5d3SJohn Marino		print "%d\t%d\t%s" % (i.starts, i.ends, i.mode)
85*86d7f5d3SJohn Marino
86*86d7f5d3SJohn Marino
87*86d7f5d3SJohn Marinofilepos = 0
88*86d7f5d3SJohn MarinofileLen10thC = 0
89*86d7f5d3SJohn Marinoprint "[..........]"
90*86d7f5d3SJohn Marinosys.stdout.write("[")
91*86d7f5d3SJohn Marinosys.stdout.flush()
92*86d7f5d3SJohn Marino
93*86d7f5d3SJohn MarinomodeNotTrivial = 1
94*86d7f5d3SJohn Marinowhile filepos < fileLen:
95*86d7f5d3SJohn Marino
96*86d7f5d3SJohn Marino	if modeNotTrivial == 1:
97*86d7f5d3SJohn Marino		c = mode(filepos)
98*86d7f5d3SJohn Marino#	print (filepos, c.mode)
99*86d7f5d3SJohn Marino	if c.mode == 'REQUIRED':
100*86d7f5d3SJohn Marino		if aString[filepos] == bString[filepos]:
101*86d7f5d3SJohn Marino			c.miss = c.miss + 1
102*86d7f5d3SJohn Marino	else:
103*86d7f5d3SJohn Marino		if aString[filepos] != bString[filepos] and c.mode != 'ALLOWED':
104*86d7f5d3SJohn Marino			sys.exit("Mismatch at %d: change forbidden" % filepos)
105*86d7f5d3SJohn Marino
106*86d7f5d3SJohn Marino	# Do some maintaince, print progress bar, and clean changelist
107*86d7f5d3SJohn Marino	#
108*86d7f5d3SJohn Marino	# Maintaining two counters appears to be faster than modulo operation
109*86d7f5d3SJohn Marino	if fileLen10thC == fileLen10th:
110*86d7f5d3SJohn Marino		fileLen10thC = 0
111*86d7f5d3SJohn Marino		sys.stdout.write(".")
112*86d7f5d3SJohn Marino		sys.stdout.flush()
113*86d7f5d3SJohn Marino		changelist = cleanchanges(filepos)
114*86d7f5d3SJohn Marino		if len(changelist) == 1:
115*86d7f5d3SJohn Marino			modeNotTrivial = 0
116*86d7f5d3SJohn Marino	filepos = filepos + 1
117*86d7f5d3SJohn Marino	fileLen10thC = fileLen10thC + 1
118*86d7f5d3SJohn Marino
119*86d7f5d3SJohn Marinofor c in changelist:
120*86d7f5d3SJohn Marino	if c.mode == 'REQUIRED':
121*86d7f5d3SJohn Marino		if c.strictness == 'SEMANTIC' and c.miss == (c.ends-c.starts+1):
122*86d7f5d3SJohn Marino			sys.exit("Mismatch: not even a single change in region %d-%d." % (c.starts, c.ends))
123*86d7f5d3SJohn Marino   	        # This is not correct. We should do a statistical test
124*86d7f5d3SJohn Marino	        # of the sampled data against the hypothetical distribution
125*86d7f5d3SJohn Marino	        # of collision. Chi-Square Test.
126*86d7f5d3SJohn Marino		if c.strictness == 'RANDOM' and c.miss == (c.ends-c.starts+1):
127*86d7f5d3SJohn Marino			sys.exit("Mismatch: not even a single change in region %d-%d." % (c.starts, c.ends))
128*86d7f5d3SJohn Marino
129*86d7f5d3SJohn Marinoprint ".] - everything ok"
130