github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/analyzer/config_analyzer_test.go (about) 1 package analyzer_test 2 3 import ( 4 "context" 5 "errors" 6 "os" 7 "testing" 8 9 v1 "github.com/google/go-containerregistry/pkg/v1" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 13 "github.com/devseccon/trivy/pkg/fanal/analyzer" 14 "github.com/devseccon/trivy/pkg/fanal/types" 15 ) 16 17 type mockConfigAnalyzer struct{} 18 19 func newMockConfigAnalyzer(_ analyzer.ConfigAnalyzerOptions) (analyzer.ConfigAnalyzer, error) { 20 return mockConfigAnalyzer{}, nil 21 } 22 23 func (mockConfigAnalyzer) Required(targetOS types.OS) bool { 24 return targetOS.Family == "alpine" 25 } 26 27 func (mockConfigAnalyzer) Analyze(_ context.Context, input analyzer.ConfigAnalysisInput) (*analyzer.ConfigAnalysisResult, error) { 28 if input.Config == nil { 29 return nil, errors.New("error") 30 } 31 return &analyzer.ConfigAnalysisResult{ 32 HistoryPackages: types.Packages{ 33 { 34 Name: "musl", 35 Version: "1.1.24-r2", 36 }, 37 }, 38 }, nil 39 } 40 41 func (mockConfigAnalyzer) Type() analyzer.Type { 42 return analyzer.Type("test") 43 } 44 45 func (mockConfigAnalyzer) Version() int { 46 return 1 47 } 48 49 func TestMain(m *testing.M) { 50 mock := mockConfigAnalyzer{} 51 analyzer.RegisterConfigAnalyzer(mock.Type(), newMockConfigAnalyzer) 52 defer analyzer.DeregisterConfigAnalyzer(mock.Type()) 53 os.Exit(m.Run()) 54 } 55 56 func TestAnalyzeConfig(t *testing.T) { 57 type args struct { 58 targetOS types.OS 59 config *v1.ConfigFile 60 disabledAnalyzers []analyzer.Type 61 filePatterns []string 62 } 63 tests := []struct { 64 name string 65 args args 66 want *analyzer.ConfigAnalysisResult 67 }{ 68 { 69 name: "happy path", 70 args: args{ 71 targetOS: types.OS{ 72 Family: "alpine", 73 Name: "3.11.6", 74 }, 75 config: &v1.ConfigFile{ 76 OS: "linux", 77 }, 78 }, 79 want: &analyzer.ConfigAnalysisResult{ 80 HistoryPackages: []types.Package{ 81 { 82 Name: "musl", 83 Version: "1.1.24-r2", 84 }, 85 }, 86 }, 87 }, 88 { 89 name: "non-target OS", 90 args: args{ 91 targetOS: types.OS{ 92 Family: "debian", 93 Name: "9.2", 94 }, 95 config: &v1.ConfigFile{ 96 OS: "linux", 97 }, 98 }, 99 want: &analyzer.ConfigAnalysisResult{}, 100 }, 101 { 102 name: "Analyze returns an error", 103 args: args{ 104 targetOS: types.OS{ 105 Family: "alpine", 106 Name: "3.11.6", 107 }, 108 }, 109 want: &analyzer.ConfigAnalysisResult{}, 110 }, 111 } 112 for _, tt := range tests { 113 t.Run(tt.name, func(t *testing.T) { 114 a, err := analyzer.NewConfigAnalyzerGroup(analyzer.ConfigAnalyzerOptions{ 115 FilePatterns: tt.args.filePatterns, 116 DisabledAnalyzers: tt.args.disabledAnalyzers, 117 }) 118 require.NoError(t, err) 119 got := a.AnalyzeImageConfig(context.Background(), tt.args.targetOS, tt.args.config) 120 assert.Equal(t, tt.want, got) 121 }) 122 } 123 } 124 125 func TestConfigAnalyzerGroup_AnalyzerVersions(t *testing.T) { 126 tests := []struct { 127 name string 128 disabled []analyzer.Type 129 want analyzer.Versions 130 }{ 131 { 132 name: "happy path", 133 disabled: []analyzer.Type{}, 134 want: analyzer.Versions{ 135 Analyzers: map[string]int{ 136 "apk-command": 1, 137 "test": 1, 138 }, 139 }, 140 }, 141 { 142 name: "disable analyzers", 143 disabled: []analyzer.Type{ 144 analyzer.TypeAlpine, 145 analyzer.TypeApkCommand, 146 }, 147 want: analyzer.Versions{ 148 Analyzers: map[string]int{ 149 "test": 1, 150 }, 151 }, 152 }, 153 } 154 for _, tt := range tests { 155 t.Run(tt.name, func(t *testing.T) { 156 a, err := analyzer.NewConfigAnalyzerGroup(analyzer.ConfigAnalyzerOptions{ 157 DisabledAnalyzers: tt.disabled, 158 }) 159 require.NoError(t, err) 160 got := a.AnalyzerVersions() 161 assert.Equal(t, tt.want, got) 162 }) 163 } 164 }