@@ -47,6 +47,7 @@ def test_dummy(upload_assets_on_fail, tmp_path):
47
47
_log = logging .getLogger (__name__ )
48
48
49
49
_UPLOAD_ASSETS_PLUGIN_NAME = "upload_assets"
50
+ _USER_PROPERTY = "upload_assets"
50
51
51
52
52
53
def pytest_addoption (parser : pytest .Parser ):
@@ -94,6 +95,9 @@ def collect(self, path: Path, name: str):
94
95
"""Collect assets to upload"""
95
96
assert self .collected_assets is not None , "No active collection of assets"
96
97
self .collected_assets [name ] = path
98
+ # TODO: this stat won't work properly in pytest-xdist context
99
+ # because incrementing stat happens on xdist workers,
100
+ # while summary is done from xdist controller).
97
101
self .upload_stats ["collected" ] += 1
98
102
99
103
def pytest_runtest_logstart (self , nodeid ):
@@ -103,26 +107,40 @@ def pytest_runtest_logstart(self, nodeid):
103
107
def pytest_runtest_logreport (self , report : pytest .TestReport ):
104
108
# TODO #22: option to upload on other outcome as well?
105
109
if report .when == "call" and report .outcome == "failed" :
106
- self ._upload_collected_assets (nodeid = report .nodeid )
110
+ self ._upload_collected_assets (nodeid = report .nodeid , report = report )
111
+
112
+ # Merge stats
113
+ for upload_info in (
114
+ v for k , v in report .user_properties if k == _USER_PROPERTY
115
+ ):
116
+ for k , v in upload_info ["stats" ].items ():
117
+ self .upload_stats [k ] += v
118
+ if upload_info ["uploads" ]:
119
+ self .upload_reports [report .nodeid ] = upload_info ["uploads" ]
107
120
108
121
def pytest_runtest_logfinish (self , nodeid ):
109
122
# Reset collection of assets
110
123
self .collected_assets = None
111
124
112
- def _upload_collected_assets (self , nodeid : str ):
113
- upload_report = {}
125
+ def _upload_collected_assets (self , nodeid : str , report : pytest .TestReport ):
126
+ upload_info = {
127
+ "stats" : {"uploaded" : 0 , "failed" : 0 },
128
+ "uploads" : {},
129
+ }
114
130
for name , path in self .collected_assets .items ():
115
131
try :
116
132
url = self ._upload_asset (nodeid = nodeid , name = name , path = path )
117
- upload_report [name ] = {"url" : url }
118
- self . upload_stats ["uploaded" ] += 1
133
+ upload_info [ "uploads" ] [name ] = {"url" : url }
134
+ upload_info [ "stats" ] ["uploaded" ] += 1
119
135
except Exception as e :
120
136
_log .error (
121
137
f"Failed to upload asset { name = } from { path = } : { e = } " , exc_info = True
122
138
)
123
- upload_report [name ] = {"error" : str (e )}
124
- self .upload_stats ["failed" ] += 1
125
- self .upload_reports [nodeid ] = upload_report
139
+ upload_info ["uploads" ][name ] = {"error" : str (e )}
140
+ upload_info ["stats" ]["failed" ] += 1
141
+
142
+ # Pass upload info through user_properties to be xdist-compatible
143
+ report .user_properties .append ([_USER_PROPERTY , upload_info ])
126
144
127
145
def _upload_asset (self , nodeid : str , name : str , path : Path ) -> str :
128
146
safe_nodeid = re .sub (r"[^a-zA-Z0-9_.-]" , "_" , nodeid )
0 commit comments