Browse code

ctest: Support Python 3.5

Python 3.6 is not available on Debian 9 and other older LTS releases.
This patch removes use of Python f-strings which were introduced in
Python 3.6 so as to support Python 3.5.

TODO: Revert this commit when Debian 9 dies or gets f-string support
(whichver comes first).

Micah Snyder authored on 2021/01/21 00:27:04
Showing 7 changed files
... ...
@@ -14,23 +14,23 @@ def main():
14 14
 
15 15
     split_dir = Path(args.split_dir)
16 16
     if not split_dir.exists():
17
-        print(f"Error: Split directory does not exist: {args.split_dir}")
17
+        print("Error: Split directory does not exist: {}".format(args.split_dir))
18 18
 
19
-    match_pattern = Path(split_dir, f"split.{args.test_file}a*")
19
+    match_pattern = Path(split_dir, "split.{}a*".format(args.test_file))
20 20
 
21 21
     input_files = [
22
-        x for x in split_dir.iterdir() if (x.is_file() and x.match(f"{match_pattern}"))
22
+        x for x in split_dir.iterdir() if (x.is_file() and x.match("{}".format(match_pattern)))
23 23
     ]
24 24
 
25 25
     if len(input_files) == 0:
26
-        print(f"Error: No splits matching '{args.test_file}' in: {args.split_dir}")
26
+        print("Error: No splits matching '{}' in: {}".format(args.test_file, args.split_dir))
27 27
         exit(1)
28 28
 
29 29
     test_file_path = Path(args.build_dir, args.test_file)
30 30
     try:
31 31
         test_file_path.touch(0o666, exist_ok=True)
32 32
     except FileNotFoundError:
33
-        print(f"Failed to create file: {test_file_path}")
33
+        print("Failed to create file: {}".format(test_file_path))
34 34
         exit(1)
35 35
 
36 36
     input_files.sort()
... ...
@@ -40,7 +40,7 @@ def main():
40 40
 
41 41
     test_file_path.write_bytes(file_data)
42 42
 
43
-    print(f"Assembled: '{test_file_path}'")
43
+    print("Assembled: '{}'".format(test_file_path))
44 44
 
45 45
 
46 46
 if __name__ == "__main__":
... ...
@@ -67,10 +67,10 @@ class TC(testcase.TestCase):
67 67
         #assert found_open_port == True
68 68
 
69 69
         # Prep a clamd.conf to use for most (if not all) of the tests.
70
-        config = f'''
70
+        config = '''
71 71
             Foreground yes
72
-            PidFile {TC.clamd_pid}
73
-            DatabaseDirectory {TC.path_db}
72
+            PidFile {pid}
73
+            DatabaseDirectory {dbdir}
74 74
             LogFileMaxSize 0
75 75
             LogTime yes
76 76
             #Debug yes
... ...
@@ -82,20 +82,20 @@ class TC(testcase.TestCase):
82 82
             CommandReadTimeout 1
83 83
             MaxQueue 800
84 84
             MaxConnectionQueueLength 1024
85
-            '''
85
+            '''.format(pid=TC.clamd_pid, dbdir=TC.path_db)
86 86
         if operating_system == 'windows':
87 87
             # Only have TCP socket option for Windows.
88
-            config += f'''
89
-                TCPSocket {TC.clamd_port_num}
88
+            config += '''
89
+                TCPSocket {socket}
90 90
                 TCPAddr 127.0.0.1
91
-                '''
91
+                '''.format(socket=TC.clamd_port_num)
92 92
         else:
93 93
             # Use LocalSocket for Posix, because that's what check_clamd expects.
94
-            config += f'''
95
-                LocalSocket {TC.clamd_socket}
96
-                TCPSocket {TC.clamd_port_num}
94
+            config += '''
95
+                LocalSocket {localsocket}
96
+                TCPSocket {tcpsocket}
97 97
                 TCPAddr 127.0.0.1
98
-                '''
98
+                '''.format(localsocket=TC.clamd_socket, tcpsocket=TC.clamd_port_num)
99 99
 
100 100
         TC.clamd_config = TC.path_tmp / 'clamd-test.conf'
101 101
         TC.clamd_config.write_text(config)
... ...
@@ -124,7 +124,7 @@ class TC(testcase.TestCase):
124 124
                 self.proc.wait(timeout=120)
125 125
                 self.proc.stdin.close()
126 126
             except OSError as exc:
127
-                self.log.warning(f'Unexpected exception {exc}')
127
+                self.log.warning('Unexpected exception {}'.format(exc))
128 128
                 pass  # ignore
129 129
             self.proc = None
130 130
         try:
... ...
@@ -142,8 +142,10 @@ class TC(testcase.TestCase):
142 142
         '''
143 143
         Start clamd
144 144
         '''
