102 lines
2.3 KiB
Go
102 lines
2.3 KiB
Go
|
// 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)
|
||
|
}
|
||
|
}
|