Skip to content

Commit

Permalink
Add basic Golang tests for Statement layer
Browse files Browse the repository at this point in the history
Signed-off-by: Marcela Melara <[email protected]>
  • Loading branch information
marcelamelara committed May 9, 2023
1 parent 12dd21a commit 4cda93e
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 43 deletions.
48 changes: 5 additions & 43 deletions examples/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,15 @@ func createStatementPbFromJson(subName string, subSha256 string, predicateType s
if err != nil {
return nil, fmt.Errorf("failed to unmarshal predicate: %w", err)
}
return createStatementPb(subName, subSha256, predicateType, pred), nil
return createStatementPb(subName, subSha256, predicateType, pred)
}

func createStatementPb(subName string, subSha256 string, predicateType string, predicate *structpb.Struct) *spb.Statement {
sub := []*spb.Statement_Subject{{
func createStatementPb(subName string, subSha256 string, predicateType string, predicate *structpb.Struct) (*spb.Statement, error) {
sub := []*spb.ResourceDescriptor{{
Name: subName,
Digest: map[string]string{"sha256": strings.ToLower(subSha256)},
}}
statement := &spb.Statement{
Type: "https://in-toto.io/Statement/v1",
Subject: sub,
PredicateType: predicateType,
Predicate: predicate,
}
return statement
return spb.NewStatementPb(sub, predicateType, predicate)
}

func createVsa(subName string, subSha256 string, vsaBody *vpb.VerificationSummary) (*spb.Statement, error) {
Expand All @@ -45,32 +39,7 @@ func createVsa(subName string, subSha256 string, vsaBody *vpb.VerificationSummar
if err != nil {
return nil, err
}
return createStatementPb(subName, subSha256, "https://slsa.dev/verification_summary/v0.2", vsaStruct), nil
}

func createTestResourceDescriptor() (*spb.ResourceDescriptor, error) {
// Create a ResourceDescriptor
a1, err := structpb.NewStruct(map[string]interface{}{
"keyStr": "value1",
"keyNum": 13})
if err != nil {
return nil, err
}
a2, err := structpb.NewStruct(map[string]interface{}{
"keyObj": map[string]interface{}{
"subKey": "subVal"}})
if err != nil {
return nil, err
}
r := &spb.ResourceDescriptor{
Name: "theName",
Uri: "http://example.com",
Digest: map[string]string{"sha256": "abc123"},
Content: []byte("bytescontent"),
DownloadLocation: "http://example.com/test.zip",
MediaType: "theMediaType",
Annotations: map[string]*structpb.Struct{"a1": a1, "a2": a2}}
return r, nil
return createStatementPb(subName, subSha256, "https://slsa.dev/verification_summary/v0.2", vsaStruct)
}

// Example of how to use protobuf to create in-toto statements.
Expand Down Expand Up @@ -131,11 +100,4 @@ func main() {
}
fmt.Printf("\nRead statement with predicateType %v\n", s.PredicateType)
fmt.Printf("Predicate %v\n", s.Predicate)

// Test ResourceDescriptor
r, err := createTestResourceDescriptor()
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nResourceDescriptor as json:\n%v\n", protojson.Format(r))
}
62 changes: 62 additions & 0 deletions go/v1/resource_descriptor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Tests for in-toto attestation ResourceDescriptor protos.
*/

package v1

import (
"testing"

"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/types/known/structpb"
"github.com/stretchr/testify/assert"
)

const wantFullRd = `{"name":"theName","uri":"https://example.com","digest":{"alg1":"abc123"},"content":"Ynl0ZXNjb250ZW50","downloadLocation":"https://example.com/test.zip","mediaType":"theMediaType","annotations":{"a1":{"keyNum": 13,"keyStr":"value1"},"a2":{"keyObj":{"subKey":"subVal"}}}}`

const badRd = `{"downloadLocation":"https://example.com/test.zip","mediaType":"theMediaType"}`

func createTestResourceDescriptor() (*ResourceDescriptor, error) {
// Create a ResourceDescriptor
a1, err := structpb.NewStruct(map[string]interface{}{
"keyStr": "value1",
"keyNum": 13})
if err != nil {
return nil, err
}
a2, err := structpb.NewStruct(map[string]interface{}{
"keyObj": map[string]interface{}{
"subKey": "subVal"}})
if err != nil {
return nil, err
}

return NewResourceDescriptorPb("theName", "https://example.com",
map[string]string{"alg1": "abc123"}, []byte("bytescontent"),
"https://example.com/test.zip", "theMediaType",
map[string]*structpb.Struct{"a1": a1, "a2": a2})
}

func TestJsonUnmarshalResourceDescriptor(t *testing.T) {
got := &ResourceDescriptor{}
err := protojson.Unmarshal([]byte(wantFullRd), got)

assert.Nil(t, err, "Error during JSON unmarshalling")

want, err := createTestResourceDescriptor()

assert.Nil(t, err, "Error during test RD creation")
assert.True(t, proto.Equal(got, want), "Protos do not match")
}

func TestBadResourceDescriptor(t *testing.T) {
got := &ResourceDescriptor{}
err := protojson.Unmarshal([]byte(badRd), got)

assert.Nil(t, err, "Error during JSON unmarshalling")

result := IsValidResourceDescriptor(got)

assert.False(t, result, "Error: created malformed ResourceDescriptor")
}
113 changes: 113 additions & 0 deletions go/v1/statement_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Tests for in-toto attestation ResourceDescriptor protos.
*/

package v1

import (
"testing"

"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/types/known/structpb"
"github.com/stretchr/testify/assert"
)

const wantSt = `{"_type":"https://in-toto.io/Statement/v1","subject":[{"name":"theSub","digest":{"alg1":"abc123"}}],"predicateType":"thePredicate","predicate":{"keyObj":{"subKey":"subVal"}}}`

func createTestStatement() (*Statement, error) {
// Create a Statement
sub, err := NewResourceDescriptorPb("theSub", "",
map[string]string{"alg1": "abc123"}, nil, "", "", nil)
if err != nil {
return nil, err
}

pred, err := structpb.NewStruct(map[string]interface{}{
"keyObj": map[string]interface{}{
"subKey": "subVal"}})
if err != nil {
return nil, err
}

return NewStatementPb([]*ResourceDescriptor{sub}, "thePredicate",
pred)
}

func TestJsonUnmarshalStatement(t *testing.T) {
got := &Statement{}
err := protojson.Unmarshal([]byte(wantSt), got)

assert.Nil(t, err, "Error during JSON unmarshalling")

want, err := createTestStatement()

assert.Nil(t, err, "Error during test Statement creation")
assert.True(t, proto.Equal(got, want), "Protos do not match")
}

func TestBadStatementType(t *testing.T) {
var badStType = `{"_type":"https://in-toto.io/Statement/v0","subject":[{"name":"theSub","digest":{"alg1":"abc123"}}],"predicateType":"thePredicate","predicate":{"keyObj":{"subKey":"subVal"}}}`

got := &Statement{}
err := protojson.Unmarshal([]byte(badStType), got)

assert.Nil(t, err, "Error during JSON unmarshalling")

result := IsValidStatement(got)

assert.False(t, result,
"Error: created malformed Statement (bad type)")
}

func TestBadStatementSubject(t *testing.T) {
var badStNoSub = `{"_type":"https://in-toto.io/Statement/v1","subject":[],"predicateType":"thePredicate","predicate":{"keyObj":{"subKey":"subVal"}}}`

got := &Statement{}
err := protojson.Unmarshal([]byte(badStNoSub), got)

assert.Nil(t, err, "Error during JSON unmarshalling")

result := IsValidStatement(got)

assert.False(t, result,
"Error: created malformed Statement (empty subject)")

var badStBadSub = `{"_type":"https://in-toto.io/Statement/v1","subject":[{"downloadLocation":"https://example.com/test.zip"}],"predicateType":"thePredicate","predicate":{"keyObj":{"subKey":"subVal"}}}`

got = &Statement{}
err = protojson.Unmarshal([]byte(badStBadSub), got)

assert.Nil(t, err, "Error during JSON unmarshalling")

result = IsValidStatement(got)

assert.False(t, result,
"Error: created malformed Statement (bad subject)")
}

func TestBadStatementPredicate(t *testing.T) {
var badStPredType = `{"_type":"https://in-toto.io/Statement/v1","subject":[{"name":"theSub","digest":{"alg1":"abc123"}}],"predicateType":"","predicate":{"keyObj":{"subKey":"subVal"}}}`

got := &Statement{}
err := protojson.Unmarshal([]byte(badStPredType), got)

assert.Nil(t, err, "Error during JSON unmarshalling")

result := IsValidStatement(got)

assert.False(t, result,
"Error: created malformed Statement (bad predicate type)")

var badStPred = `{"_type":"https://in-toto.io/Statement/v1","subject":[{"name":"theSub","digest":{"alg1":"abc123"}}],"predicateType":"thePredicate"}`

got = &Statement{}
err = protojson.Unmarshal([]byte(badStPred), got)

assert.Nil(t, err, "Error during JSON unmarshalling")

result = IsValidStatement(got)

assert.False(t, result,
"Error: created malformed Statement (no prdicate)")
}

0 comments on commit 4cda93e

Please sign in to comment.