istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/cmd/pilot-agent/status/ready/probe_test.go (about)

     1  // Copyright Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package ready
    16  
    17  import (
    18  	"context"
    19  	"net"
    20  	"testing"
    21  
    22  	. "github.com/onsi/gomega"
    23  
    24  	"istio.io/istio/pilot/cmd/pilot-agent/status/testserver"
    25  )
    26  
    27  var (
    28  	liveServerStats = "cluster_manager.cds.update_success: 1\nlistener_manager.lds.update_success: 1\nserver.state: 0\nlistener_manager.workers_started: 1"
    29  	onlyServerStats = "server.state: 0"
    30  	initServerStats = "cluster_manager.cds.update_success: 1\nlistener_manager.lds.update_success: 1\nserver.state: 2"
    31  	noServerStats   = ""
    32  )
    33  
    34  func TestEnvoyStatsCompleteAndSuccessful(t *testing.T) {
    35  	g := NewWithT(t)
    36  
    37  	server := testserver.CreateAndStartServer(liveServerStats)
    38  	defer server.Close()
    39  	ctx, cancel := context.WithCancel(context.Background())
    40  	defer cancel()
    41  	probe := Probe{AdminPort: uint16(server.Listener.Addr().(*net.TCPAddr).Port)}
    42  	probe.Context = ctx
    43  
    44  	err := probe.Check()
    45  
    46  	g.Expect(err).NotTo(HaveOccurred())
    47  }
    48  
    49  func TestEnvoyDraining(t *testing.T) {
    50  	g := NewWithT(t)
    51  
    52  	server := testserver.CreateAndStartServer(liveServerStats)
    53  	defer server.Close()
    54  	ctx, cancel := context.WithCancel(context.Background())
    55  	probe := Probe{AdminPort: uint16(server.Listener.Addr().(*net.TCPAddr).Port), Context: ctx}
    56  	cancel()
    57  
    58  	err := probe.isEnvoyReady()
    59  
    60  	g.Expect(err).To(HaveOccurred())
    61  }
    62  
    63  func TestEnvoyStats(t *testing.T) {
    64  	cases := []struct {
    65  		name   string
    66  		stats  string
    67  		result string
    68  	}{
    69  		{
    70  			"only lds",
    71  			"listener_manager.lds.update_success: 1",
    72  			"config not fully received from XDS server: cds updates: 0 successful, 0 rejected; lds updates: 1 successful, 0 rejected",
    73  		},
    74  		{
    75  			"only cds",
    76  			"cluster_manager.cds.update_success: 1",
    77  			"config not fully received from XDS server: cds updates: 1 successful, 0 rejected; lds updates: 0 successful, 0 rejected",
    78  		},
    79  		{
    80  			"reject CDS",
    81  			`cluster_manager.cds.update_rejected: 1
    82  listener_manager.lds.update_success: 1`,
    83  			"config received from XDS server, but was rejected: cds updates: 0 successful, 1 rejected; lds updates: 1 successful, 0 rejected",
    84  		},
    85  		{
    86  			"no config",
    87  			``,
    88  			"config not received from XDS server (is Istiod running?): cds updates: 0 successful, 0 rejected; lds updates: 0 successful, 0 rejected",
    89  		},
    90  		{
    91  			"workers not started",
    92  			`
    93  cluster_manager.cds.update_success: 1
    94  listener_manager.lds.update_success: 1
    95  listener_manager.workers_started: 0
    96  server.state: 0`,
    97  			"workers have not yet started",
    98  		},
    99  		{
   100  			"full",
   101  			`
   102  cluster_manager.cds.update_success: 1
   103  listener_manager.lds.update_success: 1
   104  listener_manager.workers_started: 1
   105  server.state: 0`,
   106  			"",
   107  		},
   108  	}
   109  
   110  	for _, tt := range cases {
   111  		t.Run(tt.name, func(t *testing.T) {
   112  			server := testserver.CreateAndStartServer(tt.stats)
   113  			defer server.Close()
   114  			ctx, cancel := context.WithCancel(context.Background())
   115  			defer cancel()
   116  			probe := Probe{AdminPort: uint16(server.Listener.Addr().(*net.TCPAddr).Port)}
   117  			probe.Context = ctx
   118  			err := probe.Check()
   119  
   120  			// Expect no error
   121  			if tt.result == "" {
   122  				if err != nil {
   123  					t.Fatalf("Expected no error, got: %v", err)
   124  				}
   125  				return
   126  			}
   127  			// Expect error
   128  			if err.Error() != tt.result {
   129  				t.Fatalf("Expected: \n'%v', got: \n'%v'", tt.result, err.Error())
   130  			}
   131  		})
   132  	}
   133  }
   134  
   135  func TestEnvoyInitializing(t *testing.T) {
   136  	g := NewWithT(t)
   137  
   138  	server := testserver.CreateAndStartServer(initServerStats)
   139  	defer server.Close()
   140  	ctx, cancel := context.WithCancel(context.Background())
   141  	defer cancel()
   142  	probe := Probe{AdminPort: uint16(server.Listener.Addr().(*net.TCPAddr).Port)}
   143  	probe.Context = ctx
   144  	err := probe.Check()
   145  
   146  	g.Expect(err).To(HaveOccurred())
   147  }
   148  
   149  func TestEnvoyNoClusterManagerStats(t *testing.T) {
   150  	g := NewWithT(t)
   151  
   152  	server := testserver.CreateAndStartServer(onlyServerStats)
   153  	defer server.Close()
   154  	ctx, cancel := context.WithCancel(context.Background())
   155  	defer cancel()
   156  	probe := Probe{AdminPort: uint16(server.Listener.Addr().(*net.TCPAddr).Port)}
   157  	probe.Context = ctx
   158  	err := probe.Check()
   159  
   160  	g.Expect(err).To(HaveOccurred())
   161  }
   162  
   163  func TestEnvoyNoServerStats(t *testing.T) {
   164  	g := NewWithT(t)
   165  
   166  	server := testserver.CreateAndStartServer(noServerStats)
   167  	defer server.Close()
   168  	ctx, cancel := context.WithCancel(context.Background())
   169  	defer cancel()
   170  	probe := Probe{AdminPort: uint16(server.Listener.Addr().(*net.TCPAddr).Port)}
   171  	probe.Context = ctx
   172  	err := probe.Check()
   173  
   174  	g.Expect(err).To(HaveOccurred())
   175  }
   176  
   177  func TestEnvoyReadinessCache(t *testing.T) {
   178  	g := NewWithT(t)
   179  
   180  	server := testserver.CreateAndStartServer(noServerStats)
   181  	ctx, cancel := context.WithCancel(context.Background())
   182  	defer cancel()
   183  	probe := Probe{AdminPort: uint16(server.Listener.Addr().(*net.TCPAddr).Port)}
   184  	probe.Context = ctx
   185  	err := probe.Check()
   186  	g.Expect(err).To(HaveOccurred())
   187  	g.Expect(probe.atleastOnceReady).Should(BeFalse())
   188  	err = probe.Check()
   189  	g.Expect(err).To(HaveOccurred())
   190  	g.Expect(probe.atleastOnceReady).Should(BeFalse())
   191  	server.Close()
   192  
   193  	server = testserver.CreateAndStartServer(liveServerStats)
   194  	probe.AdminPort = uint16(server.Listener.Addr().(*net.TCPAddr).Port)
   195  	err = probe.Check()
   196  	g.Expect(err).NotTo(HaveOccurred())
   197  	g.Expect(probe.atleastOnceReady).Should(BeTrue())
   198  	server.Close()
   199  
   200  	server = testserver.CreateAndStartServer(noServerStats)
   201  	probe.AdminPort = uint16(server.Listener.Addr().(*net.TCPAddr).Port)
   202  	err = probe.Check()
   203  	g.Expect(err).NotTo(HaveOccurred())
   204  	g.Expect(probe.atleastOnceReady).Should(BeTrue())
   205  	server.Close()
   206  
   207  	err = probe.Check()
   208  	g.Expect(err).NotTo(HaveOccurred())
   209  	g.Expect(probe.atleastOnceReady).Should(BeTrue())
   210  }