Consul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.2 KiB

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package resourcehcl_test
import (
"flag"
"fmt"
"os"
"path"
"testing"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/encoding/protojson"
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/internal/resource/demo"
"github.com/hashicorp/consul/internal/resourcehcl"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/proto/private/prototest"
)
var update = flag.Bool("update", false, "update golden files")
func FuzzUnmarshall(f *testing.F) {
entries, err := os.ReadDir("./testdata")
require.NoError(f, err)
read := func(t *testing.F, path string) ([]byte, bool) {
t.Helper()
bytes, err := os.ReadFile(fmt.Sprintf("./testdata/%s", path))
switch {
case err == nil:
return bytes, true
case os.IsNotExist(err):
return nil, false
}
t.Fatalf("failed to read file %s %v", path, err)
return nil, false
}
for _, entry := range entries {
ext := path.Ext(entry.Name())
if ext != ".hcl" {
continue
}
input, _ := read(f, entry.Name())
f.Add(input)
}
registry := resource.NewRegistry()
demo.RegisterTypes(registry)
f.Fuzz(func(t *testing.T, input []byte) {
got, err := resourcehcl.Unmarshal(input, registry)
if err != nil {
return
}
require.NotNil(t, got)
})
}
func TestUnmarshal(t *testing.T) {
entries, err := os.ReadDir("./testdata")
require.NoError(t, err)
read := func(t *testing.T, path string) ([]byte, bool) {
t.Helper()
bytes, err := os.ReadFile(fmt.Sprintf("./testdata/%s", path))
switch {
case err == nil:
return bytes, true
case os.IsNotExist(err):
return nil, false
}
t.Fatalf("failed to read file %s %v", path, err)
return nil, false
}
write := func(t *testing.T, path string, src []byte) {
t.Helper()
require.NoError(t, os.WriteFile(fmt.Sprintf("./testdata/%s", path), src, 0o600))
}
for _, entry := range entries {
name := entry.Name()
ext := path.Ext(name)
if ext != ".hcl" {
continue
}
base := name[0 : len(name)-len(ext)]
t.Run(base, func(t *testing.T) {
input, _ := read(t, name)
registry := resource.NewRegistry()
demo.RegisterTypes(registry)
output, err := resourcehcl.UnmarshalOptions{SourceFileName: name}.
Unmarshal(input, registry)
if *update {
if err == nil {
json, err := protojson.Marshal(output)
require.NoError(t, err)
write(t, base+".golden", json)
} else {
write(t, base+".error", []byte(err.Error()))
}
}
goldenJSON, haveGoldenJSON := read(t, base+".golden")
goldenError, haveGoldenError := read(t, base+".error")
if haveGoldenError && haveGoldenJSON {
t.Fatalf("both %s.golden and %s.error exist, delete one", base, base)
}
if !haveGoldenError && !haveGoldenJSON && !*update {
t.Fatalf("neither %s.golden or %s.error exist, run the tests again with the -update flag to create one", base, base)
}
if haveGoldenError {
require.Error(t, err)
require.Equal(t, string(goldenError), err.Error())
}
if haveGoldenJSON {
require.NoError(t, err)
var exp pbresource.Resource
require.NoError(t, protojson.Unmarshal(goldenJSON, &exp))
prototest.AssertDeepEqual(t, &exp, output)
}
})
}
}