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