1// Copyright 2019 Istio Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package cover 16 17import ( 18 "fmt" 19 "sync" 20) 21 22var registry = &Registry{ 23 blocks: make(map[string]*blockState), 24} 25 26// Registry for code coverage blocks 27type Registry struct { 28 mu sync.RWMutex 29 blocks map[string]*blockState 30} 31 32// GetRegistry returns the singleton code coverage block registry. 33func GetRegistry() *Registry { 34 return registry 35} 36 37// Register code coverage data structure 38func (r *Registry) Register( 39 length int, context string, 40 readPosFn ReadPosFn, readStmtFn ReadStmtFn, readCountFn ReadCountFn, clearCountFn ClearCountFn) { 41 e := initEntry(length, context, readPosFn, readStmtFn, readCountFn, clearCountFn) 42 43 r.mu.Lock() 44 45 _, found := r.blocks[context] 46 if !found { 47 r.blocks[context] = e 48 } 49 50 r.mu.Unlock() 51 52 if found { 53 panic(fmt.Sprintf("Registry.Register: Name already registered: %q", context)) 54 } 55} 56 57// Snapshot the coverage data from registered coverage data structures 58func (r *Registry) Snapshot() { 59 r.mu.RLock() 60 defer r.mu.RUnlock() 61 62 for _, e := range r.blocks { 63 e.Capture() 64 } 65} 66 67// Clear the coverage data from registered coverage data structures 68func (r *Registry) Clear() { 69 r.mu.RLock() 70 defer r.mu.RUnlock() 71 72 for _, e := range r.blocks { 73 e.Clear() 74 } 75} 76 77// GetCoverage collects Read from all registered blocks. 78func (r *Registry) GetCoverage() *Coverage { 79 r.mu.RLock() 80 defer r.mu.RUnlock() 81 82 sn := make([]*Block, 0, len(r.blocks)) 83 84 for _, e := range r.blocks { 85 sn = append(sn, e.Read()) 86 } 87 88 return &Coverage{ 89 Blocks: sn, 90 } 91} 92