Skip to content

Commit

Permalink
update output path
Browse files Browse the repository at this point in the history
  • Loading branch information
gemmahou committed Apr 16, 2024
1 parent aa688ee commit cb1a608
Show file tree
Hide file tree
Showing 122 changed files with 146 additions and 130 deletions.
29 changes: 20 additions & 9 deletions config/tests/samples/create/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"net/http"
"os"
"path/filepath"
"strings"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -86,6 +85,12 @@ type Harness struct {

// goldenFiles tracks the golden files we checked, so we can look for "extra" golden files.
goldenFiles []string

options *HarnessOptions
}

type HarnessOptions struct {
VCRPath string
}

type httpRoundTripperKeyType int
Expand All @@ -105,16 +110,23 @@ func NewHarnessWithManager(ctx context.Context, t *testing.T, mgr manager.Manage
}

func NewHarness(ctx context.Context, t *testing.T) *Harness {
opts := &HarnessOptions{
VCRPath: "",
}
return NewHarnessWithOptions(ctx, t, opts)
}

func NewHarnessWithOptions(ctx context.Context, t *testing.T, opts *HarnessOptions) *Harness {
ctx, ctxCancel := context.WithCancel(ctx)
t.Cleanup(func() {
ctxCancel()
})

log := log.FromContext(ctx)

h := &Harness{
T: t,
Ctx: ctx,
T: t,
Ctx: ctx,
options: opts,
}

kccConfig := kccmanager.Config{}
Expand Down Expand Up @@ -345,8 +357,7 @@ func NewHarness(ctx context.Context, t *testing.T) *Harness {
} else {
t.Fatalf("[VCR] VCR_MODE should be set to record or replay; value %q is not known", input)
}
dir := "./testdata/vcr-cassette/"
testName := strings.ReplaceAll(t.Name(), "/", "_")
path := filepath.Join(h.options.VCRPath, "_vcr_cassettes")

if kccConfig.HTTPClient == nil {
httpClient, err := google.DefaultClient(ctx, gcp.ClientScopes...)
Expand All @@ -356,7 +367,7 @@ func NewHarness(ctx context.Context, t *testing.T) *Harness {
kccConfig.HTTPClient = httpClient
}
opts := &recorder.Options{
CassetteName: filepath.Join(dir, testName+"-dcl"),
CassetteName: filepath.Join(path, "dcl"),
Mode: vcrMode,
RealTransport: kccConfig.HTTPClient.Transport,
}
Expand All @@ -373,7 +384,7 @@ func NewHarness(ctx context.Context, t *testing.T) *Harness {
ret = &http.Client{Transport: t.(http.RoundTripper)}
}
opts := &recorder.Options{
CassetteName: filepath.Join(dir, testName+"-tf"),
CassetteName: filepath.Join(path, "tf"),
Mode: vcrMode,
RealTransport: ret.Transport,
}
Expand All @@ -391,7 +402,7 @@ func NewHarness(ctx context.Context, t *testing.T) *Harness {
ret = &http.Client{Transport: t.(http.RoundTripper)}
}
opts := &recorder.Options{
CassetteName: filepath.Join(dir, testName+"-oauth"),
CassetteName: filepath.Join(path, "oauth"),
Mode: vcrMode,
RealTransport: ret.Transport,
}
Expand Down
247 changes: 126 additions & 121 deletions tests/e2e/unified_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ func testFixturesInSeries(ctx context.Context, t *testing.T, testPause bool, can
if targetGCP := os.Getenv("E2E_GCP_TARGET"); targetGCP == "mock" {
subtestTimeout = time.Minute
}

if os.Getenv("RUN_E2E") == "" {
t.Skip("RUN_E2E not set; skipping")
}
Expand Down Expand Up @@ -171,15 +170,10 @@ func testFixturesInSeries(ctx context.Context, t *testing.T, testPause bool, can
create.MaybeSkip(t, fixture.Name, opt.Create)
}

h := create.NewHarness(ctx, t)
project := h.Project

if testPause {
// we need to modify CC/ CCC state
createPausedCC(ctx, t, h.GetClient())
}

// Create test harness
var h *create.Harness
if os.Getenv("E2E_GCP_TARGET") == "vcr" {
h = create.NewHarnessWithOptions(ctx, t, &create.HarnessOptions{VCRPath: fixture.SourceDir})
hash := func(s string) uint64 {
h := fnv.New64a()
h.Write([]byte(s))
Expand All @@ -188,7 +182,6 @@ func testFixturesInSeries(ctx context.Context, t *testing.T, testPause bool, can
uniqueID = strconv.FormatUint(hash(t.Name()), 36)
// Stop recording after tests finish and write to cassette
t.Cleanup(func() {

err := h.VCRRecorderDCL.Stop()
if err != nil {
t.Errorf("[VCR] Failed stop DCL vcr recorder: %v", err)
Expand All @@ -202,118 +195,15 @@ func testFixturesInSeries(ctx context.Context, t *testing.T, testPause bool, can
t.Errorf("[VCR] Failed stop Oauth vcr recorder: %v", err)
}
})
configureVCR(t, h)
} else {
h = create.NewHarness(ctx, t)
}
project := h.Project

replaceWellKnownValues := func(s string) string {
// Replace project id and number
result := strings.Replace(s, project.ProjectID, "example-project", -1)
result = strings.Replace(result, fmt.Sprintf("%d", project.ProjectNumber), "123456789", -1)

// Replace user info
obj := make(map[string]any)
if err := json.Unmarshal([]byte(s), &obj); err == nil {
toReplace, _, _ := unstructured.NestedString(obj, "user")
if len(toReplace) != 0 {
result = strings.Replace(result, toReplace, "[email protected]", -1)
}
}
return result
}

unique := make(map[string]bool)

hook := func(i *cassette.Interaction) error {
// Remove internal error message from failed interactions
resCode := i.Response.Code
if resCode == 404 || resCode == 400 || resCode == 403 {
i.Response.Body = "fake error message"
// Set Content-Length to zero
i.Response.ContentLength = 0
}

// Discard repeated operation retry interactions
reqURL := i.Request.URL
resBody := i.Response.Body

if strings.Contains(reqURL, "operations") {
sorted, _ := sortJSON(resBody)
if _, exists := unique[sorted]; !exists {
unique[sorted] = true // Mark as seen
} else {
i.DiscardOnSave = true
}
}

var requestHeadersToRemove = []string{
"Authorization",
"User-Agent",
}
for _, header := range requestHeadersToRemove {
delete(i.Request.Headers, header)
}

var responseHeadersToRemove = []string{
"Cache-Control",
"Server",
"Vary",
"X-Content-Type-Options",
"X-Frame-Options",
"X-Xss-Protection",
"Date",
"Etag",
}
for _, header := range responseHeadersToRemove {
delete(i.Response.Headers, header)
}

i.Request.Body = replaceWellKnownValues(i.Request.Body)
i.Response.Body = replaceWellKnownValues(i.Response.Body)
i.Request.URL = replaceWellKnownValues(i.Request.URL)

return nil
}
h.VCRRecorderDCL.AddHook(hook, recorder.BeforeSaveHook)
h.VCRRecorderTF.AddHook(hook, recorder.BeforeSaveHook)
h.VCRRecorderOauth.AddHook(hook, recorder.BeforeSaveHook)

matcher := func(r *http.Request, i cassette.Request) bool {
if r.Method != i.Method || r.URL.String() != i.URL {
return false
}

// Default matcher only checks the request URL and Method. If request body exists, check the body as well.
// This guarantees that the replayed response matches what the real service would return for that particular request.
if r.Body != nil && r.Body != http.NoBody {
var reqBody []byte
var err error
reqBody, err = io.ReadAll(r.Body)
if err != nil {
t.Fatal("[VCR] Failed to read request body")
}
r.Body.Close()
r.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody))
if string(reqBody) == i.Body {
return true
}

// If body contains JSON, it might be reordered
contentType := r.Header.Get("Content-Type")
if strings.Contains(contentType, "application/json") {
sortedReqBody, err := sortJSON(string(reqBody))
if err != nil {
return false
}
sortedBody, err := sortJSON(i.Body)
if err != nil {
return false
}
return sortedReqBody == sortedBody
}
}
return true
}
h.VCRRecorderDCL.SetMatcher(matcher)
h.VCRRecorderTF.SetMatcher(matcher)
h.VCRRecorderOauth.SetMatcher(matcher)
if testPause {
// we need to modify CC/ CCC state
createPausedCC(ctx, t, h.GetClient())
}

primaryResource, opt := loadFixture(project)
Expand Down Expand Up @@ -712,3 +602,118 @@ func addTestTimeout(ctx context.Context, t *testing.T, timeout time.Duration) co

return ctx
}

func configureVCR(t *testing.T, h *create.Harness) {
project := h.Project
replaceWellKnownValues := func(s string) string {
// Replace project id and number
result := strings.Replace(s, project.ProjectID, "example-project", -1)
result = strings.Replace(result, fmt.Sprintf("%d", project.ProjectNumber), "123456789", -1)

// Replace user info
obj := make(map[string]any)
if err := json.Unmarshal([]byte(s), &obj); err == nil {
toReplace, _, _ := unstructured.NestedString(obj, "user")
if len(toReplace) != 0 {
result = strings.Replace(result, toReplace, "[email protected]", -1)
}
}
return result
}

unique := make(map[string]bool)

hook := func(i *cassette.Interaction) error {
// Remove internal error message from failed interactions
resCode := i.Response.Code
if resCode == 404 || resCode == 400 || resCode == 403 {
i.Response.Body = "fake error message"
// Set Content-Length to zero
i.Response.ContentLength = 0
}

// Discard repeated operation retry interactions
reqURL := i.Request.URL
resBody := i.Response.Body

if strings.Contains(reqURL, "operations") {
sorted, _ := sortJSON(resBody)
if _, exists := unique[sorted]; !exists {
unique[sorted] = true // Mark as seen
} else {
i.DiscardOnSave = true
}
}

var requestHeadersToRemove = []string{
"Authorization",
"User-Agent",
}
for _, header := range requestHeadersToRemove {
delete(i.Request.Headers, header)
}

var responseHeadersToRemove = []string{
"Cache-Control",
"Server",
"Vary",
"X-Content-Type-Options",
"X-Frame-Options",
"X-Xss-Protection",
"Date",
"Etag",
}
for _, header := range responseHeadersToRemove {
delete(i.Response.Headers, header)
}

i.Request.Body = replaceWellKnownValues(i.Request.Body)
i.Response.Body = replaceWellKnownValues(i.Response.Body)
i.Request.URL = replaceWellKnownValues(i.Request.URL)

return nil
}
h.VCRRecorderDCL.AddHook(hook, recorder.BeforeSaveHook)
h.VCRRecorderTF.AddHook(hook, recorder.BeforeSaveHook)
h.VCRRecorderOauth.AddHook(hook, recorder.BeforeSaveHook)

matcher := func(r *http.Request, i cassette.Request) bool {
if r.Method != i.Method || r.URL.String() != i.URL {
return false
}

// Default matcher only checks the request URL and Method. If request body exists, check the body as well.
// This guarantees that the replayed response matches what the real service would return for that particular request.
if r.Body != nil && r.Body != http.NoBody {
var reqBody []byte
var err error
reqBody, err = io.ReadAll(r.Body)
if err != nil {
t.Fatal("[VCR] Failed to read request body")
}
r.Body.Close()
r.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody))
if string(reqBody) == i.Body {
return true
}

// If body contains JSON, it might be reordered
contentType := r.Header.Get("Content-Type")
if strings.Contains(contentType, "application/json") {
sortedReqBody, err := sortJSON(string(reqBody))
if err != nil {
return false
}
sortedBody, err := sortJSON(i.Body)
if err != nil {
return false
}
return sortedReqBody == sortedBody
}
}
return true
}
h.VCRRecorderDCL.SetMatcher(matcher)
h.VCRRecorderTF.SetMatcher(matcher)
h.VCRRecorderOauth.SetMatcher(matcher)
}

0 comments on commit cb1a608

Please sign in to comment.