github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/rekor/client_test.go (about)

     1  package rekor_test
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/devseccon/trivy/pkg/rekor"
    13  )
    14  
    15  func TestClient_Search(t *testing.T) {
    16  	type args struct {
    17  		hash string
    18  	}
    19  	tests := []struct {
    20  		name             string
    21  		mockResponseFile string
    22  		args             args
    23  		want             []rekor.EntryID
    24  		wantErr          string
    25  	}{
    26  		{
    27  			name:             "happy path",
    28  			mockResponseFile: "testdata/search-response.json",
    29  			args: args{
    30  				hash: "92251458088c638061cda8fd8b403b76d661a4dc6b7ee71b6affcf1872557b2b",
    31  			},
    32  			want: []rekor.EntryID{
    33  				{
    34  					TreeID: "392f8ecba72f4326",
    35  					UUID:   "eb624a7403756250b5f2ad58842a99d1653cd6f147f4ce9eda2da350bd908a55",
    36  				},
    37  				{
    38  					TreeID: "392f8ecba72f4326",
    39  					UUID:   "414eaca77bd19bf5f378725d7fd79309605a81b69cc0101f5cd3119d0a216523",
    40  				},
    41  				{
    42  					TreeID: "",
    43  					UUID:   "414eaca77bd19bf5f378725d7fd79309605a81b69cc0101f5cd3119d0a012345",
    44  				},
    45  			},
    46  		},
    47  		{
    48  			name:             "invalid UUID",
    49  			mockResponseFile: "testdata/search-invalid-response.json",
    50  			args: args{
    51  				hash: "92251458088c638061cda8fd8b403b76d661a4dc6b7ee71b6affcf1872557b2b",
    52  			},
    53  			wantErr: "invalid entry UUID",
    54  		},
    55  	}
    56  	for _, tt := range tests {
    57  		t.Run(tt.name, func(t *testing.T) {
    58  			ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    59  				http.ServeFile(w, r, tt.mockResponseFile)
    60  				return
    61  			}))
    62  			defer ts.Close()
    63  
    64  			c, err := rekor.NewClient(ts.URL)
    65  			require.NoError(t, err)
    66  
    67  			got, err := c.Search(context.Background(), tt.args.hash)
    68  			if tt.wantErr != "" {
    69  				assert.ErrorContains(t, err, tt.wantErr)
    70  				return
    71  			}
    72  			assert.NoError(t, err)
    73  			assert.Equal(t, tt.want, got)
    74  		})
    75  	}
    76  }
    77  
    78  func TestClient_GetEntries(t *testing.T) {
    79  	type args struct {
    80  		uuids []rekor.EntryID
    81  	}
    82  	tests := []struct {
    83  		name             string
    84  		mockResponseFile string
    85  		args             args
    86  		want             []rekor.Entry
    87  		wantErr          error
    88  	}{
    89  		{
    90  			name:             "happy path",
    91  			mockResponseFile: "testdata/log-entries.json",
    92  			args: args{
    93  				uuids: []rekor.EntryID{
    94  					{
    95  						TreeID: "392f8ecba72f4326",
    96  						UUID:   "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b1e",
    97  					},
    98  					{
    99  						TreeID: "392f8ecba72f4326",
   100  						UUID:   "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a741a2f",
   101  					},
   102  				},
   103  			},
   104  			want: []rekor.Entry{
   105  				{
   106  					Statement: []byte(`{"_type":"https://in-toto.io/Statement/v0.1","predicateType":"cosign.sigstore.dev/attestation/v1","subject":[{"name":"ghcr.io/devseccon/trivy-test-images","digest":{"sha256":"20d3f693dcffa44d6b24eae88783324d25cc132c22089f70e4fbfb858625b062"}}],"predicate":{"Data":"\"foo\\n\"\n","Timestamp":"2022-08-26T01:17:17Z"}}`),
   107  				},
   108  				{
   109  					Statement: []byte(`{"_type":"https://in-toto.io/Statement/v0.1","predicateType":"cosign.sigstore.dev/attestation/v1","subject":[{"name":"ghcr.io/devseccon/trivy-test-images","digest":{"sha256":"20d3f693dcffa44d6b24eae88783324d25cc132c22089f70e4fbfb858625b062"}}],"predicate":{"Data":"\"bar\\n\"\n","Timestamp":"2022-08-26T01:17:17Z"}}`),
   110  				},
   111  			},
   112  		},
   113  		{
   114  			name:             "no attestation",
   115  			mockResponseFile: "testdata/log-entries-no-attestation.json",
   116  			args: args{
   117  				uuids: []rekor.EntryID{
   118  					{
   119  						TreeID: "392f8ecba72f4326",
   120  						UUID:   "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b1e",
   121  					},
   122  				},
   123  			},
   124  			want: []rekor.Entry{},
   125  		},
   126  		{
   127  			name: "over get entries limit",
   128  			args: args{
   129  				uuids: []rekor.EntryID{
   130  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b10"},
   131  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b11"},
   132  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b12"},
   133  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b13"},
   134  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b14"},
   135  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b15"},
   136  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b16"},
   137  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b17"},
   138  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b18"},
   139  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b19"},
   140  					{TreeID: "392f8ecba72f4326", UUID: "8b5b2debb565fd5cb05ae0d3935351fa3faabce558bede72e197b5722a742b1a"},
   141  				},
   142  			},
   143  			want:    []rekor.Entry{},
   144  			wantErr: rekor.ErrOverGetEntriesLimit,
   145  		},
   146  	}
   147  
   148  	for _, tt := range tests {
   149  		t.Run(tt.name, func(t *testing.T) {
   150  			ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   151  				http.ServeFile(w, r, tt.mockResponseFile)
   152  				return
   153  			}))
   154  			defer ts.Close()
   155  
   156  			client, err := rekor.NewClient(ts.URL)
   157  			require.NoError(t, err)
   158  
   159  			got, err := client.GetEntries(context.Background(), tt.args.uuids)
   160  			require.Equal(t, tt.wantErr, err)
   161  			require.Equal(t, tt.want, got)
   162  		})
   163  	}
   164  }