Skip to content

Commit 742edd8

Browse files
author
Sotiris Nanopoulos
authored
test(windows): Enable more Windows tests (openservicemesh#4143)
Despite issue openservicemesh#4141 I was able to validate and enable a bunch of tests on Windows 1. Add a Windows pod for tcp requests 2. Add a Windows pod for httpbin 3. Aggregate timeouts accross platform on a single variable Signed-off-by: Sotiris Nanopoulos <[email protected]>
1 parent 88f30f5 commit 742edd8

File tree

10 files changed

+123
-57
lines changed

10 files changed

+123
-57
lines changed

tests/e2e/e2e_controller_restart_test.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var _ = OSMDescribe("Test HTTP traffic from 1 pod client -> 1 pod server before
1515
OSMDescribeInfo{
1616
Tier: 2,
1717
Bucket: 1,
18+
OS: OSCrossPlatform,
1819
},
1920
func() {
2021
Context("SimpleClientServer traffic test involving osm-controller restart: HTTP", func() {
@@ -40,14 +41,7 @@ func testHTTPTrafficWithControllerRestart() {
4041
}
4142

4243
// Get simple pod definitions for the HTTP server
43-
svcAccDef, podDef, svcDef, err := Td.SimplePodApp(
44-
SimplePodAppDef{
45-
PodName: destName,
46-
Namespace: destName,
47-
Image: "kennethreitz/httpbin",
48-
Ports: []int{80},
49-
OS: Td.ClusterOS,
50-
})
44+
svcAccDef, podDef, svcDef, err := Td.GetOSSpecificHTTPBinPod(destName, destName)
5145
Expect(err).NotTo(HaveOccurred())
5246

5347
_, err = Td.CreateServiceAccount(destName, &svcAccDef)
@@ -88,7 +82,7 @@ func testHTTPTrafficWithControllerRestart() {
8882
SourcePod: srcPod.Name,
8983
SourceContainer: srcPod.Name,
9084

91-
Destination: fmt.Sprintf("%s.%s", dstSvc.Name, dstSvc.Namespace),
85+
Destination: fmt.Sprintf("%s.%s.svc.cluster.local", dstSvc.Name, dstSvc.Namespace),
9286
}
9387

9488
srcToDestStr := fmt.Sprintf("%s -> %s",
@@ -105,7 +99,7 @@ func testHTTPTrafficWithControllerRestart() {
10599
}
106100
Td.T.Logf("> (%s) HTTP Req succeeded: %d", srcToDestStr, result.StatusCode)
107101
return true
108-
}, 5, 90*time.Second)
102+
}, 5, Td.ReqSuccessTimeout)
109103

110104
Expect(cond).To(BeTrue(), "Failed testing HTTP traffic from source pod %s to destination service %s", srcPod.Name, dstSvc.Name)
111105

@@ -124,7 +118,7 @@ func testHTTPTrafficWithControllerRestart() {
124118
}
125119
Td.T.Logf("%s > (%s) HTTP Req succeeded: %d", time.Now(), srcToDestStr, result.StatusCode)
126120
return true
127-
}, 20, 80*time.Second)
121+
}, 20, Td.ReqSuccessTimeout)
128122
Expect(cond).To(BeTrue(), "Failed testing HTTP traffic from source pod %s to destination service %s after osm-controller restart", srcPod.Name, dstSvc.Name)
129123
})
130124
}

tests/e2e/e2e_egress_test.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
. "github.com/onsi/ginkgo"
88
. "github.com/onsi/gomega"
99

10-
"github.com/openservicemesh/osm/pkg/constants"
1110
. "github.com/openservicemesh/osm/tests/framework"
1211
)
1312

