Skip to content

Commit 10f1f52

Browse files
committed
Move firecracker-report-parser implementation to practitest-firecracker
Simpler to manage and we still can reuse it in the UI backend by importing it from `practitest-firecracker`
1 parent 4cc6fd9 commit 10f1f52

6 files changed

Lines changed: 227 additions & 28 deletions

File tree

.idea/libraries/Deps__github_PractiTest_firecracker_report_parser_9fed1a.xml

Lines changed: 0 additions & 9 deletions
This file was deleted.

deps.edn

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@
77
throttler/throttler {:mvn/version "1.0.0"}
88
org.clojure/tools.logging {:mvn/version "1.1.0"}
99
ch.qos.logback/logback-classic {:mvn/version "1.2.3"}
10-
clj-time/clj-time {:mvn/version "0.15.2"}
11-
github-PractiTest/firecracker-report-parser {:git/url "git@github.com:PractiTest/firecracker-report-parser.git"
12-
:deps/manifest :deps
13-
:sha "9fed1ab43b42f1b6d426925eaf159e620e793c56"}}
10+
clj-time/clj-time {:mvn/version "0.15.2"}}
1411
:aliases
1512
{:dev {:extra-paths ["dev"]}
1613
:package {:extra-paths ["resources" "target/cljs/"]}

practitest-firecracker.iml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
<orderEntry type="library" name="Deps: org.clojure/tools.cli:1.0.194" level="project" />
3030
<orderEntry type="library" name="Deps: org.apache.httpcomponents/httpasyncclient:4.1.4" level="project" />
3131
<orderEntry type="library" name="Deps: org.clojure/tools.analyzer.jvm:1.0.0" level="project" />
32-
<orderEntry type="library" name="Deps: github-PractiTest/firecracker-report-parser:9fed1a" level="project" />
3332
<orderEntry type="library" name="Deps: com.fasterxml.jackson.dataformat/jackson-dataformat-cbor:2.10.2" level="project" />
3433
<orderEntry type="library" name="Deps: ch.qos.logback/logback-core:1.2.3" level="project" />
3534
<orderEntry type="library" name="Deps: slingshot:0.12.2" level="project" />

src/practitest_firecracker/core.clj

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
(ns practitest-firecracker.core
22
(:require
3-
[practitest-firecracker.cli :refer [parse-args]]
4-
[practitest-firecracker.practitest :refer [make-client
5-
create-sf-testset
6-
make-runs
7-
populate-sf-results
8-
create-testsets
9-
group-tests
10-
create-or-update-tests
11-
create-instances
12-
create-runs]]
13-
[firecracker-report-parser.core :refer [send-directory parse-files]]
14-
[clojure.pprint :as pprint]
15-
[clojure.java.io :refer [file]]
16-
[clj-time.core :as t])
3+
[practitest-firecracker.cli :refer [parse-args]]
4+
[practitest-firecracker.practitest :refer [make-client
5+
make-runs
6+
populate-sf-results
7+
create-testsets
8+
group-tests
9+
create-or-update-tests
10+
create-instances
11+
create-runs]]
12+
[practitest-firecracker.parser.core :refer [send-directory parse-files]]
13+
[clojure.pprint :as pprint]
14+
[clojure.java.io :refer [file]]
15+
[clj-time.core :as t])
1716
(:gen-class))
1817

