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  }