github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/gosbom/pkg/cataloger/java/graalvm_native_image_cataloger_test.go (about)

     1  package java
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"compress/gzip"
     7  	"encoding/binary"
     8  	"io"
     9  	"os"
    10  	"path"
    11  	"testing"
    12  
    13  	"github.com/nextlinux/gosbom/gosbom/cpe"
    14  	"github.com/nextlinux/gosbom/gosbom/pkg"
    15  	"github.com/nextlinux/gosbom/gosbom/pkg/cataloger/internal/unionreader"
    16  	"github.com/stretchr/testify/assert"
    17  )
    18  
    19  func TestParseNativeImage(t *testing.T) {
    20  	tests := []struct {
    21  		fixture string
    22  		newFn   func(filename string, r io.ReaderAt) (nativeImage, error)
    23  	}{
    24  		{
    25  			fixture: "example-java-app",
    26  			newFn:   newElf,
    27  		},
    28  		{
    29  			fixture: "gcc-amd64-darwin-exec-debug",
    30  			newFn:   newMachO,
    31  		},
    32  	}
    33  	for _, test := range tests {
    34  		t.Run(test.fixture, func(t *testing.T) {
    35  			f, err := os.Open("test-fixtures/java-builds/packages/" + test.fixture)
    36  			assert.NoError(t, err)
    37  			readerCloser := io.NopCloser(f)
    38  			reader, err := unionreader.GetUnionReader(readerCloser)
    39  			assert.NoError(t, err)
    40  			parsed := false
    41  			readers, err := unionreader.GetReaders(reader)
    42  			for _, r := range readers {
    43  				ni, err := test.newFn(test.fixture, r)
    44  				assert.NoError(t, err)
    45  				_, err = ni.fetchPkgs()
    46  				if err == nil {
    47  					t.Fatalf("should have failed to extract SBOM.")
    48  				}
    49  				// If we can enumerate the symbols in the binary, we can parse the binary.
    50  				if err.Error() == nativeImageMissingSymbolsError {
    51  					parsed = true
    52  				}
    53  			}
    54  			if !parsed {
    55  				t.Fatalf("Could not parse the Native Image executable: %v", test.fixture)
    56  			}
    57  		})
    58  	}
    59  }
    60  
    61  func TestParseNativeImageSbom(t *testing.T) {
    62  	tests := []struct {
    63  		fixture  string
    64  		expected []pkg.Package
    65  	}{
    66  		{
    67  			fixture: "test-fixtures/graalvm-sbom/micronaut.json",
    68  			expected: []pkg.Package{
    69  				{
    70  					Name:         "netty-codec-http2",
    71  					Version:      "4.1.73.Final",
    72  					Language:     pkg.Java,
    73  					Type:         pkg.GraalVMNativeImagePkg,
    74  					MetadataType: pkg.JavaMetadataType,
    75  					FoundBy:      nativeImageCatalogerName,
    76  					Metadata: pkg.JavaMetadata{
    77  						PomProperties: &pkg.PomProperties{
    78  							GroupID: "io.netty",
    79  						},
    80  					},
    81  					CPEs: []cpe.CPE{
    82  						{
    83  							Part:    "a",
    84  							Vendor:  "codec",
    85  							Product: "codec",
    86  							Version: "4.1.73.Final",
    87  						},
    88  						{
    89  							Part:    "a",
    90  							Vendor:  "codec",
    91  							Product: "netty-codec-http2",
    92  							Version: "4.1.73.Final",
    93  						},
    94  						{
    95  							Part:    "a",
    96  							Vendor:  "codec",
    97  							Product: "netty_codec_http2",
    98  							Version: "4.1.73.Final",
    99  						},
   100  					},
   101  				},
   102  			},
   103  		},
   104  	}
   105  	for _, test := range tests {
   106  		t.Run(path.Base(test.fixture), func(t *testing.T) {
   107  			// Create a buffer to resemble a compressed SBOM in a native image.
   108  			sbom, err := os.ReadFile(test.fixture)
   109  			assert.NoError(t, err)
   110  			var b bytes.Buffer
   111  			writebytes := bufio.NewWriter(&b)
   112  			z := gzip.NewWriter(writebytes)
   113  			_, err = z.Write(sbom)
   114  			assert.NoError(t, err)
   115  			_ = z.Close()
   116  			_ = writebytes.Flush()
   117  			compressedsbom := b.Bytes()
   118  			sbomlength := uint64(len(compressedsbom))
   119  			_ = binary.Write(writebytes, binary.LittleEndian, sbomlength)
   120  			_ = writebytes.Flush()
   121  			compressedsbom = b.Bytes()
   122  			actual, err := decompressSbom(compressedsbom, 0, sbomlength)
   123  			assert.NoError(t, err)
   124  			assert.Equal(t, test.expected, actual)
   125  		})
   126  	}
   127  }