1918
(defn exit [status msg]
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
(ns practitest-firecracker.parser.core
2+
(:require
3+
[clojure.java.io :as io]
4+
[clojure.string :as str]
5+
[clojure.xml :as xml]
6+
[clojure.zip :as zip])
7+
(:import (java.text NumberFormat)
8+
(java.io ByteArrayInputStream)))
9+
10+
(defn round
11+
[x & {p :precision}]
12+
(if (< x 0.006)
13+
(if p
14+
(let [scale (Math/pow 10 p)]
15+
(-> x (* scale) Math/round (/ scale)))
16+
(Math/round x))
17+
x))
18+
19+
(defn str-to-number [val]
20+
(if (not (nil? val)) (.parse (NumberFormat/getInstance) val) 0))
21+
22+
(defn zip-str [s]
23+
(zip/xml-zip
24+
(xml/parse (ByteArrayInputStream. (.getBytes s "UTF-8")))))
25+
26+
(defn filter-tags [tag-key xml-content]
27+
(let [filter-result (filter #(= (:tag %) tag-key) xml-content)]
28+
filter-result))
29+
30+
(defn get-attrs [obj]
31+
(conj obj (:attrs obj)))
32+
33+
(defn case-data [case]
34+
(let [content (:content case)
35+
case-type (filter #(contains? #{:error :failure :flake :skipped} (:tag %)) content)
36+
system-message (filter #(contains? #{:system-out :system-err} (:tag %)) content)
37+
attrs (:attrs case)
38+
name (if (:classname attrs) (:name attrs) (last (str/split (:name attrs) #">")))]
39+
(assoc attrs
40+
:time (str-to-number (:time attrs))
41+
:full-class-name (:classname attrs)
42+
:full-name (str (:classname attrs) "." (:name attrs))
43+
:has-failure? (some? case-type)
44+
:failure-message (if case-type (get-in (first case-type) [:attrs :message]) nil)
45+
:failure-detail (if system-message (str (first (:content (first system-message))) (first (:content (first case-type)))) nil)
46+
:class-name (when (:classname attrs) (last (str/split (:classname attrs) #"\.")))
47+
:failure-type (if (and case-type (first case-type)) (:tag (first case-type)) nil)
48+
;; :case-type case-type
49+
;; :case-content content
50+
;; :name name
51+
:test-case-name name
52+
:pt-test-step-name name
53+
:system-message system-message)))
54+
55+
(defn get-case-info [test-cases]
56+
(map case-data test-cases))
57+
58+
(defn group-by-classname [val]
59+
(last (str/split (:classname (:attrs val)) #"\.")))
60+
61+
(defn group-by-name [val]
62+
(last (str/split (:name (:attrs val)) #">")))
63+
64+
(defn group-testcase-data [data multi-test-cases]
65+
(let [grouping-func (if (contains? (:attrs (first data)) :classname)
66+
group-by-classname
67+
group-by-name)]
68+
(if multi-test-cases
69+
(->> data
70+
(group-by grouping-func)
71+
(map (fn [[k vals]] [k (into {:test-cases (get-case-info vals)} (first (map :attrs vals)))]))
72+
(into {}))
73+
(->> data
74+
(map-indexed (fn [index val] {index (into {:test-cases (list (case-data val))} (:attrs val))}))
75+
(into {})))))
76+
77+
(defn test-data [test]
78+
(let [package (if (:classname test) (clojure.string/join "." (drop-last (str/split (:classname test) #"\."))) (:name test))
79+
name (if (:classname test) (last (str/split (:classname test) #"\.")) (last (str/split (:name test) #">")))]
80+
(assoc test
81+
:errors (count (filter #(= (:failure-type %) :error) (:test-cases test)))
82+
:failures (count (filter #(= (:failure-type %) :failure) (:test-cases test)))
83+
:flakes (count (filter #(= (:failure-type %) :flake) (:test-cases test)))
84+
:skipped (count (filter #(= (:failure-type %) :skipped) (:test-cases test)))
85+
:tests (count (:test-cases test))
86+
;; :name name
87+
;; :name-test-suite name
88+
:suite-name (:suite-name test)
89+
:pt-first-case-name (:name (first (:test-cases test)))
90+
:pt-test-name name
91+
:pt-name-combine (str name " - " (:name (first (:test-cases test))))
92+
:time-elapsed (round (reduce + (map :time (:test-cases test))) :precision 3)
93+
:full-class-name (:classname test)
94+
:package-name package)))
95+
96+
(defn get-test-aggregations [test val]
97+
(let [map-vals (vals val)
98+
map-vals-with (map #(assoc % :suite-name (:name (:attrs test))) map-vals)
99+
result (first (conj (or (:test-list test) []) (map test-data map-vals-with)))]
100+
result))
101+
102+
(defn get-another-lvl-data [multi-test-cases sample data]
103+
(let [content-data (if sample (keep-indexed #(if (> 20 %1) %2) (:content data)) (:content data))]
104+
(case (:tag data)
105+
:testsuite (assoc (get-attrs data) :test-list
106+
(get-test-aggregations data (group-testcase-data (filter-tags :testcase content-data) multi-test-cases)))
107+
:testsuites (assoc data :testsuite-list
108+
(for [suite content-data]
109+
(get-another-lvl-data multi-test-cases sample suite)))
110+
nil)))
111+
112+
(defn clean-content [testsuite]
113+
(let [val (map (fn [suite]
114+
(assoc suite :content nil)) (:testsuite-list testsuite))]
115+
{:testsuite-list (filter-tags :testsuite val)}))
116+
117+
(defn get-data [parsed-file multi-test-cases sample]
118+
(let [first-parsed-file (first parsed-file)]
119+
(if (= (:tag first-parsed-file) :testsuites)
120+
(->> first-parsed-file
121+
(get-another-lvl-data multi-test-cases sample)
122+
clean-content
123+
(into {}))
124+
(->> {:tag :testsuites :content parsed-file}
125+
(get-another-lvl-data multi-test-cases sample)
126+
clean-content
127+
(into {})))))
128+
129+
(defn testset-vals [gf]
130+
(let [val (:testsuite-list gf)
131+
result (reduce conj () val)]
132+
result))
133+
134+
(defn get-files-data [parsed-files multi-test-cases sample]
135+
(let [grouped-files (for [file parsed-files] (get-data file multi-test-cases sample))
136+
grouped grouped-files
137+
testsuite-list (flatten (map testset-vals grouped))
138+
]
139+
testsuite-list))
140+
141+
(defn merged-testset [testsets tests testset-name]
142+
(list {:tag :testsuite
143+
:test-list tests
144+
:name testset-name
145+
:tests (reduce + (map #(str-to-number %) (map :tests testsets)))
146+
:time (reduce + (map #(str-to-number %) (map :time testsets)))
147+
:failures (reduce + (map #(str-to-number %) (map :failues testsets)))
148+
:skipped (reduce + (map #(str-to-number %) (map :skipped testsets)))
149+
}))
150+
151+
(defn merge-testsets [testsets testset-name]
152+
(let [group-tests (flatten (reduce conj (for [testset testsets] (:test-list testset))))]
153+
(merged-testset testsets group-tests testset-name)))
154+
155+
(defn merge-testsets-by-name [testsets]
156+
(let [testsets-by-name (group-by :name testsets)
157+
merged-testsets (for [sub-testsets testsets-by-name]
158+
(reduce conj (merge-testsets (last sub-testsets) (first sub-testsets))))]
159+
merged-testsets))
160+
161+
(defn parse-n-merge-data [grouped-files-map parsed-content]
162+
(let [merge-content (merge (get grouped-files-map (:test-list parsed-content)) parsed-content)]
163+
merge-content))
164+
165+
(defn get-files-path [directory]
166+
(let [file-seqs (.listFiles (io/file directory))
167+
filtered-files (filter (fn [file] (str/ends-with? (.getAbsolutePath file) ".xml")) file-seqs)
168+
filtered-paths (for [file filtered-files] (.getAbsolutePath file))]
169+
filtered-paths))
170+
171+
(defn parse-files [directory]
172+
(let [filtered-paths (get-files-path directory)
173+
files (for [path filtered-paths] (slurp path))
174+
parsed-files (for [file files] (zip-str file))]
175+
parsed-files))
176+
177+
(defn merge-results [parsed-files multi-test-cases multi-testsets testset-name sample]
178+
(let [grouped-data (get-files-data parsed-files multi-test-cases sample)
179+
result (if multi-testsets (merge-testsets-by-name grouped-data) (merge-testsets grouped-data testset-name))
180+
]
181+
result))
182+
183+
(defn send-directory [parsed-dirs multi-test-cases multi-testsets testset-name sample]
184+
(let [result (first
185+
(conj (list)
186+
(first
187+
(for [dir parsed-dirs]
188+
(merge-results dir multi-test-cases multi-testsets testset-name sample)))))]
189+
result))
190+
191+
(defn get-dir-by-path [path multi-test-cases multi-testsets testset-name sample]
192+
(let [directory (clojure.java.io/file path)
193+
parsed-dirs (for [dir (file-seq directory)] (parse-files dir))]
194+
(send-directory parsed-dirs multi-test-cases multi-testsets testset-name sample)))
195+
196+
(defn -main [& [arg multi-test-cases multi-testsets testset-name sample]]
197+
(if-not (empty? arg)
198+
(let [result (get-dir-by-path arg (= "true" multi-test-cases) (= "true" multi-testsets) testset-name (= "true" sample))]
199+
result)
200+
(throw (Exception. "Must have at least one argument!"))))
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
(ns practitest-firecracker.parser.utils
2+
(:require
3+
[clojure.pprint :as pprint]
4+
[clojure.string :as str]))
5+
6+
(defn return-file [file]
7+
(pprint/pprint (slurp file)))
8+
9+
(defn return-files [directory]
10+
(let [filtered-files (filter (fn [file] (str/ends-with? (.getAbsolutePath file) ".xml")) (file-seq directory))
11+
filtered-paths (for [file filtered-files] (.getAbsolutePath file))
12+
files (for [path filtered-paths] (return-file path))]
13+
files))

0 commit comments

Comments
 (0)