-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tests for Parallel and Sorted runners (#21)
* test examples * fix * fix * fix * fix * fix * fix * added dependencies * added tests for Parallel and Sorted runners * test linter as well * fix linter * fix build status badge * make linter happy * make containers self-sufficient * improve caching of docker image * revert * update linter * add more margin because travis tests in macos are slower * travis is too unstable * use special _test package for testing * rename jobResult to jr for brevity * added testHosts to test functions * moved helpers to testing.go and copied nullloger * remove runner_test * use "vendored" null logger * clarity * rename serial.go to sorted.go * fixes * forgot to include :S * increase margin of error
- Loading branch information
Showing
7 changed files
with
219 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package runner_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
|
||
"github.com/nornir-automation/gornir/pkg/gornir" | ||
"github.com/nornir-automation/gornir/pkg/plugins/runner" | ||
) | ||
|
||
// TestParallel is going to check that the func runs on all hosts | ||
// and that it takes less than X time to complete. The test func | ||
// basically will sleep for N ms and given we are using goroutines | ||
// the completion should only be slightly above it even though | ||
// we are sleeping once per device | ||
func TestParallel(t *testing.T) { | ||
testCases := []struct { | ||
name string | ||
expected map[string]bool | ||
sleepDuration time.Duration | ||
}{ | ||
{ | ||
name: "simple test", | ||
expected: map[string]bool{"dev1": true, "dev2": true, "dev3": true, "dev4": true}, | ||
sleepDuration: 200 * time.Millisecond, | ||
}, | ||
} | ||
|
||
testHosts := map[string]*gornir.Host{ | ||
"dev1": {Hostname: "dev1"}, | ||
"dev2": {Hostname: "dev2"}, | ||
"dev3": {Hostname: "dev3"}, | ||
"dev4": {Hostname: "dev4"}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
tc := tc | ||
results := make(chan *gornir.JobResult, len(testHosts)) | ||
t.Run(tc.name, func(t *testing.T) { | ||
rnr := runner.Parallel() | ||
startTime := time.Now() | ||
if err := rnr.Run( | ||
context.Background(), | ||
&testTaskSleep{sleepDuration: tc.sleepDuration}, | ||
testHosts, | ||
gornir.NewJobParameters("test", NewNullLogger()), | ||
results, | ||
); err != nil { | ||
t.Fatal(err) | ||
} | ||
if err := rnr.Wait(); err != nil { | ||
t.Fatal(err) | ||
} | ||
close(results) | ||
|
||
// let's process the results and turn it into a map so we can | ||
// compare with our expected value | ||
got := make(map[string]bool) | ||
for res := range results { | ||
got[res.JobParameters().Host().Hostname] = res.Data().(*testTaskSleepResults).success | ||
} | ||
if !cmp.Equal(got, tc.expected) { | ||
t.Error(cmp.Diff(got, tc.expected)) | ||
} | ||
// now we check test took what we expected | ||
if time.Since(startTime) > (tc.sleepDuration + time.Millisecond*100) { | ||
t.Errorf("test took to long, parallelization might not be working: %v\n", time.Since(startTime).Seconds()) | ||
} | ||
}) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package runner_test | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
"time" | ||
|
||
"github.com/nornir-automation/gornir/pkg/gornir" | ||
) | ||
|
||
type testTaskSleep struct { | ||
sleepDuration time.Duration | ||
} | ||
|
||
type testTaskSleepResults struct { | ||
success bool | ||
} | ||
|
||
func (t *testTaskSleep) Run(ctx context.Context, wg *sync.WaitGroup, jp *gornir.JobParameters, jr chan *gornir.JobResult) { | ||
defer wg.Done() | ||
time.Sleep(t.sleepDuration) | ||
result := gornir.NewJobResult(ctx, jp) | ||
result.SetData(&testTaskSleepResults{success: true}) | ||
jr <- result | ||
} | ||
|
||
// Null is a logger that doesn't do anything. Implements gornir.Logger interface | ||
type Null struct { | ||
} | ||
|
||
// NewNullLogger instantiates a new Null logger | ||
func NewNullLogger() *Null { | ||
return &Null{} | ||
} | ||
|
||
// WithField implements gornir.Logger interface | ||
func (n *Null) WithField(field string, value interface{}) gornir.Logger { | ||
return n | ||
} | ||
|
||
// Info implements gornir.Logger interface | ||
func (n *Null) Info(args ...interface{}) { | ||
} | ||
|
||
// Debug implements gornir.Logger interface | ||
func (n *Null) Debug(args ...interface{}) { | ||
} | ||
|
||
// Error implements gornir.Logger interface | ||
func (n *Null) Error(args ...interface{}) { | ||
} | ||
|
||
// Warn implements gornir.Logger interface | ||
func (n *Null) Warn(args ...interface{}) { | ||
} | ||
|
||
// Fatal implements gornir.Logger interface | ||
func (n *Null) Fatal(args ...interface{}) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package runner_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
|
||
"github.com/nornir-automation/gornir/pkg/gornir" | ||
"github.com/nornir-automation/gornir/pkg/plugins/runner" | ||
) | ||
|
||
// TestSorted runs test func and verifies the hosts are executed | ||
// in alphabetical order by checking the results come in the right | ||
// order | ||
func TestSorted(t *testing.T) { | ||
testCases := []struct { | ||
name string | ||
expected []string | ||
sleepDuration time.Duration | ||
}{ | ||
{ | ||
name: "run in alphabetical order", | ||
expected: []string{"dev1", "dev2", "dev3", "dev4"}, | ||
sleepDuration: 1 * time.Millisecond, | ||
}, | ||
} | ||
|
||
testHosts := map[string]*gornir.Host{ | ||
"dev1": {Hostname: "dev1"}, | ||
"dev2": {Hostname: "dev2"}, | ||
"dev3": {Hostname: "dev3"}, | ||
"dev4": {Hostname: "dev4"}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
tc := tc | ||
results := make(chan *gornir.JobResult, len(testHosts)) | ||
t.Run(tc.name, func(t *testing.T) { | ||
rnr := runner.Sorted() | ||
if err := rnr.Run( | ||
context.Background(), | ||
&testTaskSleep{sleepDuration: tc.sleepDuration}, | ||
testHosts, | ||
gornir.NewJobParameters("test", NewNullLogger()), | ||
results, | ||
); err != nil { | ||
t.Fatal(err) | ||
} | ||
if err := rnr.Wait(); err != nil { | ||
t.Fatal(err) | ||
} | ||
close(results) | ||
|
||
// let's process the results and turn it into a list so we can | ||
// compare with our expected value | ||
got := make([]string, len(testHosts)) | ||
i := 0 | ||
for res := range results { | ||
got[i] = res.JobParameters().Host().Hostname | ||
i++ | ||
} | ||
if !cmp.Equal(got, tc.expected) { | ||
t.Error(cmp.Diff(got, tc.expected)) | ||
} | ||
}) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters