...

Source file src/github.com/sigstore/rekor/tests/util.go

Documentation: github.com/sigstore/rekor/tests

     1  //
     2  // Copyright 2021 The Sigstore Authors.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  //go:build e2e
    17  // +build e2e
    18  
    19  package e2e
    20  
    21  import (
    22  	"encoding/base64"
    23  	"fmt"
    24  	"io/ioutil"
    25  	"math/rand"
    26  	"os"
    27  	"os/exec"
    28  	"strings"
    29  	"testing"
    30  	"time"
    31  
    32  	"github.com/sigstore/rekor/pkg/generated/models"
    33  )
    34  
    35  const (
    36  	cli         = "../rekor-cli"
    37  	server      = "../rekor-server"
    38  	nodeDataDir = "node"
    39  )
    40  
    41  func outputContains(t *testing.T, output, sub string) {
    42  	t.Helper()
    43  	if !strings.Contains(output, sub) {
    44  		t.Errorf("Expected [%s] in response, got %s", sub, output)
    45  	}
    46  }
    47  
    48  func run(t *testing.T, stdin, cmd string, arg ...string) string {
    49  	t.Helper()
    50  	// Coverage flag must be the first arg passed to coverage binary
    51  	// No impact when running with regular binary
    52  	arg = append([]string{coverageFlag()}, arg...)
    53  	c := exec.Command(cmd, arg...)
    54  	if stdin != "" {
    55  		c.Stdin = strings.NewReader(stdin)
    56  	}
    57  	if os.Getenv("REKORTMPDIR") != "" {
    58  		// ensure that we use a clean state.json file for each run
    59  		c.Env = append(c.Env, "HOME="+os.Getenv("REKORTMPDIR"))
    60  	}
    61  	b, err := c.CombinedOutput()
    62  	if err != nil {
    63  		t.Log(string(b))
    64  		t.Fatal(err)
    65  	}
    66  	return stripCoverageOutput(string(b))
    67  }
    68  
    69  func runCli(t *testing.T, arg ...string) string {
    70  	t.Helper()
    71  	arg = append(arg, rekorServerFlag())
    72  	// use a blank config file to ensure no collision
    73  	if os.Getenv("REKORTMPDIR") != "" {
    74  		arg = append(arg, "--config="+os.Getenv("REKORTMPDIR")+".rekor.yaml")
    75  	}
    76  	return run(t, "", cli, arg...)
    77  }
    78  
    79  func runCliStdout(t *testing.T, arg ...string) string {
    80  	t.Helper()
    81  	// Coverage flag must be the first arg passed to coverage binary
    82  	// No impact when running with regular binary
    83  	arg = append([]string{coverageFlag()}, arg...)
    84  	arg = append(arg, rekorServerFlag())
    85  	c := exec.Command(cli, arg...)
    86  
    87  	if os.Getenv("REKORTMPDIR") != "" {
    88  		// ensure that we use a clean state.json file for each run
    89  		c.Env = append(c.Env, "HOME="+os.Getenv("REKORTMPDIR"))
    90  	}
    91  	b, err := c.Output()
    92  	if err != nil {
    93  		t.Log(string(b))
    94  		t.Fatal(err)
    95  	}
    96  	return stripCoverageOutput(string(b))
    97  }
    98  
    99  func runCliErr(t *testing.T, arg ...string) string {
   100  	t.Helper()
   101  	// Coverage flag must be the first arg passed to coverage binary
   102  	// No impact when running with regular binary
   103  	arg = append([]string{coverageFlag()}, arg...)
   104  	arg = append(arg, rekorServerFlag())
   105  	// use a blank config file to ensure no collision
   106  	if os.Getenv("REKORTMPDIR") != "" {
   107  		arg = append(arg, "--config="+os.Getenv("REKORTMPDIR")+".rekor.yaml")
   108  	}
   109  	cmd := exec.Command(cli, arg...)
   110  	b, err := cmd.CombinedOutput()
   111  	if err == nil {
   112  		t.Log(string(b))
   113  		t.Fatalf("expected error, got %s", string(b))
   114  	}
   115  	return stripCoverageOutput(string(b))
   116  }
   117  
   118  func rekorServerFlag() string {
   119  	return fmt.Sprintf("--rekor_server=%s", rekorServer())
   120  }
   121  
   122  func rekorServer() string {
   123  	if s := os.Getenv("REKOR_SERVER"); s != "" {
   124  		return s
   125  	}
   126  	return "http://localhost:3000"
   127  }
   128  
   129  func coverageFlag() string {
   130  	return "-test.coverprofile=/tmp/rekor-cli." + randomSuffix(8) + ".cov"
   131  }
   132  
   133  func stripCoverageOutput(out string) string {
   134  	return strings.Split(strings.Split(out, "PASS")[0], "FAIL")[0]
   135  }
   136  
   137  func readFile(t *testing.T, p string) string {
   138  	b, err := ioutil.ReadFile(p)
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  	return strings.TrimSpace(string(b))
   143  }
   144  
   145  func randomSuffix(n int) string {
   146  	const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
   147  
   148  	b := make([]byte, n)
   149  	for i := range b {
   150  		b[i] = letterBytes[rand.Intn(len(letterBytes))]
   151  	}
   152  	return string(b)
   153  }
   154  
   155  func randomData(t *testing.T, n int) []byte {
   156  	t.Helper()
   157  	rand.Seed(time.Now().UnixNano())
   158  	data := make([]byte, n)
   159  	if _, err := rand.Read(data[:]); err != nil {
   160  		t.Fatal(err)
   161  	}
   162  	return data
   163  }
   164  
   165  func createArtifact(t *testing.T, artifactPath string) string {
   166  	t.Helper()
   167  	// First let's generate some random data so we don't have to worry about dupes.
   168  	data := randomData(t, 100)
   169  
   170  	artifact := base64.StdEncoding.EncodeToString(data[:])
   171  	// Write this to a file
   172  	write(t, artifact, artifactPath)
   173  	return artifact
   174  }
   175  
   176  func extractLogEntry(t *testing.T, le models.LogEntry) models.LogEntryAnon {
   177  	t.Helper()
   178  
   179  	if len(le) != 1 {
   180  		t.Fatal("expected length to be 1, is actually", len(le))
   181  	}
   182  	for _, v := range le {
   183  		return v
   184  	}
   185  	// this should never happen
   186  	return models.LogEntryAnon{}
   187  }
   188  
   189  func write(t *testing.T, data string, path string) {
   190  	t.Helper()
   191  	if err := ioutil.WriteFile(path, []byte(data), 0644); err != nil {
   192  		t.Fatal(err)
   193  	}
   194  }
   195  

View as plain text