11import os
22import logging
3+ import shutil
34
45import pytest
56from ccmlib .cluster_factory import ClusterFactory as CCMClusterFactory
910from . import CLUSTER_NAME , SINGLE_NODE_CLUSTER_NAME , MULTIDC_CLUSTER_NAME
1011from . import path as ccm_path
1112
13+ _failed_reports = []
14+ _ccm_logs_preserved = False
15+ _log_artifact_dir = os .environ .get ('INTEGRATION_LOG_ARTIFACT_DIR' , 'integration-test-logs' )
16+ _preserved_file_extensions = ('.conf' , '.log' , '.yaml' , '.yml' )
17+
18+
19+ def pytest_runtest_logreport (report ):
20+ if report .failed :
21+ _failed_reports .append (report )
22+
23+
24+ def preserve_ccm_logs_on_failure ():
25+ global _ccm_logs_preserved
26+ if _ccm_logs_preserved or not _failed_reports or not os .path .isdir (ccm_path ):
27+ return
28+
29+ destination = os .path .abspath (_log_artifact_dir )
30+ ccm_destination = os .path .join (destination , 'ccm' )
31+ os .makedirs (ccm_destination , exist_ok = True )
32+
33+ with open (os .path .join (destination , 'failed-tests.txt' ), 'w' ) as failed_tests :
34+ for report in _failed_reports :
35+ failed_tests .write ('%s %s\n ' % (report .when , report .nodeid ))
36+
37+ for root , _ , files in os .walk (ccm_path ):
38+ rel_root = os .path .relpath (root , ccm_path )
39+ path_parts = set (rel_root .split (os .sep ))
40+ preserve_all = bool (path_parts .intersection (('conf' , 'logs' )))
41+
42+ for filename in files :
43+ if not preserve_all and not filename .endswith (_preserved_file_extensions ):
44+ continue
45+
46+ source_file = os .path .join (root , filename )
47+ rel_file = os .path .relpath (source_file , ccm_path )
48+ destination_file = os .path .join (ccm_destination , rel_file )
49+ os .makedirs (os .path .dirname (destination_file ), exist_ok = True )
50+ shutil .copy2 (source_file , destination_file )
51+
52+ logging .info ("Preserved ccm logs for failed tests under %s" , destination )
53+ _ccm_logs_preserved = True
54+
1255
1356@pytest .fixture (scope = "session" , autouse = True )
1457def cleanup_clusters ():
1558
1659 yield
1760
61+ preserve_ccm_logs_on_failure ()
62+
1863 if not os .environ .get ('DISABLE_CLUSTER_CLEANUP' ):
1964 for cluster_name in [CLUSTER_NAME , SINGLE_NODE_CLUSTER_NAME , MULTIDC_CLUSTER_NAME ,
2065 'cluster_tests' , 'shared_aware' , 'sni_proxy' , 'test_ip_change' , 'test_client_routes_replacement' ]:
@@ -29,4 +74,5 @@ def cleanup_clusters():
2974def setup_and_teardown_packages ():
3075 print ('setup' )
3176 yield
77+ preserve_ccm_logs_on_failure ()
3278 teardown_package ()
0 commit comments