perfmonger 0.10.2 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -0
  3. data/.travis.yml +9 -8
  4. data/HOWTO.md +0 -1
  5. data/NEWS +49 -5
  6. data/README.md +77 -27
  7. data/Rakefile +33 -11
  8. data/core/Makefile +22 -31
  9. data/core/build.sh +6 -8
  10. data/core/cmd/perfmonger-player/perfmonger-player.go +247 -0
  11. data/core/{perfmonger-plot-formatter.go → cmd/perfmonger-plot-formatter/perfmonger-plot-formatter.go} +20 -5
  12. data/core/{perfmonger-recorder.go → cmd/perfmonger-recorder/perfmonger-recorder.go} +22 -2
  13. data/core/{perfmonger-summarizer.go → cmd/perfmonger-summarizer/perfmonger-summarizer.go} +22 -15
  14. data/core/cmd/perfmonger-viewer/perfmonger-viewer.go +164 -0
  15. data/core/go.mod +10 -0
  16. data/core/go.sum +17 -0
  17. data/core/subsystem/Makefile +4 -0
  18. data/core/subsystem/perfmonger_linux.go +95 -0
  19. data/core/subsystem/perfmonger_linux_test.go +40 -0
  20. data/core/subsystem/stat.go +70 -0
  21. data/core/subsystem/stat_test.go +9 -0
  22. data/core/subsystem/usage.go +223 -66
  23. data/core/subsystem/usage_test.go +62 -32
  24. data/core/utils.go +2 -2
  25. data/{bin → exe}/perfmonger +0 -0
  26. data/lib/exec/perfmonger-player_darwin_amd64 +0 -0
  27. data/lib/exec/perfmonger-player_linux_amd64 +0 -0
  28. data/lib/exec/perfmonger-plot-formatter_darwin_amd64 +0 -0
  29. data/lib/exec/perfmonger-plot-formatter_linux_amd64 +0 -0
  30. data/lib/exec/perfmonger-recorder_darwin_amd64 +0 -0
  31. data/lib/exec/perfmonger-recorder_linux_amd64 +0 -0
  32. data/lib/exec/perfmonger-summarizer_darwin_amd64 +0 -0
  33. data/lib/exec/perfmonger-summarizer_linux_amd64 +0 -0
  34. data/lib/exec/perfmonger-viewer_darwin_amd64 +0 -0
  35. data/lib/exec/perfmonger-viewer_linux_amd64 +0 -0
  36. data/lib/perfmonger/command/fingerprint.rb +26 -1
  37. data/lib/perfmonger/command/live.rb +19 -0
  38. data/lib/perfmonger/command/play.rb +16 -0
  39. data/lib/perfmonger/command/plot.rb +23 -9
  40. data/lib/perfmonger/command/record.rb +24 -3
  41. data/lib/perfmonger/command/record_option.rb +16 -0
  42. data/lib/perfmonger/command/server.rb +1 -1
  43. data/lib/perfmonger/version.rb +1 -1
  44. data/misc/werker-box/Dockerfile +34 -0
  45. data/misc/werker-box/build-push.sh +7 -0
  46. data/perfmonger.gemspec +2 -1
  47. data/spec/data/busy100.pgr.played +3 -3
  48. data/spec/fingerprint_spec.rb +1 -1
  49. data/spec/live_spec.rb +2 -3
  50. data/spec/perfmonger_spec.rb +1 -1
  51. data/spec/play_spec.rb +1 -1
  52. data/spec/plot_spec.rb +16 -1
  53. data/spec/record_spec.rb +10 -1
  54. data/spec/spec_helper.rb +28 -3
  55. data/spec/stat_spec.rb +2 -2
  56. data/spec/summary_spec.rb +1 -1
  57. data/wercker.yml +29 -16
  58. metadata +34 -14
  59. data/core/perfmonger-player.go +0 -196
  60. data/lib/exec/perfmonger-player_linux_386 +0 -0
  61. data/lib/exec/perfmonger-plot-formatter_linux_386 +0 -0
  62. data/lib/exec/perfmonger-recorder_linux_386 +0 -0
  63. data/lib/exec/perfmonger-summarizer_linux_386 +0 -0
@@ -262,6 +262,14 @@ func TestNewNetStat(t *testing.T) {
262
262
  }
263
263
  }
264
264
 
