17 from email
.utils
import formatdate
18 from pathlib
import Path
20 from urllib
import parse
22 import dump_trace_images
24 TRACES_DB_PATH
= "./traces-db/"
25 RESULTS_PATH
= "./results/"
27 def replay(trace_path
, device_name
):
28 success
= dump_trace_images
.dump_from_trace(trace_path
, [], device_name
)
31 print("[check_image] Trace %s couldn't be replayed. See above logs for more information." % (str(trace_path
)))
32 return None, None, None
34 base_path
= trace_path
.parent
35 file_name
= trace_path
.name
36 files
= glob
.glob(str(base_path
/ "test" / device_name
/ (file_name
+ "-*" + ".png")))
39 files
= glob
.glob(str(base_path
/ "test" / device_name
/ (file_name
+ ".log")))
42 return hashlib
.md5(Image
.open(image_file
).tobytes()).hexdigest(), image_file
, log_file
44 def gitlab_ensure_trace(project_url
, trace
):
45 trace_path
= TRACES_DB_PATH
+ trace
['path']
46 if project_url
is None:
47 if not os
.path
.exists(trace_path
):
48 print("{} missing".format(trace_path
))
52 os
.makedirs(os
.path
.dirname(trace_path
), exist_ok
=True)
54 if os
.path
.exists(trace_path
):
57 print("[check_image] Downloading trace %s" % (trace
['path']), end
=" ", flush
=True)
58 download_time
= time
.time()
59 r
= requests
.get(project_url
+ trace
['path'])
60 open(trace_path
, "wb").write(r
.content
)
61 print("took %ds." % (time
.time() - download_time
), flush
=True)
63 def sign_with_hmac(key
, message
):
64 key
= key
.encode("UTF-8")
65 message
= message
.encode("UTF-8")
67 signature
= hmac
.new(key
, message
, hashlib
.sha1
).digest()
69 return base64
.encodebytes(signature
).strip().decode()
71 def upload_artifact(file_name
, content_type
, device_name
):
72 with
open('.minio_credentials', 'r') as f
:
73 credentials
= json
.load(f
)["minio-packet.freedesktop.org"]
74 minio_key
= credentials
["AccessKeyId"]
75 minio_secret
= credentials
["SecretAccessKey"]
76 minio_token
= credentials
["SessionToken"]
78 resource
= '/artifacts/%s/%s/%s/%s' % (os
.environ
['CI_PROJECT_PATH'], os
.environ
['CI_PIPELINE_ID'], device_name
, os
.path
.basename(file_name
))
79 date
= formatdate(timeval
=None, localtime
=False, usegmt
=True)
80 url
= 'https://minio-packet.freedesktop.org%s' % (resource
)
81 to_sign
= "PUT\n\n%s\n%s\nx-amz-security-token:%s\n%s" % (content_type
, date
, minio_token
, resource
)
82 signature
= sign_with_hmac(minio_secret
, to_sign
)
84 with
open(file_name
, 'rb') as data
:
85 headers
= {'Host': 'minio-packet.freedesktop.org',
87 'Content-Type': content_type
,
88 'Authorization': 'AWS %s:%s' % (minio_key
, signature
),
89 'x-amz-security-token': minio_token
}
90 print("Uploading artifact to %s" % url
);
91 r
= requests
.put(url
, headers
=headers
, data
=data
)
95 def gitlab_check_trace(project_url
, device_name
, trace
, expectation
):
96 gitlab_ensure_trace(project_url
, trace
)
99 result
[trace
['path']] = {}
100 result
[trace
['path']]['expected'] = expectation
['checksum']
102 trace_path
= Path(TRACES_DB_PATH
+ trace
['path'])
103 checksum
, image_file
, log_file
= replay(trace_path
, device_name
)
105 result
[trace
['path']]['actual'] = 'error'
107 elif checksum
== expectation
['checksum']:
108 print("[check_image] Images match for %s" % (trace
['path']))
111 print("[check_image] Images differ for %s (expected: %s, actual: %s)" %
112 (trace
['path'], expectation
['checksum'], checksum
))
113 print("[check_image] For more information see "
114 "https://gitlab.freedesktop.org/mesa/mesa/blob/master/.gitlab-ci/tracie/README.md")
117 trace_dir
= os
.path
.split(trace
['path'])[0]
118 dir_in_results
= os
.path
.join(trace_dir
, "test", device_name
)
119 results_path
= os
.path
.join(RESULTS_PATH
, dir_in_results
)
120 os
.makedirs(results_path
, exist_ok
=True)
121 shutil
.move(log_file
, os
.path
.join(results_path
, os
.path
.split(log_file
)[1]))
122 if not ok
and os
.environ
.get('TRACIE_UPLOAD_TO_MINIO', '0') == '1':
123 upload_artifact(image_file
, 'image/png', device_name
)
124 if not ok
or os
.environ
.get('TRACIE_STORE_IMAGES', '0') == '1':
125 image_name
= os
.path
.split(image_file
)[1]
126 shutil
.move(image_file
, os
.path
.join(results_path
, image_name
))
127 result
[trace
['path']]['image'] = os
.path
.join(dir_in_results
, image_name
)
129 result
[trace
['path']]['actual'] = checksum
133 def run(filename
, device_name
):
135 with
open(filename
, 'r') as f
:
136 y
= yaml
.safe_load(f
)
139 project_url
= y
["traces-db"]["download-url"]
143 traces
= y
['traces'] or []
147 for expectation
in trace
['expectations']:
148 if expectation
['device'] == device_name
:
149 ok
, result
= gitlab_check_trace(project_url
,
152 all_ok
= all_ok
and ok
153 results
.update(result
)
155 os
.makedirs(RESULTS_PATH
, exist_ok
=True)
156 with
open(os
.path
.join(RESULTS_PATH
, 'results.yml'), 'w') as f
:
157 yaml
.safe_dump(results
, f
, default_flow_style
=False)
158 if os
.environ
.get('TRACIE_UPLOAD_TO_MINIO', '0') == '1':
159 upload_artifact(os
.path
.join(RESULTS_PATH
, 'results.yml'), 'text/yaml', device_name
)
164 parser
= argparse
.ArgumentParser()
165 parser
.add_argument('--file', required
=True,
166 help='the name of the traces.yml file listing traces and their checksums for each device')
167 parser
.add_argument('--device-name', required
=True,
168 help="the name of the graphics device used to replay traces")
170 args
= parser
.parse_args(args
)
171 return run(args
.file, args
.device_name
)
173 if __name__
== "__main__":
174 all_ok
= main(sys
.argv
[1:])
175 sys
.exit(0 if all_ok
else 1)