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  }