github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/pkg/cataloger/java/parse_java_manifest_test.go (about) 1 package java 2 3 import ( 4 "encoding/json" 5 "os" 6 "testing" 7 8 "github.com/go-test/deep" 9 "github.com/stretchr/testify/assert" 10 11 "github.com/anchore/syft/syft/pkg" 12 ) 13 14 func TestParseJavaManifest(t *testing.T) { 15 tests := []struct { 16 fixture string 17 expected pkg.JavaManifest 18 }{ 19 { 20 fixture: "test-fixtures/manifest/small", 21 expected: pkg.JavaManifest{ 22 Main: map[string]string{ 23 "Manifest-Version": "1.0", 24 }, 25 }, 26 }, 27 { 28 fixture: "test-fixtures/manifest/standard-info", 29 expected: pkg.JavaManifest{ 30 Main: map[string]string{ 31 "Name": "the-best-name", 32 "Manifest-Version": "1.0", 33 "Specification-Title": "the-spec-title", 34 "Specification-Version": "the-spec-version", 35 "Specification-Vendor": "the-spec-vendor", 36 "Implementation-Title": "the-impl-title", 37 "Implementation-Version": "the-impl-version", 38 "Implementation-Vendor": "the-impl-vendor", 39 }, 40 }, 41 }, 42 { 43 fixture: "test-fixtures/manifest/extra-info", 44 expected: pkg.JavaManifest{ 45 Main: map[string]string{ 46 "Manifest-Version": "1.0", 47 "Archiver-Version": "Plexus Archiver", 48 "Created-By": "Apache Maven 3.6.3", 49 }, 50 NamedSections: map[string]map[string]string{ 51 "thing-1": { 52 "Built-By": "?", 53 }, 54 "1": { 55 "Build-Jdk": "14.0.1", 56 "Main-Class": "hello.HelloWorld", 57 }, 58 }, 59 }, 60 }, 61 { 62 fixture: "test-fixtures/manifest/extra-empty-lines", 63 expected: pkg.JavaManifest{ 64 Main: map[string]string{ 65 "Manifest-Version": "1.0", 66 "Archiver-Version": "Plexus Archiver", 67 "Created-By": "Apache Maven 3.6.3", 68 }, 69 NamedSections: map[string]map[string]string{ 70 "thing-1": { 71 "Built-By": "?", 72 }, 73 "thing-2": { 74 "Built-By": "someone!", 75 }, 76 "2": { 77 "Other": "things", 78 }, 79 "3": { 80 "Last": "item", 81 }, 82 }, 83 }, 84 }, 85 { 86 fixture: "test-fixtures/manifest/continuation", 87 expected: pkg.JavaManifest{ 88 Main: map[string]string{ 89 "Manifest-Version": "1.0", 90 "Plugin-ScmUrl": "https://github.com/jenkinsci/plugin-pom/example-jenkins-plugin", 91 }, 92 }, 93 }, 94 { 95 // regression test, we should always keep the full version 96 fixture: "test-fixtures/manifest/version-with-date", 97 expected: pkg.JavaManifest{ 98 Main: map[string]string{ 99 "Manifest-Version": "1.0", 100 "Implementation-Version": "1.3 2244 October 5 2005", 101 }, 102 }, 103 }, 104 } 105 106 for _, test := range tests { 107 t.Run(test.fixture, func(t *testing.T) { 108 fixture, err := os.Open(test.fixture) 109 if err != nil { 110 t.Fatalf("could not open fixture: %+v", err) 111 } 112 113 actual, err := parseJavaManifest(test.fixture, fixture) 114 if err != nil { 115 t.Fatalf("failed to parse manifest: %+v", err) 116 } 117 118 diffs := deep.Equal(actual, &test.expected) 119 if len(diffs) > 0 { 120 for _, d := range diffs { 121 t.Errorf("diff: %+v", d) 122 } 123 124 b, err := json.MarshalIndent(actual, "", " ") 125 if err != nil { 126 t.Fatalf("can't show results: %+v", err) 127 } 128 129 t.Errorf("full result: %s", string(b)) 130 } 131 }) 132 } 133 } 134 135 func TestSelectName(t *testing.T) { 136 tests := []struct { 137 desc string 138 manifest pkg.JavaManifest 139 archive archiveFilename 140 expected string 141 }{ 142 { 143 desc: "Get name from Implementation-Title", 144 archive: archiveFilename{}, 145 manifest: pkg.JavaManifest{ 146 Main: map[string]string{ 147 "Implementation-Title": "maven-wrapper", 148 }, 149 }, 150 expected: "maven-wrapper", 151 }, 152 { 153 desc: "Implementation-Title does not override name from filename", 154 manifest: pkg.JavaManifest{ 155 Main: map[string]string{ 156 "Name": "foo", 157 "Implementation-Title": "maven-wrapper", 158 }, 159 }, 160 archive: newJavaArchiveFilename("/something/omg.jar"), 161 expected: "omg", 162 }, 163 } 164 165 for _, test := range tests { 166 t.Run(test.desc, func(t *testing.T) { 167 result := selectName(&test.manifest, test.archive) 168 169 if result != test.expected { 170 t.Errorf("mismatch in names: '%s' != '%s'", result, test.expected) 171 } 172 }) 173 } 174 } 175 176 func TestSelectVersion(t *testing.T) { 177 tests := []struct { 178 name string 179 manifest pkg.JavaManifest 180 archive archiveFilename 181 expected string 182 }{ 183 { 184 name: "Get name from Implementation-Version", 185 archive: archiveFilename{}, 186 manifest: pkg.JavaManifest{ 187 Main: map[string]string{ 188 "Implementation-Version": "1.8.2", 189 }, 190 }, 191 expected: "1.8.2", 192 }, 193 { 194 name: "Implementation-Version takes precedence over Specification-Version", 195 manifest: pkg.JavaManifest{ 196 Main: map[string]string{ 197 "Implementation-Version": "1.8.2", 198 "Specification-Version": "1.0", 199 }, 200 }, 201 expected: "1.8.2", 202 }, 203 { 204 name: "Implementation-Version found outside the main section", 205 manifest: pkg.JavaManifest{ 206 Main: map[string]string{ 207 "Manifest-Version": "1.0", 208 "Ant-Version": "Apache Ant 1.8.2", 209 "Created-By": "1.5.0_22-b03 (Sun Microsystems Inc.)", 210 }, 211 NamedSections: map[string]map[string]string{ 212 "org/apache/tools/ant/taskdefs/optional/": { 213 "Implementation-Version": "1.8.2", 214 }, 215 }, 216 }, 217 expected: "1.8.2", 218 }, 219 { 220 name: "Implementation-Version takes precedence over Specification-Version in subsequent section", 221 manifest: pkg.JavaManifest{ 222 Main: map[string]string{ 223 "Manifest-Version": "1.0", 224 "Ant-Version": "Apache Ant 1.8.2", 225 "Created-By": "1.5.0_22-b03 (Sun Microsystems Inc.)", 226 "Specification-Version": "2.0", 227 }, 228 NamedSections: map[string]map[string]string{ 229 "org/apache/tools/ant/taskdefs/optional/": { 230 "Specification-Version": "1.8", 231 }, 232 "some-other-section": { 233 "Implementation-Version": "1.8.2", 234 }, 235 }, 236 }, 237 expected: "1.8.2", 238 }, 239 { 240 name: "Implementation-Version takes precedence over Specification-Version in subsequent section", 241 manifest: pkg.JavaManifest{ 242 Main: map[string]string{ 243 "Manifest-Version": "1.0", 244 "Ant-Version": "Apache Ant 1.8.2", 245 "Created-By": "1.5.0_22-b03 (Sun Microsystems Inc.)", 246 }, 247 NamedSections: map[string]map[string]string{ 248 "some-other-section": { 249 "Bundle-Version": "1.11.28", 250 }, 251 }, 252 }, 253 expected: "1.11.28", 254 }, 255 } 256 257 for _, test := range tests { 258 t.Run(test.name, func(t *testing.T) { 259 result := selectVersion(&test.manifest, test.archive) 260 261 assert.Equal(t, test.expected, result) 262 }) 263 } 264 }