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

Fix color handling, generate the summary with JS, improve CI #1975

Merged
merged 16 commits into from
May 18, 2021

Conversation

na--
Copy link
Member

@na-- na-- commented Apr 16, 2021

Read commit by commit. This should be merged after we release k6 v0.32.0, I'm just polishing it and pushing it, so it's easy to merge after the release.

This PR should fix #1806 and close #1805, as well as make several other minor improvements, mostly about various dependencies (#1933).

It also introduces a minor breaking change, though I'm not sure if it's even worth noting in the release notes... k6 will no longer highlight the output of several sub-commands: pause, resume, scale, stats, and status.

Finally, because I wanted to use the new file embedding capabilities in Go 1.16, I bumped the minimum required version to that. I switched the xk6 tests to run with the latest stable Go version and the tip. For the main test suite, I temporarily disabled the 1.15 tests, but also added testing with the tip (which is non-blocking, so it won't prevent a PR merge or a release). This shouldn't be a problem, since we will only release this in k6 v0.33.0, ~2.5 months from now. But it gave me the opportunity to also drop the go.rice dependency 🎉

@na-- na-- added this to the v0.33.0 milestone Apr 16, 2021
@na-- na-- changed the title [WIP] Fix colors switch to js summary [WIP] Fix color handling and generate the summary with JS Apr 16, 2021
@codecov-commenter
Copy link

codecov-commenter commented Apr 16, 2021

Codecov Report

Merging #1975 (6778f12) into master (daca27c) will decrease coverage by 0.20%.
The diff coverage is 12.72%.

❗ Current head 6778f12 differs from pull request most recent head 0dd3012. Consider uploading reports for the commit 0dd3012 to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1975      +/-   ##
==========================================
- Coverage   71.92%   71.72%   -0.21%     
==========================================
  Files         182      179       -3     
  Lines       14291    14085     -206     
==========================================
- Hits        10279    10102     -177     
+ Misses       3368     3346      -22     
+ Partials      644      637       -7     
Flag Coverage Δ
ubuntu 71.66% <12.72%> (-0.21%) ⬇️
windows 71.47% <12.72%> (-0.12%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
cmd/cloud.go 4.73% <0.00%> (-0.11%) ⬇️
cmd/login_cloud.go 0.00% <0.00%> (ø)
cmd/pause.go 0.00% <0.00%> (ø)
cmd/resume.go 0.00% <0.00%> (ø)
cmd/root.go 8.82% <0.00%> (+0.06%) ⬆️
cmd/run.go 12.14% <0.00%> (-0.26%) ⬇️
cmd/scale.go 0.00% <0.00%> (ø)
cmd/stats.go 0.00% <0.00%> (ø)
cmd/status.go 0.00% <0.00%> (ø)
cmd/ui.go 20.61% <0.00%> (-1.99%) ⬇️
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update daca27c...0dd3012. Read the comment docs.

@na-- na-- force-pushed the fix-colors-switch-to-js-summary branch from 2c61abd to ab62876 Compare April 16, 2021 20:13
@na-- na-- changed the title [WIP] Fix color handling and generate the summary with JS [WIP] Fix color handling, generate the summary with JS, improve CI Apr 16, 2021
@na-- na-- force-pushed the fix-colors-switch-to-js-summary branch from 45cdd2e to 3ff9787 Compare April 16, 2021 20:31
@na-- na-- changed the title [WIP] Fix color handling, generate the summary with JS, improve CI Fix color handling, generate the summary with JS, improve CI Apr 16, 2021
@na-- na-- marked this pull request as ready for review April 16, 2021 20:51
Copy link
Contributor

@mstoykov mstoykov left a comment

Choose a reason for hiding this comment

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

Seems fine on first read, but we need to test this a lot ... especially on windows

ui.Dump(stdout, status)
return nil

return yamlPrint(stdout, status)
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this is a good case for wrapping errors as "could not marshal YAML:" will be quite strange error for someone calling k6 pause or co.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, though to be fair, the new state isn't any worse than the previous behavior where it would have printed just the raw YAML marshaling error, without even the could not marshal YAML: in front of it 😅 but yeah, I may wrap these errors locally as well...

@na--
Copy link
Member Author

na-- commented Apr 20, 2021

I converted this back to draft because I want to make a few more changes, prompted by grafana/jslib.k6.io#32

First, I think I should rename the uiState sent to handleSummary() to the more generic state, and have it include things like the total test run duration. It is currently in the summary, just not exposed in the JS object directly: https://github.com/k6io/k6/blob/47a0b493cce0020d445a47edbca79c25ab5a550f/lib/runner.go#L110

Also, AreColorsDisabled (i.e. NoColors) should probably not be in data.state and should instead be moved to the data.options.

na-- added 2 commits May 14, 2021 14:12
If the environment contains TERM=dumb, we don't consider them to be a TTY. This is in line with what the github.com/fatih/color library checks: https://github.com/fatih/color/blob/v1.10.0/color.go#L20-L21
@na-- na-- marked this pull request as ready for review May 14, 2021 11:41
@na-- na-- force-pushed the fix-colors-switch-to-js-summary branch from 0aad6a6 to 25cd528 Compare May 14, 2021 11:41
@na-- na-- requested review from mstoykov and imiric May 14, 2021 11:42
mstoykov
mstoykov previously approved these changes May 17, 2021
Copy link
Contributor

@mstoykov mstoykov left a comment

Choose a reason for hiding this comment

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

LGTM, I had a couple of nitpicks, but if it works .... I am fine with merging it and my 5 minutes of testing didn't show any problems so 👍

@@ -330,7 +333,8 @@ This will execute the test on the k6 cloud service. Use "k6 login cloud" to auth
return ExitCode{error: errors.New("Test progress error"), Code: cloudFailedToGetProgressErrorCode}
}

fprintf(stdout, " test status: %s\n", ui.ValueColor.Sprint(testProgress.RunStatusText))
valueColor := getColor(noColor || !stdoutTTY, color.FgCyan)
Copy link
Contributor

Choose a reason for hiding this comment

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

Given how now you repeat color.FgCyan a lot I would argue it should probably be a constant somewhere ... probably named valueColorColor :P

Copy link
Member Author

Choose a reason for hiding this comment

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

It's already a constant 😛 It's used in like 5 places across 2 modules, and not always for values (e.g. the banner), so I don't want to define a constant for that.

js/summary.go Outdated Show resolved Hide resolved
Copy link
Contributor

@imiric imiric left a comment

Choose a reason for hiding this comment

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

No blockers from me, just minor suggestions. I would've preferred to review separate PRs for the color fixes and JS summary changes, but the commits are isolated, so it wasn't a big issue.

I think we're missing some integration tests to ensure color is handled correctly, but it could be added later. Though it worked fine in my manual tests. It's kind of wild we're generating the summary entirely in JS now 😄 🎉

And kudos for dropping all those Go dependencies! 👍

cmd/ui.go Outdated Show resolved Hide resolved
// getColor() returns the requested color, or an uncolored object, depending on
// the value of noColor. The explicit EnableColor() and DisableColor() are
// needed because the library checks os.Stdout itself otherwise...
func getColor(noColor bool, attributes ...color.Attribute) *color.Color {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add high-level (integration?) tests for this, to check the new behavior, using TERM=dumb, etc.?

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 is very difficult to do currently with all of these globals, I think it falls under #342 and #883. The end goal is to almost completely remove the globals, i.e. have something that passes os.Environ() and the CLI flags as parameters, which will allow us to have sane tests as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant high-level as in user acceptance tests, similar to the xk6 ones we have now, running k6 itself in a shell, checking the output, etc.

But that requires coming up with the framework and CI pipeline, so it's fine if we do it later as part of #342.

js/summary.go Outdated Show resolved Hide resolved
.github/workflows/all.yml Show resolved Hide resolved
js/summary.go Outdated Show resolved Hide resolved
)

// TODO: move this to a separate JS file and use go.rice to embed it
const summaryWrapperLambdaCode = `
// Copied from https://github.com/k6io/jslib.k6.io/tree/master/lib/k6-summary
Copy link
Contributor

Choose a reason for hiding this comment

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

This means we can deprecate the jslib, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

No? jslib has a ton of other libraries. Besides, having textSummary() in there is very helpful for users that want to define their own handleSummary() function, e.g. to emit a json or a junit file, but they also want to continue getting the text summary at the end of the test. They can just import { textSummary } from 'https://jslib.k6.io/lib/k6-summary/0.0.1/index.js' and use that in handleSummary()'s result.

Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't mean deprecating jslib.k6.io altogether 😄, just this lib.

I wasn't aware there were differences between the version committed here and the one on jslib. Though since we already bundle it in the binary, couldn't we expose it as a built-in JS module and avoid the remote loading? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

There aren't any differences, except we don't bundle the JUnit code (we'll probably split it apart in jslib as well soon). And we can potentially expose it as a JS module, if we figure out a nice module name, but that will be a separate issue/PR

na-- added 6 commits May 18, 2021 10:34
We still use the noColor and stdoutTTY global variables, but we explicitly pass them as function arguments, so it's clear which parts of the code depend on them when we eventually fully refactor them into locals.
The affected commands are k6 pause, resume, scale, stats and status. This allows us to remove the github.com/zyedidia/highlight dependency and significantly simplify the color management mess.
Due to incomplete test setup, there were differences between the expected text and JSON results of the end-of-test summary handling...
This is necessary so that any handleSummary() callback, including the default one, would know if it can use colors (or other special terminal features) or not.
This is needed because we want to use the file embedding API.
na-- added 5 commits May 18, 2021 10:34
This allows us to drop the github.com/dustin/go-humanize and also the explicit nature of the golang.org/x/text dependency.
This should no longer be needed, since we hopefully don't have any more rogue color generators that don't respect stdoutTTY/stderrTTY and noColor. The next step would be making these variables local and passing them through the cmd logic as arguments, not reading their values directly out of the global scope.
mstoykov
mstoykov previously approved these changes May 18, 2021
@na-- na-- requested review from imiric and mstoykov May 18, 2021 07:57
mstoykov
mstoykov previously approved these changes May 18, 2021
Copy link
Contributor

@imiric imiric left a comment

Choose a reason for hiding this comment

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

LGTM, just a couple of minor notes.

@@ -344,7 +345,8 @@ func (r *Runner) HandleSummary(ctx context.Context, summary *lib.Summary) (map[s
}()
*vu.Context = ctx

handleSummaryWrapperRaw, err := vu.Runtime.RunString(summaryWrapperLambdaCode)
wrapper := strings.Replace(summaryWrapperLambdaCode, "/*JSLIB_SUMMARY_CODE*/", jslibSummaryCode, 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm probably missing it, but what's the reason for having a wrapper and doing this replace? Since both summaryWrapperLambdaCode and jslibSummaryCode are static, couldn't we just bundle a single JS file?

Copy link
Member Author

Choose a reason for hiding this comment

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

We probably could, but this insulates us from future changes in the jslib summary code, and it also keeps the scope a bit cleaner 🤷‍♂️

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, sorry, misread your question. I don't want to bundle a single JS file since I want it to be easy to update the summary.js when the one in jslib is updated

@@ -29,120 +29,6 @@ import (
"github.com/stretchr/testify/assert"
)

func TestMetricHumanizeValue(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

These were very important tests IMO that we lose in the conversion to JS. We should probably add some for the JS implementation.

Copy link
Member Author

Choose a reason for hiding this comment

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

I replicated (and IIRC even expanded a bit) these tests in https://github.com/k6io/jslib.k6.io/blob/master/tests/summary.js when I was writing the JS summary generation code.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, neat, I forgot about those. I suppose it's fine then, though running them as part of the k6 tests would give us more confidence, as they're run more frequently and use the latest k6 version. But this goes back to the point of eventually deprecating the jslib version, which we can consider later.

Copy link
Member Author

Choose a reason for hiding this comment

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

In k6 we have somewhat higher-level tests in https://github.com/k6io/k6/blob/master/js/summary_test.go - they are like integration tests for the JS summary code, so I'd rather expand those than to write more low-level ones.

@na-- na-- merged commit 6b635e9 into master May 18, 2021
@na-- na-- deleted the fix-colors-switch-to-js-summary branch May 18, 2021 09:33
@na-- na-- mentioned this pull request May 18, 2021
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.

Replace text summary generation with JS code Fix TTY color support
4 participants