runtime_test.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright 2012 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. package runtime
  5. import (
  6. "fmt"
  7. "net/http"
  8. "net/http/httptest"
  9. "testing"
  10. "time"
  11. "github.com/golang/protobuf/proto"
  12. "golang.org/x/net/context"
  13. "google.golang.org/appengine/internal/aetesting"
  14. pb "google.golang.org/appengine/internal/system"
  15. )
  16. func TestRunInBackgroundSendFirst(t *testing.T) { testRunInBackground(t, true) }
  17. func TestRunInBackgroundRecvFirst(t *testing.T) { testRunInBackground(t, false) }
  18. func testRunInBackground(t *testing.T, sendFirst bool) {
  19. srv := httptest.NewServer(nil)
  20. defer srv.Close()
  21. const id = "f00bar"
  22. sendWait, recvWait := make(chan bool), make(chan bool)
  23. sbr := make(chan bool) // strobed when system.StartBackgroundRequest has started
  24. calls := 0
  25. c := aetesting.FakeSingleContext(t, "system", "StartBackgroundRequest", func(req *pb.StartBackgroundRequestRequest, res *pb.StartBackgroundRequestResponse) error {
  26. calls++
  27. if calls > 1 {
  28. t.Errorf("Too many calls to system.StartBackgroundRequest")
  29. }
  30. sbr <- true
  31. res.RequestId = proto.String(id)
  32. <-sendWait
  33. return nil
  34. })
  35. var c2 context.Context // a fake
  36. newContext = func(*http.Request) context.Context {
  37. return c2
  38. }
  39. var fRun int
  40. f := func(c3 context.Context) {
  41. fRun++
  42. if c3 != c2 {
  43. t.Errorf("f got a different context than expected")
  44. }
  45. }
  46. ribErrc := make(chan error)
  47. go func() {
  48. ribErrc <- RunInBackground(c, f)
  49. }()
  50. brErrc := make(chan error)
  51. go func() {
  52. <-sbr
  53. req, err := http.NewRequest("GET", srv.URL+"/_ah/background", nil)
  54. if err != nil {
  55. brErrc <- fmt.Errorf("http.NewRequest: %v", err)
  56. return
  57. }
  58. req.Header.Set("X-AppEngine-BackgroundRequest", id)
  59. client := &http.Client{
  60. Transport: &http.Transport{
  61. Proxy: http.ProxyFromEnvironment,
  62. },
  63. }
  64. <-recvWait
  65. _, err = client.Do(req)
  66. brErrc <- err
  67. }()
  68. // Send and receive are both waiting at this point.
  69. waits := [2]chan bool{sendWait, recvWait}
  70. if !sendFirst {
  71. waits[0], waits[1] = waits[1], waits[0]
  72. }
  73. waits[0] <- true
  74. time.Sleep(100 * time.Millisecond)
  75. waits[1] <- true
  76. if err := <-ribErrc; err != nil {
  77. t.Fatalf("RunInBackground: %v", err)
  78. }
  79. if err := <-brErrc; err != nil {
  80. t.Fatalf("background request: %v", err)
  81. }
  82. if fRun != 1 {
  83. t.Errorf("Got %d runs of f, want 1", fRun)
  84. }
  85. }