...

Source file src/go.opencensus.io/plugin/ocgrpc/trace_test.go

Documentation: go.opencensus.io/plugin/ocgrpc

     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  
    15  package ocgrpc_test
    16  
    17  import (
    18  	"context"
    19  	"io"
    20  	"testing"
    21  	"time"
    22  
    23  	"go.opencensus.io/internal/testpb"
    24  	"go.opencensus.io/trace"
    25  )
    26  
    27  type testExporter struct {
    28  	ch chan *trace.SpanData
    29  }
    30  
    31  func (t *testExporter) ExportSpan(s *trace.SpanData) {
    32  	go func() { t.ch <- s }()
    33  }
    34  
    35  func TestStreaming(t *testing.T) {
    36  	trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
    37  	te := testExporter{make(chan *trace.SpanData)}
    38  	trace.RegisterExporter(&te)
    39  	defer trace.UnregisterExporter(&te)
    40  
    41  	client, cleanup := testpb.NewTestClient(t)
    42  
    43  	stream, err := client.Multiple(context.Background())
    44  	if err != nil {
    45  		t.Fatalf("Call failed: %v", err)
    46  	}
    47  
    48  	err = stream.Send(&testpb.FooRequest{})
    49  	if err != nil {
    50  		t.Fatalf("Couldn't send streaming request: %v", err)
    51  	}
    52  	stream.CloseSend()
    53  
    54  	for {
    55  		_, err := stream.Recv()
    56  		if err == io.EOF {
    57  			break
    58  		}
    59  		if err != nil {
    60  			t.Errorf("stream.Recv() = %v; want no errors", err)
    61  		}
    62  	}
    63  
    64  	cleanup()
    65  
    66  	s1 := <-te.ch
    67  	s2 := <-te.ch
    68  
    69  	checkSpanData(t, s1, s2, "testpb.Foo.Multiple", true)
    70  
    71  	select {
    72  	case <-te.ch:
    73  		t.Fatal("received extra exported spans")
    74  	case <-time.After(time.Second / 10):
    75  	}
    76  }
    77  
    78  func TestStreamingFail(t *testing.T) {
    79  	trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
    80  	te := testExporter{make(chan *trace.SpanData)}
    81  	trace.RegisterExporter(&te)
    82  	defer trace.UnregisterExporter(&te)
    83  
    84  	client, cleanup := testpb.NewTestClient(t)
    85  
    86  	stream, err := client.Multiple(context.Background())
    87  	if err != nil {
    88  		t.Fatalf("Call failed: %v", err)
    89  	}
    90  
    91  	err = stream.Send(&testpb.FooRequest{Fail: true})
    92  	if err != nil {
    93  		t.Fatalf("Couldn't send streaming request: %v", err)
    94  	}
    95  	stream.CloseSend()
    96  
    97  	for {
    98  		_, err := stream.Recv()
    99  		if err == nil || err == io.EOF {
   100  			t.Errorf("stream.Recv() = %v; want errors", err)
   101  		} else {
   102  			break
   103  		}
   104  	}
   105  
   106  	s1 := <-te.ch
   107  	s2 := <-te.ch
   108  
   109  	checkSpanData(t, s1, s2, "testpb.Foo.Multiple", false)
   110  	cleanup()
   111  
   112  	select {
   113  	case <-te.ch:
   114  		t.Fatal("received extra exported spans")
   115  	case <-time.After(time.Second / 10):
   116  	}
   117  }
   118  
   119  func TestSingle(t *testing.T) {
   120  	trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
   121  	te := testExporter{make(chan *trace.SpanData)}
   122  	trace.RegisterExporter(&te)
   123  	defer trace.UnregisterExporter(&te)
   124  
   125  	client, cleanup := testpb.NewTestClient(t)
   126  
   127  	_, err := client.Single(context.Background(), &testpb.FooRequest{})
   128  	if err != nil {
   129  		t.Fatalf("Couldn't send request: %v", err)
   130  	}
   131  
   132  	s1 := <-te.ch
   133  	s2 := <-te.ch
   134  
   135  	checkSpanData(t, s1, s2, "testpb.Foo.Single", true)
   136  	cleanup()
   137  
   138  	select {
   139  	case <-te.ch:
   140  		t.Fatal("received extra exported spans")
   141  	case <-time.After(time.Second / 10):
   142  	}
   143  }
   144  
   145  func TestServerSpanDuration(t *testing.T) {
   146  	client, cleanup := testpb.NewTestClient(t)
   147  	defer cleanup()
   148  
   149  	te := testExporter{make(chan *trace.SpanData, 100)}
   150  	trace.RegisterExporter(&te)
   151  	defer trace.UnregisterExporter(&te)
   152  
   153  	trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
   154  
   155  	ctx := context.Background()
   156  	const sleep = 100 * time.Millisecond
   157  	client.Single(ctx, &testpb.FooRequest{SleepNanos: int64(sleep)})
   158  
   159  loop:
   160  	for {
   161  		select {
   162  		case span := <-te.ch:
   163  			if span.SpanKind != trace.SpanKindServer {
   164  				continue loop
   165  			}
   166  			if got, want := span.EndTime.Sub(span.StartTime), sleep; got < want {
   167  				t.Errorf("span duration = %dns; want at least %dns", got, want)
   168  			}
   169  			break loop
   170  		default:
   171  			t.Fatal("no more spans")
   172  		}
   173  	}
   174  }
   175  
   176  func TestSingleFail(t *testing.T) {
   177  	trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
   178  	te := testExporter{make(chan *trace.SpanData)}
   179  	trace.RegisterExporter(&te)
   180  	defer trace.UnregisterExporter(&te)
   181  
   182  	client, cleanup := testpb.NewTestClient(t)
   183  
   184  	_, err := client.Single(context.Background(), &testpb.FooRequest{Fail: true})
   185  	if err == nil {
   186  		t.Fatalf("Got nil error from request, want non-nil")
   187  	}
   188  
   189  	s1 := <-te.ch
   190  	s2 := <-te.ch
   191  
   192  	checkSpanData(t, s1, s2, "testpb.Foo.Single", false)
   193  	cleanup()
   194  
   195  	select {
   196  	case <-te.ch:
   197  		t.Fatal("received extra exported spans")
   198  	case <-time.After(time.Second / 10):
   199  	}
   200  }
   201  
   202  func checkSpanData(t *testing.T, s1, s2 *trace.SpanData, methodName string, success bool) {
   203  	t.Helper()
   204  
   205  	if s1.SpanKind == trace.SpanKindServer {
   206  		s1, s2 = s2, s1
   207  	}
   208  
   209  	if got, want := s1.Name, methodName; got != want {
   210  		t.Errorf("Got name %q want %q", got, want)
   211  	}
   212  	if got, want := s2.Name, methodName; got != want {
   213  		t.Errorf("Got name %q want %q", got, want)
   214  	}
   215  	if got, want := s2.SpanContext.TraceID, s1.SpanContext.TraceID; got != want {
   216  		t.Errorf("Got trace IDs %s and %s, want them equal", got, want)
   217  	}
   218  	if got, want := s2.ParentSpanID, s1.SpanContext.SpanID; got != want {
   219  		t.Errorf("Got ParentSpanID %s, want %s", got, want)
   220  	}
   221  	if got := (s1.Status.Code == 0); got != success {
   222  		t.Errorf("Got success=%t want %t", got, success)
   223  	}
   224  	if got := (s2.Status.Code == 0); got != success {
   225  		t.Errorf("Got success=%t want %t", got, success)
   226  	}
   227  	if s1.HasRemoteParent {
   228  		t.Errorf("Got HasRemoteParent=%t, want false", s1.HasRemoteParent)
   229  	}
   230  	if !s2.HasRemoteParent {
   231  		t.Errorf("Got HasRemoteParent=%t, want true", s2.HasRemoteParent)
   232  	}
   233  }
   234  

View as plain text