GoPLS Viewer

Home|gopls/internal/event/export/ocagent/ocagent_test.go
1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package ocagent_test
6
7import (
8    "bytes"
9    "context"
10    "encoding/json"
11    "fmt"
12    "io/ioutil"
13    "net/http"
14    "sync"
15    "testing"
16    "time"
17
18    "golang.org/x/tools/internal/event"
19    "golang.org/x/tools/internal/event/core"
20    "golang.org/x/tools/internal/event/export"
21    "golang.org/x/tools/internal/event/export/metric"
22    "golang.org/x/tools/internal/event/export/ocagent"
23    "golang.org/x/tools/internal/event/keys"
24    "golang.org/x/tools/internal/event/label"
25)
26
27const testNodeStr = `{
28    "node":{
29        "identifier":{
30            "host_name":"tester",
31            "pid":1,
32            "start_timestamp":"1970-01-01T00:00:00Z"
33        },
34        "library_info":{
35            "language":4,
36            "exporter_version":"0.0.1",
37            "core_library_version":"x/tools"
38        },
39        "service_info":{
40            "name":"ocagent-tests"
41        }
42    },`
43
44var (
45    keyDB     = keys.NewString("db""the database name")
46    keyMethod = keys.NewString("method""a metric grouping key")
47    keyRoute  = keys.NewString("route""another metric grouping key")
48
49    key1DB = keys.NewString("1_db""A test string key")
50
51    key2aAge      = keys.NewFloat64("2a_age""A test float64 key")
52    key2bTTL      = keys.NewFloat32("2b_ttl""A test float32 key")
53    key2cExpiryMS = keys.NewFloat64("2c_expiry_ms""A test float64 key")
54
55    key3aRetry = keys.NewBoolean("3a_retry""A test boolean key")
56    key3bStale = keys.NewBoolean("3b_stale""Another test boolean key")
57
58    key4aMax      = keys.NewInt("4a_max""A test int key")
59    key4bOpcode   = keys.NewInt8("4b_opcode""A test int8 key")
60    key4cBase     = keys.NewInt16("4c_base""A test int16 key")
61    key4eChecksum = keys.NewInt32("4e_checksum""A test int32 key")
62    key4fMode     = keys.NewInt64("4f_mode""A test int64 key")
63
64    key5aMin     = keys.NewUInt("5a_min""A test uint key")
65    key5bMix     = keys.NewUInt8("5b_mix""A test uint8 key")
66    key5cPort    = keys.NewUInt16("5c_port""A test uint16 key")
67    key5dMinHops = keys.NewUInt32("5d_min_hops""A test uint32 key")
68    key5eMaxHops = keys.NewUInt64("5e_max_hops""A test uint64 key")
69
70    recursiveCalls = keys.NewInt64("recursive_calls""Number of recursive calls")
71    bytesIn        = keys.NewInt64("bytes_in""Number of bytes in")           //, unit.Bytes)
72    latencyMs      = keys.NewFloat64("latency""The latency in milliseconds"//, unit.Milliseconds)
73
74    metricLatency = metric.HistogramFloat64{
75        Name:        "latency_ms",
76        Description"The latency of calls in milliseconds",
77        Keys:        []label.Key{keyMethodkeyRoute},
78        Buckets:     []float64{05102550},
79    }
80
81    metricBytesIn = metric.HistogramInt64{
82        Name:        "latency_ms",
83        Description"The latency of calls in milliseconds",
84        Keys:        []label.Key{keyMethodkeyRoute},
85        Buckets:     []int64{0105010050010002000},
86    }
87
88    metricRecursiveCalls = metric.Scalar{
89        Name:        "latency_ms",
90        Description"The latency of calls in milliseconds",
91        Keys:        []label.Key{keyMethodkeyRoute},
92    }
93)
94
95type testExporter struct {
96    ocagent *ocagent.Exporter
97    sent    fakeSender
98}
99
100func registerExporter() *testExporter {
101    exporter := &testExporter{}
102    cfg := ocagent.Config{
103        Host:    "tester",
104        Process1,
105        Service"ocagent-tests",
106        Client:  &http.Client{Transport: &exporter.sent},
107    }
108    cfg.Start_ = time.Parse(time.RFC3339Nano"1970-01-01T00:00:00Z")
109    exporter.ocagent = ocagent.Connect(&cfg)
110
111    metrics := metric.Config{}
112    metricLatency.Record(&metricslatencyMs)
113    metricBytesIn.Record(&metricsbytesIn)
114    metricRecursiveCalls.SumInt64(&metricsrecursiveCalls)
115
116    e := exporter.ocagent.ProcessEvent
117    e = metrics.Exporter(e)
118    e = spanFixer(e)
119    e = export.Spans(e)
120    e = export.Labels(e)
121    e = timeFixer(e)
122    event.SetExporter(e)
123    return exporter
124}
125
126func timeFixer(output event.Exporterevent.Exporter {
127    start_ := time.Parse(time.RFC3339Nano"1970-01-01T00:00:30Z")
128    at_ := time.Parse(time.RFC3339Nano"1970-01-01T00:00:40Z")
129    end_ := time.Parse(time.RFC3339Nano"1970-01-01T00:00:50Z")
130    return func(ctx context.Contextev core.Eventlm label.Mapcontext.Context {
131        switch {
132        case event.IsStart(ev):
133            ev = core.CloneEvent(evstart)
134        case event.IsEnd(ev):
135            ev = core.CloneEvent(evend)
136        default:
137            ev = core.CloneEvent(evat)
138        }
139        return output(ctxevlm)
140    }
141}
142
143func spanFixer(output event.Exporterevent.Exporter {
144    return func(ctx context.Contextev core.Eventlm label.Mapcontext.Context {
145        if event.IsStart(ev) {
146            span := export.GetSpan(ctx)
147            span.ID = export.SpanContext{}
148        }
149        return output(ctxevlm)
150    }
151}
152
153func (e *testExporterOutput(route string) []byte {
154    e.ocagent.Flush()
155    return e.sent.get(route)
156}
157
158func checkJSON(t *testing.Tgotwant []byte) {
159    // compare the compact form, to allow for formatting differences
160    g := &bytes.Buffer{}
161    if err := json.Compact(ggot); err != nil {
162        t.Fatal(err)
163    }
164    w := &bytes.Buffer{}
165    if err := json.Compact(wwant); err != nil {
166        t.Fatal(err)
167    }
168    if g.String() != w.String() {
169        t.Fatalf("Got:\n%s\nWant:\n%s"gw)
170    }
171}
172
173type fakeSender struct {
174    mu   sync.Mutex
175    data map[string][]byte
176}
177
178func (s *fakeSenderget(route string) []byte {
179    s.mu.Lock()
180    defer s.mu.Unlock()
181    datafound := s.data[route]
182    if found {
183        delete(s.dataroute)
184    }
185    return data
186}
187
188func (s *fakeSenderRoundTrip(req *http.Request) (*http.Responseerror) {
189    s.mu.Lock()
190    defer s.mu.Unlock()
191    if s.data == nil {
192        s.data = make(map[string][]byte)
193    }
194    dataerr := ioutil.ReadAll(req.Body)
195    if err != nil {
196        return nilerr
197    }
198    path := req.URL.EscapedPath()
199    if _found := s.data[path]; found {
200        return nilfmt.Errorf("duplicate delivery to %v"path)
201    }
202    s.data[path] = data
203    return &http.Response{
204        Status:     "200 OK",
205        StatusCode200,
206        Proto:      "HTTP/1.0",
207        ProtoMajor1,
208        ProtoMinor0,
209    }, nil
210}
211
MembersX
testExporter
registerExporter
timeFixer
checkJSON.err
fakeSender.RoundTrip
timeFixer.at
spanFixer.output
checkJSON.got
fakeSender.get.s
fakeSender.RoundTrip.data
fakeSender.RoundTrip.path
testNodeStr
testExporter.ocagent
timeFixer.end
testExporter.Output.e
checkJSON.want
ioutil
registerExporter.exporter
fakeSender.RoundTrip.err
timeFixer.output
checkJSON
checkJSON.t
fakeSender.mu
fakeSender.data
fakeSender.RoundTrip.req
timeFixer._
spanFixer
testExporter.Output
testExporter.Output.route
fakeSender.get
checkJSON.g
fakeSender
fakeSender.get.route
ocagent
testExporter.sent
registerExporter.cfg
registerExporter.e
spanFixer.BlockStmt.BlockStmt.span
registerExporter.metrics
timeFixer.start
checkJSON.w
fakeSender.RoundTrip.s
Members
X