github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/test/cli/json_schema_test.go (about)

     1  package cli
     2  
     3  import (
     4  	"fmt"
     5  	"path"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/xeipuuv/gojsonschema"
    10  
    11  	"github.com/anchore/stereoscope/pkg/imagetest"
    12  	"github.com/lineaje-labs/syft/internal"
    13  )
    14  
    15  // this is the path to the json schema directory relative to the root of the repo
    16  const jsonSchemaPath = "schema/json"
    17  
    18  func TestJSONSchema(t *testing.T) {
    19  
    20  	imageFixture := func(t *testing.T) string {
    21  		fixtureImageName := "image-pkg-coverage"
    22  		imagetest.GetFixtureImage(t, "docker-archive", fixtureImageName)
    23  		tarPath := imagetest.GetFixtureImageTarPath(t, fixtureImageName)
    24  		return "docker-archive:" + tarPath
    25  	}
    26  
    27  	tests := []struct {
    28  		name       string
    29  		subcommand string
    30  		args       []string
    31  		fixture    func(*testing.T) string
    32  	}{
    33  		{
    34  			name:       "packages:image:docker-archive:pkg-coverage",
    35  			subcommand: "packages",
    36  			args:       []string{"-o", "json"},
    37  			fixture:    imageFixture,
    38  		},
    39  		{
    40  			name:       "packages:dir:pkg-coverage",
    41  			subcommand: "packages",
    42  			args:       []string{"-o", "json"},
    43  			fixture: func(t *testing.T) string {
    44  				return "dir:test-fixtures/image-pkg-coverage"
    45  			},
    46  		},
    47  	}
    48  
    49  	for _, test := range tests {
    50  		t.Run(test.name, func(t *testing.T) {
    51  			fixtureRef := test.fixture(t)
    52  			args := []string{
    53  				test.subcommand, fixtureRef, "-q",
    54  			}
    55  			args = append(args, test.args...)
    56  
    57  			_, stdout, stderr := runSyft(t, nil, args...)
    58  
    59  			if len(strings.Trim(stdout, "\n ")) < 100 {
    60  				t.Fatalf("bad syft run:\noutput: %q\n:error: %q", stdout, stderr)
    61  			}
    62  
    63  			validateJsonAgainstSchema(t, stdout)
    64  		})
    65  	}
    66  }
    67  
    68  func validateJsonAgainstSchema(t testing.TB, json string) {
    69  	t.Helper()
    70  	fullSchemaPath := path.Join(repoRoot(t), jsonSchemaPath, fmt.Sprintf("schema-%s.json", internal.JSONSchemaVersion))
    71  	schemaLoader := gojsonschema.NewReferenceLoader(fmt.Sprintf("file://%s", fullSchemaPath))
    72  	documentLoader := gojsonschema.NewStringLoader(json)
    73  
    74  	result, err := gojsonschema.Validate(schemaLoader, documentLoader)
    75  	if err != nil {
    76  		t.Fatal("unable to validate json schema:", err.Error())
    77  	}
    78  
    79  	if !result.Valid() {
    80  		t.Errorf("failed json schema validation:")
    81  		t.Errorf("JSON:\n%s\n", json)
    82  		for _, desc := range result.Errors() {
    83  			t.Errorf("  - %s\n", desc)
    84  		}
    85  	}
    86  }