Skip to content

Commit 75f5628

Browse files
Removed passwords and included a file
1 parent 7f60f7b commit 75f5628

2 files changed

Lines changed: 253 additions & 2 deletions

File tree

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
"""Merge Marvin suite results into summary.tsv, summary.json, and summary.txt."""
19+
20+
from __future__ import print_function
21+
22+
import argparse
23+
import json
24+
import re
25+
import sys
26+
from datetime import datetime, timezone
27+
28+
29+
def parse_results_txt(path):
30+
"""Return list of (tag, label, test_id, status, detail) from Marvin results.txt."""
31+
rows = []
32+
with open(path, encoding="utf-8") as fh:
33+
for line in fh:
34+
line = line.rstrip("\n")
35+
m = re.search(r"TestName: (\S+) \| Status : (\S+)", line)
36+
if m:
37+
rows.append(("", "", m.group(1), m.group(2), ""))
38+
continue
39+
m = re.match(r"(.+?) \.\.\. SKIP: (.+)$", line)
40+
if m:
41+
name = m.group(1).strip()
42+
detail = m.group(2).strip()
43+
rows.append(("", "", name, "SKIP", detail))
44+
return rows
45+
46+
47+
def parse_tsv_line(line):
48+
parts = line.rstrip("\n").split("\t", 4)
49+
while len(parts) < 5:
50+
parts.append("")
51+
return tuple(parts)
52+
53+
54+
def normalize_status(status):
55+
st = (status or "").upper()
56+
if st == "SUCCESS":
57+
return "PASS", "pass"
58+
if st == "SKIP":
59+
return "SKIP", "skip"
60+
return "FAIL", "fail"
61+
62+
63+
def format_summary_text(rows):
64+
lines = [
65+
"================================================================",
66+
" TEST SUMMARY",
67+
"================================================================",
68+
]
69+
pass_n = fail_n = skip_n = 0
70+
current_label = None
71+
for tag, label, test_id, status, detail in rows:
72+
group = "[%s] %s" % (tag, label) if tag else label
73+
if group != current_label:
74+
if current_label is not None:
75+
lines.append("")
76+
lines.append(" %s" % group)
77+
current_label = group
78+
mark, bucket = normalize_status(status)
79+
if bucket == "pass":
80+
pass_n += 1
81+
elif bucket == "skip":
82+
skip_n += 1
83+
else:
84+
fail_n += 1
85+
suffix = ""
86+
st = (status or "").upper()
87+
if st == "SKIP" and detail:
88+
suffix = " — %s" % detail
89+
elif st not in ("SUCCESS", "SKIP"):
90+
suffix = " — %s" % status
91+
lines.append(" %-4s %s%s" % (mark, test_id, suffix))
92+
93+
total = pass_n + fail_n + skip_n
94+
lines.extend([
95+
"",
96+
"================================================================",
97+
" TOTAL: %d passed, %d failed, %d skipped (%d tests)" % (
98+
pass_n, fail_n, skip_n, total),
99+
"================================================================",
100+
])
101+
return "\n".join(lines) + "\n", pass_n, fail_n, skip_n
102+
103+
104+
def rows_to_json(rows, meta=None):
105+
suites = {}
106+
tests = []
107+
pass_n = fail_n = skip_n = 0
108+
for tag, label, test_id, status, detail in rows:
109+
mark, bucket = normalize_status(status)
110+
if bucket == "pass":
111+
pass_n += 1
112+
elif bucket == "skip":
113+
skip_n += 1
114+
else:
115+
fail_n += 1
116+
suite_key = tag or label
117+
if suite_key not in suites:
118+
suites[suite_key] = {
119+
"tag": tag,
120+
"label": label,
121+
"passed": 0,
122+
"failed": 0,
123+
"skipped": 0,
124+
"tests": [],
125+
}
126+
suites[suite_key]["tests"].append({
127+
"name": test_id,
128+
"status": mark,
129+
"detail": detail or None,
130+
})
131+
if bucket == "pass":
132+
suites[suite_key]["passed"] += 1
133+
elif bucket == "skip":
134+
suites[suite_key]["skipped"] += 1
135+
else:
136+
suites[suite_key]["failed"] += 1
137+
tests.append({
138+
"tag": tag,
139+
"label": label,
140+
"name": test_id,
141+
"status": mark,
142+
"detail": detail or None,
143+
})
144+
145+
payload = {
146+
"generatedAt": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
147+
"totals": {
148+
"passed": pass_n,
149+
"failed": fail_n,
150+
"skipped": skip_n,
151+
"total": pass_n + fail_n + skip_n,
152+
},
153+
"suites": list(suites.values()),
154+
"tests": tests,
155+
}
156+
if meta:
157+
payload["run"] = meta
158+
return payload
159+
160+
161+
def load_rows_from_tsv(path):
162+
rows = []
163+
with open(path, encoding="utf-8") as fh:
164+
for line in fh:
165+
if line.strip():
166+
rows.append(parse_tsv_line(line))
167+
return rows
168+
169+
170+
def load_rows_from_suite_specs(specs):
171+
rows = []
172+
for spec in specs:
173+
parts = spec.split(":", 2)
174+
if len(parts) != 3:
175+
print("Invalid --suite spec (want tag:label:path): %s" % spec,
176+
file=sys.stderr)
177+
sys.exit(1)
178+
tag, label, path = parts
179+
for _tag, _label, test_id, status, detail in parse_results_txt(path):
180+
rows.append((tag, label, test_id, status, detail))
181+
return rows
182+
183+
184+
def write_outputs(out_dir, rows, meta=None):
185+
tsv_path = out_dir + "/summary.tsv"
186+
json_path = out_dir + "/summary.json"
187+
txt_path = out_dir + "/summary.txt"
188+
189+
with open(tsv_path, "w", encoding="utf-8") as fh:
190+
for row in rows:
191+
fh.write("\t".join(row) + "\n")
192+
193+
summary_text, pass_n, fail_n, skip_n = format_summary_text(rows)
194+
with open(txt_path, "w", encoding="utf-8") as fh:
195+
fh.write(summary_text)
196+
197+
payload = rows_to_json(rows, meta=meta)
198+
with open(json_path, "w", encoding="utf-8") as fh:
199+
json.dump(payload, fh, indent=2)
200+
fh.write("\n")
201+
202+
return pass_n, fail_n, skip_n, summary_text
203+
204+
205+
def main():
206+
parser = argparse.ArgumentParser(
207+
description="Aggregate Marvin test results into summary files.")
208+
parser.add_argument(
209+
"--out-dir", required=True,
210+
help="Directory for summary.tsv, summary.json, summary.txt")
211+
parser.add_argument(
212+
"--summary-tsv",
213+
help="Read existing tab-separated summary (from run_tests.sh)")
214+
parser.add_argument(
215+
"--suite", action="append", default=[],
216+
help="Suite spec tag:label:path/to/results.txt (repeatable)")
217+
parser.add_argument(
218+
"--meta-json",
219+
help="JSON string or path to run metadata merged into summary.json")
220+
parser.add_argument(
221+
"--print", dest="print_summary", action="store_true",
222+
help="Print human-readable summary to stdout")
223+
args = parser.parse_args()
224+
225+
if args.summary_tsv:
226+
rows = load_rows_from_tsv(args.summary_tsv)
227+
elif args.suite:
228+
rows = load_rows_from_suite_specs(args.suite)
229+
else:
230+
print("Provide --summary-tsv or at least one --suite", file=sys.stderr)
231+
sys.exit(1)
232+
233+
meta = None
234+
if args.meta_json:
235+
if args.meta_json.startswith("{"):
236+
meta = json.loads(args.meta_json)
237+
else:
238+
with open(args.meta_json, encoding="utf-8") as fh:
239+
meta = json.load(fh)
240+
241+
pass_n, fail_n, skip_n, summary_text = write_outputs(
242+
args.out_dir.rstrip("/"), rows, meta=meta)
243+
244+
if args.print_summary:
245+
print(summary_text, end="")
246+
247+
return 0 if fail_n == 0 else 1
248+
249+
250+
if __name__ == "__main__":
251+
sys.exit(main())

test/integration/plugins/ontap/ontap.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
{
6767
"url": "http://10.193.56.62",
6868
"username": "root",
69-
"password": "netapp1!",
69+
"password": "<<password>>",
7070
"hosttags": "kvmHost"
7171
}
7272
]
@@ -99,7 +99,7 @@
9999
"storageIP": "10.196.35.203",
100100
"svmName": "vs0",
101101
"username": "admin",
102-
"password": "netapp1!"
102+
"password": "<<password>>"
103103
},
104104
"storagePool": {
105105
"storagePoolScope": "CLUSTER",

0 commit comments

Comments
 (0)