145
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamd} --config-file={TC.clamd_config}'
146
-        self.log.info(f'Starting clamd: {command}')
145
+        command = '{valgrind} {valgrind_args} {clamd} --config-file={clamd_config}'.format(
146
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamd=TC.clamd, clamd_config=TC.clamd_config
147
+        )
148
+        self.log.info('Starting clamd: {}'.format(command))
147 149
         self.proc = subprocess.Popen(
148 150
             command.strip().split(' '),
149 151
             stdin=subprocess.PIPE,
... ...
@@ -163,7 +165,8 @@ class TC(testcase.TestCase):
163 163
         The first scan uses ping & wait to give clamd time to start.
164 164
         '''
165 165
         # default (filepath) mode
166
-        output = self.execute_command(f'{TC.clamdscan} --ping 5 --wait -c {TC.clamd_config} {scan_args}')
166
+        output = self.execute_command('{clamdscan} --ping 5 --wait -c {clamd_config} {scan_args}'.format(
167
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config, scan_args=scan_args))
167 168
         assert output.ec == expected_ec
168 169
         if expected_out != [] or unexpected_out != []:
169 170
             self.verify_output(output.out, expected=expected_out, unexpected=unexpected_out)
... ...
@@ -171,7 +174,8 @@ class TC(testcase.TestCase):
171 171
             self.verify_output(output.err, expected=expected_err, unexpected=unexpected_err)
172 172
 
173 173
         # multi mode
174
-        output = self.execute_command(f'{TC.clamdscan} -c {TC.clamd_config} -m {scan_args}')
174
+        output = self.execute_command('{clamdscan} -c {clamd_config} -m {scan_args}'.format(
175
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config, scan_args=scan_args))
175 176
         assert output.ec == expected_ec
176 177
         if expected_out != [] or unexpected_out != []:
177 178
             self.verify_output(output.out, expected=expected_out, unexpected=unexpected_out)
... ...
@@ -180,7 +184,8 @@ class TC(testcase.TestCase):
180 180
 
181 181
         if TC.has_fdpass_support:
182 182
             # fdpass
183
-            output = self.execute_command(f'{TC.clamdscan} -c {TC.clamd_config} --fdpass {scan_args}')
183
+            output = self.execute_command('{clamdscan} -c {clamd_config} --fdpass {scan_args}'.format(
184
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config, scan_args=scan_args))
184 185
             assert output.ec == expected_ec
185 186
             if expected_out != [] or unexpected_out != []:
186 187
                 self.verify_output(output.out, expected=expected_out, unexpected=unexpected_out)
... ...
@@ -188,7 +193,8 @@ class TC(testcase.TestCase):
188 188
                 self.verify_output(output.err, expected=expected_err, unexpected=unexpected_err)
189 189
 
190 190
             # fdpass multi mode
191
-            output = self.execute_command(f'{TC.clamdscan} -c {TC.clamd_config} --fdpass -m {scan_args}')
191
+            output = self.execute_command('{clamdscan} -c {clamd_config} --fdpass -m {scan_args}'.format(
192
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config, scan_args=scan_args))
192 193
             assert output.ec == expected_ec
193 194
             if expected_out != [] or unexpected_out != []:
194 195
                 self.verify_output(output.out, expected=expected_out, unexpected=unexpected_out)
... ...
@@ -196,7 +202,8 @@ class TC(testcase.TestCase):
196 196
                 self.verify_output(output.err, expected=expected_err, unexpected=unexpected_err)
197 197
 
198 198
         # stream
199
-        output = self.execute_command(f'{TC.clamdscan} -c {TC.clamd_config} --stream {scan_args}')
199
+        output = self.execute_command('{clamdscan} -c {clamd_config} --stream {scan_args}'.format(
200
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config, scan_args=scan_args))
200 201
         assert output.ec == expected_ec
201 202
         if expected_out != [] or unexpected_out != []:
202 203
             self.verify_output(output.out, expected=expected_out, unexpected=unexpected_out)
... ...
@@ -204,7 +211,8 @@ class TC(testcase.TestCase):
204 204
             self.verify_output(output.err, expected=expected_err, unexpected=unexpected_err)
205 205
 
206 206
         # stream multi mode
207
-        output = self.execute_command(f'{TC.clamdscan} -c {TC.clamd_config} --stream -m {scan_args}')
207
+        output = self.execute_command('{clamdscan} -c {clamd_config} --stream -m {scan_args}'.format(
208
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config, scan_args=scan_args))
208 209
         assert output.ec == expected_ec
209 210
         if expected_out != [] or unexpected_out != []:
210 211
             self.verify_output(output.out, expected=expected_out, unexpected=unexpected_out)
... ...
@@ -223,7 +231,8 @@ class TC(testcase.TestCase):
223 223
         The first scan uses ping & wait to give clamd time to start.
224 224
         '''
225 225
         # default mode
226
-        output = self.execute_command(f'{TC.clamdscan} --ping 5 --wait -c {TC.clamd_config} {scan_args}')
226
+        output = self.execute_command('{clamdscan} --ping 5 --wait -c {clamd_config} {scan_args}'.format(
227
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config, scan_args=scan_args))
227 228
         assert output.ec == expected_ec
228 229
         if expected_out != [] or unexpected_out != []:
229 230
             self.verify_output(output.out, expected=expected_out, unexpected=unexpected_out)
... ...
@@ -231,7 +240,8 @@ class TC(testcase.TestCase):
231 231
             self.verify_output(output.err, expected=expected_err, unexpected=unexpected_err)
232 232
 
233 233
         # multi mode
234
-        output = self.execute_command(f'{TC.clamdscan} -c {TC.clamd_config} -m {scan_args}')
234
+        output = self.execute_command('{clamdscan} -c {clamd_config} -m {scan_args}'.format(
235
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config, scan_args=scan_args))
235 236
         assert output.ec == expected_ec
236 237
         if expected_out != [] or unexpected_out != []:
237 238
             self.verify_output(output.out, expected=expected_out, unexpected=unexpected_out)
... ...
@@ -250,7 +260,8 @@ class TC(testcase.TestCase):
250 250
         Use ping & wait to give clamd time to start.
251 251
         '''
252 252
         # fdpass
253
-        output = self.execute_command(f'{TC.clamdscan} --ping 5 --wait -c {TC.clamd_config} --fdpass {scan_args}')
253
+        output = self.execute_command('{clamdscan} --ping 5 --wait -c {clamd_config} --fdpass {scan_args}'.format(
254
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config, scan_args=scan_args))
254 255
         assert output.ec == expected_ec
255 256
         if expected_out != [] or unexpected_out != []:
256 257
             self.verify_output(output.out, expected=expected_out, unexpected=unexpected_out)
... ...
@@ -263,13 +274,14 @@ class TC(testcase.TestCase):
263 263
         '''
264 264
         self.step_name('clamd version test')
265 265
 
266
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamd} --config-file={TC.clamd_config} -V'
266
+        command = '{valgrind} {valgrind_args} {clamd} --config-file={clamd_config} -V'.format(
267
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamd=TC.clamd, clamd_config=TC.clamd_config)
267 268
         output = self.execute_command(command)
