* feat(cve/mitre): support go-cve-dictionary:mitre * chore: adopt reviewer comment * refactor(models): refactor CveContents method
722 lines
16 KiB
Go
722 lines
16 KiB
Go
package models
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/future-architect/vuls/constant"
|
|
)
|
|
|
|
func TestCveContents_Except(t *testing.T) {
|
|
type args struct {
|
|
exceptCtypes []CveContentType
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
v CveContents
|
|
args args
|
|
wantValues CveContents
|
|
}{
|
|
{
|
|
name: "happy",
|
|
v: CveContents{
|
|
RedHat: []CveContent{{Type: RedHat}},
|
|
Ubuntu: []CveContent{{Type: Ubuntu}},
|
|
Debian: []CveContent{{Type: Debian}},
|
|
},
|
|
args: args{
|
|
exceptCtypes: []CveContentType{Ubuntu, Debian},
|
|
},
|
|
wantValues: CveContents{
|
|
RedHat: []CveContent{{Type: RedHat}},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if gotValues := tt.v.Except(tt.args.exceptCtypes...); !reflect.DeepEqual(gotValues, tt.wantValues) {
|
|
t.Errorf("CveContents.Except() = %v, want %v", gotValues, tt.wantValues)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSourceLinks(t *testing.T) {
|
|
type in struct {
|
|
lang string
|
|
cveID string
|
|
cont CveContents
|
|
confidences Confidences
|
|
}
|
|
var tests = []struct {
|
|
in in
|
|
out []CveContentStr
|
|
}{
|
|
// lang: ja
|
|
{
|
|
in: in{
|
|
lang: "ja",
|
|
cveID: "CVE-2017-6074",
|
|
cont: CveContents{
|
|
Jvn: []CveContent{{
|
|
Type: Jvn,
|
|
SourceLink: "https://jvn.jp/vu/JVNVU93610402/",
|
|
}},
|
|
RedHat: []CveContent{{
|
|
Type: RedHat,
|
|
SourceLink: "https://access.redhat.com/security/cve/CVE-2017-6074",
|
|
}},
|
|
Nvd: []CveContent{{
|
|
Type: Nvd,
|
|
References: []Reference{
|
|
{
|
|
Link: "https://lists.apache.org/thread.html/765be3606d865de513f6df9288842c3cf58b09a987c617a535f2b99d@%3Cusers.tapestry.apache.org%3E",
|
|
Source: "",
|
|
RefID: "",
|
|
Tags: []string{"Vendor Advisory"},
|
|
},
|
|
{
|
|
Link: "http://yahoo.com",
|
|
Source: "",
|
|
RefID: "",
|
|
Tags: []string{"Vendor"},
|
|
},
|
|
},
|
|
SourceLink: "https://nvd.nist.gov/vuln/detail/CVE-2017-6074",
|
|
}},
|
|
},
|
|
},
|
|
out: []CveContentStr{
|
|
{
|
|
Type: Nvd,
|
|
Value: "https://lists.apache.org/thread.html/765be3606d865de513f6df9288842c3cf58b09a987c617a535f2b99d@%3Cusers.tapestry.apache.org%3E",
|
|
},
|
|
{
|
|
Type: Nvd,
|
|
Value: "https://nvd.nist.gov/vuln/detail/CVE-2017-6074",
|
|
},
|
|
{
|
|
Type: Jvn,
|
|
Value: "https://jvn.jp/vu/JVNVU93610402/",
|
|
},
|
|
{
|
|
Type: RedHat,
|
|
Value: "https://access.redhat.com/security/cve/CVE-2017-6074",
|
|
},
|
|
},
|
|
},
|
|
// lang: en
|
|
{
|
|
in: in{
|
|
lang: "en",
|
|
cveID: "CVE-2017-6074",
|
|
cont: CveContents{
|
|
Jvn: []CveContent{{
|
|
Type: Jvn,
|
|
SourceLink: "https://jvn.jp/vu/JVNVU93610402/",
|
|
}},
|
|
RedHat: []CveContent{{
|
|
Type: RedHat,
|
|
SourceLink: "https://access.redhat.com/security/cve/CVE-2017-6074",
|
|
}},
|
|
},
|
|
},
|
|
out: []CveContentStr{
|
|
{
|
|
Type: RedHat,
|
|
Value: "https://access.redhat.com/security/cve/CVE-2017-6074",
|
|
},
|
|
},
|
|
},
|
|
// lang: empty
|
|
{
|
|
in: in{
|
|
lang: "en",
|
|
cveID: "CVE-2017-6074",
|
|
cont: CveContents{},
|
|
},
|
|
out: []CveContentStr{
|
|
{
|
|
Type: Nvd,
|
|
Value: "https://nvd.nist.gov/vuln/detail/CVE-2017-6074",
|
|
},
|
|
},
|
|
},
|
|
// Confidence: JvnVendorProductMatch
|
|
{
|
|
in: in{
|
|
lang: "en",
|
|
cveID: "CVE-2017-6074",
|
|
cont: CveContents{
|
|
Jvn: []CveContent{{
|
|
Type: Jvn,
|
|
SourceLink: "https://jvn.jp/vu/JVNVU93610402/",
|
|
}},
|
|
},
|
|
confidences: Confidences{
|
|
Confidence{DetectionMethod: JvnVendorProductMatchStr},
|
|
},
|
|
},
|
|
out: []CveContentStr{
|
|
{
|
|
Type: Jvn,
|
|
Value: "https://jvn.jp/vu/JVNVU93610402/",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for i, tt := range tests {
|
|
actual := tt.in.cont.PrimarySrcURLs(tt.in.lang, "redhat", tt.in.cveID, tt.in.confidences)
|
|
if !reflect.DeepEqual(tt.out, actual) {
|
|
t.Errorf("\n[%d] expected: %v\n actual: %v\n", i, tt.out, actual)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCveContents_PatchURLs(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
v CveContents
|
|
wantUrls []string
|
|
}{
|
|
{
|
|
name: "happy",
|
|
v: CveContents{
|
|
Nvd: []CveContent{
|
|
{
|
|
References: []Reference{
|
|
{
|
|
Link: "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c52873e5a1ef72f845526d9f6a50704433f9c625",
|
|
Source: "cve@mitre.org",
|
|
Tags: []string{"Patch", "Vendor Advisory"},
|
|
},
|
|
{
|
|
Link: "https://lists.debian.org/debian-lts-announce/2020/01/msg00013.html",
|
|
Source: "cve@mitre.org",
|
|
Tags: []string{"Mailing List", "Third Party Advisory"},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
References: []Reference{
|
|
{
|
|
Link: "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c52873e5a1ef72f845526d9f6a50704433f9c625",
|
|
Tags: []string{"Patch", "Vendor Advisory"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantUrls: []string{"https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c52873e5a1ef72f845526d9f6a50704433f9c625"},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if gotUrls := tt.v.PatchURLs(); !reflect.DeepEqual(gotUrls, tt.wantUrls) {
|
|
t.Errorf("CveContents.PatchURLs() = %v, want %v", gotUrls, tt.wantUrls)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCveContents_Cpes(t *testing.T) {
|
|
type args struct {
|
|
myFamily string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
v CveContents
|
|
args args
|
|
wantValues []CveContentCpes
|
|
}{
|
|
{
|
|
name: "happy",
|
|
v: CveContents{
|
|
Nvd: []CveContent{{
|
|
Cpes: []Cpe{{
|
|
URI: "cpe:/a:microsoft:internet_explorer:8.0.6001:beta",
|
|
FormattedString: "cpe:2.3:a:microsoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*",
|
|
}},
|
|
}},
|
|
},
|
|
args: args{myFamily: "redhat"},
|
|
wantValues: []CveContentCpes{{
|
|
Type: Nvd,
|
|
Value: []Cpe{{
|
|
URI: "cpe:/a:microsoft:internet_explorer:8.0.6001:beta",
|
|
FormattedString: "cpe:2.3:a:microsoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*",
|
|
}},
|
|
}},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if gotValues := tt.v.Cpes(tt.args.myFamily); !reflect.DeepEqual(gotValues, tt.wantValues) {
|
|
t.Errorf("CveContents.Cpes() = %v, want %v", gotValues, tt.wantValues)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
func TestCveContents_References(t *testing.T) {
|
|
type args struct {
|
|
myFamily string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
v CveContents
|
|
args args
|
|
wantValues []CveContentRefs
|
|
}{
|
|
{
|
|
name: "happy",
|
|
v: CveContents{
|
|
Mitre: []CveContent{{CveID: "CVE-2024-0001"}},
|
|
Nvd: []CveContent{
|
|
{
|
|
References: []Reference{
|
|
{
|
|
Link: "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c52873e5a1ef72f845526d9f6a50704433f9c625",
|
|
Source: "cve@mitre.org",
|
|
Tags: []string{"Patch", "Vendor Advisory"},
|
|
},
|
|
{
|
|
Link: "https://lists.debian.org/debian-lts-announce/2020/01/msg00013.html",
|
|
Source: "cve@mitre.org",
|
|
Tags: []string{"Mailing List", "Third Party Advisory"},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
References: []Reference{
|
|
{
|
|
Link: "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c52873e5a1ef72f845526d9f6a50704433f9c625",
|
|
Tags: []string{"Patch", "Vendor Advisory"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantValues: []CveContentRefs{
|
|
{
|
|
Type: Nvd,
|
|
Value: []Reference{
|
|
{
|
|
Link: "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c52873e5a1ef72f845526d9f6a50704433f9c625",
|
|
Source: "cve@mitre.org",
|
|
Tags: []string{"Patch", "Vendor Advisory"},
|
|
},
|
|
{
|
|
Link: "https://lists.debian.org/debian-lts-announce/2020/01/msg00013.html",
|
|
Source: "cve@mitre.org",
|
|
Tags: []string{"Mailing List", "Third Party Advisory"},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Type: Nvd,
|
|
Value: []Reference{
|
|
{
|
|
Link: "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c52873e5a1ef72f845526d9f6a50704433f9c625",
|
|
Tags: []string{"Patch", "Vendor Advisory"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if gotValues := tt.v.References(tt.args.myFamily); !reflect.DeepEqual(gotValues, tt.wantValues) {
|
|
t.Errorf("CveContents.References() = %v, want %v", gotValues, tt.wantValues)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCveContents_CweIDs(t *testing.T) {
|
|
type args struct {
|
|
myFamily string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
v CveContents
|
|
args args
|
|
wantValues []CveContentStr
|
|
}{
|
|
{
|
|
name: "happy",
|
|
v: CveContents{
|
|
Mitre: []CveContent{{CweIDs: []string{"CWE-001"}}},
|
|
Nvd: []CveContent{
|
|
{CweIDs: []string{"CWE-001"}},
|
|
{CweIDs: []string{"CWE-001"}},
|
|
},
|
|
},
|
|
args: args{myFamily: "redhat"},
|
|
wantValues: []CveContentStr{
|
|
{
|
|
Type: Mitre,
|
|
Value: "CWE-001",
|
|
},
|
|
{
|
|
Type: Nvd,
|
|
Value: "CWE-001",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if gotValues := tt.v.CweIDs(tt.args.myFamily); !reflect.DeepEqual(gotValues, tt.wantValues) {
|
|
t.Errorf("CveContents.CweIDs() = %v, want %v", gotValues, tt.wantValues)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCveContents_UniqCweIDs(t *testing.T) {
|
|
type args struct {
|
|
myFamily string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
v CveContents
|
|
args args
|
|
want []CveContentStr
|
|
}{
|
|
{
|
|
name: "happy",
|
|
v: CveContents{
|
|
Mitre: []CveContent{{CweIDs: []string{"CWE-001"}}},
|
|
Nvd: []CveContent{
|
|
{CweIDs: []string{"CWE-001"}},
|
|
{CweIDs: []string{"CWE-001"}},
|
|
},
|
|
},
|
|
args: args{myFamily: "redhat"},
|
|
want: []CveContentStr{
|
|
{
|
|
Type: Nvd,
|
|
Value: "CWE-001",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := tt.v.UniqCweIDs(tt.args.myFamily); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("CveContents.UniqCweIDs() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCveContents_SSVC(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
v CveContents
|
|
want []CveContentSSVC
|
|
}{
|
|
{
|
|
name: "happy",
|
|
v: CveContents{
|
|
Mitre: []CveContent{
|
|
{
|
|
Type: Mitre,
|
|
CveID: "CVE-2024-5732",
|
|
Title: "Clash Proxy Port improper authentication",
|
|
Optional: map[string]string{"source": "CNA"},
|
|
},
|
|
{
|
|
Type: Mitre,
|
|
CveID: "CVE-2024-5732",
|
|
Title: "CISA ADP Vulnrichment",
|
|
SSVC: &SSVC{
|
|
Exploitation: "none",
|
|
Automatable: "no",
|
|
TechnicalImpact: "partial",
|
|
},
|
|
Optional: map[string]string{"source": "ADP:CISA-ADP"},
|
|
},
|
|
},
|
|
},
|
|
want: []CveContentSSVC{
|
|
{
|
|
Type: "mitre(ADP:CISA-ADP)",
|
|
Value: SSVC{
|
|
Exploitation: "none",
|
|
Automatable: "no",
|
|
TechnicalImpact: "partial",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := tt.v.SSVC(); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("CveContents.SSVC() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCveContents_Sort(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
v CveContents
|
|
want CveContents
|
|
}{
|
|
{
|
|
name: "sorted",
|
|
v: map[CveContentType][]CveContent{
|
|
"jvn": {
|
|
{Cvss3Score: 3},
|
|
{Cvss3Score: 10},
|
|
},
|
|
},
|
|
want: map[CveContentType][]CveContent{
|
|
"jvn": {
|
|
{Cvss3Score: 10},
|
|
{Cvss3Score: 3},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "sort JVN by cvss3, cvss2, sourceLink",
|
|
v: map[CveContentType][]CveContent{
|
|
"jvn": {
|
|
{
|
|
Cvss3Score: 3,
|
|
Cvss2Score: 3,
|
|
SourceLink: "https://jvndb.jvn.jp/ja/contents/2023/JVNDB-2023-001210.html",
|
|
},
|
|
{
|
|
Cvss3Score: 3,
|
|
Cvss2Score: 3,
|
|
SourceLink: "https://jvndb.jvn.jp/ja/contents/2021/JVNDB-2021-001210.html",
|
|
},
|
|
},
|
|
},
|
|
want: map[CveContentType][]CveContent{
|
|
"jvn": {
|
|
{
|
|
Cvss3Score: 3,
|
|
Cvss2Score: 3,
|
|
SourceLink: "https://jvndb.jvn.jp/ja/contents/2021/JVNDB-2021-001210.html",
|
|
},
|
|
{
|
|
Cvss3Score: 3,
|
|
Cvss2Score: 3,
|
|
SourceLink: "https://jvndb.jvn.jp/ja/contents/2023/JVNDB-2023-001210.html",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "sort JVN by cvss3, cvss2",
|
|
v: map[CveContentType][]CveContent{
|
|
"jvn": {
|
|
{
|
|
Cvss3Score: 3,
|
|
Cvss2Score: 1,
|
|
},
|
|
{
|
|
Cvss3Score: 3,
|
|
Cvss2Score: 10,
|
|
},
|
|
},
|
|
},
|
|
want: map[CveContentType][]CveContent{
|
|
"jvn": {
|
|
{
|
|
Cvss3Score: 3,
|
|
Cvss2Score: 10,
|
|
},
|
|
{
|
|
Cvss3Score: 3,
|
|
Cvss2Score: 1,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "sort CVSS v4.0",
|
|
v: CveContents{
|
|
Mitre: []CveContent{
|
|
{Cvss40Score: 0},
|
|
{Cvss40Score: 6.9},
|
|
},
|
|
},
|
|
want: CveContents{
|
|
Mitre: []CveContent{
|
|
{Cvss40Score: 6.9},
|
|
{Cvss40Score: 0},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "sort CVSS v4.0 and CVSS v3",
|
|
v: CveContents{
|
|
Mitre: []CveContent{
|
|
{
|
|
Cvss40Score: 0,
|
|
Cvss3Score: 7.3,
|
|
},
|
|
{
|
|
Cvss40Score: 0,
|
|
Cvss3Score: 9.8,
|
|
},
|
|
},
|
|
},
|
|
want: CveContents{
|
|
Mitre: []CveContent{
|
|
{
|
|
Cvss40Score: 0,
|
|
Cvss3Score: 9.8,
|
|
},
|
|
{
|
|
Cvss40Score: 0,
|
|
Cvss3Score: 7.3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
tt.v.Sort()
|
|
if !reflect.DeepEqual(tt.v, tt.want) {
|
|
t.Errorf("\n[%s] expected: %v\n actual: %v\n", tt.name, tt.want, tt.v)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCveContent_Empty(t *testing.T) {
|
|
type fields struct {
|
|
Type CveContentType
|
|
CveID string
|
|
Title string
|
|
Summary string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
want bool
|
|
}{
|
|
{
|
|
name: "empty",
|
|
fields: fields{
|
|
Summary: "",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "not empty",
|
|
fields: fields{
|
|
Summary: "summary",
|
|
},
|
|
want: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := (CveContent{
|
|
Type: tt.fields.Type,
|
|
CveID: tt.fields.CveID,
|
|
Title: tt.fields.Title,
|
|
Summary: tt.fields.Summary,
|
|
}).Empty(); got != tt.want {
|
|
t.Errorf("CveContent.Empty() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNewCveContentType(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
want CveContentType
|
|
}{
|
|
{
|
|
name: "redhat",
|
|
want: RedHat,
|
|
},
|
|
{
|
|
name: "centos",
|
|
want: RedHat,
|
|
},
|
|
{
|
|
name: "unknown",
|
|
want: Unknown,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := NewCveContentType(tt.name); got != tt.want {
|
|
t.Errorf("NewCveContentType() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetCveContentTypes(t *testing.T) {
|
|
tests := []struct {
|
|
family string
|
|
want []CveContentType
|
|
}{
|
|
{
|
|
family: constant.RedHat,
|
|
want: []CveContentType{RedHat, RedHatAPI},
|
|
},
|
|
{
|
|
family: constant.Debian,
|
|
want: []CveContentType{Debian, DebianSecurityTracker},
|
|
},
|
|
{
|
|
family: constant.Ubuntu,
|
|
want: []CveContentType{Ubuntu, UbuntuAPI},
|
|
},
|
|
{
|
|
family: constant.FreeBSD,
|
|
want: nil,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.family, func(t *testing.T) {
|
|
if got := GetCveContentTypes(tt.family); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("GetCveContentTypes() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCveContentTypes_Except(t *testing.T) {
|
|
type args struct {
|
|
excepts []CveContentType
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
c CveContentTypes
|
|
args args
|
|
wantExcepted CveContentTypes
|
|
}{
|
|
{
|
|
name: "happy",
|
|
c: CveContentTypes{Ubuntu, UbuntuAPI},
|
|
args: args{
|
|
excepts: []CveContentType{Ubuntu},
|
|
},
|
|
wantExcepted: CveContentTypes{UbuntuAPI},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if gotExcepted := tt.c.Except(tt.args.excepts...); !reflect.DeepEqual(gotExcepted, tt.wantExcepted) {
|
|
t.Errorf("CveContentTypes.Except() = %v, want %v", gotExcepted, tt.wantExcepted)
|
|
}
|
|
})
|
|
}
|
|
}
|