span_annotating_client_trace_test.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright 2018, OpenCensus Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package ochttp_test
  15. import (
  16. "errors"
  17. "net/http"
  18. "net/http/httptest"
  19. "strings"
  20. "sync"
  21. "testing"
  22. "go.opencensus.io/plugin/ochttp"
  23. "go.opencensus.io/trace"
  24. )
  25. func TestSpanAnnotatingClientTrace(t *testing.T) {
  26. server := httptest.NewServer(http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
  27. resp.Write([]byte("Hello, world!"))
  28. }))
  29. defer server.Close()
  30. recorder := &testExporter{}
  31. trace.RegisterExporter(recorder)
  32. tr := ochttp.Transport{
  33. NewClientTrace: ochttp.NewSpanAnnotatingClientTrace,
  34. StartOptions: trace.StartOptions{
  35. Sampler: trace.AlwaysSample(),
  36. },
  37. }
  38. req, err := http.NewRequest("POST", server.URL, strings.NewReader("req-body"))
  39. if err != nil {
  40. t.Errorf("error creating request: %v", err)
  41. }
  42. resp, err := tr.RoundTrip(req)
  43. if err != nil {
  44. t.Errorf("response error: %v", err)
  45. }
  46. if err := resp.Body.Close(); err != nil {
  47. t.Errorf("error closing response body: %v", err)
  48. }
  49. if got, want := resp.StatusCode, 200; got != want {
  50. t.Errorf("resp.StatusCode=%d; want=%d", got, want)
  51. }
  52. if got, want := len(recorder.spans), 1; got != want {
  53. t.Fatalf("span count=%d; want=%d", got, want)
  54. }
  55. var annotations []string
  56. for _, annotation := range recorder.spans[0].Annotations {
  57. annotations = append(annotations, annotation.Message)
  58. }
  59. required := []string{
  60. "GetConn", "GotConn", "GotFirstResponseByte", "ConnectStart",
  61. "ConnectDone", "WroteHeaders", "WroteRequest",
  62. }
  63. if errs := requiredAnnotations(required, annotations); len(errs) > 0 {
  64. for _, err := range errs {
  65. t.Error(err)
  66. }
  67. }
  68. }
  69. type testExporter struct {
  70. mu sync.Mutex
  71. spans []*trace.SpanData
  72. }
  73. func (t *testExporter) ExportSpan(s *trace.SpanData) {
  74. t.mu.Lock()
  75. t.spans = append(t.spans, s)
  76. t.mu.Unlock()
  77. }
  78. func requiredAnnotations(required []string, list []string) []error {
  79. var errs []error
  80. for _, item := range required {
  81. var found bool
  82. for _, v := range list {
  83. if v == item {
  84. found = true
  85. }
  86. }
  87. if !found {
  88. errs = append(errs, errors.New("missing expected annotation: "+item))
  89. }
  90. }
  91. return errs
  92. }