...

Source file src/github.com/emissary-ingress/emissary/v3/cmd/entrypoint/host_semantic_test.go

Documentation: github.com/emissary-ingress/emissary/v3/cmd/entrypoint

     1  package entrypoint_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"regexp"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/emissary-ingress/emissary/v3/cmd/entrypoint"
    14  	bootstrap "github.com/emissary-ingress/emissary/v3/pkg/api/envoy/config/bootstrap/v3"
    15  	"github.com/emissary-ingress/emissary/v3/pkg/api/getambassador.io/v3alpha1"
    16  	"github.com/emissary-ingress/emissary/v3/pkg/kates"
    17  	"github.com/emissary-ingress/emissary/v3/pkg/snapshot/v1"
    18  )
    19  
    20  func getExpected(expectedFile string, inputObjects []kates.Object) ([]RenderedListener, []v3alpha1.Mapping, []string, error) {
    21  	// Figure out all the mappings and clusters we'll need.
    22  	neededClusters := []string{}
    23  	neededMappings := []v3alpha1.Mapping{}
    24  
    25  	// Read the expected rendering from a file.
    26  	content, err := ioutil.ReadFile(expectedFile)
    27  	if err != nil {
    28  		return nil, nil, nil, err
    29  	}
    30  
    31  	var expectedListeners []RenderedListener
    32  	if err := json.Unmarshal(content, &expectedListeners); err != nil {
    33  		return nil, nil, nil, err
    34  	}
    35  
    36  	// Build the set of expected mappings and clusters from our objects.
    37  	clusterRE := regexp.MustCompile("[^0-9A-Za-z_]")
    38  
    39  	for _, obj := range inputObjects {
    40  		// Skip things that aren't Mappings.
    41  		mapping, ok := obj.(*v3alpha1.Mapping)
    42  
    43  		if !ok {
    44  			continue
    45  		}
    46  
    47  		// We need to see this Mapping in our snapshot.
    48  		neededMappings = append(neededMappings, *mapping)
    49  
    50  		// Grab the cluster name, and remember it for later.
    51  		mangledService := clusterRE.ReplaceAll([]byte(mapping.Spec.Service), []byte("_"))
    52  		clusterName := fmt.Sprintf("cluster_%s_default", mangledService)
    53  		neededClusters = append(neededClusters, clusterName)
    54  	}
    55  
    56  	return expectedListeners, neededMappings, neededClusters, nil
    57  }
    58  
    59  func testSemanticSet(t *testing.T, inputFile string, expectedFile string) {
    60  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true, DiagdDebug: true}, nil)
    61  
    62  	inputObjects, err := LoadYAML(inputFile)
    63  	require.NoError(t, err)
    64  
    65  	// expectedListeners is what we think we're going to get.
    66  	expectedListeners, neededMappings, neededClusters, err := getExpected(expectedFile, inputObjects)
    67  	require.NoError(t, err)
    68  	expectedJSON, err := JSONifyRenderedListeners(expectedListeners)
    69  	require.NoError(t, err)
    70  
    71  	// Now, what did we _actually_ get?
    72  	require.NoError(t, f.UpsertFile(inputFile))
    73  	f.Flush()
    74  
    75  	snap, err := f.GetSnapshot(func(snapshot *snapshot.Snapshot) bool {
    76  		// XXX Ew. Switch to a dict, FFS.
    77  		for _, mapping := range neededMappings {
    78  			mappingNamespace := mapping.Namespace
    79  
    80  			if mappingNamespace == "" {
    81  				mappingNamespace = "default"
    82  			}
    83  
    84  			mappingName := mapping.Name
    85  
    86  			t.Logf("GetSnapshot: looking for %s/%s", mappingNamespace, mappingName)
    87  
    88  			found := false
    89  			for _, m := range snapshot.Kubernetes.Mappings {
    90  				if m.Namespace == mappingNamespace && m.Name == mappingName {
    91  					found = true
    92  					break
    93  				}
    94  			}
    95  
    96  			if !found {
    97  				return false
    98  			}
    99  		}
   100  
   101  		return true
   102  	})
   103  	require.NoError(t, err)
   104  	require.NotNil(t, snap)
   105  
   106  	envoyConfig, err := f.GetEnvoyConfig(func(config *bootstrap.Bootstrap) bool {
   107  		for _, cluster := range neededClusters {
   108  			if FindCluster(config, ClusterNameContains(cluster)) == nil {
   109  				return false
   110  			}
   111  		}
   112  
   113  		return true
   114  	})
   115  	require.NoError(t, err)
   116  	require.NotNil(t, envoyConfig)
   117  
   118  	actualListeners, err := RenderEnvoyConfig(t, envoyConfig)
   119  	require.NoError(t, err)
   120  	actualJSON, err := JSONifyRenderedListeners(actualListeners)
   121  	require.NoError(t, err)
   122  
   123  	err = ioutil.WriteFile("/tmp/host-semantics-expected.json", []byte(expectedJSON), 0644)
   124  	if err == io.EOF {
   125  		err = nil
   126  	}
   127  	require.NoError(t, err)
   128  
   129  	err = ioutil.WriteFile("/tmp/host-semantics-actual.json", []byte(actualJSON), 0644)
   130  	if err == io.EOF {
   131  		err = nil
   132  	}
   133  	require.NoError(t, err)
   134  
   135  	require.Equal(t, expectedJSON, actualJSON, "Mismatch!")
   136  }
   137  
   138  func TestHostSemanticsMinimal(t *testing.T) {
   139  	testSemanticSet(t, "testdata/hostsem-minimal.yaml", "testdata/hostsem-minimal-expected.json")
   140  }
   141  
   142  func TestHostSemanticsBasic(t *testing.T) {
   143  	testSemanticSet(t, "testdata/hostsem-basic.yaml", "testdata/hostsem-basic-expected.json")
   144  }
   145  
   146  func TestHostSemanticsCleartextOnly(t *testing.T) {
   147  	testSemanticSet(t, "testdata/hostsem-cleartextonly.yaml", "testdata/hostsem-cleartextonly-expected.json")
   148  }
   149  
   150  func TestHostSemanticsDisjoint(t *testing.T) {
   151  	testSemanticSet(t, "testdata/hostsem-disjoint-hosts.yaml", "testdata/hostsem-disjoint-hosts-expected.json")
   152  }
   153  
   154  func TestHostSemanticsHostSelector(t *testing.T) {
   155  	testSemanticSet(t, "testdata/hostsem-hostsel.yaml", "testdata/hostsem-hostsel-expected.json")
   156  }
   157  

View as plain text