Verify completeness of sample-lbcd.conf using reflection on config struct.
This commit is contained in:
parent
4772e2e7fb
commit
67b68d3917
1 changed files with 104 additions and 0 deletions
104
config_test.go
104
config_test.go
|
@ -1,9 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -14,6 +16,108 @@ var (
|
||||||
rpcpassRegexp = regexp.MustCompile("(?m)^rpcpass=.+$")
|
rpcpassRegexp = regexp.MustCompile("(?m)^rpcpass=.+$")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Define a struct "configCmdLineOnly" containing a subset of configuration
|
||||||
|
// parameters which are command-line only. These fields are copied line-by-line
|
||||||
|
// from "config" struct in "config.go", and the field names, types, and tags must
|
||||||
|
// match for the test to work.
|
||||||
|
//
|
||||||
|
type configCmdLineOnly struct {
|
||||||
|
ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"`
|
||||||
|
DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"`
|
||||||
|
DropCfIndex bool `long:"dropcfindex" description:"Deletes the index used for committed filtering (CF) support from the database on start up and then exits."`
|
||||||
|
DropTxIndex bool `long:"droptxindex" description:"Deletes the hash-based transaction index from the database on start up and then exits."`
|
||||||
|
DisableCheckpoints bool `long:"nocheckpoints" description:"Disable built-in checkpoints. Don't do this unless you know what you're doing."`
|
||||||
|
NoWinService bool `long:"nowinservice" description:"Do not start as a background service on Windows -- NOTE: This flag only works on the command line, not in the config file"`
|
||||||
|
DisableStallHandler bool `long:"nostalldetect" description:"Disables the stall handler system for each peer, useful in simnet/regtest integration tests frameworks"`
|
||||||
|
RegressionTest bool `long:"regtest" description:"Use the regression test network"`
|
||||||
|
SimNet bool `long:"simnet" description:"Use the simulation test network"`
|
||||||
|
SigNet bool `long:"signet" description:"Use the signet test network"`
|
||||||
|
SigNetChallenge string `long:"signetchallenge" description:"Connect to a custom signet network defined by this challenge instead of using the global default signet test network -- Can be specified multiple times"`
|
||||||
|
SigNetSeedNode []string `long:"signetseednode" description:"Specify a seed node for the signet network instead of using the global default signet network seed nodes"`
|
||||||
|
ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func fieldEq(f1, f2 reflect.StructField) bool {
|
||||||
|
return (f1.Name == f2.Name) && (f1.Type == f2.Type) && (f1.Tag == f2.Tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSampleConfigFileComplete(t *testing.T) {
|
||||||
|
// find out where the sample config lives
|
||||||
|
_, path, _, ok := runtime.Caller(0)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Failed finding config file path")
|
||||||
|
}
|
||||||
|
sampleConfigFile := filepath.Join(filepath.Dir(path), sampleConfigFilename)
|
||||||
|
|
||||||
|
// Read the sample config file
|
||||||
|
content, err := ioutil.ReadFile(sampleConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed reading sample config file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allFields := reflect.VisibleFields(reflect.TypeOf(config{}))
|
||||||
|
cmdlineFields := reflect.VisibleFields(reflect.TypeOf(configCmdLineOnly{}))
|
||||||
|
|
||||||
|
// Verify cmdlineFields is a subset of allFields.
|
||||||
|
for _, cf := range cmdlineFields {
|
||||||
|
// Check for presence of field "cf" in config struct.
|
||||||
|
var field *reflect.StructField
|
||||||
|
for _, f := range allFields {
|
||||||
|
f := f // new instance of loop var for return
|
||||||
|
if fieldEq(cf, f) {
|
||||||
|
field = &f
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if field == nil {
|
||||||
|
t.Errorf("cmdline field: %s type: %s is not present in type %s",
|
||||||
|
cf.Name, cf.Type, reflect.TypeOf(config{}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify sample config covers all parameters.
|
||||||
|
for _, f := range allFields {
|
||||||
|
longname, ok := f.Tag.Lookup("long")
|
||||||
|
if !ok {
|
||||||
|
// Field has no long-form name, so not eligible for
|
||||||
|
// inclusion in sample config.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for presence of field "f" in our configCmdLineOnly struct.
|
||||||
|
var cmdline *reflect.StructField
|
||||||
|
for _, cf := range cmdlineFields {
|
||||||
|
cf := cf // new instance of loop var for return
|
||||||
|
if fieldEq(cf, f) {
|
||||||
|
cmdline = &cf
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for assignment (<longname>="), or commented assignment ("; <longname>=").
|
||||||
|
pattern := fmt.Sprintf("(?m)^(;\\s*)?%s=.*$", longname)
|
||||||
|
assignment, err := regexp.Compile(pattern)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("config field: %s longname: %s failed compiling regexp (%s): %v",
|
||||||
|
f.Name, longname, pattern, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
assigned := assignment.Match(content)
|
||||||
|
|
||||||
|
// Field "f" must be present in either the sample config (<longname>=X),
|
||||||
|
// or it must be one of the command line only fields, but not both.
|
||||||
|
if !assigned && (cmdline == nil) {
|
||||||
|
t.Errorf("config field: %s longname: %s assignment (%s) should be present in %s",
|
||||||
|
f.Name, longname, assignment, sampleConfigFilename)
|
||||||
|
}
|
||||||
|
if assigned && (cmdline != nil) {
|
||||||
|
t.Errorf("config field: %s longname: %s should not be present in both %s and type %s",
|
||||||
|
f.Name, longname, sampleConfigFilename, reflect.TypeOf(configCmdLineOnly{}).Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCreateDefaultConfigFile(t *testing.T) {
|
func TestCreateDefaultConfigFile(t *testing.T) {
|
||||||
// find out where the sample config lives
|
// find out where the sample config lives
|
||||||
_, path, _, ok := runtime.Caller(0)
|
_, path, _, ok := runtime.Caller(0)
|
||||||
|
|
Loading…
Add table
Reference in a new issue