Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: omit envoy golden test files that differ from the latest version #9807

Merged
merged 2 commits into from
Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
13 changes: 7 additions & 6 deletions agent/xds/clusters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ func TestClustersFromSnapshot(t *testing.T) {
},
}

latestEnvoyVersion := proxysupport.EnvoyVersions[0]
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
Expand Down Expand Up @@ -660,7 +661,7 @@ func TestClustersFromSnapshot(t *testing.T) {
gName = tt.overrideGoldenName
}

require.JSONEq(goldenEnvoy(t, filepath.Join("clusters", gName), envoyVersion, gotJSON), gotJSON)
require.JSONEq(goldenEnvoy(t, filepath.Join("clusters", gName), envoyVersion, latestEnvoyVersion, gotJSON), gotJSON)
})
}
})
Expand Down Expand Up @@ -818,15 +819,15 @@ func setupTLSRootsAndLeaf(t *testing.T, snap *proxycfg.ConfigSnapshot) {
if snap.Leaf() != nil {
switch snap.Kind {
case structs.ServiceKindConnectProxy:
snap.ConnectProxy.Leaf.CertPEM = golden(t, "test-leaf-cert", "", "")
snap.ConnectProxy.Leaf.PrivateKeyPEM = golden(t, "test-leaf-key", "", "")
snap.ConnectProxy.Leaf.CertPEM = loadTestResource(t, "test-leaf-cert")
snap.ConnectProxy.Leaf.PrivateKeyPEM = loadTestResource(t, "test-leaf-key")
case structs.ServiceKindIngressGateway:
snap.IngressGateway.Leaf.CertPEM = golden(t, "test-leaf-cert", "", "")
snap.IngressGateway.Leaf.PrivateKeyPEM = golden(t, "test-leaf-key", "", "")
snap.IngressGateway.Leaf.CertPEM = loadTestResource(t, "test-leaf-cert")
snap.IngressGateway.Leaf.PrivateKeyPEM = loadTestResource(t, "test-leaf-key")
}
}
if snap.Roots != nil {
snap.Roots.Roots[0].RootCert = golden(t, "test-root-cert", "", "")
snap.Roots.Roots[0].RootCert = loadTestResource(t, "test-root-cert")
}
}

Expand Down
3 changes: 2 additions & 1 deletion agent/xds/endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ func Test_endpointsFromSnapshot(t *testing.T) {
},
}

latestEnvoyVersion := proxysupport.EnvoyVersions[0]
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
Expand Down Expand Up @@ -599,7 +600,7 @@ func Test_endpointsFromSnapshot(t *testing.T) {
gName = tt.overrideGoldenName
}

require.JSONEq(goldenEnvoy(t, filepath.Join("endpoints", gName), envoyVersion, gotJSON), gotJSON)
require.JSONEq(goldenEnvoy(t, filepath.Join("endpoints", gName), envoyVersion, latestEnvoyVersion, gotJSON), gotJSON)
})
}
})
Expand Down
88 changes: 81 additions & 7 deletions agent/xds/golden_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"

