blob: 8f3a124d273b452bcf4d642fa3fdb738d135b1d0 [file] [log] [blame]
// Copyright 2012 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package runtime
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/golang/protobuf/proto"
"golang.org/x/net/context"
"google.golang.org/appengine/internal/aetesting"
pb "google.golang.org/appengine/internal/system"
)
func TestRunInBackgroundSendFirst(t *testing.T) { testRunInBackground(t, true) }
func TestRunInBackgroundRecvFirst(t *testing.T) { testRunInBackground(t, false) }
func testRunInBackground(t *testing.T, sendFirst bool) {
srv := httptest.NewServer(nil)
defer srv.Close()
const id = "f00bar"
sendWait, recvWait := make(chan bool), make(chan bool)
sbr := make(chan bool) // strobed when system.StartBackgroundRequest has started
calls := 0
c := aetesting.FakeSingleContext(t, "system", "StartBackgroundRequest", func(req *pb.StartBackgroundRequestRequest, res *pb.StartBackgroundRequestResponse) error {
calls++
if calls > 1 {
t.Errorf("Too many calls to system.StartBackgroundRequest")
}
sbr <- true
res.RequestId = proto.String(id)
<-sendWait
return nil
})
var c2 context.Context // a fake
newContext = func(*http.Request) context.Context {
return c2
}
var fRun int
f := func(c3 context.Context) {
fRun++
if c3 != c2 {
t.Errorf("f got a different context than expected")
}
}
ribErrc := make(chan error)
go func() {
ribErrc <- RunInBackground(c, f)
}()
brErrc := make(chan error)
go func() {
<-sbr
req, err := http.NewRequest("GET", srv.URL+"/_ah/background", nil)
if err != nil {
brErrc <- fmt.Errorf("http.NewRequest: %v", err)
return
}
req.Header.Set("X-AppEngine-BackgroundRequest", id)
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
},
}
<-recvWait
_, err = client.Do(req)
brErrc <- err
}()
// Send and receive are both waiting at this point.
waits := [2]chan bool{sendWait, recvWait}
if !sendFirst {
waits[0], waits[1] = waits[1], waits[0]
}
waits[0] <- true
time.Sleep(100 * time.Millisecond)
waits[1] <- true
if err := <-ribErrc; err != nil {
t.Fatalf("RunInBackground: %v", err)
}
if err := <-brErrc; err != nil {
t.Fatalf("background request: %v", err)
}
if fRun != 1 {
t.Errorf("Got %d runs of f, want 1", fRun)
}
}