1 /* Copyright (c) 2015, Google Inc. 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14 15 package runner 16 17 import ( 18 "encoding/json" 19 "os" 20 "time" 21 ) 22 23 // testOutput is a representation of Chromium's JSON test result format. See 24 // https://www.chromium.org/developers/the-json-test-results-format 25 type testOutput struct { 26 Version int `json:"version"` 27 Interrupted bool `json:"interrupted"` 28 PathDelimiter string `json:"path_delimiter"` 29 SecondsSinceEpoch float64 `json:"seconds_since_epoch"` 30 NumFailuresByType map[string]int `json:"num_failures_by_type"` 31 Tests map[string]testResult `json:"tests"` 32 allPassed bool 33 } 34 35 type testResult struct { 36 Actual string `json:"actual"` 37 Expected string `json:"expected"` 38 IsUnexpected bool `json:"is_unexpected"` 39 } 40 41 func newTestOutput() *testOutput { 42 return &testOutput{ 43 Version: 3, 44 PathDelimiter: ".", 45 SecondsSinceEpoch: float64(time.Now().UnixNano()) / float64(time.Second/time.Nanosecond), 46 NumFailuresByType: make(map[string]int), 47 Tests: make(map[string]testResult), 48 allPassed: true, 49 } 50 } 51 52 func (t *testOutput) addResult(name, result string) { 53 if _, found := t.Tests[name]; found { 54 panic(name) 55 } 56 t.Tests[name] = testResult{ 57 Actual: result, 58 Expected: "PASS", 59 IsUnexpected: result != "PASS", 60 } 61 t.NumFailuresByType[result]++ 62 if result != "PASS" { 63 t.allPassed = false 64 } 65 } 66 67 func (t *testOutput) writeTo(name string) error { 68 file, err := os.Create(name) 69 if err != nil { 70 return err 71 } 72 defer file.Close() 73 out, err := json.MarshalIndent(t, "", " ") 74 if err != nil { 75 return err 76 } 77 _, err = file.Write(out) 78 return err 79 } 80