mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
cb66952a0d
In prep for tsd.System Tracker plumbing throughout tailscaled, defensively permit all methods on Tracker to accept a nil receiver without crashing, lest I screw something up later. (A health tracking system that itself causes crashes would be no good.) Methods on nil receivers should not be called, so a future change will also collect their stacks (and panic during dev/test), but we should at least not crash in prod. This also locks that in with a test using reflect to automatically call all methods on a nil receiver and check they don't crash. Updates #11874 Updates #4136 Change-Id: I8e955046ebf370ec8af0c1fb63e5123e6282a9d3 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package health
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestAppendWarnableDebugFlags(t *testing.T) {
|
|
var tr Tracker
|
|
|
|
for i := range 10 {
|
|
w := NewWarnable(WithMapDebugFlag(fmt.Sprint(i)))
|
|
if i%2 == 0 {
|
|
tr.SetWarnable(w, errors.New("boom"))
|
|
}
|
|
}
|
|
|
|
want := []string{"z", "y", "0", "2", "4", "6", "8"}
|
|
|
|
var got []string
|
|
for range 20 {
|
|
got = append(got[:0], "z", "y")
|
|
got = tr.AppendWarnableDebugFlags(got)
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("AppendWarnableDebugFlags = %q; want %q", got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test that all exported methods on *Tracker don't panic with a nil receiver.
|
|
func TestNilMethodsDontCrash(t *testing.T) {
|
|
var nilt *Tracker
|
|
rv := reflect.ValueOf(nilt)
|
|
for i := 0; i < rv.NumMethod(); i++ {
|
|
mt := rv.Type().Method(i)
|
|
t.Logf("calling Tracker.%s ...", mt.Name)
|
|
var args []reflect.Value
|
|
for j := 0; j < mt.Type.NumIn(); j++ {
|
|
if j == 0 && mt.Type.In(j) == reflect.TypeFor[*Tracker]() {
|
|
continue
|
|
}
|
|
args = append(args, reflect.Zero(mt.Type.In(j)))
|
|
}
|
|
rv.Method(i).Call(args)
|
|
}
|
|
}
|