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

[Test] Implement RayService In-place update test in Golang #2536

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

CheyuWu
Copy link
Contributor

@CheyuWu CheyuWu commented Nov 12, 2024

Why are these changes needed?

Implement test_in_place_update in Golang, and add a file rayservice_in_place_update_test.go under https://github.com/ray-project/kuberay/tree/master/ray-operator/test/e2e.

Related issue number

Close #2516

Checks

  • I've made sure the tests are passing.
  • Testing Strategy
    • Unit tests
    • Manual tests
    • This PR is not tested :(

@CheyuWu
Copy link
Contributor Author

CheyuWu commented Nov 12, 2024

@kevin85421 @MortalHappiness
PTAL

Comment on lines 65 to 67
func GetRayService(t Test, namespace, name string) (*rayv1.RayService, error) {
return t.Client().Ray().RayV1().RayServices(namespace).Get(t.Ctx(), name, metav1.GetOptions{})
}
Copy link
Member

Choose a reason for hiding this comment

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

Could you rebase with the master branch? This function already exists on the master branch.

serveConfig = strings.Replace(serveConfig, "factor: 5", "factor: 3", -1)

rayService.Spec.ServeConfigV2 = serveConfig
rs, err := UpdateRayServiceConfig(test, namespace.Name, rayServiceFromYaml.Name, serveConfig)
Copy link
Member

@MortalHappiness MortalHappiness Nov 13, 2024

Choose a reason for hiding this comment

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

I think we don't need this UpdateRayServiceConfig function. Simply call t.Client().Ray().RayV1().RayServices(namespace).Update directly here is enough.

}

func SetupPortForward(t Test, podName, namespace string, localPort, remotePort int) (chan struct{}, error) {
func SetupPortForward(t Test, req *rest.Request, localPort, remotePort int) (chan struct{}, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Just curious about why the function signature changed?

Copy link
Contributor Author

@CheyuWu CheyuWu Nov 13, 2024

Choose a reason for hiding this comment

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

Well, when I was working on this task, I was considering whether to use the method of creating a curl pod or setting up a port-forward. I then encountered an issue where SetupPortForward couldn’t port-forward the service, so I initially switched to a more general approach. Ultimately, I decided to go with creating a curl pod, but I forgot to delete it afterward.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should I revert this or just keep it?

Copy link
Member

@MortalHappiness MortalHappiness Nov 13, 2024

Choose a reason for hiding this comment

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

I think you can revert it because it is not related to this PR.

{
Name: containerName,
Image: "rancher/curl",
Command: []string{"/bin/sh", "-c", "while true; do sleep 10; done"},
Copy link
Member

Choose a reason for hiding this comment

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

I think tail -f /dev/null is better here.

Comment on lines 38 to 45
rs, err := GetRayService(test, namespace.Name, rayServiceFromYaml.Name)
g.Expect(err).NotTo(HaveOccurred())
if rs.Status.PendingServiceStatus.RayClusterName != "" {
rayClusterName = rs.Status.PendingServiceStatus.RayClusterName
} else if rs.Status.ActiveServiceStatus.RayClusterName != "" {
rayClusterName = rs.Status.ActiveServiceStatus.RayClusterName
}
g.Expect(rayClusterName).NotTo(BeEmpty())
Copy link
Member

Choose a reason for hiding this comment

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

I found the logic here also appears in ray-operator/test/sampleyaml/rayservice_test.go. We can refactor this logic to a helper function called UnderlyingRayCluster that takes RayService as input and returns RayCluster, and then use WithTransform in both places.

curlPodName := "curl-pod"
curlContainerName := "curl-container"

curlPod, err := CreateCurlPod(test, curlPodName, curlContainerName, namespace.Name)
Copy link
Member

Choose a reason for hiding this comment

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

We should wait until the curl pod becomes ready using Eventually

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I check the curl pod status below the create curl pod

Copy link
Member

Choose a reason for hiding this comment

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

Oh I found it. I think you can put it directly under this line to improve readability.

Comment on lines 95 to 96
rsStatus := RayServiceStatus(rs)
g.Expect(rsStatus).To(Equal(rayv1.Running))
Copy link
Member

Choose a reason for hiding this comment

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

Only these 2 lines need to be wrapped with Eventually. We don't want to updte the rayservice config repeatedly.

Comment on lines 100 to 109
g.Eventually(func(g Gomega) {
newRs, err := GetRayService(test, namespace.Name, rayServiceFromYaml.Name)
g.Expect(err).NotTo(HaveOccurred())
// curl /fruit
stdout, _ := curlRayServicePod(test, newRs, curlPod, curlContainerName, "/fruit", `["MANGO", 2]`)
g.Expect(stdout.String()).To(Equal("8"))
// curl /calc
stdout, _ = curlRayServicePod(test, newRs, curlPod, curlContainerName, "/calc", `["MUL", 3]`)
g.Expect(stdout.String()).To(Equal("9 pizzas please!"))
}, TestTimeoutShort).Should(Succeed())
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need to wrap these lines in Eventually.

Copy link
Contributor Author

@CheyuWu CheyuWu Nov 13, 2024

Choose a reason for hiding this comment

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

The reason I'm wrapping this with Eventually is that the curl request is made too quickly, and the results are not correct. However, If I retry the steps it will succeed eventually. So, I wrap with Eventually

Copy link
Member

@MortalHappiness MortalHappiness Nov 13, 2024

Choose a reason for hiding this comment

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

Why if the result will be incorrect if the curl request is sent too quickly? Once we make sure both the RayService and the curl pod are running and ready, the request must succeed. Do you know the root cause of why the result may be incorrect?

Copy link
Contributor Author

@CheyuWu CheyuWu Nov 13, 2024

Choose a reason for hiding this comment

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

I'm thinking it might be that the service hasn't cleared the original resources yet. Waiting for 5 seconds works. I'll take a look and see how I can handle this.

Copy link
Member

Choose a reason for hiding this comment

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

Great! Once you find the root cause, you can use Eventually to wait for that state change to steady state before sending requests.

Copy link
Contributor Author

@CheyuWu CheyuWu Nov 13, 2024

Choose a reason for hiding this comment

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

I think I forget to check g.Expect(newRs.Status.ObservedGeneration).To(Equal(newRs.Generation))
Eventually is not need anymore

@CheyuWu
Copy link
Contributor Author

CheyuWu commented Nov 14, 2024

I've made all the necessary changes. If there’s anything else that needs to be modified, please let me know. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature] Implement RayService In-place update test in Golang
2 participants