This repository has been archived by the owner on Jul 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 277
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create e2e test for retry, tests fields retryOn and numRetries
Signed-off-by: Shalier Xia <shalierxia@microsoft.com>
- Loading branch information
Showing
7 changed files
with
348 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package main | ||
|
||
import ( | ||
_ "embed" | ||
"fmt" | ||
"net/http" | ||
"sync" | ||
|
||
"github.com/openservicemesh/osm/pkg/logger" | ||
"github.com/openservicemesh/osm/tests/e2e" | ||
) | ||
|
||
var log = logger.NewPretty("retry") | ||
|
||
var mu sync.Mutex | ||
var httpRequests uint32 | ||
|
||
const retryOn = 555 | ||
|
||
func retryHandler(w http.ResponseWriter, r *http.Request) { | ||
mu.Lock() | ||
// Count number of http requests received | ||
httpRequests++ | ||
mu.Unlock() | ||
|
||
// Return status code that causes retry policy | ||
if httpRequests <= e2e.NumRetries { | ||
w.WriteHeader(retryOn) | ||
} | ||
_, err := w.Write([]byte(fmt.Sprintf("RequestCount:%v\n", httpRequests))) | ||
if err != nil { | ||
log.Error().Err(err).Msgf("Couldn't write number of requests recevied") | ||
} | ||
} | ||
|
||
func main() { | ||
// mux := http.NewServeMux() | ||
http.HandleFunc("/", retryHandler) | ||
err := http.ListenAndServe(":9091", nil) | ||
log.Fatal().Err(err).Msgf("Failed to start HTTP server on port 9091") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
package e2e | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
||
"github.com/openservicemesh/osm/pkg/apis/policy/v1alpha1" | ||
. "github.com/openservicemesh/osm/tests/framework" | ||
) | ||
|
||
const client = "client" | ||
const server = "server" | ||
|
||
var meshNs = []string{client, server} | ||
|
||
var _ = OSMDescribe("Test Retry Policy", | ||
OSMDescribeInfo{ | ||
Tier: 2, | ||
Bucket: 8, | ||
}, | ||
func() { | ||
Context("Retry policy enabled", func() { | ||
It("tests retryOn and numRetries field for retry policy", | ||
func() { | ||
// Install OSM | ||
installOpts := Td.GetOSMInstallOpts() | ||
installOpts.EnablePermissiveMode = true | ||
installOpts.EnableRetryPolicy = true | ||
Expect(Td.InstallOSM(installOpts)).To(Succeed()) | ||
|
||
// Create test NS in mesh | ||
for _, n := range meshNs { | ||
Expect(Td.CreateNs(n, nil)).To(Succeed()) | ||
Expect(Td.AddNsToMesh(true, n)).To(Succeed()) | ||
} | ||
|
||
// Load retry image | ||
retryImage := fmt.Sprintf("%s/retry:%s", installOpts.ContainerRegistryLoc, installOpts.OsmImagetag) | ||
Expect(Td.LoadImagesToKind([]string{"retry"})).To(Succeed()) | ||
|
||
svcAccDef, podDef, svcDef, err := Td.SimplePodApp( | ||
SimplePodAppDef{ | ||
PodName: server, | ||
Namespace: server, | ||
ServiceAccountName: server, | ||
Command: []string{"/retry"}, | ||
Image: retryImage, | ||
Ports: []int{9091}, | ||
OS: Td.ClusterOS, | ||
}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
_, err = Td.CreateServiceAccount(server, &svcAccDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
_, err = Td.CreatePod(server, podDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
serverSvc, err := Td.CreateService(server, svcDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
Expect(Td.WaitForPodsRunningReady(server, 90*time.Second, 1, nil)).To(Succeed()) | ||
|
||
// Get simple Pod definitions for the source/client | ||
svcAccDef, podDef, svcDef, err = Td.SimplePodApp(SimplePodAppDef{ | ||
PodName: client, | ||
Namespace: client, | ||
Command: []string{"sleep", "365d"}, | ||
Image: "curlimages/curl", | ||
Ports: []int{80}, | ||
OS: Td.ClusterOS, | ||
}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
clientSvcAcct, err := Td.CreateServiceAccount(client, &svcAccDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
clientPod, err := Td.CreatePod(client, podDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
_, err = Td.CreateService(client, svcDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
Expect(Td.WaitForPodsRunningReady(client, 90*time.Second, 1, nil)).To(Succeed()) | ||
|
||
retry := &v1alpha1.Retry{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "retrypolicy", | ||
Namespace: client, | ||
}, | ||
Spec: v1alpha1.RetrySpec{ | ||
Source: v1alpha1.RetrySrcDstSpec{ | ||
Kind: "ServiceAccount", | ||
Name: clientSvcAcct.Name, | ||
Namespace: client, | ||
}, | ||
Destinations: []v1alpha1.RetrySrcDstSpec{ | ||
{ | ||
Kind: "Service", | ||
Name: serverSvc.Name, | ||
Namespace: server, | ||
}, | ||
}, | ||
RetryPolicy: v1alpha1.RetryPolicySpec{ | ||
RetryOn: "5xx", | ||
PerTryTimeout: &metav1.Duration{Duration: time.Duration(1 * time.Second)}, | ||
NumRetries: &NumRetries, | ||
RetryBackoffBaseInterval: &metav1.Duration{Duration: time.Duration(5 * time.Second)}, | ||
}, | ||
}, | ||
} | ||
_, err = Td.PolicyClient.PolicyV1alpha1().Retries(client).Create(context.TODO(), retry, metav1.CreateOptions{}) | ||
Expect(err).ToNot((HaveOccurred())) | ||
|
||
req := HTTPRequestDef{ | ||
SourceNs: client, | ||
SourcePod: clientPod.Name, | ||
SourceContainer: podDef.GetName(), | ||
Destination: fmt.Sprintf("%s.%s.svc.cluster.local:9091", serverSvc.Name, server), | ||
} | ||
|
||
By("A request that will be retried NumRetries times then succeed") | ||
// wait for server | ||
time.Sleep(3 * time.Second) | ||
result := Td.RetryHTTPRequest(req) | ||
// One count is the initial http request that returns a retriable status code | ||
// followed by numRetries retries | ||
Expect(result.RequestCount).To(Equal(int(NumRetries) + 1)) | ||
Expect(result.StatusCode).To(Equal(200)) | ||
Expect(result.Err).To(BeNil()) | ||
}) | ||
}) | ||
Context("Retry policy disabled", func() { | ||
It("tests retry does not occur", | ||
func() { | ||
// Install OSM | ||
installOpts := Td.GetOSMInstallOpts() | ||
installOpts.EnablePermissiveMode = true | ||
installOpts.EnableRetryPolicy = false | ||
Expect(Td.InstallOSM(installOpts)).To(Succeed()) | ||
|
||
// Create test NS in mesh | ||
for _, n := range meshNs { | ||
Expect(Td.CreateNs(n, nil)).To(Succeed()) | ||
Expect(Td.AddNsToMesh(true, n)).To(Succeed()) | ||
} | ||
// Load retry image | ||
retryImage := fmt.Sprintf("%s/retry:%s", installOpts.ContainerRegistryLoc, installOpts.OsmImagetag) | ||
Expect(Td.LoadImagesToKind([]string{"retry"})).To(Succeed()) | ||
|
||
svcAccDef, podDef, svcDef, err := Td.SimplePodApp( | ||
SimplePodAppDef{ | ||
PodName: server, | ||
Namespace: server, | ||
ServiceAccountName: server, | ||
Command: []string{"/retry"}, | ||
Image: retryImage, | ||
Ports: []int{9091}, | ||
OS: Td.ClusterOS, | ||
}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
_, err = Td.CreateServiceAccount(server, &svcAccDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
_, err = Td.CreatePod(server, podDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
serverSvc, err := Td.CreateService(server, svcDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
Expect(Td.WaitForPodsRunningReady(server, 90*time.Second, 1, nil)).To(Succeed()) | ||
|
||
// Get simple Pod definitions for the source/client | ||
svcAccDef, podDef, svcDef, err = Td.SimplePodApp(SimplePodAppDef{ | ||
PodName: client, | ||
Namespace: client, | ||
Command: []string{"sleep", "365d"}, | ||
Image: "curlimages/curl", | ||
Ports: []int{80}, | ||
OS: Td.ClusterOS, | ||
}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
clientSvcAcct, err := Td.CreateServiceAccount(client, &svcAccDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
clientPod, err := Td.CreatePod(client, podDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
_, err = Td.CreateService(client, svcDef) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
Expect(Td.WaitForPodsRunningReady(client, 90*time.Second, 1, nil)).To(Succeed()) | ||
|
||
retry := &v1alpha1.Retry{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "retrypolicy", | ||
Namespace: client, | ||
}, | ||
Spec: v1alpha1.RetrySpec{ | ||
Source: v1alpha1.RetrySrcDstSpec{ | ||
Kind: "ServiceAccount", | ||
Name: clientSvcAcct.Name, | ||
Namespace: client, | ||
}, | ||
Destinations: []v1alpha1.RetrySrcDstSpec{ | ||
{ | ||
Kind: "Service", | ||
Name: serverSvc.Name, | ||
Namespace: server, | ||
}, | ||
}, | ||
RetryPolicy: v1alpha1.RetryPolicySpec{ | ||
RetryOn: "5xx", | ||
PerTryTimeout: &metav1.Duration{Duration: time.Duration(1 * time.Second)}, | ||
NumRetries: &NumRetries, | ||
RetryBackoffBaseInterval: &metav1.Duration{Duration: time.Duration(5 * time.Second)}, | ||
}, | ||
}, | ||
} | ||
_, err = Td.PolicyClient.PolicyV1alpha1().Retries(client).Create(context.TODO(), retry, metav1.CreateOptions{}) | ||
Expect(err).ToNot((HaveOccurred())) | ||
|
||
req := HTTPRequestDef{ | ||
SourceNs: client, | ||
SourcePod: clientPod.Name, | ||
SourceContainer: podDef.GetName(), | ||
Destination: fmt.Sprintf("%s.%s.svc.cluster.local:9091", serverSvc.Name, server), | ||
} | ||
|
||
By("A request that will not be retried on") | ||
// wait for server | ||
time.Sleep(3 * time.Second) | ||
result := Td.RetryHTTPRequest(req) | ||
// One count is the initial http request that is not retried on | ||
Expect(result.RequestCount).To(Equal(1)) | ||
Expect(result.StatusCode).To(Equal(555)) | ||
Expect(result.Err).To(BeNil()) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.