1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package ocgrpc
17
18 import (
19 "strings"
20 "testing"
21
22 "go.opencensus.io/stats"
23 "go.opencensus.io/stats/view"
24 )
25
26 func TestSpecServerMeasures(t *testing.T) {
27 spec := `
28 | Measure name | Unit | Description |
29 |------------------------------------------|------|-----------------------------------------------------------------------------------------------|
30 | grpc.io/server/received_messages_per_rpc | 1 | Number of messages received in each RPC. Has value 1 for non-streaming RPCs. |
31 | grpc.io/server/received_bytes_per_rpc | By | Total bytes received across all messages per RPC. |
32 | grpc.io/server/sent_messages_per_rpc | 1 | Number of messages sent in each RPC. Has value 1 for non-streaming RPCs. |
33 | grpc.io/server/sent_bytes_per_rpc | By | Total bytes sent in across all response messages per RPC. |
34 | grpc.io/server/server_latency | ms | Time between first byte of request received to last byte of response sent, or terminal error. |`
35
36 lines := strings.Split(spec, "\n")[3:]
37 type measureDef struct {
38 name string
39 unit string
40 desc string
41 }
42 measureDefs := make([]measureDef, 0, len(lines))
43 for _, line := range lines {
44 cols := colSep.Split(line, -1)[1:]
45 if len(cols) < 3 {
46 t.Fatalf("Invalid config line %#v", cols)
47 }
48 measureDefs = append(measureDefs, measureDef{cols[0], cols[1], cols[2]})
49 }
50
51 gotMeasures := []stats.Measure{
52 ServerReceivedMessagesPerRPC,
53 ServerReceivedBytesPerRPC,
54 ServerSentMessagesPerRPC,
55 ServerSentBytesPerRPC,
56 ServerLatency,
57 }
58
59 if got, want := len(gotMeasures), len(measureDefs); got != want {
60 t.Fatalf("len(gotMeasures) = %d; want %d", got, want)
61 }
62
63 for i, m := range gotMeasures {
64 defn := measureDefs[i]
65 if got, want := m.Name(), defn.name; got != want {
66 t.Errorf("Name = %q; want %q", got, want)
67 }
68 if got, want := m.Unit(), defn.unit; got != want {
69 t.Errorf("%q: Unit = %q; want %q", defn.name, got, want)
70 }
71 if got, want := m.Description(), defn.desc; got != want {
72 t.Errorf("%q: Description = %q; want %q", defn.name, got, want)
73 }
74 }
75 }
76
77 func TestSpecServerViews(t *testing.T) {
78 defaultViewsSpec := `
79 | View name | Measure suffix | Aggregation | Tags suffix |
80 |---------------------------------------|------------------------|--------------|------------------------------|
81 | grpc.io/server/received_bytes_per_rpc | received_bytes_per_rpc | distribution | server_method |
82 | grpc.io/server/sent_bytes_per_rpc | sent_bytes_per_rpc | distribution | server_method |
83 | grpc.io/server/server_latency | server_latency | distribution | server_method |
84 | grpc.io/server/completed_rpcs | server_latency | count | server_method, server_status |`
85
86 extraViewsSpec := `
87 | View name | Measure suffix | Aggregation | Tags suffix |
88 |------------------------------------------|---------------------------|--------------|---------------|
89 | grpc.io/server/received_messages_per_rpc | received_messages_per_rpc | distribution | server_method |
90 | grpc.io/server/sent_messages_per_rpc | sent_messages_per_rpc | distribution | server_method |`
91
92 lines := strings.Split(defaultViewsSpec, "\n")[3:]
93 lines = append(lines, strings.Split(extraViewsSpec, "\n")[3:]...)
94 type viewDef struct {
95 name string
96 measureSuffix string
97 aggregation string
98 tags string
99 }
100 viewDefs := make([]viewDef, 0, len(lines))
101 for _, line := range lines {
102 cols := colSep.Split(line, -1)[1:]
103 if len(cols) < 4 {
104 t.Fatalf("Invalid config line %#v", cols)
105 }
106 viewDefs = append(viewDefs, viewDef{cols[0], cols[1], cols[2], cols[3]})
107 }
108
109 views := DefaultServerViews
110 views = append(views, ServerReceivedMessagesPerRPCView, ServerSentMessagesPerRPCView)
111
112 if got, want := len(views), len(viewDefs); got != want {
113 t.Fatalf("len(gotMeasures) = %d; want %d", got, want)
114 }
115
116 for i, v := range views {
117 defn := viewDefs[i]
118 if got, want := v.Name, defn.name; got != want {
119 t.Errorf("Name = %q; want %q", got, want)
120 }
121 if got, want := v.Measure.Name(), "grpc.io/server/"+defn.measureSuffix; got != want {
122 t.Errorf("%q: Measure.Name = %q; want %q", defn.name, got, want)
123 }
124 switch v.Aggregation.Type {
125 case view.AggTypeDistribution:
126 if got, want := "distribution", defn.aggregation; got != want {
127 t.Errorf("%q: Description = %q; want %q", defn.name, got, want)
128 }
129 case view.AggTypeCount:
130 if got, want := "count", defn.aggregation; got != want {
131 t.Errorf("%q: Description = %q; want %q", defn.name, got, want)
132 }
133 default:
134 t.Errorf("Invalid aggregation type")
135 }
136 wantTags := strings.Split(defn.tags, ", ")
137 if got, want := len(v.TagKeys), len(wantTags); got != want {
138 t.Errorf("len(TagKeys) = %d; want %d", got, want)
139 }
140 for j := range wantTags {
141 if got, want := v.TagKeys[j].Name(), "grpc_"+wantTags[j]; got != want {
142 t.Errorf("TagKeys[%d].Name() = %q; want %q", j, got, want)
143 }
144 }
145 }
146 }
147
View as plain text