示例#1
0
func TestHTTPWithinStopTimeout(t *testing.T) {
	t.Parallel()
	hello := []byte("hello")
	finOkHandler := make(chan struct{})
	okHandler := func(w http.ResponseWriter, r *http.Request) {
		defer close(finOkHandler)
		w.WriteHeader(200)
		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}
	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())
	}()

	actualBody, err := ioutil.ReadAll(res.Body)
	ensure.Nil(t, err)
	ensure.DeepEqual(t, actualBody, hello)
	ensure.Nil(t, res.Body.Close())
	<-finOkHandler
	<-finStop
}
示例#2
0
func TestExistingConnState(t *testing.T) {
	t.Parallel()
	hello := []byte("hello")
	fin := make(chan struct{})
	okHandler := func(w http.ResponseWriter, r *http.Request) {
		defer close(fin)
		w.Write(hello)
	}

	var called int32
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	ensure.Nil(t, err)
	server := &http.Server{
		Handler: http.HandlerFunc(okHandler),
		ConnState: func(c net.Conn, s http.ConnState) {
			atomic.AddInt32(&called, 1)
		},
	}
	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)
	actualBody, err := ioutil.ReadAll(res.Body)
	ensure.Nil(t, err)
	ensure.DeepEqual(t, actualBody, hello)
	ensure.Nil(t, res.Body.Close())

	ensure.Nil(t, s.Stop())
	<-fin

	ensure.True(t, atomic.LoadInt32(&called) > 0)
}
示例#3
0
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
}
示例#4
0
func TestDoubleStop(t *testing.T) {
	t.Parallel()
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	ensure.Nil(t, err)
	server := &http.Server{}
	down := &httpdown.HTTP{}
	s := down.Serve(server, listener)
	ensure.Nil(t, s.Stop())
	ensure.Nil(t, s.Stop())
}
示例#5
0
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
}
示例#6
0
func TestHTTPServeError(t *testing.T) {
	t.Parallel()
	expectedError := errors.New("foo")
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	errChan := make(chan error)
	listener = &acceptErrListener{Listener: listener, err: errChan}
	ensure.Nil(t, err)
	server := &http.Server{}
	down := &httpdown.HTTP{}
	s := down.Serve(server, listener)
	errChan <- expectedError
	ensure.DeepEqual(t, s.Wait(), expectedError)
	ensure.Nil(t, s.Stop())
}
示例#7
0
func TestMuxContextMakerError(t *testing.T) {
	givenErr := errors.New("")
	var actualErr error
	mux, err := ctxmux.New(
		ctxmux.MuxContextMaker(func(r *http.Request) (context.Context, error) {
			return nil, givenErr
		}),
		ctxmux.MuxErrorHandler(
			func(ctx context.Context, w http.ResponseWriter, r *http.Request, err error) {
				ensure.DeepEqual(t, ctx, context.Background())
				actualErr = err
			}),
	)
	ensure.Nil(t, err)
	hw := httptest.NewRecorder()
	hr := &http.Request{
		Method: "GET",
		URL: &url.URL{
			Path: "/",
		},
	}
	mux.GET(hr.URL.Path, func(context.Context, http.ResponseWriter, *http.Request) error {
		panic("not reached")
	})
	mux.ServeHTTP(hw, hr)
	ensure.DeepEqual(t, actualErr, givenErr)
}
示例#8
0
func TestServerAbort(t *testing.T) {
	t.Parallel()
	for _, code := range []int{200, 500} {
		server := httptest.NewServer(
			http.HandlerFunc(
				func(w http.ResponseWriter, r *http.Request) {
					w.Header().Add("Content-Length", "4000")
					w.WriteHeader(code)
					w.Write(bytes.Repeat([]byte("a"), 3000))
				},
			),
		)

		u, err := url.Parse(server.URL)
		ensure.Nil(t, err)

		c := &parse.Client{
			Credentials: defaultRestAPIKey,
			BaseURL:     u,
		}
		res := make(map[string]interface{})
		_, err = c.Get(nil, res)
		ensure.NotNil(t, err)
		server.CloseClientConnections()
		server.Close()
	}
}
示例#9
0
func TestServeCombinedURLWithExt(t *testing.T) {
	contents := [][]byte{
		[]byte("foo"),
		[]byte("bar"),
	}
	var count int
	h := Handler{
		Path: "/",
		Box: funcBox(func(name string) ([]byte, error) {
			defer func() { count++ }()
			return contents[count], nil
		}),
	}
	v, err := h.URL("n1.js", "n2")
	ensure.Nil(t, err)
	ensure.DeepEqual(t, v, "/W1sibjEuanMiLCJhY2JkMThkYiJdLFsibjIiLCIzN2I1MWQxOSJdXQ.js")
	w := httptest.NewRecorder()
	r := &http.Request{
		URL: &url.URL{
			Path: v,
		},
	}
	h.ServeHTTP(w, r)
	ensure.DeepEqual(t, w.Code, http.StatusOK)
	ensure.DeepEqual(t, w.Body.String(), "foobar")
	ensure.DeepEqual(t, w.Header(), http.Header{
		"Content-Length": []string{"6"},
		"Cache-Control":  []string{cacheControl},
		"Content-Type":   []string{"application/javascript"},
	})
}
示例#10
0
func TestServerAbort(t *testing.T) {
	t.Parallel()
	for _, code := range []int{200, 500} {
		server := httptest.NewServer(
			http.HandlerFunc(
				func(w http.ResponseWriter, r *http.Request) {
					w.Header().Add("Content-Length", "4000")
					w.WriteHeader(code)
					w.Write(bytes.Repeat([]byte("a"), 3000))
				},
			),
		)

		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.NotNil(t, err)
		ensure.StringContains(t, err.Error(), fmt.Sprintf(`GET %s`, server.URL))
		server.CloseClientConnections()
		server.Close()
	}
}
示例#11
0
func TestDecodeMultiple(t *testing.T) {
	value, err := decode("W1siZm9vMSIsImJhcjEiXSxbImZvbzIiLCJiYXIyIl1d")
	ensure.Nil(t, err)
	ensure.DeepEqual(t, value, []file{
		{Name: "foo1", Hash: "bar1"},
		{Name: "foo2", Hash: "bar2"},
	})
}
示例#12
0
func TestNilStruct(t *testing.T) {
	var c capture
	ensure.Nil(&c, typ{})
	c.Equal(t, `ensure_test.go:131: expected nil value but got:
(ensure_test.typ) {
 Answer: (int) 0
}`)
}
示例#13
0
func TestEncodeMultiple(t *testing.T) {
	files := []file{
		{Name: "foo1", Hash: "bar1"},
		{Name: "foo2", Hash: "bar2"},
	}
	value, err := encode(files)
	ensure.Nil(t, err)
	ensure.DeepEqual(t, value, "W1siZm9vMSIsImJhcjEiXSxbImZvbzIiLCJiYXIyIl1d")
}
示例#14
0
func TestExplicitAreIgnored(t *testing.T) {
	const name = "TestExplicitAreIgnored"
	s := flag.NewFlagSet(name, flag.PanicOnError)
	const bar = int(43)
	barActual := s.Int("bar", 0, "")
	s.Parse([]string{"-bar", fmt.Sprint(bar)})
	os.Setenv(named(name, "bar"), "44")
	ensure.Nil(t, flagenv.ParseSet(name, s))
	ensure.DeepEqual(t, *barActual, bar)
}
示例#15
0
func TestSimple(t *testing.T) {
	t.Parallel()
	var out bytes.Buffer
	w := htmlwriter.New(&out)
	const original = "hello & world"
	n, err := w.Write([]byte(original))
	ensure.Nil(t, err)
	ensure.DeepEqual(t, n, 17)
	ensure.DeepEqual(t, out.String(), html.EscapeString(original))
}
示例#16
0
func TestLoadFromCache(t *testing.T) {
	const magic = "foo"
	h := Handler{
		Box: funcBox(func(name string) ([]byte, error) {
			ensure.DeepEqual(t, name, magic)
			return []byte(magic), nil
		}),
	}
	f, err := h.load(magic)
	ensure.Nil(t, err)
	ensure.DeepEqual(t, f, file{
		Name:    magic,
		Content: []byte(magic),
		Hash:    "acbd18db",
	})
	h.Box = nil
	f2, err := h.load(magic)
	ensure.Nil(t, err)
	ensure.DeepEqual(t, f2, f)
}
示例#17
0
func TestHTTPListenerCloseError(t *testing.T) {
	t.Parallel()
	expectedError := errors.New("foo")
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	listener = &closeErrListener{Listener: listener, err: expectedError}
	ensure.Nil(t, err)
	server := &http.Server{}
	down := &httpdown.HTTP{}
	s := down.Serve(server, listener)
	ensure.DeepEqual(t, s.Stop(), expectedError)
}
示例#18
0
func TestRestAPIKeyModify(t *testing.T) {
	t.Parallel()
	var req http.Request
	k := parse.RestAPIKey{
		ApplicationID: defaultApplicationID,
		RestAPIKey:    "42",
	}
	ensure.Nil(t, k.Modify(&req))
	ensure.DeepEqual(t, req.Header.Get("X-Parse-Application-ID"), k.ApplicationID)
	ensure.DeepEqual(t, req.Header.Get("X-Parse-REST-API-Key"), k.RestAPIKey)
}
示例#19
0
func TestHTTPStopWithFinishedRequest(t *testing.T) {
	t.Parallel()
	hello := []byte("hello")
	fin := make(chan struct{})
	okHandler := func(w http.ResponseWriter, r *http.Request) {
		defer close(fin)
		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{}
	s := down.Serve(server, listener)
	res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String()))
	ensure.Nil(t, err)
	actualBody, err := ioutil.ReadAll(res.Body)
	ensure.Nil(t, err)
	ensure.DeepEqual(t, actualBody, hello)
	ensure.Nil(t, res.Body.Close())

	// At this point the request is finished, and the connection should be alive
	// but idle (because we have keep alive enabled by default in our Transport).
	ensure.Nil(t, s.Stop())
	<-fin

	ensure.Nil(t, s.Wait())
}
示例#20
0
func TestAFewFlags(t *testing.T) {
	const name = "TestAFewFlags"
	s := flag.NewFlagSet(name, flag.PanicOnError)
	const foo = "42"
	const bar = int(43)
	fooActual := s.String("foo", "", "")
	barActual := s.Int("bar", 0, "")
	os.Setenv(named(name, "foo"), foo)
	os.Setenv(named(name, "bar"), fmt.Sprint(bar))
	ensure.Nil(t, flagenv.ParseSet(name, s))
	ensure.DeepEqual(t, *fooActual, foo)
	ensure.DeepEqual(t, *barActual, bar)
}
示例#21
0
func TestSessionTokenModify(t *testing.T) {
	t.Parallel()
	st := parse.SessionToken{
		ApplicationID: defaultApplicationID,
		RestAPIKey:    "42",
		SessionToken:  "43",
	}
	var req http.Request
	ensure.Nil(t, st.Modify(&req))
	ensure.DeepEqual(t, req.Header.Get("X-Parse-Application-ID"), st.ApplicationID)
	ensure.DeepEqual(t, req.Header.Get("X-Parse-REST-API-Key"), st.RestAPIKey)
	ensure.DeepEqual(t, req.Header.Get("X-Parse-Session-Token"), st.SessionToken)
}
示例#22
0
func TestHTTPHandlerFunc(t *testing.T) {
	w := httptest.NewRecorder()
	r := &http.Request{}
	var actualW http.ResponseWriter
	var actualR *http.Request
	h := ctxmux.HTTPHandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		actualW = w
		actualR = r
	})
	ensure.Nil(t, h(nil, w, r))
	ensure.DeepEqual(t, actualW, w)
	ensure.DeepEqual(t, actualR, r)
}
示例#23
0
func TestPublicGetDiscardBody(t *testing.T) {
	t.Parallel()
	res, err := defaultFbClient.Do(
		&http.Request{
			Method: "GET",
			URL: &url.URL{
				Path: "5526183",
			},
		},
		nil,
	)
	ensure.Nil(t, err)
	ensure.DeepEqual(t, res.StatusCode, 200)
}
示例#24
0
func TestLinkStyleInvalidHREF(t *testing.T) {
	givenErr := errors.New("")
	l := LinkStyle{
		Handler: &Handler{
			Box: funcBox(func(name string) ([]byte, error) {
				return nil, givenErr
			}),
		},
		HREF: []string{"foo"},
	}
	v, err := l.HTML()
	ensure.Nil(t, v)
	ensure.DeepEqual(t, err, givenErr)
}
示例#25
0
func TestImgInvalidSrc(t *testing.T) {
	givenErr := errors.New("")
	l := Img{
		Handler: &Handler{
			Box: funcBox(func(name string) ([]byte, error) {
				return nil, givenErr
			}),
		},
		Src: "foo",
	}
	v, err := l.HTML()
	ensure.Nil(t, v)
	ensure.DeepEqual(t, err, givenErr)
}
示例#26
0
func TestLinkStyle(t *testing.T) {
	l := LinkStyle{
		Handler: &Handler{
			Box: funcBox(func(name string) ([]byte, error) {
				return []byte("foo"), nil
			}),
		},
		HREF: []string{"foo"},
	}
	v, err := l.HTML()
	ensure.Nil(t, err)
	ensure.DeepEqual(t, v, &h.LinkStyle{
		HREF: "W1siZm9vIiwiYWNiZDE4ZGIiXV0",
	})
}
示例#27
0
func TestHTTPStopWithNoRequest(t *testing.T) {
	t.Parallel()
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	ensure.Nil(t, err)

	statsDone := make(chan struct{}, 2)
	hc := &stats.HookClient{
		BumpSumHook: func(key string, val float64) {
			if key == "serve" && val == 1 {
				statsDone <- struct{}{}
			}
			if key == "stop" && val == 1 {
				statsDone <- struct{}{}
			}
		},
	}

	server := &http.Server{}
	down := &httpdown.HTTP{Stats: hc}
	s := down.Serve(server, listener)
	ensure.Nil(t, s.Stop())
	<-statsDone
	<-statsDone
}
示例#28
0
func TestScriptInvalidSrc(t *testing.T) {
	givenErr := errors.New("")
	h := Handler{
		Box: funcBox(func(name string) ([]byte, error) {
			return nil, givenErr
		}),
	}
	l := Script{
		Handler: &h,
		Src:     []string{"foo"},
	}
	v, err := l.HTML()
	ensure.Nil(t, v)
	ensure.DeepEqual(t, err, givenErr)
}
示例#29
0
func TestCombinedURLExt(t *testing.T) {
	contents := [][]byte{
		[]byte("foo"),
		[]byte("bar"),
	}
	var count int
	h := Handler{
		Box: funcBox(func(name string) ([]byte, error) {
			defer func() { count++ }()
			return contents[count], nil
		}),
	}
	v, err := h.URL("n1.js", "n2")
	ensure.Nil(t, err)
	ensure.DeepEqual(t, v, "W1sibjEuanMiLCJhY2JkMThkYiJdLFsibjIiLCIzN2I1MWQxOSJdXQ.js")
}
示例#30
0
func TestSuccessfulRequest(t *testing.T) {
	t.Parallel()
	expected := map[string]int{"answer": 42}
	c := &parse.Client{
		Transport: transportFunc(func(r *http.Request) (*http.Response, error) {
			return &http.Response{
				StatusCode: http.StatusOK,
				Body:       ioutil.NopCloser(bytes.NewReader(jsonB(t, expected))),
			}, nil
		}),
	}
	var m map[string]int
	_, err := c.Post(nil, true, &m)
	ensure.Nil(t, err)
	ensure.DeepEqual(t, m, expected)
}