1// Copyright 2014 Google Inc. All rights reserved. 2// Use of this source code is governed by the Apache 2.0 3// license that can be found in the LICENSE file. 4 5// +build !appengine 6 7package internal 8 9import ( 10 "sync" 11 "testing" 12 "time" 13 14 netcontext "golang.org/x/net/context" 15 16 basepb "google.golang.org/appengine/internal/base" 17) 18 19func TestDialLimit(t *testing.T) { 20 // Fill up semaphore with false acquisitions to permit only two TCP connections at a time. 21 // We don't replace limitSem because that results in a data race when net/http lazily closes connections. 22 nFake := cap(limitSem) - 2 23 for i := 0; i < nFake; i++ { 24 limitSem <- 1 25 } 26 defer func() { 27 for i := 0; i < nFake; i++ { 28 <-limitSem 29 } 30 }() 31 32 f, c, cleanup := setup() // setup is in api_test.go 33 defer cleanup() 34 f.hang = make(chan int) 35 36 // If we make two RunSlowly RPCs (which will wait for f.hang to be strobed), 37 // then the simple Non200 RPC should hang. 38 var wg sync.WaitGroup 39 wg.Add(2) 40 for i := 0; i < 2; i++ { 41 go func() { 42 defer wg.Done() 43 Call(toContext(c), "errors", "RunSlowly", &basepb.VoidProto{}, &basepb.VoidProto{}) 44 }() 45 } 46 time.Sleep(50 * time.Millisecond) // let those two RPCs start 47 48 ctx, _ := netcontext.WithTimeout(toContext(c), 50*time.Millisecond) 49 err := Call(ctx, "errors", "Non200", &basepb.VoidProto{}, &basepb.VoidProto{}) 50 if err != errTimeout { 51 t.Errorf("Non200 RPC returned with err %v, want errTimeout", err) 52 } 53 54 // Drain the two RunSlowly calls. 55 f.hang <- 1 56 f.hang <- 1 57 wg.Wait() 58} 59