package lib
import (
"reflect"
"testing"
"time"
"github.com/armon/go-metrics/prometheus"
"github.com/stretchr/testify/require"
)
func makeFullTelemetryConfig ( t * testing . T ) TelemetryConfig {
var (
promOpts = prometheus . PrometheusOpts { }
strSliceVal = [ ] string { "foo" }
strVal = "foo"
intVal = int64 ( 1 * time . Second )
)
cfg := TelemetryConfig { }
cfgP := reflect . ValueOf ( & cfg )
cfgV := cfgP . Elem ( )
for i := 0 ; i < cfgV . NumField ( ) ; i ++ {
f := cfgV . Field ( i )
if ! f . IsValid ( ) || ! f . CanSet ( ) {
continue
}
// Set non-zero values for all fields. We only implement kinds that exist
// now for brevity but will fail the test if a new field type is added since
// this is likely not implemented in MergeDefaults either.
switch f . Kind ( ) {
case reflect . Struct :
if f . Type ( ) != reflect . TypeOf ( promOpts ) {
t . Fatalf ( "unknown struct type in TelemetryConfig: actual %v, expected: %v" , f . Type ( ) , reflect . TypeOf ( promOpts ) )
}
// TODO(kit): This should delve into the fields and set them individually rather than using an empty struct
f . Set ( reflect . ValueOf ( promOpts ) )
case reflect . Slice :
if f . Type ( ) != reflect . TypeOf ( strSliceVal ) {
t . Fatalf ( "unknown slice type in TelemetryConfig." +
" You need to update MergeDefaults and this test code." )
}
f . Set ( reflect . ValueOf ( strSliceVal ) )
case reflect . Int , reflect . Int64 : // time.Duration == int64
f . SetInt ( intVal )
case reflect . String :
f . SetString ( strVal )
case reflect . Bool :
f . SetBool ( true )
default :
t . Fatalf ( "unknown field type in TelemetryConfig" +
" You need to update MergeDefaults and this test code." )
}
}
return cfg
}
func TestTelemetryConfig_MergeDefaults ( t * testing . T ) {
tests := [ ] struct {
name string
cfg TelemetryConfig
defaults TelemetryConfig
want TelemetryConfig
} {
{
name : "basic merge" ,
cfg : TelemetryConfig {
StatsiteAddr : "stats.it:4321" ,
} ,
defaults : TelemetryConfig {
StatsdAddr : "localhost:5678" ,
StatsiteAddr : "localhost:1234" ,
} ,
want : TelemetryConfig {
StatsdAddr : "localhost:5678" ,
StatsiteAddr : "stats.it:4321" ,
} ,
} ,
{
// This test uses reflect to build a TelemetryConfig with every value set
// to ensure that we exercise every possible field type. This means that
// if new fields are added that are not supported types in the code, this
// test should either ensure they work or fail to build the test case and
// fail the test.
name : "exhaustive" ,
cfg : TelemetryConfig { } ,
defaults : makeFullTelemetryConfig ( t ) ,
want : makeFullTelemetryConfig ( t ) ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
c := tt . cfg
c . MergeDefaults ( & tt . defaults )
require . Equal ( t , tt . want , c )
} )
}
}