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

WIP: Tests for #821: unexpose leaving previous K8S service unusable #962

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 244 additions & 0 deletions test/integration/examples/custom/helloworld/helloworld_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"log"
"os"
"testing"
"time"

"github.com/skupperproject/skupper/api/types"
"github.com/skupperproject/skupper/pkg/kube"
Expand Down Expand Up @@ -275,6 +276,20 @@ func TestHelloWorldCLI(t *testing.T) {
},
},
}},
{Ctx: prv, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-frontend:8080",
Silent: true,
ShowError: true,
Verbose: true,
},
&cli.CurlTester{
Target: "http://hello-world-backend:8080/api/hello",
Silent: true,
ShowError: true,
Verbose: true,
},
}},
},
}, {
Name: "service-unbind-delete",
Expand Down Expand Up @@ -413,6 +428,204 @@ func TestHelloWorldCLI(t *testing.T) {
},
}},
},
}, {
Name: "expose-service",
Tasks: []cli.SkupperTask{
{Ctx: prv, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-backend-k8s-service:8080/api/hello",
Silent: true,
ShowError: true,
Verbose: true,
},
}},
{Ctx: pub, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-backend-k8s-service:8080/api/hello",
ExpectFail: true, // this is a standard k8s service, so before exposure it does not exist on pub
Silent: true,
ShowError: true,
Verbose: true,
},
}},
{Ctx: prv, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-frontend-k8s-service:8080",
ExpectFail: true, // this is a standard k8s service, so before exposure it does not exist on pub
Silent: true,
ShowError: true,
Verbose: true,
},
}},
{Ctx: pub, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-frontend-k8s-service:8080",
Silent: true,
ShowError: true,
Verbose: true,
},
}},
{Ctx: pub, Commands: []cli.SkupperCommandTester{
// skupper expose - expose and ensure service is available
&cli.ExposeTester{
TargetType: "service",
TargetName: "hello-world-frontend-k8s-service",
Address: "hello-world-frontend-k8s-service",
Port: 8080,
Protocol: "http",
TargetPort: 8080,
},
// skupper status - asserts that 1 service is exposed
&cli.StatusTester{
RouterMode: "interior",
ConnectedSites: 1,
ExposedServices: 1,
ConsoleEnabled: true,
ConsoleAuthInternal: true,
},
}},
{Ctx: prv, Commands: []cli.SkupperCommandTester{
// skupper expose - exposes backend and certify it is available
&cli.ExposeTester{
TargetType: "service",
TargetName: "hello-world-backend-k8s-service",
Address: "hello-world-backend-k8s-service",
Port: 8080,
Protocol: "http",
TargetPort: 8080,
},
// skupper status - asserts that there are 2 exposed services
&cli.StatusTester{
RouterMode: "edge",
SiteName: "private",
ConnectedSites: 1,
ExposedServices: 2,
},
}},
{Ctx: prv, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-backend-k8s-service:8080/api/hello",
Interval: time.Second,
MaxRetries: 100,
Silent: true,
ShowError: true,
Verbose: true,
},
}},
{Ctx: pub, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-backend-k8s-service:8080/api/hello",
Interval: time.Second,
MaxRetries: 100,
Silent: true,
ShowError: true,
Verbose: true,
},
}},
{Ctx: prv, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-frontend-k8s-service:8080",
Interval: time.Second,
MaxRetries: 100,
Silent: true,
ShowError: true,
Verbose: true,
},
}},
{Ctx: pub, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-frontend-k8s-service:8080",
Interval: time.Second,
MaxRetries: 100,
Silent: true,
ShowError: true,
Verbose: true,
},
}},
},
}, {
Name: "unexpose-service",
Tasks: []cli.SkupperTask{
{Ctx: pub, Commands: []cli.SkupperCommandTester{
// skupper unexpose - unexpose and verify it has been removed
&cli.UnexposeTester{
TargetType: "service",
TargetName: "hello-world-frontend-k8s-service",
Address: "hello-world-frontend-k8s-service",
SkipRemovalValidation: true,
},
// skupper status - verify only 1 service is exposed
&cli.StatusTester{
RouterMode: "interior",
ConnectedSites: 1,
ExposedServices: 1,
ConsoleEnabled: true,
ConsoleAuthInternal: true,
},
}},
{Ctx: prv, Commands: []cli.SkupperCommandTester{
// skupper unexpose - unexpose and verify it has been removed
&cli.UnexposeTester{
TargetType: "deployment",
TargetName: "hello-world-backend-k8s-service",
Address: "hello-world-backend-k8s-service",
SkipRemovalValidation: true,
},
// skupper status - verify there is no exposed services
&cli.StatusTester{
RouterMode: "edge",
SiteName: "private",
ConnectedSites: 1,
ExposedServices: 0,
},
}},
{Ctx: prv, Commands: []cli.SkupperCommandTester{
// After unexpose, is the pre-existing k8s service still
// working on its own namespace?
&cli.CurlTester{
Target: "http://hello-world-backend-k8s-service:8080/api/hello",
Interval: time.Second,
MaxRetries: 100,
Silent: true,
ShowError: true,
Verbose: true,
},
}},
{Ctx: pub, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-backend-k8s-service:8080/api/hello",
ExpectFail: true, // this was a standard k8s service, so after unexpose it should not exist on pub
Interval: time.Second,
MaxRetries: 100,
Silent: true,
ShowError: true,
Verbose: true,
},
}},
{Ctx: prv, Commands: []cli.SkupperCommandTester{
&cli.CurlTester{
Target: "http://hello-world-frontend-k8s-service:8080",
ExpectFail: true, // this was a standard k8s service, so after unexpose it should not exist on prv
Interval: time.Second,
MaxRetries: 100,
Silent: true,
ShowError: true,
Verbose: true,
},
}},
{Ctx: pub, Commands: []cli.SkupperCommandTester{
// After unexpose, is the pre-existing k8s service still
// working on its own namespace?
&cli.CurlTester{
Target: "http://hello-world-frontend-k8s-service:8080",
Interval: time.Second,
MaxRetries: 100,
Silent: true,
ShowError: true,
Verbose: true,
},
}},
},
}, {
Name: "version",
Tasks: []cli.SkupperTask{
Expand Down Expand Up @@ -449,6 +662,11 @@ func TestHelloWorldCLI(t *testing.T) {
// Running the scenarios
cli.RunScenarios(t, scenarios)

if t.Failed() {
pub.DumpTestInfo("hello_world")
prv.DumpTestInfo("hello_world")
}

}

// deployResources Deploys the hello-world-frontend and hello-world-backend
Expand All @@ -473,6 +691,32 @@ func deployResources(pub *base.ClusterContext, prv *base.ClusterContext) error {
return err
}

// Creating k8s services
k8s.CreateService(
pub.VanClient,
"hello-world-frontend-k8s-service",
map[string]string{},
map[string]string{"app": "hello-world-frontend"},
map[string]string{"app": "hello-world-frontend"},
[]v1.ServicePort{
{
Port: 8080,
},
},
)
k8s.CreateService(
prv.VanClient,
"hello-world-backend-k8s-service",
map[string]string{},
map[string]string{"app": "hello-world-backend"},
map[string]string{"app": "hello-world-backend"},
[]v1.ServicePort{
{
Port: 8080,
},
},
)

// Waiting for deployments to be ready
if _, err := kube.WaitDeploymentReady("hello-world-frontend", pub.Namespace, pub.VanClient.KubeClient, constants.ImagePullingAndResourceCreationTimeout, constants.DefaultTick); err != nil {
return err
Expand Down
29 changes: 29 additions & 0 deletions test/utils/k8s/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"time"

"github.com/skupperproject/skupper/client"
"github.com/skupperproject/skupper/test/utils/constants"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -86,3 +87,31 @@ func WaitForSkupperServiceToBeCreatedAndReadyToUse(ns string, kubeClient kuberne
fmt.Printf("Waiting for skupper service: %s\n", serviceName)
return WaitForServiceToBeCreatedAndReadyToUse(ns, kubeClient, serviceName, time.Second*10)
}

// createService creates a new service at the provided cluster/namespace
// TODO this is a generic copy of annotation.createService. If this is to be kept,
// perhaps that function should call this. But perhaps this should be refactored into
// something that uses structures instead of individual arguments?
func CreateService(cluster *client.VanClient, name string, annotations, labels, selector map[string]string, ports []apiv1.ServicePort) (*apiv1.Service, error) {

svc := &apiv1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: labels,
Annotations: annotations,
},
Spec: apiv1.ServiceSpec{
Ports: ports,
Selector: selector,
Type: apiv1.ServiceTypeLoadBalancer,
},
Copy link
Member

@fgiorgetti fgiorgetti Dec 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be safer to create the service with ClusterIP, as depending on where the test is run
it won't get an IP.

}

// Creating the new service
svc, err := cluster.KubeClient.CoreV1().Services(cluster.Namespace).Create(svc)
if err != nil {
return nil, err
}

return svc, nil
}
Loading