mirror of
https://github.com/ossf/scorecard.git
synced 2024-11-09 17:32:13 +03:00
2169bc44c7
Signed-off-by: Arnaud J Le Hors <lehors@us.ibm.com> Signed-off-by: Arnaud J Le Hors <lehors@us.ibm.com>
161 lines
4.1 KiB
Go
161 lines
4.1 KiB
Go
// Copyright 2021 OpenSSF Scorecard Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
// Package utests defines util fns for Scorecard unit testing.
|
|
package utests
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
"github.com/ossf/scorecard/v4/checker"
|
|
)
|
|
|
|
// TestReturn encapsulates expected CheckResult return values.
|
|
type TestReturn struct {
|
|
Error error
|
|
Score int
|
|
NumberOfWarn int
|
|
NumberOfInfo int
|
|
NumberOfDebug int
|
|
}
|
|
|
|
// TestDetailLogger implements `checker.DetailLogger`.
|
|
type TestDetailLogger struct {
|
|
messages []checker.CheckDetail
|
|
}
|
|
|
|
// Info implements DetailLogger.Info.
|
|
func (l *TestDetailLogger) Info(msg *checker.LogMessage) {
|
|
cd := checker.CheckDetail{
|
|
Type: checker.DetailInfo,
|
|
Msg: *msg,
|
|
}
|
|
l.messages = append(l.messages, cd)
|
|
}
|
|
|
|
// Warn implements DetailLogger.Warn.
|
|
func (l *TestDetailLogger) Warn(msg *checker.LogMessage) {
|
|
cd := checker.CheckDetail{
|
|
Type: checker.DetailWarn,
|
|
Msg: *msg,
|
|
}
|
|
l.messages = append(l.messages, cd)
|
|
}
|
|
|
|
// Debug implements DetailLogger.Debug.
|
|
func (l *TestDetailLogger) Debug(msg *checker.LogMessage) {
|
|
cd := checker.CheckDetail{
|
|
Type: checker.DetailDebug,
|
|
Msg: *msg,
|
|
}
|
|
l.messages = append(l.messages, cd)
|
|
}
|
|
|
|
// Flush implements DetailLogger.Flush.
|
|
func (l *TestDetailLogger) Flush() []checker.CheckDetail {
|
|
ret := l.messages
|
|
l.messages = nil
|
|
return ret
|
|
}
|
|
|
|
func getTestReturn(cr *checker.CheckResult, logger *TestDetailLogger) (*TestReturn, error) {
|
|
ret := new(TestReturn)
|
|
for _, v := range logger.messages {
|
|
switch v.Type {
|
|
default:
|
|
//nolint: goerr113
|
|
return nil, fmt.Errorf("invalid type %v", v.Type)
|
|
case checker.DetailInfo:
|
|
ret.NumberOfInfo++
|
|
case checker.DetailDebug:
|
|
ret.NumberOfDebug++
|
|
case checker.DetailWarn:
|
|
ret.NumberOfWarn++
|
|
}
|
|
}
|
|
ret.Score = cr.Score
|
|
ret.Error = cr.Error
|
|
return ret, nil
|
|
}
|
|
|
|
func errCmp(e1, e2 error) bool {
|
|
return errors.Is(e1, e2) || errors.Is(e2, e1)
|
|
}
|
|
|
|
// ValidateTestReturn validates expected TestReturn with actual checker.CheckResult values.
|
|
// nolint: thelper
|
|
func ValidateTestReturn(
|
|
t *testing.T,
|
|
name string,
|
|
expected *TestReturn,
|
|
actual *checker.CheckResult,
|
|
logger *TestDetailLogger,
|
|
) bool {
|
|
actualTestReturn, err := getTestReturn(actual, logger)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if !cmp.Equal(*expected, *actualTestReturn, cmp.Comparer(errCmp)) {
|
|
log.Println(name+":", cmp.Diff(*expected, *actualTestReturn))
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// ValidatePinningDependencies tests that at least one entry returns true for isExpectedMessage.
|
|
func ValidatePinningDependencies(isExpectedDependency func(checker.Dependency) bool,
|
|
r *checker.PinningDependenciesData,
|
|
) bool {
|
|
for _, dep := range r.Dependencies {
|
|
if isExpectedDependency(dep) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ValidateLogMessage tests that at least one log message returns true for isExpectedMessage.
|
|
func ValidateLogMessage(isExpectedMessage func(checker.LogMessage, checker.DetailType) bool,
|
|
dl *TestDetailLogger,
|
|
) bool {
|
|
for _, message := range dl.messages {
|
|
if isExpectedMessage(message.Msg, message.Type) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ValidateLogMessageOffsets tests that the log message offsets match those
|
|
// in the passed in slice.
|
|
func ValidateLogMessageOffsets(dl *TestDetailLogger, offsets []uint) bool {
|
|
if len(dl.messages) != len(offsets) {
|
|
log.Println(cmp.Diff(dl.messages, offsets))
|
|
return false
|
|
}
|
|
for i, message := range dl.messages {
|
|
expectedOffset := offsets[i]
|
|
if expectedOffset != message.Msg.Offset {
|
|
log.Println(cmp.Diff(message.Msg.Offset, expectedOffset))
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|