github.com/yogeshkumararora/slsa-github-generator@v1.10.1-0.20240520161934-11278bd5afb4/slsa/provenance_test.go (about)

     1  // Copyright 2023 SLSA Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package slsa
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/google/go-cmp/cmp"
    23  	intoto "github.com/in-toto/in-toto-golang/in_toto"
    24  	slsacommon "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common"
    25  	slsa02 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2"
    26  	"github.com/yogeshkumararora/slsa-github-generator/github"
    27  )
    28  
    29  var (
    30  	testBuildType   = "http://example.com/v1"
    31  	testBuildConfig = "test build config"
    32  )
    33  
    34  type TestBuild struct {
    35  	*GithubActionsBuild
    36  }
    37  
    38  func (*TestBuild) URI() string {
    39  	return testBuildType
    40  }
    41  
    42  func (*TestBuild) BuildConfig(context.Context) (interface{}, error) {
    43  	return testBuildConfig, nil
    44  }
    45  
    46  func TestHostedActionsProvenance(t *testing.T) {
    47  	now := time.Date(2022, 4, 14, 12, 24, 0, 0, time.UTC)
    48  
    49  	testCases := []struct {
    50  		b        BuildType
    51  		token    *github.OIDCToken
    52  		expected *intoto.ProvenanceStatement
    53  		name     string
    54  	}{
    55  		{
    56  			name: "empty",
    57  			b: &TestBuild{
    58  				GithubActionsBuild: NewGithubActionsBuild(nil, &github.WorkflowContext{}).WithClients(&NilClientProvider{}),
    59  			},
    60  			token: &github.OIDCToken{
    61  				Audience: []string{""},
    62  				Expiry:   now.Add(1 * time.Hour),
    63  			},
    64  			expected: &intoto.ProvenanceStatement{
    65  				StatementHeader: intoto.StatementHeader{
    66  					Type:          intoto.StatementInTotoV01,
    67  					PredicateType: slsa02.PredicateSLSAProvenance,
    68  				},
    69  				Predicate: slsa02.ProvenancePredicate{
    70  					Builder: slsacommon.ProvenanceBuilder{
    71  						ID: GithubHostedActionsBuilderID,
    72  					},
    73  					BuildType:   testBuildType,
    74  					BuildConfig: testBuildConfig,
    75  					Invocation: slsa02.ProvenanceInvocation{
    76  						Environment: map[string]interface{}{
    77  							"github_run_id":           "",
    78  							"github_run_attempt":      "",
    79  							"github_actor":            "",
    80  							"github_base_ref":         "",
    81  							"github_event_name":       "",
    82  							"github_head_ref":         "",
    83  							"github_ref":              "",
    84  							"github_ref_type":         "",
    85  							"github_repository_owner": "",
    86  							"github_run_number":       "",
    87  							"github_sha1":             "",
    88  						},
    89  					},
    90  					Metadata: &slsa02.ProvenanceMetadata{},
    91  				},
    92  			},
    93  		},
    94  		{
    95  			name: "invocation env",
    96  			b: &TestBuild{
    97  				GithubActionsBuild: NewGithubActionsBuild(nil, &github.WorkflowContext{
    98  					RunID:      "12345",
    99  					RunAttempt: "1",
   100  					EventName:  "pull_request",
   101  					SHA:        "abcde",
   102  					RefType:    "branch",
   103  					Ref:        "some/ref",
   104  					BaseRef:    "some/base_ref",
   105  					HeadRef:    "some/head_ref",
   106  					RunNumber:  "102937",
   107  					Actor:      "user",
   108  				}).WithClients(&NilClientProvider{}),
   109  			},
   110  			token: &github.OIDCToken{
   111  				Audience: []string{"hoge"},
   112  				Expiry:   now.Add(1 * time.Hour),
   113  			},
   114  			expected: &intoto.ProvenanceStatement{
   115  				StatementHeader: intoto.StatementHeader{
   116  					Type:          intoto.StatementInTotoV01,
   117  					PredicateType: slsa02.PredicateSLSAProvenance,
   118  				},
   119  				Predicate: slsa02.ProvenancePredicate{
   120  					Builder: slsacommon.ProvenanceBuilder{
   121  						ID: GithubHostedActionsBuilderID,
   122  					},
   123  					BuildType:   testBuildType,
   124  					BuildConfig: testBuildConfig,
   125  					Invocation: slsa02.ProvenanceInvocation{
   126  						Environment: map[string]interface{}{
   127  							"github_run_id":           "12345",
   128  							"github_run_attempt":      "1",
   129  							"github_actor":            "user",
   130  							"github_base_ref":         "some/base_ref",
   131  							"github_event_name":       "pull_request",
   132  							"github_head_ref":         "some/head_ref",
   133  							"github_ref":              "some/ref",
   134  							"github_ref_type":         "branch",
   135  							"github_repository_owner": "",
   136  							"github_run_number":       "102937",
   137  							"github_sha1":             "abcde",
   138  						},
   139  						ConfigSource: slsa02.ConfigSource{
   140  							Digest: slsacommon.DigestSet{
   141  								"sha1": "abcde",
   142  							},
   143  						},
   144  					},
   145  					Metadata: &slsa02.ProvenanceMetadata{
   146  						BuildInvocationID: "12345-1",
   147  					},
   148  				},
   149  			},
   150  		},
   151  	}
   152  
   153  	for _, tc := range testCases {
   154  		t.Run(tc.name, func(t *testing.T) {
   155  			g := NewHostedActionsGenerator(tc.b).WithClients(&NilClientProvider{})
   156  
   157  			if p, err := g.Generate(context.Background()); err != nil {
   158  				t.Fatalf("unexpected error: %v", err)
   159  			} else {
   160  				if want, got := tc.expected, p; !cmp.Equal(want, got) {
   161  					t.Errorf("unexpected result\nwant: %#v\ngot:  %#v\ndiff: %v", want, got, cmp.Diff(want, got))
   162  				}
   163  			}
   164  		})
   165  	}
   166  }