Skip to content

Commit 17ade83

Browse files
committed
added test environment
1 parent 8056239 commit 17ade83

File tree

4 files changed

+148
-3
lines changed

4 files changed

+148
-3
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ __pycache__/
55
.idea/
66

77
path_bpatch.py
8+
9+
/test/*
10+
!/test/*.py

bpatch.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ def generate_hex_fw(filename, fw_path, fw_header_path, header_fw_size):
642642
# check if the patched firmware is equal to the new firmware
643643
if os.system(f"diff patched_fw.tmp new_fw.tmp"):
644644
print("The txt patch is not correct")
645-
exit()
645+
exit(2)
646646
else:
647647
print("The txt patch is correct")
648648

@@ -653,7 +653,7 @@ def generate_hex_fw(filename, fw_path, fw_header_path, header_fw_size):
653653
# check if the patched firmware is equal to the new firmware
654654
if os.system(f"diff {path_patch_txt} patch_txt_new.tmp"):
655655
print("The bin patch is not correct")
656-
exit()
656+
exit(3)
657657
else:
658658
print("The bin patch is correct")
659659

@@ -665,13 +665,16 @@ def generate_hex_fw(filename, fw_path, fw_header_path, header_fw_size):
665665
# check if the patched firmware is equal to the new firmware
666666
if os.system(f"diff patched_fw.tmp {new_fw}"):
667667
print("The patch is not correct")
668+
exit(1)
668669
else:
669670
print("The patch is correct")
670671

671672
# remove temporary files
672673
for tmp in to_remove:
673674
os.remove(tmp)
674675

676+
exit(0)
677+
675678
# decode function
676679
elif sys.argv[1] == 'decode':
677680
# check the number of arguments
@@ -708,7 +711,7 @@ def generate_hex_fw(filename, fw_path, fw_header_path, header_fw_size):
708711
print("Error during parsing arguments")
709712

710713
# apply the patch
711-
os.system(f"{path_patch_exec} {old_fw} {p} {new_fw} {read_buffer} {patch_buffer} {verbose}")
714+
exit(os.system(f"{path_patch_exec} {old_fw} {p} {new_fw} {read_buffer} {patch_buffer} {verbose}"))
712715

713716
# help function
714717
elif sys.argv[1] == 'help':

test/plot.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import matplotlib.pyplot as plt
2+
import numpy as np
3+
from math import ceil
4+
import os
5+
6+
from test import extract_last_decimal
7+
8+
for d in os.listdir():
9+
if d.startswith('f'):
10+
r = {}
11+
12+
fw_size = np.array([])
13+
patch_size = np.array([])
14+
n_frag_patch = np.array([])
15+
n_frag_fw = np.array([])
16+
ovh_nbd = np.array([])
17+
ovh_nbc = np.array([])
18+
ovh_nba = np.array([])
19+
ovh_tot = np.array([])
20+
n_nba = np.array([])
21+
22+
if os.path.exists(d + '/testout'):
23+
for report in os.listdir(d + '/testout'):
24+
if report.startswith('report'):
25+
# extract version
26+
version = extract_last_decimal(report)
27+
# add to dictionary
28+
r[version] = report
29+
30+
# check if there are report in the folder
31+
if r:
32+
fw_versions = sorted(r.keys())
33+
for v in fw_versions:
34+
with open(d + '/testout/' + r[v], 'r') as f:
35+
f.readline()
36+
fields = f.readline().split(',')
37+
38+
fw_size = np.append(fw_size, int(fields[0]))
39+
patch_size = np.append(patch_size, int(fields[1]))
40+
n_frag_patch = np.append(n_frag_patch, ceil(int(fields[1])/112))
41+
n_frag_fw = np.append(n_frag_fw, ceil(int(fields[0])/112))
42+
n_nba = np.append(n_nba, int(fields[4]))
43+
ovh_nbd = np.append(ovh_nbd, float(fields[5]))
44+
ovh_nbc = np.append(ovh_nbc, float(fields[6]))
45+
ovh_nba = np.append(ovh_nba, float(fields[7]))
46+
ovh_tot = np.append(ovh_tot, float(fields[8]))
47+
48+
# fig, axs = plt.subplots(2, 2, figsize=(15, 10))
49+
fig, axs = plt.subplots(2, 2)
50+
fig.suptitle(f'Statistics folder: {d}')
51+
52+
axs[0, 0].set_title('Compression')
53+
axs[0, 0].plot(fw_versions, patch_size / fw_size * 100)
54+
axs[0, 0].set_xlabel('FW version')
55+
axs[0, 0].set_ylabel('Patch compression [%]')
56+
axs[0, 0].grid()
57+
58+
axs[0, 1].set_title('New Bytes')
59+
axs[0, 1].plot(fw_versions, np.ceil(n_nba / 1024))
60+
axs[0, 1].set_xlabel('FW version')
61+
axs[0, 1].set_ylabel('kB')
62+
axs[0, 1].grid()
63+
64+
axs[1, 0].set_title('Overhead')
65+
axs[1, 0].plot(fw_versions, ovh_nbd, fw_versions, ovh_nbc, fw_versions, ovh_nba, fw_versions, ovh_tot)
66+
axs[1, 0].set_xlabel('FW version')
67+
axs[1, 0].set_ylabel('Overhead respect new bytes [%]')
68+
axs[1, 0].legend(['nbd', 'nbc', 'nba', 'total'])
69+
axs[1, 0].grid()
70+
71+
width = 0.3 # the width of the bars
72+
species = np.arange(len(fw_versions))
73+
74+
p1 = axs[1, 1].bar(species - width / 2, n_frag_fw, width, label='FW')
75+
axs[1, 1].bar_label(p1, label_type='edge')
76+
p2 = axs[1, 1].bar(species + width / 2, n_frag_patch, width, label='Patch')
77+
axs[1, 1].bar_label(p2, label_type='edge')
78+
79+
axs[1, 1].set_title('Number of fragment comparison')
80+
axs[1, 1].set_xticks(species)
81+
axs[1, 1].set_xticklabels(fw_versions)
82+
axs[1, 1].legend()
83+
84+
plt.tight_layout()
85+
plt.show()
86+
87+
exit()

test/test.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import os
2+
import subprocess
3+
import re
4+
import sys
5+
6+
def extract_last_decimal(s):
7+
# find all numbers in the string
8+
numbers = re.findall(r'\d+', s)
9+
# restur last number if exists
10+
return numbers[-1]if numbers else None
11+
12+
def test_bpatch():
13+
error_count = 0
14+
15+
for d in os.listdir():
16+
if d.startswith('f'):
17+
print(f'### Start test folder {d} ###')
18+
# create output directory if not exists
19+
if not os.path.exists(d + '/testout'):
20+
os.makedirs(d + '/testout')
21+
# create firmware dict with fw name and version
22+
f = {}
23+
for el in os.listdir(d):
24+
# check if the file is a binary file
25+
if el.endswith('.bin'):
26+
version = extract_last_decimal(el)
27+
# check if the version is not None and not in the dict
28+
if version is None:
29+
print(f'Error: cannot find version in {el}', file=sys.stderr)
30+
exit(-1)
31+
if version in f:
32+
print(f'Error: duplicate version {version} in {el}', file=sys.stderr)
33+
exit(-1)
34+
# add fw in dict
35+
f[version] = el
36+
37+
for version in sorted(f.keys())[:-1]:
38+
print(f'Start test bpatch for {d}/{f[version]} and {d}/{f[str(int(version) + 1)]}')
39+
# run bpatch
40+
if os.system(f'python3 ../bpatch.py encode {d}/{f[version]} {d}/{f[str(int(version) + 1)]} {d}/testout/patch_{int(version) + 1}.bin -v -R {d}/testout/report_{int(version) + 1}.csv> /dev/null') != 0:
41+
print(f'Error while running bpatch for {d}/{f[version]} and {d}/{f[str(int(version) + 1)]}', file=sys.stderr)
42+
error_count += 1
43+
else:
44+
print('Test OK')
45+
46+
print(f'### End test folder {d} ###\n\n')
47+
48+
return error_count
49+
50+
51+
if __name__ == '__main__':
52+
exit(test_bpatch())

0 commit comments

Comments
 (0)