268 269
 
269 270
         assert output.ec == 0  # success
270 271
 
271 272
         expected_results = [
272
-            f'ClamAV {TC.version}',
273
+            'ClamAV {}'.format(TC.version),
273 274
         ]
274 275
         self.verify_output(output.out, expected=expected_results)
275 276
 
... ...
@@ -284,7 +296,8 @@ class TC(testcase.TestCase):
284 284
         poll = self.proc.poll()
285 285
         assert poll == None  # subprocess is alive if poll() returns None
286 286
 
287
-        output = self.execute_command(f'{TC.clamdscan} -p 5 -c {TC.clamd_config}')
287
+        output = self.execute_command('{clamdscan} -p 5 -c {clamd_config}'.format(
288
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config))
288 289
 
289 290
         assert output.ec == 0  # success
290 291
         self.verify_output(output.out, expected=['PONG'])
... ...
@@ -308,15 +321,17 @@ class TC(testcase.TestCase):
308 308
         # First we'll ping-pong to make sure clamd is up
309 309
         # If clamd isn't up before the version test, clamdscan will return it's
310 310
         # own version, which isn't really the point of the test.
311
-        output = self.execute_command(f'{TC.clamdscan} --ping 5 -c {TC.clamd_config}')
311
+        output = self.execute_command('{clamdscan} --ping 5 -c {clamd_config}'.format(
312
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config))
312 313
         assert output.ec == 0  # success
313 314
         self.verify_output(output.out, expected=['PONG'])
314 315
 
315 316
         # Ok now it's up, let's check clamd's version via clamdscan.
316
-        output = self.execute_command(f'{TC.clamdscan} --version -c {TC.clamd_config}')
317
+        output = self.execute_command('{clamdscan} --version -c {clamd_config}'.format(
318
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config))
317 319
         assert output.ec == 0  # success
318 320
         self.verify_output(output.out,
319
-            expected=[f'ClamAV {TC.version}'], unexpected=['Could not connect to clamd'])
321
+            expected=['ClamAV {}'.format(TC.version)], unexpected=['Could not connect to clamd'])
320 322
 
321 323
     def test_clamd_03_reload(self):
