fix usage info in run_benchmark
[python-delta-tar] / testing / run_benchmark.py
CommitLineData
3b8cae5a
ERE
1#!/usr/bin/env python3
2
3# Copyright (C) 2014 Intra2net AG
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as published
7# by the Free Software Foundation; either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see
17# <http://www.gnu.org/licenses/lgpl-3.0.html>
18
19# Authors: Victor Ramirez de la Corte <victor@wadobo.com>
20# Eduardo Robles Elvira <edulix@wadobo.com>
21
22import argparse
23import os
24import zlib
25import fnmatch
26import cProfile
27import io
28import pstats
29
30
08bb4b4a 31def main(args = None):
3b8cae5a
ERE
32 '''
33 Main function, parses the command line arguments and launches the appropiate
34 benchmark test.
35 '''
36 parser = argparse.ArgumentParser(description='Profiling test options. ')
904d3019
ERE
37 parser.add_argument('-t', '--test',
38 choices=['delta-tarfile', 'tarfile', 'zlib',
39 'zlib-blocks'],
3b8cae5a
ERE
40 help='Select option for testing. ')
41 parser.add_argument('-l', '--compression-level', type=int, default=9,
42 choices=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
43 help='Select level of compression for zlib. ')
44 parser.add_argument('-p', '--path',
45 help='path to the file/dir to compress.')
46 parser.add_argument('-P', '--profile', action='store_true',
47 help='Enable profile')
48 parser.add_argument('-m', '--tarmode', default="w:gz",
5cd23642 49 help='Specify tarfile mode [w:gz]')
904d3019
ERE
50 parser.add_argument('-st', '--strategy', default='default',
51 choices=['default', 'filtered', 'huffman_only'],
52 help='Select the deflate strategy in zlib related '
53 'tests.')
3b8cae5a
ERE
54 parser.add_argument(
55 '-s', '--sort',
56 help='Sort output profile',
57 choices=[ 'calls', 'cumulative', 'cumtime', 'file', 'path', 'module',
58 'ncalls', 'pcalls', 'line', 'name', 'nfl', 'stdname', 'time',
59 'tottime'],
60 default="cumulative")
61
08bb4b4a
ERE
62 if not args:
63 pargs = parser.parse_args()
64 else:
65 pargs = parser.parse_args(args)
66
3b8cae5a
ERE
67 compression_level = pargs.compression_level
68 path = pargs.path
69
70 # start profiling
71 if pargs.profile:
72 pr = cProfile.Profile()
73 pr.enable()
74
75 if pargs.test in ['delta-tarfile', 'tarfile']:
76 test_tarfile(pargs.test, compression_level, path, pargs.tarmode)
904d3019
ERE
77 elif pargs.test == 'zlib':
78 test_zlib(compression_level, path, pargs.strategy)
79 elif pargs.test == 'zlib-blocks':
80 test_zlib_blocks(compression_level, path, pargs.strategy)
3b8cae5a
ERE
81 else:
82 parser.print_help()
83
84 # end profiling
85 if pargs.profile:
86 pr.disable()
87 print_profile(pr, pargs.sort)
88
89def test_tarfile(res, compression_level=9, path='source_dir', tarmode="w:gz"):
90 '''
91 Test that creates a tarfile called test_tarfile.tar.gz
92 '''
93 if res == 'delta-tarfile':
94 deltatar = os.path.abspath("../deltatar")
95 import sys
96 sys.path.append("..")
97 from deltatar import tarfile as TarFile
98 elif res == 'tarfile':
99 import tarfile as TarFile
100
101 print("creating a tarfile with mode = '%s'" % tarmode)
102 with open('test_tarfile.tar.gz', 'wb') as fo:
103 tar = TarFile.open(mode=tarmode, fileobj=fo,
104 compresslevel=compression_level)
105 tar.add(path)
106
904d3019
ERE
107def test_zlib(compression_level=9, path='source_dir', strategy='default',
108 BUFSIZE = 16 * 1024):
109 '''
110 Test that compresses a directory with zlib
111 '''
112 if strategy == 'default':
113 strategy = zlib.Z_DEFAULT_STRATEGY
114 elif strategy == 'filtered':
115 strategy = zlib.Z_FILTERED
116 else:
117 strategy = zlib.Z_HUFFMAN_ONLY
118
119 c = zlib.compressobj(compression_level,
120 zlib.DEFLATED,
121 -zlib.MAX_WBITS,
122 zlib.DEF_MEM_LEVEL,
123 strategy)
124
125 def add(path):
126 l = 0
127 l_orig = 0
128 if os.path.isdir(path):
129 for f in os.listdir(path):
130 l2, l_orig2 = add(os.path.join(path, f))
131 l += l2
132 l_orig += l_orig2
133 elif os.path.isfile(path):
134 with open(path, 'rb') as fo:
135 while True:
136 buf = fo.read(BUFSIZE)
137 l_orig += len(buf)
138 if len(buf) == 0:
139 return l, l_orig
140 buf = c.compress(buf)
141 if buf is not None:
142 l += len(buf)
143 return l, l_orig
144
145 l, l_orig = add(path)
146 l += len(c.flush())
147 print("total size: %d MiB compressed, %d MiB uncompressed" % (
148 (l / (1024 ** 2)),
149 (l_orig / (1024 ** 2))))
150
151
152def test_zlib_blocks(compression_level=9, path='source_dir', strategy='default',
153 BUFSIZE = 16 * 1024):
154 '''
155 Test that compresses a directory with zlib
156 '''
157 if strategy == 'default':
158 strategy = zlib.Z_DEFAULT_STRATEGY
159 elif strategy == 'filtered':
160 strategy = zlib.Z_FILTERED
161 else:
162 strategy = zlib.Z_HUFFMAN_ONLY
163
164 def add(path):
165 l = 0
166 l_orig = 0
167 if os.path.isdir(path):
168 for f in os.listdir(path):
169 l2, l_orig2 = add(os.path.join(path, f))
170 l += l2
171 l_orig += l_orig2
172 elif os.path.isfile(path):
173 c = zlib.compressobj(compression_level,
174 zlib.DEFLATED,
175 -zlib.MAX_WBITS,
176 zlib.DEF_MEM_LEVEL,
177 strategy)
178 with open(path, 'rb') as fo:
179 while True:
180 buf = fo.read(BUFSIZE)
181 l_orig += len(buf)
182 if len(buf) == 0:
183 l += len(c.flush())
184 return l, l_orig
185 buf = c.compress(buf)
186 if buf is not None:
187 l += len(buf)
188 return l, l_orig
189
190 l, l_orig = add(path)
191 print("total size: %d MiB compressed, %d MiB uncompressed" % (
192 (l / (1024 ** 2)),
193 (l_orig / (1024 ** 2))))
194
3b8cae5a
ERE
195def print_profile(pr, sort):
196 s = io.StringIO()
197 if not sort:
198 sort = 'cumulative'
199 ps = pstats.Stats(pr, stream=s).sort_stats(sort)
200 ps.print_stats(20)
201 print(s.getvalue())
202
203
204if __name__ == '__main__':
205 main()