-
Notifications
You must be signed in to change notification settings - Fork 47
/
runner_worker.go
108 lines (91 loc) · 2.83 KB
/
runner_worker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package runner
import (
"context"
"sync"
"time"
"github.com/mszostok/codeowners-validator/internal/check"
"github.com/mszostok/codeowners-validator/internal/printer"
"github.com/mszostok/codeowners-validator/pkg/codeowners"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
const (
// MaxUint defines the max unsigned int value.
MaxUint = ^uint(0)
// MaxInt defines the max signed int value.
MaxInt = int(MaxUint >> 1)
)
// Printer prints the checks results
type Printer interface {
PrintCheckResult(checkName string, duration time.Duration, checkOut check.Output)
PrintSummary(allCheck int, failedChecks int)
}
// CheckRunner runs all registered checks in parallel.
// Needs to be initialized via NewCheckRunner func.
type CheckRunner struct {
m sync.RWMutex
log logrus.FieldLogger
codeowners []codeowners.Entry
repoPath string
treatedAsFailure check.SeverityType
checks []check.Checker
printer Printer
allFoundIssues map[check.SeverityType]uint32
notPassedChecksCnt int
}
// NewCheckRunner is a constructor for CheckRunner
func NewCheckRunner(log logrus.FieldLogger, co []codeowners.Entry, repoPath string, treatedAsFailure check.SeverityType, checks ...check.Checker) *CheckRunner {
return &CheckRunner{
log: log.WithField("service", "check:runner"),
repoPath: repoPath,
treatedAsFailure: treatedAsFailure,
codeowners: co,
checks: checks,
printer: &printer.TTYPrinter{},
allFoundIssues: map[check.SeverityType]uint32{},
}
}
// Run executes given test in a loop with given throttle
func (r *CheckRunner) Run(ctx context.Context) {
wg := sync.WaitGroup{}
// TODO(mszostok): timeout per check?
wg.Add(len(r.checks))
for _, c := range r.checks {
go func(c check.Checker) {
defer wg.Done()
startTime := time.Now()
out, err := c.Check(ctx, check.Input{
CodeownersEntries: r.codeowners,
RepoDir: r.repoPath,
})
if err != nil {
// TODO(mszostok): add err handling (logging it internally is not enough)
r.log.Errorf(errors.Wrapf(err, "while executing checker %s", c.Name()).Error())
return
}
r.collectMetrics(out)
r.printer.PrintCheckResult(c.Name(), time.Since(startTime), out)
}(c)
}
wg.Wait()
r.printer.PrintSummary(len(r.checks), r.notPassedChecksCnt)
}
func (r *CheckRunner) ShouldExitWithCheckFailure() bool {
higherOccurredIssue := check.SeverityType(MaxInt)
for key := range r.allFoundIssues {
if higherOccurredIssue > key {
higherOccurredIssue = key
}
}
return higherOccurredIssue <= r.treatedAsFailure
}
func (r *CheckRunner) collectMetrics(checkOut check.Output) {
r.m.Lock()
defer r.m.Unlock()
for _, i := range checkOut.Issues {
r.allFoundIssues[i.Severity]++
}
if len(checkOut.Issues) > 0 {
r.notPassedChecksCnt++
}
}