From 72acff3afbbbd6d977710961801216b470937219 Mon Sep 17 00:00:00 2001 From: Marcel Ludwig Date: Mon, 21 Nov 2022 16:02:47 +0100 Subject: [PATCH 01/11] merge without value eval --- config/configload/merge.go | 42 +++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/config/configload/merge.go b/config/configload/merge.go index 311632b1b..60d242fec 100644 --- a/config/configload/merge.go +++ b/config/configload/merge.go @@ -563,24 +563,24 @@ func mergeDefinitions(bodies []*hclsyntax.Body) (*hclsyntax.Block, map[string]*h func mergeDefaults(bodies []*hclsyntax.Body) (*hclsyntax.Block, error) { attrs := make(hclsyntax.Attributes) - envVars := make(map[string]cty.Value) + envVars := make(map[string]hcl.Expression) for _, body := range bodies { for _, block := range body.Blocks { if block.Type == defaults { for name, attr := range block.Body.Attributes { if name == environmentVars { - v, err := eval.Value(nil, attr.Expr) - if err != nil { - return nil, err + expObj, ok := attr.Expr.(*hclsyntax.ObjectConsExpr) + if !ok { + r := attr.Expr.Range() + return nil, newDiagErr(&r, fmt.Sprintf("error: %s must be object type", environmentVars)) } - for k, value := range v.AsValueMap() { - if value.Type() != cty.String { - return nil, fmt.Errorf("value in 'environment_variables' is not a string") - } - - envVars[k] = value + for _, kv := range expObj.ExprMap() { + k := kv.Key.(*hclsyntax.ObjectConsKeyExpr) + uk := k.UnwrapExpression().(*hclsyntax.ScopeTraversalExpr) + keyName := uk.Traversal.RootName() + envVars[keyName] = kv.Value } } else { attrs[name] = attr // Currently not used @@ -591,20 +591,34 @@ func mergeDefaults(bodies []*hclsyntax.Body) (*hclsyntax.Block, error) { } if len(envVars) > 0 { + items := make([]hclsyntax.ObjectConsItem, 0) + for k, v := range envVars { + items = append(items, hclsyntax.ObjectConsItem{ + KeyExpr: &hclsyntax.ObjectConsKeyExpr{ + Wrapped: &hclsyntax.ScopeTraversalExpr{ + Traversal: hcl.Traversal{hcl.TraverseRoot{Name: k}}, + }, + ForceNonLiteral: false, + }, + ValueExpr: v.(hclsyntax.Expression), + }) + } + attrs[environmentVars] = &hclsyntax.Attribute{ Name: environmentVars, - Expr: &hclsyntax.LiteralValueExpr{ - Val: cty.MapVal(envVars), + Expr: &hclsyntax.ObjectConsExpr{ + Items: items, }, } } - return &hclsyntax.Block{ + defaultsBlock := &hclsyntax.Block{ Type: defaults, Body: &hclsyntax.Body{ Attributes: attrs, }, - }, nil + } + return defaultsBlock, nil } func mergeSettings(bodies []*hclsyntax.Body) *hclsyntax.Block { From 8b87e514ebf3ae3b4a902f3d07ba01d1a66905d2 Mon Sep 17 00:00:00 2001 From: Marcel Ludwig Date: Wed, 23 Nov 2022 13:22:47 +0100 Subject: [PATCH 02/11] evaluate twice and simplify code --- CHANGELOG.md | 1 + config/configload/helper.go | 11 ++---- config/configload/load.go | 24 +++++++------ server/http_integration_test.go | 35 +++++++++++++++++++ server/testdata/integration/env/02_couper.hcl | 16 +++++++++ 5 files changed, 68 insertions(+), 19 deletions(-) create mode 100644 server/testdata/integration/env/02_couper.hcl diff --git a/CHANGELOG.md b/CHANGELOG.md index 1694cdd9c..a8fd0d5f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Unreleased changes are available as `avenga/couper:edge` container. * **Changed** * Replaced the JWT library because the former library was no longer maintained ([#612](https://github.com/avenga/couper/pull/612)) * Routing and [OpenAPI validation](https://docs.couper.io/configuration/block/openapi) now use gorilla/mux ([#614](https://github.com/avenga/couper/pull/614)) + * Usage of `env` variables and functions is now possible for the `defaults` block ([#630](https://github.com/avenga/couper/pull/630)) * **Fixed** * Aligned the evaluation of [`beta_oauth2`](https://docs.couper.io/configuration/block/oauth2_ac)/[`oidc`](https://docs.couper.io/configuration/block/oidc) `redirect_uri` to `saml` `sp_acs_url` ([#589](https://github.com/avenga/couper/pull/589)) diff --git a/config/configload/helper.go b/config/configload/helper.go index 2dfe71829..e832d22c1 100644 --- a/config/configload/helper.go +++ b/config/configload/helper.go @@ -23,16 +23,11 @@ type helper struct { } // newHelper creates a container with some methods to keep things simple here and there. -func newHelper(body hcl.Body, src [][]byte, environment string) (*helper, error) { - defaultsBlock := &config.DefaultsBlock{} - if diags := gohcl.DecodeBody(body, nil, defaultsBlock); diags.HasErrors() { - return nil, diags - } - +func newHelper(body hcl.Body) (*helper, error) { couperConfig := &config.Couper{ - Context: eval.NewContext(src, defaultsBlock.Defaults, environment), + Context: evalContext, Definitions: &config.Definitions{}, - Defaults: defaultsBlock.Defaults, + Defaults: defaultsConfig, Settings: config.NewDefaultSettings(), } diff --git a/config/configload/load.go b/config/configload/load.go index c4b781561..191514ea6 100644 --- a/config/configload/load.go +++ b/config/configload/load.go @@ -75,14 +75,16 @@ func init() { func updateContext(body hcl.Body, srcBytes [][]byte, environment string) hcl.Diagnostics { defaultsBlock := &config.DefaultsBlock{} - if diags := gohcl.DecodeBody(body, nil, defaultsBlock); diags.HasErrors() { + // defaultsCtx is a temporary one to allow env variables and functions for defaults {} + defaultsCtx := eval.NewContext(srcBytes, nil, environment).HCLContext() + if diags := gohcl.DecodeBody(body, defaultsCtx, defaultsBlock); diags.HasErrors() { return diags } + defaultsConfig = defaultsBlock.Defaults // global assign // We need the "envContext" to be able to resolve absolute paths in the config. - defaultsConfig = defaultsBlock.Defaults evalContext = eval.NewContext(srcBytes, defaultsConfig, environment) - envContext = evalContext.HCLContext() + envContext = evalContext.HCLContext() // global assign return nil } @@ -179,7 +181,7 @@ func bodiesToConfig(parsedBodies []*hclsyntax.Body, srcBytes [][]byte, env strin return nil, err } - conf, err := LoadConfig(configBody, srcBytes, env) + conf, err := LoadConfig(configBody) if err != nil { return nil, err } @@ -206,12 +208,12 @@ func LoadFiles(filesList []string, env string) (*config.Couper, error) { if env == "" { settingsBlock := mergeSettings(parsedBodies) - settings := &config.Settings{} - if diags := gohcl.DecodeBody(settingsBlock.Body, nil, settings); diags.HasErrors() { + confSettings := &config.Settings{} + if diags := gohcl.DecodeBody(settingsBlock.Body, nil, confSettings); diags.HasErrors() { return nil, diags } - if settings.Environment != "" { - return LoadFiles(filesList, settings.Environment) + if confSettings.Environment != "" { + return LoadFiles(filesList, confSettings.Environment) } } @@ -266,17 +268,17 @@ func LoadBytes(src []byte, filename string) (*config.Couper, error) { return nil, err } - return LoadConfig(hclBody, [][]byte{src}, "") + return LoadConfig(hclBody) } -func LoadConfig(body *hclsyntax.Body, src [][]byte, environment string) (*config.Couper, error) { +func LoadConfig(body *hclsyntax.Body) (*config.Couper, error) { var err error if diags := ValidateConfigSchema(body, &config.Couper{}); diags.HasErrors() { return nil, diags } - helper, err := newHelper(body, src, environment) + helper, err := newHelper(body) if err != nil { return nil, err } diff --git a/server/http_integration_test.go b/server/http_integration_test.go index 7fc3854b3..567cf0c2b 100644 --- a/server/http_integration_test.go +++ b/server/http_integration_test.go @@ -518,6 +518,41 @@ func TestHTTPServer_EnvVars(t *testing.T) { } } +func TestHTTPServer_DefaultEnvVars(t *testing.T) { + helper := test.New(t) + client := newClient() + + env.SetTestOsEnviron(func() []string { + return []string{"VALUE_4=value4"} + }) + defer env.SetTestOsEnviron(os.Environ) + + shutdown, hook := newCouper("testdata/integration/env/02_couper.hcl", test.New(t)) + defer shutdown() + + hook.Reset() + + req, err := http.NewRequest(http.MethodGet, "http://example.com:8080", nil) + helper.Must(err) + + res, err := client.Do(req) + helper.Must(err) + + if res.StatusCode != http.StatusOK { + t.Errorf("expected 200, got %d", res.StatusCode) + } + + b, err := io.ReadAll(res.Body) + helper.Must(err) + + var result []string + helper.Must(json.Unmarshal(b, &result)) + + if diff := cmp.Diff(result, []string{"value1", "", "default_value_3", "value4"}); diff != "" { + t.Error(diff) + } +} + func TestHTTPServer_XFHHeader(t *testing.T) { client := newClient() diff --git a/server/testdata/integration/env/02_couper.hcl b/server/testdata/integration/env/02_couper.hcl new file mode 100644 index 000000000..5d41f0255 --- /dev/null +++ b/server/testdata/integration/env/02_couper.hcl @@ -0,0 +1,16 @@ +server { + endpoint "/" { + response { + json_body = [env.KEY1, env.KEY2, env.KEY3, env.KEY4] + } + } +} + +defaults { + environment_variables = { + KEY1 = "value1" + KEY2 = env.VALUE_2 + KEY3 = default(env.VALUE_3, "default_value_3") + KEY4 = env.VALUE_4 + } +} From 6f4821259c7c4df3fbeea63bf3bf5e024bc6c638 Mon Sep 17 00:00:00 2001 From: Marcel Ludwig Date: Wed, 23 Nov 2022 13:38:05 +0100 Subject: [PATCH 03/11] fixup test; method signature also missing bodiesToConfig call for LoadBytes --- config/configload/helper.go | 3 +-- config/configload/load.go | 2 +- eval/context_test.go | 5 ++--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/config/configload/helper.go b/config/configload/helper.go index e832d22c1..7adf2fd1f 100644 --- a/config/configload/helper.go +++ b/config/configload/helper.go @@ -12,7 +12,6 @@ import ( hclbody "github.com/avenga/couper/config/body" "github.com/avenga/couper/config/sequence" "github.com/avenga/couper/errors" - "github.com/avenga/couper/eval" ) type helper struct { @@ -40,7 +39,7 @@ func newHelper(body hcl.Body) (*helper, error) { return &helper{ config: couperConfig, content: content, - context: couperConfig.Context.(*eval.Context).HCLContext(), + context: evalContext.HCLContext(), defsBackends: make(map[string]*hclsyntax.Body), }, nil } diff --git a/config/configload/load.go b/config/configload/load.go index 191514ea6..8ff2ddf59 100644 --- a/config/configload/load.go +++ b/config/configload/load.go @@ -268,7 +268,7 @@ func LoadBytes(src []byte, filename string) (*config.Couper, error) { return nil, err } - return LoadConfig(hclBody) + return bodiesToConfig([]*hclsyntax.Body{hclBody}, [][]byte{src}, "") } func LoadConfig(body *hclsyntax.Body) (*config.Couper, error) { diff --git a/eval/context_test.go b/eval/context_test.go index db38cd1ad..8cdf4da31 100644 --- a/eval/context_test.go +++ b/eval/context_test.go @@ -236,14 +236,13 @@ func TestCouperVariables(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(subT *testing.T) { - bytes := []byte(tt.hcl) - hclBody, err := parser.Load(bytes, "couper.hcl") + hclBody, err := parser.Load([]byte(tt.hcl), "couper.hcl") if err != nil { subT.Error(err) return } - cf, err := configload.LoadConfig(hclBody, [][]byte{bytes}, tt.env) + cf, err := configload.LoadConfig(hclBody) if err != nil { subT.Error(err) return From 114d950562fc75d364a393bf00decd43c47582f9 Mon Sep 17 00:00:00 2001 From: Marcel Ludwig Date: Wed, 23 Nov 2022 13:47:59 +0100 Subject: [PATCH 04/11] fixup test; use loadBytes --- eval/context_test.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/eval/context_test.go b/eval/context_test.go index 8cdf4da31..5be0a91fa 100644 --- a/eval/context_test.go +++ b/eval/context_test.go @@ -13,7 +13,6 @@ import ( "github.com/zclconf/go-cty/cty" "github.com/avenga/couper/config/configload" - "github.com/avenga/couper/config/parser" "github.com/avenga/couper/config/request" "github.com/avenga/couper/eval" "github.com/avenga/couper/internal/seetie" @@ -191,7 +190,8 @@ func TestDefaultEnvVariables(t *testing.T) { t.Run(tt.name, func(subT *testing.T) { cf, err := configload.LoadBytes([]byte(tt.hcl), "couper.hcl") if err != nil { - subT.Fatal(err) + subT.Error(err) + return } hclContext := cf.Context.(*eval.Context).HCLContext() @@ -236,13 +236,7 @@ func TestCouperVariables(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(subT *testing.T) { - hclBody, err := parser.Load([]byte(tt.hcl), "couper.hcl") - if err != nil { - subT.Error(err) - return - } - - cf, err := configload.LoadConfig(hclBody) + cf, err := configload.LoadBytes([]byte(tt.hcl), "couper.hcl") if err != nil { subT.Error(err) return From 7d99fff45da061fdf8adaf3dc421a60d54660860 Mon Sep 17 00:00:00 2001 From: Marcel Ludwig Date: Wed, 23 Nov 2022 21:02:22 +0100 Subject: [PATCH 05/11] fix context test, pass env --- config/configload/load.go | 6 +++++- eval/context_test.go | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/config/configload/load.go b/config/configload/load.go index 8ff2ddf59..22ac74812 100644 --- a/config/configload/load.go +++ b/config/configload/load.go @@ -259,6 +259,10 @@ func loadTestContents(tcs []testContent) (*config.Couper, error) { } func LoadBytes(src []byte, filename string) (*config.Couper, error) { + return LoadBytesEnv(src, filename, "") +} + +func LoadBytesEnv(src []byte, filename, env string) (*config.Couper, error) { hclBody, err := parser.Load(src, filename) if err != nil { return nil, err @@ -268,7 +272,7 @@ func LoadBytes(src []byte, filename string) (*config.Couper, error) { return nil, err } - return bodiesToConfig([]*hclsyntax.Body{hclBody}, [][]byte{src}, "") + return bodiesToConfig([]*hclsyntax.Body{hclBody}, [][]byte{src}, env) } func LoadConfig(body *hclsyntax.Body) (*config.Couper, error) { diff --git a/eval/context_test.go b/eval/context_test.go index 5be0a91fa..2e4c1011a 100644 --- a/eval/context_test.go +++ b/eval/context_test.go @@ -236,7 +236,7 @@ func TestCouperVariables(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(subT *testing.T) { - cf, err := configload.LoadBytes([]byte(tt.hcl), "couper.hcl") + cf, err := configload.LoadBytesEnv([]byte(tt.hcl), "couper.hcl", tt.env) if err != nil { subT.Error(err) return From d9a68cdcfcd0036e1bfa4904309c01412f99b3eb Mon Sep 17 00:00:00 2001 From: Marcel Ludwig Date: Wed, 23 Nov 2022 21:38:43 +0100 Subject: [PATCH 06/11] handle different key expression types --- config/configload/merge.go | 51 ++++++++++++------- server/http_integration_test.go | 2 +- server/testdata/integration/env/02_couper.hcl | 3 +- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/config/configload/merge.go b/config/configload/merge.go index 60d242fec..07327c368 100644 --- a/config/configload/merge.go +++ b/config/configload/merge.go @@ -563,28 +563,45 @@ func mergeDefinitions(bodies []*hclsyntax.Body) (*hclsyntax.Block, map[string]*h func mergeDefaults(bodies []*hclsyntax.Body) (*hclsyntax.Block, error) { attrs := make(hclsyntax.Attributes) - envVars := make(map[string]hcl.Expression) + envVars := make(map[string]hclsyntax.Expression) for _, body := range bodies { for _, block := range body.Blocks { - if block.Type == defaults { - for name, attr := range block.Body.Attributes { - if name == environmentVars { - expObj, ok := attr.Expr.(*hclsyntax.ObjectConsExpr) - if !ok { - r := attr.Expr.Range() - return nil, newDiagErr(&r, fmt.Sprintf("error: %s must be object type", environmentVars)) - } + if block.Type != defaults { + continue + } + + for name, attr := range block.Body.Attributes { + if name != environmentVars { + attrs[name] = attr // Currently not used + continue + } + + expObj, ok := attr.Expr.(*hclsyntax.ObjectConsExpr) + if !ok { + r := attr.Expr.Range() + return nil, newDiagErr(&r, fmt.Sprintf("%s must be object type", environmentVars)) + } - for _, kv := range expObj.ExprMap() { - k := kv.Key.(*hclsyntax.ObjectConsKeyExpr) - uk := k.UnwrapExpression().(*hclsyntax.ScopeTraversalExpr) - keyName := uk.Traversal.RootName() - envVars[keyName] = kv.Value + for _, item := range expObj.Items { + k := item.KeyExpr.(*hclsyntax.ObjectConsKeyExpr) + r := item.KeyExpr.Range() + var keyName string + switch exp := k.Wrapped.(type) { + case *hclsyntax.ScopeTraversalExpr: + keyName = exp.Traversal.RootName() + case *hclsyntax.TemplateExpr: + if !exp.IsStringLiteral() { + return nil, newDiagErr(&r, "unsupported key template expression") } - } else { - attrs[name] = attr // Currently not used + v, _ := exp.Value(nil) + keyName = v.AsString() + default: + r := item.KeyExpr.Range() + return nil, newDiagErr(&r, "unsupported key expression") } + + envVars[keyName] = item.ValueExpr } } } @@ -600,7 +617,7 @@ func mergeDefaults(bodies []*hclsyntax.Body) (*hclsyntax.Block, error) { }, ForceNonLiteral: false, }, - ValueExpr: v.(hclsyntax.Expression), + ValueExpr: v, }) } diff --git a/server/http_integration_test.go b/server/http_integration_test.go index 567cf0c2b..b6af7db5a 100644 --- a/server/http_integration_test.go +++ b/server/http_integration_test.go @@ -548,7 +548,7 @@ func TestHTTPServer_DefaultEnvVars(t *testing.T) { var result []string helper.Must(json.Unmarshal(b, &result)) - if diff := cmp.Diff(result, []string{"value1", "", "default_value_3", "value4"}); diff != "" { + if diff := cmp.Diff(result, []string{"value1", "", "default_value_3", "value4", "value5"}); diff != "" { t.Error(diff) } } diff --git a/server/testdata/integration/env/02_couper.hcl b/server/testdata/integration/env/02_couper.hcl index 5d41f0255..93ff7348c 100644 --- a/server/testdata/integration/env/02_couper.hcl +++ b/server/testdata/integration/env/02_couper.hcl @@ -1,7 +1,7 @@ server { endpoint "/" { response { - json_body = [env.KEY1, env.KEY2, env.KEY3, env.KEY4] + json_body = [env.KEY1, env.KEY2, env.KEY3, env.KEY4, env.KEY5] } } } @@ -12,5 +12,6 @@ defaults { KEY2 = env.VALUE_2 KEY3 = default(env.VALUE_3, "default_value_3") KEY4 = env.VALUE_4 + "KEY5" = "value5" } } From d3eccb4e84baf468608ab285e8179af96d224feb Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Thu, 24 Nov 2022 10:55:59 +0100 Subject: [PATCH 07/11] restrict ScopeTraversalExpr to identifier --- config/configload/merge.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/configload/merge.go b/config/configload/merge.go index 07327c368..27d1b4055 100644 --- a/config/configload/merge.go +++ b/config/configload/merge.go @@ -589,6 +589,9 @@ func mergeDefaults(bodies []*hclsyntax.Body) (*hclsyntax.Block, error) { var keyName string switch exp := k.Wrapped.(type) { case *hclsyntax.ScopeTraversalExpr: + if len(exp.Traversal) > 1 { + return nil, newDiagErr(&r, "unsupported key scope traversal expression") + } keyName = exp.Traversal.RootName() case *hclsyntax.TemplateExpr: if !exp.IsStringLiteral() { From 148b186a57d356b70a24f6839bfb8fd84301f432 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Thu, 24 Nov 2022 10:57:26 +0100 Subject: [PATCH 08/11] Documented key restrictions --- config/defaults.go | 2 +- docs/website/content/2.configuration/4.block/defaults.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/defaults.go b/config/defaults.go index 904b543fa..164f6ad19 100644 --- a/config/defaults.go +++ b/config/defaults.go @@ -5,7 +5,7 @@ import "github.com/hashicorp/hcl/v2" type DefaultEnvVars map[string]string type Defaults struct { - EnvironmentVariables DefaultEnvVars `hcl:"environment_variables,optional" docs:"One or more environment variable assignments"` + EnvironmentVariables DefaultEnvVars `hcl:"environment_variables,optional" docs:"One or more environment variable assignments. Keys must be either identifiers or simple string expressions."` } type DefaultsBlock struct { diff --git a/docs/website/content/2.configuration/4.block/defaults.md b/docs/website/content/2.configuration/4.block/defaults.md index 9a8f4fe82..05738ffb2 100644 --- a/docs/website/content/2.configuration/4.block/defaults.md +++ b/docs/website/content/2.configuration/4.block/defaults.md @@ -12,7 +12,7 @@ The `defaults` block lets you define default values. values: [ { "default": "", - "description": "One or more environment variable assignments", + "description": "One or more environment variable assignments. Keys must be either identifiers or simple string expressions.", "name": "environment_variables", "type": "object" } From b5d576540eb8502f039ccf59df17b8a65ebff449 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Thu, 24 Nov 2022 11:39:23 +0100 Subject: [PATCH 09/11] fixed TestHTTPServer_ServeHTTP_Files2 --- server/http_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/http_test.go b/server/http_test.go index 4399ee8f0..cf34d2637 100644 --- a/server/http_test.go +++ b/server/http_test.go @@ -176,7 +176,7 @@ func TestHTTPServer_ServeHTTP_Files2(t *testing.T) { helper.Must(err) error404Content := []byte("

route not found error: My custom error template

") - spaContent, err := os.ReadFile(conf.Servers[0].SPAs[0].BootstrapFile) + spaContent, err := os.ReadFile(conf.Servers[0].SPAs[1].BootstrapFile) helper.Must(err) tmpStoreCh := make(chan struct{}) From 29e546c7c812a525ec2b40393f225430138b5e42 Mon Sep 17 00:00:00 2001 From: Marcel Ludwig Date: Thu, 24 Nov 2022 11:40:40 +0100 Subject: [PATCH 10/11] Fixup explicit expectation content --- server/http_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/http_test.go b/server/http_test.go index cf34d2637..f56508657 100644 --- a/server/http_test.go +++ b/server/http_test.go @@ -176,8 +176,7 @@ func TestHTTPServer_ServeHTTP_Files2(t *testing.T) { helper.Must(err) error404Content := []byte("

route not found error: My custom error template

") - spaContent, err := os.ReadFile(conf.Servers[0].SPAs[1].BootstrapFile) - helper.Must(err) + spaContent := []byte("

vue.js

") tmpStoreCh := make(chan struct{}) defer close(tmpStoreCh) From af60aef7cefdb8589fd8527a31b29c086b85bca6 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Thu, 24 Nov 2022 12:27:52 +0100 Subject: [PATCH 11/11] test cases for key/value type errors --- config/configload/load_test.go | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/config/configload/load_test.go b/config/configload/load_test.go index 1c92e2211..cbcbfcab3 100644 --- a/config/configload/load_test.go +++ b/config/configload/load_test.go @@ -616,6 +616,44 @@ func TestConfigErrors(t *testing.T) { }`, `configuration error: referenced backend "as" is not defined`, }, + { + "wrong environment_variables type", + `server {} + defaults { + environment_variables = "val" + }`, + "couper.hcl:3,30-35: environment_variables must be object type; ", + }, + { + "unsupported key scope traversal expression", + `server {} + defaults { + environment_variables = { + env.FOO = "val" + } + }`, + "couper.hcl:4,8-15: unsupported key scope traversal expression; ", + }, + { + "unsupported key template expression", + `server {} + defaults { + environment_variables = { + "key${1 + 0}" = "val" + } + }`, + "couper.hcl:4,8-21: unsupported key template expression; ", + }, + { + "unsupported key expression", + `server {} + defaults { + environment_variables = { + to_upper("key") = "val" + } + }`, + "couper.hcl:4,8-23: unsupported key expression; ", + }, } for _, tt := range tests {