minikube/pkg/minikube/service/service_test.go

896 lines
24 KiB
Go

/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package service
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"reflect"
"strings"
"testing"
"text/template"
"time"
"github.com/docker/machine/libmachine"
"github.com/docker/machine/libmachine/host"
"github.com/pkg/errors"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/kubernetes"
typed_core "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/kubernetes/typed/core/v1/fake"
testing_fake "k8s.io/client-go/testing"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/tests"
)
type MockClientGetter struct {
servicesMap map[string]typed_core.ServiceInterface
endpointsMap map[string]typed_core.EndpointsInterface
secretsMap map[string]typed_core.SecretInterface
Fake fake.FakeCoreV1
}
func init() {
getCoreClientFail = false
}
// Force GetCoreClient to fail
var getCoreClientFail bool
func (m *MockClientGetter) GetCoreClient() (typed_core.CoreV1Interface, error) {
if getCoreClientFail {
return nil, fmt.Errorf("test Error - Get")
}
return &MockCoreClient{
servicesMap: m.servicesMap,
endpointsMap: m.endpointsMap,
secretsMap: m.secretsMap}, nil
}
func (m *MockClientGetter) GetClientset(timeout time.Duration) (*kubernetes.Clientset, error) {
return nil, nil
}
// Secrets return fake secret for foo namespace or secrets from mocked client
func (m *MockCoreClient) Secrets(ns string) typed_core.SecretInterface {
if ns == "foo" {
return &fake.FakeSecrets{Fake: &fake.FakeCoreV1{Fake: &testing_fake.Fake{}}}
}
return m.secretsMap[ns]
}
func (m *MockCoreClient) Services(namespace string) typed_core.ServiceInterface {
return m.servicesMap[namespace]
}
type MockCoreClient struct {
fake.FakeCoreV1
servicesMap map[string]typed_core.ServiceInterface
endpointsMap map[string]typed_core.EndpointsInterface
secretsMap map[string]typed_core.SecretInterface
}
var secretsNamespaces = map[string]typed_core.SecretInterface{
"default": defaultNamespaceSecretsInterface,
}
var defaultNamespaceSecretsInterface = &MockSecretInterface{
SecretsList: &core.SecretList{
Items: []core.Secret{
{},
},
},
}
var serviceNamespaces = map[string]typed_core.ServiceInterface{
"default": defaultNamespaceServiceInterface,
}
var defaultNamespaceServiceInterface = &MockServiceInterface{
ServiceList: &core.ServiceList{
Items: []core.Service{
{
ObjectMeta: meta.ObjectMeta{
Name: "mock-dashboard",
Namespace: "default",
Labels: map[string]string{"mock": "mock"},
},
Spec: core.ServiceSpec{
Ports: []core.ServicePort{
{
NodePort: int32(1111),
TargetPort: intstr.IntOrString{
IntVal: int32(11111),
},
},
{
NodePort: int32(2222),
TargetPort: intstr.IntOrString{
IntVal: int32(22222),
},
},
},
},
},
{
ObjectMeta: meta.ObjectMeta{
Name: "mock-dashboard-no-ports",
Namespace: "default",
Labels: map[string]string{"mock": "mock"},
},
Spec: core.ServiceSpec{
Ports: []core.ServicePort{},
},
},
},
},
}
var endpointNamespaces = map[string]typed_core.EndpointsInterface{
"default": defaultNamespaceEndpointInterface,
}
var defaultNamespaceEndpointInterface = &MockEndpointsInterface{}
func (m *MockCoreClient) Endpoints(namespace string) typed_core.EndpointsInterface {
return m.endpointsMap[namespace]
}
type MockEndpointsInterface struct {
fake.FakeEndpoints
Endpoints *core.Endpoints
}
var endpointMap = map[string]*core.Endpoints{
"no-subsets": {},
"not-ready": {
Subsets: []core.EndpointSubset{
{
Addresses: []core.EndpointAddress{},
NotReadyAddresses: []core.EndpointAddress{
{IP: "1.1.1.1"},
{IP: "2.2.2.2"},
},
},
},
},
"one-ready": {
Subsets: []core.EndpointSubset{
{
Addresses: []core.EndpointAddress{
{IP: "1.1.1.1"},
},
NotReadyAddresses: []core.EndpointAddress{
{IP: "2.2.2.2"},
},
},
},
},
"mock-dashboard": {
Subsets: []core.EndpointSubset{
{
Ports: []core.EndpointPort{
{
Name: "port1",
Port: int32(11111),
},
{
Name: "port2",
Port: int32(22222),
},
},
},
},
},
}
func (e MockEndpointsInterface) Get(name string, _ meta.GetOptions) (*core.Endpoints, error) {
endpoint, ok := endpointMap[name]
if !ok {
return nil, errors.New("Endpoint not found")
}
return endpoint, nil
}
type MockServiceInterface struct {
fake.FakeServices
ServiceList *core.ServiceList
}
type MockSecretInterface struct {
fake.FakeSecrets
SecretsList *core.SecretList
}
func (s MockServiceInterface) List(opts meta.ListOptions) (*core.ServiceList, error) {
serviceList := &core.ServiceList{
Items: []core.Service{},
}
if opts.LabelSelector != "" {
keyValArr := strings.Split(opts.LabelSelector, "=")
for _, service := range s.ServiceList.Items {
if service.Spec.Selector[keyValArr[0]] == keyValArr[1] {
serviceList.Items = append(serviceList.Items, service)
}
}
return serviceList, nil
}
return s.ServiceList, nil
}
func (s MockServiceInterface) Get(name string, _ meta.GetOptions) (*core.Service, error) {
for _, svc := range s.ServiceList.Items {
if svc.ObjectMeta.Name == name {
return &svc, nil
}
}
return nil, nil
}
func TestGetServiceListFromServicesByLabel(t *testing.T) {
serviceList := &core.ServiceList{
Items: []core.Service{
{
Spec: core.ServiceSpec{
Selector: map[string]string{
"foo": "bar",
},
},
},
},
}
serviceIface := MockServiceInterface{
ServiceList: serviceList,
}
if _, err := getServiceListFromServicesByLabel(&serviceIface, "nothing", "nothing"); err != nil {
t.Fatalf("Service had no label match, but getServiceListFromServicesByLabel returned an error")
}
if _, err := getServiceListFromServicesByLabel(&serviceIface, "foo", "bar"); err != nil {
t.Fatalf("Endpoint was ready with at least one Address, but getServiceListFromServicesByLabel returned an error")
}
}
func TestPrintURLsForService(t *testing.T) {
defaultTemplate := template.Must(template.New("svc-template").Parse("http://{{.IP}}:{{.Port}}"))
client := &MockCoreClient{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
}
var tests = []struct {
description string
serviceName string
namespace string
tmpl *template.Template
expectedOutput []string
err bool
}{
{
description: "should get all node ports",
serviceName: "mock-dashboard",
namespace: "default",
tmpl: defaultTemplate,
expectedOutput: []string{"http://127.0.0.1:1111", "http://127.0.0.1:2222"},
},
{
description: "should get all node ports with arbitrary format",
serviceName: "mock-dashboard",
namespace: "default",
tmpl: template.Must(template.New("svc-arbitrary-template").Parse("{{.IP}}:{{.Port}}")),
expectedOutput: []string{"127.0.0.1:1111", "127.0.0.1:2222"},
},
{
description: "should get the name of all target ports with arbitrary format",
serviceName: "mock-dashboard",
namespace: "default",
tmpl: template.Must(template.New("svc-arbitrary-template").Parse("{{.Name}}={{.IP}}:{{.Port}}")),
expectedOutput: []string{"port1=127.0.0.1:1111", "port2=127.0.0.1:2222"},
},
{
description: "empty slice for no node ports",
serviceName: "mock-dashboard-no-ports",
namespace: "default",
tmpl: defaultTemplate,
expectedOutput: []string{},
},
{
description: "throw error without template",
err: true,
},
}
for _, test := range tests {
test := test
t.Run(test.description, func(t *testing.T) {
t.Parallel()
urls, err := printURLsForService(client, "127.0.0.1", test.serviceName, test.namespace, test.tmpl)
if err != nil && !test.err {
t.Errorf("Error: %v", err)
}
if err == nil && test.err {
t.Errorf("Expected error but got none")
}
if !reflect.DeepEqual(urls, test.expectedOutput) {
t.Errorf("\nExpected %v \nActual: %v \n\n", test.expectedOutput, urls)
}
})
}
}
func TestOptionallyHttpsFormattedUrlString(t *testing.T) {
var tests = []struct {
description string
bareURLString string
https bool
expectedHTTPSFormattedURLString string
expectedIsHTTPSchemedURL bool
}{
{
description: "no https for http schemed with no https option",
bareURLString: "http://192.168.99.100:30563",
https: false,
expectedHTTPSFormattedURLString: "http://192.168.99.100:30563",
expectedIsHTTPSchemedURL: true,
},
{
description: "no https for non-http schemed with no https option",
bareURLString: "xyz.http.myservice:30563",
https: false,
expectedHTTPSFormattedURLString: "xyz.http.myservice:30563",
expectedIsHTTPSchemedURL: false,
},
{
description: "https for http schemed with https option",
bareURLString: "http://192.168.99.100:30563",
https: true,
expectedHTTPSFormattedURLString: "https://192.168.99.100:30563",
expectedIsHTTPSchemedURL: true,
},
{
description: "no https for non-http schemed with https option and http substring",
bareURLString: "xyz.http.myservice:30563",
https: true,
expectedHTTPSFormattedURLString: "xyz.http.myservice:30563",
expectedIsHTTPSchemedURL: false,
},
}
for _, test := range tests {
test := test
t.Run(test.description, func(t *testing.T) {
t.Parallel()
httpsFormattedURLString, isHTTPSchemedURL := OptionallyHTTPSFormattedURLString(test.bareURLString, test.https)
if httpsFormattedURLString != test.expectedHTTPSFormattedURLString {
t.Errorf("\nhttpsFormattedURLString, Expected %v \nActual: %v \n\n", test.expectedHTTPSFormattedURLString, httpsFormattedURLString)
}
if isHTTPSchemedURL != test.expectedIsHTTPSchemedURL {
t.Errorf("\nisHTTPSchemedURL, Expected %v \nActual: %v \n\n",
test.expectedHTTPSFormattedURLString, httpsFormattedURLString)
}
})
}
}
func TestGetServiceURLs(t *testing.T) {
defaultAPI := &tests.MockAPI{
FakeStore: tests.FakeStore{
Hosts: map[string]*host.Host{
config.GetMachineName(): {
Name: config.GetMachineName(),
Driver: &tests.MockDriver{},
},
},
},
}
defaultTemplate := template.Must(template.New("svc-template").Parse("http://{{.IP}}:{{.Port}}"))
var tests = []struct {
description string
api libmachine.API
namespace string
expected URLs
err bool
}{
{
description: "no host",
api: &tests.MockAPI{
FakeStore: tests.FakeStore{
Hosts: make(map[string]*host.Host),
},
},
err: true,
},
{
description: "correctly return serviceURLs",
namespace: "default",
api: defaultAPI,
expected: []URL{
{
Namespace: "default",
Name: "mock-dashboard",
URLs: []string{"http://127.0.0.1:1111", "http://127.0.0.1:2222"},
},
{
Namespace: "default",
Name: "mock-dashboard-no-ports",
URLs: []string{},
},
},
},
}
defer revertK8sClient(K8s)
for _, test := range tests {
test := test
t.Run(test.description, func(t *testing.T) {
t.Parallel()
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
}
urls, err := GetServiceURLs(test.api, test.namespace, defaultTemplate)
if err != nil && !test.err {
t.Errorf("Error GetServiceURLs %v", err)
}
if err == nil && test.err {
t.Errorf("Test should have failed, but didn't")
}
if !reflect.DeepEqual(urls, test.expected) {
t.Errorf("URLs did not match, expected %v \n\n got %v", test.expected, urls)
}
})
}
}
func TestGetServiceURLsForService(t *testing.T) {
defaultAPI := &tests.MockAPI{
FakeStore: tests.FakeStore{
Hosts: map[string]*host.Host{
config.GetMachineName(): {
Name: config.GetMachineName(),
Driver: &tests.MockDriver{},
},
},
},
}
defaultTemplate := template.Must(template.New("svc-template").Parse("http://{{.IP}}:{{.Port}}"))
var tests = []struct {
description string
api libmachine.API
namespace string
service string
expected []string
err bool
}{
{
description: "no host",
api: &tests.MockAPI{
FakeStore: tests.FakeStore{
Hosts: make(map[string]*host.Host),
},
},
err: true,
},
{
description: "correctly return serviceURLs",
namespace: "default",
service: "mock-dashboard",
api: defaultAPI,
expected: []string{"http://127.0.0.1:1111", "http://127.0.0.1:2222"},
},
{
description: "correctly return empty serviceURLs",
namespace: "default",
service: "mock-dashboard-no-ports",
api: defaultAPI,
expected: []string{},
},
}
defer revertK8sClient(K8s)
for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
t.Parallel()
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
}
urls, err := GetServiceURLsForService(test.api, test.namespace, test.service, defaultTemplate)
if err != nil && !test.err {
t.Errorf("Error GetServiceURLsForService %v", err)
}
if err == nil && test.err {
t.Errorf("Test should have failed, but didn't")
}
if !reflect.DeepEqual(urls, test.expected) {
t.Errorf("URLs did not match, expected %+v \n\n got %+v", test.expected, urls)
}
})
}
}
func revertK8sClient(k K8sClient) {
K8s = k
getCoreClientFail = false
}
func TestGetCoreClient(t *testing.T) {
originalEnv := os.Getenv("KUBECONFIG")
defer func() {
err := os.Setenv("KUBECONFIG", originalEnv)
if err != nil {
t.Fatalf("Error reverting env KUBECONFIG to its original value. Got err (%s)", err)
}
}()
mockK8sConfig := `apiVersion: v1
clusters:
- cluster:
server: https://192.168.99.102:8443
name: minikube
contexts:
- context:
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
`
var tests = []struct {
description string
kubeconfigPath string
config string
err bool
}{
{
description: "ok",
kubeconfigPath: "/tmp/kube_config",
config: mockK8sConfig,
err: false,
},
{
description: "empty config",
kubeconfigPath: "/tmp/kube_config",
config: "",
err: true,
},
{
description: "broken config",
kubeconfigPath: "/tmp/kube_config",
config: "this**is&&not: yaml::valid: file",
err: true,
},
}
for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
mockK8sConfigByte := []byte(test.config)
mockK8sConfigPath := test.kubeconfigPath
err := ioutil.WriteFile(mockK8sConfigPath, mockK8sConfigByte, 0644)
defer func() { os.Remove(mockK8sConfigPath) }()
if err != nil {
t.Fatalf("Unexpected error when writing to file %v. Error: %v", test.kubeconfigPath, err)
}
os.Setenv("KUBECONFIG", mockK8sConfigPath)
k8s := K8sClientGetter{}
_, err = k8s.GetCoreClient()
if err != nil && !test.err {
t.Fatalf("GetCoreClient returned unexpected error: %v", err)
}
if err == nil && test.err {
t.Fatal("GetCoreClient expected to return error but got nil")
}
})
}
}
func TestPrintServiceList(t *testing.T) {
var buf bytes.Buffer
out := &buf
input := [][]string{{"foo", "bar", "baz"}}
PrintServiceList(out, input)
expected := `|-----------|------|-----|
| NAMESPACE | NAME | URL |
|-----------|------|-----|
| foo | bar | baz |
|-----------|------|-----|
`
got := out.String()
if got != expected {
t.Fatalf("PrintServiceList(%v) expected to return %v but got \n%v", input, expected, got)
}
}
func TestGetServiceListByLabel(t *testing.T) {
t.Run("failed Get Client", func(t *testing.T) {
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
}
getCoreClientFail = true
defer revertK8sClient(K8s)
ns := "foo"
_, err := GetServiceListByLabel(ns, "mock-dashboard", "foo")
if err == nil {
t.Fatal("GetServiceListByLabel expected to fail when GetCoreClient fails")
}
})
t.Run("bad namespace", func(t *testing.T) {
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
}
defer revertK8sClient(K8s)
ns := "no-such-namespace"
_, err := GetServiceListByLabel(ns, "mock-dashboard", "foo")
if err == nil {
t.Fatalf("GetServiceListByLabel expected to fail for bad namespace: %v", ns)
}
})
t.Run("ok no matches", func(t *testing.T) {
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
}
defer revertK8sClient(K8s)
ns, svc, label := "default", "mock-dashboard", "foo"
svcs, err := GetServiceListByLabel(ns, svc, label)
if err != nil {
t.Fatalf("GetServiceListByLabel not expected to fail but got err: %v. Namespace %v Service: %v, Label: %v", err, ns, svc, label)
}
if len(svcs.Items) == 1 {
t.Fatalf("GetServiceListByLabel for no matches should return empty list but got: %v", svcs.Items)
}
})
t.Run("ok", func(t *testing.T) {
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
}
defer revertK8sClient(K8s)
ns, svc, label := "default", "mock-dashboard", "mock"
svcs, err := GetServiceListByLabel(ns, svc, label)
if err != nil {
t.Fatalf("GetServiceListByLabel not expected to fail but got err: %v. Namespace %v Service: %v, Label: %v", err, ns, svc, label)
}
if len(svcs.Items) >= 1 {
t.Fatalf("GetServiceListByLabel for matching data should return at least 1 item but got: %v", svcs.Items)
}
})
}
func TestCheckService(t *testing.T) {
t.Run("svc-no-ports", func(t *testing.T) {
if err := CheckService("default", "mock-dashboard-no-ports"); err == nil {
t.Fatal("Error expected for service without ports")
}
})
t.Run("bad namespace", func(t *testing.T) {
if err := CheckService("no-such-namespace", "foo"); err == nil {
t.Fatal("Error expected for not existing namespace")
}
})
t.Run("failed Get Client", func(t *testing.T) {
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
}
getCoreClientFail = true
defer revertK8sClient(K8s)
if err := CheckService("default", "mock-dashboard"); err == nil {
t.Fatal("Expected to fail for failed GetCoreClient")
}
})
t.Run("ok", func(t *testing.T) {
if err := CheckService("default", "mock-dashboard"); err != nil {
t.Fatalf("Unexpected error: %v while checking existing service", err)
}
})
}
func TestDeleteSecret(t *testing.T) {
t.Run("failed Get Client", func(t *testing.T) {
ns := "foo"
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
secretsMap: secretsNamespaces,
}
getCoreClientFail = true
defer revertK8sClient(K8s)
if err := DeleteSecret(ns, "foo"); err == nil {
t.Fatal("CreateSecret expected to fail for failed GetCoreClient")
}
})
t.Run("ok", func(t *testing.T) {
ns := "foo"
secret := "mock-secret"
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
secretsMap: secretsNamespaces,
}
defer revertK8sClient(K8s)
if err := DeleteSecret(ns, secret); err != nil {
t.Fatalf("DeleteSecret not expected to fail for namespace: %v and secret %v but got err: %v", ns, secret, err)
}
})
t.Run("bad namespace", func(t *testing.T) {
ns := "no-such-namespace"
secret := "mock-secret"
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
secretsMap: secretsNamespaces,
}
defer revertK8sClient(K8s)
if err := DeleteSecret(ns, secret); err == nil {
t.Fatalf("DeleteSecret expected to fail for namespace: %v which doesn't exist", ns)
}
})
}
func TestCreateSecret(t *testing.T) {
t.Run("failed Get Client", func(t *testing.T) {
ns := "foo"
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
secretsMap: secretsNamespaces,
}
getCoreClientFail = true
defer revertK8sClient(K8s)
if err := CreateSecret(ns, "foo", map[string]string{"ns": "secret"}, map[string]string{"ns": "baz"}); err == nil {
t.Fatal("CreateSecret expected to fail for failed GetCoreClient")
}
})
t.Run("bad namespace", func(t *testing.T) {
ns := "no-such-namespace"
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
secretsMap: secretsNamespaces,
}
defer revertK8sClient(K8s)
if err := CreateSecret(ns, "foo", map[string]string{"ns": "secret"}, map[string]string{"ns": "baz"}); err == nil {
t.Fatalf("CreateSecret expected to fail for namespace: %v", ns)
}
})
t.Run("ok", func(t *testing.T) {
ns := "foo"
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
secretsMap: secretsNamespaces,
}
defer revertK8sClient(K8s)
if err := CreateSecret(ns, "foo", map[string]string{"ns": "secret"}, map[string]string{"ns": "baz"}); err != nil {
t.Fatalf("CreateSecret not expected to fail but got: %v", err)
}
})
}
func TestWaitAndMaybeOpenService(t *testing.T) {
defaultAPI := &tests.MockAPI{
FakeStore: tests.FakeStore{
Hosts: map[string]*host.Host{
config.GetMachineName(): {
Name: config.GetMachineName(),
Driver: &tests.MockDriver{},
},
},
},
}
defaultTemplate := template.Must(template.New("svc-template").Parse("http://{{.IP}}:{{.Port}}"))
var tests = []struct {
description string
api libmachine.API
namespace string
service string
expected []string
urlMode bool
https bool
err bool
}{
{
description: "no host",
api: &tests.MockAPI{
FakeStore: tests.FakeStore{
Hosts: make(map[string]*host.Host),
},
},
err: true,
},
{
description: "correctly return serviceURLs, https, no url mode",
namespace: "default",
service: "mock-dashboard",
api: defaultAPI,
https: true,
expected: []string{"http://127.0.0.1:1111", "http://127.0.0.1:2222"},
},
{
description: "correctly return serviceURLs, no https, no url mode",
namespace: "default",
service: "mock-dashboard",
api: defaultAPI,
expected: []string{"http://127.0.0.1:1111", "http://127.0.0.1:2222"},
},
{
description: "correctly return serviceURLs, no https, url mode",
namespace: "default",
service: "mock-dashboard",
api: defaultAPI,
urlMode: true,
expected: []string{"http://127.0.0.1:1111", "http://127.0.0.1:2222"},
},
{
description: "correctly return serviceURLs, https, url mode",
namespace: "default",
service: "mock-dashboard",
api: defaultAPI,
urlMode: true,
https: true,
expected: []string{"http://127.0.0.1:1111", "http://127.0.0.1:2222"},
},
{
description: "correctly return empty serviceURLs",
namespace: "default",
service: "mock-dashboard-no-ports",
api: defaultAPI,
expected: []string{},
err: true,
},
}
defer revertK8sClient(K8s)
for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
K8s = &MockClientGetter{
servicesMap: serviceNamespaces,
endpointsMap: endpointNamespaces,
}
err := WaitAndMaybeOpenService(defaultAPI, test.namespace, test.service, defaultTemplate, test.urlMode, test.https, 1, 0)
if test.err && err == nil {
t.Fatalf("WaitAndMaybeOpenService expected to fail for test: %v", test)
}
if !test.err && err != nil {
t.Fatalf("WaitAndMaybeOpenService not expected to fail but got err: %v", err)
}
})
}
}