1 package v01
2
3 import (
4 "encoding/json"
5 "testing"
6 "time"
7
8 "github.com/google/go-cmp/cmp"
9 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common"
10 "github.com/stretchr/testify/assert"
11 )
12
13 func TestDecodeProvenancePredicate(t *testing.T) {
14
15
16 var data = `
17 {
18 "builder": { "id": "https://github.com/Attestations/GitHubHostedActions@v1" },
19 "recipe": {
20 "type": "https://github.com/Attestations/GitHubActionsWorkflow@v1",
21 "definedInMaterial": 0,
22 "entryPoint": "build.yaml:maketgz"
23 },
24 "metadata": {
25 "buildStartedOn": "2020-08-19T08:38:00Z",
26 "completeness": {
27 "environment": true
28 }
29 },
30 "materials": [
31 {
32 "uri": "git+https://github.com/curl/curl-docker@master",
33 "digest": { "sha1": "d6525c840a62b398424a78d792f457477135d0cf" }
34 }, {
35 "uri": "github_hosted_vm:ubuntu-18.04:20210123.1"
36 }
37 ]
38 }
39 `
40 var testTime = time.Unix(1597826280, 0)
41 var want = ProvenancePredicate{
42 Builder: common.ProvenanceBuilder{
43 ID: "https://github.com/Attestations/GitHubHostedActions@v1",
44 },
45 Recipe: ProvenanceRecipe{
46 Type: "https://github.com/Attestations/GitHubActionsWorkflow@v1",
47 DefinedInMaterial: new(int),
48 EntryPoint: "build.yaml:maketgz",
49 },
50 Metadata: &ProvenanceMetadata{
51 BuildStartedOn: &testTime,
52 Completeness: ProvenanceComplete{
53 Environment: true,
54 },
55 },
56 Materials: []common.ProvenanceMaterial{
57 {
58 URI: "git+https://github.com/curl/curl-docker@master",
59 Digest: common.DigestSet{
60 "sha1": "d6525c840a62b398424a78d792f457477135d0cf",
61 },
62 },
63 {
64 URI: "github_hosted_vm:ubuntu-18.04:20210123.1",
65 },
66 },
67 }
68 var got ProvenancePredicate
69
70 if err := json.Unmarshal([]byte(data), &got); err != nil {
71 t.Errorf("failed to unmarshal json: %s\n", err)
72 return
73 }
74
75
76
77 loc := want.Metadata.BuildStartedOn.Location()
78 tmp := got.Metadata.BuildStartedOn.In(loc)
79 got.Metadata.BuildStartedOn = &tmp
80
81 assert.Equal(t, want, got, "Unexpected object after decoding")
82 }
83
84 func TestEncodeProvenancePredicate(t *testing.T) {
85 var testTime = time.Unix(1597826280, 0).In(time.UTC)
86 var p = ProvenancePredicate{
87 Builder: common.ProvenanceBuilder{
88 ID: "https://github.com/Attestations/GitHubHostedActions@v1",
89 },
90 Recipe: ProvenanceRecipe{
91 Type: "https://github.com/Attestations/GitHubActionsWorkflow@v1",
92 DefinedInMaterial: new(int),
93 EntryPoint: "build.yaml:maketgz",
94 },
95 Metadata: &ProvenanceMetadata{
96 BuildStartedOn: &testTime,
97 BuildFinishedOn: &testTime,
98 Completeness: ProvenanceComplete{
99 Arguments: true,
100 Environment: false,
101 Materials: true,
102 },
103 },
104 Materials: []common.ProvenanceMaterial{
105 {
106 URI: "git+https://github.com/curl/curl-docker@master",
107 Digest: common.DigestSet{
108 "sha1": "d6525c840a62b398424a78d792f457477135d0cf",
109 },
110 },
111 {
112 URI: "github_hosted_vm:ubuntu-18.04:20210123.1",
113 },
114 {
115 URI: "git+https://github.com/curl/",
116 },
117 },
118 }
119 var want = `{"builder":{"id":"https://github.com/Attestations/GitHubHostedActions@v1"},"recipe":{"type":"https://github.com/Attestations/GitHubActionsWorkflow@v1","definedInMaterial":0,"entryPoint":"build.yaml:maketgz"},"metadata":{"buildStartedOn":"2020-08-19T08:38:00Z","buildFinishedOn":"2020-08-19T08:38:00Z","completeness":{"arguments":true,"environment":false,"materials":true},"reproducible":false},"materials":[{"uri":"git+https://github.com/curl/curl-docker@master","digest":{"sha1":"d6525c840a62b398424a78d792f457477135d0cf"}},{"uri":"github_hosted_vm:ubuntu-18.04:20210123.1"},{"uri":"git+https://github.com/curl/"}]}`
120 b, err := json.Marshal(&p)
121 assert.Nil(t, err, "Error during JSON marshal")
122 if d := cmp.Diff(want, string(b)); d != "" {
123 t.Fatal(d)
124 }
125 assert.Equal(t, want, string(b), "Wrong JSON produced")
126 }
127
128
129
130 func TestMetadataNoTime(t *testing.T) {
131 var md = ProvenanceMetadata{
132 Completeness: ProvenanceComplete{
133 Arguments: true,
134 },
135 Reproducible: true,
136 }
137 var want = `{"completeness":{"arguments":true,"environment":false,"materials":false},"reproducible":true}`
138 var got ProvenanceMetadata
139 b, err := json.Marshal(&md)
140
141 t.Run("Marshal", func(t *testing.T) {
142 assert.Nil(t, err, "Error during JSON marshal")
143 assert.Equal(t, want, string(b), "Wrong JSON produced")
144 })
145
146 t.Run("Unmashal", func(t *testing.T) {
147 err := json.Unmarshal(b, &got)
148 assert.Nil(t, err, "Error during JSON unmarshal")
149 assert.Equal(t, md, got, "Wrong struct after JSON unmarshal")
150 })
151 }
152
153
154
155 func TestRecipe(t *testing.T) {
156 var r = ProvenanceRecipe{
157 Type: "testType",
158 EntryPoint: "testEntry",
159 }
160 var want = `{"type":"testType","entryPoint":"testEntry"}`
161 var got ProvenanceRecipe
162 b, err := json.Marshal(&r)
163
164 t.Run("No time/marshal", func(t *testing.T) {
165 assert.Nil(t, err, "Error during JSON marshal")
166 assert.Equal(t, want, string(b), "Wrong JSON produced")
167 })
168
169 t.Run("No time/unmarshal", func(t *testing.T) {
170 err = json.Unmarshal(b, &got)
171 assert.Nil(t, err, "Error during JSON unmarshal")
172 assert.Equal(t, r, got, "Wrong struct after JSON unmarshal")
173 })
174
175
176 r.DefinedInMaterial = new(int)
177 want = `{"type":"testType","definedInMaterial":0,"entryPoint":"testEntry"}`
178 b, err = json.Marshal(&r)
179
180 t.Run("With time/marshal", func(t *testing.T) {
181 assert.Nil(t, err, "Error during JSON marshal")
182 assert.Equal(t, want, string(b), "Wrong JSON produced")
183 })
184
185 t.Run("With time/unmarshal", func(t *testing.T) {
186 err = json.Unmarshal(b, &got)
187 assert.Nil(t, err, "Error during JSON unmarshal")
188 assert.Equal(t, r, got, "Wrong struct after JSON unmarshal")
189 })
190 }
191
View as plain text