internal/lsp: change tests to use the main exporter

Now the tests are at a high enough level, we can
switch them to using the full exporter by bulding
a fake http client to bind it to. This lets us
use the true public interface and also excercise
more of the functionality in the tests.
With this we are now ready to replace the entire
implementation safely.

Change-Id: Ifdbf6230de3ec7c7c5381c840b135cb7a0bc1e55
Reviewed-on: https://go-review.googlesource.com/c/tools/+/209161
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
This commit is contained in:
Ian Cottrell 2019-11-27 11:24:29 -05:00
parent 75f8c4427c
commit 2f6d8bf0ad
3 changed files with 65 additions and 31 deletions

View File

@ -1,11 +1,11 @@
package ocagent_test
import (
"context"
"testing"
"time"
"golang.org/x/tools/internal/telemetry"
"golang.org/x/tools/internal/telemetry/export/ocagent"
"golang.org/x/tools/internal/telemetry/metric"
)
@ -312,12 +312,12 @@ func TestEncodeMetric(t *testing.T) {
},
}
ctx := context.TODO()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ocagent.EncodeMetric(cfg, tt.data)
if err != nil {
t.Fatal(err)
}
exporter.Metric(ctx, tt.data)
exporter.Flush()
got := sent.get("/v1/metrics")
checkJSON(t, got, []byte(tt.want))
})
}

View File

@ -149,20 +149,6 @@ func (cfg *Config) buildNode() *wire.Node {
}
}
func EncodeSpan(cfg Config, span *telemetry.Span) ([]byte, error) {
return json.Marshal(&wire.ExportTraceServiceRequest{
Node: cfg.buildNode(),
Spans: []*wire.Span{convertSpan(span)},
})
}
func EncodeMetric(cfg Config, m telemetry.MetricData) ([]byte, error) {
return json.Marshal(&wire.ExportMetricsServiceRequest{
Node: cfg.buildNode(),
Metrics: []*wire.Metric{convertMetric(m, cfg.Start)},
})
}
func (e *exporter) send(endpoint string, message interface{}) {
blob, err := json.Marshal(message)
if err != nil {

View File

@ -9,27 +9,36 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"sync"
"testing"
"time"
"golang.org/x/tools/internal/telemetry"
"golang.org/x/tools/internal/telemetry/export"
"golang.org/x/tools/internal/telemetry/export/ocagent"
"golang.org/x/tools/internal/telemetry/tag"
)
var (
cfg = ocagent.Config{
Host: "tester",
Process: 1,
Service: "ocagent-tests",
}
start time.Time
at time.Time
end time.Time
exporter export.Exporter
sent fakeSender
start time.Time
at time.Time
end time.Time
)
func init() {
cfg := ocagent.Config{
Host: "tester",
Process: 1,
Service: "ocagent-tests",
Client: &http.Client{Transport: &sent},
}
cfg.Start, _ = time.Parse(time.RFC3339Nano, "1970-01-01T00:00:00Z")
exporter = ocagent.Connect(&cfg)
}
const testNodeStr = `{
@ -267,10 +276,10 @@ func TestEvents(t *testing.T) {
Finish: end,
Events: []telemetry.Event{tt.event(ctx)},
}
got, err := ocagent.EncodeSpan(cfg, span)
if err != nil {
t.Fatal(err)
}
exporter.StartSpan(ctx, span)
exporter.FinishSpan(ctx, span)
exporter.Flush()
got := sent.get("/v1/trace")
checkJSON(t, got, []byte(tt.want))
})
}
@ -291,3 +300,42 @@ func checkJSON(t *testing.T, got, want []byte) {
t.Fatalf("Got:\n%s\nWant:\n%s", g, w)
}
}
type fakeSender struct {
mu sync.Mutex
data map[string][]byte
}
func (s *fakeSender) get(route string) []byte {
s.mu.Lock()
defer s.mu.Unlock()
data, found := s.data[route]
if found {
delete(s.data, route)
}
return data
}
func (s *fakeSender) RoundTrip(req *http.Request) (*http.Response, error) {
s.mu.Lock()
defer s.mu.Unlock()
if s.data == nil {
s.data = make(map[string][]byte)
}
data, err := ioutil.ReadAll(req.Body)
if err != nil {
return nil, err
}
path := req.URL.EscapedPath()
if _, found := s.data[path]; found {
return nil, fmt.Errorf("duplicate delivery to %v", path)
}
s.data[path] = data
return &http.Response{
Status: "200 OK",
StatusCode: 200,
Proto: "HTTP/1.0",
ProtoMajor: 1,
ProtoMinor: 0,
}, nil
}