-
Notifications
You must be signed in to change notification settings - Fork 54
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
Testing: Save pod logs and resources after e2e test run #234
Conversation
790d618
to
98e238d
Compare
test/e2e/install_test.go
Outdated
|
||
// Get all namespaces | ||
namespaces, err := kubeClient.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) | ||
Expect(err).To(Not(HaveOccurred())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Global: I can't remember - does Expect abort the test immediately if the expectation fails? If so, I'd recommend distinguishing between a hard-failure (e.g. couldn't create kubeClient, couldn't create artifactPath) and soft failures (couldn't list something, couldn't marshal something, etc.). For the soft failures, I'd suggest logging the issue and continuing, so you try to capture as much as you can.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expect does abort immediately
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a useful logger... fmt.Printf
is good enough? what do you propose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://onsi.github.io/ginkgo/#logging-output has details on what's available
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed, PTAL.
test/e2e/install_test.go
Outdated
buf := make([]byte, 1024) | ||
for { | ||
_, err := logs.Read(buf) | ||
if err != nil { | ||
break | ||
} | ||
} | ||
|
||
// Save logs to artifact path | ||
err = os.WriteFile(filepath.Join(namespaceArtifactPath, pod.Name+"-"+container.Name+"-logs.txt"), buf, 0644) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My gut is telling me this will only read 1024 bytes of the log at a time, and only write out the last 1024 bytes? (Although golang surprises me sometimes.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So my understanding is that this will read from the logs 1024 bytes at a time until it encounters an error (ideally and EOF error to signal the end of the file, but the error check doesn't seem to differentiate - and maybe there isn't a need to) and then will break and write the output. I would personally prefer to substitute this for loop with a buf, err := io.ReadAll(logs)
as it should handle all the reading for us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logs can be very long and artifact gathers that get OOMKilled write nothing :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's why I previously suggested a small buffer and io.Copy
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could be reading it wrong, but it looks like io.ReadAll()
internally reads a small buffer at a time: https://cs.opensource.google/go/go/+/refs/tags/go1.20.4:src/io/io.go;drc=dc8e2a6a8ec94f2c98ba20edd57932eba284efb1;l=690
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely agree with the suggestion of io.Copy
for writing as the stream is read
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It starts small, but because this function returns the entire contents, io.ReadAll
continually increases the size of the buffer as it reads more data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using io.Copy
now, let me know if that's better
.github/workflows/e2e.yaml
Outdated
ARTIFACT_PATH=/tmp/artifacts make e2e | ||
|
||
- uses: cytopia/[email protected] | ||
if: ${{ always() }} | ||
with: | ||
name: e2e-artifacts | ||
path: /tmp/artifacts/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be nice to make the artifact path a variable we define once and use in multiple places. Some docs on github action (environment) variables: https://docs.github.com/en/actions/learn-github-actions/variables#about-variables
test/e2e/install_test.go
Outdated
|
||
// Get all namespaces | ||
namespaces, err := kubeClient.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) | ||
Expect(err).To(Not(HaveOccurred())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expect does abort immediately
test/e2e/install_test.go
Outdated
buf := make([]byte, 1024) | ||
for { | ||
_, err := logs.Read(buf) | ||
if err != nil { | ||
break | ||
} | ||
} | ||
|
||
// Save logs to artifact path | ||
err = os.WriteFile(filepath.Join(namespaceArtifactPath, pod.Name+"-"+container.Name+"-logs.txt"), buf, 0644) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So my understanding is that this will read from the logs 1024 bytes at a time until it encounters an error (ideally and EOF error to signal the end of the file, but the error check doesn't seem to differentiate - and maybe there isn't a need to) and then will break and write the output. I would personally prefer to substitute this for loop with a buf, err := io.ReadAll(logs)
as it should handle all the reading for us.
c69e58f
to
97bba47
Compare
3a5881c
to
5f6a597
Compare
5f6a597
to
a23d0a9
Compare
6234c66
to
393c7b8
Compare
3be517f
to
387bd53
Compare
387bd53
to
ffbc1eb
Compare
Codecov ReportPatch coverage has no change and project coverage change:
Additional details and impacted files@@ Coverage Diff @@
## main #234 +/- ##
==========================================
- Coverage 81.64% 77.23% -4.42%
==========================================
Files 21 18 -3
Lines 937 795 -142
==========================================
- Hits 765 614 -151
- Misses 119 146 +27
+ Partials 53 35 -18
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
ffbc1eb
to
345bd1f
Compare
20aaceb
to
ca58e6d
Compare
What's the status of this PR? Functionality like this would help shed light on this apparent e2e code coverage change. #336 (comment) |
ca58e6d
to
6808ee5
Compare
6808ee5
to
b3e67f3
Compare
test/e2e/install_test.go
Outdated
const ( | ||
defaultTimeout = 30 * time.Second | ||
defaultPoll = 1 * time.Second | ||
testCatalogRef = "localhost/testdata/catalogs/test-catalog:e2e" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be removed - e2e_suite_test.go currently has consts for this, and a helper function getCatalogImageRef
which supports optionally changing the catalog image via an env var.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
test/e2e/install_test.go
Outdated
// - bundle | ||
// - bundledeployments | ||
// - catalogsources | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
test/e2e/install_test.go
Outdated
@@ -222,3 +243,163 @@ var _ = Describe("Operator Install", func() { | |||
|
|||
}) | |||
}) | |||
|
|||
// getArtifactsOutput gets all the artifacts from the test run and saves them to the artifact path. | |||
// right now it will save: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// right now it will save: | |
// Currently it saves: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@jmprusi if you can rebase and make my requested changes, we can merge |
Signed-off-by: Joaquim Moreno Prusi <[email protected]>
b3e67f3
to
b9824db
Compare
Signed-off-by: Joaquim Moreno Prusi <[email protected]>
b9824db
to
29b8758
Compare
Description
Generate a summary of logs/resources after e2e runs.
Disabled by default, to enable, pass the
ARTIFACT_PATH
env var when running the e2e tests:ARTIFACT_PATH=/tmp/e2e/ make test
Enabled on GitHub CI, you can access the artifacts via the "e2e / e2e-kind (pull_request)" check/action.
Current output of a e2e test run:
TODO:
Reviewer Checklist