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

e2e tests: clean up antihelpful BeTrue()s #12387

Merged
merged 2 commits into from
Nov 23, 2021

Conversation

edsantiago
Copy link
Member

Many ginkgo tests have been written to use this evil form:

GrepString("foo")
Expect(that to BeTrue())

...which yields horrible useless messages on failure:

false is not true

Identify those (automatically, via script) and convert to:

Expect(output to ContainSubstring("foo"))

...which yields:

"this output" does not contain substring "foo"

There are still many BeTrue()s left. This is just a start.

Signed-off-by: Ed Santiago [email protected]

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Nov 22, 2021

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: edsantiago

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 22, 2021
@@ -186,23 +180,22 @@ var _ = Describe("Podman UserNS support", func() {
session := podmanTest.Podman([]string{"run", "--userns=auto:size=500", "alpine", "cat", "/proc/self/uid_map"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
ok, _ := session.GrepString("500")
Copy link
Member Author

Choose a reason for hiding this comment

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

This, and (old) lines 194, 199 required manual fixing (my script could not identify them). Unless I'm missing something major, I believe these three lines were complete NOPs.

@edsantiago
Copy link
Member Author

Aside from the above comment, all changes (at this point) were generated by a script. Once (if?) CI passes I will post the content of said script, for future posterity.

@Luap99
Copy link
Member

Luap99 commented Nov 22, 2021

I like this but tests are failing.

@edsantiago
Copy link
Member Author

Yeah; HasPrefix() is not a 1:1 replacement for LineInOutputStartsWith(). I'm websearching to see what I can find.

And, Static Build seems completely broken, something to do with nix. I've restarted it four times, no luck.

@@ -252,7 +252,7 @@ var _ = Describe("Podman run", func() {
session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.LineInOutputStartsWith("search")).To(BeTrue())
Expect(session.OutputToString()).To(HavePrefix("search"))
Copy link
Member

Choose a reason for hiding this comment

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

This is not correct, LineInOutputStartsWith checks each line individually for this prefix while your change only works for the first line.

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, exactly. I'm looking for a Ginkgo replacement.

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 you need to write your own custom matcher

@edsantiago edsantiago force-pushed the remove_betrue branch 2 times, most recently from 031a263 to 34791da Compare November 22, 2021 20:55
Many ginkgo tests have been written to use this evil form:

    GrepString("foo")
    Expect(that to BeTrue())

...which yields horrible useless messages on failure:

    false is not true

Identify those (automatically, via script) and convert to:

    Expect(output to ContainSubstring("foo"))

...which yields:

    "this output" does not contain substring "foo"

There are still many BeTrue()s left. This is just a start.

This is commit 1 of 2. It includes the script I used, and
all changes to *.go are those computed by the script.
Commit 2 will apply some manual fixes.

Signed-off-by: Ed Santiago <[email protected]>
@rhatdan
Copy link
Member

rhatdan commented Nov 22, 2021

/lgtm
/hold

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Nov 22, 2021
@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Nov 22, 2021
Commit 2 of 2: there were (still are?) a bunch of string
checks that didn't have a corresponding Expect(). IIUC
that means they were NOPs. Try to identify and fix those.

The first few were caught by Go linting, "ok is defined
but not used". When I realized the problem, I looked for
more using:

    $ ack -A2 LineInOutputStartsWith

...and tediously eyeballing the results, looking for
matches in which the next line was not Expect(). If
test was wrong (e.g. "server" should've been "nameserver"),
fix that.

Also: remove the remove-betrue script. We don't need it
in the repo, I just wanted to preserve it for posterity.

Signed-off-by: Ed Santiago <[email protected]>
@openshift-ci openshift-ci bot removed the lgtm Indicates that a PR is ready to be merged. label Nov 22, 2021
})

It("podman run add dns server", func() {
session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
session.LineInOutputStartsWith("server 1.2.3.4")
Expect(session.OutputToStringArray()).To(ContainElement(HavePrefix("nameserver 1.2.3.4")))
Copy link
Member Author

Choose a reason for hiding this comment

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

Another manual (not automated) change: this (and the other copy/paste instance in run_dns_test.go below) was broken from before, but the test was a NOP so it was never caught.

@edsantiago
Copy link
Member Author

OK, I'm done for today but I think this final iteration should pass CI.

This is nearly impossible to review, but I would appreciate eyeballs on the second commit (the Oops one) because you should be really scared by what you find there: a small number of tests that were doing nothing whatsoever. And I suspect there may be more, but they're super hard to find and I can't think of any automated way to detect them.

Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

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

/lgtm
/hold

Thank you, Ed!

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Nov 23, 2021
@vrothberg
Copy link
Member

I want another pair of eyes to parse the new changes before merging.

Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

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

LGTM

Maybe we should remove GrepString(), LineInOutputContains() and LineInOutputStartsWith() to prevent such errors in the future.

@Luap99
Copy link
Member

Luap99 commented Nov 23, 2021

/hold cancel

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Nov 23, 2021
@openshift-merge-robot openshift-merge-robot merged commit a55473b into containers:main Nov 23, 2021
@edsantiago edsantiago deleted the remove_betrue branch November 23, 2021 11:46
@edsantiago
Copy link
Member Author

Thanks everyone!

Maybe we should remove GrepString(), LineInOutputContains() and LineInOutputStartsWith() to prevent such errors in the future.

That was my initial goal. It's not quite that simple:

podman/test/e2e/ps_test.go

Lines 280 to 283 in 90c635f

match, StatusLine := result.GrepString(`Status`)
Expect(match).To(BeTrue())
// container is running or exit, so it must contain `ago`
Expect(StatusLine[0]).To(ContainSubstring("ago"))

I will be following up on it, though. I will be doing so in medium-size reviewable chunks.

@Luap99
Copy link
Member

Luap99 commented Nov 23, 2021

I am wondering if the linter is running on the test/e2e directory. Normally the linter will complain if the return value is unused.

@edsantiago
Copy link
Member Author

It is (running): that's how I found the initial bugs that led me to the second commit. My script removed an ok = Grep; Expect() pair, but left an earlier ok := Grep that had no Expect(). That's what the Validate test caught.

@Luap99
Copy link
Member

Luap99 commented Nov 23, 2021

@edsantiago I think this is just the go compiler complaining about an unused variable not the actual linter.

@edsantiago
Copy link
Member Author

@vrothberg FYI, for baseline purposes: here are cirrus-pr-timing results for a recent PR

type distro user local remote container
int fedora-34 root 29:45 31:31 28:53
int fedora-35 root 29:27 28:04 28:50
int ubuntu-2110 root 36:20 43:15
int fedora-34 rootless 27:48
int fedora-35 rootless 32:00
int ubuntu-2110 rootless 24:12
sys fedora-34 root 21:11 12:03
sys fedora-35 root 22:04 13:17
sys ubuntu-2110 root 21:33 13:59
sys fedora-34 rootless 20:31
sys fedora-35 rootless 20:16
sys ubuntu-2110 rootless 19:51

@Luap99
Copy link
Member

Luap99 commented Nov 23, 2021

@edsantiago The linter is not running:

$ bin/golangci-lint run test/e2e
test/e2e/common_test.go:77:5: `noCache` is unused (deadcode)
var noCache = "Cannot run nocache with remote"
    ^
test/e2e/play_kube_test.go:783:6: `withDeploymentLabel` is unused (deadcode)
func withDeploymentLabel(k, v string) deploymentOption {
     ^
test/e2e/common_test.go:36:2: don't use ALL_CAPS in Go names; use CamelCase (golint)
        PODMAN_BINARY      string
        ^
test/e2e/common_test.go:37:2: don't use ALL_CAPS in Go names; use CamelCase (golint)
        CONMON_BINARY      string
        ^
test/e2e/common_test.go:38:2: don't use ALL_CAPS in Go names; use CamelCase (golint)
        CNI_CONFIG_DIR     string
        ^
test/e2e/common_test.go:600:33: method CreateSeccompJson should be CreateSeccompJSON (golint)
func (p *PodmanTestIntegration) CreateSeccompJson(in []byte) (string, error) {
                                ^
test/e2e/common_test.go:875:1: receiver name p should be consistent with previous receiver name s for PodmanSessionIntegration (golint)
func (p *PodmanSessionIntegration) jq(jqCommand string) (string, error) {
^
test/e2e/config_amd64.go:13:2: don't use underscores in Go names; var `ubi_minimal` should be `ubiMinimal` (golint)
        ubi_minimal              = "registry.access.redhat.com/ubi8-minimal"
        ^
test/e2e/config_amd64.go:14:2: don't use underscores in Go names; var `ubi_init` should be `ubiInit` (golint)
        ubi_init                 = "registry.access.redhat.com/ubi8-init"
        ^
test/e2e/network_test.go:188:2: don't use underscores in Go names; var `rm_func` should be `rmFunc` (golint)
        rm_func := func(rm string) {
        ^
test/e2e/play_kube_test.go:829:2: struct field `CpuRequest` should be `CPURequest` (golint)
        CpuRequest      string
        ^
test/e2e/play_kube_test.go:830:2: struct field `CpuLimit` should be `CPULimit` (golint)
        CpuLimit        string
        ^
test/e2e/play_kube_test.go:910:6: func withCpuRequest should be withCPURequest (golint)
func withCpuRequest(request string) ctrOption {
     ^
test/e2e/play_kube_test.go:916:6: func withCpuLimit should be withCPULimit (golint)
func withCpuLimit(limit string) ctrOption {
     ^
test/e2e/play_kube_test.go:2311:4: var `expectedCpuRequest` should be `expectedCPURequest` (golint)
                        expectedCpuRequest    string = "100m"
                        ^
test/e2e/play_kube_test.go:2312:4: var `expectedCpuLimit` should be `expectedCPULimit` (golint)
                        expectedCpuLimit      string = "200m"
                        ^
test/e2e/play_kube_test.go:2317:3: var `expectedCpuQuota` should be `expectedCPUQuota` (golint)
                expectedCpuQuota := milliCPUToQuota(expectedCpuLimit)
                ^
test/e2e/play_kube_test.go:2354:4: var `expectedCpuLimit` should be `expectedCPULimit` (golint)
                        expectedCpuLimit string = "1"
                        ^
test/e2e/pod_rm_test.go:135:3: don't use underscores in Go names; var `num_pods` should be `numPods` (golint)
                num_pods := podmanTest.NumberOfPods()
                ^
test/e2e/ps_test.go:446:11: `if` block ends with a `return` statement, so drop this `else` and outdent its block (golint)
                        } else {
                               ^
test/e2e/pull_test.go:394:3: var `shortImageId` should be `shortImageID` (golint)
                shortImageId := strings.Split(setup.OutputToString(), ":")[1]
                ^
test/e2e/rmi_test.go:100:3: var `cirrosId` should be `cirrosID` (golint)
                cirrosId := setup.OutputToString()
                ^
test/e2e/run_networking_test.go:792:2: don't use underscores in Go names; var `ping_test` should be `pingTest` (golint)
        ping_test := func(netns string) {
        ^
test/e2e/run_privileged_test.go:24:2: don't use underscores in Go names; var `ctrCap_n` should be `ctrCapN` (golint)
        ctrCap_n, err := strconv.ParseUint(ctrCap, 16, 64)
        ^
test/e2e/run_privileged_test.go:27:2: don't use underscores in Go names; var `hostCap_n` should be `hostCapN` (golint)
        hostCap_n, err := strconv.ParseUint(hostCap, 16, 64)
        ^
test/e2e/run_privileged_test.go:34:2: don't use underscores in Go names; var `hostCap_masked` should be `hostCapMasked` (golint)
        hostCap_masked := hostCap_n & (1<<len(capability.List()) - 1)
        ^
test/e2e/systemd_test.go:53:3: don't use underscores in Go names; var `sys_file` should be `sysFile` (golint)
                sys_file := ioutil.WriteFile("/etc/systemd/system/redis.service", []byte(systemdUnitFile), 0644)
                ^
test/e2e/play_build_test.go:97:3: ineffectual assignment to `err` (ineffassign)
                err := os.Mkdir(yamlDir, 0755)
                ^
test/e2e/play_build_test.go:133:3: ineffectual assignment to `err` (ineffassign)
                err := os.Mkdir(yamlDir, 0755)
                ^
test/e2e/play_build_test.go:169:3: ineffectual assignment to `err` (ineffassign)
                err := os.Mkdir(yamlDir, 0755)
                ^
test/e2e/pod_create_test.go:759:3: ineffectual assignment to `ok` (ineffassign)
                ok, _ := session.GrepString("500")
                ^
test/e2e/secret_test.go:211:3: ineffectual assignment to `secrID` (ineffassign)
                secrID := session.OutputToString()
                ^
test/e2e/volume_create_test.go:100:3: ineffectual assignment to `volName` (ineffassign)
                volName = session.OutputToString()
                ^
test/e2e/volume_create_test.go:105:3: ineffectual assignment to `volName` (ineffassign)
                volName = session.OutputToString()
                ^
test/e2e/image_scp_test.go:65:52: `transfering` is a misspelling of `transferring` (misspell)
                SkipIfNotRootless("this is a rootless only test, transfering from root to rootless using PodmanAsUser")
                                                                 ^
test/e2e/checkpoint_test.go:1034:5: Using the variable on range scope `share` in function literal (scopelint)
                                share,
                                ^
test/e2e/checkpoint_test.go:1083:18: Using the variable on range scope `share` in function literal (scopelint)
                        wrongShare := share[:strings.LastIndex(share, ",")]
                                      ^
test/e2e/checkpoint_test.go:1121:5: Using the variable on range scope `share` in function literal (scopelint)
                                share,
                                ^
test/e2e/play_kube_test.go:2335:70: Using a reference for the variable on range scope `pod` (scopelint)
                        inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&pod), "--format", `
                                                                                          ^
test/e2e/play_kube_test.go:2369:70: Using a reference for the variable on range scope `pod` (scopelint)
                        inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&pod), "--format", `{{ .HostConfig.CpuPeriod }}:{{ .HostConfig.CpuQuota }}`})
                                                                                          ^
test/e2e/common_test.go:687:2: S1008: should use 'return os.Getenv("container") != ""' instead of 'if os.Getenv("container") != "" { return true }; return false' (gosimple)
        if os.Getenv("container") != "" {
        ^
test/e2e/logs_test.go:23:2: S1008: should use 'return info.OutputToString() == "journald"' instead of 'if info.OutputToString() == "journald" { return true }; return false' (gosimple)
        if info.OutputToString() == "journald" {
        ^
test/e2e/container_create_volume_test.go:31:27: S1039: unnecessary use of fmt.Sprintf (gosimple)
        containersConf := []byte(fmt.Sprintf("[containers]\nprepare_volume_on_create = true\n"))
                                 ^
test/e2e/containers_conf_test.go:410:28: S1039: unnecessary use of fmt.Sprintf (gosimple)
                containersConf := []byte(fmt.Sprintf("[engine]\nimage_copy_tmp_dir=\"/foobar\""))
                                         ^
test/e2e/containers_conf_test.go:423:27: S1039: unnecessary use of fmt.Sprintf (gosimple)
                containersConf = []byte(fmt.Sprintf("[engine]\nimage_copy_tmp_dir=\"storage\""))
                                        ^
test/e2e/toolbox_test.go:69:3: S1021: should merge variable declaration with assignment on next line (gosimple)
                var session *PodmanSessionIntegration
                ^
test/e2e/toolbox_test.go:79:3: S1021: should merge variable declaration with assignment on next line (gosimple)
                var session *PodmanSessionIntegration
                ^
test/e2e/toolbox_test.go:167:3: S1021: should merge variable declaration with assignment on next line (gosimple)
                var session *PodmanSessionIntegration
                ^
test/e2e/common_test.go:478:20: composites: `github.com/containers/podman/v3/test/utils.PodmanSession` composite literal uses unkeyed fields (govet)
        podmanSession := &PodmanSession{session}
                          ^
test/e2e/common_test.go:532:36: ST1016: methods on the same type should have the same receiver name (seen 1x "p", 4x "s") (stylecheck)
func (s *PodmanSessionIntegration) InspectContainerToJSON() []define.InspectContainerData {
                                   ^
test/e2e/common_test.go:27:2: ST1019: package "github.com/onsi/ginkgo" is being imported more than once (stylecheck)
        "github.com/onsi/ginkgo"
        ^
test/e2e/runlabel_test.go:21:5: var `GlobalDockerfile` is unused (unused)

The interesting failures are the ineffassign ones, e.g.

test/e2e/pod_create_test.go:759:3: ineffectual assignment to `ok` (ineffassign)
                ok, _ := session.GrepString("500")

@edsantiago
Copy link
Member Author

@Luap99 thanks! #12398 caught that Grep one. I will use lint results in subsequent followup PRs.

@github-actions github-actions bot added the locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. label Sep 22, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants