Add unit test for EventHandler am: 3e334cfed2
am: 66a29aefa0
Original change: https://android-review.googlesource.com/c/platform/build/blueprint/+/2458548 Change-Id: I67314a9444b805d6ce4ce75df34c33fc20cdeb6e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
db79b843ca
3 changed files with 109 additions and 3 deletions
|
@ -24,4 +24,7 @@ bootstrap_go_package {
|
||||||
srcs: [
|
srcs: [
|
||||||
"event_handler.go",
|
"event_handler.go",
|
||||||
],
|
],
|
||||||
|
testSrcs: [
|
||||||
|
"event_handler_test.go",
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,9 @@ func (e Event) RuntimeNanoseconds() uint64 {
|
||||||
// call to End (though other events may begin and end before this event ends).
|
// call to End (though other events may begin and end before this event ends).
|
||||||
// Events within the same scope must have unique names.
|
// Events within the same scope must have unique names.
|
||||||
func (h *EventHandler) Begin(name string) {
|
func (h *EventHandler) Begin(name string) {
|
||||||
|
if strings.ContainsRune(name, '.') {
|
||||||
|
panic(fmt.Sprintf("illegal event name (avoid dot): %s", name))
|
||||||
|
}
|
||||||
h.scopeIds = append(h.scopeIds, name)
|
h.scopeIds = append(h.scopeIds, name)
|
||||||
h.scopeStartTimes = append(h.scopeStartTimes, _now())
|
h.scopeStartTimes = append(h.scopeStartTimes, _now())
|
||||||
}
|
}
|
||||||
|
@ -71,7 +74,7 @@ func (h *EventHandler) Do(name string, f func()) {
|
||||||
// themselves been marked completed.
|
// themselves been marked completed.
|
||||||
func (h *EventHandler) End(name string) {
|
func (h *EventHandler) End(name string) {
|
||||||
if len(h.scopeIds) == 0 || name != h.scopeIds[len(h.scopeIds)-1] {
|
if len(h.scopeIds) == 0 || name != h.scopeIds[len(h.scopeIds)-1] {
|
||||||
panic(fmt.Errorf("Unexpected scope end '%s'. Current scope: (%s)",
|
panic(fmt.Errorf("unexpected scope end '%s'. Current scope: (%s)",
|
||||||
name, h.scopeIds))
|
name, h.scopeIds))
|
||||||
}
|
}
|
||||||
event := Event{
|
event := Event{
|
||||||
|
@ -94,14 +97,14 @@ func (h *EventHandler) End(name string) {
|
||||||
func (h *EventHandler) CompletedEvents() []Event {
|
func (h *EventHandler) CompletedEvents() []Event {
|
||||||
if len(h.scopeIds) > 0 {
|
if len(h.scopeIds) > 0 {
|
||||||
panic(fmt.Errorf(
|
panic(fmt.Errorf(
|
||||||
"Retrieving events before all events have been closed. Current scope: (%s)",
|
"retrieving events before all events have been closed. Current scope: (%s)",
|
||||||
h.scopeIds))
|
h.scopeIds))
|
||||||
}
|
}
|
||||||
// Validate no two events have the same full id.
|
// Validate no two events have the same full id.
|
||||||
ids := map[string]struct{}{}
|
ids := map[string]struct{}{}
|
||||||
for _, event := range h.completedEvents {
|
for _, event := range h.completedEvents {
|
||||||
if _, containsId := ids[event.Id]; containsId {
|
if _, containsId := ids[event.Id]; containsId {
|
||||||
panic(fmt.Errorf("Duplicate event registered: %s", event.Id))
|
panic(fmt.Errorf("duplicate event registered: %s", event.Id))
|
||||||
}
|
}
|
||||||
ids[event.Id] = struct{}{}
|
ids[event.Id] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
100
metrics/event_handler_test.go
Normal file
100
metrics/event_handler_test.go
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package metrics
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Map[A any, B any](in []A, f func(A) B) []B {
|
||||||
|
r := make([]B, len(in))
|
||||||
|
for i, a := range in {
|
||||||
|
r[i] = f(a)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEventNameWithDot(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
r := fmt.Sprintf("%v", recover())
|
||||||
|
if !strings.HasPrefix(r, "illegal event name") {
|
||||||
|
t.Errorf("The code did not panic in the expected manner: %s", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
eh := EventHandler{}
|
||||||
|
eh.Begin("a.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEventNesting(t *testing.T) {
|
||||||
|
eh := EventHandler{}
|
||||||
|
eh.Begin("a")
|
||||||
|
eh.Begin("b")
|
||||||
|
eh.End("b")
|
||||||
|
eh.Begin("c")
|
||||||
|
eh.End("c")
|
||||||
|
eh.End("a")
|
||||||
|
expected := []string{"a.b", "a.c", "a"}
|
||||||
|
actual := Map(eh.CompletedEvents(), func(e Event) string {
|
||||||
|
return e.Id
|
||||||
|
})
|
||||||
|
if !reflect.DeepEqual(expected, actual) {
|
||||||
|
t.Errorf("expected: %s actual %s", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEventOverlap(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
r := fmt.Sprintf("%v", recover())
|
||||||
|
if !strings.Contains(r, "unexpected scope end 'a'") {
|
||||||
|
t.Errorf("expected panic but: %s", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
eh := EventHandler{}
|
||||||
|
eh.Begin("a")
|
||||||
|
eh.Begin("b")
|
||||||
|
eh.End("a")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEventDuplication(t *testing.T) {
|
||||||
|
eh := EventHandler{}
|
||||||
|
eh.Begin("a")
|
||||||
|
eh.Begin("b")
|
||||||
|
eh.End("b")
|
||||||
|
eh.Begin("b")
|
||||||
|
eh.End("b")
|
||||||
|
eh.End("a")
|
||||||
|
defer func() {
|
||||||
|
r := fmt.Sprintf("%v", recover())
|
||||||
|
if !strings.HasPrefix(r, "duplicate event") {
|
||||||
|
t.Errorf("expected panic but: %s", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
eh.CompletedEvents()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIncompleteEvent(t *testing.T) {
|
||||||
|
eh := EventHandler{}
|
||||||
|
eh.Begin("a")
|
||||||
|
defer func() {
|
||||||
|
r := fmt.Sprintf("%v", recover())
|
||||||
|
if !strings.HasPrefix(r, "retrieving events before all events have been closed.") {
|
||||||
|
t.Errorf("expected panic but: %s", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
eh.CompletedEvents()
|
||||||
|
}
|
Loading…
Reference in a new issue