@@ -422,7 +422,7 @@ def test_combining_corrupt_data(self):
422
422
self .make_file (".coverage.foo" , """La la la, this isn't coverage data!""" )
423
423
cov = coverage .Coverage ()
424
424
warning_regex = (
425
- r"Couldn't use data file '.*\.coverage\.foo': file (is encrypted or )? is not a database"
425
+ r"Couldn't use data file '.*\.coverage\.foo': file is not a database"
426
426
)
427
427
with self .assert_warnings (cov , [warning_regex ]):
428
428
cov .combine ()
@@ -1234,3 +1234,189 @@ def test_combine_no_suffix_multiprocessing(self):
1234
1234
cov .save ()
1235
1235
self .assert_file_count (".coverage.*" , 0 )
1236
1236
self .assert_exists (".coverage" )
1237
+
1238
+
1239
+ class CombiningTest (CoverageTest ):
1240
+ """More tests of combining data."""
1241
+
1242
+ B_LINES = {"b_or_c.py" : [1 , 2 , 3 , 4 , 8 , 9 ]}
1243
+ C_LINES = {"b_or_c.py" : [1 , 2 , 3 , 6 , 7 , 8 , 9 ]}
1244
+
1245
+ def make_b_or_c_py (self ):
1246
+ """Create b_or_c.py, used in a few of these tests."""
1247
+ # "b_or_c.py b" will run 6 lines.
1248
+ # "b_or_c.py c" will run 7 lines.
1249
+ # Together, they run 8 lines.
1250
+ self .make_file ("b_or_c.py" , """\
1251
+ import sys
1252
+ a = 2
1253
+ if sys.argv[1] == 'b':
1254
+ b = 4
1255
+ else:
1256
+ c = 6
1257
+ c2 = 7
1258
+ d = 8
1259
+ print('done')
1260
+ """ )
1261
+
1262
+ def test_combine_parallel_data (self ):
1263
+ self .make_b_or_c_py ()
1264
+ self .make_data_file (".coverage.b" , lines = self .B_LINES )
1265
+ self .make_data_file (".coverage.c" , lines = self .C_LINES )
1266
+
1267
+ # Combine the parallel coverage data files into .coverage .
1268
+ cov = coverage .Coverage ()
1269
+ cov .combine (strict = True )
1270
+ self .assert_exists (".coverage" )
1271
+
1272
+ # After combining, there should be only the .coverage file.
1273
+ self .assert_file_count (".coverage.*" , 0 )
1274
+
1275
+ # Read the coverage file and see that b_or_c.py has all 8 lines
1276
+ # executed.
1277
+ data = coverage .CoverageData ()
1278
+ data .read ()
1279
+ assert line_counts (data )['b_or_c.py' ] == 8
1280
+
1281
+ # Running combine again should fail, because there are no parallel data
1282
+ # files to combine.
1283
+ cov = coverage .Coverage ()
1284
+ with pytest .raises (NoDataError , match = r"No data to combine" ):
1285
+ cov .combine (strict = True )
1286
+
1287
+ # And the originally combined data is still there.
1288
+ data = coverage .CoverageData ()
1289
+ data .read ()
1290
+ assert line_counts (data )['b_or_c.py' ] == 8
1291
+
1292
+ def test_combine_parallel_data_with_a_corrupt_file (self ):
1293
+ self .make_b_or_c_py ()
1294
+ self .make_data_file (".coverage.b" , lines = self .B_LINES )
1295
+ self .make_data_file (".coverage.c" , lines = self .C_LINES )
1296
+
1297
+ # Make a bogus data file.
1298
+ self .make_file (".coverage.bad" , "This isn't a coverage data file." )
1299
+
1300
+ # Combine the parallel coverage data files into .coverage .
1301
+ cov = coverage .Coverage ()
1302
+ with pytest .warns (Warning ) as warns :
1303
+ cov .combine (strict = True )
1304
+ assert_coverage_warnings (
1305
+ warns ,
1306
+ re .compile (
1307
+ r"Couldn't use data file '.*[/\\]\.coverage\.bad': file is not a database"
1308
+ ),
1309
+ )
1310
+
1311
+ # After combining, those two should be the only data files.
1312
+ self .assert_exists (".coverage" )
1313
+ self .assert_exists (".coverage.bad" )
1314
+ self .assert_file_count (".coverage.*" , 1 )
1315
+
1316
+ # Read the coverage file and see that b_or_c.py has all 8 lines
1317
+ # executed.
1318
+ data = coverage .CoverageData ()
1319
+ data .read ()
1320
+ assert line_counts (data )['b_or_c.py' ] == 8
1321
+
1322
+ def test_combine_no_usable_files (self ):
1323
+ # https://github.com/nedbat/coveragepy/issues/629
1324
+ self .make_b_or_c_py ()
1325
+ self .make_data_file (".coverage" , lines = self .B_LINES )
1326
+
1327
+ # Make bogus data files.
1328
+ self .make_file (".coverage.bad1" , "This isn't a coverage data file." )
1329
+ self .make_file (".coverage.bad2" , "This isn't a coverage data file." )
1330
+
1331
+ # Combine the parallel coverage data files into .coverage, but nothing is readable.
1332
+ cov = coverage .Coverage ()
1333
+ with pytest .warns (Warning ) as warns :
1334
+ with pytest .raises (NoDataError , match = r"No usable data files" ):
1335
+ cov .combine (strict = True )
1336
+
1337
+ warn_rx = re .compile (
1338
+ r"Couldn't use data file '.*[/\\]\.coverage\.bad[12]': file is not a database"
1339
+ )
1340
+ assert_coverage_warnings (warns , warn_rx , warn_rx )
1341
+
1342
+ # After combining, we should have a main file and two parallel files.
1343
+ self .assert_exists (".coverage" )
1344
+ self .assert_exists (".coverage.bad1" )
1345
+ self .assert_exists (".coverage.bad2" )
1346
+ self .assert_file_count (".coverage.*" , 2 )
1347
+
1348
+ # Read the coverage file and see that b_or_c.py has 6 lines
1349
+ # executed (we only did b, not c).
1350
+ data = coverage .CoverageData ()
1351
+ data .read ()
1352
+ assert line_counts (data )['b_or_c.py' ] == 6
1353
+
1354
+ def test_combine_parallel_data_in_two_steps (self ):
1355
+ self .make_b_or_c_py ()
1356
+ self .make_data_file (".coverage.b" , lines = self .B_LINES )
1357
+
1358
+ # Combine the (one) parallel coverage data file into .coverage .
1359
+ cov = coverage .Coverage ()
1360
+ cov .combine (strict = True )
1361
+
1362
+ self .assert_exists (".coverage" )
1363
+ self .assert_file_count (".coverage.*" , 0 )
1364
+
1365
+ self .make_data_file (".coverage.c" , lines = self .C_LINES )
1366
+ self .assert_exists (".coverage" )
1367
+ self .assert_file_count (".coverage.*" , 1 )
1368
+
1369
+ # Combine the parallel coverage data files into .coverage .
1370
+ cov = coverage .Coverage ()
1371
+ cov .load ()
1372
+ cov .combine (strict = True )
1373
+
1374
+ # After combining, there should be only the .coverage file.
1375
+ self .assert_exists (".coverage" )
1376
+ self .assert_file_count (".coverage.*" , 0 )
1377
+
1378
+ # Read the coverage file and see that b_or_c.py has all 8 lines
1379
+ # executed.
1380
+ data = coverage .CoverageData ()
1381
+ data .read ()
1382
+ assert line_counts (data )['b_or_c.py' ] == 8
1383
+
1384
+ def test_combine_parallel_data_no_append (self ):
1385
+ self .make_b_or_c_py ()
1386
+ self .make_data_file (".coverage.b" , lines = self .B_LINES )
1387
+
1388
+ # Combine the (one) parallel coverage data file into .coverage .
1389
+ cov = coverage .Coverage ()
1390
+ cov .combine (strict = True )
1391
+ self .assert_exists (".coverage" )
1392
+ self .assert_file_count (".coverage.*" , 0 )
1393
+
1394
+ self .make_data_file (".coverage.c" , lines = self .C_LINES )
1395
+
1396
+ # Combine the parallel coverage data files into .coverage, but don't
1397
+ # use the data in .coverage already.
1398
+ cov = coverage .Coverage ()
1399
+ cov .combine (strict = True )
1400
+
1401
+ # After combining, there should be only the .coverage file.
1402
+ self .assert_exists (".coverage" )
1403
+ self .assert_file_count (".coverage.*" , 0 )
1404
+
1405
+ # Read the coverage file and see that b_or_c.py has only 7 lines
1406
+ # because we didn't keep the data from running b.
1407
+ data = coverage .CoverageData ()
1408
+ data .read ()
1409
+ assert line_counts (data )['b_or_c.py' ] == 7
1410
+
1411
+ def test_combine_parallel_data_keep (self ):
1412
+ self .make_b_or_c_py ()
1413
+ self .make_data_file (".coverage.b" , lines = self .B_LINES )
1414
+ self .make_data_file (".coverage.c" , lines = self .C_LINES )
1415
+
1416
+ # Combine the parallel coverage data files into .coverage with the keep flag.
1417
+ cov = coverage .Coverage ()
1418
+ cov .combine (strict = True , keep = True )
1419
+
1420
+ # After combining, the .coverage file & the original combined file should still be there.
1421
+ self .assert_exists (".coverage" )
1422
+ self .assert_file_count (".coverage.*" , 2 )
0 commit comments