265
+ func TestNewMemStat(t *testing.T) {
266
+ memstat := NewMemStat()
267
+
268
+ if memstat == nil {
269
+ t.Error("failed to create MemStat")
270
+ }
271
+ }
272
+
265
273
  func TestNewStatRecord(t *testing.T) {
266
274
  stat_record := NewStatRecord()
267
275
 
@@ -278,4 +286,5 @@ func TestNewStatRecord(t *testing.T) {
278
286
  checkFieldIsNil("Disk")
279
287
  checkFieldIsNil("Softirq")
280
288
  checkFieldIsNil("Net")
289
+ checkFieldIsNil("Mem")
281
290
  }
@@ -2,12 +2,13 @@ package subsystem
2
2
 
3
3
  import (
4
4
  "bytes"
5
- "encoding/json"
6
5
  "errors"
7
6
  "fmt"
8
7
  "regexp"
9
8
  "sort"
10
9
  "time"
10
+
11
+ projson "github.com/hayamiz/go-projson"
11
12
  )
12
13
 
13
14
  type CpuCoreUsage struct {
@@ -84,25 +85,56 @@ type NetUsageEntry struct {
84
85
 
85
86
  type NetUsage map[string]*NetUsageEntry
86
87
 
87
- func (ccusage *CpuCoreUsage) WriteJsonTo(buf *bytes.Buffer) {
88
- buf.WriteString(
89
- fmt.Sprintf(`{"usr":%.2f,"nice":%.2f,"sys":%.2f,"idle":%.2f,"iowait":%.2f,"hardirq":%.2f,"softirq":%.2f,"steal":%.2f,"guest":%.2f,"guestnice":%.2f}`,
90
- ccusage.User, ccusage.Nice, ccusage.Sys, ccusage.Idle, ccusage.Iowait,
91
- ccusage.Hardirq, ccusage.Softirq, ccusage.Steal, ccusage.Guest, ccusage.GuestNice))
88
+ type MemUsage struct {
89
+ mem *MemStat
92
90
  }
93
91
 
94
- func (cusage *CpuUsage) WriteJsonTo(buf *bytes.Buffer) {
95
- buf.WriteString(
96
- fmt.Sprintf(`{"num_core":%d,"all":`, cusage.NumCore))
97
- cusage.All.WriteJsonTo(buf)
98
- buf.WriteString(`,"cores":[`)
99
- for idx, ccusage := range cusage.CoreUsages {
100
- if idx > 0 {
101
- buf.WriteString(",")
102
- }
103
- ccusage.WriteJsonTo(buf)
92
+ var UseColor = false
93
+
94
+ func SetUseColor(use_color bool) {
95
+ UseColor = use_color
96
+ }
97
+
98
+ func (ccusage *CpuCoreUsage) WriteJsonTo(printer *projson.JsonPrinter) {
99
+ printer.BeginObject()
100
+ printer.PutKey("usr")
101
+ printer.PutFloatFmt(ccusage.User, "%.2f")
102
+ printer.PutKey("nice")
103
+ printer.PutFloatFmt(ccusage.Nice, "%.2f")
104
+ printer.PutKey("sys")
105
+ printer.PutFloatFmt(ccusage.Sys, "%.2f")
106
+ printer.PutKey("idle")
107
+ printer.PutFloatFmt(ccusage.Idle, "%.2f")
108
+ printer.PutKey("iowait")
109
+ printer.PutFloatFmt(ccusage.Iowait, "%.2f")
110
+ printer.PutKey("hardirq")
111
+ printer.PutFloatFmt(ccusage.Hardirq, "%.2f")
112
+ printer.PutKey("softirq")
113
+ printer.PutFloatFmt(ccusage.Softirq, "%.2f")
114
+ printer.PutKey("steal")
115
+ printer.PutFloatFmt(ccusage.Steal, "%.2f")
116
+ printer.PutKey("guest")
117
+ printer.PutFloatFmt(ccusage.Guest, "%.2f")
118
+ printer.PutKey("guestnice")
119
+ printer.PutFloatFmt(ccusage.GuestNice, "%.2f")
120
+ printer.FinishObject()
121
+ }
122
+
123
+ func (cusage *CpuUsage) WriteJsonTo(printer *projson.JsonPrinter) {
124
+ printer.BeginObject()
125
+ printer.PutKey("num_core")
126
+ printer.PutInt(cusage.NumCore)
127
+ printer.PutKey("all")
128
+
129
+ cusage.All.WriteJsonTo(printer)
130
+
131
+ printer.PutKey("cores")
132
+ printer.BeginArray()
133
+ for _, ccusage := range cusage.CoreUsages {
134
+ ccusage.WriteJsonTo(printer)
104
135
  }
105
- buf.WriteString(`]}`)
136
+ printer.FinishArray()
137
+ printer.FinishObject()
106
138
  }
107
139
 
108
140
  func GetCpuCoreUsage(c1 *CpuCoreStat, c2 *CpuCoreStat) (*CpuCoreUsage, error) {
@@ -225,35 +257,68 @@ func GetInterruptUsage(t1 time.Time, i1 *InterruptStat, t2 time.Time, i2 *Interr
225
257
  return usage, nil
226
258
  }
227
259
 
228
- func (intr_usage *InterruptUsage) WriteJsonTo(buf *bytes.Buffer) {
229
- buf.WriteString("{")
230
- buf.WriteString(`"core_dev_intr":[`)
231
- for idx, core_usage := range intr_usage.CoreIntrUsages {
232
- if idx > 0 {
233
- buf.WriteString(",")
234
- }
235
- fmt.Fprintf(buf, "%.2f", core_usage.Device)
260
+ func (intr_usage *InterruptUsage) WriteJsonTo(printer *projson.JsonPrinter) {
261
+ printer.BeginObject()
262
+ printer.PutKey("core_dev_intr")
263
+ printer.BeginArray()
264
+ for _, core_usage := range intr_usage.CoreIntrUsages {
265
+ printer.PutFloatFmt(core_usage.Device, "%.2f")
236
266
  }
237
- buf.WriteString(`],"core_sys_intr":[`)
238
- for idx, core_usage := range intr_usage.CoreIntrUsages {
239
- if idx > 0 {
240
- buf.WriteString(",")
241
- }
242
- fmt.Fprintf(buf, "%.2f", core_usage.System)
267
+ printer.FinishArray()
268
+
269
+ printer.PutKey("core_sys_intr")
270
+ printer.BeginArray()
271
+ for _, core_usage := range intr_usage.CoreIntrUsages {
272
+ printer.PutFloatFmt(core_usage.System, "%.2f")
243
273
  }
244
- buf.WriteString("]")
245
- buf.WriteString("}")
274
+ printer.FinishArray()
275
+ printer.FinishObject()
246
276
  }
247
277
 
248
- func (duentry *DiskUsageEntry) WriteJsonTo(buf *bytes.Buffer) {
249
- fmt.Fprintf(buf,
250
- `{"riops":%.2f,"wiops":%.2f,"rkbyteps":%.2f,"wkbyteps":%.2f,"rlatency":%.3f,"wlatency":%.3f,"rsize":%.2f,"wsize":%.2f,"qlen":%.2f}`,
251
- duentry.RdIops, duentry.WrIops, duentry.RdSecps/2.0, duentry.WrSecps/2.0,
252
- duentry.RdLatency, duentry.WrLatency,
253
- duentry.AvgRdSize, duentry.AvgWrSize, duentry.ReqQlen)
278
+ func (duentry *DiskUsageEntry) WriteJsonTo(printer *projson.JsonPrinter) {
279
+ printer.BeginObject()
280
+ printer.PutKey("riops")
281
+ printer.PutFloatFmt(duentry.RdIops, "%.2f")
282
+ printer.PutKey("wiops")
283
+ printer.PutFloatFmt(duentry.WrIops, "%.2f")
284
+ printer.PutKey("rkbyteps")
285
+ printer.PutFloatFmt(duentry.RdSecps/2.0, "%.2f")
286
+ printer.PutKey("wkbyteps")
287
+ printer.PutFloatFmt(duentry.WrSecps/2.0, "%.2f")
288
+ printer.PutKey("rlatency")
289
+ printer.PutFloatFmt(duentry.RdLatency, "%.3f")
290
+ printer.PutKey("wlatency")
291
+ printer.PutFloatFmt(duentry.WrLatency, "%.3f")
292
+ printer.PutKey("rsize")
293
+ printer.PutFloatFmt(duentry.AvgRdSize, "%.2f")
294
+ printer.PutKey("wsize")
295
+ printer.PutFloatFmt(duentry.AvgWrSize, "%.2f")
296
+ printer.PutKey("qlen")
297
+ printer.PutFloatFmt(duentry.ReqQlen, "%.2f")
298
+ printer.FinishObject()
254
299
  }
255
300
 
256
- func (dusage *DiskUsage) WriteJsonTo(buf *bytes.Buffer) {
301
+ func strarrayToString(arr []string) string {
302
+ buf := bytes.NewBuffer([]byte{})
303
+
304
+ fmt.Fprintf(buf, "[")
305
+ for i, elem := range arr {
306
+ if i > 0 {
307
+ fmt.Fprintf(buf, ",")
308
+ }
309
+
310
+ if UseColor {
311
+ fmt.Fprintf(buf, "\033[35m\"%s\"\033[0m", elem)
312
+ } else {
313
+ fmt.Fprintf(buf, "\"%s\"", elem)
314
+ }
315
+ }
316
+ fmt.Fprintf(buf, "]")
317
+
318
+ return buf.String()
319
+ }
320
+
321
+ func (dusage *DiskUsage) WriteJsonTo(printer *projson.JsonPrinter) {
257
322
  var devices []string
258
323
 
259
324
  for device, _ := range *dusage {
@@ -263,23 +328,24 @@ func (dusage *DiskUsage) WriteJsonTo(buf *bytes.Buffer) {
263
328
  }
264
329
  sort.Strings(devices)
265
330
 
266
- bytes, err := json.Marshal(devices)
267
- if err != nil {
268
- panic(err)
331
+ printer.BeginObject()
332
+ printer.PutKey("devices")
333
+ printer.BeginArray()
334
+ for _, device := range devices {
335
+ printer.PutString(device)
269
336
  }
270
- fmt.Fprintf(buf, `{"devices":%s`, string(bytes))
337
+ printer.FinishArray()
271
338
 
272
339
  devices = append(devices, "total")
273
340
 
274
341
  for _, device := range devices {
275
342
  usage := (*dusage)[device]
276
- buf.WriteString(`,"`)
277
- buf.WriteString(device)
278
- buf.WriteString(`":`)
279
- usage.WriteJsonTo(buf)
343
+
344
+ printer.PutKey(device)
345
+ usage.WriteJsonTo(printer)
280
346
  }
281
347
 
282
- buf.WriteByte('}')
348
+ printer.FinishObject()
283
349
  }
284
350
 
285
351
  func avgDelta(v int64, w int64, interval float64) float64 {
@@ -470,7 +536,7 @@ func GetNetUsage(t1 time.Time, d1 *NetStat, t2 time.Time, d2 *NetStat) (*NetUsag
470
536
  return net_usage, nil
471
537
  }
472
538
 
473
- func (nusage *NetUsage) WriteJsonTo(buf *bytes.Buffer) {
539
+ func (nusage *NetUsage) WriteJsonTo(printer *projson.JsonPrinter) {
474
540
  var devices []string
475
541
 
476
542
  for device, _ := range *nusage {
@@ -480,30 +546,121 @@ func (nusage *NetUsage) WriteJsonTo(buf *bytes.Buffer) {
480
546
  }
481
547
  sort.Strings(devices)
482
548
 
483
- bytes, err := json.Marshal(devices)
484
- if err != nil {
485
- panic(err)
549
+ printer.BeginObject()
550
+ printer.PutKey("devices")
551
+ printer.BeginArray()
552
+ for _, device := range devices {
553
+ printer.PutString(device)
486
554
  }
487
- fmt.Fprintf(buf, `{"devices":%s`, string(bytes))
555
+ printer.FinishArray()
488
556
 
489
557
  devices = append(devices, "total")
490
558
 
491
559
  for _, device := range devices {
492
560
  usage := (*nusage)[device]
493
- buf.WriteString(`,"`)
494
- buf.WriteString(device)
495
- buf.WriteString(`":`)
496
- usage.WriteJsonTo(buf)
561
+
562
+ printer.PutKey(device)
563
+ usage.WriteJsonTo(printer)
564
+ }
565
+
566
+ printer.FinishObject()
567
+ }
568
+
569
+ func GetMemUsage(mem *MemStat) (*MemUsage, error) {
570
+ if mem == nil {
571
+ return nil, errors.New("invalid memstat")
497
572
  }
498
573
 
499
- buf.WriteByte('}')
574
+ musage := new(MemUsage)
575
+ musage.mem = mem
576
+
577
+ return musage, nil
578
+ }
579
+
580
+ func (musage *MemUsage) WriteJsonTo(printer *projson.JsonPrinter) {
581
+ printer.BeginObject()
582
+
583
+ printer.PutKey("mem_total")
584
+ printer.PutInt64(musage.mem.MemTotal)
585
+ printer.PutKey("mem_used")
586
+ printer.PutInt64(musage.mem.MemTotal - musage.mem.MemFree - musage.mem.Buffers - musage.mem.Cached - musage.mem.SReclaimable)
587
+ printer.PutKey("mem_free")
588
+ printer.PutInt64(musage.mem.MemFree)
589
+ printer.PutKey("buffers")
590
+ printer.PutInt64(musage.mem.Buffers)
591
+ printer.PutKey("cached")
592
+ printer.PutInt64(musage.mem.Cached)
593
+ printer.PutKey("swap_cached")
594
+ printer.PutInt64(musage.mem.SwapCached)
595
+ printer.PutKey("active")
596
+ printer.PutInt64(musage.mem.Active)
597
+ printer.PutKey("inactive")
598
+ printer.PutInt64(musage.mem.Inactive)
599
+ printer.PutKey("swap_total")
600
+ printer.PutInt64(musage.mem.SwapTotal)
601
+ printer.PutKey("swap_free")
602
+ printer.PutInt64(musage.mem.SwapFree)
603
+ printer.PutKey("dirty")
604
+ printer.PutInt64(musage.mem.Dirty)
605
+ printer.PutKey("writeback")
606
+ printer.PutInt64(musage.mem.Writeback)
607
+ printer.PutKey("anon_pages")
608
+ printer.PutInt64(musage.mem.AnonPages)
609
+ printer.PutKey("mapped")
610
+ printer.PutInt64(musage.mem.Mapped)
611
+ printer.PutKey("shmem")
612
+ printer.PutInt64(musage.mem.Shmem)
613
+ printer.PutKey("slab")
614
+ printer.PutInt64(musage.mem.Slab)
615
+ printer.PutKey("s_reclaimable")
616
+ printer.PutInt64(musage.mem.SReclaimable)
617
+ printer.PutKey("s_unreclaim")
618
+ printer.PutInt64(musage.mem.SUnreclaim)
619
+ printer.PutKey("kernel_stack")
620
+ printer.PutInt64(musage.mem.KernelStack)
621
+ printer.PutKey("page_tables")
622
+ printer.PutInt64(musage.mem.PageTables)
623
+ printer.PutKey("nfs_unstable")
624
+ printer.PutInt64(musage.mem.NFS_Unstable)
625
+ printer.PutKey("bounce")
626
+ printer.PutInt64(musage.mem.Bounce)
627
+ printer.PutKey("commit_limit")
628
+ printer.PutInt64(musage.mem.CommitLimit)
629
+ printer.PutKey("committed_as")
630
+ printer.PutInt64(musage.mem.Committed_AS)
631
+ printer.PutKey("anon_huge_pages")
632
+ printer.PutInt64(musage.mem.AnonHugePages)
633
+ printer.PutKey("huge_pages_total")
634
+ printer.PutInt64(musage.mem.HugePages_Total)
635
+ printer.PutKey("huge_pages_free")
636
+ printer.PutInt64(musage.mem.HugePages_Free)
637
+ printer.PutKey("huge_pages_rsvd")
638
+ printer.PutInt64(musage.mem.HugePages_Rsvd)
639
+ printer.PutKey("huge_pages_surp")
640
+ printer.PutInt64(musage.mem.HugePages_Surp)
641
+
642
+ printer.FinishObject()
500
643
  }
501
644
 
502
- func (entry *NetUsageEntry) WriteJsonTo(buf *bytes.Buffer) {
503
- buf.WriteString(
504
- fmt.Sprintf(`{"rxkbyteps":%.2f,"rxpktps":%.2f,"rxerrps":%.2f,"rxdropps":%.2f,"txkbyteps":%.2f,"txpktps":%.2f,"txerrps":%.2f,"txdropps":%.2f}`,
505
- entry.RxBytesPerSec/1024.0, entry.RxPacketsPerSec,
506
- entry.RxErrorsPerSec, entry.RxDropsPerSec,
507
- entry.TxBytesPerSec/1024.0, entry.TxPacketsPerSec,
508
- entry.TxErrorsPerSec, entry.TxDropsPerSec))
645
+ func (entry *NetUsageEntry) WriteJsonTo(printer *projson.JsonPrinter) {
646
+ printer.BeginObject()
647
+
648
+ printer.PutKey("rxkbyteps")
649
+ printer.PutFloatFmt(entry.RxBytesPerSec/1024.0, "%.2f")
650
+ printer.PutKey("rxpktps")
651
+ printer.PutFloatFmt(entry.RxPacketsPerSec, "%.2f")
652
+ printer.PutKey("rxerrps")
653
+ printer.PutFloatFmt(entry.RxErrorsPerSec, "%.2f")
654
+ printer.PutKey("rxdropps")
655
+ printer.PutFloatFmt(entry.RxDropsPerSec, "%.2f")
656
+ printer.PutKey("txkbyteps")
657
+ printer.PutFloatFmt(entry.TxBytesPerSec/1024.0, "%.2f")
658
+ printer.PutKey("txpktps")
659
+ printer.PutFloatFmt(entry.TxPacketsPerSec, "%.2f")
660
+ printer.PutKey("txerrps")
661
+ printer.PutFloatFmt(entry.TxErrorsPerSec, "%.2f")
662
+ printer.PutKey("txdropps")
663
+ printer.PutFloatFmt(entry.TxDropsPerSec, "%.2f")
664
+
665
+ printer.FinishObject()
509
666
  }
@@ -1,7 +1,6 @@
1
1
  package subsystem
2
2
 
3
3
  import (
4
- "bytes"
5
4
  "encoding/json"
6
5
  "math"
7
6
  "regexp"
@@ -9,6 +8,8 @@ import (
9
8
  "strings"
10
9
  "testing"
11
10
  "time"
11
+
12
+ projson "github.com/hayamiz/go-projson"
12
13
  )
13
14
 
14
15
  func isValidJson(byt []byte) bool {
@@ -89,7 +90,7 @@ func TestGetCoreUsage(t *testing.T) {
89
90
  usage.Steal == 0 &&
90
91
  usage.Guest == 0 &&
91
92
  usage.GuestNice == 0) {
92
- t.Error("usage is not 0%, want 0%")
93
+ t.Error("usage is not 0 percent, want 0 percent")
93
94
  }
94
95
 
95
96
  // should return error if c1.Uptime() is larger than c2.Uptime()
@@ -120,10 +121,14 @@ func TestGetCoreUsage(t *testing.T) {
120
121
  t.Errorf("usage.Sys = %v, want 25.0", usage.User)
121
122
  }
122
123
 
123
- buf := bytes.NewBuffer([]byte{})
124
- usage.WriteJsonTo(buf)
125
- if !isValidJson(buf.Bytes()) {
126
- t.Errorf("Invalid JSON: %s", buf.String())
124
+ printer := projson.NewPrinter()
125
+ usage.WriteJsonTo(printer)
126
+ if str, err := printer.String(); err != nil {
127
+ t.Errorf("failed to print JSON")
128
+ } else {
129
+ if !isValidJson([]byte(str)) {
130
+ t.Errorf("Invalid JSON: %s", str)
131
+ }
127
132
  }
128
133
  }
129
134
 
@@ -207,15 +212,20 @@ func TestGetCpuUsage(t *testing.T) {
207
212
  t.Errorf("usage.Sys = %v, want 25.0", usage.CoreUsages[1].User)
208
213
  }
209
214
 
210
- buf := bytes.NewBuffer([]byte{})
211
- usage.WriteJsonTo(buf)
212
- if !isValidJson(buf.Bytes()) {
213
- t.Errorf("Invalid JSON: %s", buf.String())
215
+ printer := projson.NewPrinter()
216
+ usage.WriteJsonTo(printer)
217
+ str, err := printer.String()
218
+ if err != nil {
219
+ t.Errorf("failed printing JSON")
220
+ } else {
221
+ if !isValidJson([]byte(str)) {
222
+ t.Errorf("Invalid JSON: %s", str)
223
+ }
214
224
  }
215
225
 
216
226
  assertHasKey := func(key_path string) {
217
- if !jsonHasKey(buf.Bytes(), key_path) {
218
- t.Errorf("%v is not present in JSON:\n%v", key_path, buf.String())
227
+ if !jsonHasKey([]byte(str), key_path) {
228
+ t.Errorf("%v is not present in JSON:\n%v", key_path, str)
219
229
  }
220
230
  }
221
231
  assertHasKey("num_core")
@@ -291,10 +301,15 @@ func TestDiskUsage(t *testing.T) {
291
301
  t.Errorf("sda.RdSectors = %v, want %v", (*usage)["sda"].RdSectors, 350)
292
302
  }
293
303
 
294
- buf := bytes.NewBuffer([]byte{})
295
- usage.WriteJsonTo(buf)
296
- if !isValidJson(buf.Bytes()) {
297
- t.Errorf("invalid json: %s", buf.String())
304
+ printer := projson.NewPrinter()
305
+ usage.WriteJsonTo(printer)
306
+ str, err := printer.String()
307
+ if err != nil {
308
+ t.Errorf("failed printing JSON")
309
+ } else {
310
+ if !isValidJson([]byte(str)) {
311
+ t.Errorf("invalid json: %s", str)
312
+ }
298
313
  }
299
314
 
300
315
  d1.Entries = append(d1.Entries, NewDiskStatEntry())
@@ -347,15 +362,20 @@ func TestDiskUsage(t *testing.T) {
347
362
  t.Errorf("total.RdSectors = %v, want %v", (*usage)["total"].RdSectors, 350)
348
363
  }
349
364
 
350
- buf = bytes.NewBuffer([]byte{})
351
- usage.WriteJsonTo(buf)
352
- if !isValidJson(buf.Bytes()) {
353
- t.Errorf("invalid json: %s", buf.String())
365
+ printer = projson.NewPrinter()
366
+ usage.WriteJsonTo(printer)
367
+ str, err = printer.String()
368
+ if err != nil {
369
+ t.Errorf("failed printing JSON")
370
+ } else {
371
+ if !isValidJson([]byte(str)) {
372
+ t.Errorf("invalid json: %s", str)
373
+ }
354
374
  }
355
375
 
356
376
  assertHasKey := func(key_path string) {
357
- if !jsonHasKey(buf.Bytes(), key_path) {
358
- t.Errorf("%v is not present in JSON:\n%v", key_path, buf.String())
377
+ if !jsonHasKey([]byte(str), key_path) {
378
+ t.Errorf("%v is not present in JSON:\n%v", key_path, str)
359
379
  }
360
380
  }
361
381
  assertHasKey("devices")
@@ -428,10 +448,15 @@ func TestGetNetUsage(t *testing.T) {
428
448
  t.Errorf("lo.RxPacketsPerSec = %v, want %v", (*usage)["lo"].RxPacketsPerSec, 100.0/interval)
429
449
  }
430
450
 
431
- buf := bytes.NewBuffer([]byte{})
432
- usage.WriteJsonTo(buf)
433
- if !isValidJson(buf.Bytes()) {
434
- t.Errorf("invalid json: %s", buf.String())
451
+ printer := projson.NewPrinter()
452
+ usage.WriteJsonTo(printer)
453
+ str, err := printer.String()
454
+ if err != nil {
455
+ t.Errorf("failed printing JSON")
456
+ } else {
457
+ if !isValidJson([]byte(str)) {
458
+ t.Errorf("invalid json: %s", str)
459
+ }
435
460
  }
436
461
 
437
462
  n1.Entries = append(n1.Entries, NewNetStatEntry())
@@ -483,15 +508,20 @@ func TestGetNetUsage(t *testing.T) {
483
508
  (100.0+150.0)/interval)
484
509
  }
485
510
 
486
- buf = bytes.NewBuffer([]byte{})
487
- usage.WriteJsonTo(buf)
488
- if !isValidJson(buf.Bytes()) {
489
- t.Errorf("invalid json: %s", buf.String())
511
+ printer = projson.NewPrinter()
512
+ usage.WriteJsonTo(printer)
513
+ str, err = printer.String()
514
+ if err != nil {
515
+ t.Errorf("failed printing JSON")
516
+ } else {
517
+ if !isValidJson([]byte(str)) {
518
+ t.Errorf("invalid json: %s", str)
519
+ }
490
520
  }
491
521
 
492
522
  assertHasKey := func(key_path string) {
493
- if !jsonHasKey(buf.Bytes(), key_path) {
494
- t.Errorf("%v is not present in JSON:\n%v", key_path, buf.String())
523
+ if !jsonHasKey([]byte(str), key_path) {
524
+ t.Errorf("%v is not present in JSON:\n%v", key_path, str)
495
525
  }
496
526
  }
497
527
  assertHasKey("devices")