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