git » gofer » commit c853cb7

config: Make marshalling output usable

author Alberto Bertogli
2020-06-13 11:44:17 UTC
committer Alberto Bertogli
2020-06-13 12:14:28 UTC
parent d5eb1fec7b9ffe0f2a06217305410d0818375577

config: Make marshalling output usable

This patch makes the config marshalling readable and usable, by
implementing marshallers that were missing, and adding some annotations
to omit empty fields to make the output more readable.

The tests are also extended to validate this.

config/config.go +38 -26
test/test.sh +33 -12

diff --git a/config/config.go b/config/config.go
index 6fe1ece..0dd84a2 100644
--- a/config/config.go
+++ b/config/config.go
@@ -11,58 +11,57 @@ import (
 )
 
 type Config struct {
-	ControlAddr string `yaml:"control_addr"`
+	ControlAddr string `yaml:"control_addr,omitempty"`
 
 	// Map address -> config.
-	HTTP  map[string]HTTP
-	HTTPS map[string]HTTPS
-	Raw   map[string]Raw
+	HTTP  map[string]HTTP  `yaml:",omitempty"`
+	HTTPS map[string]HTTPS `yaml:",omitempty"`
+	Raw   map[string]Raw   `yaml:",omitempty"`
 
-	ReqLog map[string]ReqLog
+	ReqLog map[string]ReqLog `yaml:",omitempty"`
 }
 
 type HTTP struct {
 	Routes map[string]Route
 
-	Auth map[string]string
+	Auth map[string]string `yaml:",omitempty"`
 
-	SetHeader map[string]map[string]string
+	SetHeader map[string]map[string]string `yaml:",omitempty"`
 
-	ReqLog map[string]string
+	ReqLog map[string]string `yaml:",omitempty"`
 }
 
 type HTTPS struct {
 	HTTP  `yaml:",inline"`
-	Certs string
+	Certs string `yaml:",omitempty"`
 }
 
 type Route struct {
-	Dir      string
-	File     string
-	Proxy    *URL
-	Redirect *URL
-	CGI      []string
-	Status   int
-	DirOpts  DirOpts
+	Dir      string   `yaml:",omitempty"`
+	File     string   `yaml:",omitempty"`
+	Proxy    *URL     `yaml:",omitempty"`
+	Redirect *URL     `yaml:",omitempty"`
+	CGI      []string `yaml:",omitempty"`
+	Status   int      `yaml:",omitempty"`
+	DirOpts  DirOpts  `yaml:",omitempty"`
 }
 
 type DirOpts struct {
-	Listing map[string]bool
-	Exclude []Regexp
+	Listing map[string]bool `yaml:",omitempty"`
+	Exclude []Regexp        `yaml:",omitempty"`
 }
 
 type Raw struct {
-	Addr   string
-	Certs  string
-	To     string
-	ToTLS  bool `yaml:"to_tls"`
-	ReqLog string
+	Certs  string `yaml:",omitempty"`
+	To     string `yaml:",omitempty"`
+	ToTLS  bool   `yaml:"to_tls,omitempty"`
+	ReqLog string `yaml:",omitempty"`
 }
 
 type ReqLog struct {
-	File    string
-	BufSize int
-	Format  string
+	File    string `yaml:",omitempty"`
+	BufSize int    `yaml:",omitempty"`
+	Format  string `yaml:",omitempty"`
 }
 
 func (c Config) String() string {
@@ -160,6 +159,7 @@ func LoadString(contents string) (*Config, error) {
 
 // Wrapper to simplify regexp in configuration.
 type Regexp struct {
+	orig string
 	*regexp.Regexp
 }
 
@@ -174,10 +174,15 @@ func (re *Regexp) UnmarshalYAML(unmarshal func(interface{}) error) error {
 		return err
 	}
 
+	re.orig = s
 	re.Regexp = rx
 	return nil
 }
 
+func (re Regexp) MarshalYAML() (interface{}, error) {
+	return re.orig, nil
+}
+
 // Wrapper to simplify URLs in configuration.
 type URL url.URL
 
@@ -196,6 +201,13 @@ func (u *URL) UnmarshalYAML(unmarshal func(interface{}) error) error {
 	return nil
 }
 
+func (u *URL) MarshalYAML() (interface{}, error) {
+	if u == nil {
+		return "", nil
+	}
+	return u.String(), nil
+}
+
 func (u *URL) URL() url.URL {
 	return url.URL(*u)
 }
diff --git a/test/test.sh b/test/test.sh
index 22659f5..89a0680 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -28,19 +28,26 @@ else
 fi
 ( cd util; go build exp.go )
 
-
-# Run gofer in the background (sets $PID to its process id).
-function gofer() {
+function set_cover() {
 	# Set the coverage arguments each time, as we don't want the different
 	# runs to override the generated profile.
 	if [ "$COVER_DIR" != "" ]; then
 		COVER_ARGS="-test.run=^TestRunMain$ \
 			-test.coverprofile=$COVER_DIR/it-`date +%s.%N`.out"
 	fi
+}
 
-	$SYSTEMD_ACTIVATE ../gofer $COVER_ARGS \
-		-v=3 \
-		"$@" >> .out.log 2>&1 &
+function gofer() {
+	set_cover
+	../gofer $COVER_ARGS -v=3  "$@"  >> .out.log 2>&1
+}
+
+# Run gofer in the background (sets $PID to its process id).
+function gofer_bg() {
+	# Duplicate gofer() because if we put the function in the background,
+	# the pid will be of bash, not the subprocess.
+	set_cover
+	../gofer $COVER_ARGS -v=3  "$@"  >> .out.log 2>&1 &
 	PID=$!
 }
 
@@ -62,10 +69,6 @@ function generate_certs() {
 	)
 }
 
-function curl() {
-	curl --cacert ".certs/localhost/fullchain.pem" "$@"
-}
-
 function exp() {
 	if [ "$V" == "1" ]; then
 		VF="-v"
@@ -99,13 +102,13 @@ echo "## Setup"
 rm -f .01-fe.requests.log .01-be.requests.log
 
 # Launch the backend serving static files and CGI.
-gofer -logfile=.01-be.log -configfile=01-be.yaml
+gofer_bg -logfile=.01-be.log -configfile=01-be.yaml
 BE_PID=$PID
 wait_until_ready 8450
 
 # Launch the test instance.
 generate_certs
-gofer -logfile=.01-fe.log -configfile=01-fe.yaml
+gofer_bg -logfile=.01-fe.log -configfile=01-fe.yaml
 FE_PID=$PID
 wait_until_ready 8441  # http
 wait_until_ready 8442  # https
@@ -119,6 +122,21 @@ snoop
 #
 echo "## Tests"
 
+echo "### Config"
+
+curl -sS "http://127.0.0.1:8440/debug/config" > .fe-debug-conf
+if ! gofer -configfile=.fe-debug-conf -configcheck; then
+	echo "Failed to parse FE config from monitoring output"
+	exit 1
+fi
+
+curl -sS "http://127.0.0.1:8459/debug/config" > .be-debug-conf
+if ! gofer -configfile=.be-debug-conf -configcheck; then
+	echo "Failed to parse BE config from monitoring output"
+	exit 1
+fi
+
+
 # Common tests, for both servers.
 for base in \
 	http://localhost:8441 \
@@ -244,6 +262,9 @@ exp https://localhost:8442/dar/ -bodyre '<a href="%C3%B1aca">ñaca</a>'
 # misconfiguration.
 exp http://localhost:8450/file/second -body "tracañaca\n"
 
+# Check that the debug / handler only serves /.
+exp "http://127.0.0.1:8459/notexists" -status 404
+
 
 echo "### Raw proxying"
 exp http://localhost:8445/file -body "ñaca\n"