preallocate bindings capacity in dockerhub and groq, with unit tests (#5213)
* preallocate bindings capacity in dockerhub and groq, with unit tests * ran linter
This commit is contained in:
@@ -133,7 +133,7 @@ func secretInfoToAnalyzerResult(info *SecretInfo) *analyzers.AnalyzerResult {
|
||||
result := analyzers.AnalyzerResult{
|
||||
AnalyzerType: analyzers.AnalyzerTypeDockerHub,
|
||||
Metadata: map[string]any{"Valid_Key": info.Valid},
|
||||
Bindings: make([]analyzers.Binding, len(info.Repositories)),
|
||||
Bindings: make([]analyzers.Binding, 0, len(info.Repositories)),
|
||||
}
|
||||
|
||||
// extract information to create bindings and append to result bindings
|
||||
|
||||
@@ -15,6 +15,90 @@ import (
|
||||
//go:embed result_output.json
|
||||
var expectedOutput []byte
|
||||
|
||||
func repo(name string) Repository {
|
||||
return Repository{
|
||||
ID: "user123/repo/image/" + name,
|
||||
Name: name,
|
||||
Type: "image",
|
||||
IsPrivate: true,
|
||||
StarCount: 1,
|
||||
PullCount: 2,
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecretInfoToAnalyzerResult(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
repos []Repository
|
||||
wantLen int
|
||||
wantNames []string
|
||||
}{
|
||||
{
|
||||
name: "one repository produces exactly one binding",
|
||||
repos: []Repository{repo("repo1")},
|
||||
wantLen: 1,
|
||||
wantNames: []string{"repo1"},
|
||||
},
|
||||
{
|
||||
name: "three repositories produce exactly three bindings, not six",
|
||||
repos: []Repository{repo("repo1"), repo("repo2"), repo("repo3")},
|
||||
wantLen: 3,
|
||||
wantNames: []string{"repo1", "repo2", "repo3"},
|
||||
},
|
||||
{
|
||||
name: "no repositories: no bindings",
|
||||
repos: nil,
|
||||
wantLen: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
info := &SecretInfo{
|
||||
Valid: true,
|
||||
User: User{ID: "uuid-123", Username: "user123", Email: "[email protected]"},
|
||||
Permissions: []string{"repo:admin"},
|
||||
Repositories: tt.repos,
|
||||
}
|
||||
|
||||
result := secretInfoToAnalyzerResult(info)
|
||||
if result == nil {
|
||||
t.Fatal("secretInfoToAnalyzerResult() returned nil")
|
||||
}
|
||||
|
||||
if len(result.Bindings) != tt.wantLen {
|
||||
t.Errorf("got %d bindings, want %d", len(result.Bindings), tt.wantLen)
|
||||
}
|
||||
|
||||
// Mirrors the four proto min_len constraints so this test fails for
|
||||
// the same reason the enterprise API does.
|
||||
for i, binding := range result.Bindings {
|
||||
if binding.Resource.Name == "" {
|
||||
t.Errorf("binding[%d].Resource.Name is empty", i)
|
||||
}
|
||||
if binding.Resource.Type == "" {
|
||||
t.Errorf("binding[%d].Resource.Type is empty", i)
|
||||
}
|
||||
if binding.Resource.FullyQualifiedName == "" {
|
||||
t.Errorf("binding[%d].Resource.FullyQualifiedName is empty", i)
|
||||
}
|
||||
if binding.Permission.Value == "" {
|
||||
t.Errorf("binding[%d].Permission.Value is empty", i)
|
||||
}
|
||||
}
|
||||
|
||||
for i, name := range tt.wantNames {
|
||||
if i >= len(result.Bindings) {
|
||||
break
|
||||
}
|
||||
if result.Bindings[i].Resource.Name != name {
|
||||
t.Errorf("binding[%d].Resource.Name = %q, want %q", i, result.Bindings[i].Resource.Name, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzer_Analyze(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5)
|
||||
defer cancel()
|
||||
|
||||
@@ -121,7 +121,7 @@ func secretInfoToAnalyzerResult(info *SecretInfo) *analyzers.AnalyzerResult {
|
||||
result := analyzers.AnalyzerResult{
|
||||
AnalyzerType: analyzers.AnalyzerTypeGroq,
|
||||
Metadata: map[string]any{"Valid_Key": info.Valid},
|
||||
Bindings: make([]analyzers.Binding, len(info.GroqResources)),
|
||||
Bindings: make([]analyzers.Binding, 0, len(info.GroqResources)),
|
||||
}
|
||||
|
||||
// extract information to create bindings and append to result bindings
|
||||
|
||||
@@ -12,6 +12,91 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||
)
|
||||
|
||||
func resource(id, name, resourceType string) GroqResource {
|
||||
return GroqResource{
|
||||
ID: id,
|
||||
Name: name,
|
||||
Type: resourceType,
|
||||
Permission: PermissionStrings[FullAccess],
|
||||
Metadata: map[string]string{"status": "completed"},
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecretInfoToAnalyzerResult(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
resources []GroqResource
|
||||
wantLen int
|
||||
wantNames []string
|
||||
}{
|
||||
{
|
||||
name: "one resource produces exactly one binding",
|
||||
resources: []GroqResource{resource("batch_123", "batch_123", "batch")},
|
||||
wantLen: 1,
|
||||
wantNames: []string{"batch_123"},
|
||||
},
|
||||
{
|
||||
name: "three resources produce exactly three bindings, not six",
|
||||
resources: []GroqResource{
|
||||
resource("batch_123", "batch_123", "batch"),
|
||||
resource("file_456", "training.jsonl", "file"),
|
||||
resource("file_789", "eval.jsonl", "file"),
|
||||
},
|
||||
wantLen: 3,
|
||||
wantNames: []string{"batch_123", "training.jsonl", "eval.jsonl"},
|
||||
},
|
||||
{
|
||||
name: "no resources: no bindings",
|
||||
resources: nil,
|
||||
wantLen: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
info := &SecretInfo{
|
||||
Valid: true,
|
||||
GroqResources: tt.resources,
|
||||
}
|
||||
|
||||
result := secretInfoToAnalyzerResult(info)
|
||||
if result == nil {
|
||||
t.Fatal("secretInfoToAnalyzerResult() returned nil")
|
||||
}
|
||||
|
||||
if len(result.Bindings) != tt.wantLen {
|
||||
t.Errorf("got %d bindings, want %d", len(result.Bindings), tt.wantLen)
|
||||
}
|
||||
|
||||
// Mirrors the four proto min_len constraints so this test fails for
|
||||
// the same reason the enterprise API does.
|
||||
for i, binding := range result.Bindings {
|
||||
if binding.Resource.Name == "" {
|
||||
t.Errorf("binding[%d].Resource.Name is empty", i)
|
||||
}
|
||||
if binding.Resource.Type == "" {
|
||||
t.Errorf("binding[%d].Resource.Type is empty", i)
|
||||
}
|
||||
if binding.Resource.FullyQualifiedName == "" {
|
||||
t.Errorf("binding[%d].Resource.FullyQualifiedName is empty", i)
|
||||
}
|
||||
if binding.Permission.Value == "" {
|
||||
t.Errorf("binding[%d].Permission.Value is empty", i)
|
||||
}
|
||||
}
|
||||
|
||||
for i, name := range tt.wantNames {
|
||||
if i >= len(result.Bindings) {
|
||||
break
|
||||
}
|
||||
if result.Bindings[i].Resource.Name != name {
|
||||
t.Errorf("binding[%d].Resource.Name = %q, want %q", i, result.Bindings[i].Resource.Name, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzer_Analyze(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5)
|
||||
defer cancel()
|
||||
|
||||
Reference in New Issue
Block a user