func TestObfuscator(t *testing.T) { T := testlib.NewT(t) T.Finish() b := &basicAuthObfuscator{ username: "******", password: "******", } rr := &RequestResponse{ Request: &http.Request{ URL: &url.URL{ User: url.UserPassword("user2", "pass2"), }, Header: http.Header(map[string][]string{ "Authorization": []string{"test"}, }), }, } b.Obfuscator(rr) T.Equal(rr.Request.URL.User.String(), "user1:pass1") T.Equal(rr.Request.Header.Get("Authorization"), "Basic dXNlcjE6cGFzczE=") b.password = "" b.Obfuscator(rr) T.Equal(rr.Request.URL.User.String(), "user1") T.Equal(rr.Request.Header.Get("Authorization"), "Basic dXNlcjE6") }
func TestBadVersion(t *testing.T) { T := testlib.NewT(t) defer T.Finish() fd := T.TempFile() isSetup = sync.Once{} record = false replay = true passThrough = false DefaultReplay = false fileName = fd.Name() // Write all zeros to the temp file which will be version 0. _, err := fd.Write([]byte{0, 0, 0, 0}) T.ExpectSuccess(err) T.ExpectSuccess(fd.Close()) // Now check to see if the setup function fails for the right reasons. defer func() { err := recover() if err == nil { T.Fatalf("Expected panic not returned.") } else if err2, ok := err.(error); !ok { T.Fatalf("Unknown panic return: %#v\n", err) } else { T.ExpectErrorMessage(err2, "Unknown version: 0") } }() rt := roundTripper{} rt.replaySetup() }
func TestGobError_GobDecode(t *testing.T) { T := testlib.NewT(t) defer T.Finish() // Most of the Decoding tests are in TestGobError_GobEncode other than // a simple bogus data check. g := &gobError{} T.ExpectError(g.GobDecode([]byte{0, 1, 2, 3})) }
func TestIsRecording(t *testing.T) { T := testlib.NewT(t) defer T.Finish() record = true T.Equal(IsRecording(), true) record = false T.Equal(IsRecording(), false) record = false }
func TestIsPassingThrough(t *testing.T) { T := testlib.NewT(t) defer T.Finish() record = false replay = false T.Equal(IsPassingThrough(), true) replay = true T.Equal(IsPassingThrough(), false) replay = false }
func TestGzipper(t *testing.T) { T := testlib.NewT(t) defer T.Finish() // Ensure that the bad arg conditions to not work. func() { forcePanic := func(i int) { panic(i) } defer func() { err := recover() if err != nil { T.Fatalf("Unexpected panic: %#v\n", err) } }() initGzipper([]string{"XXX"}, nil, nil, forcePanic) initGzipper([]string{"XXX", "YYY"}, nil, nil, forcePanic) }() // Setup files that we will use for input/output for the function. data := []byte("A test string that should always make it through.") in := T.TempFile() out := T.TempFile() // Write the uncompressed data to the input file. _, err := in.Write(data) T.ExpectSuccess(err) _, err = in.Seek(0, 0) T.ExpectSuccess(err) // call the gzipper initializer. func() { defer func() { err := recover() if err != nil { T.Fatalf("Unexpected error: %#v\n", err) } }() exited := false exit := func(i int) { exited = true } initGzipper([]string{os.Args[0], InterceptorToken}, in, out, exit) T.Equal(exited, true) }() // Read the data back and ensure that it matches what we wrote in. fd, err := os.Open(out.Name()) T.ExpectSuccess(err) reader, err := gzip.NewReader(fd) T.ExpectSuccess(err) var readData []byte = make([]byte, 1024) n, err := reader.Read(readData) T.ExpectSuccess(err) T.Equal(n, len(data)) T.Equal(readData[0:n], data) }
func TestGobQuery_RequestResponse(t *testing.T) { T := testlib.NewT(t) defer T.Finish() defer func() { err := recover() if err == nil { T.Fatalf("The expected panic didn't happen") } else if _, ok := err.(*dvrFailure); !ok { T.Fatalf("An unexpected panic happened: %#v", err) } }() panicOutput = ioutil.Discard gq := &gobQuery{Request: new(gobRequest)} gq.Request.URL = "://" gq.RequestResponse() T.Fatalf("The above call should never return.") }
func TestIsMode(t *testing.T) { T := testlib.NewT(t) defer T.Finish() test := func(rec, repl, pass, def, ex1, ex2 bool) { record = rec replay = repl passThrough = pass DefaultReplay = def got1, got2 := mode() T.Equal(got1, ex1) T.Equal(got2, ex2) } // Recording mode. test(true, false, false, false, true, false) test(true, false, false, true, true, false) test(true, false, true, false, true, false) test(true, false, true, true, true, false) test(true, true, false, false, true, false) test(true, true, false, true, true, false) test(true, true, true, false, true, false) test(true, true, true, true, true, false) // Replay mode. test(false, true, false, false, false, true) test(false, true, false, true, false, true) test(false, true, true, false, false, true) test(false, true, true, true, false, true) // Passthrough (forced) test(false, false, true, false, false, false) test(false, false, true, true, false, false) // Default Replay test(false, false, false, true, false, true) // Default test(false, false, false, false, false, false) // Reset the defaults/ record = false replay = false passThrough = false DefaultReplay = false }
func TestMatcher(t *testing.T) { T := testlib.NewT(t) defer T.Finish() left := &RequestResponse{} right := &RequestResponse{ Request: &http.Request{ Method: "GET", URL: &url.URL{ Scheme: "http", Opaque: "opaque", User: url.UserPassword("user", "password"), Host: "host", Path: "path", RawQuery: "raw", Fragment: "fragment", }, Header: http.Header(map[string][]string{ "header1": []string{"value1", "value2"}, }), Trailer: http.Header(map[string][]string{ "header2": []string{"value3", "value4"}, }), }, RequestBody: []byte("body"), } // Test 1: nil values (returns false T.Equal(matcher(nil, nil), false) T.Equal(matcher(left, right), false) // Test 2: nil url. left.Request = &http.Request{} T.Equal(matcher(left, right), false) // Test 3: Different Schemes left.Request = &http.Request{ URL: &url.URL{ Scheme: "NOT_GET", }, } T.Equal(matcher(left, right), false) left.Request.URL.Scheme = right.Request.URL.Scheme // Test 4: Different Opaque values. left.Request.URL.Opaque = "NOT_OPAQUE" T.Equal(matcher(left, right), false) left.Request.URL.Opaque = right.Request.URL.Opaque // Test 5: Different Host values. left.Request.URL.Host = "NOT_HOST" T.Equal(matcher(left, right), false) left.Request.URL.Host = right.Request.URL.Host // Test 6: Different Path values. left.Request.URL.Path = "NOT_PATH" T.Equal(matcher(left, right), false) left.Request.URL.Path = right.Request.URL.Path // Test 7: Different RawQuery values. left.Request.URL.RawQuery = "NOT_RAW_QUERY" T.Equal(matcher(left, right), false) left.Request.URL.RawQuery = right.Request.URL.RawQuery // Test 8: Different Fragment values. left.Request.URL.Fragment = "NOT_FRAGMENT" T.Equal(matcher(left, right), false) left.Request.URL.Fragment = right.Request.URL.Fragment // Test 9: Left URL.User == nil T.Equal(matcher(left, right), false) // Test 10: Right URL.User = nil left.Request.URL.User = right.Request.URL.User right.Request.URL.User = nil T.Equal(matcher(left, right), false) // Test 11: URL.User.String() is different. right.Request.URL.User = url.UserPassword("not_user", "not_password") T.Equal(matcher(left, right), false) right.Request.URL.User = left.Request.URL.User // Test 12: RequestBody values differ. left.RequestBody = []byte("NOT_THE_SAME") T.Equal(matcher(left, right), false) left.RequestBody = right.RequestBody // Test 13: Headers are different. left.Request.Header = http.Header(map[string][]string{ "header1": []string{"value1", "value2_XXX"}, }) T.Equal(matcher(left, right), false) left.Request.Header = right.Request.Header // Test 14: Trailers are different. left.Request.Trailer = http.Header(map[string][]string{ "header2": []string{"value1", "value2_XXX"}, }) T.Equal(matcher(left, right), false) left.Request.Trailer = right.Request.Trailer // Test 15: Successful match. T.Equal(matcher(left, right), true) // Test 16: Second try fails. T.Equal(matcher(left, right), false) }
func TestDvrFailure_Error(t *testing.T) { T := testlib.NewT(t) defer T.Finish() e := dvrFailure{Err: fmt.Errorf("Expected")} T.Equal(e.Error(), "Expected") }
func TestFullCycle(t *testing.T) { // Reset default settings, defer func() { record = false replay = false passThrough = false DefaultReplay = false fileName = "testdata/archive.dvr" }() T := testlib.NewT(t) defer T.Finish() // Start an HTTP server and ensure that the listener is closed when // the test finishes. This will shut down the server. listener := runHttpServer(T) defer listener.Close() addr := listener.Addr().String() // // Pass Through Tests // // Fun a bunch of queries against the server directly (no dvr at all) as // we as with a pass through dvr Transport in place. Once we are done // we compare all of the results of the two tests against each other. fileName = T.TempFile().Name() resetTest(T) record = false replay = false directResponses := runTests(T, OriginalDefaultTransport, addr, "", "") passthroughTripper := &roundTripper{ realRoundTripper: OriginalDefaultTransport, } T.Equal(runTests(T, passthroughTripper, addr, "", ""), directResponses) // // Record Tests // // Next we setup a temp file and record the same tests as above into it. // We setup a recording RoundTripper and run the same tests as above into // it. Once done we compare the results against the direct responses. resetTest(T) record = true replay = false recordTripper := &roundTripper{realRoundTripper: OriginalDefaultTransport} T.Equal(runTests(T, recordTripper, addr, "", ""), directResponses) // // Replay tests // // Now we need to validate the file by attempting to "replay" it. To do // this we create a new roundTripper with the replay option set to the file // we just created and reset the flags. resetTest(T) record = false replay = true replayTripper := &roundTripper{realRoundTripper: OriginalDefaultTransport} T.Equal(runTests(T, replayTripper, addr, "", ""), directResponses) // Make sure that a new, completely unknown requests results in a panic // with the right types and such. var err error req := &http.Request{} req.URL, err = url.Parse(fmt.Sprintf("http://%s/wtf", addr)) T.ExpectSuccess(err) req.Header = map[string][]string{"TestHeader": []string{"Value1"}} req.Trailer = map[string][]string{"TestTrailer": []string{"Value2"}} bodyWriter := &bytesBufferCloser{} _, err = bodyWriter.Write(bytes.Repeat([]byte("TEST"), 256)) T.ExpectSuccess(err) req.Body = bodyWriter client := &http.Client{} client.Transport = replayTripper func() { defer func() { panicErr := recover() if panicErr == nil { T.Fatalf("An expected panic didn't happen!") } else if err, ok := panicErr.(*dvrFailure); !ok { panic(panicErr) } else { T.ExpectErrorMessage(err, "Matcher didn't match any execeted") T.ExpectErrorMessage(err, "URL: "+req.URL.String()) T.ExpectErrorMessage(err, "Method", "GET") T.ExpectErrorMessage(err, "Headers:") T.ExpectErrorMessage(err, "TestHeader: Value1") T.ExpectErrorMessage(err, "Trailers:") T.ExpectErrorMessage(err, "TestTrailer: Value2") T.ExpectErrorMessage(err, "Body:") T.ExpectErrorMessage(err, "TESTTESTTESTTEST") T.ExpectErrorMessage(err, "(content truncated by dvr)") } }() panicOutput = ioutil.Discard resp, err := client.Do(req) T.Fatalf("The previous call should have paniced. It Returned: %#v %#v", resp, err) }() // // Obfuscator // // Setup a BasicAuthOfbuscator Obfuscator = BasicAuthObfuscator("user2", "pass2") // Now setup a recorder that will recurd all requests with one username // and password. fileName = T.TempFile().Name() resetTest(T) record = true replay = false recordTripper = &roundTripper{realRoundTripper: OriginalDefaultTransport} runTests(T, recordTripper, addr, "user1", "pass1") // Now we attempt to play the results back, only using a replay session, // only this time we use a different username and password but it should // still work. Note that we can not compare them to the direct results // since they will contain auth headers and such. Instead we fail if a panic // is raised. resetTest(T) record = false replay = true replayTripper = &roundTripper{realRoundTripper: OriginalDefaultTransport} func() { defer func() { err := recover() if err == nil { return } T.Fatalf("Unexpected panic: %s", err) }() runTests(T, replayTripper, addr, "user2", "pass2") }() }
func TestGobError_GobEncode(t *testing.T) { T := testlib.NewT(t) defer T.Finish() // Test 1: An unencodable error. g := &gobError{Error: customError("Unexpected")} // Encode the error. buffer := &bytes.Buffer{} encoder := gob.NewEncoder(buffer) T.ExpectSuccess(encoder.Encode(g)) // Decode the byte array to see what was returned. g2 := new(gobError) decoder := gob.NewDecoder(buffer) T.ExpectSuccess(decoder.Decode(g2)) // Make sure that the two encoded objects types are NOT the same. T.NotEqual(g, g2) // Ensure that the type of g2.Error is actually a gobSafeError if _, ok := g2.Error.(*gobSafeError); !ok { T.Fatalf("g2.Error is not a gobSafeEror, its a %T", g2.Error) } // Test 2: An encodable error. g = &gobError{Error: &http.ProtocolError{ErrorString: "Expected"}} // Encode the error. buffer = &bytes.Buffer{} encoder = gob.NewEncoder(buffer) T.ExpectSuccess(encoder.Encode(g)) // Decode the byte array to see what was returned. g2 = new(gobError) decoder = gob.NewDecoder(buffer) T.ExpectSuccess(decoder.Decode(g2)) // Ensure that the two encoded objects ARE the same. T.Equal(g, g2) // Ensure that the type of g2.Error is actually a *http.ProtocolError if _, ok := g2.Error.(*http.ProtocolError); !ok { T.Fatalf("g2.Error is not a *http.ProtocolError, its a %T", g2.Error) } // Test 3: An errors.stringError object. g = &gobError{Error: errors.New("Expected")} // Encode the error. buffer = &bytes.Buffer{} encoder = gob.NewEncoder(buffer) T.ExpectSuccess(encoder.Encode(g)) // Decode the byte array to see what was returned. g2 = new(gobError) decoder = gob.NewDecoder(buffer) T.ExpectSuccess(decoder.Decode(g2)) // Ensure that the two encoded objects ARE the same. T.Equal(g, g2) // Ensure that the type of g2.Error is actually a *http.ProtocolError if reflect.TypeOf(g.Error) != reflect.TypeOf(g2.Error) { T.Fatalf("g2.Error is not a *http.ProtocolError, its a %T", g2.Error) } }
func TestSimpleCoverage(t *testing.T) { T := testlib.NewT(t) defer T.Finish() T.Equal(newGobRequest(nil), nil) T.Equal(newGobResponse(nil), nil) }