Skip to content

Commit d591e38

Browse files
🌱 Add RepoClient re-use E2E tests. (#2625)
* Add e2e test for re-used repoclient. Signed-off-by: Spencer Schrock <sschrock@google.com> * Improve diff logging Signed-off-by: Spencer Schrock <sschrock@google.com> * Skip scorecard e2e test during unit tests. Signed-off-by: Spencer Schrock <sschrock@google.com> * Fix linter. Signed-off-by: Spencer Schrock <sschrock@google.com> --------- Signed-off-by: Spencer Schrock <sschrock@google.com>
1 parent a7e81bb commit d591e38

2 files changed

Lines changed: 170 additions & 0 deletions

File tree

pkg/pkg_suite_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2023 OpenSSF Scorecard Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package pkg_test
16+
17+
import (
18+
"os"
19+
"testing"
20+
21+
. "github.com/onsi/ginkgo/v2"
22+
. "github.com/onsi/gomega"
23+
)
24+
25+
func TestPkg(t *testing.T) {
26+
if val, exists := os.LookupEnv("SKIP_GINKGO"); exists && val == "1" {
27+
t.Skip()
28+
}
29+
RegisterFailHandler(Fail)
30+
RunSpecs(t, "Pkg Suite")
31+
}

pkg/scorecard_e2e_test.go

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// Copyright 2023 OpenSSF Scorecard Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package pkg
16+
17+
import (
18+
"context"
19+
"fmt"
20+
"sort"
21+
"time"
22+
23+
"github.com/google/go-cmp/cmp"
24+
. "github.com/onsi/ginkgo/v2"
25+
. "github.com/onsi/gomega"
26+
27+
"github.com/ossf/scorecard/v4/checker"
28+
"github.com/ossf/scorecard/v4/checks"
29+
"github.com/ossf/scorecard/v4/clients"
30+
"github.com/ossf/scorecard/v4/clients/githubrepo"
31+
sclog "github.com/ossf/scorecard/v4/log"
32+
)
33+
34+
func (r *ScorecardResult) normalize() {
35+
r.Date = time.Time{}
36+
sort.Slice(r.Checks, func(i, j int) bool {
37+
return r.Checks[i].Name < r.Checks[j].Name
38+
})
39+
}
40+
41+
func countDetails(c []checker.CheckDetail) (debug, info, warn int) {
42+
for i := range c {
43+
switch c[i].Type {
44+
case checker.DetailDebug:
45+
debug++
46+
case checker.DetailInfo:
47+
info++
48+
case checker.DetailWarn:
49+
warn++
50+
}
51+
}
52+
return debug, info, warn
53+
}
54+
55+
//nolint:lll,gocritic // comparison was failing with pointer types
56+
func compareScorecardResults(a, b ScorecardResult) bool {
57+
if a.Repo != b.Repo {
58+
fmt.Fprintf(GinkgoWriter, "Unequal repo details in results: %v vs %v\n", a.Repo, b.Repo)
59+
return false
60+
}
61+
if a.Scorecard != b.Scorecard {
62+
fmt.Fprintf(GinkgoWriter, "Unequal scorecard details in results: %v vs %v\n", a.Scorecard, b.Scorecard)
63+
return false
64+
}
65+
if len(a.Checks) != len(b.Checks) {
66+
fmt.Fprintf(GinkgoWriter, "Unequal number of checks in results: %d vs %d\n", len(a.Checks), len(b.Checks))
67+
return false
68+
}
69+
for i := range a.Checks {
70+
if a.Checks[i].Name != b.Checks[i].Name {
71+
fmt.Fprintf(GinkgoWriter, "Check name mismatch: %q vs %q\n", a.Checks[i].Name, b.Checks[i].Name)
72+
return false
73+
}
74+
if a.Checks[i].Version != b.Checks[i].Version {
75+
fmt.Fprintf(GinkgoWriter, "%q version mismatch: %d vs %d\n", a.Checks[i].Name, a.Checks[i].Version, b.Checks[i].Version)
76+
return false
77+
}
78+
if a.Checks[i].Score != b.Checks[i].Score {
79+
fmt.Fprintf(GinkgoWriter, "%q score mismatch: %d vs %d\n", a.Checks[i].Name, a.Checks[i].Score, b.Checks[i].Score)
80+
return false
81+
}
82+
if a.Checks[i].Reason != b.Checks[i].Reason {
83+
fmt.Fprintf(GinkgoWriter, "%q reason mismatch: %q vs %q\n", a.Checks[i].Name, a.Checks[i].Reason, b.Checks[i].Reason)
84+
return false
85+
}
86+
// details are only compared using the number of debug, info and warn
87+
aDebug, aInfo, aWarn := countDetails(a.Checks[i].Details)
88+
bDebug, bInfo, bWarn := countDetails(b.Checks[i].Details)
89+
if aDebug != bDebug || aInfo != bInfo || aWarn != bWarn {
90+
fmt.Fprintf(GinkgoWriter, "%q details mismatch:\n", a.Checks[i].Name)
91+
fmt.Fprintf(GinkgoWriter, "\tdebug: %d-%d\n", aDebug, bDebug)
92+
fmt.Fprintf(GinkgoWriter, "\tinfo: %d-%d\n", aInfo, bInfo)
93+
fmt.Fprintf(GinkgoWriter, "\twarn: %d-%d\n", aWarn, bWarn)
94+
return false
95+
}
96+
}
97+
return true
98+
}
99+
100+
var _ = Describe("E2E TEST: RunScorecard with re-used repoClient", func() {
101+
Context("E2E TEST: Validate results are identical regardless of order", func() {
102+
assertLastResultsIdentical := func(repos []string) {
103+
if len(repos) < 2 {
104+
return
105+
}
106+
ctx := context.Background()
107+
allChecks := checks.GetAll()
108+
109+
isolatedLogger := sclog.NewLogger(sclog.DebugLevel)
110+
lastRepo := repos[len(repos)-1]
111+
repo, rc, ofrc, cc, vc, err := checker.GetClients(ctx, lastRepo, "", isolatedLogger)
112+
Expect(err).Should(BeNil())
113+
isolatedResult, err := RunScorecard(ctx, repo, clients.HeadSHA, 0, allChecks, rc, ofrc, cc, vc)
114+
Expect(err).Should(BeNil())
115+
116+
logger := sclog.NewLogger(sclog.DebugLevel)
117+
_, rc2, ofrc2, cc2, vc2, err := checker.GetClients(ctx, repos[0], "", logger)
118+
Expect(err).Should(BeNil())
119+
120+
var sharedResult ScorecardResult
121+
for i := range repos {
122+
repo, err = githubrepo.MakeGithubRepo(repos[i])
123+
Expect(err).Should(BeNil())
124+
sharedResult, err = RunScorecard(ctx, repo, clients.HeadSHA, 0, allChecks, rc2, ofrc2, cc2, vc2)
125+
Expect(err).Should(BeNil())
126+
}
127+
128+
isolatedResult.normalize()
129+
sharedResult.normalize()
130+
Expect(isolatedResult).To(BeComparableTo(sharedResult, cmp.Comparer(compareScorecardResults)))
131+
}
132+
It("A then B results should be produce the same distribution of details as the isolated B results", func() {
133+
assertLastResultsIdentical([]string{
134+
"https://github.com/ossf-tests/scorecard",
135+
"https://github.com/ossf-tests/scorecard-action",
136+
})
137+
})
138+
})
139+
})

0 commit comments

Comments
 (0)