@@ -45,7 +44,7 @@ var _ = OSMDescribe("HTTP and HTTPS Egress",
4544
Expect(err).NotTo(HaveOccurred())
4645

4746
// Expect it to be up and running in it's receiver namespace
48-
Expect(Td.WaitForPodsRunningReady(sourceNs, 240*time.Second, 1, nil)).To(Succeed())
47+
Expect(Td.WaitForPodsRunningReady(sourceNs, Td.PodDeploymentTimeout, 1, nil)).To(Succeed())
4948
protocols := []string{
5049
"http://",
5150
"https://",
@@ -61,12 +60,6 @@ var _ = OSMDescribe("HTTP and HTTPS Egress",
6160
}
6261
}
6362

64-
waitTime := 60 * time.Second
65-
if Td.ClusterOS == constants.OSWindows {
66-
//TODO(#4027): Make the timeouts equal on all platforms.
67-
waitTime = 5 * 60 * time.Second
68-
}
69-
7063
for _, url := range urls {
7164
cond := Td.WaitForRepeatedSuccess(func() bool {
7265
result := Td.HTTPRequest(HTTPRequestDef{
@@ -83,7 +76,7 @@ var _ = OSMDescribe("HTTP and HTTPS Egress",
8376
}
8477
Td.T.Logf("%s > REST req succeeded: %d", url, result.StatusCode)
8578
return true
86-
}, 5, waitTime)
79+
}, 5, Td.ReqSuccessTimeout)
8780
Expect(cond).To(BeTrue())
8881
}
8982

tests/e2e/e2e_pod_client_server_test.go

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ import (
1212
v1 "k8s.io/api/core/v1"
1313
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1414

15+
"github.com/openservicemesh/osm/pkg/constants"
1516
. "github.com/openservicemesh/osm/tests/framework"
1617
)
1718

1819
var _ = OSMDescribe("Test HTTP traffic from 1 pod client -> 1 pod server",
1920
OSMDescribeInfo{
2021
Tier: 1,
2122
Bucket: 7,
23+
OS: OSCrossPlatform,
2224
},
2325
func() {
2426
Context("Test traffic flowing from client to server with a Kubernetes Service for the Source: HTTP", func() {
@@ -51,14 +53,7 @@ func testTraffic(withSourceKubernetesService bool) {
5153
}
5254

5355
// Get simple pod definitions for the HTTP server
54-
svcAccDef, podDef, svcDef, err := Td.SimplePodApp(
55-
SimplePodAppDef{
56-
PodName: destName,
57-
Namespace: destName,
58-
Image: "kennethreitz/httpbin",
59-
Ports: []int{80},
60-
OS: Td.ClusterOS,
61-
})
56+
svcAccDef, podDef, svcDef, err := Td.GetOSSpecificHTTPBinPod(destName, destName)
6257
Expect(err).NotTo(HaveOccurred())
6358

6459
_, err = Td.CreateServiceAccount(destName, &svcAccDef)
@@ -99,7 +94,7 @@ func testTraffic(withSourceKubernetesService bool) {
9994
SourcePod: srcPod.Name,
10095
SourceContainer: sourceName,
10196

102-
Destination: fmt.Sprintf("%s.%s", dstSvc.Name, dstSvc.Namespace),
97+
Destination: fmt.Sprintf("%s.%s.svc.cluster.local", dstSvc.Name, dstSvc.Namespace),
10398
}
10499

105100
srcToDestStr := fmt.Sprintf("%s -> %s",
@@ -116,7 +111,7 @@ func testTraffic(withSourceKubernetesService bool) {
116111
}
117112
Td.T.Logf("> (%s) HTTP Req succeeded: %d", srcToDestStr, result.StatusCode)
118113
return true
119-
}, 5, 90*time.Second)
114+
}, 5, Td.ReqSuccessTimeout)
120115

121116
sourceService := map[bool]string{true: "with", false: "without"}[withSourceKubernetesService]
122117
Expect(cond).To(BeTrue(), "Failed testing HTTP traffic from source pod %s Kubernetes Service to a destination", sourceService)
@@ -142,15 +137,32 @@ func testTraffic(withSourceKubernetesService bool) {
142137
}
143138

144139
func setupSource(sourceName string, withKubernetesService bool) *v1.Pod {
145-
// Get simple Pod definitions for the client
146-
svcAccDef, podDef, svcDef, err := Td.SimplePodApp(SimplePodAppDef{
147-
PodName: sourceName,
148-
Namespace: sourceName,
149-
Command: []string{"sleep", "365d"},
150-
Image: "curlimages/curl",
151-
Ports: []int{80},
152-
OS: Td.ClusterOS,
153-
})
140+
var svcAccDef v1.ServiceAccount
141+
var podDef v1.Pod
142+
var svcDef v1.Service
143+
var err error
144+
if Td.ClusterOS == constants.OSWindows {
145+
svcAccDef, podDef, svcDef, err = Td.SimplePodApp(SimplePodAppDef{
146+
PodName: sourceName,
147+
Namespace: sourceName,
148+
Command: []string{"cmd", "/c"},
149+
Args: []string{"FOR /L %N IN () DO ping -n 30 127.0.0.1> nul"},
150+
Image: WindowsNanoserverDockerImage,
151+
Ports: []int{80},
152+
OS: Td.ClusterOS,
153+
})
154+
} else {
155+
// Get simple Pod definitions for the client
156+
svcAccDef, podDef, svcDef, err = Td.SimplePodApp(SimplePodAppDef{
157+
PodName: sourceName,
158+
Namespace: sourceName,
159+
Command: []string{"sleep", "365d"},
160+
Image: "curlimages/curl",
161+
Ports: []int{80},
162+
OS: Td.ClusterOS,
163+
})
164+
}
165+
154166
Expect(err).NotTo(HaveOccurred())
155167

156168
_, err = Td.CreateServiceAccount(sourceName, &svcAccDef)
@@ -166,7 +178,7 @@ func setupSource(sourceName string, withKubernetesService bool) *v1.Pod {
166178
}
167179

168180
// Expect it to be up and running in it's receiver namespace
169-
Expect(Td.WaitForPodsRunningReady(sourceName, 90*time.Second, 1, nil)).To(Succeed())
181+
Expect(Td.WaitForPodsRunningReady(sourceName, Td.PodDeploymentTimeout, 1, nil)).To(Succeed())
170182

171183
return srcPod
172184
}

tests/e2e/e2e_tcp_client_server_test.go

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111

1212
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1313

14-
"github.com/openservicemesh/osm/pkg/constants"
1514
"github.com/openservicemesh/osm/tests/framework"
1615
. "github.com/openservicemesh/osm/tests/framework"
1716
)
@@ -20,6 +19,7 @@ var _ = OSMDescribe("Test TCP traffic from 1 pod client -> 1 pod server",
2019
OSMDescribeInfo{
2120
Tier: 1,
2221
Bucket: 8,
22+
OS: OSCrossPlatform,
2323
},
2424
func() {
2525
Context("SimpleClientServer TCP with SMI policies", func() {
@@ -56,17 +56,8 @@ func testTCPTraffic(permissiveMode bool) {
5656
destinationPort := 80
5757

5858
// Get simple pod definitions for the TCP server
59-
svcAccDef, podDef, svcDef, err := Td.SimplePodApp(
60-
SimplePodAppDef{
61-
PodName: framework.RandomNameWithPrefix("pod"),
62-
Namespace: destNs,
63-
Image: fmt.Sprintf("%s/tcp-echo-server:%s", installOpts.ContainerRegistryLoc, installOpts.OsmImagetag),
64-
Command: []string{"/tcp-echo-server"},
65-
Args: []string{"--port", fmt.Sprintf("%d", destinationPort)},
66-
Ports: []int{destinationPort},
67-
AppProtocol: constants.ProtocolTCP,
68-
OS: Td.ClusterOS,
69-
})
59+
svcAccDef, podDef, svcDef, err := Td.GetOSSpecificTCPEchoPod(framework.RandomNameWithPrefix("pod"), destNs, destinationPort)
60+
7061
Expect(err).NotTo(HaveOccurred())
7162

7263
_, err = Td.CreateServiceAccount(destNs, &svcAccDef)
@@ -115,7 +106,7 @@ func testTCPTraffic(permissiveMode bool) {
115106
SourcePod: srcPod.Name,
116107
SourceContainer: srcPod.Name,
117108

118-
DestinationHost: fmt.Sprintf("%s.%s", dstSvc.Name, dstSvc.Namespace),
109+
DestinationHost: fmt.Sprintf("%s.%s.svc.cluster.local", dstSvc.Name, dstSvc.Namespace),
119110
DestinationPort: destinationPort,
120111
Message: requestMsg,
121112
}
@@ -140,7 +131,7 @@ func testTCPTraffic(permissiveMode bool) {
140131
}
141132
Td.T.Logf("> (%s) TCP Req succeeded, response: %s", srcToDestStr, result.Response)
142133
return true
143-
}, 5, 90*time.Second)
134+
}, 5, Td.ReqSuccessTimeout)
144135

145136
Expect(cond).To(BeTrue(), "Failed testing TCP traffic from %s", srcToDestStr)
146137

tests/e2e/e2e_tcp_egress_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ var _ = OSMDescribe("Test TCP traffic from 1 pod client -> egress server",
1616
OSMDescribeInfo{
1717
Tier: 1,
1818
Bucket: 9,
19+
// TODO(#1610): This test assumes that the user can create a pod that is not part of the mesh.
20+
// On Windows we set the HNS policies on all pods on the cluster and as a result we can't
21+
// have pods that are not part of the mesh. This will be resolved when OSM CNI is available.
22+
OS: constants.OSLinux,
1923
},
2024
func() {
2125
Context("SimpleClientServer egress TCP", func() {

tests/framework/common.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,13 @@ func (td *OsmTestData) InitTestData(t GinkgoTInterface) error {
217217

218218
if td.DeployOnWindowsWorkers {
219219
td.ClusterOS = constants.OSWindows
220+
//TODO(#4027): Make the timeouts equal on all platforms.
221+
td.ReqSuccessTimeout = 5 * 60 * time.Second
222+
td.PodDeploymentTimeout = 240 * time.Second
220223
} else {
221224
td.ClusterOS = constants.OSLinux
225+
td.ReqSuccessTimeout = 60 * time.Second
226+
td.PodDeploymentTimeout = 90 * time.Second
222227
}
223228

224229
// String parameter validation

tests/framework/common_apps.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,30 @@ func (td *OsmTestData) SimpleDeploymentApp(def SimpleDeploymentAppDef) (corev1.S
545545
return serviceAccountDefinition, deploymentDefinition, serviceDefinition, nil
546546
}
547547

548+
// GetOSSpecificHTTPBinPod returns a OS pod that runs httpbin.
549+
func (td *OsmTestData) GetOSSpecificHTTPBinPod(podName string, namespace string) (corev1.ServiceAccount, corev1.Pod, corev1.Service, error) {
550+
if td.ClusterOS == constants.OSWindows {
551+
return Td.SimplePodApp(
552+
SimplePodAppDef{
553+
PodName: podName,
554+
Namespace: namespace,
555+
Command: []string{"bin/go-httpbin.exe"},
556+
Args: []string{"--port", "80"},
557+
Image: HttpbinOSMWindowsImage,
558+
Ports: []int{80},
559+
OS: Td.ClusterOS,
560+
})
561+
}
562+
return Td.SimplePodApp(
563+
SimplePodAppDef{
564+
PodName: podName,
565+
Namespace: namespace,
566+
Image: "kennethreitz/httpbin",
567+
Ports: []int{80},
568+
OS: Td.ClusterOS,
569+
})
570+
}
571+
548572
// GetOSSpecificSleepPod returns a simple OS specific busy loop pod.
549573
func (td *OsmTestData) GetOSSpecificSleepPod(sourceNs string) (corev1.ServiceAccount, corev1.Pod, corev1.Service, error) {
550574
if td.ClusterOS == constants.OSWindows {
@@ -569,6 +593,31 @@ func (td *OsmTestData) GetOSSpecificSleepPod(sourceNs string) (corev1.ServiceAcc
569593
})
570594
}
571595

596+
// GetOSSpecificTCPEchoPod returns a simple OS specific tcp-echo pod.
597+
func (td *OsmTestData) GetOSSpecificTCPEchoPod(podName string, namespace string, destinationPort int) (corev1.ServiceAccount, corev1.Pod, corev1.Service, error) {
598+
var image string
599+
var command string
600+
installOpts := Td.GetOSMInstallOpts()
601+
if td.ClusterOS == constants.OSWindows {
602+
image = fmt.Sprintf("%s/tcp-echo-server-windows:%s", installOpts.ContainerRegistryLoc, installOpts.OsmImagetag)
603+
command = "/tcp-echo-server.exe"
604+
} else {
605+
image = fmt.Sprintf("%s/tcp-echo-server:%s", installOpts.ContainerRegistryLoc, installOpts.OsmImagetag)
606+
command = "/tcp-echo-server"
607+
}
608+
return Td.SimplePodApp(
609+
SimplePodAppDef{
610+
PodName: podName,
611+
Namespace: namespace,
612+
Image: image,
613+
Command: []string{command},
614+
Args: []string{"--port", fmt.Sprintf("%d", destinationPort)},
615+
Ports: []int{destinationPort},
616+
AppProtocol: constants.ProtocolTCP,
617+
OS: Td.ClusterOS,
618+
})
619+
}
620+
572621
// GetGrafanaPodHandle generic func to forward a grafana pod and returns a handler pointing to the locally forwarded resource
573622
func (td *OsmTestData) GetGrafanaPodHandle(ns string, grafanaPodName string, port uint16) (*Grafana, error) {
574623
dialer, err := k8s.DialerToPod(td.RestConfig, td.Client, grafanaPodName, ns)

tests/framework/common_traffic.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,18 @@ func (td *OsmTestData) HTTPRequest(ht HTTPRequestDef) HTTPRequestResult {
134134

135135
// TCPRequest runs a synchronous TCP request to run the TCPRequestDef and return a TCPRequestResult
136136
func (td *OsmTestData) TCPRequest(req TCPRequestDef) TCPRequestResult {
137-
commandArgs := fmt.Sprintf("echo \"%s\" | nc %s %d", req.Message, req.DestinationHost, req.DestinationPort)
138-
command := []string{"sh", "-c", commandArgs}
137+
var command []string
138+
if td.ClusterOS == constants.OSWindows {
139+
powershellCommand := fmt.Sprintf("$IP = [System.Net.Dns]::GetHostAddresses('%s');", req.DestinationHost) +
140+
fmt.Sprintf("$Socket = New-Object System.Net.Sockets.TCPClient($IP, %d);", req.DestinationPort) +
141+
"$Stream = $Socket.GetStream(); $Writer = New-Object System.IO.StreamWriter($Stream);" +
142+
fmt.Sprintf(" $Writer.WriteLine('%s'); $Writer.Flush();", req.Message) +
143+
"$reader = New-Object System.IO.StreamReader($Stream); Write-Host -NoNewline $reader.ReadLine()"
144+
command = []string{"pwsh.exe", "-c", powershellCommand}
145+
} else {
146+
commandArgs := fmt.Sprintf("echo \"%s\" | nc %s %d", req.Message, req.DestinationHost, req.DestinationPort)
147+
command = []string{"sh", "-c", commandArgs}
148+
}
139149

140150
stdout, stderr, err := td.RunRemote(req.SourceNs, req.SourcePod, req.SourceContainer, command)
141151
if err != nil {

tests/framework/constants.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,8 @@ const (
7474
EnvoyOSMWindowsImage = "openservicemesh/envoy-windows-nanoserver@sha256:94590d10bc8a46c60cd3a3858d80f3d6577d4e9a191fa05c0077f8b3d6002e22"
7575

7676
// WindowsNanoserverDockerImage is the base Windows image that is compatible with the test cluster.
77-
WindowsNanoserverDockerImage = "mcr.microsoft.com/windows/nanoserver/insider:10.0.20348.1"
77+
WindowsNanoserverDockerImage = "mcr.microsoft.com/powershell:lts-nanoserver-ltsc2022"
78+
79+
// HttpbinOSMWindowsImage is the Windows based httpbin image used for testing.
80+
HttpbinOSMWindowsImage = "openservicemesh/go-http-win@sha256:dd81377aa0ff749a5a9a7a1a25786a710f77991c94b3015f674163e32d7fe5f8"
7881
)

tests/framework/types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package framework
22

33
import (
4+
"time"
5+
46
"github.com/onsi/ginkgo"
57
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
68
"k8s.io/client-go/kubernetes"
@@ -66,6 +68,9 @@ type OsmTestData struct {
6668

6769
ClusterOS string // The operating system of the working nodes in the cluster. Mixed OS traffic is not supported.
6870

71+
ReqSuccessTimeout time.Duration // ReqSuccessTimeout timeout duration that the test expects for all requests from the client to server to succeed.
72+
PodDeploymentTimeout time.Duration // PodDeploymentTimeout timeout duration that the test expects for all pods to be in ready state after they are deployed.
73+
6974
// Cluster handles and rest config
7075
Env *cli.EnvSettings
7176
RestConfig *rest.Config

0 commit comments

Comments
 (0)