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

refactor: Refactor -p/--publish flag test for run command #39

Merged
Merged
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
21 changes: 8 additions & 13 deletions fnet/dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,26 @@
package fnet

import (
"net"
"net/http"
"time"

"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
)

// DialAndRead dials the network address, reads the data from the established connection, and asserts it against want.
func DialAndRead(network, address, want string, maxRetry int, retryInterval time.Duration) {
var (
conn net.Conn
err error
)
// HTTPGetAndAssert sends an HTTP GET request to the specified URL, asserts the response status code against want, and closes the response body.
func HTTPGetAndAssert(url string, want int, maxRetry int, retryInterval time.Duration) {
var err error
for i := 0; i < maxRetry; i++ {
conn, err = net.Dial(network, address)
// #nosec G107 // it does not matter if url is not a constant for testing.
resp, err := http.Get(url)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: The default http client does not have timeout, but we may want to set one (maybe just 3~5 seconds since the traffic is only on localhost) as a good practice. More details: https://stackoverflow.com/a/25344458/6355435

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated in #42

if err != nil {
time.Sleep(retryInterval)
continue
}

b := make([]byte, len([]byte(want))) //nolint:makezero // The content of b does not matter,
// but len(b) must be equal to len([]byte(want)) so that conn.Read can read the whole thing.
gomega.Expect(conn.Read(b)).Error().ShouldNot(gomega.HaveOccurred())
gomega.Expect(b).To(gomega.Equal([]byte(want)))
gomega.Expect(conn.Close()).To(gomega.Succeed())
gomega.Expect(resp.StatusCode).To(gomega.Equal(want))
gomega.Expect(resp.Body.Close()).To(gomega.Succeed())
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Usually resp.Body.Close() is defered right after checking that the err from the request is not nil. This ensures that the response body is closed no matter what happens later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated in #42

return
}
ginkgo.Fail(err.Error())
Expand Down
15 changes: 5 additions & 10 deletions tests/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,17 +360,12 @@ func Run(o *RunOption) {
for _, publish := range []string{"-p", "--publish"} {
publish := publish
ginkgo.It(fmt.Sprintf("port of the container should be published to the host port with %s flag", publish), func() {
const (
containerPort = 80
strEchoed = "hello"
)
const containerPort = 80
hostPort := fnet.GetFreePort()
// The nc version used by alpine image is https://busybox.net/downloads/BusyBox.html#nc,
// which is different from that in linux: https://linux.die.net/man/1/nc.
command.Run(o.BaseOpt, "run", "-d", publish, fmt.Sprintf("%d:%d", hostPort, containerPort), defaultImage,
"sh", "-c", fmt.Sprintf("echo %s | nc -l -p %d", strEchoed, containerPort))

fnet.DialAndRead("tcp", fmt.Sprintf("localhost:%d", hostPort), strEchoed, 20, 200*time.Millisecond)
// Start an Nginx container in detached mode with the specified publish flag and mapping the container port to
// a randomly selected host port.
command.Run(o.BaseOpt, "run", "-d", publish, fmt.Sprintf("%d:%d", hostPort, containerPort), nginxImage)
fnet.HTTPGetAndAssert(fmt.Sprintf("http://localhost:%d", hostPort), 200, 20, 200*time.Millisecond)
})
}
})
Expand Down
1 change: 1 addition & 0 deletions tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const (
alpineImage = "public.ecr.aws/docker/library/alpine:latest"
olderAlpineImage = "public.ecr.aws/docker/library/alpine:3.13"
amazonLinux2Image = "public.ecr.aws/amazonlinux/amazonlinux:2"
nginxImage = "public.ecr.aws/docker/library/nginx:latest"
testImageName = "test:tag"
nonexistentImageName = "ne-repo:ne-tag"
nonexistentContainerName = "ne-ctr"
Expand Down