github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/src/net/http/export_test.go (about)

     1  // Copyright 2011 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Bridge package to expose http internals to tests in the http_test
     6  // package.
     7  
     8  package http
     9  
    10  import (
    11  	"net"
    12  	"sync"
    13  	"time"
    14  )
    15  
    16  var (
    17  	DefaultUserAgent              = defaultUserAgent
    18  	NewLoggingConn                = newLoggingConn
    19  	ExportAppendTime              = appendTime
    20  	ExportRefererForURL           = refererForURL
    21  	ExportServerNewConn           = (*Server).newConn
    22  	ExportCloseWriteAndWait       = (*conn).closeWriteAndWait
    23  	ExportErrRequestCanceled      = errRequestCanceled
    24  	ExportServeFile               = serveFile
    25  	ExportHttp2ConfigureTransport = http2ConfigureTransport
    26  	ExportHttp2ConfigureServer    = http2ConfigureServer
    27  )
    28  
    29  func init() {
    30  	// We only want to pay for this cost during testing.
    31  	// When not under test, these values are always nil
    32  	// and never assigned to.
    33  	testHookMu = new(sync.Mutex)
    34  }
    35  
    36  var (
    37  	SetEnterRoundTripHook  = hookSetter(&testHookEnterRoundTrip)
    38  	SetTestHookWaitResLoop = hookSetter(&testHookWaitResLoop)
    39  	SetRoundTripRetried    = hookSetter(&testHookRoundTripRetried)
    40  )
    41  
    42  func SetReadLoopBeforeNextReadHook(f func()) {
    43  	testHookMu.Lock()
    44  	defer testHookMu.Unlock()
    45  	unnilTestHook(&f)
    46  	testHookReadLoopBeforeNextRead = f
    47  }
    48  
    49  // SetPendingDialHooks sets the hooks that run before and after handling
    50  // pending dials.
    51  func SetPendingDialHooks(before, after func()) {
    52  	unnilTestHook(&before)
    53  	unnilTestHook(&after)
    54  	testHookPrePendingDial, testHookPostPendingDial = before, after
    55  }
    56  
    57  func SetTestHookServerServe(fn func(*Server, net.Listener)) { testHookServerServe = fn }
    58  
    59  func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
    60  	return &timeoutHandler{
    61  		handler: handler,
    62  		timeout: func() <-chan time.Time { return ch },
    63  		// (no body and nil cancelTimer)
    64  	}
    65  }
    66  
    67  func ResetCachedEnvironment() {
    68  	httpProxyEnv.reset()
    69  	httpsProxyEnv.reset()
    70  	noProxyEnv.reset()
    71  }
    72  
    73  func (t *Transport) NumPendingRequestsForTesting() int {
    74  	t.reqMu.Lock()
    75  	defer t.reqMu.Unlock()
    76  	return len(t.reqCanceler)
    77  }
    78  
    79  func (t *Transport) IdleConnKeysForTesting() (keys []string) {
    80  	keys = make([]string, 0)
    81  	t.idleMu.Lock()
    82  	defer t.idleMu.Unlock()
    83  	if t.idleConn == nil {
    84  		return
    85  	}
    86  	for key := range t.idleConn {
    87  		keys = append(keys, key.String())
    88  	}
    89  	return
    90  }
    91  
    92  func (t *Transport) IdleConnCountForTesting(cacheKey string) int {
    93  	t.idleMu.Lock()
    94  	defer t.idleMu.Unlock()
    95  	if t.idleConn == nil {
    96  		return 0
    97  	}
    98  	for k, conns := range t.idleConn {
    99  		if k.String() == cacheKey {
   100  			return len(conns)
   101  		}
   102  	}
   103  	return 0
   104  }
   105  
   106  func (t *Transport) IdleConnChMapSizeForTesting() int {
   107  	t.idleMu.Lock()
   108  	defer t.idleMu.Unlock()
   109  	return len(t.idleConnCh)
   110  }
   111  
   112  func (t *Transport) IsIdleForTesting() bool {
   113  	t.idleMu.Lock()
   114  	defer t.idleMu.Unlock()
   115  	return t.wantIdle
   116  }
   117  
   118  func (t *Transport) RequestIdleConnChForTesting() {
   119  	t.getIdleConnCh(connectMethod{nil, "http", "example.com"})
   120  }
   121  
   122  func (t *Transport) PutIdleTestConn() bool {
   123  	c, _ := net.Pipe()
   124  	return t.putIdleConn(&persistConn{
   125  		t:        t,
   126  		conn:     c,                   // dummy
   127  		closech:  make(chan struct{}), // so it can be closed
   128  		cacheKey: connectMethodKey{"", "http", "example.com"},
   129  	})
   130  }
   131  
   132  // All test hooks must be non-nil so they can be called directly,
   133  // but the tests use nil to mean hook disabled.
   134  func unnilTestHook(f *func()) {
   135  	if *f == nil {
   136  		*f = nop
   137  	}
   138  }
   139  
   140  func hookSetter(dst *func()) func(func()) {
   141  	return func(fn func()) {
   142  		unnilTestHook(&fn)
   143  		*dst = fn
   144  	}
   145  }