Expand All @@ -18,9 +19,32 @@ import (
// update allows golden files to be updated based on the current output.
var update = flag.Bool("update", false, "update golden files")

// goldenSimple is just for read/write access to a golden file that is not
// envoy specific.
func goldenSimple(t *testing.T, name, got string) string {
return golden(t, name, "", "", got)
}

// goldenEnvoy is a special variant of golden() that silos each named test by
// each supported envoy version
func goldenEnvoy(t *testing.T, name, envoyVersion, got string) string {
func goldenEnvoy(t *testing.T, name, envoyVersion, latestEnvoyVersion, got string) string {
t.Helper()

require.NotEmpty(t, envoyVersion)

// We'll need both the name of this golden file for the requested version
// of envoy AND the latest version of envoy due to how the golden file
// coalescing works below when there is no xDS generated skew across envoy
// versions.
subname := goldenEnvoyVersionName(t, envoyVersion)
latestSubname := goldenEnvoyVersionName(t, latestEnvoyVersion)

return golden(t, name, subname, latestSubname, got)
}

func goldenEnvoyVersionName(t *testing.T, envoyVersion string) string {
t.Helper()

require.NotEmpty(t, envoyVersion)

// We do version sniffing on the complete version, but only generate
Expand All @@ -29,14 +53,26 @@ func goldenEnvoy(t *testing.T, name, envoyVersion, got string) string {
segments := version.Segments()
require.Len(t, segments, 3)

subname := fmt.Sprintf("envoy-%d-%d-x", segments[0], segments[1])

return golden(t, name, subname, got)
return fmt.Sprintf("envoy-%d-%d-x", segments[0], segments[1])
}

// golden reads and optionally writes the expected data to the golden file,
// returning the contents as a string.
func golden(t *testing.T, name, subname, got string) string {
//
// The golden file is named with two components the "name" and the "subname".
// In the common case of xDS tests the "name" component is the logical name of
// the test itself, and the "subname" is derived from the envoy major version.
//
// If latestSubname is specified we use that as a fallback source of comparison
// if the specific golden file referred to by subname is absent.
//
// If the -update flag is passed when executing the tests then the contents of
// the "got" argument are written to the golden file on disk. If the
// latestSubname argument is specified in this mode and the generated content
// matches that of the latest generated content then the specific golden file
// referred to by 'subname' is deleted to avoid unnecessary duplication in the
// testdata directory.
func golden(t *testing.T, name, subname, latestSubname, got string) string {
t.Helper()

suffix := ".golden"
Expand All @@ -45,14 +81,52 @@ func golden(t *testing.T, name, subname, got string) string {
}

golden := filepath.Join("testdata", name+suffix)
if *update && got != "" {
err := ioutil.WriteFile(golden, []byte(got), 0644)

// Always load the latest golden file if configured to do so.
latestExpected := ""
if latestSubname != "" && subname != latestSubname {
latestGolden := filepath.Join("testdata", fmt.Sprintf("%s.%s.golden", name, latestSubname))
raw, err := ioutil.ReadFile(latestGolden)
require.NoError(t, err)
rboyer marked this conversation as resolved.
Show resolved Hide resolved
latestExpected = string(raw)
}

// Handle easy updates to the golden files in the agent/xds/testdata
// directory.
//
// To trim down PRs, we only create per-version golden files if they differ
// from the latest version.
if *update && got != "" {
if latestExpected == got {
// In update mode we erase a golden file if it is identical to
// the golden file corresponding to the latest version of
// envoy.
err := os.Remove(golden)
if err != nil && !os.IsNotExist(err) {
require.NoError(t, err)
}
return got
}

require.NoError(t, ioutil.WriteFile(golden, []byte(got), 0644))
return got
}

expected, err := ioutil.ReadFile(golden)
if latestExpected != "" && os.IsNotExist(err) {
// In readonly mode if a specific golden file isn't found, we fallback
// on the latest one.
return latestExpected
}
require.NoError(t, err)
return string(expected)
}

func loadTestResource(t *testing.T, name string) string {
t.Helper()

expected, err := ioutil.ReadFile(filepath.Join("testdata", name+".golden"))
require.NoError(t, err)
return string(expected)
}

Expand Down
3 changes: 2 additions & 1 deletion agent/xds/listeners_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ func TestListenersFromSnapshot(t *testing.T) {
},
}

latestEnvoyVersion := proxysupport.EnvoyVersions[0]
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
Expand Down Expand Up @@ -527,7 +528,7 @@ func TestListenersFromSnapshot(t *testing.T) {
gName = tt.overrideGoldenName
}

require.JSONEq(goldenEnvoy(t, filepath.Join("listeners", gName), envoyVersion, gotJSON), gotJSON)
require.JSONEq(goldenEnvoy(t, filepath.Join("listeners", gName), envoyVersion, latestEnvoyVersion, gotJSON), gotJSON)
})
}
})
Expand Down
4 changes: 2 additions & 2 deletions agent/xds/rbac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,15 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) {

gotJSON := protoToJSON(t, filter)

require.JSONEq(t, golden(t, filepath.Join("rbac", name), "", gotJSON), gotJSON)
require.JSONEq(t, goldenSimple(t, filepath.Join("rbac", name), gotJSON), gotJSON)
})
t.Run("http filter", func(t *testing.T) {
filter, err := makeRBACHTTPFilter(tt.intentions, tt.intentionDefaultAllow)
require.NoError(t, err)

gotJSON := protoToJSON(t, filter)

require.JSONEq(t, golden(t, filepath.Join("rbac", name+"--httpfilter"), "", gotJSON), gotJSON)
require.JSONEq(t, goldenSimple(t, filepath.Join("rbac", name+"--httpfilter"), gotJSON), gotJSON)
})
})
}
Expand Down
3 changes: 2 additions & 1 deletion agent/xds/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ func TestRoutesFromSnapshot(t *testing.T) {
},
}

latestEnvoyVersion := proxysupport.EnvoyVersions[0]
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
Expand Down Expand Up @@ -278,7 +279,7 @@ func TestRoutesFromSnapshot(t *testing.T) {
gName = tt.overrideGoldenName
}

require.JSONEq(goldenEnvoy(t, filepath.Join("routes", gName), envoyVersion, gotJSON), gotJSON)
require.JSONEq(goldenEnvoy(t, filepath.Join("routes", gName), envoyVersion, latestEnvoyVersion, gotJSON), gotJSON)
})
}
})
Expand Down
Loading