github.com/anchore/syft@v1.38.2/syft/format/spdxjson/decoder_test.go (about)

     1  package spdxjson
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"path/filepath"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/anchore/syft/syft/pkg"
    14  	"github.com/anchore/syft/syft/sbom"
    15  )
    16  
    17  func TestDecoder_Decode(t *testing.T) {
    18  	tests := []struct {
    19  		name          string
    20  		fail          bool
    21  		id            sbom.FormatID
    22  		version       string
    23  		packages      []string
    24  		relationships []string
    25  	}{
    26  		{
    27  			name:          "alpine-3.10.syft.spdx.json",
    28  			id:            ID,
    29  			version:       "2.2",
    30  			packages:      []string{"busybox", "libssl1.1", "ssl_client"},
    31  			relationships: []string{"busybox", "busybox", "libssl1.1", "libssl1.1"},
    32  		},
    33  		{
    34  			name:          "alpine-3.10.vendor.spdx.json",
    35  			id:            ID,
    36  			version:       "2.2",
    37  			packages:      []string{"alpine", "busybox", "ssl_client"},
    38  			relationships: []string{},
    39  		},
    40  		{
    41  			name:    "example7-bin.spdx.json",
    42  			id:      ID,
    43  			version: "2.2",
    44  		},
    45  		{
    46  			name:    "example7-go-module.spdx.json",
    47  			id:      ID,
    48  			version: "2.2",
    49  		},
    50  		{
    51  			name:    "example7-golang.spdx.json",
    52  			id:      ID,
    53  			version: "2.2",
    54  		},
    55  		{
    56  			name:    "example7-third-party-modules.spdx.json",
    57  			id:      ID,
    58  			version: "2.2",
    59  		},
    60  		{
    61  			name:    "bad/example7-bin.spdx.json",
    62  			id:      ID,
    63  			version: "2.2",
    64  			fail:    true,
    65  		},
    66  		{
    67  			name:    "bad/example7-go-module.spdx.json",
    68  			id:      ID,
    69  			version: "2.2",
    70  			fail:    true,
    71  		},
    72  		{
    73  			name:    "bad/example7-golang.spdx.json",
    74  			id:      ID,
    75  			version: "2.2",
    76  			fail:    true,
    77  		},
    78  		{
    79  			name:    "bad/example7-third-party-modules.spdx.json",
    80  			id:      ID,
    81  			version: "2.2",
    82  			fail:    true,
    83  		},
    84  		{
    85  			name: "bad/bad-sbom",
    86  			fail: true,
    87  		},
    88  	}
    89  
    90  	for _, test := range tests {
    91  		t.Run(test.name, func(t *testing.T) {
    92  			reader, err := os.Open(filepath.Join("test-fixtures", "spdx", test.name))
    93  			require.NoError(t, err)
    94  
    95  			reset := func() { _, err = reader.Seek(0, io.SeekStart); require.NoError(t, err) }
    96  
    97  			dec := NewFormatDecoder()
    98  
    99  			formatID, formatVersion := dec.Identify(reader)
   100  			if test.fail {
   101  				assert.Equal(t, test.id, formatID)
   102  				assert.Equal(t, test.version, formatVersion)
   103  
   104  				reset()
   105  				_, decodeID, decodeVersion, err := dec.Decode(reader)
   106  				require.Error(t, err)
   107  				assert.Equal(t, test.id, decodeID)
   108  				assert.Equal(t, test.version, decodeVersion)
   109  
   110  				return
   111  			}
   112  			assert.Equal(t, test.id, formatID)
   113  			assert.Equal(t, test.version, formatVersion)
   114  
   115  			reset()
   116  			s, decodeID, decodeVersion, err := dec.Decode(reader)
   117  
   118  			require.NoError(t, err)
   119  			assert.Equal(t, test.id, decodeID)
   120  			assert.Equal(t, test.version, decodeVersion)
   121  
   122  			if test.packages != nil {
   123  				assert.Equal(t, s.Artifacts.Packages.PackageCount(), len(test.packages))
   124  
   125  			packages:
   126  				for _, pkgName := range test.packages {
   127  					for _, p := range s.Artifacts.Packages.Sorted() {
   128  						if p.Name == pkgName {
   129  							continue packages
   130  						}
   131  					}
   132  					assert.NoError(t, fmt.Errorf("Unable to find package: %s", pkgName))
   133  				}
   134  			}
   135  
   136  			if test.relationships != nil {
   137  				assert.Len(t, s.Relationships, len(test.relationships))
   138  
   139  			relationships:
   140  				for _, pkgName := range test.relationships {
   141  					for _, rel := range s.Relationships {
   142  						p, ok := rel.From.(pkg.Package)
   143  						if ok && p.Name == pkgName {
   144  							continue relationships
   145  						}
   146  					}
   147  					assert.NoError(t, fmt.Errorf("Unable to find relationship: %s", pkgName))
   148  				}
   149  			}
   150  		})
   151  	}
   152  }
   153  
   154  func TestDecoder_Identify(t *testing.T) {
   155  	type testCase struct {
   156  		name    string
   157  		file    string
   158  		id      sbom.FormatID
   159  		version string
   160  	}
   161  
   162  	var cases []testCase
   163  
   164  	for _, version := range SupportedVersions() {
   165  		cases = append(cases, testCase{
   166  			name:    fmt.Sprintf("v%s schema", version),
   167  			file:    fmt.Sprintf("test-fixtures/identify/%s.json", version),
   168  			id:      ID,
   169  			version: version,
   170  		})
   171  	}
   172  
   173  	for _, test := range cases {
   174  		t.Run(test.name, func(t *testing.T) {
   175  			reader, err := os.Open(test.file)
   176  			require.NoError(t, err)
   177  
   178  			dec := NewFormatDecoder()
   179  
   180  			formatID, formatVersion := dec.Identify(reader)
   181  			assert.Equal(t, test.id, formatID)
   182  			assert.Equal(t, test.version, formatVersion)
   183  		})
   184  	}
   185  }