Codebase list golang-github-go-kit-kit / run/dff50435-7a33-4f0c-bbdc-f455eb10d80a/main tracing / opencensus / jsonrpc_test.go
run/dff50435-7a33-4f0c-bbdc-f455eb10d80a/main

Tree @run/dff50435-7a33-4f0c-bbdc-f455eb10d80a/main (Download .tar.gz)

jsonrpc_test.go @run/dff50435-7a33-4f0c-bbdc-f455eb10d80a/mainraw · history · blame

package opencensus_test

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/http/httptest"
	"net/url"
	"testing"

	"go.opencensus.io/plugin/ochttp"
	"go.opencensus.io/plugin/ochttp/propagation/b3"
	"go.opencensus.io/plugin/ochttp/propagation/tracecontext"
	"go.opencensus.io/trace"
	"go.opencensus.io/trace/propagation"

	"github.com/go-kit/kit/endpoint"
	ockit "github.com/go-kit/kit/tracing/opencensus"
	jsonrpc "github.com/go-kit/kit/transport/http/jsonrpc"
)

func TestJSONRPCClientTrace(t *testing.T) {
	t.Skip("FLAKY")

	var (
		err          error
		rec          = &recordingExporter{}
		rURL, _      = url.Parse("https://httpbin.org/anything")
		endpointName = "DummyEndpoint"
	)

	trace.RegisterExporter(rec)

	traces := []struct {
		name string
		err  error
	}{
		{"", nil},
		{"CustomName", nil},
		{"", errors.New("dummy-error")},
	}

	for _, tr := range traces {
		clientTracer := ockit.JSONRPCClientTrace(
			ockit.WithName(tr.name),
			ockit.WithSampler(trace.AlwaysSample()),
		)
		ep := jsonrpc.NewClient(
			rURL,
			endpointName,
			jsonrpc.ClientRequestEncoder(func(ctx context.Context, i interface{}) (json.RawMessage, error) {
				return json.RawMessage(`{}`), nil
			}),
			jsonrpc.ClientResponseDecoder(func(ctx context.Context, r jsonrpc.Response) (response interface{}, err error) {
				return nil, tr.err
			}),
			clientTracer,
		).Endpoint()

		ctx, parentSpan := trace.StartSpan(context.Background(), "test")

		_, err = ep(ctx, nil)
		if want, have := tr.err, err; want != have {
			t.Fatalf("unexpected error, want %v, have %v", tr.err, err)
		}

		spans := rec.Flush()
		if want, have := 1, len(spans); want != have {
			t.Fatalf("incorrect number of spans, want %d, have %d", want, have)
		}

		span := spans[0]
		if want, have := parentSpan.SpanContext().SpanID, span.ParentSpanID; want != have {
			t.Errorf("incorrect parent ID, want %s, have %s", want, have)
		}

		if want, have := tr.name, span.Name; want != have && want != "" {
			t.Errorf("incorrect span name, want %s, have %s", want, have)
		}

		if want, have := endpointName, span.Name; want != have && tr.name == "" {
			t.Errorf("incorrect span name, want %s, have %s", want, have)
		}

		code := trace.StatusCodeOK
		if tr.err != nil {
			code = trace.StatusCodeUnknown

			if want, have := err.Error(), span.Status.Message; want != have {
				t.Errorf("incorrect span status msg, want %s, have %s", want, have)
			}
		}

		if want, have := int32(code), span.Status.Code; want != have {
			t.Errorf("incorrect span status code, want %d, have %d", want, have)
		}
	}
}

func TestJSONRPCServerTrace(t *testing.T) {
	var (
		endpointName = "DummyEndpoint"
		rec          = &recordingExporter{}
	)

	trace.RegisterExporter(rec)

	traces := []struct {
		useParent   bool
		name        string
		err         error
		propagation propagation.HTTPFormat
	}{
		{false, "", nil, nil},
		{true, "", nil, nil},
		{true, "CustomName", nil, &b3.HTTPFormat{}},
		{true, "", errors.New("dummy-error"), &tracecontext.HTTPFormat{}},
	}

	for _, tr := range traces {
		var client http.Client

		handler := jsonrpc.NewServer(
			jsonrpc.EndpointCodecMap{
				endpointName: jsonrpc.EndpointCodec{
					Endpoint: endpoint.Nop,
					Decode:   func(context.Context, json.RawMessage) (interface{}, error) { return nil, nil },
					Encode:   func(context.Context, interface{}) (json.RawMessage, error) { return nil, tr.err },
				},
			},
			ockit.JSONRPCServerTrace(
				ockit.WithName(tr.name),
				ockit.WithSampler(trace.AlwaysSample()),
				ockit.WithHTTPPropagation(tr.propagation),
			),
		)

		server := httptest.NewServer(handler)
		defer server.Close()

		jsonStr := []byte(fmt.Sprintf(`{"method":"%s"}`, endpointName))
		req, err := http.NewRequest("POST", server.URL, bytes.NewBuffer(jsonStr))
		if err != nil {
			t.Fatalf("unable to create JSONRPC request: %v", err)
		}

		if tr.useParent {
			client = http.Client{
				Transport: &ochttp.Transport{
					StartOptions: trace.StartOptions{
						Sampler: trace.AlwaysSample(),
					},
					Propagation: tr.propagation,
				},
			}
		}

		resp, err := client.Do(req.WithContext(context.Background()))
		if err != nil {
			t.Fatalf("unable to send JSONRPC request: %v", err)
		}
		resp.Body.Close()

		spans := rec.Flush()

		expectedSpans := 1
		if tr.useParent {
			expectedSpans++
		}

		if want, have := expectedSpans, len(spans); want != have {
			t.Fatalf("incorrect number of spans, want %d, have %d", want, have)
		}

		if tr.useParent {
			if want, have := spans[1].TraceID, spans[0].TraceID; want != have {
				t.Errorf("incorrect trace ID, want %s, have %s", want, have)
			}

			if want, have := spans[1].SpanID, spans[0].ParentSpanID; want != have {
				t.Errorf("incorrect span ID, want %s, have %s", want, have)
			}
		}

		if want, have := tr.name, spans[0].Name; want != have && want != "" {
			t.Errorf("incorrect span name, want %s, have %s", want, have)
		}

		if want, have := endpointName, spans[0].Name; want != have && tr.name == "" {
			t.Errorf("incorrect span name, want %s, have %s", want, have)
		}
	}
}