322 324
         '''
... ...
@@ -332,19 +347,20 @@ class TC(testcase.TestCase):
332 332
 
333 333
         (TC.path_tmp / 'reload-testfile').write_bytes(b'ClamAV-RELOAD-Test')
334 334
 
335
-        self.run_clamdscan(f'{TC.path_tmp / "reload-testfile"}',
335
+        self.run_clamdscan('{}'.format(TC.path_tmp / "reload-testfile"),
336 336
             expected_ec=0, expected_out=['reload-testfile: OK', 'Infected files: 0'])
337 337
 
338 338
         (TC.path_db / 'reload-test.ndb').write_text('ClamAV-RELOAD-TestFile:0:0:436c616d41562d52454c4f41442d54657374')
339 339
 
340
-        output = self.execute_command(f'{TC.clamdscan} --reload -c {TC.clamd_config}')
340
+        output = self.execute_command('{clamdscan} --reload -c {clamd_config}'.format(
341
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config))
341 342
         assert output.ec == 0  # success
342 343
 
343 344
         time.sleep(2) # give clamd a moment to reload before trying again
344 345
                       # with multi-threaded reloading will clamd would happily
345 346
                       # re-scan with the old engine while it reloads.
346 347
 
347
-        self.run_clamdscan(f'{TC.path_tmp / "reload-testfile"}',
348
+        self.run_clamdscan('{}'.format(TC.path_tmp / "reload-testfile"),
348 349
             expected_ec=1, expected_out=['ClamAV-RELOAD-TestFile.UNOFFICIAL FOUND', 'Infected files: 1'])
349 350
 
350 351
     def test_clamd_04_all_testfiles(self):
... ...
@@ -359,10 +375,10 @@ class TC(testcase.TestCase):
359 359
         assert poll == None  # subprocess is alive if poll() returns None
360 360
 
361 361
         testfiles = ' '.join([str(testpath) for testpath in TC.testpaths])
362
-        expected_results = [f'{testpath.name}: ClamAV-Test-File.UNOFFICIAL FOUND' for testpath in TC.testpaths]
363
-        expected_results.append(f'Infected files: {len(TC.testpaths)}')
362
+        expected_results = ['{}: ClamAV-Test-File.UNOFFICIAL FOUND'.format(testpath.name) for testpath in TC.testpaths]
363
+        expected_results.append('Infected files: {}'.format(len(TC.testpaths)))
364 364
 
365
-        self.run_clamdscan(f'{testfiles}',
365
+        self.run_clamdscan(testfiles,
366 366
             expected_ec=1, expected_out=expected_results)
367 367
 
368 368
     def test_clamd_05_check_clamd(self):
... ...
@@ -378,14 +394,15 @@ class TC(testcase.TestCase):
378 378
         assert poll == None  # subprocess is alive if poll() returns None
379 379
 
380 380
         # Let's first use the ping-pong test to make sure clamd is listening.
381
-        output = self.execute_command(f'{TC.clamdscan} -p 5 -c {TC.clamd_config}')
381
+        output = self.execute_command('{clamdscan} -p 5 -c {clamd_config}'.format(
382
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config))
382 383
         assert output.ec == 0  # success
383 384
         self.verify_output(output.out, expected=['PONG'])
384 385
 
385 386
         # Ok now run check_clamd to have fun with clamd's API
386
-        output = self.execute_command(f'{TC.check_clamd}')
387
-        self.log.info(f'check_clamd stdout: \n{output.out}')
388
-        self.log.info(f'check_clamd stderr: \n{output.err}')
387
+        output = self.execute_command('{}'.format(TC.check_clamd))
388
+        self.log.info('check_clamd stdout: \n{}'.format(output.out))
389
+        self.log.info('check_clamd stderr: \n{}'.format(output.err))
389 390
         assert output.ec == 0  # success
390 391
 
391 392
         expected_results = [
... ...
@@ -394,7 +411,8 @@ class TC(testcase.TestCase):
394 394
         self.verify_output(output.out, expected=expected_results)
395 395
 
396 396
         # Let's do another ping-pong test to see if `check_clamd` killed clamd (Mu-ha-ha).
397
-        output = self.execute_command(f'{TC.clamdscan} -p 5 -c {TC.clamd_config}')
397
+        output = self.execute_command('{clamdscan} -p 5 -c {clamd_config}'.format(
398
+            clamdscan=TC.clamdscan, clamd_config=TC.clamd_config))
398 399
         assert output.ec == 0  # success
399 400
         self.verify_output(output.out, expected=['PONG'])
400 401
 
... ...
@@ -414,7 +432,7 @@ class TC(testcase.TestCase):
414 414
         poll = self.proc.poll()
415 415
         assert poll == None  # subprocess is alive if poll() returns None
416 416
 
417
-        self.run_clamdscan(f'{TC.path_build / "unit_tests" / "clam-phish-exe"}',
417
+        self.run_clamdscan('{}'.format(TC.path_build / "unit_tests" / "clam-phish-exe"),
418 418
             expected_ec=1, expected_out=['ClamAV-Test-File'])
419 419
 
420 420
     def test_clamd_07_HeuristicScanPrecedence_on(self):
... ...
@@ -436,7 +454,7 @@ class TC(testcase.TestCase):
436 436
         poll = self.proc.poll()
437 437
         assert poll == None  # subprocess is alive if poll() returns None
438 438
 
439
-        self.run_clamdscan(f'{TC.path_build / "unit_tests" / "clam-phish-exe"}',
439
+        self.run_clamdscan('{}'.format(TC.path_build / "unit_tests" / "clam-phish-exe"),
440 440
             expected_ec=1, expected_out=['Heuristics.Phishing.Email.SpoofedDomain'])
441 441
 
442 442
     @unittest.skipIf(operating_system == 'windows', 'This test uses a shell script to test virus-action. TODO: add Windows support to this test.')
... ...
@@ -447,17 +465,19 @@ class TC(testcase.TestCase):
447 447
         self.step_name('Testing clamd + clamdscan w/ VirusEvent')
448 448
 
449 449
         with TC.clamd_config.open('a') as config:
450
-            config.write(f'VirusEvent {TC.path_source / "unit_tests" / "virusaction-test.sh"} {TC.path_tmp} "Virus found: %v"\n')
450
+            config.write('VirusEvent {} {} "Virus found: %v"\n'.format(
451
+                TC.path_source / "unit_tests" / "virusaction-test.sh",
452
+                TC.path_tmp))
451 453
 
452 454
         self.start_clamd()
453 455
 
454 456
         poll = self.proc.poll()
455 457
         assert poll == None  # subprocess is alive if poll() returns None
456 458
 
457
-        self.run_clamdscan_file_only(f'{TC.path_build / "test" / "clam.exe"}',
459
+        self.run_clamdscan_file_only('{}'.format(TC.path_build / "test" / "clam.exe"),
458 460
             expected_ec=1)#, expected_out=['Virus found: ClamAV-Test-File.UNOFFICIAL'])
459 461
 
460
-        self.log.info(f'verifying log output from virusaction-test.sh: {str(TC.path_tmp / "test-clamd.log")}')
462
+        self.log.info('verifying log output from virusaction-test.sh: {}'.format(str(TC.path_tmp / "test-clamd.log")))
461 463
         self.verify_log(str(TC.path_tmp / 'test-clamd.log'),
462 464
             expected=['Virus found: ClamAV-Test-File.UNOFFICIAL'],
463 465
             unexpected=['VirusEvent incorrect', 'VirusName incorrect'])
... ...
@@ -72,13 +72,15 @@ class TC(testcase.TestCase):
72 72
     def test_clamscan_00_version(self):
73 73
         self.step_name('clamscan version test')
74 74
 
75
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamscan} -V'
75
+        command = '{valgrind} {valgrind_args} {clamscan} -V'.format(
76
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamscan=TC.clamscan
77
+        )
76 78
         output = self.execute_command(command)
77 79
 
78 80
         assert output.ec == 0  # success
79 81
 
80 82
         expected_results = [
81
-            f'ClamAV {TC.version}',
83
+            'ClamAV {}'.format(TC.version),
82 84
         ]
83 85
         self.verify_output(output.out, expected=expected_results)
84 86
 
... ...
@@ -86,28 +88,32 @@ class TC(testcase.TestCase):
86 86
         self.step_name('Test that clamscan alerts on all test files')
87 87
 
88 88
         testfiles = ' '.join([str(testpath) for testpath in TC.testpaths])
89
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamscan} -d {TC.path_db / "clamav.hdb"} {testfiles}'
89
+        command = '{valgrind} {valgrind_args} {clamscan} -d {path_db} {testfiles}'.format(
90
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamscan=TC.clamscan, path_db=TC.path_db / "clamav.hdb", testfiles=testfiles,
91
+        )
90 92
         output = self.execute_command(command)
91 93
 
92 94
         assert output.ec == 1  # virus found
93 95
 
94
-        expected_results = [f'{testpath.name}: ClamAV-Test-File.UNOFFICIAL FOUND' for testpath in TC.testpaths]
95
-        expected_results.append(f'Scanned files: {len(TC.testpaths)}')
96
-        expected_results.append(f'Infected files: {len(TC.testpaths)}')
96
+        expected_results = ['{}: ClamAV-Test-File.UNOFFICIAL FOUND'.format(testpath.name) for testpath in TC.testpaths]
97
+        expected_results.append('Scanned files: {}'.format(len(TC.testpaths)))
98
+        expected_results.append('Infected files: {}'.format(len(TC.testpaths)))
97 99
         self.verify_output(output.out, expected=expected_results)
98 100
 
99 101
     def test_clamscan_02_all_testfiles_ign2(self):
100 102
         self.step_name('Test that clamscan ignores ClamAV-Test-File alerts')
101 103
 
102 104
         testfiles = ' '.join([str(testpath) for testpath in TC.testpaths])
103
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamscan} -d {TC.path_db / "clamav.hdb"} -d {TC.path_db / "clamav.ign2"} {testfiles}'
105
+        command = '{valgrind} {valgrind_args} {clamscan} -d {path_db} -d {path_ign_db} {testfiles}'.format(
106
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamscan=TC.clamscan, path_db=TC.path_db / "clamav.hdb", path_ign_db=TC.path_db / "clamav.ign2", testfiles=testfiles,
107
+        )
104 108
         output = self.execute_command(command)
105 109
 
106 110
         assert output.ec == 1  # virus found
107 111
 
108
-        expected_results = [f'{testpath.name}: ClamAV-Test-File.UNOFFICIAL FOUND' for testpath in TC.testpaths]
109
-        expected_results.append(f'Scanned files: {len(TC.testpaths)}')
110
-        expected_results.append(f'Infected files: {len(TC.testpaths)}')
112
+        expected_results = ['{}: ClamAV-Test-File.UNOFFICIAL FOUND'.format(testpath.name) for testpath in TC.testpaths]
113
+        expected_results.append('Scanned files: {}'.format(len(TC.testpaths)))
114
+        expected_results.append('Infected files: {}'.format(len(TC.testpaths)))
111 115
         self.verify_output(output.out, expected=expected_results)
112 116
 
113 117
     def test_clamscan_03_phish_test_not_enabled(self):
... ...
@@ -116,7 +122,9 @@ class TC(testcase.TestCase):
116 116
         testpaths = list(TC.path_source.glob('unit_tests/input/phish-test-*'))
117 117
 
118 118
         testfiles = ' '.join([str(testpath) for testpath in testpaths])
119
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamscan} -d {TC.path_db / "phish.pdb"} {testfiles}'
119
+        command = '{valgrind} {valgrind_args} {clamscan} -d {path_db} {testfiles}'.format(
120
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamscan=TC.clamscan, path_db=TC.path_db / "phish.pdb", path_ign_db=TC.path_db / "clamav.ign2", testfiles=testfiles,
121
+        )
120 122
         output = self.execute_command(command)
121 123
 
122 124
         assert output.ec == 0  # virus NOT found
... ...
@@ -133,7 +141,9 @@ class TC(testcase.TestCase):
133 133
         testpaths = list(TC.path_source.glob('unit_tests/input/phish-test-*'))
134 134
 
135 135
         testfiles = ' '.join([str(testpath) for testpath in testpaths])
136
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamscan} -d {TC.path_db / "phish.pdb"} --alert-phishing-ssl --alert-phishing-cloak {testfiles}'
136
+        command = '{valgrind} {valgrind_args} {clamscan} -d {path_db} --alert-phishing-ssl --alert-phishing-cloak {testfiles}'.format(
137
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamscan=TC.clamscan, path_db=TC.path_db / "phish.pdb", testfiles=testfiles,
138
+        )
137 139
         output = self.execute_command(command)
138 140
 
139 141
         assert output.ec == 1  # virus found
... ...
@@ -150,13 +160,15 @@ class TC(testcase.TestCase):
150 150
         self.step_name('Test icon (.ldb + .idb) signatures')
151 151
 
152 152
         testfiles = ' '.join([str(testpath) for testpath in TC.testpaths])
153
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamscan} -d {TC.path_db / "icon.ldb"} -d {TC.path_db / "icon.idb"} {testfiles}'
153
+        command = '{valgrind} {valgrind_args} {clamscan} -d {path_ldb} -d {path_idb} {testfiles}'.format(
154
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamscan=TC.clamscan, path_ldb=TC.path_db / "icon.ldb", path_idb=TC.path_db / "icon.idb", testfiles=testfiles,
155
+        )
154 156
         output = self.execute_command(command)
155 157
 
156 158
         assert output.ec == 1  # virus found
157 159
 
158 160
         # Use check_fpu_endian to determine expected results
159
-        command = f'{TC.check_fpu_endian}'
161
+        command = '{}'.format(TC.check_fpu_endian)
160 162
         fpu_endian_output = self.execute_command(command)
161 163
 
162 164
         expected_results = [
... ...
@@ -168,14 +180,16 @@ class TC(testcase.TestCase):
168 168
         else:
169 169
             expected_results.append('clam.ea06.exe: ClamAV-Test-Icon-EA0X.UNOFFICIAL FOUND')
170 170
             expected_num_infected = 4
171
-        expected_results.append(f'Infected files: {expected_num_infected}')
171
+        expected_results.append('Infected files: {}'.format(expected_num_infected))
172 172
         self.verify_output(output.out, expected=expected_results)
173 173
 
174 174
     def test_clamscan_06_LDB_VI(self):
175 175
         self.step_name('Test LDB VI feature')
176 176
 
177 177
         testfiles = ' '.join([str(testpath) for testpath in TC.testpaths])
178
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamscan} -d {TC.path_db / "Clam-VI.ldb"} {testfiles}'
178
+        command = '{valgrind} {valgrind_args} {clamscan} -d {path_db} {testfiles}'.format(
179
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamscan=TC.clamscan, path_db=TC.path_db / "Clam-VI.ldb", testfiles=testfiles,
180
+        )
179 181
         output = self.execute_command(command)
180 182
 
181 183
         assert output.ec == 1  # virus found
... ...
@@ -191,7 +205,9 @@ class TC(testcase.TestCase):
191 191
         self.step_name('Test yara signature - detect TAR file magic at an offset')
192 192
 
193 193
         testfiles = ' '.join([str(testpath) for testpath in TC.testpaths])
194
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamscan} -d {TC.path_db / "yara-at-offset.yara"} {testfiles}'
194
+        command = '{valgrind} {valgrind_args} {clamscan} -d {path_db} {testfiles}'.format(
195
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamscan=TC.clamscan, path_db=TC.path_db / "yara-at-offset.yara", testfiles=testfiles,
196
+        )
195 197
         output = self.execute_command(command)
196 198
 
197 199
         assert output.ec == 1  # virus found
... ...
@@ -207,7 +223,9 @@ class TC(testcase.TestCase):
207 207
         self.step_name('Test yara signature - detect TAR file magic in a range')
208 208
 
209 209
         testfiles = ' '.join([str(testpath) for testpath in TC.testpaths])
210
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.clamscan} -d {TC.path_db / "yara-in-range.yara"} {testfiles}'
210
+        command = '{valgrind} {valgrind_args} {clamscan} -d {path_db} {testfiles}'.format(
211
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, clamscan=TC.clamscan, path_db=TC.path_db / "yara-in-range.yara", testfiles=testfiles,
212
+        )
211 213
         output = self.execute_command(command)
212 214
 
213 215
         assert output.ec == 1  # virus found
... ...
@@ -36,18 +36,22 @@ class TC(testcase.TestCase):
36 36
         TC.path_db = Path(TC.path_tmp, 'database')
37 37
         TC.freshclam_pid = Path(TC.path_tmp, 'freshclam-test.pid')
38 38
         TC.freshclam_config = Path(TC.path_tmp, 'freshclam-test.conf')
39
-        TC.freshclam_config.write_text(f'''
39
+        TC.freshclam_config.write_text('''
40 40
             DatabaseMirror 127.0.0.1
41
-            PidFile {TC.freshclam_pid}
41
+            PidFile {freshclam_pid}
42 42
             LogVerbose yes
43 43
             LogFileMaxSize 0
44 44
             LogTime yes
45
-            DatabaseDirectory {TC.path_db}
46
-            DatabaseCustomURL file://{TC.path_www / "clamav.hdb"}
45
+            DatabaseDirectory {path_db}
46
+            DatabaseCustomURL file://{file_db}
47 47
             ExcludeDatabase daily
48 48
             ExcludeDatabase main
49 49
             ExcludeDatabase bytecode
50
-        ''')
50
+        '''.format(
51
+            freshclam_pid=TC.freshclam_pid,
52
+            path_db=TC.path_db,
53
+            file_db=TC.path_www / "clamav.hdb",
54
+        ))
51 55
 
52 56
     @classmethod
53 57
     def tearDownClass(cls):
... ...
@@ -63,27 +67,31 @@ class TC(testcase.TestCase):
63 63
     def test_freshclam_00_version(self):
64 64
         self.step_name('freshclam version test')
65 65
 
66
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.freshclam} --config-file={TC.freshclam_config} -V'
66
+        command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} -V'.format(
67
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config
68
+        )
67 69
         output = self.execute_command(command)
68 70
 
69 71
         assert output.ec == 0  # success
70 72
 
71 73
         expected_results = [
72
-            f'ClamAV {TC.version}',
74
+            'ClamAV {}'.format(TC.version),
73 75
         ]
74 76
         self.verify_output(output.out, expected=expected_results)
75 77
 
76 78
     def test_freshclam_01_file_copy(self):
77 79
         self.step_name('Basic freshclam test using file:// to "download" clamav.hdb')
78 80
 
79
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.freshclam} --config-file={TC.freshclam_config}'
81
+        command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config}'.format(
82
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config
83
+        )
80 84
         output = self.execute_command(command)
81 85
 
82 86
         assert output.ec == 0  # success
83 87
 
84 88
         expected_results = [
85
-            f'Downloading clamav.hdb',
86
-            f'Database test passed.',
87
-            f'clamav.hdb updated',
89
+            'Downloading clamav.hdb',
90
+            'Database test passed.',
91
+            'clamav.hdb updated',
88 92
         ]
89 93
         self.verify_output(output.out, expected=expected_results)
... ...
@@ -39,7 +39,9 @@ class TC(testcase.TestCase):
39 39
         self.step_name('libclamav unit tests')
40 40
 
41 41
         # If no valgrind, valgrind nad valgrind args are empty strings
42
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.check_clamav}'
42
+        command = '{valgrind} {valgrind_args} {check_clamav}'.format(
43
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, check_clamav=TC.check_clamav
44
+        )
43 45
         output = self.execute_command(command)
44 46
 
45 47
         assert output.ec == 0  # success
... ...
@@ -36,18 +36,22 @@ class TC(testcase.TestCase):
36 36
         TC.path_db = TC.path_tmp / 'database'
37 37
         TC.sigtool_pid = TC.path_tmp / 'sigtool-test.pid'
38 38
         TC.sigtool_config = TC.path_tmp / 'sigtool-test.conf'
39
-        TC.sigtool_config.write_text(f'''
39
+        TC.sigtool_config.write_text('''
40 40
             DatabaseMirror 127.0.0.1
41
-            PidFile {TC.sigtool_pid}
41
+            PidFile {sigtool_pid}
42 42
             LogVerbose yes
43 43
             LogFileMaxSize 0
44 44
             LogTime yes
45
-            DatabaseDirectory {TC.path_db}
46
-            DatabaseCustomURL file://{TC.path_www}/clamav.hdb
45
+            DatabaseDirectory {path_db}
46
+            DatabaseCustomURL file://{path_www}/clamav.hdb
47 47
             ExcludeDatabase daily
48 48
             ExcludeDatabase main
49 49
             ExcludeDatabase bytecode
50
-        ''')
50
+        '''.format(
51
+            sigtool_pid=TC.sigtool_pid,
52
+            path_db=TC.path_db,
53
+            path_www=TC.path_www
54
+        ))
51 55
 
52 56
     @classmethod
53 57
     def tearDownClass(cls):
... ...
@@ -63,14 +67,15 @@ class TC(testcase.TestCase):
63 63
     def test_sigtool_00_version(self):
64 64
         self.step_name('sigtool version test')
65 65
 
66
-        self.log.warning(f'VG: {os.getenv("VG")}')
67
-        command = f'{TC.valgrind} {TC.valgrind_args} {TC.sigtool} -V'
66
+        self.log.warning('VG: {}'.format(os.getenv("VG")))
67
+        command = '{valgrind} {valgrind_args} {sigtool} -V'.format(
68
+            valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, sigtool=TC.sigtool
69
+        )
68 70
         output = self.execute_command(command)
69 71
 
70 72
         assert output.ec == 0  # success
71 73
 
72 74
         expected_results = [
73
-            f'ClamAV {TC.version}',
75
+            'ClamAV {}'.format(TC.version),
74 76
         ]
75 77
         self.verify_output(output.out, expected=expected_results)
76
-
... ...
@@ -117,10 +117,10 @@ class TestCase(unittest.TestCase):
117 117
         if os.getenv('VALGRIND') != None:
118 118
             cls.log_suffix = '.valgrind.log'
119 119
             cls.valgrind = Path(os.getenv("VALGRIND"))
120
-            cls.valgrind_args = f'-v --trace-children=yes --track-fds=yes --leak-check=full '         \
121
-                                f'--suppressions={cls.path_source / "unit_tests" / "valgrind.supp"} ' \
122
-                                f'--log-file={cls.path_tmp / "valgrind.log"} '                        \
123
-                                f'--error-exitcode=123'
120
+            cls.valgrind_args = '-v --trace-children=yes --track-fds=yes --leak-check=full '                  + \
121
+                                '--suppressions={} '.format(cls.path_source / "unit_tests" / "valgrind.supp") + \
122
+                                '--log-file={} '.format(cls.path_tmp / "valgrind.log")                        + \
123
+                                '--error-exitcode=123'
124 124
 
125 125
         # cls.log.info(f"{cls.__name__} Environment:")
126 126
         # cls.log.info(f"  version:           {cls.version}")
... ...
@@ -161,7 +161,7 @@ class TestCase(unittest.TestCase):
161 161
     def setUp(self):
162 162
         print("")
163 163
 
164
-        log_path = Path(self.path_build / 'unit_tests' / f'{self._testMethodName}{self.log_suffix}')
164
+        log_path = Path(self.path_build / 'unit_tests' / '{}{}'.format(self._testMethodName, self.log_suffix))
165 165
         try:
166 166
             log_path.unlink()
167 167
         except Exception:
... ...
@@ -263,10 +263,10 @@ class TestCase(unittest.TestCase):
263 263
             log_file = self.path_tmp / 'valgrind.log'
264 264
 
265 265
         if not log_file.exists():
266
-            raise AssertionError(f'{log_file} not found. Valgrind failed to run?')
266
+            raise AssertionError('{} not found. Valgrind failed to run?'.format(log_file))
267 267
 
268 268
         errors = False
269
-        self.log.info(f'Verifying {log_file}...')
269
+        self.log.info('Verifying {}...'.format(log_file))
270 270
         try:
271 271
             self.verify_log(
272 272
                 str(log_file),
... ...
@@ -276,9 +276,9 @@ class TestCase(unittest.TestCase):
276 276
             )
277 277
         except AssertionError:
278 278
             self.log.warning("*" * 69)
279
-            self.log.warning(f'Valgrind test failed!'.center(69, ' '))
280
-            self.log.warning(f'Please submit this log to https://bugzilla.clamav.net:'.center(69, ' '))
281
-            self.log.warning(f'{log_file}'.center(69, ' '))
279
+            self.log.warning('Valgrind test failed!'.center(69, ' '))
280
+            self.log.warning('Please submit this log to https://bugzilla.clamav.net:'.center(69, ' '))
281
+            self.log.warning(str(log_file).center(69, ' '))
282 282
             self.log.warning("*" * 69)
283 283
             errors = True
284 284
         finally:
... ...
@@ -616,9 +616,9 @@ class Executor(object):
616 616
                 # We will likely need these for testing and can propagate them
617 617
                 # manually, like so:
618 618
                 if "LD_LIBRARY_PATH" in sys_env:
619
-                    cmd = f"export LD_LIBRARY_PATH={sys_env['LD_LIBRARY_PATH']} && {cmd}"
619
+                    cmd = "export LD_LIBRARY_PATH={} && {}".format(sys_env['LD_LIBRARY_PATH'], cmd)
620 620
                 if "DYLD_LIBRARY_PATH" in sys_env:
621
-                    cmd = f"export DYLD_LIBRARY_PATH={sys_env['DYLD_LIBRARY_PATH']} && {cmd}"
621
+                    cmd = "export DYLD_LIBRARY_PATH={} && {}".format(sys_env['DYLD_LIBRARY_PATH'], cmd)
622 622
 
623 623
             self._logger.debug("Run command: %s" % (cmd,))
624 624
             self._process = subprocess.Popen(
... ...
@@ -929,4 +929,3 @@ class LogChecker:
929 929
             filename,
930 930
             found_items,
931 931
         )
932
-