github.com/jn0/go-json@v0.1.0/json_test.go (about) 1 package json 2 3 import "testing" 4 import "github.com/stretchr/testify/assert" 5 6 import ( // for Example* 7 "fmt" 8 "io/ioutil" 9 "os" 10 "strings" 11 "time" 12 ) 13 14 func BenchmarkAll(b *testing.B) { 15 b.ResetTimer() 16 for i := 0; i < 1000; i++ { 17 ParseValue(source) 18 } 19 } 20 21 func ExampleUptime() { 22 // Suppose you have to feed some data to a monitor. 23 // The API makes you to use JSON. 24 // One of the monitored values is system uptime. 25 26 // Read the data from `procfs(5)` (or run `uptime(1)` and catch its output) 27 const uptime = "/proc/uptime" 28 data, err := ioutil.ReadFile(uptime) 29 if err != nil { 30 fmt.Fprintf(os.Stderr, "ioutil.ReadFile(%+q): %v", uptime, err) 31 return // handle file access/read error here 32 } 33 // It should arrive as something like "3294591.50 12242861.60\n", 34 // where the first token is uptime (the 2nd one we wont use). 35 36 word := strings.Split(strings.TrimSpace(string(data)), " ") 37 if len(word) != 2 { 38 fmt.Fprintf(os.Stderr, "Garbage read from %+q: %v", uptime, data) 39 return // not much one can do if there is a "syntax error"... 40 } 41 42 // Use these values instead of "stable" fakes below 43 now := time.Now().UTC().Unix() // an integer 44 val := word[0] // a string (float will be parsed) 45 46 now = 1576839878 // fake 47 val = "3295164.960" // fake; still use string here, a "real" float would be ok too 48 49 report := new(JsonObject) // The report. 50 report.Insert("time", NewJsonInt(now)) // Add time stamp. 51 report.Insert("uptime", NewJsonFloat(val)) // Add the value reported. 52 53 fmt.Println(report.Json()) // Produce JSON text... 54 // Output: 55 // { "time": 1576839878, "uptime": 3295164.960000 } 56 } 57 58 func TestPanics(t *testing.T) { 59 // The only parser that panics is parseString for wrong \uXXXX things. 60 61 i1 := new(JsonInt) 62 assert.Panics(t, func() { i1.Set(123.123) }, "Int.Set(Float)") 63 assert.Panics(t, func() { i1.Append(123) }, "Int.Append()") 64 assert.Panics(t, func() { i1.Insert("xyz", 123) }, "Int.Insert()") 65 66 f1 := new(JsonFloat) 67 assert.Panics(t, func() { f1.Set(123) }, "Float.Set(Int)") 68 assert.Panics(t, func() { f1.Append(123.123) }, "Float.Append()") 69 assert.Panics(t, func() { f1.Insert("xyz", 123.123) }, "Float.Insert()") 70 71 b1 := new(JsonBool) 72 assert.Panics(t, func() { b1.Set(123.123) }, "Bool.Set(Float)") 73 assert.Panics(t, func() { b1.Parse("never") }, "Bool.Parse(garbage)") 74 assert.Panics(t, func() { b1.Append(true) }, "Bool.Append()") 75 assert.Panics(t, func() { b1.Insert("xyz", true) }, "Bool.Insert()") 76 77 s1 := new(JsonString) 78 assert.Panics(t, func() { s1.Set(123.123) }, "String.Set(Float)") 79 assert.Panics(t, func() { s1.Append("123") }, "String.Append()") 80 assert.Panics(t, func() { s1.Insert("xyz", "123") }, "String.Insert()") 81 assert.Panics(t, func() { s1.Parse(`"zzz\u123zzz"`) }, `String.Parse("\u123z")`) 82 83 a1 := new(JsonArray) 84 assert.Panics(t, func() { a1.Set(123.123) }, "Array.Set(Float)") 85 assert.Panics(t, func() { a1.Insert("xyz", 123) }, "Array.Insert()") 86 87 o1 := new(JsonObject) 88 assert.Panics(t, func() { o1.Set(123.123) }, "Object.Set(Float)") 89 assert.Panics(t, func() { o1.Append(123) }, "Object.Append()") 90 assert.Panics(t, func() { o1.Insert("xyz", o1) }, "Object looped") 91 92 t.Logf("All panics performed") 93 } 94 95 func TestValues(t *testing.T) { 96 97 var is = 12345 98 i1 := NewJsonInt(is) 99 i2 := new(JsonInt) 100 var i0 *JsonInt 101 if i0.Json() != "null" { 102 t.Errorf("int: %q != null", i0.Json()) 103 } 104 if e := i2.Parse(i1.Json()); e != nil { 105 t.Errorf("int: Parse(%+q): %v", i1.Json(), e) 106 } 107 if !i1.Equal(i2) { 108 t.Errorf("int: !parse.Equal(json): %q != %q", i1.Json(), i2.Json()) 109 } 110 if i1.Json() != i2.Json() { 111 t.Errorf("int: parse != json: %q != %q", i1.Json(), i2.Json()) 112 } 113 i1.Set(int8(123)) 114 i2.Set(int32(123)) 115 if !i1.Equal(i2) { 116 t.Errorf("int: !Equal(): %q != %q", i1.Json(), i2.Json()) 117 } 118 i1.Set(int(12388)) 119 i2.Set(int16(12388)) 120 if !i1.Equal(i2) { 121 t.Errorf("int: !Equal(): %q != %q", i1.Json(), i2.Json()) 122 } 123 i1.Set(int(12399)) 124 i2.Set("12399") 125 if !i1.Equal(i2) { 126 t.Errorf("int: !Equal(): %q != %q", i1.Json(), i2.Json()) 127 } 128 i1.Set(int64(111)) 129 i2.Set(222) 130 if i1.Equal(i2) { 131 t.Errorf("int: Equal(): %q == %q", i1.Json(), i2.Json()) 132 } 133 if i1.Equal(new(JsonFloat)) { 134 t.Errorf("int: Equal(): %q == Float", i1.Json()) 135 } 136 137 var f0 *JsonFloat 138 if f0.Json() != "null" { 139 t.Errorf("float: %q != null", f0.Json()) 140 } 141 var fs = -3.1 142 f1 := NewJsonFloat(fs) 143 f2 := new(JsonFloat) 144 if e := f2.Parse(f1.Json()); e != nil { 145 t.Errorf("string: Parse(%+q): %v", f1.Json(), e) 146 } 147 if f1.Equal(i1) { 148 t.Errorf("float: Equal(int): %q != %q", f1.Json(), i1.Json()) 149 } 150 if !f1.Equal(f2) { 151 t.Errorf("float: !parse.Equal(json): %q != %q", f1.Json(), f2.Json()) 152 } 153 if f1.Json() != f2.Json() { 154 t.Errorf("float: parse != json: %q != %q", f1.Json(), f2.Json()) 155 } 156 f1.Set(123.2) 157 f2.Set("123.2") 158 if !f1.Equal(f2) || 159 f1.Value() != 123.2 || f2.Value() != 123.2 || 160 f1.Value() != f2.Value() { 161 t.Errorf("float: !Equal(): %q != %q", f1.Json(), f2.Json()) 162 } 163 f1.Set(float32(123.4)) 164 f2.Set(float64(123.4)) 165 if !f1.Equal(f2) { 166 t.Logf("float: !Equal(): %q=%f != %q=%f (IT HAPPENS)", 167 f1.Json(), f1.Value(), f2.Json(), f2.Value()) 168 } 169 if e := f2.Parse("asd"); e == nil { 170 t.Errorf("string: Parse(%+q): no error", "asd") 171 } 172 173 var b0 *JsonBool 174 if b0.Json() != "null" { 175 t.Errorf("float: %q != null", b0.Json()) 176 } 177 var bs = true 178 b1 := NewJsonBool(bs) 179 b2 := new(JsonBool) 180 if e := b2.Parse(b1.Json()); e != nil { 181 t.Errorf("string: Parse(%+q): %v", b1.Json(), e) 182 } 183 if !b1.Equal(b2) || !(b1.Value().(bool)) || !(b2.Value().(bool)) { 184 t.Errorf("bool: !parse.Equal(json): %q != %q", b1.Json(), b2.Json()) 185 } 186 if b1.Json() != b2.Json() { 187 t.Errorf("bool: parse != json: %q != %q", b1.Json(), b2.Json()) 188 } 189 b1.Set(true) 190 b2.Set(!false) 191 if !b1.Equal(b2) || !(b1.Value().(bool)) || !(b2.Value().(bool)) { 192 t.Errorf("bool: !Equal(): %q != %q", b1.Json(), b2.Json()) 193 } 194 b1.Set("true") 195 b2.Set("false") 196 if b1.Equal(b2) || !(b1.Value().(bool)) || (b2.Value().(bool)) { 197 t.Errorf("bool: Equal(): %q != %q", b1.Json(), b2.Json()) 198 } 199 if b1.Equal(i1) { 200 t.Errorf("bool: Equal(Int): %q == %q", b1.Json(), i1.Json()) 201 } 202 203 var s0 *JsonString 204 if s0.Json() != "null" { 205 t.Errorf("string: %q != null", s0.Json()) 206 } 207 var ss = "some string" 208 s1 := NewJsonString(ss) 209 s2 := new(JsonString) 210 if e := s2.Parse(s1.Json()); e != nil { 211 t.Errorf("string: Parse(%+q): %v", s1.Json(), e) 212 } 213 if s1.Equal(i1) { 214 t.Errorf("string: Equal(Int): %q != %q", s1.Json(), i1.Json()) 215 } 216 if !s1.Equal(s2) { 217 t.Errorf("string: !parse.Equal(json): %q != %q", s1.Json(), s2.Json()) 218 } 219 if s1.Json() != s2.Json() { 220 t.Errorf("string: parse != json: %q != %q", s1.Json(), s2.Json()) 221 } 222 if s1.Value() != ss { 223 t.Errorf("string: %q != %q", s1.Json(), ss) 224 } 225 s1.Set("string one") 226 s2.Set("string one") 227 if !s1.Equal(s2) { 228 t.Errorf("string: !Equal(): %q != %q", s1.Json(), s2.Json()) 229 } 230 s2.Parse("\"string one\"") 231 if !s1.Equal(s2) { 232 t.Errorf("string: !Equal(): %q != %q", s1.Json(), s2.Json()) 233 } 234 if e := s2.Parse(`bad string`); e == nil { 235 t.Errorf("string: Parse(garbage) passed") 236 } 237 if e := s2.Parse(`"bad string"XXX`); e == nil { 238 t.Errorf(`string: Parse("string"garbage) passed`) 239 } 240 241 var a0, a2 *JsonArray 242 if a0.Json() != "null" { 243 t.Errorf("array: %q != null", a0.Json()) 244 } 245 if !a0.Equal(a2) { 246 t.Errorf("array: %q != %q", a0.Json(), a2.Json()) 247 } 248 var as = []JsonValue{i1, b1, s1, nil} // don't use floats! they aren't equal 249 a1 := NewJsonArray(as) 250 a1.Append(NewJsonInt(-35)) 251 a2 = new(JsonArray) 252 if a0.Equal(a1) { 253 t.Errorf("array: %q == %q", a0.Json(), a1.Json()) 254 } 255 if !a0.Equal(a2) { 256 t.Errorf("array: %q != %q", a0.Json(), a2.Json()) 257 } 258 a1.Value() 259 a0 = new(JsonArray) 260 if !a0.Equal(a2) { 261 t.Errorf("array: %q == %q", a0.Json(), a2.Json()) 262 } 263 if e := a2.Parse(a1.Json()); e != nil { 264 t.Errorf("string: Parse(%+q): %v", a1.Json(), e) 265 } 266 if a1.Equal(i1) { 267 t.Errorf("array: %q != %q", a1.Json(), i1.Json()) 268 } 269 if !a1.Equal(a2) { 270 t.Errorf("array: !parse.Equal(json): %q != %q", a1.Json(), a2.Json()) 271 } 272 if a1.Json() != a2.Json() { 273 t.Errorf("array: parse != json: %q != %q", a1.Json(), a2.Json()) 274 } 275 a1.Append(NewJsonInt(999)) 276 if a1.Equal(a2) { 277 t.Errorf("array: Equal(): %q != %q", a1.Json(), a2.Json()) 278 } 279 a1.Set([]JsonValue{i1, b1, s1, i0}) 280 if a1.Equal(a2) { 281 t.Errorf("array: Equal(): %q == %q", a1.Json(), a2.Json()) 282 } 283 a1.Set([]JsonValue{i1, b1, s1, nil}) 284 if a1.Equal(a2) { 285 t.Errorf("array: Equal(): %q == %q", a1.Json(), a2.Json()) 286 } 287 if a1.Json() == a2.Json() { 288 t.Errorf("array: %q == %q", a1.Json(), a2.Json()) 289 } 290 a1 = NewJsonArray([]JsonValue{i1, b1, s1, i1}) 291 a2 = NewJsonArray([]JsonValue{i1, b1, s1, i2}) 292 if a1.Equal(a2) { 293 fmt.Println(a1.Json()) 294 fmt.Println(a2.Json()) 295 t.Errorf("array: Equal(): %q == %q", a1.Json(), a2.Json()) 296 } 297 a1 = NewJsonArray([]JsonValue{i1, b1, s1, i2}) 298 a2 = NewJsonArray([]JsonValue{i1, b1, s1, nil}) 299 if a1.Equal(a2) { 300 fmt.Println(a1.Json()) 301 fmt.Println(a2.Json()) 302 t.Errorf("array: Equal(): %q == %q", a1.Json(), a2.Json()) 303 } 304 a1 = NewJsonArray([]JsonValue{i1, b1, s1, i0}) 305 a2 = NewJsonArray([]JsonValue{i1, b1, s1, nil}) 306 if !a1.Equal(a2) { 307 fmt.Println(a1.Json()) 308 fmt.Println(a2.Json()) 309 t.Errorf("array: Equal(): %q != %q", a1.Json(), a2.Json()) 310 } 311 if e := a0.Parse(`[x]`); e == nil { 312 t.Errorf("array: Parse(): no error") 313 } 314 if e := a0.Parse(`[0],`); e == nil { 315 t.Errorf("array: Parse(): no error") 316 } 317 a1.Set(as) 318 319 var os = map[string]JsonValue{ 320 "one": i1, 321 "two": s1, 322 "tree": nil, 323 "list": a1, 324 "bool": b1, 325 } 326 var o0 *JsonObject 327 o1 := NewJsonObject(os) 328 o1.Value() 329 // o1.Insert("self", o1) // he-he... 330 o2 := new(JsonObject) 331 if !o2.IsNull() { 332 t.Errorf("object: not (%+q).IsNull()", o2.Json()) 333 } 334 if !o2.Equal(o0) { 335 t.Errorf("object: %q != %q", o2.Json(), o0.Json()) 336 } 337 o1.Insert("new", NewJsonInt(-35)) 338 if o2.Equal(o1) { 339 t.Errorf("object: %q == %q", o2.Json(), o1.Json()) 340 } 341 if e := o2.Parse(o1.Json()); e != nil { 342 t.Errorf("object: Parse(%+q): %v", o1.Json(), e) 343 } 344 if !o1.Equal(o2) { 345 fmt.Println(o1.Json()) 346 fmt.Println(o2.Json()) 347 t.Errorf("object: !parse.Equal(json): %q != %q", o1.Json(), o2.Json()) 348 } 349 o2.Insert("other", o1) 350 if o1.Equal(o2) { 351 t.Errorf("object: Equal(): %q != %q", o1.Json(), o2.Json()) 352 } 353 if e := o2.Parse(`x`); e == nil { 354 t.Errorf("object: Parse(junk): no error") 355 } 356 if e := o2.Parse(`{"x":1},`); e == nil { 357 t.Errorf("object: Parse(tail): no error") 358 } 359 o2.Set(*o1) 360 if !o2.Equal(o1) { 361 fmt.Println(o1.Json()) 362 fmt.Println(o2.Json()) 363 t.Errorf("object: %q != %q", o2.Json(), o1.Json()) 364 } 365 o2.Set(o1) 366 if !o2.Equal(o1) { 367 fmt.Println(o1.Json()) 368 fmt.Println(o2.Json()) 369 t.Errorf("object: %q != %q", o2.Json(), o1.Json()) 370 } 371 o2.Set(o1.Value()) 372 if !o2.Equal(o1) { 373 fmt.Println(o1.Json()) 374 fmt.Println(o2.Json()) 375 t.Errorf("object: %q != %q", o2.Json(), o1.Json()) 376 } 377 o1.Insert("diff", new(JsonInt)) 378 o2.Insert("diff", NewJsonInt(1)) 379 if o2.Equal(o1) { 380 fmt.Println(o1.Json()) 381 fmt.Println(o2.Json()) 382 t.Errorf("object: %q == %q", o2.Json(), o1.Json()) 383 } 384 o2.Set(o1.Value()) 385 o1.Insert("xx1", NewJsonInt(1)) 386 o2.Insert("xx2", NewJsonInt(1)) 387 if o2.Equal(o1) { 388 fmt.Println(o1.Json()) 389 fmt.Println(o2.Json()) 390 t.Errorf("object: %q == %q", o2.Json(), o1.Json()) 391 } 392 393 } 394 395 func TestParsers(t *testing.T) { 396 397 test := func( 398 s string, 399 f func(string) (JsonValue, string, error), 400 eval func(JsonValue, string, error) bool, 401 ) { 402 v, tail, err := f(s) 403 ok := eval(v, tail, err) 404 x := t.Logf 405 if !ok { 406 x = t.Errorf 407 } 408 o := "" 409 if v != nil { 410 o = v.Json() 411 } 412 x("s=%q (v=%#v=%s tail=%#v err=%#v) ok=%v", s, v, o, tail, err, ok) 413 } 414 415 noerr := func(v JsonValue, t string, e error) bool { return e == nil } 416 erratic := func(v JsonValue, t string, e error) bool { return e != nil } 417 notail := func(v JsonValue, t string, e error) bool { return t == "" } 418 taily := func(v JsonValue, t string, e error) bool { return t != "" } 419 clean := func(v JsonValue, t string, e error) bool { return noerr(v, t, e) && notail(v, t, e) } 420 421 test(`bad`, parseObject, erratic) 422 test(` bad `, parseObject, erratic) 423 test(` `, parseObject, erratic) 424 test(`{ "simple": "object" }`, parseObject, clean) 425 test(` { "simple" : "object" } `, parseObject, clean) 426 test(`{ "simple": "object" }, 1`, parseObject, taily) 427 test(`{ "": "object" }, 1`, parseObject, taily) 428 test(`{ "simple": "" }, 1`, parseObject, taily) 429 test(`{ "better": "object", "one": 1, "null": null, "neg": -2.5 }`, parseObject, clean) 430 test(`{ "simple" = "bad object"}`, parseObject, erratic) 431 test(`{ "simple": "bad object"`, parseObject, erratic) 432 test(`{ "simple": }`, parseObject, erratic) 433 test(`{ "simple": `, parseObject, erratic) 434 test(`{ "simple" `, parseObject, erratic) 435 test(`{ "simple": "bad object }`, parseObject, erratic) 436 test(`{ "simple": "bad object", }`, parseObject, erratic) 437 test(`{ "simple: bad object, }`, parseObject, erratic) 438 test(`{ "simple": "bad object",`, parseObject, erratic) 439 test(`{ "simple": "bad object" X`, parseObject, erratic) 440 test(`{ wrong: "object" }`, parseObject, erratic) 441 442 test(` `, parseArray, erratic) 443 test(` [ 1, "simple", true, "list" ] `, parseArray, clean) 444 test(`[ 1, "simple", true, "list" ]`, parseArray, clean) 445 test(` [ 1, "simple", true, "list" ], "tail"`, parseArray, taily) 446 test(`[ null, "simple", false, "list", ]`, parseArray, erratic) 447 test(`[ null, "simple", false, "list",,,0 ]`, parseArray, erratic) 448 test(`[ null, "simple", false, "list"`, parseArray, erratic) 449 test(`[ null,`, parseArray, erratic) 450 test(`[ null XXX`, parseArray, erratic) 451 test(`xxx`, parseArray, erratic) 452 453 test(`"simple\nstring"`, parseString, clean) 454 test(`"\nstring\twith\rescapes\u005c\u002Fyepp\backspace\formfeed"`, parseString, clean) 455 test(` `, parseString, erratic) 456 test(` "simple\nstring" `, parseString, clean) 457 test(` "" `, parseString, clean) 458 test(` " " `, parseString, clean) 459 test(`"simple\nstring", 123`, parseString, taily) 460 test(`"simple wrong string`, parseString, erratic) 461 test(`"simple wrong string\"`, parseString, erratic) 462 test(`simple wrong string\"`, parseString, erratic) 463 464 test(``, parseNumber, erratic) 465 test(` `, parseNumber, erratic) 466 test(`123`, parseNumber, clean) 467 test(` 123 `, parseNumber, clean) 468 test(`0123`, parseNumber, clean) 469 test(`0123.03210`, parseNumber, clean) 470 test(`+0123.03210`, parseNumber, clean) 471 test(`-0123.03210`, parseNumber, clean) 472 test(`x123`, parseNumber, erratic) 473 test(`0x123`, parseNumber, taily) 474 test(`123x`, parseNumber, taily) 475 test(`123.321`, parseNumber, clean) 476 test(`+987`, parseNumber, clean) 477 test(`-321.`, parseNumber, clean) 478 479 test(`true`, parseBool, clean) 480 test(` `, parseBool, erratic) 481 test(` xxxx `, parseBool, erratic) 482 test(`false`, parseBool, clean) 483 test(`true,xxx`, parseBool, taily) 484 test(`trUe`, parseBool, erratic) 485 486 test(`null`, parseNull, clean) 487 test(` `, parseNull, erratic) 488 test(` xxx `, parseNull, erratic) 489 test(`null,`, parseNull, taily) 490 test(`nUll`, parseNull, erratic) 491 492 test(`null`, ParseValue, clean) 493 test(`{ "not": [{ "so": "simple" }, "object"] }`, ParseValue, clean) 494 test(`[ 1, "simple", [ true, "list" ], null, -2.5 ]`, ParseValue, clean) 495 test(`"simple\nstring"`, ParseValue, clean) 496 test(`+0123.03210`, ParseValue, clean) 497 test(`false`, ParseValue, clean) 498 test(` xxx `, ParseValue, erratic) 499 test(` false `, ParseValue, clean) 500 test(` `, ParseValue, erratic) 501 } 502 503 const source = ` 504 { 505 "update": true, 506 "time": 1576745142824, 507 "uptime": 2749251.96, 508 "hostname": "jet-one", 509 "loadavg": { 510 "kernel": { 511 "runnable": 5, 512 "total": 297 513 }, 514 "last_pid": 6810, 515 "average": [ 516 1.01, 517 1.03, 518 1.11 519 ] 520 }, 521 "mounts": [ 522 { 523 "spec": "/dev/root", 524 "file": "/", 525 "vfstype": "ext4", 526 "mntops": [ 527 "rw", 528 "relatime", 529 "data=ordered" 530 ], 531 "freq": 0, 532 "passno": 0, 533 "size": { 534 "total_kb": 27736252, 535 "used_kb": 13165476, 536 "available_kb": 13138816 537 } 538 }, 539 { 540 "file": "/dev", 541 "vfstype": "devtmpfs", 542 "mntops": [ 543 "rw", 544 "relatime", 545 "size=7976116k", 546 "nr_inodes=1994029", 547 "mode=755" 548 ], 549 "freq": 0, 550 "passno": 0, 551 "size": { 552 "total_kb": 7976116, 553 "used_kb": 0, 554 "available_kb": 7976116 555 }, 556 "spec": "devtmpfs" 557 }, 558 { 559 "vfstype": "sysfs", 560 "mntops": [ 561 "rw", 562 "nosuid", 563 "nodev", 564 "noexec", 565 "relatime" 566 ], 567 "freq": 0, 568 "passno": 0, 569 "size": null, 570 "spec": "sysfs", 571 "file": "/sys" 572 }, 573 { 574 "size": null, 575 "spec": "proc", 576 "file": "/proc", 577 "vfstype": "proc", 578 "mntops": [ 579 "rw", 580 "nosuid", 581 "nodev", 582 "noexec", 583 "relatime" 584 ], 585 "freq": 0, 586 "passno": 0 587 }, 588 { 589 "passno": 0, 590 "size": { 591 "used_kb": 4612, 592 "available_kb": 8038300, 593 "total_kb": 8042912 594 }, 595 "spec": "tmpfs", 596 "file": "/dev/shm", 597 "vfstype": "tmpfs", 598 "mntops": [ 599 "rw", 600 "nosuid", 601 "nodev" 602 ], 603 "freq": 0 604 }, 605 { 606 "spec": "devpts", 607 "file": "/dev/pts", 608 "vfstype": "devpts", 609 "mntops": [ 610 "rw", 611 "nosuid", 612 "noexec", 613 "relatime", 614 "gid=5", 615 "mode=620", 616 "ptmxmode=000" 617 ], 618 "freq": 0, 619 "passno": 0, 620 "size": null 621 }, 622 { 623 "freq": 0, 624 "passno": 0, 625 "size": { 626 "total_kb": 8042912, 627 "used_kb": 833212, 628 "available_kb": 7209700 629 }, 630 "spec": "tmpfs", 631 "file": "/run", 632 "vfstype": "tmpfs", 633 "mntops": [ 634 "rw", 635 "nosuid", 636 "nodev", 637 "mode=755" 638 ] 639 }, 640 { 641 "mntops": [ 642 "rw", 643 "nosuid", 644 "nodev", 645 "noexec", 646 "relatime", 647 "size=5120k" 648 ], 649 "freq": 0, 650 "passno": 0, 651 "size": { 652 "total_kb": 5120, 653 "used_kb": 12, 654 "available_kb": 5108 655 }, 656 "spec": "tmpfs", 657 "file": "/run/lock", 658 "vfstype": "tmpfs" 659 }, 660 { 661 "vfstype": "tmpfs", 662 "mntops": [ 663 "ro", 664 "nosuid", 665 "nodev", 666 "noexec", 667 "mode=755" 668 ], 669 "freq": 0, 670 "passno": 0, 671 "size": { 672 "total_kb": 8042912, 673 "used_kb": 0, 674 "available_kb": 8042912 675 }, 676 "spec": "tmpfs", 677 "file": "/sys/fs/cgroup" 678 }, 679 { 680 "vfstype": "cgroup", 681 "mntops": [ 682 "rw", 683 "nosuid", 684 "nodev", 685 "noexec", 686 "relatime", 687 "xattr", 688 "release_agent=/lib/systemd/systemd-cgroups-agent", 689 "name=systemd" 690 ], 691 "freq": 0, 692 "passno": 0, 693 "size": null, 694 "spec": "cgroup", 695 "file": "/sys/fs/cgroup/systemd" 696 }, 697 { 698 "freq": 0, 699 "passno": 0, 700 "size": null, 701 "spec": "pstore", 702 "file": "/sys/fs/pstore", 703 "vfstype": "pstore", 704 "mntops": [ 705 "rw", 706 "nosuid", 707 "nodev", 708 "noexec", 709 "relatime" 710 ] 711 }, 712 { 713 "passno": 0, 714 "size": null, 715 "spec": "cgroup", 716 "file": "/sys/fs/cgroup/cpu,cpuacct", 717 "vfstype": "cgroup", 718 "mntops": [ 719 "rw", 720 "nosuid", 721 "nodev", 722 "noexec", 723 "relatime", 724 "cpu", 725 "cpuacct" 726 ], 727 "freq": 0 728 }, 729 { 730 "mntops": [ 731 "rw", 732 "nosuid", 733 "nodev", 734 "noexec", 735 "relatime", 736 "freezer" 737 ], 738 "freq": 0, 739 "passno": 0, 740 "size": null, 741 "spec": "cgroup", 742 "file": "/sys/fs/cgroup/freezer", 743 "vfstype": "cgroup" 744 }, 745 { 746 "passno": 0, 747 "size": null, 748 "spec": "cgroup", 749 "file": "/sys/fs/cgroup/perf_event", 750 "vfstype": "cgroup", 751 "mntops": [ 752 "rw", 753 "nosuid", 754 "nodev", 755 "noexec", 756 "relatime", 757 "perf_event" 758 ], 759 "freq": 0 760 }, 761 { 762 "mntops": [ 763 "rw", 764 "nosuid", 765 "nodev", 766 "noexec", 767 "relatime", 768 "debug" 769 ], 770 "freq": 0, 771 "passno": 0, 772 "size": null, 773 "spec": "cgroup", 774 "file": "/sys/fs/cgroup/debug", 775 "vfstype": "cgroup" 776 }, 777 { 778 "vfstype": "cgroup", 779 "mntops": [ 780 "rw", 781 "nosuid", 782 "nodev", 783 "noexec", 784 "relatime", 785 "memory" 786 ], 787 "freq": 0, 788 "passno": 0, 789 "size": null, 790 "spec": "cgroup", 791 "file": "/sys/fs/cgroup/memory" 792 }, 793 { 794 "size": null, 795 "spec": "cgroup", 796 "file": "/sys/fs/cgroup/pids", 797 "vfstype": "cgroup", 798 "mntops": [ 799 "rw", 800 "nosuid", 801 "nodev", 802 "noexec", 803 "relatime", 804 "pids" 805 ], 806 "freq": 0, 807 "passno": 0 808 }, 809 { 810 "spec": "cgroup", 811 "file": "/sys/fs/cgroup/net_cls,net_prio", 812 "vfstype": "cgroup", 813 "mntops": [ 814 "rw", 815 "nosuid", 816 "nodev", 817 "noexec", 818 "relatime", 819 "net_cls", 820 "net_prio" 821 ], 822 "freq": 0, 823 "passno": 0, 824 "size": null 825 }, 826 { 827 "size": null, 828 "spec": "cgroup", 829 "file": "/sys/fs/cgroup/cpuset", 830 "vfstype": "cgroup", 831 "mntops": [ 832 "rw", 833 "nosuid", 834 "nodev", 835 "noexec", 836 "relatime", 837 "cpuset" 838 ], 839 "freq": 0, 840 "passno": 0 841 }, 842 { 843 "spec": "cgroup", 844 "file": "/sys/fs/cgroup/blkio", 845 "vfstype": "cgroup", 846 "mntops": [ 847 "rw", 848 "nosuid", 849 "nodev", 850 "noexec", 851 "relatime", 852 "blkio" 853 ], 854 "freq": 0, 855 "passno": 0, 856 "size": null 857 }, 858 { 859 "size": null, 860 "spec": "cgroup", 861 "file": "/sys/fs/cgroup/devices", 862 "vfstype": "cgroup", 863 "mntops": [ 864 "rw", 865 "nosuid", 866 "nodev", 867 "noexec", 868 "relatime", 869 "devices" 870 ], 871 "freq": 0, 872 "passno": 0 873 }, 874 { 875 "vfstype": "debugfs", 876 "mntops": [ 877 "rw", 878 "relatime" 879 ], 880 "freq": 0, 881 "passno": 0, 882 "size": null, 883 "spec": "debugfs", 884 "file": "/sys/kernel/debug" 885 }, 886 { 887 "vfstype": "mqueue", 888 "mntops": [ 889 "rw", 890 "relatime" 891 ], 892 "freq": 0, 893 "passno": 0, 894 "size": null, 895 "spec": "mqueue", 896 "file": "/dev/mqueue" 897 }, 898 { 899 "spec": "configfs", 900 "file": "/sys/kernel/config", 901 "vfstype": "configfs", 902 "mntops": [ 903 "rw", 904 "relatime" 905 ], 906 "freq": 0, 907 "passno": 0, 908 "size": null 909 }, 910 { 911 "vfstype": "tmpfs", 912 "mntops": [ 913 "rw", 914 "nosuid", 915 "nodev", 916 "relatime", 917 "size=804292k", 918 "mode=700", 919 "uid=1001", 920 "gid=1001" 921 ], 922 "freq": 0, 923 "passno": 0, 924 "size": { 925 "total_kb": 804292, 926 "used_kb": 16, 927 "available_kb": 804276 928 }, 929 "spec": "tmpfs", 930 "file": "/run/user/1001" 931 }, 932 { 933 "freq": 0, 934 "passno": 0, 935 "size": { 936 "total_kb": 804292, 937 "used_kb": 0, 938 "available_kb": 804292 939 }, 940 "spec": "tmpfs", 941 "file": "/run/user/1002", 942 "vfstype": "tmpfs", 943 "mntops": [ 944 "rw", 945 "nosuid", 946 "nodev", 947 "relatime", 948 "size=804292k", 949 "mode=700", 950 "uid=1002", 951 "gid=1002" 952 ] 953 } 954 ], 955 "meminfo": { 956 "MemFree_kB": 3776048, 957 "MemAvailable_kB": 5085380, 958 "Buffers_kB": 199708, 959 "Cached_kB": 1904324, 960 "SwapCached_kB": 0, 961 "SwapTotal_kB": 0, 962 "SwapFree_kB": 0, 963 "MemTotal_kB": 8042912 964 }, 965 "spools": [ 966 { 967 "path": "/var/cache/jetson", 968 "exists": true, 969 "count": 0 970 } 971 ], 972 "sensors": [ 973 { 974 "adapter": "Virtual device", 975 "values": [ 976 { 977 "crit": 101, 978 "name": "temp1", 979 "input": 20.5 980 } 981 ], 982 "sensor": "BCPU-therm-virtual-0" 983 }, 984 { 985 "adapter": "Virtual device", 986 "values": [ 987 { 988 "name": "temp1", 989 "input": 20.5, 990 "crit": 101 991 } 992 ], 993 "sensor": "MCPU-therm-virtual-0" 994 }, 995 { 996 "sensor": "GPU-therm-virtual-0", 997 "adapter": "Virtual device", 998 "values": [ 999 { 1000 "crit": -40, 1001 "name": "temp1", 1002 "input": 19 1003 } 1004 ] 1005 }, 1006 { 1007 "sensor": "Tboard_tegra-virtual-0", 1008 "adapter": "Virtual device", 1009 "values": [ 1010 { 1011 "name": "temp1", 1012 "input": 18, 1013 "crit": 107 1014 } 1015 ] 1016 }, 1017 { 1018 "sensor": "Tdiode_tegra-virtual-0", 1019 "adapter": "Virtual device", 1020 "values": [ 1021 { 1022 "name": "temp1", 1023 "input": 17.75, 1024 "crit": 107 1025 } 1026 ] 1027 }, 1028 { 1029 "sensor": "thermal-fan-est-virtual-0", 1030 "adapter": "Virtual device", 1031 "values": [ 1032 { 1033 "name": "temp1", 1034 "input": 19.6 1035 } 1036 ] 1037 } 1038 ], 1039 "net": [ 1040 { 1041 "response": { 1042 "status": 200, 1043 "content_type": "text/plain; charset=utf-8", 1044 "body": "31.173.81.31" 1045 }, 1046 "url": "https://ifconfig.co/", 1047 "scheme": "https", 1048 "error": null 1049 } 1050 ] 1051 } 1052 ` 1053 1054 func TestAll(t *testing.T) { 1055 json, tail, err := ParseValue(source) 1056 if err != nil { 1057 t.Errorf("GetValue(%+q): %v", source, err) 1058 } 1059 if tail != "" { 1060 t.Errorf("%+q tail", tail) 1061 } 1062 t.Logf("%s", json.Json()) 1063 }