Commit | Line | Data |
---|---|---|
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 | ||
22 | import argparse | |
23 | import os | |
24 | import zlib | |
25 | import fnmatch | |
26 | import cProfile | |
27 | import io | |
28 | import pstats | |
29 | ||
30 | ||
08bb4b4a | 31 | def 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 | ||
89 | def 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 |
107 | def 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 | ||
152 | def 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 |
195 | def 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 | ||
204 | if __name__ == '__main__': | |
205 | main() |