func TestEmptySessionTokenInSessionToken(t *testing.T) { t.Parallel() st := parse.SessionToken{ ApplicationID: defaultApplicationID, RestAPIKey: "rk", } ensure.Err(t, st.Modify(nil), regexp.MustCompile("empty SessionToken")) }
func TestCredentiasModifyError(t *testing.T) { t.Parallel() c := parse.Client{ Credentials: parse.RestAPIKey{}, } _, err := c.Do(&http.Request{}, nil, nil) ensure.Err(t, err, regexp.MustCompile("empty ApplicationID")) }
func TestMissingCredentials(t *testing.T) { t.Parallel() var c parse.Client req := http.Request{Method: "GET", URL: &url.URL{Path: "classes/Foo/Bar"}} _, err := c.Do(&req, nil, nil) ensure.NotNil(t, err) ensure.Err(t, err, regexp.MustCompile(`parse: api error with message="unauthorized"`)) }
func TestInvalidFlagValue(t *testing.T) { const name = "TestInvalidFlagValue" s := flag.NewFlagSet(name, flag.PanicOnError) s.Int("bar", 0, "") os.Setenv(named(name, "bar"), "a") ensure.Err(t, flagenv.ParseSet(name, s), regexp.MustCompile(`failed to set flag "bar" with value "a"`)) }
func TestNewRequestAfterStop(t *testing.T) { t.Parallel() const count = 10000 hello := []byte("hello") finOkHandler := make(chan struct{}) unblockOkHandler := make(chan struct{}) okHandler := func(w http.ResponseWriter, r *http.Request) { defer close(finOkHandler) w.WriteHeader(200) const diff = 500 for i := 0; i < count-diff; i++ { w.Write(hello) } <-unblockOkHandler for i := 0; i < diff; i++ { w.Write(hello) } } listener, err := net.Listen("tcp", "127.0.0.1:0") listener, onClose := NewOnCloseListener(listener) ensure.Nil(t, err) server := &http.Server{Handler: http.HandlerFunc(okHandler)} transport := &http.Transport{} client := &http.Client{Transport: transport} down := &httpdown.HTTP{} s := down.Serve(server, listener) res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String())) ensure.Nil(t, err) finStop := make(chan struct{}) go func() { defer close(finStop) ensure.Nil(t, s.Stop()) }() // Wait until the listener is closed. <-onClose // Now the next request should not be able to connect as the listener is // now closed. _, err = client.Get(fmt.Sprintf("http://%s/", listener.Addr().String())) // We should just get "connection refused" here, but sometimes, very rarely, // we get a "connection reset" instead. Unclear why this happens. ensure.Err(t, err, regexp.MustCompile("(connection refused|connection reset by peer)$")) // Unblock the handler and ensure we finish writing the rest of the body // successfully. close(unblockOkHandler) actualBody, err := ioutil.ReadAll(res.Body) ensure.Nil(t, err) ensure.DeepEqual(t, actualBody, bytes.Repeat(hello, count)) ensure.Nil(t, res.Body.Close()) <-finOkHandler <-finStop }
func TestTransportError(t *testing.T) { t.Parallel() c := &fbapi.Client{ Transport: errorTransport{}, } res := make(map[string]interface{}) _, err := c.Do(&http.Request{Method: "GET"}, res) ensure.Err(t, err, regexp.MustCompile(`42`)) }
func TestReturnsFirstError(t *testing.T) { const name = "TestReturnsFirstError" s := flag.NewFlagSet(name, flag.PanicOnError) s.Int("bar1", 0, "") s.Int("bar2", 0, "") os.Setenv(named(name, "bar1"), "a") ensure.Err(t, flagenv.ParseSet(name, s), regexp.MustCompile(`failed to set flag "bar1" with value "a"`)) }
func TestLoadFromBoxError(t *testing.T) { const msg = "foo" h := Handler{ Box: funcBox(func(name string) ([]byte, error) { return nil, errors.New(msg) }), } _, err := h.load("baz") ensure.Err(t, err, regexp.MustCompile(msg)) }
func TestCustomHTTPTransport(t *testing.T) { t.Parallel() const message = "hello world" c := &parse.Client{ Transport: transportFunc(func(*http.Request) (*http.Response, error) { return nil, errors.New(message) }), } _, err := c.Do(&http.Request{}, nil, nil) ensure.Err(t, err, regexp.MustCompile(message)) }
func TestCombinedURLBoxError(t *testing.T) { const msg = "foo" h := Handler{ Box: funcBox(func(name string) ([]byte, error) { return nil, errors.New(msg) }), } v, err := h.URL("baz") ensure.DeepEqual(t, v, "") ensure.Err(t, err, regexp.MustCompile(msg)) }
func TestNilURLWithBaseURL(t *testing.T) { t.Parallel() client := &fbapi.Client{ BaseURL: &url.URL{ Scheme: "https", Host: "graph.facebook.com", Path: "/20aa2519-4745-4522-92a9-4522b8edf6e9", }, } res, err := client.Do(&http.Request{Method: "GET"}, nil) ensure.Err(t, err, regexp.MustCompile(`failed with code 803`)) ensure.DeepEqual(t, res.StatusCode, 404) }
func TestHTTPStopTimeoutMissed(t *testing.T) { t.Parallel() klock := clock.NewMock() const count = 10000 hello := []byte("hello") finOkHandler := make(chan struct{}) unblockOkHandler := make(chan struct{}) okHandler := func(w http.ResponseWriter, r *http.Request) { defer close(finOkHandler) w.Header().Set("Content-Length", fmt.Sprint(len(hello)*count)) w.WriteHeader(200) for i := 0; i < count/2; i++ { w.Write(hello) } <-unblockOkHandler for i := 0; i < count/2; i++ { w.Write(hello) } } listener, err := net.Listen("tcp", "127.0.0.1:0") ensure.Nil(t, err) server := &http.Server{Handler: http.HandlerFunc(okHandler)} transport := &http.Transport{} client := &http.Client{Transport: transport} down := &httpdown.HTTP{ StopTimeout: time.Minute, Clock: klock, } s := down.Serve(server, listener) res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String())) ensure.Nil(t, err) finStop := make(chan struct{}) go func() { defer close(finStop) ensure.Nil(t, s.Stop()) }() klock.Wait(clock.Calls{After: 1}) // wait for Stop to call After klock.Add(down.StopTimeout) _, err = ioutil.ReadAll(res.Body) ensure.Err(t, err, regexp.MustCompile("^unexpected EOF$")) ensure.Nil(t, res.Body.Close()) close(unblockOkHandler) <-finOkHandler <-finStop }
func TestInvalidGet(t *testing.T) { t.Parallel() res, err := defaultFbClient.Do( &http.Request{ Method: "GET", URL: &url.URL{ Path: "20aa2519-4745-4522-92a9-4522b8edf6e9", }, }, nil, ) ensure.Err(t, err, regexp.MustCompile(`failed with code 803`)) ensure.DeepEqual(t, res.StatusCode, 404) }
func TestHTTPSDefaultListenError(t *testing.T) { if os.Getuid() == 0 { t.Skip("cant run this test as root") } t.Parallel() cert, err := tls.X509KeyPair(localhostCert, localhostKey) if err != nil { t.Fatalf("error loading cert: %v", err) } down := &httpdown.HTTP{} _, err = down.ListenAndServe(&http.Server{ TLSConfig: &tls.Config{ NextProtos: []string{"http/1.1"}, Certificates: []tls.Certificate{cert}, }, }) ensure.Err(t, err, regexp.MustCompile("listen tcp :443: bind: permission denied")) }
func TestHTTPDefaultListenError(t *testing.T) { if os.Getuid() == 0 { t.Skip("cant run this test as root") } statsDone := make(chan struct{}, 1) hc := &stats.HookClient{ BumpSumHook: func(key string, val float64) { if key == "listen.error" && val == 1 { statsDone <- struct{}{} } }, } t.Parallel() down := &httpdown.HTTP{Stats: hc} _, err := down.ListenAndServe(&http.Server{}) ensure.Err(t, err, regexp.MustCompile("listen tcp :80: bind: permission denied")) <-statsDone }
func TestExtras(t *testing.T) { var c capture e := errors.New("foo") ensure.Err( &c, e, nil, map[string]int{"answer": 42}, "baz", 43, 44.45, typ{Answer: 46}, ) c.Equal(t, `ensure_test.go:51: unexpected error: foo (map[string]int) (len=1) { (string) (len=6) "answer": (int) 42 } (string) (len=3) "baz" (int) 43 (float64) 44.45 (ensure_test.typ) { Answer: (int) 46 }`) }
func TestHTMLResponse(t *testing.T) { t.Parallel() server := httptest.NewServer( http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) w.Write([]byte("<html></html>")) }, ), ) u, err := url.Parse(server.URL) ensure.Nil(t, err) c := &fbapi.Client{ Transport: defaultHTTPTransport, BaseURL: u, } res := make(map[string]interface{}) _, err = c.Do(&http.Request{Method: "GET"}, res) ensure.Err(t, err, regexp.MustCompile(`got 500 Internal Server Error`)) server.CloseClientConnections() server.Close() }
func TestRestAPIKeyEmptyApplicationID(t *testing.T) { t.Parallel() var mk parse.RestAPIKey ensure.Err(t, mk.Modify(nil), regexp.MustCompile("empty ApplicationID")) }
func TestMatchingError(t *testing.T) { var c capture e := errors.New("foo") ensure.Err(&c, e, regexp.MustCompile("bar")) c.Equal(t, "ensure_test.go:22: expected error: \"bar\" but got \"foo\"") }
func TestExpectedNilErr(t *testing.T) { var c capture ensure.Err(&c, nil, nil) c.Equal(t, "") }
func TestUnexpectedNilErr(t *testing.T) { var c capture ensure.Err(&c, nil, regexp.MustCompile("bar")) c.Equal(t, "ensure_test.go:110: expected error: \"bar\" but got a nil error") }
func TestNilErr(t *testing.T) { var c capture e := errors.New("foo") ensure.Err(&c, e, nil) c.Equal(t, "ensure_test.go:15: unexpected error: foo") }
func TestDecodeNotTwoParts(t *testing.T) { encoded := base64.URLEncoding.EncodeToString([]byte("[[]]")) value, err := decode(encoded) ensure.True(t, value == nil) ensure.Err(t, err, regexp.MustCompile(`static: invalid URL "W1tdXQ=="`)) }
func TestNilURLWithDefaultBaseURL(t *testing.T) { t.Parallel() res, err := defaultFbClient.Do(&http.Request{Method: "GET"}, nil) ensure.Err(t, err, regexp.MustCompile(`failed with code 100`)) ensure.DeepEqual(t, res.StatusCode, 400) }
func TestCombinedURLNoNames(t *testing.T) { var h Handler v, err := h.URL() ensure.DeepEqual(t, v, "") ensure.Err(t, err, regexp.MustCompile("zero names given")) }
func TestDecodeInvalidBase64(t *testing.T) { value, err := decode("#") ensure.True(t, value == nil) ensure.Err(t, err, regexp.MustCompile(`static: invalid URL "#"`)) }
func TestDecodeInvalidJSON(t *testing.T) { encoded := base64.URLEncoding.EncodeToString([]byte("x")) value, err := decode(encoded) ensure.True(t, value == nil) ensure.Err(t, err, regexp.MustCompile(`static: invalid URL "eA=="`)) }
func TestHTTPKillTimeoutMissed(t *testing.T) { t.Parallel() klock := clock.NewMock() statsDone := make(chan struct{}, 1) hc := &stats.HookClient{ BumpSumHook: func(key string, val float64) { if key == "kill.timeout" && val == 1 { statsDone <- struct{}{} } }, } const count = 10000 hello := []byte("hello") finOkHandler := make(chan struct{}) unblockOkHandler := make(chan struct{}) okHandler := func(w http.ResponseWriter, r *http.Request) { defer close(finOkHandler) w.Header().Set("Content-Length", fmt.Sprint(len(hello)*count)) w.WriteHeader(200) for i := 0; i < count/2; i++ { w.Write(hello) } <-unblockOkHandler for i := 0; i < count/2; i++ { w.Write(hello) } } listener, err := net.Listen("tcp", "127.0.0.1:0") ensure.Nil(t, err) unblockConnClose := make(chan chan struct{}, 1) listener = &closeErrConnListener{ Listener: listener, unblockClose: unblockConnClose, } server := &http.Server{Handler: http.HandlerFunc(okHandler)} transport := &http.Transport{} client := &http.Client{Transport: transport} down := &httpdown.HTTP{ StopTimeout: time.Minute, KillTimeout: time.Minute, Stats: hc, Clock: klock, } s := down.Serve(server, listener) res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String())) ensure.Nil(t, err) // Start the Stop process. finStop := make(chan struct{}) go func() { defer close(finStop) ensure.Nil(t, s.Stop()) }() klock.Wait(clock.Calls{After: 1}) // wait for Stop to call After klock.Add(down.StopTimeout) // trigger stop timeout klock.Wait(clock.Calls{After: 2}) // wait for Kill to call After klock.Add(down.KillTimeout) // trigger kill timeout // We hit both the StopTimeout & the KillTimeout. <-finStop // Then we unblock the Close, so we get an unexpected EOF since we close // before we finish writing the response. connCloseDone := make(chan struct{}) unblockConnClose <- connCloseDone <-connCloseDone close(unblockConnClose) // Then we unblock the handler which tries to write the rest of the data. close(unblockOkHandler) _, err = ioutil.ReadAll(res.Body) ensure.Err(t, err, regexp.MustCompile("^unexpected EOF$")) ensure.Nil(t, res.Body.Close()) <-finOkHandler <-statsDone }
func TestEmptySessionToken(t *testing.T) { t.Parallel() var st parse.SessionToken ensure.Err(t, st.Modify(nil), regexp.MustCompile("empty ApplicationID")) }
func TestEmptyRestAPIKey(t *testing.T) { t.Parallel() mk := parse.RestAPIKey{ApplicationID: defaultApplicationID} ensure.Err(t, mk.Modify(nil), regexp.MustCompile("empty RestAPIKey")) }