func TestWildcard(t *testing.T) {
	tok := start(t)
	res, err := tok.Lookup("", -1, "sys")
	if err != nil {
		t.Fatalf("*:-1:sys lookup failed: %s", err)
	}
	if res.Instance != 0 || res.Module != "cpu" {
		t.Fatalf("unexpected lookup return 1: %#v", res)
	}
	res, err = tok.Lookup("acpi", -1, "")
	if err != nil {
		t.Fatalf("acpi:-1:* lookup failed: %s", err)
	}
	if res.Instance != 0 || res.Name != "acpi" {
		t.Fatalf("unexpected lookup return 2: %#v", res)
	}
	stop(t, tok)
}
Test empty-string lookups in both module and name portions.
These should map to NULLs in the underlying kstat_lookup()
call and then give us (predictable) wildcard results.
package kstat_test
import (
	"runtime"
	"testing"
	"time"
	"github.com/siebenmann/go-kstat"
)
func start(t *testing.T) *kstat.Token {
	tok, err := kstat.Open()
	if err != nil {
		t.Fatalf("Open failure: %s", err)
	}
	return tok
}
func stop(t *testing.T, tok *kstat.Token) {
	err := tok.Close()
	if err != nil {
		t.Fatalf("Close failure: %s", err)
	}
}
func lookup(t *testing.T, tok *kstat.Token, module, name string) *kstat.KStat {
	ks, err := tok.Lookup(module, -1, name)
	if err != nil {
		t.Fatalf("lookup failure on %s:-1:%s: %s", module, name, err)
	}
	return ks
}
func kgetnamed(t *testing.T, ks *kstat.KStat, stat string) *kstat.Named {
	n, err := ks.GetNamed(stat)
	if err != nil {
		t.Fatalf("getting '%s' from %s: %s", stat, ks, err)
	}
	return n
}
func TestOpenClose(t *testing.T) {
	tok := start(t)
	stop(t, tok)
}
func TestLookupNamed(t *testing.T) {
	tok := start(t)
	ks := lookup(t, tok, "cpu", "sys")
	if ks.Module != "cpu" || ks.Name != "sys" || ks.Instance != 0 || ks.Class != "misc" {
		t.Fatalf("cpu:0:sys kstat has bad module/instance/name/class value(s): %#v", ks)
	}
	n, err := ks.GetNamed("syscall")
	if err != nil {
		t.Fatalf("1st getting cpu:-1:sys:syscall failure: %s", err)
	}
	if n.Type != kstat.Uint64 {
		t.Fatalf("%s has wrong type: %s", n, n.Type)
	}
	if n.UintVal == 0 || n.StringVal != "" || n.IntVal != 0 {
		t.Fatalf("%s value fields are not right: %#v", n, n)
	}
	if n.Name != "syscall" {
		t.Fatalf("%s kstat name mismatch: should be \"syscall\", is %q.", ks, n.Name)
	}
	n1, err := tok.GetNamed("cpu", -1, "sys", "syscall")
	if err != nil {
		t.Fatalf("2nd getting cpu:-1:sys:syscall' failure: %s", err)
	}
	if n1.Type != n.Type || n1.StringVal != n.StringVal || n1.IntVal != n.IntVal {
		t.Fatalf("inconsistent values between original and tok.GetNamed: %#v vs %#v", n, n1)
	}
	stop(t, tok)
}
func TestRefresh(t *testing.T) {
	tok := start(t)
	ks := lookup(t, tok, "unix", "system_misc")
	n := kgetnamed(t, ks, "clk_intr")
	if n.Type != kstat.Uint32 {
		t.Fatalf("%s has wrong type: %s", n, n.Type)
	}
	osnap := ks.Snaptime
	time.Sleep(time.Second * 1)
	err := ks.Refresh()
	if err != nil {
		t.Fatalf("%s refresh error: %s", ks, err)
	}
	if osnap == ks.Snaptime {
		t.Fatalf("%s snaptime did not change: %d", ks, osnap)
	}
	n2 := kgetnamed(t, ks, "clk_intr")
	if n2.UintVal == n.UintVal {
		t.Fatalf("clk_intr count did not change: still %d\n", n2.UintVal)
	}
	stop(t, tok)
}
func TestLookupSnaptime(t *testing.T) {
	tok := start(t)
	ks := lookup(t, tok, "cpu", "sys")
	if ks.Snaptime <= 0 {
		t.Fatalf("%s Snaptime is zero (unset) after .Lookup()", ks)
	}
	stop(t, tok)
}
func TestSnaptimes(t *testing.T) {
	tok := start(t)
	ks := lookup(t, tok, "cpu", "sys")
	osnap := ks.Snaptime
	n := kgetnamed(t, ks, "syscall")
	if osnap != ks.Snaptime {
		t.Fatalf("getting %s changed KStat snaptime: %d vs %d", n, osnap, ks.Snaptime)
	}
	if n.Snaptime != ks.Snaptime {
		t.Fatalf("%s snaptime not KStat snaptime: %d vs %d", n, n.Snaptime, ks.Snaptime)
	}
	n2 := kgetnamed(t, ks, "sysread")
	if n2.Snaptime != n.Snaptime {
		t.Fatalf("%s snaptime not %s snaptime: %d vs %d", n2, n, n2.Snaptime, n.Snaptime)
	}
	err := ks.Refresh()
	if err != nil {
		t.Fatalf("%s Refresh() error: %s", ks, err)
	}
	if osnap == ks.Snaptime {
		t.Fatalf("%s Snaptime not updated after Refresh", ks)
	}
	stop(t, tok)
}
func TestPostClose(t *testing.T) {
	tok := start(t)
	ks := lookup(t, tok, "cpu", "sys")
	stop(t, tok)
	_, err := tok.Lookup("cpu", -1, "sys")
	if err == nil {
		t.Fatalf("Lookup succeeds after Close")
	}
	err = ks.Refresh()
	if err == nil {
		t.Fatalf("KStat Refresh succeeds after Close")
	}
	res := tok.All()
	if len(res) > 0 {
		t.Fatalf("tok.All succeeds after Close")
	}
	_, err = ks.GetNamed("trap")
	if err == nil {
		t.Fatalf("ks.GetNamed succeeds after Close")
	}
	_, err = ks.AllNamed()
	if err == nil {
		t.Fatalf("ks.AllNamed succeeds after Close")
	}
}
func TestAlls(t *testing.T) {
	tok := start(t)
	lst := tok.All()
	if len(lst) == 0 {
		t.Fatalf("tok.All gave us a zero-length list")
	}
	ks := lookup(t, tok, "cpu", "sys")
	l2, err := ks.AllNamed()
	if err != nil {
		t.Fatalf("%s AllNamed failed: %s", ks, err)
	}
	if len(l2) == 0 {
		t.Fatalf("%s AllNamed was empty", ks)
	}
	stop(t, tok)
}
func TestNotNamed(t *testing.T) {
	tok := start(t)
	ks := lookup(t, tok, "unix", "vminfo")
	if ks.Type != 0 {
		t.Fatalf("unix:-1:vminfo has crazy type: %#v", ks)
	}
	r, err := ks.GetNamed("swap_alloc")
	if err == nil {
		t.Fatalf("getting %s as a named succeeded", r)
	}
	_, err = ks.AllNamed()
	if err == nil {
		t.Fatalf("ks.AllNamed() on %s succeeded", ks)
	}
	ks, err = tok.Lookup("sd", 0, "sd0")
	if err != nil && ks.Type == kstat.IoStat {
		_, err = ks.AllNamed()
		if err == nil {
			t.Fatalf("ks.AllNamed on %s succeeded", ks)
		}
	}
	stop(t, tok)
}
func TestNoSuch(t *testing.T) {
	tok := start(t)
	ks := lookup(t, tok, "cpu", "sys")
	res, err := ks.GetNamed("nosuch")
	if err == nil {
		t.Fatalf("ks.GetNamed succeeded: %#v", res)
	}
	res2, err := tok.Lookup("nosuch", -1, "nosuch")
	if err == nil {
		t.Fatalf("tok.Lookup succeeded: %#v", res2)
	}
	stop(t, tok)
}