Skip to content

Commit

Permalink
Resolves #69: Make error when getting certificates more transparent f…
Browse files Browse the repository at this point in the history
…or user.

Signed-off-by: Fabian Kammel <[email protected]>
  • Loading branch information
datosh committed Aug 8, 2023
1 parent e982e5b commit 4b0fa13
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 2 deletions.
7 changes: 5 additions & 2 deletions verify/trust/trust.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/google/go-sev-guest/abi"
"github.com/google/go-sev-guest/kds"
"github.com/google/logger"
"go.uber.org/multierr"
)

var (
Expand Down Expand Up @@ -103,7 +104,7 @@ func (n *SimpleHTTPSGetter) Get(url string) ([]byte, error) {
if err != nil {
return nil, err
} else if resp.StatusCode >= 300 {
return nil, fmt.Errorf("failed to retrieve %s", url)
return nil, fmt.Errorf("failed to retrieve '%s' status %d", url, resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
Expand All @@ -128,20 +129,22 @@ type RetryHTTPSGetter struct {
func (n *RetryHTTPSGetter) Get(url string) ([]byte, error) {
delay := initialDelay
ctx, cancel := context.WithTimeout(context.Background(), n.Timeout)
var returnedError error
for {
body, err := n.Getter.Get(url)
if err == nil {
cancel()
return body, nil
}
returnedError = multierr.Append(returnedError, err)
delay = delay + delay
if delay > n.MaxRetryDelay {
delay = n.MaxRetryDelay
}
select {
case <-ctx.Done():
cancel()
return nil, fmt.Errorf("timeout") // context cancelled
return nil, multierr.Append(returnedError, fmt.Errorf("timeout")) // context cancelled
case <-time.After(delay): // wait to retry
}
}
Expand Down
93 changes: 93 additions & 0 deletions verify/trust/trust_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package trust

import (
"bytes"
"errors"
"testing"
"time"
)

// FakeHTTPSGetter is a test double for HTTPSGetter. It can hold a slice
// of body and error responses so Get can be called multiple times and return
// different values, as to simulate different scenarios.
type FakeHTTPSGetter struct {
// callCount is used to return the respective responses
callCount int
ResponseBody [][]byte
ResponseError []error
}

// Get the next configured response body and error.
func (f *FakeHTTPSGetter) Get(url string) ([]byte, error) {
body := f.ResponseBody[f.callCount]
err := f.ResponseError[f.callCount]
f.callCount++
return body, err
}

func stringsToByteSlice(strings ...string) [][]byte {
var result [][]byte
for idx := range strings {
s := strings[idx]
result = append(result, []byte(s))
}
return result
}

func TestRetryHTTPSGetterSuccess(t *testing.T) {
r := &RetryHTTPSGetter{
Timeout: 2 * time.Second,
MaxRetryDelay: 1 * time.Millisecond,
Getter: &FakeHTTPSGetter{
ResponseBody: stringsToByteSlice("content"),
ResponseError: []error{nil},
},
}

body, err := r.Get("https://any.url")
if !bytes.Equal(body, []byte("content")) {
t.Errorf("expected '%s' but got '%s'", "content", body)
}
if err != nil {
t.Errorf("expected no error, but got %s", err.Error())
}
}

func TestRetryHTTPSGetterSecondSuccess(t *testing.T) {
r := &RetryHTTPSGetter{
Timeout: 2 * time.Second,
MaxRetryDelay: 1 * time.Millisecond,
Getter: &FakeHTTPSGetter{
ResponseBody: stringsToByteSlice("", "content"),
ResponseError: []error{errors.New("failed"), nil},
},
}

body, err := r.Get("https://any.url")
if !bytes.Equal(body, []byte("content")) {
t.Errorf("expected '%s' but got '%s'", "content", body)
}
if err != nil {
t.Errorf("expected no error, but got %s", err.Error())
}
}

func TestRetryHTTPSGetterAllFail(t *testing.T) {
fail := errors.New("failed")
r := &RetryHTTPSGetter{
Timeout: 1 * time.Millisecond,
MaxRetryDelay: 1 * time.Millisecond,
Getter: &FakeHTTPSGetter{
ResponseBody: stringsToByteSlice("", "", ""),
ResponseError: []error{fail, fail, fail},
},
}

body, err := r.Get("https://any.url")
if !bytes.Equal(body, []byte("")) {
t.Errorf("expected '%s' but got '%s'", "content", body)
}
if err == nil {
t.Errorf("expected error, but got none")
}
}

0 comments on commit 4b0fa13

Please sign in to comment.