istio.io/istio@v0.0.0-20240520182934-d79c90f27776/istioctl/pkg/waypoint/waypoint_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 waypoint 16 17 import ( 18 "bytes" 19 "context" 20 "fmt" 21 "os" 22 "strings" 23 "testing" 24 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 gateway "sigs.k8s.io/gateway-api/apis/v1" 27 28 "istio.io/api/label" 29 "istio.io/istio/istioctl/pkg/cli" 30 "istio.io/istio/pilot/pkg/model/kstatus" 31 "istio.io/istio/pkg/config/constants" 32 ) 33 34 func TestWaypointList(t *testing.T) { 35 cases := []struct { 36 name string 37 args []string 38 gateways []*gateway.Gateway 39 expectedOutFile string 40 }{ 41 { 42 name: "no gateways", 43 args: strings.Split("list", " "), 44 gateways: []*gateway.Gateway{}, 45 expectedOutFile: "no-gateway", 46 }, 47 { 48 name: "default namespace gateway", 49 args: strings.Split("list", " "), 50 gateways: []*gateway.Gateway{ 51 makeGateway(constants.DefaultNamespaceWaypoint, "default", true, true), 52 makeGateway(constants.DefaultNamespaceWaypoint, "fake", true, true), 53 }, 54 expectedOutFile: "default-gateway", 55 }, 56 { 57 name: "all namespaces gateways", 58 args: strings.Split("list -A", " "), 59 gateways: []*gateway.Gateway{ 60 makeGateway(constants.DefaultNamespaceWaypoint, "default", true, true), 61 makeGateway(constants.DefaultNamespaceWaypoint, "fake", true, true), 62 }, 63 expectedOutFile: "all-gateway", 64 }, 65 { 66 name: "have both managed and unmanaged gateways", 67 args: strings.Split("list -A", " "), 68 gateways: []*gateway.Gateway{ 69 makeGateway("bookinfo", "default", false, true), 70 makeGateway("bookinfo-invalid", "fake", true, false), 71 makeGateway(constants.DefaultNamespaceWaypoint, "default", false, true), 72 makeGateway("bookinfo-valid", "bookinfo", true, true), 73 makeGateway("no-name-convention", "default", true, true), 74 makeGatewayWithRevision("bookinfo-rev", "bookinfo", true, true, "rev1"), 75 }, 76 expectedOutFile: "combined-gateway", 77 }, 78 } 79 for _, tt := range cases { 80 t.Run(tt.name, func(t *testing.T) { 81 ctx := cli.NewFakeContext(&cli.NewFakeContextOption{ 82 Namespace: "default", 83 }) 84 client, err := ctx.CLIClient() 85 if err != nil { 86 t.Fatal(err) 87 } 88 89 for _, gw := range tt.gateways { 90 _, _ = client.GatewayAPI().GatewayV1().Gateways(gw.Namespace).Create(context.Background(), gw, metav1.CreateOptions{}) 91 } 92 defaultFile, err := os.ReadFile(fmt.Sprintf("testdata/waypoint/%s", tt.expectedOutFile)) 93 if err != nil { 94 t.Fatal(err) 95 } 96 expectedOut := string(defaultFile) 97 if len(expectedOut) == 0 { 98 t.Fatal("expected output is empty") 99 } 100 101 var out bytes.Buffer 102 rootCmd := Cmd(ctx) 103 rootCmd.SetArgs(tt.args) 104 rootCmd.SetOut(&out) 105 rootCmd.SetErr(&out) 106 107 fErr := rootCmd.Execute() 108 if fErr != nil { 109 t.Fatal(fErr) 110 } 111 output := out.String() 112 if output != expectedOut { 113 t.Fatalf("expected %s, got %s", expectedOut, output) 114 } 115 }) 116 } 117 } 118 119 func makeGateway(name, namespace string, programmed, isWaypoint bool) *gateway.Gateway { 120 conditions := make([]metav1.Condition, 0) 121 if programmed { 122 conditions = append(conditions, metav1.Condition{ 123 Type: string(gateway.GatewayConditionProgrammed), 124 Status: kstatus.StatusTrue, 125 }) 126 } else { 127 conditions = append(conditions, metav1.Condition{ 128 Type: string(gateway.GatewayConditionProgrammed), 129 Status: kstatus.StatusFalse, 130 }) 131 } 132 className := "other" 133 if isWaypoint { 134 className = constants.WaypointGatewayClassName 135 } 136 return &gateway.Gateway{ 137 ObjectMeta: metav1.ObjectMeta{ 138 Name: name, 139 Namespace: namespace, 140 }, 141 Spec: gateway.GatewaySpec{ 142 GatewayClassName: gateway.ObjectName(className), 143 }, 144 Status: gateway.GatewayStatus{ 145 Conditions: conditions, 146 }, 147 } 148 } 149 150 func makeGatewayWithRevision(name, namespace string, programmed, isWaypoint bool, rev string) *gateway.Gateway { 151 gw := makeGateway(name, namespace, programmed, isWaypoint) 152 if gw.Labels == nil { 153 gw.Labels = make(map[string]string) 154 } 155 gw.Labels[label.IoIstioRev.Name] = rev 156 return gw 157 }