1
0
mirror of https://github.com/go-task/task.git synced 2025-06-23 00:38:19 +02:00

feat: add parallel test execution to improve runtime (#1882)

This commit is contained in:
christiandins
2024-12-12 01:47:10 +01:00
committed by GitHub
parent b9a5d1c573
commit 4dffab2e0a
14 changed files with 441 additions and 34 deletions

View File

@ -11,6 +11,10 @@ linters:
- gofumpt - gofumpt
- misspell - misspell
- noctx - noctx
- paralleltest
- tenv
- thelper
- tparallel
linters-settings: linters-settings:
depguard: depguard:

View File

@ -12,6 +12,8 @@ import (
) )
func TestArgs(t *testing.T) { func TestArgs(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
Args []string Args []string
ExpectedCalls []*ast.Call ExpectedCalls []*ast.Call
@ -97,6 +99,8 @@ func TestArgs(t *testing.T) {
for i, test := range tests { for i, test := range tests {
t.Run(fmt.Sprintf("TestArgs%d", i+1), func(t *testing.T) { t.Run(fmt.Sprintf("TestArgs%d", i+1), func(t *testing.T) {
t.Parallel()
calls, globals := args.Parse(test.Args...) calls, globals := args.Parse(test.Args...)
assert.Equal(t, test.ExpectedCalls, calls) assert.Equal(t, test.ExpectedCalls, calls)
if test.ExpectedGlobals.Len() > 0 || globals.Len() > 0 { if test.ExpectedGlobals.Len() > 0 || globals.Len() > 0 {

View File

@ -7,6 +7,8 @@ import (
) )
func TestNormalizeFilename(t *testing.T) { func TestNormalizeFilename(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
In, Out string In, Out string
}{ }{

View File

@ -26,6 +26,8 @@ import (
// | false | true | false | // | false | true | false |
// | false | false | false | // | false | false | false |
func TestIsTaskUpToDate(t *testing.T) { func TestIsTaskUpToDate(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
name string name string
task *ast.Task task *ast.Task
@ -150,6 +152,8 @@ func TestIsTaskUpToDate(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel()
mockStatusChecker := mocks.NewStatusCheckable(t) mockStatusChecker := mocks.NewStatusCheckable(t)
if tt.setupMockStatusChecker != nil { if tt.setupMockStatusChecker != nil {
tt.setupMockStatusChecker(mockStatusChecker) tt.setupMockStatusChecker(mockStatusChecker)

View File

@ -9,6 +9,8 @@ import (
) )
func TestFromMap(t *testing.T) { func TestFromMap(t *testing.T) {
t.Parallel()
m := map[int]string{3: "three", 1: "one", 2: "two"} m := map[int]string{3: "three", 1: "one", 2: "two"}
om := FromMap(m) om := FromMap(m)
assert.Len(t, om.m, 3) assert.Len(t, om.m, 3)
@ -20,6 +22,8 @@ func TestFromMap(t *testing.T) {
} }
func TestSetGetExists(t *testing.T) { func TestSetGetExists(t *testing.T) {
t.Parallel()
om := New[int, string]() om := New[int, string]()
assert.False(t, om.Exists(1)) assert.False(t, om.Exists(1))
assert.Equal(t, "", om.Get(1)) assert.Equal(t, "", om.Get(1))
@ -29,6 +33,8 @@ func TestSetGetExists(t *testing.T) {
} }
func TestSort(t *testing.T) { func TestSort(t *testing.T) {
t.Parallel()
om := New[int, string]() om := New[int, string]()
om.Set(3, "three") om.Set(3, "three")
om.Set(1, "one") om.Set(1, "one")
@ -38,6 +44,8 @@ func TestSort(t *testing.T) {
} }
func TestSortFunc(t *testing.T) { func TestSortFunc(t *testing.T) {
t.Parallel()
om := New[int, string]() om := New[int, string]()
om.Set(3, "three") om.Set(3, "three")
om.Set(1, "one") om.Set(1, "one")
@ -49,6 +57,8 @@ func TestSortFunc(t *testing.T) {
} }
func TestKeysValues(t *testing.T) { func TestKeysValues(t *testing.T) {
t.Parallel()
om := New[int, string]() om := New[int, string]()
om.Set(3, "three") om.Set(3, "three")
om.Set(1, "one") om.Set(1, "one")
@ -58,6 +68,8 @@ func TestKeysValues(t *testing.T) {
} }
func Range(t *testing.T) { func Range(t *testing.T) {
t.Helper()
om := New[int, string]() om := New[int, string]()
om.Set(3, "three") om.Set(3, "three")
om.Set(1, "one") om.Set(1, "one")
@ -81,6 +93,8 @@ func Range(t *testing.T) {
} }
func TestOrderedMapMerge(t *testing.T) { func TestOrderedMapMerge(t *testing.T) {
t.Parallel()
om1 := New[string, int]() om1 := New[string, int]()
om1.Set("a", 1) om1.Set("a", 1)
om1.Set("b", 2) om1.Set("b", 2)
@ -104,6 +118,8 @@ func TestOrderedMapMerge(t *testing.T) {
} }
func TestUnmarshalYAML(t *testing.T) { func TestUnmarshalYAML(t *testing.T) {
t.Parallel()
yamlString := ` yamlString := `
3: three 3: three
1: one 1: one

View File

@ -19,6 +19,8 @@ import (
) )
func TestInterleaved(t *testing.T) { func TestInterleaved(t *testing.T) {
t.Parallel()
var b bytes.Buffer var b bytes.Buffer
var o output.Output = output.Interleaved{} var o output.Output = output.Interleaved{}
w, _, _ := o.WrapWriter(&b, io.Discard, "", nil) w, _, _ := o.WrapWriter(&b, io.Discard, "", nil)
@ -30,6 +32,8 @@ func TestInterleaved(t *testing.T) {
} }
func TestGroup(t *testing.T) { func TestGroup(t *testing.T) {
t.Parallel()
var b bytes.Buffer var b bytes.Buffer
var o output.Output = output.Group{} var o output.Output = output.Group{}
stdOut, stdErr, cleanup := o.WrapWriter(&b, io.Discard, "", nil) stdOut, stdErr, cleanup := o.WrapWriter(&b, io.Discard, "", nil)
@ -48,6 +52,8 @@ func TestGroup(t *testing.T) {
} }
func TestGroupWithBeginEnd(t *testing.T) { func TestGroupWithBeginEnd(t *testing.T) {
t.Parallel()
tmpl := templater.Cache{ tmpl := templater.Cache{
Vars: &ast.Vars{ Vars: &ast.Vars{
OrderedMap: omap.FromMap(map[string]ast.Var{ OrderedMap: omap.FromMap(map[string]ast.Var{
@ -61,6 +67,8 @@ func TestGroupWithBeginEnd(t *testing.T) {
End: "::endgroup::", End: "::endgroup::",
} }
t.Run("simple", func(t *testing.T) { t.Run("simple", func(t *testing.T) {
t.Parallel()
var b bytes.Buffer var b bytes.Buffer
w, _, cleanup := o.WrapWriter(&b, io.Discard, "", &tmpl) w, _, cleanup := o.WrapWriter(&b, io.Discard, "", &tmpl)
@ -72,6 +80,8 @@ func TestGroupWithBeginEnd(t *testing.T) {
assert.Equal(t, "::group::example-value\nfoo\nbar\nbaz\n::endgroup::\n", b.String()) assert.Equal(t, "::group::example-value\nfoo\nbar\nbaz\n::endgroup::\n", b.String())
}) })
t.Run("no output", func(t *testing.T) { t.Run("no output", func(t *testing.T) {
t.Parallel()
var b bytes.Buffer var b bytes.Buffer
_, _, cleanup := o.WrapWriter(&b, io.Discard, "", &tmpl) _, _, cleanup := o.WrapWriter(&b, io.Discard, "", &tmpl)
require.NoError(t, cleanup(nil)) require.NoError(t, cleanup(nil))
@ -80,6 +90,8 @@ func TestGroupWithBeginEnd(t *testing.T) {
} }
func TestGroupErrorOnlySwallowsOutputOnNoError(t *testing.T) { func TestGroupErrorOnlySwallowsOutputOnNoError(t *testing.T) {
t.Parallel()
var b bytes.Buffer var b bytes.Buffer
var o output.Output = output.Group{ var o output.Output = output.Group{
ErrorOnly: true, ErrorOnly: true,
@ -94,6 +106,8 @@ func TestGroupErrorOnlySwallowsOutputOnNoError(t *testing.T) {
} }
func TestGroupErrorOnlyShowsOutputOnError(t *testing.T) { func TestGroupErrorOnlyShowsOutputOnError(t *testing.T) {
t.Parallel()
var b bytes.Buffer var b bytes.Buffer
var o output.Output = output.Group{ var o output.Output = output.Group{
ErrorOnly: true, ErrorOnly: true,
@ -107,7 +121,7 @@ func TestGroupErrorOnlyShowsOutputOnError(t *testing.T) {
assert.Equal(t, "std-out\nstd-err\n", b.String()) assert.Equal(t, "std-out\nstd-err\n", b.String())
} }
func TestPrefixed(t *testing.T) { func TestPrefixed(t *testing.T) { //nolint:paralleltest // cannot run in parallel
var b bytes.Buffer var b bytes.Buffer
l := &logger.Logger{ l := &logger.Logger{
Color: false, Color: false,
@ -116,7 +130,7 @@ func TestPrefixed(t *testing.T) {
var o output.Output = output.NewPrefixed(l) var o output.Output = output.NewPrefixed(l)
w, _, cleanup := o.WrapWriter(&b, io.Discard, "prefix", nil) w, _, cleanup := o.WrapWriter(&b, io.Discard, "prefix", nil)
t.Run("simple use cases", func(t *testing.T) { t.Run("simple use cases", func(t *testing.T) { //nolint:paralleltest // cannot run in parallel
b.Reset() b.Reset()
fmt.Fprintln(w, "foo\nbar") fmt.Fprintln(w, "foo\nbar")
@ -126,7 +140,7 @@ func TestPrefixed(t *testing.T) {
require.NoError(t, cleanup(nil)) require.NoError(t, cleanup(nil))
}) })
t.Run("multiple writes for a single line", func(t *testing.T) { t.Run("multiple writes for a single line", func(t *testing.T) { //nolint:paralleltest // cannot run in parallel
b.Reset() b.Reset()
for _, char := range []string{"T", "e", "s", "t", "!"} { for _, char := range []string{"T", "e", "s", "t", "!"} {
@ -140,6 +154,8 @@ func TestPrefixed(t *testing.T) {
} }
func TestPrefixedWithColor(t *testing.T) { func TestPrefixedWithColor(t *testing.T) {
t.Parallel()
color.NoColor = false color.NoColor = false
var b bytes.Buffer var b bytes.Buffer
@ -155,6 +171,8 @@ func TestPrefixedWithColor(t *testing.T) {
} }
t.Run("colors should loop", func(t *testing.T) { t.Run("colors should loop", func(t *testing.T) {
t.Parallel()
for i, w := range writers { for i, w := range writers {
b.Reset() b.Reset()
@ -164,7 +182,11 @@ func TestPrefixedWithColor(t *testing.T) {
l.FOutf(&prefix, color, fmt.Sprintf("prefix-%d", i)) l.FOutf(&prefix, color, fmt.Sprintf("prefix-%d", i))
fmt.Fprintln(w, "foo\nbar") fmt.Fprintln(w, "foo\nbar")
assert.Equal(t, fmt.Sprintf("[%s] foo\n[%s] bar\n", prefix.String(), prefix.String()), b.String()) assert.Equal(
t,
fmt.Sprintf("[%s] foo\n[%s] bar\n", prefix.String(), prefix.String()),
b.String(),
)
} }
}) })
} }

View File

@ -9,6 +9,8 @@ import (
) )
func TestAlphaNumericWithRootTasksFirst_Sort(t *testing.T) { func TestAlphaNumericWithRootTasksFirst_Sort(t *testing.T) {
t.Parallel()
task1 := &ast.Task{Task: "task1"} task1 := &ast.Task{Task: "task1"}
task2 := &ast.Task{Task: "task2"} task2 := &ast.Task{Task: "task2"}
task3 := &ast.Task{Task: "ns1:task3"} task3 := &ast.Task{Task: "ns1:task3"}
@ -40,6 +42,8 @@ func TestAlphaNumericWithRootTasksFirst_Sort(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel()
s := &AlphaNumericWithRootTasksFirst{} s := &AlphaNumericWithRootTasksFirst{}
s.Sort(tt.tasks) s.Sort(tt.tasks)
assert.Equal(t, tt.want, tt.tasks) assert.Equal(t, tt.want, tt.tasks)
@ -48,6 +52,8 @@ func TestAlphaNumericWithRootTasksFirst_Sort(t *testing.T) {
} }
func TestAlphaNumeric_Sort(t *testing.T) { func TestAlphaNumeric_Sort(t *testing.T) {
t.Parallel()
task1 := &ast.Task{Task: "task1"} task1 := &ast.Task{Task: "task1"}
task2 := &ast.Task{Task: "task2"} task2 := &ast.Task{Task: "task2"}
task3 := &ast.Task{Task: "ns1:task3"} task3 := &ast.Task{Task: "ns1:task3"}
@ -69,6 +75,8 @@ func TestAlphaNumeric_Sort(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel()
s := &AlphaNumeric{} s := &AlphaNumeric{}
s.Sort(tt.tasks) s.Sort(tt.tasks)
assert.Equal(t, tt.tasks, tt.want) assert.Equal(t, tt.tasks, tt.want)

View File

@ -13,6 +13,8 @@ import (
) )
func TestPrintsDependenciesIfPresent(t *testing.T) { func TestPrintsDependenciesIfPresent(t *testing.T) {
t.Parallel()
buffer, l := createDummyLogger() buffer, l := createDummyLogger()
task := &ast.Task{ task := &ast.Task{
Deps: []*ast.Dep{ Deps: []*ast.Dep{
@ -38,6 +40,8 @@ func createDummyLogger() (*bytes.Buffer, logger.Logger) {
} }
func TestDoesNotPrintDependenciesIfMissing(t *testing.T) { func TestDoesNotPrintDependenciesIfMissing(t *testing.T) {
t.Parallel()
buffer, l := createDummyLogger() buffer, l := createDummyLogger()
task := &ast.Task{ task := &ast.Task{
Deps: []*ast.Dep{}, Deps: []*ast.Dep{},
@ -49,6 +53,8 @@ func TestDoesNotPrintDependenciesIfMissing(t *testing.T) {
} }
func TestPrintTaskName(t *testing.T) { func TestPrintTaskName(t *testing.T) {
t.Parallel()
buffer, l := createDummyLogger() buffer, l := createDummyLogger()
task := &ast.Task{ task := &ast.Task{
Task: "my-task-name", Task: "my-task-name",
@ -60,6 +66,8 @@ func TestPrintTaskName(t *testing.T) {
} }
func TestPrintTaskCommandsIfPresent(t *testing.T) { func TestPrintTaskCommandsIfPresent(t *testing.T) {
t.Parallel()
buffer, l := createDummyLogger() buffer, l := createDummyLogger()
task := &ast.Task{ task := &ast.Task{
Cmds: []*ast.Cmd{ Cmds: []*ast.Cmd{
@ -78,6 +86,8 @@ func TestPrintTaskCommandsIfPresent(t *testing.T) {
} }
func TestDoesNotPrintCommandIfMissing(t *testing.T) { func TestDoesNotPrintCommandIfMissing(t *testing.T) {
t.Parallel()
buffer, l := createDummyLogger() buffer, l := createDummyLogger()
task := &ast.Task{ task := &ast.Task{
Cmds: []*ast.Cmd{}, Cmds: []*ast.Cmd{},
@ -89,6 +99,8 @@ func TestDoesNotPrintCommandIfMissing(t *testing.T) {
} }
func TestLayout(t *testing.T) { func TestLayout(t *testing.T) {
t.Parallel()
buffer, l := createDummyLogger() buffer, l := createDummyLogger()
task := &ast.Task{ task := &ast.Task{
Task: "sample-task", Task: "sample-task",
@ -123,6 +135,8 @@ commands:
} }
func TestPrintDescriptionAsFallback(t *testing.T) { func TestPrintDescriptionAsFallback(t *testing.T) {
t.Parallel()
buffer, l := createDummyLogger() buffer, l := createDummyLogger()
taskWithoutSummary := &ast.Task{ taskWithoutSummary := &ast.Task{
Desc: "description", Desc: "description",
@ -150,6 +164,8 @@ func TestPrintDescriptionAsFallback(t *testing.T) {
} }
func TestPrintAllWithSpaces(t *testing.T) { func TestPrintAllWithSpaces(t *testing.T) {
t.Parallel()
buffer, l := createDummyLogger() buffer, l := createDummyLogger()
t1 := &ast.Task{Task: "t1"} t1 := &ast.Task{Task: "t1"}

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,8 @@ import (
) )
func TestPlatformParsing(t *testing.T) { func TestPlatformParsing(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
Input string Input string
ExpectedOS string ExpectedOS string
@ -34,6 +36,8 @@ func TestPlatformParsing(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.Input, func(t *testing.T) { t.Run(test.Input, func(t *testing.T) {
t.Parallel()
var p Platform var p Platform
err := p.parsePlatform(test.Input) err := p.parsePlatform(test.Input)

View File

@ -11,6 +11,8 @@ import (
) )
func TestPreconditionParse(t *testing.T) { func TestPreconditionParse(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
content string content string
v any v any

View File

@ -12,6 +12,8 @@ import (
) )
func TestCmdParse(t *testing.T) { func TestCmdParse(t *testing.T) {
t.Parallel()
const ( const (
yamlCmd = `echo "a string command"` yamlCmd = `echo "a string command"`
yamlDep = `"task-name"` yamlDep = `"task-name"`

View File

@ -7,6 +7,8 @@ import (
) )
func TestGitNode_ssh(t *testing.T) { func TestGitNode_ssh(t *testing.T) {
t.Parallel()
node, err := NewGitNode("git@github.com:foo/bar.git//Taskfile.yml?ref=main", "", false) node, err := NewGitNode("git@github.com:foo/bar.git//Taskfile.yml?ref=main", "", false)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "main", node.ref) assert.Equal(t, "main", node.ref)
@ -19,6 +21,8 @@ func TestGitNode_ssh(t *testing.T) {
} }
func TestGitNode_sshWithDir(t *testing.T) { func TestGitNode_sshWithDir(t *testing.T) {
t.Parallel()
node, err := NewGitNode("git@github.com:foo/bar.git//directory/Taskfile.yml?ref=main", "", false) node, err := NewGitNode("git@github.com:foo/bar.git//directory/Taskfile.yml?ref=main", "", false)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "main", node.ref) assert.Equal(t, "main", node.ref)
@ -31,6 +35,8 @@ func TestGitNode_sshWithDir(t *testing.T) {
} }
func TestGitNode_https(t *testing.T) { func TestGitNode_https(t *testing.T) {
t.Parallel()
node, err := NewGitNode("https://github.com/foo/bar.git//Taskfile.yml?ref=main", "", false) node, err := NewGitNode("https://github.com/foo/bar.git//Taskfile.yml?ref=main", "", false)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "main", node.ref) assert.Equal(t, "main", node.ref)
@ -43,6 +49,8 @@ func TestGitNode_https(t *testing.T) {
} }
func TestGitNode_httpsWithDir(t *testing.T) { func TestGitNode_httpsWithDir(t *testing.T) {
t.Parallel()
node, err := NewGitNode("https://github.com/foo/bar.git//directory/Taskfile.yml?ref=main", "", false) node, err := NewGitNode("https://github.com/foo/bar.git//directory/Taskfile.yml?ref=main", "", false)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "main", node.ref) assert.Equal(t, "main", node.ref)
@ -55,6 +63,8 @@ func TestGitNode_httpsWithDir(t *testing.T) {
} }
func TestGitNode_FilenameAndDir(t *testing.T) { func TestGitNode_FilenameAndDir(t *testing.T) {
t.Parallel()
node, err := NewGitNode("https://github.com/foo/bar.git//directory/Taskfile.yml?ref=main", "", false) node, err := NewGitNode("https://github.com/foo/bar.git//directory/Taskfile.yml?ref=main", "", false)
assert.NoError(t, err) assert.NoError(t, err)
filename, dir := node.FilenameAndLastDir() filename, dir := node.FilenameAndLastDir()

View File

@ -7,6 +7,8 @@ import (
) )
func TestScheme(t *testing.T) { func TestScheme(t *testing.T) {
t.Parallel()
scheme, err := getScheme("https://github.com/foo/bar.git") scheme, err := getScheme("https://github.com/foo/bar.git")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "git", scheme) assert.Equal(t, "git", scheme)