blob: 4a65eaf2f66d683cc254493e69a90779478b2749 [file] [log] [blame]
Robin Thellendb16d7162014-11-07 13:47:26 -08001package debug
Robin Thellend738bb082014-08-25 14:56:58 -07002
3import (
Robin Thellendb16d7162014-11-07 13:47:26 -08004 "fmt"
Matt Rosencrantzb30286b2014-11-10 14:52:17 -08005 "io"
Robin Thellend738bb082014-08-25 14:56:58 -07006 "io/ioutil"
7 "os"
8 "path/filepath"
9 "reflect"
10 "sort"
11 "strings"
12 "testing"
13 "time"
14
Robin Thellendb16d7162014-11-07 13:47:26 -080015 "veyron.io/veyron/veyron2"
Matt Rosencrantzbe1a8b52014-11-21 15:14:06 -080016 "veyron.io/veyron/veyron2/context"
Robin Thellendb16d7162014-11-07 13:47:26 -080017 "veyron.io/veyron/veyron2/ipc"
Jiri Simsa519c5072014-09-17 21:37:57 -070018 "veyron.io/veyron/veyron2/naming"
19 "veyron.io/veyron/veyron2/rt"
20 "veyron.io/veyron/veyron2/services/mgmt/logreader"
21 "veyron.io/veyron/veyron2/services/mgmt/stats"
Matt Rosencrantzbe1a8b52014-11-21 15:14:06 -080022 vtracesvc "veyron.io/veyron/veyron2/services/mgmt/vtrace"
Jiri Simsa519c5072014-09-17 21:37:57 -070023 "veyron.io/veyron/veyron2/verror"
Matt Rosencrantzbe1a8b52014-11-21 15:14:06 -080024 "veyron.io/veyron/veyron2/vtrace"
Cosmos Nicolaou43b95352014-10-14 11:09:52 -070025
26 libstats "veyron.io/veyron/veyron/lib/stats"
Robin Thellend5c95a6c2014-11-10 13:06:56 -080027 "veyron.io/veyron/veyron/lib/testutil"
Cosmos Nicolaou43b95352014-10-14 11:09:52 -070028 "veyron.io/veyron/veyron/profiles"
Robin Thellend738bb082014-08-25 14:56:58 -070029)
30
Robin Thellendb16d7162014-11-07 13:47:26 -080031// startDebugServer starts a debug server.
32func startDebugServer(rt veyron2.Runtime, listenSpec ipc.ListenSpec, logsDir string) (string, func(), error) {
33 if len(logsDir) == 0 {
34 return "", nil, fmt.Errorf("logs directory missing")
35 }
Matt Rosencrantzb30286b2014-11-10 14:52:17 -080036 disp := NewDispatcher(logsDir, nil, rt.VtraceStore())
Robin Thellendb16d7162014-11-07 13:47:26 -080037 server, err := rt.NewServer()
38 if err != nil {
39 return "", nil, fmt.Errorf("failed to start debug server: %v", err)
40 }
Cosmos Nicolaou28dabfc2014-12-15 22:51:07 -080041 endpoints, err := server.Listen(listenSpec)
Robin Thellendb16d7162014-11-07 13:47:26 -080042 if err != nil {
43 return "", nil, fmt.Errorf("failed to listen on %s: %v", listenSpec, err)
44 }
45 if err := server.ServeDispatcher("", disp); err != nil {
46 return "", nil, err
47 }
Cosmos Nicolaou28dabfc2014-12-15 22:51:07 -080048 ep := endpoints[0].String()
Robin Thellendb16d7162014-11-07 13:47:26 -080049 return ep, func() { server.Stop() }, nil
50}
51
Robin Thellend738bb082014-08-25 14:56:58 -070052func TestDebugServer(t *testing.T) {
Matt Rosencrantz5180d162014-12-03 13:48:40 -080053 runtime, err := rt.New()
54 if err != nil {
55 t.Fatalf("Could not initialize runtime: %v", err)
56 }
57 defer runtime.Cleanup()
58
Matt Rosencrantzbe1a8b52014-11-21 15:14:06 -080059 tracedContext := func() context.T {
60 ctx := runtime.NewContext()
61 vtrace.FromContext(ctx).Trace().ForceCollect()
62 return ctx
63 }
Robin Thellendb16d7162014-11-07 13:47:26 -080064 rootName = "debug"
Robin Thellend738bb082014-08-25 14:56:58 -070065
66 workdir, err := ioutil.TempDir("", "logreadertest")
67 if err != nil {
68 t.Fatalf("ioutil.TempDir: %v", err)
69 }
70 defer os.RemoveAll(workdir)
71 if err = ioutil.WriteFile(filepath.Join(workdir, "test.INFO"), []byte("test"), os.FileMode(0644)); err != nil {
72 t.Fatalf("ioutil.WriteFile failed: %v", err)
73 }
74
Robin Thellendb16d7162014-11-07 13:47:26 -080075 endpoint, stop, err := startDebugServer(runtime, profiles.LocalListenSpec, workdir)
Robin Thellend738bb082014-08-25 14:56:58 -070076 if err != nil {
77 t.Fatalf("StartDebugServer failed: %v", err)
78 }
79 defer stop()
80
81 // Access a logs directory that exists.
82 {
Matt Rosencrantz8a422802014-11-27 21:36:45 -080083 results, err := testutil.GlobName(runtime.NewContext(), naming.JoinAddressName(endpoint, "debug/logs"), "*")
Robin Thellend738bb082014-08-25 14:56:58 -070084 if err != nil {
85 t.Errorf("Glob failed: %v", err)
86 }
Robin Thellend738bb082014-08-25 14:56:58 -070087 if len(results) != 1 || results[0] != "test.INFO" {
88 t.Errorf("unexpected result. Got %v, want 'test.INFO'", results)
89 }
Robin Thellend738bb082014-08-25 14:56:58 -070090 }
91
92 // Access a logs directory that doesn't exist.
93 {
Matt Rosencrantz8a422802014-11-27 21:36:45 -080094 results, err := testutil.GlobName(runtime.NewContext(), naming.JoinAddressName(endpoint, "debug/logs/nowheretobefound"), "*")
Robin Thellend738bb082014-08-25 14:56:58 -070095 if len(results) != 0 {
96 t.Errorf("unexpected result. Got %v, want ''", results)
97 }
Robin Thellendac7128c2014-11-11 09:58:28 -080098 if err != nil {
99 t.Errorf("unexpected error value: %v", err)
Robin Thellend738bb082014-08-25 14:56:58 -0700100 }
101 }
102
103 // Access a log file that exists.
104 {
Robin Thellendb16d7162014-11-07 13:47:26 -0800105 lf := logreader.LogFileClient(naming.JoinAddressName(endpoint, "debug/logs/test.INFO"))
Matt Rosencrantzbe1a8b52014-11-21 15:14:06 -0800106 size, err := lf.Size(tracedContext())
Robin Thellend738bb082014-08-25 14:56:58 -0700107 if err != nil {
108 t.Errorf("Size failed: %v", err)
109 }
110 if expected := int64(len("test")); size != expected {
111 t.Errorf("unexpected result. Got %v, want %v", size, expected)
112 }
113 }
114
115 // Access a log file that doesn't exist.
116 {
Robin Thellendb16d7162014-11-07 13:47:26 -0800117 lf := logreader.LogFileClient(naming.JoinAddressName(endpoint, "debug/logs/nosuchfile.INFO"))
Matt Rosencrantzbe1a8b52014-11-21 15:14:06 -0800118 _, err = lf.Size(tracedContext())
Tilak Sharma492e8e92014-09-18 10:58:14 -0700119 if expected := verror.NoExist; !verror.Is(err, expected) {
Robin Thellend738bb082014-08-25 14:56:58 -0700120 t.Errorf("unexpected error value, got %v, want: %v", err, expected)
121 }
122 }
123
124 // Access a stats object that exists.
125 {
126 foo := libstats.NewInteger("testing/foo")
127 foo.Set(123)
128
Robin Thellendb16d7162014-11-07 13:47:26 -0800129 st := stats.StatsClient(naming.JoinAddressName(endpoint, "debug/stats/testing/foo"))
Matt Rosencrantzbe1a8b52014-11-21 15:14:06 -0800130 v, err := st.Value(tracedContext())
Robin Thellend738bb082014-08-25 14:56:58 -0700131 if err != nil {
132 t.Errorf("Value failed: %v", err)
133 }
134 if expected := int64(123); v != expected {
135 t.Errorf("unexpected result. Got %v, want %v", v, expected)
136 }
137 }
138
139 // Access a stats object that doesn't exists.
140 {
Robin Thellendb16d7162014-11-07 13:47:26 -0800141 st := stats.StatsClient(naming.JoinAddressName(endpoint, "debug/stats/testing/nobodyhome"))
Matt Rosencrantzbe1a8b52014-11-21 15:14:06 -0800142 _, err = st.Value(tracedContext())
Tilak Sharma492e8e92014-09-18 10:58:14 -0700143 if expected := verror.NoExist; !verror.Is(err, expected) {
Robin Thellend738bb082014-08-25 14:56:58 -0700144 t.Errorf("unexpected error value, got %v, want: %v", err, expected)
145 }
146 }
147
Matt Rosencrantzb30286b2014-11-10 14:52:17 -0800148 // Access vtrace.
149 {
Matt Rosencrantzbe1a8b52014-11-21 15:14:06 -0800150 vt := vtracesvc.StoreClient(naming.JoinAddressName(endpoint, "debug/vtrace"))
Matt Rosencrantzb30286b2014-11-10 14:52:17 -0800151 call, err := vt.AllTraces(runtime.NewContext())
152 if err != nil {
153 t.Errorf("AllTraces failed: %v", err)
154 }
155 ntraces := 0
156 stream := call.RecvStream()
157 for stream.Advance() {
158 stream.Value()
159 ntraces++
160 }
161 if err = stream.Err(); err != nil && err != io.EOF {
162 t.Fatalf("Unexpected error reading trace stream: %s", err)
163 }
Matt Rosencrantzbe1a8b52014-11-21 15:14:06 -0800164 if ntraces != 4 {
165 t.Errorf("We expected 4 traces, got: %d", ntraces)
Matt Rosencrantzb30286b2014-11-10 14:52:17 -0800166 }
167 }
168
Robin Thellend738bb082014-08-25 14:56:58 -0700169 // Glob from the root.
170 {
Matt Rosencrantz5180d162014-12-03 13:48:40 -0800171 ns := runtime.Namespace()
Robin Thellendb16d7162014-11-07 13:47:26 -0800172 ns.SetRoots(naming.JoinAddressName(endpoint, "debug"))
Matt Rosencrantz5180d162014-12-03 13:48:40 -0800173 ctx, cancel := runtime.NewContext().WithTimeout(10 * time.Second)
Robin Thellend738bb082014-08-25 14:56:58 -0700174 defer cancel()
175 c, err := ns.Glob(ctx, "logs/...")
176 if err != nil {
177 t.Errorf("ns.Glob failed: %v", err)
178 }
179 results := []string{}
180 for res := range c {
181 results = append(results, res.Name)
182 }
183 sort.Strings(results)
184 expected := []string{
185 "logs",
186 "logs/test.INFO",
187 }
188 if !reflect.DeepEqual(expected, results) {
189 t.Errorf("unexpected result. Got %v, want %v", results, expected)
190 }
191
192 c, err = ns.Glob(ctx, "stats/testing/*")
193 if err != nil {
194 t.Errorf("ns.Glob failed: %v", err)
195 }
196 results = []string{}
197 for res := range c {
198 results = append(results, res.Name)
199 }
200 sort.Strings(results)
201 expected = []string{
202 "stats/testing/foo",
203 }
204 if !reflect.DeepEqual(expected, results) {
205 t.Errorf("unexpected result. Got %v, want %v", results, expected)
206 }
207
Robin Thellend1bc409b2014-09-23 11:16:38 -0700208 c, err = ns.Glob(ctx, "*")
209 if err != nil {
210 t.Errorf("ns.Glob failed: %v", err)
211 }
212 results = []string{}
213 for res := range c {
214 results = append(results, res.Name)
215 }
216 sort.Strings(results)
217 expected = []string{
218 "logs",
219 "pprof",
220 "stats",
Matt Rosencrantzb30286b2014-11-10 14:52:17 -0800221 "vtrace",
Robin Thellend1bc409b2014-09-23 11:16:38 -0700222 }
223 if !reflect.DeepEqual(expected, results) {
224 t.Errorf("unexpected result. Got %v, want %v", results, expected)
225 }
226
Robin Thellend738bb082014-08-25 14:56:58 -0700227 c, err = ns.Glob(ctx, "...")
228 if err != nil {
229 t.Errorf("ns.Glob failed: %v", err)
230 }
231 results = []string{}
232 for res := range c {
233 if strings.HasPrefix(res.Name, "stats/") && !strings.HasPrefix(res.Name, "stats/testing/") {
234 // Skip any non-testing stats.
235 continue
236 }
237 results = append(results, res.Name)
238 }
239 sort.Strings(results)
240 expected = []string{
Robin Thellendc26c32e2014-10-06 17:44:04 -0700241 "",
Robin Thellend738bb082014-08-25 14:56:58 -0700242 "logs",
243 "logs/test.INFO",
Robin Thellend1bc409b2014-09-23 11:16:38 -0700244 "pprof",
Robin Thellend738bb082014-08-25 14:56:58 -0700245 "stats",
246 "stats/testing/foo",
Matt Rosencrantzb30286b2014-11-10 14:52:17 -0800247 "vtrace",
Robin Thellend738bb082014-08-25 14:56:58 -0700248 }
249 if !reflect.DeepEqual(expected, results) {
250 t.Errorf("unexpected result. Got %v, want %v", results, expected)
251 }
252 }
253}