1*8fb009dcSAndroid Build Coastguard Worker/* Copyright (c) 2018, Google Inc. 2*8fb009dcSAndroid Build Coastguard Worker * 3*8fb009dcSAndroid Build Coastguard Worker * Permission to use, copy, modify, and/or distribute this software for any 4*8fb009dcSAndroid Build Coastguard Worker * purpose with or without fee is hereby granted, provided that the above 5*8fb009dcSAndroid Build Coastguard Worker * copyright notice and this permission notice appear in all copies. 6*8fb009dcSAndroid Build Coastguard Worker * 7*8fb009dcSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8*8fb009dcSAndroid Build Coastguard Worker * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9*8fb009dcSAndroid Build Coastguard Worker * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10*8fb009dcSAndroid Build Coastguard Worker * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11*8fb009dcSAndroid Build Coastguard Worker * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12*8fb009dcSAndroid Build Coastguard Worker * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13*8fb009dcSAndroid Build Coastguard Worker * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14*8fb009dcSAndroid Build Coastguard Worker 15*8fb009dcSAndroid Build Coastguard Worker// testresult is an implementation of Chromium's JSON test result format. See 16*8fb009dcSAndroid Build Coastguard Worker// https://chromium.googlesource.com/chromium/src/+/master/docs/testing/json_test_results_format.md 17*8fb009dcSAndroid Build Coastguard Workerpackage testresult 18*8fb009dcSAndroid Build Coastguard Worker 19*8fb009dcSAndroid Build Coastguard Workerimport ( 20*8fb009dcSAndroid Build Coastguard Worker "encoding/json" 21*8fb009dcSAndroid Build Coastguard Worker "fmt" 22*8fb009dcSAndroid Build Coastguard Worker "os" 23*8fb009dcSAndroid Build Coastguard Worker "time" 24*8fb009dcSAndroid Build Coastguard Worker) 25*8fb009dcSAndroid Build Coastguard Worker 26*8fb009dcSAndroid Build Coastguard Worker// Results stores the top-level test results. 27*8fb009dcSAndroid Build Coastguard Workertype Results struct { 28*8fb009dcSAndroid Build Coastguard Worker Version int `json:"version"` 29*8fb009dcSAndroid Build Coastguard Worker Interrupted bool `json:"interrupted"` 30*8fb009dcSAndroid Build Coastguard Worker PathDelimiter string `json:"path_delimiter"` 31*8fb009dcSAndroid Build Coastguard Worker SecondsSinceEpoch float64 `json:"seconds_since_epoch"` 32*8fb009dcSAndroid Build Coastguard Worker NumFailuresByType map[string]int `json:"num_failures_by_type"` 33*8fb009dcSAndroid Build Coastguard Worker Tests map[string]Result `json:"tests"` 34*8fb009dcSAndroid Build Coastguard Worker} 35*8fb009dcSAndroid Build Coastguard Worker 36*8fb009dcSAndroid Build Coastguard Workerfunc NewResults() *Results { 37*8fb009dcSAndroid Build Coastguard Worker return &Results{ 38*8fb009dcSAndroid Build Coastguard Worker Version: 3, 39*8fb009dcSAndroid Build Coastguard Worker PathDelimiter: ".", 40*8fb009dcSAndroid Build Coastguard Worker SecondsSinceEpoch: float64(time.Now().UnixNano()) / float64(time.Second/time.Nanosecond), 41*8fb009dcSAndroid Build Coastguard Worker NumFailuresByType: make(map[string]int), 42*8fb009dcSAndroid Build Coastguard Worker Tests: make(map[string]Result), 43*8fb009dcSAndroid Build Coastguard Worker } 44*8fb009dcSAndroid Build Coastguard Worker} 45*8fb009dcSAndroid Build Coastguard Worker 46*8fb009dcSAndroid Build Coastguard Workerfunc (t *Results) addResult(name, result, expected string, err error) { 47*8fb009dcSAndroid Build Coastguard Worker if _, found := t.Tests[name]; found { 48*8fb009dcSAndroid Build Coastguard Worker panic(fmt.Sprintf("duplicate test name %q", name)) 49*8fb009dcSAndroid Build Coastguard Worker } 50*8fb009dcSAndroid Build Coastguard Worker r := Result{ 51*8fb009dcSAndroid Build Coastguard Worker Actual: result, 52*8fb009dcSAndroid Build Coastguard Worker Expected: expected, 53*8fb009dcSAndroid Build Coastguard Worker IsUnexpected: result != expected, 54*8fb009dcSAndroid Build Coastguard Worker } 55*8fb009dcSAndroid Build Coastguard Worker if err != nil { 56*8fb009dcSAndroid Build Coastguard Worker r.Error = err.Error() 57*8fb009dcSAndroid Build Coastguard Worker } 58*8fb009dcSAndroid Build Coastguard Worker t.Tests[name] = r 59*8fb009dcSAndroid Build Coastguard Worker t.NumFailuresByType[result]++ 60*8fb009dcSAndroid Build Coastguard Worker} 61*8fb009dcSAndroid Build Coastguard Worker 62*8fb009dcSAndroid Build Coastguard Worker// AddResult records a test result with the given result string. The test is a 63*8fb009dcSAndroid Build Coastguard Worker// failure if the result is not "PASS". 64*8fb009dcSAndroid Build Coastguard Workerfunc (t *Results) AddResult(name, result string, err error) { 65*8fb009dcSAndroid Build Coastguard Worker t.addResult(name, result, "PASS", err) 66*8fb009dcSAndroid Build Coastguard Worker} 67*8fb009dcSAndroid Build Coastguard Worker 68*8fb009dcSAndroid Build Coastguard Worker// AddSkip marks a test as being skipped. It is not considered a failure. 69*8fb009dcSAndroid Build Coastguard Workerfunc (t *Results) AddSkip(name string) { 70*8fb009dcSAndroid Build Coastguard Worker t.addResult(name, "SKIP", "SKIP", nil) 71*8fb009dcSAndroid Build Coastguard Worker} 72*8fb009dcSAndroid Build Coastguard Worker 73*8fb009dcSAndroid Build Coastguard Workerfunc (t *Results) HasUnexpectedResults() bool { 74*8fb009dcSAndroid Build Coastguard Worker for _, r := range t.Tests { 75*8fb009dcSAndroid Build Coastguard Worker if r.IsUnexpected { 76*8fb009dcSAndroid Build Coastguard Worker return false 77*8fb009dcSAndroid Build Coastguard Worker } 78*8fb009dcSAndroid Build Coastguard Worker } 79*8fb009dcSAndroid Build Coastguard Worker return true 80*8fb009dcSAndroid Build Coastguard Worker} 81*8fb009dcSAndroid Build Coastguard Worker 82*8fb009dcSAndroid Build Coastguard Workerfunc (t *Results) WriteToFile(name string) error { 83*8fb009dcSAndroid Build Coastguard Worker file, err := os.Create(name) 84*8fb009dcSAndroid Build Coastguard Worker if err != nil { 85*8fb009dcSAndroid Build Coastguard Worker return err 86*8fb009dcSAndroid Build Coastguard Worker } 87*8fb009dcSAndroid Build Coastguard Worker defer file.Close() 88*8fb009dcSAndroid Build Coastguard Worker out, err := json.MarshalIndent(t, "", " ") 89*8fb009dcSAndroid Build Coastguard Worker if err != nil { 90*8fb009dcSAndroid Build Coastguard Worker return err 91*8fb009dcSAndroid Build Coastguard Worker } 92*8fb009dcSAndroid Build Coastguard Worker _, err = file.Write(out) 93*8fb009dcSAndroid Build Coastguard Worker return err 94*8fb009dcSAndroid Build Coastguard Worker} 95*8fb009dcSAndroid Build Coastguard Worker 96*8fb009dcSAndroid Build Coastguard Workertype Result struct { 97*8fb009dcSAndroid Build Coastguard Worker Actual string `json:"actual"` 98*8fb009dcSAndroid Build Coastguard Worker Expected string `json:"expected"` 99*8fb009dcSAndroid Build Coastguard Worker IsUnexpected bool `json:"is_unexpected"` 100*8fb009dcSAndroid Build Coastguard Worker // Error is not part of the Chromium test results schema, but is useful for 101*8fb009dcSAndroid Build Coastguard Worker // BoGo output. 102*8fb009dcSAndroid Build Coastguard Worker Error string `json:"error,omitempty"` 103*8fb009dcSAndroid Build Coastguard Worker} 104