| // Copyright 2013 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // Test runner for coverage test. This file is not coverage-annotated; test.go is. | |
| // It knows the coverage counter is called | |
| // "thisNameMustBeVeryLongToCauseOverflowOfCounterIncrementStatementOntoNextLineForTest". | |
| package main | |
| import ( | |
| "fmt" | |
| "os" | |
| ) | |
| func main() { | |
| testAll() | |
| verify() | |
| } | |
| type block struct { | |
| count uint32 | |
| line uint32 | |
| } | |
| var counters = make(map[block]bool) | |
| // shorthand for the long counter variable. | |
| var coverTest = &thisNameMustBeVeryLongToCauseOverflowOfCounterIncrementStatementOntoNextLineForTest | |
| // check records the location and expected value for a counter. | |
| func check(line, count uint32) { | |
| b := block{ | |
| count, | |
| line, | |
| } | |
| counters[b] = true | |
| } | |
| // checkVal is a version of check that returns its extra argument, | |
| // so it can be used in conditionals. | |
| func checkVal(line, count uint32, val int) int { | |
| b := block{ | |
| count, | |
| line, | |
| } | |
| counters[b] = true | |
| return val | |
| } | |
| var PASS = true | |
| // verify checks the expected counts against the actual. It runs after the test has completed. | |
| func verify() { | |
| for b := range counters { | |
| got, index := count(b.line) | |
| if b.count == anything && got != 0 { | |
| got = anything | |
| } | |
| if got != b.count { | |
| fmt.Fprintf(os.Stderr, "test_go:%d expected count %d got %d [counter %d]\n", b.line, b.count, got, index) | |
| PASS = false | |
| } | |
| } | |
| verifyPanic() | |
| if !PASS { | |
| fmt.Fprintf(os.Stderr, "FAIL\n") | |
| os.Exit(2) | |
| } | |
| } | |
| // verifyPanic is a special check for the known counter that should be | |
| // after the panic call in testPanic. | |
| func verifyPanic() { | |
| if coverTest.Count[panicIndex-1] != 1 { | |
| // Sanity check for test before panic. | |
| fmt.Fprintf(os.Stderr, "bad before panic") | |
| PASS = false | |
| } | |
| if coverTest.Count[panicIndex] != 0 { | |
| fmt.Fprintf(os.Stderr, "bad at panic: %d should be 0\n", coverTest.Count[panicIndex]) | |
| PASS = false | |
| } | |
| if coverTest.Count[panicIndex+1] != 1 { | |
| fmt.Fprintf(os.Stderr, "bad after panic") | |
| PASS = false | |
| } | |
| } | |
| // count returns the count and index for the counter at the specified line. | |
| func count(line uint32) (uint32, int) { | |
| // Linear search is fine. Choose perfect fit over approximate. | |
| // We can have a closing brace for a range on the same line as a condition for an "else if" | |
| // and we don't want that brace to steal the count for the condition on the "if". | |
| // Therefore we test for a perfect (lo==line && hi==line) match, but if we can't | |
| // find that we take the first imperfect match. | |
| index := -1 | |
| indexLo := uint32(1e9) | |
| for i := range coverTest.Count { | |
| lo, hi := coverTest.Pos[3*i], coverTest.Pos[3*i+1] | |
| if lo == line && line == hi { | |
| return coverTest.Count[i], i | |
| } | |
| // Choose the earliest match (the counters are in unpredictable order). | |
| if lo <= line && line <= hi && indexLo > lo { | |
| index = i | |
| indexLo = lo | |
| } | |
| } | |
| if index == -1 { | |
| fmt.Fprintln(os.Stderr, "cover_test: no counter for line", line) | |
| PASS = false | |
| return 0, 0 | |
| } | |
| return coverTest.Count[index], index | |
| } |