github.com/avenga/couper@v1.12.2/main_test.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"regexp"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	logrustest "github.com/sirupsen/logrus/hooks/test"
    14  
    15  	"github.com/avenga/couper/config/env"
    16  )
    17  
    18  func Test_realmain(t *testing.T) {
    19  	localHook := &logrustest.Hook{}
    20  	testHook = localHook
    21  
    22  	base := "server/testdata/settings"
    23  
    24  	tests := []struct {
    25  		name    string
    26  		args    []string
    27  		envs    []string
    28  		wantLog string
    29  		want    int
    30  	}{
    31  		{"verify", []string{"couper", "verify", "-f", base + "/10_couper.hcl"}, nil, `10_couper.hcl:2,3-6: Unsupported block type; Blocks of type \"foo\" are not expected here.`, 1},
    32  		{"verify w/o server", []string{"couper", "verify", "-f", base + "/11_couper.hcl"}, nil, `configuration error: missing 'server' block"`, 1},
    33  		{"verify unique map-attr keys", []string{"couper", "verify", "-f", base + "/12_couper.hcl"}, nil, `12_couper.hcl:5,28-8,6: key in an attribute must be unique: 'test-key'; Key must be unique for test-key.`, 1},
    34  		{"common log format & info log level /wo file", []string{"couper", "run"}, nil, `level=error msg="stat %s/couper.hcl: no such file or directory" build=dev`, 1},
    35  		{"common log format via env /wo file", []string{"couper", "run", "-log-format", "json"}, []string{"COUPER_LOG_FORMAT=common"}, `level=error msg="stat %s/couper.hcl: no such file or directory" build=dev`, 1},
    36  		{"info log level via env /wo file", []string{"couper", "run", "-log-level", "debug"}, []string{"COUPER_LOG_LEVEL=info"}, `level=error msg="stat %s/couper.hcl: no such file or directory" build=dev`, 1},
    37  		{"json log format /wo file", []string{"couper", "run", "-log-format", "json"}, nil, `{"build":"dev","level":"error","message":"stat %s/couper.hcl: no such file or directory"`, 1},
    38  		{"json log format via env /wo file", []string{"couper", "run"}, []string{"COUPER_LOG_FORMAT=json"}, `{"build":"dev","level":"error","message":"stat %s/couper.hcl: no such file or directory"`, 1},
    39  		{"non-existent log level /wo file", []string{"couper", "run", "-log-level", "test"}, nil, `level=error msg="stat %s/couper.hcl: no such file or directory" build=dev`, 1},
    40  		{"non-existent log level via env /wo file", []string{"couper", "run"}, []string{"COUPER_LOG_LEVEL=test"}, `level=error msg="stat %s/couper.hcl: no such file or directory" build=dev`, 1},
    41  		{"common log format & info log level /w file", []string{"couper", "run", "-f", base + "/log_default.hcl"}, nil, `level=error msg="configuration error: missing 'server' block" build=dev`, 1},
    42  		{"common log format via env /w file", []string{"couper", "run", "-f", base + "/log_altered.hcl"}, []string{"COUPER_LOG_FORMAT=common"}, `level=error msg="configuration error: missing 'server' block" build=dev`, 1},
    43  		{"info log level via env /w file", []string{"couper", "run", "-f", base + "/log_default.hcl"}, []string{"COUPER_LOG_LEVEL=info"}, `level=error msg="configuration error: missing 'server' block" build=dev`, 1},
    44  		// TODO: format from file currently not possible due to the server error
    45  		{"json log format via env /w file", []string{"couper", "run", "-f", base + "/log_default.hcl"}, []string{"COUPER_LOG_FORMAT=json"}, `{"build":"dev","level":"error","message":"configuration error: missing 'server' block"`, 1},
    46  		{"non-existent log level via env /w file", []string{"couper", "run", "-f", base + "/log_altered.hcl"}, []string{"COUPER_LOG_LEVEL=test"}, `level=error msg="configuration error: missing 'server' block" build=dev`, 1},
    47  		{"-f w/o file", []string{"couper", "run", "-f"}, nil, `level=error msg="flag needs an argument: -f" build=dev`, 1},
    48  		{"path from env", []string{"couper", "run", "-f", base + "/path_from_env.hcl"}, nil, `level=error msg="configuration error: token: jwt key: read error: open %s/public.pem: no such file or directory" build=dev`, 1},
    49  		{"path from env /w missing key", []string{"couper", "run", "-f", "public/couper.hcl", "-f", base + "/no_key_from_env.hcl"}, nil, "", 0},
    50  		{"empty string in allowed_methods in endpoint", []string{"couper", "run", "-f", base + "/13_couper.hcl"}, nil, `level=error msg="%s/13_couper.hcl:3,5-27: method contains invalid character(s); " build=dev`, 1},
    51  		{"invalid method in allowed_methods in endpoint", []string{"couper", "run", "-f", base + "/14_couper.hcl"}, nil, `level=error msg="%s/14_couper.hcl:3,5-35: method contains invalid character(s); " build=dev`, 1},
    52  		{"invalid method in allowed_methods in api", []string{"couper", "run", "-f", base + "/15_couper.hcl"}, nil, `level=error msg="%s/15_couper.hcl:3,5-35: method contains invalid character(s); " build=dev`, 1},
    53  		{"rate_limit block in anonymous backend", []string{"couper", "run", "-f", base + "/17_couper.hcl"}, nil, `level=error msg="configuration error: anonymous_3_11: anonymous backend 'anonymous_3_11' cannot define 'beta_rate_limit' block(s)" build=dev`, 1},
    54  		{"non-string proxy reference", []string{"couper", "run", "-f", base + "/19_couper.hcl"}, nil, `level=error msg="%s/19_couper.hcl:3,13-14: proxy must evaluate to string; " build=dev`, 1},
    55  		{"proxy reference does not exist", []string{"couper", "run", "-f", base + "/20_couper.hcl"}, nil, `level=error msg="%s/20_couper.hcl:3,14-17: referenced proxy \"foo\" is not defined; " build=dev`, 1},
    56  		{"circular backend references", []string{"couper", "run", "-f", base + "/21_couper.hcl"}, nil, `level=error msg="configuration error: <nil>: configuration error; circular reference:`, 1},
    57  	}
    58  	for _, tt := range tests {
    59  		t.Run(tt.name, func(subT *testing.T) {
    60  			if len(tt.envs) > 0 {
    61  				env.SetTestOsEnviron(func() []string {
    62  					return tt.envs
    63  				})
    64  			}
    65  
    66  			ctx, cancel := context.WithCancel(context.Background())
    67  			time.AfterFunc(time.Second, cancel)
    68  
    69  			if got := realmain(ctx, tt.args); got != tt.want {
    70  				subT.Errorf("realmain() = %v, want %v", got, tt.want)
    71  			}
    72  			env.OsEnviron = os.Environ
    73  
    74  			currWD, _ := os.Getwd()
    75  
    76  			entry := localHook.LastEntry()
    77  			if entry == nil {
    78  				subT.Error("missing log entry")
    79  				return
    80  			}
    81  			entryStr, _ := entry.String()
    82  			if tt.wantLog == "" && subT.Failed() {
    83  				println(entryStr)
    84  			}
    85  
    86  			wantLog := tt.wantLog
    87  			if strings.Contains(wantLog, `msg="%s/`) || strings.Contains(wantLog, `open %s/`) {
    88  				wantLog = fmt.Sprintf(wantLog, filepath.Join(currWD, base))
    89  			} else if strings.Contains(wantLog, `stat %s/`) {
    90  				wantLog = fmt.Sprintf(wantLog, currWD)
    91  			}
    92  
    93  			if wantLog != "" && !strings.Contains(entryStr, wantLog) {
    94  				if strings.Contains(wantLog, `failed to load configuration:`) {
    95  					re := regexp.MustCompile(wantLog)
    96  
    97  					if !re.MatchString(entryStr) {
    98  						subT.Errorf("\nwant:\t%s\ngot:\t%s\n", wantLog, entryStr)
    99  					}
   100  				} else {
   101  					subT.Errorf("\nwant:\t%s\ngot:\t%s\n", wantLog, entryStr)
   102  				}
   103  			}
   104  		})
   105  	}
   106  }