mirror of
https://github.com/minio/minio.git
synced 2025-11-11 14:30:17 -05:00
Migrate this project to minio micro services code
This commit is contained in:
536
vendor/github.com/facebookgo/clock/clock_test.go
generated
vendored
536
vendor/github.com/facebookgo/clock/clock_test.go
generated
vendored
@@ -1,536 +0,0 @@
|
||||
package clock_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/facebookgo/clock"
|
||||
)
|
||||
|
||||
// Ensure that the clock's After channel sends at the correct time.
|
||||
func TestClock_After(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
<-clock.New().After(20 * time.Millisecond)
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's AfterFunc executes at the correct time.
|
||||
func TestClock_AfterFunc(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
clock.New().AfterFunc(20*time.Millisecond, func() {
|
||||
wg.Done()
|
||||
})
|
||||
wg.Wait()
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's time matches the standary library.
|
||||
func TestClock_Now(t *testing.T) {
|
||||
a := time.Now().Round(time.Second)
|
||||
b := clock.New().Now().Round(time.Second)
|
||||
if !a.Equal(b) {
|
||||
t.Errorf("not equal: %s != %s", a, b)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock sleeps for the appropriate amount of time.
|
||||
func TestClock_Sleep(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
clock.New().Sleep(20 * time.Millisecond)
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock ticks correctly.
|
||||
func TestClock_Tick(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
c := clock.New().Tick(20 * time.Millisecond)
|
||||
<-c
|
||||
<-c
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's ticker ticks correctly.
|
||||
func TestClock_Ticker(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
ticker := clock.New().Ticker(50 * time.Millisecond)
|
||||
<-ticker.C
|
||||
<-ticker.C
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's ticker can stop correctly.
|
||||
func TestClock_Ticker_Stp(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
gosched()
|
||||
|
||||
ticker := clock.New().Ticker(20 * time.Millisecond)
|
||||
<-ticker.C
|
||||
ticker.Stop()
|
||||
select {
|
||||
case <-ticker.C:
|
||||
t.Fatal("unexpected send")
|
||||
case <-time.After(30 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's timer waits correctly.
|
||||
func TestClock_Timer(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
timer := clock.New().Timer(20 * time.Millisecond)
|
||||
<-timer.C
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's timer can be stopped.
|
||||
func TestClock_Timer_Stop(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
|
||||
timer := clock.New().Timer(20 * time.Millisecond)
|
||||
timer.Stop()
|
||||
select {
|
||||
case <-timer.C:
|
||||
t.Fatal("unexpected send")
|
||||
case <-time.After(30 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's After channel sends at the correct time.
|
||||
func TestMock_After(t *testing.T) {
|
||||
var ok int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Create a channel to execute after 10 mock seconds.
|
||||
ch := clock.After(10 * time.Second)
|
||||
go func(ch <-chan time.Time) {
|
||||
<-ch
|
||||
atomic.StoreInt32(&ok, 1)
|
||||
}(ch)
|
||||
|
||||
// Move clock forward to just before the time.
|
||||
clock.Add(9 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 1 {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
|
||||
// Move clock forward to the after channel's time.
|
||||
clock.Add(1 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 0 {
|
||||
t.Fatal("too late")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's AfterFunc executes at the correct time.
|
||||
func TestMock_AfterFunc(t *testing.T) {
|
||||
var ok int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Execute function after duration.
|
||||
clock.AfterFunc(10*time.Second, func() {
|
||||
atomic.StoreInt32(&ok, 1)
|
||||
})
|
||||
|
||||
// Move clock forward to just before the time.
|
||||
clock.Add(9 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 1 {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
|
||||
// Move clock forward to the after channel's time.
|
||||
clock.Add(1 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 0 {
|
||||
t.Fatal("too late")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's AfterFunc doesn't execute if stopped.
|
||||
func TestMock_AfterFunc_Stop(t *testing.T) {
|
||||
// Execute function after duration.
|
||||
clock := clock.NewMock()
|
||||
timer := clock.AfterFunc(10*time.Second, func() {
|
||||
t.Fatal("unexpected function execution")
|
||||
})
|
||||
gosched()
|
||||
|
||||
// Stop timer & move clock forward.
|
||||
timer.Stop()
|
||||
clock.Add(10 * time.Second)
|
||||
gosched()
|
||||
}
|
||||
|
||||
// Ensure that the mock's current time can be changed.
|
||||
func TestMock_Now(t *testing.T) {
|
||||
clock := clock.NewMock()
|
||||
if now := clock.Now(); !now.Equal(time.Unix(0, 0)) {
|
||||
t.Fatalf("expected epoch, got: ", now)
|
||||
}
|
||||
|
||||
// Add 10 seconds and check the time.
|
||||
clock.Add(10 * time.Second)
|
||||
if now := clock.Now(); !now.Equal(time.Unix(10, 0)) {
|
||||
t.Fatalf("expected epoch, got: ", now)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock can sleep for the correct time.
|
||||
func TestMock_Sleep(t *testing.T) {
|
||||
var ok int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Create a channel to execute after 10 mock seconds.
|
||||
go func() {
|
||||
clock.Sleep(10 * time.Second)
|
||||
atomic.StoreInt32(&ok, 1)
|
||||
}()
|
||||
gosched()
|
||||
|
||||
// Move clock forward to just before the sleep duration.
|
||||
clock.Add(9 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 1 {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
|
||||
// Move clock forward to the after the sleep duration.
|
||||
clock.Add(1 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 0 {
|
||||
t.Fatal("too late")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's Tick channel sends at the correct time.
|
||||
func TestMock_Tick(t *testing.T) {
|
||||
var n int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Create a channel to increment every 10 seconds.
|
||||
go func() {
|
||||
tick := clock.Tick(10 * time.Second)
|
||||
for {
|
||||
<-tick
|
||||
atomic.AddInt32(&n, 1)
|
||||
}
|
||||
}()
|
||||
gosched()
|
||||
|
||||
// Move clock forward to just before the first tick.
|
||||
clock.Add(9 * time.Second)
|
||||
if atomic.LoadInt32(&n) != 0 {
|
||||
t.Fatalf("expected 0, got %d", n)
|
||||
}
|
||||
|
||||
// Move clock forward to the start of the first tick.
|
||||
clock.Add(1 * time.Second)
|
||||
if atomic.LoadInt32(&n) != 1 {
|
||||
t.Fatalf("expected 1, got %d", n)
|
||||
}
|
||||
|
||||
// Move clock forward over several ticks.
|
||||
clock.Add(30 * time.Second)
|
||||
if atomic.LoadInt32(&n) != 4 {
|
||||
t.Fatalf("expected 4, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's Ticker channel sends at the correct time.
|
||||
func TestMock_Ticker(t *testing.T) {
|
||||
var n int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Create a channel to increment every microsecond.
|
||||
go func() {
|
||||
ticker := clock.Ticker(1 * time.Microsecond)
|
||||
for {
|
||||
<-ticker.C
|
||||
atomic.AddInt32(&n, 1)
|
||||
}
|
||||
}()
|
||||
gosched()
|
||||
|
||||
// Move clock forward.
|
||||
clock.Add(10 * time.Microsecond)
|
||||
if atomic.LoadInt32(&n) != 10 {
|
||||
t.Fatalf("unexpected: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's Ticker channel won't block if not read from.
|
||||
func TestMock_Ticker_Overflow(t *testing.T) {
|
||||
clock := clock.NewMock()
|
||||
ticker := clock.Ticker(1 * time.Microsecond)
|
||||
clock.Add(10 * time.Microsecond)
|
||||
ticker.Stop()
|
||||
}
|
||||
|
||||
// Ensure that the mock's Ticker can be stopped.
|
||||
func TestMock_Ticker_Stop(t *testing.T) {
|
||||
var n int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Create a channel to increment every second.
|
||||
ticker := clock.Ticker(1 * time.Second)
|
||||
go func() {
|
||||
for {
|
||||
<-ticker.C
|
||||
atomic.AddInt32(&n, 1)
|
||||
}
|
||||
}()
|
||||
gosched()
|
||||
|
||||
// Move clock forward.
|
||||
clock.Add(5 * time.Second)
|
||||
if atomic.LoadInt32(&n) != 5 {
|
||||
t.Fatalf("expected 5, got: %d", n)
|
||||
}
|
||||
|
||||
ticker.Stop()
|
||||
|
||||
// Move clock forward again.
|
||||
clock.Add(5 * time.Second)
|
||||
if atomic.LoadInt32(&n) != 5 {
|
||||
t.Fatalf("still expected 5, got: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that multiple tickers can be used together.
|
||||
func TestMock_Ticker_Multi(t *testing.T) {
|
||||
var n int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
go func() {
|
||||
a := clock.Ticker(1 * time.Microsecond)
|
||||
b := clock.Ticker(3 * time.Microsecond)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-a.C:
|
||||
atomic.AddInt32(&n, 1)
|
||||
case <-b.C:
|
||||
atomic.AddInt32(&n, 100)
|
||||
}
|
||||
}
|
||||
}()
|
||||
gosched()
|
||||
|
||||
// Move clock forward.
|
||||
clock.Add(10 * time.Microsecond)
|
||||
gosched()
|
||||
if atomic.LoadInt32(&n) != 310 {
|
||||
t.Fatalf("unexpected: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleMock_After() {
|
||||
// Create a new mock clock.
|
||||
clock := clock.NewMock()
|
||||
count := 0
|
||||
|
||||
// Create a channel to execute after 10 mock seconds.
|
||||
go func() {
|
||||
<-clock.After(10 * time.Second)
|
||||
count = 100
|
||||
}()
|
||||
runtime.Gosched()
|
||||
|
||||
// Print the starting value.
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Move the clock forward 5 seconds and print the value again.
|
||||
clock.Add(5 * time.Second)
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Move the clock forward 5 seconds to the tick time and check the value.
|
||||
clock.Add(5 * time.Second)
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Output:
|
||||
// 1970-01-01 00:00:00 +0000 UTC: 0
|
||||
// 1970-01-01 00:00:05 +0000 UTC: 0
|
||||
// 1970-01-01 00:00:10 +0000 UTC: 100
|
||||
}
|
||||
|
||||
func ExampleMock_AfterFunc() {
|
||||
// Create a new mock clock.
|
||||
clock := clock.NewMock()
|
||||
count := 0
|
||||
|
||||
// Execute a function after 10 mock seconds.
|
||||
clock.AfterFunc(10*time.Second, func() {
|
||||
count = 100
|
||||
})
|
||||
runtime.Gosched()
|
||||
|
||||
// Print the starting value.
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Move the clock forward 10 seconds and print the new value.
|
||||
clock.Add(10 * time.Second)
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Output:
|
||||
// 1970-01-01 00:00:00 +0000 UTC: 0
|
||||
// 1970-01-01 00:00:10 +0000 UTC: 100
|
||||
}
|
||||
|
||||
func ExampleMock_Sleep() {
|
||||
// Create a new mock clock.
|
||||
clock := clock.NewMock()
|
||||
count := 0
|
||||
|
||||
// Execute a function after 10 mock seconds.
|
||||
go func() {
|
||||
clock.Sleep(10 * time.Second)
|
||||
count = 100
|
||||
}()
|
||||
runtime.Gosched()
|
||||
|
||||
// Print the starting value.
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Move the clock forward 10 seconds and print the new value.
|
||||
clock.Add(10 * time.Second)
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Output:
|
||||
// 1970-01-01 00:00:00 +0000 UTC: 0
|
||||
// 1970-01-01 00:00:10 +0000 UTC: 100
|
||||
}
|
||||
|
||||
func ExampleMock_Ticker() {
|
||||
// Create a new mock clock.
|
||||
clock := clock.NewMock()
|
||||
count := 0
|
||||
|
||||
// Increment count every mock second.
|
||||
go func() {
|
||||
ticker := clock.Ticker(1 * time.Second)
|
||||
for {
|
||||
<-ticker.C
|
||||
count++
|
||||
}
|
||||
}()
|
||||
runtime.Gosched()
|
||||
|
||||
// Move the clock forward 10 seconds and print the new value.
|
||||
clock.Add(10 * time.Second)
|
||||
fmt.Printf("Count is %d after 10 seconds\n", count)
|
||||
|
||||
// Move the clock forward 5 more seconds and print the new value.
|
||||
clock.Add(5 * time.Second)
|
||||
fmt.Printf("Count is %d after 15 seconds\n", count)
|
||||
|
||||
// Output:
|
||||
// Count is 10 after 10 seconds
|
||||
// Count is 15 after 15 seconds
|
||||
}
|
||||
|
||||
func ExampleMock_Timer() {
|
||||
// Create a new mock clock.
|
||||
clock := clock.NewMock()
|
||||
count := 0
|
||||
|
||||
// Increment count after a mock second.
|
||||
go func() {
|
||||
timer := clock.Timer(1 * time.Second)
|
||||
<-timer.C
|
||||
count++
|
||||
}()
|
||||
runtime.Gosched()
|
||||
|
||||
// Move the clock forward 10 seconds and print the new value.
|
||||
clock.Add(10 * time.Second)
|
||||
fmt.Printf("Count is %d after 10 seconds\n", count)
|
||||
|
||||
// Output:
|
||||
// Count is 1 after 10 seconds
|
||||
}
|
||||
|
||||
func warn(v ...interface{}) { fmt.Fprintln(os.Stderr, v...) }
|
||||
func warnf(msg string, v ...interface{}) { fmt.Fprintf(os.Stderr, msg+"\n", v...) }
|
||||
|
||||
func gosched() { time.Sleep(1 * time.Millisecond) }
|
||||
677
vendor/github.com/facebookgo/httpdown/httpdown_test.go
generated
vendored
677
vendor/github.com/facebookgo/httpdown/httpdown_test.go
generated
vendored
@@ -1,677 +0,0 @@
|
||||
package httpdown_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/facebookgo/clock"
|
||||
"github.com/facebookgo/ensure"
|
||||
"github.com/facebookgo/freeport"
|
||||
"github.com/facebookgo/httpdown"
|
||||
"github.com/facebookgo/stats"
|
||||
)
|
||||
|
||||
type onCloseListener struct {
|
||||
net.Listener
|
||||
mutex sync.Mutex
|
||||
onClose chan struct{}
|
||||
}
|
||||
|
||||
func (o *onCloseListener) Close() error {
|
||||
// Listener is closed twice, once by Grace, and once by the http library, so
|
||||
// we guard against a double close of the chan.
|
||||
defer func() {
|
||||
o.mutex.Lock()
|
||||
defer o.mutex.Unlock()
|
||||
if o.onClose != nil {
|
||||
close(o.onClose)
|
||||
o.onClose = nil
|
||||
}
|
||||
}()
|
||||
return o.Listener.Close()
|
||||
}
|
||||
|
||||
func NewOnCloseListener(l net.Listener) (net.Listener, chan struct{}) {
|
||||
c := make(chan struct{})
|
||||
return &onCloseListener{Listener: l, onClose: c}, c
|
||||
}
|
||||
|
||||
type closeErrListener struct {
|
||||
net.Listener
|
||||
err error
|
||||
}
|
||||
|
||||
func (c *closeErrListener) Close() error {
|
||||
c.Listener.Close()
|
||||
return c.err
|
||||
}
|
||||
|
||||
type acceptErrListener struct {
|
||||
net.Listener
|
||||
err chan error
|
||||
}
|
||||
|
||||
func (c *acceptErrListener) Accept() (net.Conn, error) {
|
||||
return nil, <-c.err
|
||||
}
|
||||
|
||||
type closeErrConn struct {
|
||||
net.Conn
|
||||
unblockClose chan chan struct{}
|
||||
}
|
||||
|
||||
func (c *closeErrConn) Close() error {
|
||||
ch := <-c.unblockClose
|
||||
|
||||
// Close gets called multiple times, but only the first one gets this ch
|
||||
if ch != nil {
|
||||
defer close(ch)
|
||||
}
|
||||
|
||||
return c.Conn.Close()
|
||||
}
|
||||
|
||||
type closeErrConnListener struct {
|
||||
net.Listener
|
||||
unblockClose chan chan struct{}
|
||||
}
|
||||
|
||||
func (l *closeErrConnListener) Accept() (net.Conn, error) {
|
||||
c, err := l.Listener.Accept()
|
||||
if err != nil {
|
||||
return c, err
|
||||
}
|
||||
return &closeErrConn{Conn: c, unblockClose: l.unblockClose}, nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
func TestHTTPStopWithActiveRequest(t *testing.T) {
|
||||
t.Parallel()
|
||||
const count = 10000
|
||||
hello := []byte("hello")
|
||||
finOkHandler := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(finOkHandler)
|
||||
w.WriteHeader(200)
|
||||
for i := 0; i < count; 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{}
|
||||
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, bytes.Repeat(hello, count))
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
<-finOkHandler
|
||||
<-finStop
|
||||
}
|
||||
|
||||
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 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)
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 TestHTTPKillTimeout(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" && 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)
|
||||
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)
|
||||
|
||||
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
|
||||
<-statsDone
|
||||
}
|
||||
|
||||
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 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())
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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 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 TestTLS(t *testing.T) {
|
||||
t.Parallel()
|
||||
port, err := freeport.Get()
|
||||
ensure.Nil(t, err)
|
||||
|
||||
cert, err := tls.X509KeyPair(localhostCert, localhostKey)
|
||||
if err != nil {
|
||||
t.Fatalf("error loading cert: %v", err)
|
||||
}
|
||||
const count = 10000
|
||||
hello := []byte("hello")
|
||||
finOkHandler := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(finOkHandler)
|
||||
w.WriteHeader(200)
|
||||
for i := 0; i < count; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
}
|
||||
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf("0.0.0.0:%d", port),
|
||||
Handler: http.HandlerFunc(okHandler),
|
||||
TLSConfig: &tls.Config{
|
||||
NextProtos: []string{"http/1.1"},
|
||||
Certificates: []tls.Certificate{cert},
|
||||
},
|
||||
}
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
}
|
||||
client := &http.Client{Transport: transport}
|
||||
down := &httpdown.HTTP{}
|
||||
s, err := down.ListenAndServe(server)
|
||||
ensure.Nil(t, err)
|
||||
res, err := client.Get(fmt.Sprintf("https://%s/", server.Addr))
|
||||
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, bytes.Repeat(hello, count))
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
<-finOkHandler
|
||||
<-finStop
|
||||
}
|
||||
|
||||
// localhostCert is a PEM-encoded TLS cert with SAN IPs
|
||||
// "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
|
||||
// of ASN.1 time).
|
||||
// generated from src/pkg/crypto/tls:
|
||||
// go run generate_cert.go --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
|
||||
var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||
MIIBdzCCASOgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
|
||||
bzAeFw03MDAxMDEwMDAwMDBaFw00OTEyMzEyMzU5NTlaMBIxEDAOBgNVBAoTB0Fj
|
||||
bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBALyCfqwwip8BvTKgVKGdmjZTU8DD
|
||||
ndR+WALmFPIRqn89bOU3s30olKiqYEju/SFoEvMyFRT/TWEhXHDaufThqaMCAwEA
|
||||
AaNoMGYwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud
|
||||
EwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAA
|
||||
AAAAAAAAAAAAAAEwCwYJKoZIhvcNAQEFA0EAr/09uy108p51rheIOSnz4zgduyTl
|
||||
M+4AmRo8/U1twEZLgfAGG/GZjREv2y4mCEUIM3HebCAqlA5jpRg76Rf8jw==
|
||||
-----END CERTIFICATE-----`)
|
||||
|
||||
// localhostKey is the private key for localhostCert.
|
||||
var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOQIBAAJBALyCfqwwip8BvTKgVKGdmjZTU8DDndR+WALmFPIRqn89bOU3s30o
|
||||
lKiqYEju/SFoEvMyFRT/TWEhXHDaufThqaMCAwEAAQJAPXuWUxTV8XyAt8VhNQER
|
||||
LgzJcUKb9JVsoS1nwXgPksXnPDKnL9ax8VERrdNr+nZbj2Q9cDSXBUovfdtehcdP
|
||||
qQIhAO48ZsPylbTrmtjDEKiHT2Ik04rLotZYS2U873J6I7WlAiEAypDjYxXyafv/
|
||||
Yo1pm9onwcetQKMW8CS3AjuV9Axzj6cCIEx2Il19fEMG4zny0WPlmbrcKvD/DpJQ
|
||||
4FHrzsYlIVTpAiAas7S1uAvneqd0l02HlN9OxQKKlbUNXNme+rnOnOGS2wIgS0jW
|
||||
zl1jvrOSJeP1PpAHohWz6LOhEr8uvltWkN6x3vE=
|
||||
-----END RSA PRIVATE KEY-----`)
|
||||
77
vendor/github.com/facebookgo/stats/stats_test.go
generated
vendored
77
vendor/github.com/facebookgo/stats/stats_test.go
generated
vendored
@@ -1,77 +0,0 @@
|
||||
package stats_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/facebookgo/ensure"
|
||||
"github.com/facebookgo/stats"
|
||||
)
|
||||
|
||||
// Ensure calling End works even when a BumpTimeHook isn't provided.
|
||||
func TestHookClientBumpTime(t *testing.T) {
|
||||
(&stats.HookClient{}).BumpTime("foo").End()
|
||||
}
|
||||
|
||||
func TestPrefixClient(t *testing.T) {
|
||||
const (
|
||||
prefix1 = "prefix1"
|
||||
prefix2 = "prefix2"
|
||||
avgKey = "avg"
|
||||
avgVal = float64(1)
|
||||
sumKey = "sum"
|
||||
sumVal = float64(2)
|
||||
histogramKey = "histogram"
|
||||
histogramVal = float64(3)
|
||||
timeKey = "time"
|
||||
)
|
||||
|
||||
var keys []string
|
||||
hc := &stats.HookClient{
|
||||
BumpAvgHook: func(key string, val float64) {
|
||||
keys = append(keys, key)
|
||||
ensure.DeepEqual(t, val, avgVal)
|
||||
},
|
||||
BumpSumHook: func(key string, val float64) {
|
||||
keys = append(keys, key)
|
||||
ensure.DeepEqual(t, val, sumVal)
|
||||
},
|
||||
BumpHistogramHook: func(key string, val float64) {
|
||||
keys = append(keys, key)
|
||||
ensure.DeepEqual(t, val, histogramVal)
|
||||
},
|
||||
BumpTimeHook: func(key string) interface {
|
||||
End()
|
||||
} {
|
||||
return multiEnderTest{
|
||||
EndHook: func() {
|
||||
keys = append(keys, key)
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
pc := stats.PrefixClient([]string{prefix1, prefix2}, hc)
|
||||
pc.BumpAvg(avgKey, avgVal)
|
||||
pc.BumpSum(sumKey, sumVal)
|
||||
pc.BumpHistogram(histogramKey, histogramVal)
|
||||
pc.BumpTime(timeKey).End()
|
||||
|
||||
ensure.SameElements(t, keys, []string{
|
||||
prefix1 + avgKey,
|
||||
prefix1 + sumKey,
|
||||
prefix1 + histogramKey,
|
||||
prefix1 + timeKey,
|
||||
prefix2 + avgKey,
|
||||
prefix2 + sumKey,
|
||||
prefix2 + histogramKey,
|
||||
prefix2 + timeKey,
|
||||
})
|
||||
}
|
||||
|
||||
type multiEnderTest struct {
|
||||
EndHook func()
|
||||
}
|
||||
|
||||
func (e multiEnderTest) End() {
|
||||
e.EndHook()
|
||||
}
|
||||
Reference in New Issue
Block a user