package kobject_test

import (
	"bytes"
	"context"
	_ "embed"
	"encoding/json"
	"fmt"
	"io"
	"maps"
	"reflect"
	"slices"
	"strings"
	"sync"
	"testing"
	"testing/synctest"
	"unsafe"

	. "hakurei.app/internal/kobject"
	"hakurei.app/internal/uevent"
)

func TestConsume(t *testing.T) {
	t.Parallel()

	coldboot := uevent.UUID(bytes.Repeat([]byte{0xfd}, len(uevent.UUID{})))
	testCases := []struct {
		name     string
		messages []*uevent.Message
		want     map[string]*Object
		c        []map[string]string
		errs     []error
	}{
		{"drop external synth", []*uevent.Message{
			{DevPath: "\x00", Env: []string{
				"SYNTH_UUID=fe4d7c9d-b8c6-4a70-9ef1-3d8a58d18eed",
			}},
		}, map[string]*Object{}, nil, nil},

		{"unexpected coldboot", []*uevent.Message{
			{Action: uevent.KOBJ_BIND, DevPath: "\x00", Env: []string{
				"SYNTH_UUID=fdfdfdfd-fdfd-fdfd-fdfd-fdfdfdfdfdfd",
			}},
		}, map[string]*Object{}, nil, []error{
			(&Event{
				Action:  uevent.KOBJ_BIND,
				DevPath: "\x00",
				Env:     map[string]string{},
				Synth:   &coldboot,
			}).NewError(EUnexpectedColdboot, nil),
		}},

		{"sequence", []*uevent.Message{
			{Action: uevent.KOBJ_ADD, DevPath: "\x00"},
			{Action: uevent.KOBJ_OFFLINE, DevPath: "\x00"},
		}, map[string]*Object{
			"\x00": {
				State:   StateNew,
				Offline: true,
				DevPath: "\x00",
			},
		}, nil, []error{
			BadSequenceError{Got: 0, Want: 1},
		}},

		{"action", []*uevent.Message{
			{Action: 0xbeef, DevPath: "\x00"},
		}, map[string]*Object{}, nil, []error{
			fmt.Errorf("invalid action %d", 0xbeef),
		}},

		{"add", []*uevent.Message{
			{Action: uevent.KOBJ_ADD, DevPath: "\x00", Env: []string{
				"V=\xff",
				"SEQNUM=1",
			}},
			{Action: uevent.KOBJ_ADD, DevPath: "\x00", Env: []string{
				"V=\xfd",
				"SEQNUM=2",
			}},
		}, map[string]*Object{
			"\x00": {
				State:   StateNew,
				DevPath: "\x00",
				Env:     map[string]string{"V": "\xfd"},
			},
		}, nil, []error{
			(&Event{
				Action:   uevent.KOBJ_ADD,
				DevPath:  "\x00",
				Env:      map[string]string{"V": "\xfd"},
				Sequence: 2,
			}).NewError(EDuplicateAdd, &Object{
				State:   StateNew,
				DevPath: "\x00",
				Env:     map[string]string{"V": "\xff"},
			}),
		}},

		{"remove", []*uevent.Message{
			{Action: uevent.KOBJ_REMOVE, DevPath: "\x00", Env: []string{
				"SEQNUM=0",
			}},
			{Action: uevent.KOBJ_ADD, DevPath: "\x00", Env: []string{
				"SYNTH_UUID=" + coldboot.String(),
				"SEQNUM=1",
			}},
			{Action: uevent.KOBJ_BIND, DevPath: "\x00", Env: []string{
				"DRIVER=\xfd",
				"SEQNUM=2",
			}},
			{Action: uevent.KOBJ_REMOVE, DevPath: "\x00", Env: []string{
				"SEQNUM=3",
			}},
		}, map[string]*Object{}, nil, []error{
			(&Event{
				Action:  uevent.KOBJ_REMOVE,
				DevPath: "\x00",
				Env:     map[string]string{},
			}).NewError(EBadTarget, nil),
			(&Event{
				Action:   uevent.KOBJ_REMOVE,
				DevPath:  "\x00",
				Env:      map[string]string{},
				Sequence: 3,
			}).NewError(ERemoveState, &Object{
				State:   StateBound,
				DevPath: "\x00",
				Driver:  "\xfd",
			}),
		}},

		{"change", []*uevent.Message{
			{Action: uevent.KOBJ_CHANGE, DevPath: "\x00", Env: []string{
				"V=\xff",
				"SEQNUM=9",
			}},
		}, map[string]*Object{
			"\x00": {
				State:   StateColdboot,
				DevPath: "\x00",
				Env:     map[string]string{"V": "\xff"},
			},
		}, nil, []error{
			(&Event{
				Action:   uevent.KOBJ_CHANGE,
				DevPath:  "\x00",
				Sequence: 9,
				Env: map[string]string{
					"V": "\xff",
				},
			}).NewError(EBadTarget, nil),
		}},

		{"move", []*uevent.Message{
			{Action: uevent.KOBJ_MOVE, DevPath: "\x0f", Env: []string{
				"V=\xfc",
				"SEQNUM=0",
			}},
			{Action: uevent.KOBJ_MOVE, DevPath: "\x0e", Env: []string{
				"V=\xfd",
				"DEVPATH_OLD=\xff",
				"SEQNUM=1",
			}},
		}, map[string]*Object{
			"\x0f": {DevPath: "\x0f", Env: map[string]string{"V": "\xfc"}},
			"\x0e": {DevPath: "\x0e", Env: map[string]string{"V": "\xfd"}},
		}, nil, []error{
			(&Event{
				Action:  uevent.KOBJ_MOVE,
				DevPath: "\x0f",
				Env: map[string]string{
					"V": "\xfc",
				},
			}).NewError(EMalformedMove, nil),
			(&Event{
				Action:  uevent.KOBJ_MOVE,
				DevPath: "\x0e",
				Env: map[string]string{
					"V":           "\xfd",
					"DEVPATH_OLD": "\xff",
				},
				Sequence: 1,
			}).NewError(EBadTarget, nil),
		}},

		{"offline", []*uevent.Message{
			{Action: uevent.KOBJ_ONLINE, DevPath: "\xfd", Env: []string{
				"V=\xff",
				"SEQNUM=9",
			}},
			{Action: uevent.KOBJ_OFFLINE, DevPath: "\xfd", Env: []string{
				"_V=\xfc",
				"SEQNUM=10",
			}},
			{Action: uevent.KOBJ_OFFLINE, DevPath: "\xfd", Env: []string{
				"SEQNUM=11",
			}},
			{Action: uevent.KOBJ_OFFLINE, DevPath: "\xfc", Env: []string{
				"V=\xf0",
				"SEQNUM=12",
			}},
		}, map[string]*Object{
			"\xfd": {
				Offline: true,
				DevPath: "\xfd",
				Env:     map[string]string{"V": "\xff"},
			},
			"\xfc": {
				Offline: true,
				DevPath: "\xfc",
				Env:     map[string]string{"V": "\xf0"},
			},
		}, nil, []error{
			(&Event{
				Action:  uevent.KOBJ_ONLINE,
				DevPath: "\xfd",
				Env: map[string]string{
					"V": "\xff",
				},
				Sequence: 9,
			}).NewError(EBadTarget, nil),
			(&Event{
				Action:  uevent.KOBJ_ONLINE,
				DevPath: "\xfd",
				Env: map[string]string{
					"V": "\xff",
				},
				Sequence: 9,
			}).NewError(EUnexpectedOffline, &Object{
				DevPath: "\xfd",
				Env: map[string]string{
					"V": "\xff",
				},
			}),
			(&Event{
				Action:   uevent.KOBJ_OFFLINE,
				DevPath:  "\xfd",
				Env:      map[string]string{},
				Sequence: 11,
			}).NewError(EUnexpectedOffline, &Object{
				Offline: true,
				DevPath: "\xfd",
				Env:     map[string]string{"V": "\xff"},
			}),
			(&Event{
				Action:   uevent.KOBJ_OFFLINE,
				DevPath:  "\xfc",
				Env:      map[string]string{"V": "\xf0"},
				Sequence: 12,
			}).NewError(EBadTarget, nil),
		}},

		{"bind", []*uevent.Message{
			{Action: uevent.KOBJ_ADD, DevPath: "\x00", Env: []string{
				"V=\xff",
				"DRIVER=\x00",
				"SEQNUM=1",
			}},
			{Action: uevent.KOBJ_UNBIND, DevPath: "\x00", Env: []string{
				"_V=\xfd",
				"SEQNUM=2",
			}},
			{Action: uevent.KOBJ_BIND, DevPath: "\x00", Env: []string{
				"__V=\xfc",
				"SEQNUM=3",
			}},
			{Action: uevent.KOBJ_BIND, DevPath: "\x00", Env: []string{
				"___V=\xfb",
				"SEQNUM=4",
			}},
			{Action: uevent.KOBJ_BIND, DevPath: "\x0c", Env: []string{
				"V=\xf0",
				"DRIVER=\x01",
				"SEQNUM=5",
			}},
		}, map[string]*Object{
			"\x00": {
				State:   StateBound,
				DevPath: "\x00",
				Env: map[string]string{
					"V": "\xff",
					// unbind not merged
					"__V":  "\xfc",
					"___V": "\xfb",
				},
			},
			"\f": {
				State:   StateBound,
				DevPath: "\f",
				Driver:  "\x01",
				Env: map[string]string{
					"V": "\xf0",
				},
			}}, nil, []error{
			(&Event{
				Action:   uevent.KOBJ_UNBIND,
				DevPath:  "\x00",
				Env:      map[string]string{"_V": "\xfd"},
				Sequence: 2,
			}).NewError(EUnbindState, &Object{
				State:   StateNew,
				DevPath: "\x00",
				Env:     map[string]string{"V": "\xff"},
			}),
			(&Event{
				Action:   uevent.KOBJ_BIND,
				DevPath:  "\x00",
				Env:      map[string]string{"___V": "\xfb"},
				Sequence: 4,
			}).NewError(EBindState, &Object{
				State:   StateBound,
				DevPath: "\x00",
				Env:     map[string]string{"V": "\xff", "__V": "\xfc"},
			}),
			(&Event{
				Action:   uevent.KOBJ_BIND,
				DevPath:  "\f",
				Env:      map[string]string{"V": "\xf0", "DRIVER": "\x01"},
				Sequence: 5,
			}).NewError(EBadTarget, nil),
		}},

		{"unbind", []*uevent.Message{
			{Action: uevent.KOBJ_UNBIND, DevPath: "\xfd", Env: []string{
				"SEQNUM=9",
			}},
		}, map[string]*Object{}, nil, []error{
			(&Event{
				Action:   uevent.KOBJ_UNBIND,
				DevPath:  "\xfd",
				Env:      map[string]string{},
				Sequence: 9,
			}).NewError(EBadTarget, nil),
		}},
	}
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			var (
				c    []map[string]string
				errs []error
			)
			s := New(coldboot, func(o *Object, env map[string]string) {
				c = append(c, env)
			}, func(err error) {
				errs = append(errs, err)
			})
			ueventVal := reflect.ValueOf(s).Elem().FieldByName("uevent")
			got := reflect.NewAt(ueventVal.Type(), unsafe.Pointer(ueventVal.UnsafeAddr())).
				Elem().Interface().(map[string]*Object)

			events := make(chan *uevent.Message, len(tc.messages))
			for _, m := range tc.messages {
				events <- m
			}
			close(events)
			s.Consume(t.Context(), events)

			if !reflect.DeepEqual(got, tc.want) {
				t.Errorf("Consume: %#v, want %#v", got, tc.want)
			}
			if !slices.EqualFunc(c, tc.c, maps.Equal) {
				t.Errorf("Consume: c = %#v, want %#v", c, tc.c)
			}
			if !reflect.DeepEqual(errs, tc.errs) {
				t.Errorf("Consume: errs = %#v, want %#v", errs, tc.errs)
			}
		})
	}
}

func TestIter(t *testing.T) {
	t.Parallel()
	synctest.Test(t, func(t *testing.T) {
		s := New(uevent.UUID{}, nil, nil)
		var wg sync.WaitGroup
		defer wg.Wait()
		events := make(chan *uevent.Message)
		defer close(events)
		wg.Go(func() { s.Consume(t.Context(), events) })

		events <- &uevent.Message{Action: uevent.KOBJ_ADD, DevPath: "\x00", Env: []string{
			"V=\xfd",
			"SEQNUM=0",
		}}
		events <- &uevent.Message{Action: uevent.KOBJ_ADD, DevPath: "\x01", Env: []string{
			"V=\xfc",
			"SEQNUM=1",
		}}
		synctest.Wait()
		s.Range(t.Context(), func(*Object, uevent.KobjectAction) bool {
			return false
		})

		var got []*Object
		check := func(want []*Object) {
			slices.SortFunc(got, func(a, b *Object) int {
				return strings.Compare(a.DevPath, b.DevPath)
			})
			if !reflect.DeepEqual(got, want) {
				t.Fatalf("Range: %#v, want %#v", got, want)
			}
			got = nil
		}

		ctx, cancel := context.WithCancel(t.Context())
		defer cancel()
		var done bool
		wg.Go(func() {
			s.Range(ctx, func(o *Object, _ uevent.KobjectAction) bool {
				got = append(got, o.Clone())
				return !done
			})
		})
		synctest.Wait()
		check([]*Object{
			{
				State:   StateNew,
				DevPath: "\x00",
				Env:     map[string]string{"V": "\xfd"},
			},
			{
				State:   StateNew,
				DevPath: "\x01",
				Env:     map[string]string{"V": "\xfc"},
			},
		})

		done = true
		events <- &uevent.Message{Action: uevent.KOBJ_MOVE, DevPath: " ", Env: []string{
			"DEVPATH_OLD=\x01",
		}}
		synctest.Wait()
		check([]*Object{
			{
				State:   StateNew,
				DevPath: " ",
				Env:     map[string]string{"V": "\xfc"},
			},
		})

		wg.Go(func() {
			s.Range(ctx, func(*Object, uevent.KobjectAction) bool {
				return true
			})
		})
		synctest.Wait()

		iter := reflect.ValueOf(s).Elem().FieldByName("iter")
		if l := iter.Len(); l != 1 {
			t.Errorf("len(s.iter): %d", l)
		}

		cancel()
		synctest.Wait()
		if l := iter.Len(); l != 0 {
			t.Errorf("len(s.iter): %d", l)
		}
	})
}

func TestErrors(t *testing.T) {
	t.Parallel()

	testCases := []struct {
		name string
		err  error
		want string
	}{
		{"BadSequenceError", BadSequenceError{
			Got:  0xcafe,
			Want: 0xbabe,
		}, "SEQNUM=51966, want 47806"},

		{"EUnexpectedColdboot", (&Event{
			Action: 0xbeef,
		}).NewError(EUnexpectedColdboot, nil),
			"unexpected unsupported kobject_action 48879 coldboot event"},

		{"EDuplicateAdd", (&Event{
			Action:  uevent.KOBJ_ADD,
			DevPath: "\x00",
		}).NewError(EDuplicateAdd, nil),
			`duplicate add event on devpath "\x00"`},

		{"EBadTarget", (&Event{
			Action:  uevent.KOBJ_UNBIND,
			DevPath: "\x00",
		}).NewError(EBadTarget, nil),
			`unexpected unbind event on devpath "\x00"`},

		{"ERemoveState", (&Event{
			DevPath: "\x00",
		}).NewError(ERemoveState, &Object{
			State: StateBound,
		}), `remove event targeting devpath "\x00" in state 2`},
		{"ERemoveState invalid", (&Event{
			DevPath: "\x00",
		}).NewError(ERemoveState, nil),
			"invalid remove event error"},

		{"EBindState", (&Event{
			DevPath: "\x00",
		}).NewError(EBindState, &Object{
			State: StateBound,
		}), `bind event targeting devpath "\x00" in state 2`},
		{"EBindState invalid", (&Event{
			DevPath: "\x00",
		}).NewError(EBindState, nil),
			"invalid bind state error"},

		{"EUnbindState", (&Event{
			DevPath: "\x00",
		}).NewError(EUnbindState, &Object{
			State: StateNew,
		}), `unbind event targeting devpath "\x00" in state 1`},
		{"EUnbindState invalid", (&Event{
			DevPath: "\x00",
		}).NewError(EUnbindState, nil),
			"invalid unbind state error"},

		{"EMalformedMove", (&Event{
			DevPath: "\x00",
		}).NewError(EMalformedMove, nil),
			`move event targeting devpath "\x00" missing DEVPATH_OLD`},

		{"EUnexpectedOffline", (&Event{
			DevPath: "\x00",
		}).NewError(EUnexpectedOffline, &Object{
			Offline: false,
		}), `online event targeting devpath "\x00"`},
		{"EUnexpectedOffline offline", (&Event{
			DevPath: "\x00",
		}).NewError(EUnexpectedOffline, &Object{
			Offline: true,
		}), `offline event targeting devpath "\x00"`},
		{"EUnexpectedOffline invalid", (&Event{
			DevPath: "\x00",
		}).NewError(EUnexpectedOffline, nil),
			"invalid unexpected offline error"},

		{"EventError invalid", &EventError{Kind: 0xbad},
			"invalid event error kind 2989"},
	}
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()

			if got := tc.err.Error(); got != tc.want {
				t.Errorf("Error: %s, want %s", got, tc.want)
			}
		})
	}
}

var (
	//go:embed testdata/00-coldboot
	testdata00 string
	//go:embed testdata/01-move
	testdata01 string
	//go:embed testdata/02-cpu
	testdata02 string
	//go:embed testdata/03-loop
	testdata03 string
	//go:embed testdata/04-loop-detach
	testdata04 string
	//go:embed testdata/05-loop-remove
	testdata05 string
)

func TestConsumeSample(t *testing.T) {
	t.Parallel()

	steps := []struct {
		name string
		data string
		want func(want map[string]*Object)
		c    []map[string]string
	}{
		{"coldboot", testdata00, func(want map[string]*Object) {
			maps.Copy(want, map[string]*Object{
				"/devices/LNXSYSTM:00": {
					DevPath:   "/devices/LNXSYSTM:00",
					ModAlias:  "acpi:LNXSYSTM:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXPWRBN:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXPWRBN:00",
					ModAlias:  "acpi:LNXPWRBN:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXPWRBN:00/wakeup/wakeup7": {
					DevPath:   "/devices/LNXSYSTM:00/LNXPWRBN:00/wakeup/wakeup7",
					Subsystem: "wakeup",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00",
					ModAlias:  "acpi:LNXSYBUS:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0010:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0010:00",
					ModAlias:  "acpi:ACPI0010:PNP0A05:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0010:00/LNXCPU:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0010:00/LNXCPU:00",
					ModAlias:  "acpi:LNXCPU:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0103:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0103:00",
					ModAlias:  "acpi:PNP0103:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00",
					ModAlias:  "acpi:PNP0A03:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/PNP0A06:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/PNP0A06:00",
					ModAlias:  "acpi:PNP0A06:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/PNP0A06:01": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/PNP0A06:01",
					ModAlias:  "acpi:PNP0A06:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/PNP0A06:02": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/PNP0A06:02",
					ModAlias:  "acpi:PNP0A06:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/QEMU0002:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/QEMU0002:00",
					ModAlias:  "acpi:QEMU0002:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:00",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:00/wakeup/wakeup0": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:00/wakeup/wakeup0",
					Subsystem: "wakeup",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0303:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0303:00",
					ModAlias:  "acpi:PNP0303:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0400:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0400:00",
					ModAlias:  "acpi:PNP0400:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0501:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0501:00",
					ModAlias:  "acpi:PNP0501:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0700:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0700:00",
					ModAlias:  "acpi:PNP0700:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0700:00/device:02": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0700:00/device:02",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0B00:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0B00:00",
					ModAlias:  "acpi:PNP0B00:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0F13:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/PNP0F13:00",
					ModAlias:  "acpi:PNP0F13:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/wakeup/wakeup1": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:01/wakeup/wakeup1",
					Subsystem: "wakeup",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:03": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:03",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:03/wakeup/wakeup2": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:03/wakeup/wakeup2",
					Subsystem: "wakeup",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:04": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:04",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:04/wakeup/wakeup3": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:04/wakeup/wakeup3",
					Subsystem: "wakeup",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:05": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:05",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:05/wakeup/wakeup4": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:05/wakeup/wakeup4",
					Subsystem: "wakeup",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:06": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:06",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:06/wakeup/wakeup5": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:06/wakeup/wakeup5",
					Subsystem: "wakeup",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:07": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:07",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:07/wakeup/wakeup8": {
					State:     StateNew,
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:07/wakeup/wakeup8",
					Subsystem: "wakeup"},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:08": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:08",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:09": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:09",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0a": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0a",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0b": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0b",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0c": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0c",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0d": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0d",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0e": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0e",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0f": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:0f",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:10": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:10",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:11": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:11",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:12": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:12",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:13": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:13",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:14": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:14",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:15": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:15",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:16": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:16",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:17": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:17",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:18": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:18",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:19": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:19",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1a": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1a",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1b": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1b",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1c": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1c",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1d": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1d",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1e": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1e",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1f": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:1f",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:20": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:20",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:21": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:21",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:22": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:22",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/wakeup/wakeup6": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/wakeup/wakeup6",
					Subsystem: "wakeup",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0F:00": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0F:00",
					ModAlias:  "acpi:PNP0C0F:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0F:01": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0F:01",
					ModAlias:  "acpi:PNP0C0F:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0F:02": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0F:02",
					ModAlias:  "acpi:PNP0C0F:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0F:03": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0F:03",
					ModAlias:  "acpi:PNP0C0F:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0F:04": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0F:04",
					ModAlias:  "acpi:PNP0C0F:",
					Subsystem: "acpi",
				},
				"/devices/LNXSYSTM:00/LNXSYBUS:01": {
					DevPath:   "/devices/LNXSYSTM:00/LNXSYBUS:01",
					ModAlias:  "acpi:LNXSYBUS:",
					Subsystem: "acpi",
				},
				"/devices/breakpoint": {
					DevPath:   "/devices/breakpoint",
					Subsystem: "event_source",
				},
				"/devices/cpu": {
					DevPath:   "/devices/cpu",
					Subsystem: "event_source",
				},
				"/devices/kprobe": {
					DevPath:   "/devices/kprobe",
					Subsystem: "event_source",
				},
				"/devices/msr": {
					DevPath:   "/devices/msr",
					Subsystem: "event_source",
				},
				"/devices/pci0000:00/0000:00:00.0": {
					DevPath:   "/devices/pci0000:00/0000:00:00.0",
					ModAlias:  "pci:v00008086d00001237sv00001AF4sd00001100bc06sc00i00",
					Subsystem: "pci",
					Env:       map[string]string{"PCI_CLASS": "60000", "PCI_ID": "8086:1237", "PCI_SLOT_NAME": "0000:00:00.0", "PCI_SUBSYS_ID": "1AF4:1100"},
				},
				"/devices/pci0000:00/0000:00:01.0": {
					DevPath:   "/devices/pci0000:00/0000:00:01.0",
					ModAlias:  "pci:v00008086d00007000sv00001AF4sd00001100bc06sc01i00",
					Subsystem: "pci",
					Env:       map[string]string{"PCI_CLASS": "60100", "PCI_ID": "8086:7000", "PCI_SLOT_NAME": "0000:00:01.0", "PCI_SUBSYS_ID": "1AF4:1100"},
				},
				"/devices/pci0000:00/0000:00:01.1": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1",
					ModAlias:  "pci:v00008086d00007010sv00001AF4sd00001100bc01sc01i80",
					Driver:    "ata_piix",
					Subsystem: "pci",
					Env:       map[string]string{"PCI_CLASS": "10180", "PCI_ID": "8086:7010", "PCI_SLOT_NAME": "0000:00:01.1", "PCI_SUBSYS_ID": "1AF4:1100"},
				},
				"/devices/pci0000:00/0000:00:01.1/ata1/ata_port/ata1": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata1/ata_port/ata1",
					Subsystem: "ata_port",
				},
				"/devices/pci0000:00/0000:00:01.1/ata1/host0": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata1/host0",
					Subsystem: "scsi",
					Env:       map[string]string{"DEVTYPE": "scsi_host"},
				},
				"/devices/pci0000:00/0000:00:01.1/ata1/host0/scsi_host/host0": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata1/host0/scsi_host/host0",
					Subsystem: "scsi_host",
				},
				"/devices/pci0000:00/0000:00:01.1/ata1/link1/ata_link/link1": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata1/link1/ata_link/link1",
					Subsystem: "ata_link",
				},
				"/devices/pci0000:00/0000:00:01.1/ata1/link1/dev1.0/ata_device/dev1.0": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata1/link1/dev1.0/ata_device/dev1.0",
					Subsystem: "ata_device",
				},
				"/devices/pci0000:00/0000:00:01.1/ata1/link1/dev1.1/ata_device/dev1.1": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata1/link1/dev1.1/ata_device/dev1.1",
					Subsystem: "ata_device",
				},
				"/devices/pci0000:00/0000:00:01.1/ata2/ata_port/ata2": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata2/ata_port/ata2",
					Subsystem: "ata_port",
				},
				"/devices/pci0000:00/0000:00:01.1/ata2/host1": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata2/host1",
					Subsystem: "scsi",
					Env:       map[string]string{"DEVTYPE": "scsi_host"},
				},
				"/devices/pci0000:00/0000:00:01.1/ata2/host1/scsi_host/host1": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata2/host1/scsi_host/host1",
					Subsystem: "scsi_host",
				},
				"/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0",
					Subsystem: "scsi",
					Env:       map[string]string{"DEVTYPE": "scsi_target"},
				},
				"/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0/1:0:0:0": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0/1:0:0:0",
					ModAlias:  "scsi:t-0x05",
					Subsystem: "scsi",
					Env:       map[string]string{"DEVTYPE": "scsi_device"},
				},
				"/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0/1:0:0:0/bsg/1:0:0:0": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0/1:0:0:0/bsg/1:0:0:0",
					Subsystem: "bsg",
					Env:       map[string]string{"DEVNAME": "bsg/1:0:0:0", "MAJOR": "251", "MINOR": "0"},
				},
				"/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0/1:0:0:0/scsi_device/1:0:0:0": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0/1:0:0:0/scsi_device/1:0:0:0",
					Subsystem: "scsi_device",
				},
				"/devices/pci0000:00/0000:00:01.1/ata2/link2/ata_link/link2": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata2/link2/ata_link/link2",
					Subsystem: "ata_link",
				},
				"/devices/pci0000:00/0000:00:01.1/ata2/link2/dev2.0/ata_device/dev2.0": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata2/link2/dev2.0/ata_device/dev2.0",
					Subsystem: "ata_device",
				},
				"/devices/pci0000:00/0000:00:01.1/ata2/link2/dev2.1/ata_device/dev2.1": {
					DevPath:   "/devices/pci0000:00/0000:00:01.1/ata2/link2/dev2.1/ata_device/dev2.1",
					Subsystem: "ata_device",
				},
				"/devices/pci0000:00/0000:00:01.3": {
					DevPath:   "/devices/pci0000:00/0000:00:01.3",
					ModAlias:  "pci:v00008086d00007113sv00001AF4sd00001100bc06sc80i00",
					Subsystem: "pci",
					Env:       map[string]string{"PCI_CLASS": "68000", "PCI_ID": "8086:7113", "PCI_SLOT_NAME": "0000:00:01.3", "PCI_SUBSYS_ID": "1AF4:1100"},
				},
				"/devices/pci0000:00/0000:00:02.0": {
					DevPath:   "/devices/pci0000:00/0000:00:02.0",
					ModAlias:  "pci:v00008086d0000100Esv00001AF4sd00001100bc02sc00i00",
					Subsystem: "pci",
					Env:       map[string]string{"PCI_CLASS": "20000", "PCI_ID": "8086:100E", "PCI_SLOT_NAME": "0000:00:02.0", "PCI_SUBSYS_ID": "1AF4:1100"},
				},
				"/devices/pci0000:00/0000:00:03.0": {
					DevPath:   "/devices/pci0000:00/0000:00:03.0",
					ModAlias:  "pci:v00001AF4d00001001sv00001AF4sd00000002bc01sc00i00",
					Driver:    "virtio-pci",
					Subsystem: "pci",
					Env:       map[string]string{"PCI_CLASS": "10000", "PCI_ID": "1AF4:1001", "PCI_SLOT_NAME": "0000:00:03.0", "PCI_SUBSYS_ID": "1AF4:0002"},
				},
				"/devices/pci0000:00/0000:00:03.0/virtio0": {
					DevPath:   "/devices/pci0000:00/0000:00:03.0/virtio0",
					ModAlias:  "virtio:d00000002v00001AF4",
					Driver:    "virtio_blk",
					Subsystem: "virtio",
				},
				"/devices/pci0000:00/0000:00:03.0/virtio0/block/vda": {
					DevPath:   "/devices/pci0000:00/0000:00:03.0/virtio0/block/vda",
					Subsystem: "block",
					Env:       map[string]string{"DEVNAME": "vda", "DEVTYPE": "disk", "DISKSEQ": "1", "MAJOR": "254", "MINOR": "0"},
				},
				"/devices/pci0000:00/0000:00:04.0": {
					State:     2,
					DevPath:   "/devices/pci0000:00/0000:00:04.0",
					ModAlias:  "pci:v00001AF4d00001059sv00001AF4sd00001100bc04sc01i00",
					Driver:    "virtio-pci",
					Subsystem: "pci",
					Env:       map[string]string{"PCI_CLASS": "40100", "PCI_ID": "1AF4:1059", "PCI_SLOT_NAME": "0000:00:04.0", "PCI_SUBSYS_ID": "1AF4:1100"}},
				"/devices/pci0000:00/0000:00:04.0/virtio1": {
					State:     StateNew,
					DevPath:   "/devices/pci0000:00/0000:00:04.0/virtio1",
					ModAlias:  "virtio:d00000019v00001AF4",
					Subsystem: "virtio"},
				"/devices/pci0000:00/QEMU0002:00": {
					DevPath:   "/devices/pci0000:00/QEMU0002:00",
					ModAlias:  "acpi:QEMU0002:",
					Subsystem: "platform",
				},
				"/devices/pci0000:00/pci_bus/0000:00": {
					DevPath:   "/devices/pci0000:00/pci_bus/0000:00",
					Subsystem: "pci_bus",
				},
				"/devices/platform/PNP0103:00": {
					DevPath:   "/devices/platform/PNP0103:00",
					ModAlias:  "acpi:PNP0103:",
					Subsystem: "platform",
				},
				"/devices/platform/pcspkr": {
					DevPath:   "/devices/platform/pcspkr",
					ModAlias:  "platform:pcspkr",
					Subsystem: "platform",
				},
				"/devices/platform/reg-dummy": {
					DevPath:   "/devices/platform/reg-dummy",
					ModAlias:  "platform:reg-dummy",
					Driver:    "reg-dummy",
					Subsystem: "platform",
				},
				"/devices/platform/reg-dummy/regulator/regulator.0": {
					DevPath:   "/devices/platform/reg-dummy/regulator/regulator.0",
					Subsystem: "regulator",
				},
				"/devices/platform/serial8250": {
					DevPath:   "/devices/platform/serial8250",
					ModAlias:  "platform:serial8250",
					Driver:    "serial8250",
					Subsystem: "platform",
				},
				"/devices/platform/serial8250/serial8250:0": {
					DevPath:   "/devices/platform/serial8250/serial8250:0",
					Driver:    "ctrl",
					Subsystem: "serial-base",
					Env:       map[string]string{"DEVTYPE": "ctrl"},
				},
				"/devices/platform/serial8250/serial8250:0/serial8250:0.1": {
					DevPath:   "/devices/platform/serial8250/serial8250:0/serial8250:0.1",
					Driver:    "port",
					Subsystem: "serial-base",
					Env:       map[string]string{"DEVTYPE": "port"},
				},
				"/devices/platform/serial8250/serial8250:0/serial8250:0.1/tty/ttyS1": {
					DevPath:   "/devices/platform/serial8250/serial8250:0/serial8250:0.1/tty/ttyS1",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "ttyS1", "MAJOR": "4", "MINOR": "65"},
				},
				"/devices/platform/serial8250/serial8250:0/serial8250:0.2": {
					DevPath:   "/devices/platform/serial8250/serial8250:0/serial8250:0.2",
					Driver:    "port",
					Subsystem: "serial-base",
					Env:       map[string]string{"DEVTYPE": "port"},
				},
				"/devices/platform/serial8250/serial8250:0/serial8250:0.2/tty/ttyS2": {
					DevPath:   "/devices/platform/serial8250/serial8250:0/serial8250:0.2/tty/ttyS2",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "ttyS2", "MAJOR": "4", "MINOR": "66"},
				},
				"/devices/platform/serial8250/serial8250:0/serial8250:0.3": {
					DevPath:   "/devices/platform/serial8250/serial8250:0/serial8250:0.3",
					Driver:    "port",
					Subsystem: "serial-base",
					Env:       map[string]string{"DEVTYPE": "port"},
				},
				"/devices/platform/serial8250/serial8250:0/serial8250:0.3/tty/ttyS3": {
					DevPath:   "/devices/platform/serial8250/serial8250:0/serial8250:0.3/tty/ttyS3",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "ttyS3", "MAJOR": "4", "MINOR": "67"},
				},
				"/devices/pnp0/00:00": {
					DevPath:   "/devices/pnp0/00:00",
					Subsystem: "pnp",
				},
				"/devices/pnp0/00:01": {
					DevPath:   "/devices/pnp0/00:01",
					Subsystem: "pnp",
				},
				"/devices/pnp0/00:02": {
					DevPath:   "/devices/pnp0/00:02",
					Subsystem: "pnp",
				},
				"/devices/pnp0/00:03": {
					DevPath:   "/devices/pnp0/00:03",
					Subsystem: "pnp",
				},
				"/devices/pnp0/00:04": {
					DevPath:   "/devices/pnp0/00:04",
					Driver:    "serial",
					Subsystem: "pnp",
				},
				"/devices/pnp0/00:04/00:04:0": {
					DevPath:   "/devices/pnp0/00:04/00:04:0",
					Driver:    "ctrl",
					Subsystem: "serial-base",
					Env:       map[string]string{"DEVTYPE": "ctrl"},
				},
				"/devices/pnp0/00:04/00:04:0/00:04:0.0": {
					DevPath:   "/devices/pnp0/00:04/00:04:0/00:04:0.0",
					Driver:    "port",
					Subsystem: "serial-base",
					Env:       map[string]string{"DEVTYPE": "port"},
				},
				"/devices/pnp0/00:04/00:04:0/00:04:0.0/tty/ttyS0": {
					DevPath:   "/devices/pnp0/00:04/00:04:0/00:04:0.0/tty/ttyS0",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "ttyS0", "MAJOR": "4", "MINOR": "64"},
				},
				"/devices/pnp0/00:05": {
					DevPath:   "/devices/pnp0/00:05",
					Subsystem: "pnp",
				},
				"/devices/software": {
					DevPath:   "/devices/software",
					Subsystem: "event_source",
				},
				"/devices/system/clockevents/broadcast": {
					DevPath:   "/devices/system/clockevents/broadcast",
					Subsystem: "clockevents",
				},
				"/devices/system/clockevents/clockevent0": {
					DevPath:   "/devices/system/clockevents/clockevent0",
					Subsystem: "clockevents",
				},
				"/devices/system/clocksource/clocksource0": {
					DevPath:   "/devices/system/clocksource/clocksource0",
					Subsystem: "clocksource",
				},
				"/devices/system/container/PNP0A06:00": {
					DevPath:   "/devices/system/container/PNP0A06:00",
					Subsystem: "container",
				},
				"/devices/system/container/PNP0A06:01": {
					DevPath:   "/devices/system/container/PNP0A06:01",
					Subsystem: "container",
				},
				"/devices/system/container/PNP0A06:02": {
					DevPath:   "/devices/system/container/PNP0A06:02",
					Subsystem: "container",
				},
				"/devices/system/cpu/cpu0": {
					DevPath:   "/devices/system/cpu/cpu0",
					ModAlias:  "cpu:type:x86,ven0002fam000Fmod006B:feature:,0000,0002,0003,0004,0005,0006,0007,0008,0009,000B,000C,000D,000E,000F,0010,0011,0013,0017,0018,0019,001A,0020,0022,0023,0024,0025,0026,0027,0028,0029,002B,002C,002D,002E,002F,0030,0031,0034,0037,0038,003D,0064,006E,0070,0074,0075,0076,0079,007A,007F,0080,008D,0095,009F,00C0,00C8,00ED,00F3,010F,0115,0165,016C,0282\n",
					Driver:    "processor",
					Subsystem: "cpu",
				},
				"/devices/system/machinecheck/machinecheck0": {
					DevPath:   "/devices/system/machinecheck/machinecheck0",
					Subsystem: "machinecheck",
				},
				"/devices/system/memory/memory0": {
					DevPath:   "/devices/system/memory/memory0",
					Subsystem: "memory",
				},
				"/devices/system/memory/memory1": {
					DevPath:   "/devices/system/memory/memory1",
					Subsystem: "memory",
				},
				"/devices/system/memory/memory2": {
					DevPath:   "/devices/system/memory/memory2",
					Subsystem: "memory",
				},
				"/devices/system/memory/memory3": {
					DevPath:   "/devices/system/memory/memory3",
					Subsystem: "memory",
				},
				"/devices/system/memory/memory4": {
					DevPath:   "/devices/system/memory/memory4",
					Subsystem: "memory",
				},
				"/devices/system/memory/memory5": {
					DevPath:   "/devices/system/memory/memory5",
					Subsystem: "memory",
				},
				"/devices/system/memory/memory6": {
					DevPath:   "/devices/system/memory/memory6",
					Subsystem: "memory",
				},
				"/devices/system/memory/memory7": {
					DevPath:   "/devices/system/memory/memory7",
					Subsystem: "memory",
				},
				"/devices/system/node/node0": {
					DevPath:   "/devices/system/node/node0",
					Subsystem: "node",
				},
				"/devices/tracepoint": {
					DevPath:   "/devices/tracepoint",
					Subsystem: "event_source",
				},
				"/devices/uprobe": {
					DevPath:   "/devices/uprobe",
					Subsystem: "event_source",
				},
				"/devices/virtual/bdi/254:0": {
					DevPath:   "/devices/virtual/bdi/254:0",
					Subsystem: "bdi",
				},
				"/devices/virtual/devlink/:ata2--scsi:1:0:0:0": {
					DevPath:   "/devices/virtual/devlink/:ata2--scsi:1:0:0:0",
					Subsystem: "devlink",
				},
				"/devices/virtual/dmi/id": {
					DevPath:   "/devices/virtual/dmi/id",
					ModAlias:  "dmi:bvnSeaBIOS:bvrrel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org:bd04/01/2014:br0.0:svnQEMU:pnStandardPC(i440FX+PIIX,1996):pvrpc-i440fx-10.1:cvnQEMU:ct1:cvrpc-i440fx-10.1:sku:",
					Subsystem: "dmi",
				},
				"/devices/virtual/mem/full": {
					DevPath:   "/devices/virtual/mem/full",
					Subsystem: "mem",
					Env:       map[string]string{"DEVMODE": "0666", "DEVNAME": "full", "MAJOR": "1", "MINOR": "7"},
				},
				"/devices/virtual/mem/kmsg": {
					DevPath:   "/devices/virtual/mem/kmsg",
					Subsystem: "mem",
					Env:       map[string]string{"DEVMODE": "0644", "DEVNAME": "kmsg", "MAJOR": "1", "MINOR": "11"},
				},
				"/devices/virtual/mem/mem": {
					DevPath:   "/devices/virtual/mem/mem",
					Subsystem: "mem",
					Env:       map[string]string{"DEVNAME": "mem", "MAJOR": "1", "MINOR": "1"},
				},
				"/devices/virtual/mem/null": {
					DevPath:   "/devices/virtual/mem/null",
					Subsystem: "mem",
					Env:       map[string]string{"DEVMODE": "0666", "DEVNAME": "null", "MAJOR": "1", "MINOR": "3"},
				},
				"/devices/virtual/mem/port": {
					DevPath:   "/devices/virtual/mem/port",
					Subsystem: "mem",
					Env:       map[string]string{"DEVNAME": "port", "MAJOR": "1", "MINOR": "4"},
				},
				"/devices/virtual/mem/random": {
					DevPath:   "/devices/virtual/mem/random",
					Subsystem: "mem",
					Env:       map[string]string{"DEVMODE": "0666", "DEVNAME": "random", "MAJOR": "1", "MINOR": "8"},
				},
				"/devices/virtual/mem/urandom": {
					DevPath:   "/devices/virtual/mem/urandom",
					Subsystem: "mem",
					Env:       map[string]string{"DEVMODE": "0666", "DEVNAME": "urandom", "MAJOR": "1", "MINOR": "9"},
				},
				"/devices/virtual/mem/zero": {
					DevPath:   "/devices/virtual/mem/zero",
					Subsystem: "mem",
					Env:       map[string]string{"DEVMODE": "0666", "DEVNAME": "zero", "MAJOR": "1", "MINOR": "5"},
				},
				"/devices/virtual/memory_tiering/memory_tier4": {
					DevPath:   "/devices/virtual/memory_tiering/memory_tier4",
					Subsystem: "memory_tiering",
				},
				"/devices/virtual/misc/cpu_dma_latency": {
					DevPath:   "/devices/virtual/misc/cpu_dma_latency",
					Subsystem: "misc",
					Env:       map[string]string{"DEVNAME": "cpu_dma_latency", "MAJOR": "10", "MINOR": "259"},
				},
				"/devices/virtual/misc/hpet": {
					DevPath:   "/devices/virtual/misc/hpet",
					Subsystem: "misc",
					Env:       map[string]string{"DEVNAME": "hpet", "MAJOR": "10", "MINOR": "228"},
				},
				"/devices/virtual/misc/snapshot": {
					DevPath:   "/devices/virtual/misc/snapshot",
					Subsystem: "misc",
					Env:       map[string]string{"DEVNAME": "snapshot", "MAJOR": "10", "MINOR": "231"},
				},
				"/devices/virtual/misc/udmabuf": {
					DevPath:   "/devices/virtual/misc/udmabuf",
					Subsystem: "misc",
					Env:       map[string]string{"DEVNAME": "udmabuf", "MAJOR": "10", "MINOR": "258"},
				},
				"/devices/virtual/misc/userfaultfd": {
					DevPath:   "/devices/virtual/misc/userfaultfd",
					Subsystem: "misc",
					Env:       map[string]string{"DEVNAME": "userfaultfd", "MAJOR": "10", "MINOR": "257"},
				},
				"/devices/virtual/misc/vga_arbiter": {
					DevPath:   "/devices/virtual/misc/vga_arbiter",
					Subsystem: "misc",
					Env:       map[string]string{"DEVNAME": "vga_arbiter", "MAJOR": "10", "MINOR": "256"},
				},
				"/devices/virtual/net/lo": {
					DevPath:   "/devices/virtual/net/lo",
					Subsystem: "net",
					Env:       map[string]string{"IFINDEX": "1", "INTERFACE": "lo"},
				},
				"/devices/virtual/thermal/cooling_device0": {
					DevPath:   "/devices/virtual/thermal/cooling_device0",
					Subsystem: "thermal",
				},
				"/devices/virtual/tty/console": {
					DevPath:   "/devices/virtual/tty/console",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "console", "MAJOR": "5", "MINOR": "1"},
				},
				"/devices/virtual/tty/ptmx": {
					DevPath:   "/devices/virtual/tty/ptmx",
					Subsystem: "tty",
					Env:       map[string]string{"DEVMODE": "0666", "DEVNAME": "ptmx", "MAJOR": "5", "MINOR": "2"},
				},
				"/devices/virtual/tty/tty": {
					DevPath:   "/devices/virtual/tty/tty",
					Subsystem: "tty",
					Env:       map[string]string{"DEVMODE": "0666", "DEVNAME": "tty", "MAJOR": "5", "MINOR": "0"},
				},
				"/devices/virtual/tty/tty0": {
					DevPath:   "/devices/virtual/tty/tty0",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty0", "MAJOR": "4", "MINOR": "0"},
				},
				"/devices/virtual/tty/tty1": {
					DevPath:   "/devices/virtual/tty/tty1",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty1", "MAJOR": "4", "MINOR": "1"},
				},
				"/devices/virtual/tty/tty10": {
					DevPath:   "/devices/virtual/tty/tty10",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty10", "MAJOR": "4", "MINOR": "10"},
				},
				"/devices/virtual/tty/tty11": {
					DevPath:   "/devices/virtual/tty/tty11",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty11", "MAJOR": "4", "MINOR": "11"},
				},
				"/devices/virtual/tty/tty12": {
					DevPath:   "/devices/virtual/tty/tty12",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty12", "MAJOR": "4", "MINOR": "12"},
				},
				"/devices/virtual/tty/tty13": {
					DevPath:   "/devices/virtual/tty/tty13",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty13", "MAJOR": "4", "MINOR": "13"},
				},
				"/devices/virtual/tty/tty14": {
					DevPath:   "/devices/virtual/tty/tty14",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty14", "MAJOR": "4", "MINOR": "14"},
				},
				"/devices/virtual/tty/tty15": {
					DevPath:   "/devices/virtual/tty/tty15",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty15", "MAJOR": "4", "MINOR": "15"},
				},
				"/devices/virtual/tty/tty16": {
					DevPath:   "/devices/virtual/tty/tty16",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty16", "MAJOR": "4", "MINOR": "16"},
				},
				"/devices/virtual/tty/tty17": {
					DevPath:   "/devices/virtual/tty/tty17",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty17", "MAJOR": "4", "MINOR": "17"},
				},
				"/devices/virtual/tty/tty18": {
					DevPath:   "/devices/virtual/tty/tty18",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty18", "MAJOR": "4", "MINOR": "18"},
				},
				"/devices/virtual/tty/tty19": {
					DevPath:   "/devices/virtual/tty/tty19",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty19", "MAJOR": "4", "MINOR": "19"},
				},
				"/devices/virtual/tty/tty2": {
					DevPath:   "/devices/virtual/tty/tty2",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty2", "MAJOR": "4", "MINOR": "2"},
				},
				"/devices/virtual/tty/tty20": {
					DevPath:   "/devices/virtual/tty/tty20",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty20", "MAJOR": "4", "MINOR": "20"},
				},
				"/devices/virtual/tty/tty21": {
					DevPath:   "/devices/virtual/tty/tty21",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty21", "MAJOR": "4", "MINOR": "21"},
				},
				"/devices/virtual/tty/tty22": {
					DevPath:   "/devices/virtual/tty/tty22",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty22", "MAJOR": "4", "MINOR": "22"},
				},
				"/devices/virtual/tty/tty23": {
					DevPath:   "/devices/virtual/tty/tty23",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty23", "MAJOR": "4", "MINOR": "23"},
				},
				"/devices/virtual/tty/tty24": {
					DevPath:   "/devices/virtual/tty/tty24",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty24", "MAJOR": "4", "MINOR": "24"},
				},
				"/devices/virtual/tty/tty25": {
					DevPath:   "/devices/virtual/tty/tty25",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty25", "MAJOR": "4", "MINOR": "25"},
				},
				"/devices/virtual/tty/tty26": {
					DevPath:   "/devices/virtual/tty/tty26",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty26", "MAJOR": "4", "MINOR": "26"},
				},
				"/devices/virtual/tty/tty27": {
					DevPath:   "/devices/virtual/tty/tty27",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty27", "MAJOR": "4", "MINOR": "27"},
				},
				"/devices/virtual/tty/tty28": {
					DevPath:   "/devices/virtual/tty/tty28",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty28", "MAJOR": "4", "MINOR": "28"},
				},
				"/devices/virtual/tty/tty29": {
					DevPath:   "/devices/virtual/tty/tty29",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty29", "MAJOR": "4", "MINOR": "29"},
				},
				"/devices/virtual/tty/tty3": {
					DevPath:   "/devices/virtual/tty/tty3",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty3", "MAJOR": "4", "MINOR": "3"},
				},
				"/devices/virtual/tty/tty30": {
					DevPath:   "/devices/virtual/tty/tty30",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty30", "MAJOR": "4", "MINOR": "30"},
				},
				"/devices/virtual/tty/tty31": {
					DevPath:   "/devices/virtual/tty/tty31",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty31", "MAJOR": "4", "MINOR": "31"},
				},
				"/devices/virtual/tty/tty32": {
					DevPath:   "/devices/virtual/tty/tty32",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty32", "MAJOR": "4", "MINOR": "32"},
				},
				"/devices/virtual/tty/tty33": {
					DevPath:   "/devices/virtual/tty/tty33",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty33", "MAJOR": "4", "MINOR": "33"},
				},
				"/devices/virtual/tty/tty34": {
					DevPath:   "/devices/virtual/tty/tty34",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty34", "MAJOR": "4", "MINOR": "34"},
				},
				"/devices/virtual/tty/tty35": {
					DevPath:   "/devices/virtual/tty/tty35",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty35", "MAJOR": "4", "MINOR": "35"},
				},
				"/devices/virtual/tty/tty36": {
					DevPath:   "/devices/virtual/tty/tty36",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty36", "MAJOR": "4", "MINOR": "36"},
				},
				"/devices/virtual/tty/tty37": {
					DevPath:   "/devices/virtual/tty/tty37",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty37", "MAJOR": "4", "MINOR": "37"},
				},
				"/devices/virtual/tty/tty38": {
					DevPath:   "/devices/virtual/tty/tty38",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty38", "MAJOR": "4", "MINOR": "38"},
				},
				"/devices/virtual/tty/tty39": {
					DevPath:   "/devices/virtual/tty/tty39",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty39", "MAJOR": "4", "MINOR": "39"},
				},
				"/devices/virtual/tty/tty4": {
					DevPath:   "/devices/virtual/tty/tty4",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty4", "MAJOR": "4", "MINOR": "4"},
				},
				"/devices/virtual/tty/tty40": {
					DevPath:   "/devices/virtual/tty/tty40",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty40", "MAJOR": "4", "MINOR": "40"},
				},
				"/devices/virtual/tty/tty41": {
					DevPath:   "/devices/virtual/tty/tty41",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty41", "MAJOR": "4", "MINOR": "41"},
				},
				"/devices/virtual/tty/tty42": {
					DevPath:   "/devices/virtual/tty/tty42",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty42", "MAJOR": "4", "MINOR": "42"},
				},
				"/devices/virtual/tty/tty43": {
					DevPath:   "/devices/virtual/tty/tty43",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty43", "MAJOR": "4", "MINOR": "43"},
				},
				"/devices/virtual/tty/tty44": {
					DevPath:   "/devices/virtual/tty/tty44",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty44", "MAJOR": "4", "MINOR": "44"},
				},
				"/devices/virtual/tty/tty45": {
					DevPath:   "/devices/virtual/tty/tty45",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty45", "MAJOR": "4", "MINOR": "45"},
				},
				"/devices/virtual/tty/tty46": {
					DevPath:   "/devices/virtual/tty/tty46",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty46", "MAJOR": "4", "MINOR": "46"},
				},
				"/devices/virtual/tty/tty47": {
					DevPath:   "/devices/virtual/tty/tty47",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty47", "MAJOR": "4", "MINOR": "47"},
				},
				"/devices/virtual/tty/tty48": {
					DevPath:   "/devices/virtual/tty/tty48",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty48", "MAJOR": "4", "MINOR": "48"},
				},
				"/devices/virtual/tty/tty49": {
					DevPath:   "/devices/virtual/tty/tty49",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty49", "MAJOR": "4", "MINOR": "49"},
				},
				"/devices/virtual/tty/tty5": {
					DevPath:   "/devices/virtual/tty/tty5",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty5", "MAJOR": "4", "MINOR": "5"},
				},
				"/devices/virtual/tty/tty50": {
					DevPath:   "/devices/virtual/tty/tty50",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty50", "MAJOR": "4", "MINOR": "50"},
				},
				"/devices/virtual/tty/tty51": {
					DevPath:   "/devices/virtual/tty/tty51",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty51", "MAJOR": "4", "MINOR": "51"},
				},
				"/devices/virtual/tty/tty52": {
					DevPath:   "/devices/virtual/tty/tty52",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty52", "MAJOR": "4", "MINOR": "52"},
				},
				"/devices/virtual/tty/tty53": {
					DevPath:   "/devices/virtual/tty/tty53",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty53", "MAJOR": "4", "MINOR": "53"},
				},
				"/devices/virtual/tty/tty54": {
					DevPath:   "/devices/virtual/tty/tty54",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty54", "MAJOR": "4", "MINOR": "54"},
				},
				"/devices/virtual/tty/tty55": {
					DevPath:   "/devices/virtual/tty/tty55",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty55", "MAJOR": "4", "MINOR": "55"},
				},
				"/devices/virtual/tty/tty56": {
					DevPath:   "/devices/virtual/tty/tty56",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty56", "MAJOR": "4", "MINOR": "56"},
				},
				"/devices/virtual/tty/tty57": {
					DevPath:   "/devices/virtual/tty/tty57",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty57", "MAJOR": "4", "MINOR": "57"},
				},
				"/devices/virtual/tty/tty58": {
					DevPath:   "/devices/virtual/tty/tty58",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty58", "MAJOR": "4", "MINOR": "58"},
				},
				"/devices/virtual/tty/tty59": {
					DevPath:   "/devices/virtual/tty/tty59",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty59", "MAJOR": "4", "MINOR": "59"},
				},
				"/devices/virtual/tty/tty6": {
					DevPath:   "/devices/virtual/tty/tty6",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty6", "MAJOR": "4", "MINOR": "6"},
				},
				"/devices/virtual/tty/tty60": {
					DevPath:   "/devices/virtual/tty/tty60",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty60", "MAJOR": "4", "MINOR": "60"},
				},
				"/devices/virtual/tty/tty61": {
					DevPath:   "/devices/virtual/tty/tty61",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty61", "MAJOR": "4", "MINOR": "61"},
				},
				"/devices/virtual/tty/tty62": {
					DevPath:   "/devices/virtual/tty/tty62",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty62", "MAJOR": "4", "MINOR": "62"},
				},
				"/devices/virtual/tty/tty63": {
					DevPath:   "/devices/virtual/tty/tty63",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty63", "MAJOR": "4", "MINOR": "63"},
				},
				"/devices/virtual/tty/tty7": {
					DevPath:   "/devices/virtual/tty/tty7",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty7", "MAJOR": "4", "MINOR": "7"},
				},
				"/devices/virtual/tty/tty8": {
					DevPath:   "/devices/virtual/tty/tty8",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty8", "MAJOR": "4", "MINOR": "8"},
				},
				"/devices/virtual/tty/tty9": {
					DevPath:   "/devices/virtual/tty/tty9",
					Subsystem: "tty",
					Env:       map[string]string{"DEVNAME": "tty9", "MAJOR": "4", "MINOR": "9"},
				},
				"/devices/virtual/vc/vcs": {
					DevPath:   "/devices/virtual/vc/vcs",
					Subsystem: "vc",
					Env:       map[string]string{"DEVNAME": "vcs", "MAJOR": "7", "MINOR": "0"},
				},
				"/devices/virtual/vc/vcs1": {
					DevPath:   "/devices/virtual/vc/vcs1",
					Subsystem: "vc",
					Env:       map[string]string{"DEVNAME": "vcs1", "MAJOR": "7", "MINOR": "1"},
				},
				"/devices/virtual/vc/vcsa": {
					DevPath:   "/devices/virtual/vc/vcsa",
					Subsystem: "vc",
					Env:       map[string]string{"DEVNAME": "vcsa", "MAJOR": "7", "MINOR": "128"},
				},
				"/devices/virtual/vc/vcsa1": {
					DevPath:   "/devices/virtual/vc/vcsa1",
					Subsystem: "vc",
					Env:       map[string]string{"DEVNAME": "vcsa1", "MAJOR": "7", "MINOR": "129"},
				},
				"/devices/virtual/vc/vcsu": {
					DevPath:   "/devices/virtual/vc/vcsu",
					Subsystem: "vc",
					Env:       map[string]string{"DEVNAME": "vcsu", "MAJOR": "7", "MINOR": "64"},
				},
				"/devices/virtual/vc/vcsu1": {
					DevPath:   "/devices/virtual/vc/vcsu1",
					Subsystem: "vc",
					Env:       map[string]string{"DEVNAME": "vcsu1", "MAJOR": "7", "MINOR": "65"},
				},
				"/devices/virtual/vtconsole/vtcon0": {
					DevPath:   "/devices/virtual/vtconsole/vtcon0",
					Subsystem: "vtconsole",
				},
				"/devices/virtual/workqueue/nvme-auth-wq": {
					DevPath:   "/devices/virtual/workqueue/nvme-auth-wq",
					Subsystem: "workqueue",
				},
				"/devices/virtual/workqueue/nvme-delete-wq": {
					DevPath:   "/devices/virtual/workqueue/nvme-delete-wq",
					Subsystem: "workqueue",
				},
				"/devices/virtual/workqueue/nvme-reset-wq": {
					DevPath:   "/devices/virtual/workqueue/nvme-reset-wq",
					Subsystem: "workqueue",
				},
				"/devices/virtual/workqueue/nvme-wq": {
					DevPath:   "/devices/virtual/workqueue/nvme-wq",
					Subsystem: "workqueue",
				},
				"/devices/virtual/workqueue/scsi_tmf_0": {
					DevPath:   "/devices/virtual/workqueue/scsi_tmf_0",
					Subsystem: "workqueue",
				},
				"/devices/virtual/workqueue/scsi_tmf_1": {
					DevPath:   "/devices/virtual/workqueue/scsi_tmf_1",
					Subsystem: "workqueue",
				},
				"/devices/virtual/workqueue/writeback": {
					DevPath:   "/devices/virtual/workqueue/writeback",
					Subsystem: "workqueue"}})
		}, nil},

		{"move", testdata01, func(want map[string]*Object) {
			o := want["/devices/virtual/net/lo"].Clone()
			delete(want, "/devices/virtual/net/lo")
			o.DevPath = "/devices/virtual/net/_lo"
			o.Env["INTERFACE"] = "_lo"
			want["/devices/virtual/net/_lo"] = o
		}, nil},

		{"cpu", testdata02, func(want map[string]*Object) {
			o := want["/devices/system/machinecheck/machinecheck0"].Clone()
			o.State = StateNew
			want["/devices/system/machinecheck/machinecheck0"] = o
		}, nil},

		{"loop", testdata03, func(want map[string]*Object) {
			maps.Copy(want, map[string]*Object{
				"/devices/virtual/bdi/7:0": {
					State:     StateNew,
					DevPath:   "/devices/virtual/bdi/7:0",
					Subsystem: "bdi",
				},
				"/devices/virtual/bdi/7:1": {
					State:     StateNew,
					DevPath:   "/devices/virtual/bdi/7:1",
					Subsystem: "bdi",
				},
				"/devices/virtual/bdi/7:2": {
					State:     StateNew,
					DevPath:   "/devices/virtual/bdi/7:2",
					Subsystem: "bdi",
				},
				"/devices/virtual/bdi/7:3": {
					State:     StateNew,
					DevPath:   "/devices/virtual/bdi/7:3",
					Subsystem: "bdi",
				},
				"/devices/virtual/bdi/7:4": {
					State:     StateNew,
					DevPath:   "/devices/virtual/bdi/7:4",
					Subsystem: "bdi",
				},
				"/devices/virtual/bdi/7:5": {
					State:     StateNew,
					DevPath:   "/devices/virtual/bdi/7:5",
					Subsystem: "bdi",
				},
				"/devices/virtual/bdi/7:6": {
					State:     StateNew,
					DevPath:   "/devices/virtual/bdi/7:6",
					Subsystem: "bdi",
				},
				"/devices/virtual/bdi/7:7": {
					State:     StateNew,
					DevPath:   "/devices/virtual/bdi/7:7",
					Subsystem: "bdi",
				},

				"/devices/virtual/block/loop0": {
					State:     StateNew,
					DevPath:   "/devices/virtual/block/loop0",
					Subsystem: "block",
					Env: map[string]string{
						"DEVNAME": "loop0",
						"DEVTYPE": "disk",
						"DISKSEQ": "10",
						"MAJOR":   "7",
						"MINOR":   "0",
					},
				},
				"/devices/virtual/block/loop1": {
					State:     StateNew,
					DevPath:   "/devices/virtual/block/loop1",
					Subsystem: "block",
					Env: map[string]string{
						"DEVNAME": "loop1",
						"DEVTYPE": "disk",
						"DISKSEQ": "3",
						"MAJOR":   "7",
						"MINOR":   "1",
					},
				},
				"/devices/virtual/block/loop2": {
					State:     StateNew,
					DevPath:   "/devices/virtual/block/loop2",
					Subsystem: "block",
					Env: map[string]string{
						"DEVNAME": "loop2",
						"DEVTYPE": "disk",
						"DISKSEQ": "4",
						"MAJOR":   "7",
						"MINOR":   "2",
					},
				},
				"/devices/virtual/block/loop3": {
					State:     StateNew,
					DevPath:   "/devices/virtual/block/loop3",
					Subsystem: "block",
					Env: map[string]string{
						"DEVNAME": "loop3",
						"DEVTYPE": "disk",
						"DISKSEQ": "5",
						"MAJOR":   "7",
						"MINOR":   "3",
					},
				},
				"/devices/virtual/block/loop4": {
					State:     StateNew,
					DevPath:   "/devices/virtual/block/loop4",
					Subsystem: "block",
					Env: map[string]string{
						"DEVNAME": "loop4",
						"DEVTYPE": "disk",
						"DISKSEQ": "6",
						"MAJOR":   "7",
						"MINOR":   "4",
					},
				},
				"/devices/virtual/block/loop5": {
					State:     StateNew,
					DevPath:   "/devices/virtual/block/loop5",
					Subsystem: "block",
					Env: map[string]string{
						"DEVNAME": "loop5",
						"DEVTYPE": "disk",
						"DISKSEQ": "7",
						"MAJOR":   "7",
						"MINOR":   "5",
					},
				},
				"/devices/virtual/block/loop6": {
					State:     StateNew,
					DevPath:   "/devices/virtual/block/loop6",
					Subsystem: "block",
					Env: map[string]string{
						"DEVNAME": "loop6",
						"DEVTYPE": "disk",
						"DISKSEQ": "8",
						"MAJOR":   "7",
						"MINOR":   "6",
					},
				},
				"/devices/virtual/block/loop7": {
					State:     StateNew,
					DevPath:   "/devices/virtual/block/loop7",
					Subsystem: "block",
					Env: map[string]string{
						"DEVNAME": "loop7",
						"DEVTYPE": "disk",
						"DISKSEQ": "9",
						"MAJOR":   "7",
						"MINOR":   "7",
					},
				},
				"/devices/virtual/misc/loop-control": {
					State:     StateNew,
					DevPath:   "/devices/virtual/misc/loop-control",
					Subsystem: "misc",
					Env: map[string]string{
						"DEVNAME": "loop-control",
						"MAJOR":   "10",
						"MINOR":   "237",
					},
				},

				"/module/loop": {
					State:     StateNew,
					DevPath:   "/module/loop",
					Subsystem: "module",
				},
			})
		}, []map[string]string{{}}},

		{"loop-detach", testdata04, nil, []map[string]string{
			{},
			{"DISK_MEDIA_CHANGE": "1"},
		}},

		{"loop-remove", testdata05, func(want map[string]*Object) {
			for _, k := range []string{
				"/devices/virtual/misc/loop-control",
				"/devices/virtual/bdi/7:0",
				"/devices/virtual/block/loop0",
				"/devices/virtual/bdi/7:1",
				"/devices/virtual/block/loop1",
				"/devices/virtual/bdi/7:2",
				"/devices/virtual/block/loop2",
				"/devices/virtual/bdi/7:3",
				"/devices/virtual/block/loop3",
				"/devices/virtual/bdi/7:4",
				"/devices/virtual/block/loop4",
				"/devices/virtual/bdi/7:5",
				"/devices/virtual/block/loop5",
				"/devices/virtual/bdi/7:6",
				"/devices/virtual/block/loop6",
				"/devices/virtual/bdi/7:7",
				"/devices/virtual/block/loop7",
				"/module/loop",
			} {
				delete(want, k)
			}
		}, nil},
	}
	var c []map[string]string
	s := New(uevent.UUID{
		0xfe, 0x4d, 0x7c, 0x9d,
		0xb8, 0xc6,
		0x4a, 0x70,
		0x9e, 0xf1,
		0x3d, 0x8a, 0x58, 0xd1, 0x8e, 0xed,
	}, func(o *Object, env map[string]string) {
		c = append(c, env)
	}, func(err error) {
		t.Fatal(err)
	})
	ueventVal := reflect.ValueOf(s).Elem().FieldByName("uevent")
	got := reflect.NewAt(ueventVal.Type(), unsafe.Pointer(ueventVal.UnsafeAddr())).
		Elem().Interface().(map[string]*Object)
	want := make(map[string]*Object)
	for _, step := range steps {
		if step.want != nil {
			step.want(want)
		}
		events := make(chan *uevent.Message)
		go func() {
			defer close(events)
			d := json.NewDecoder(strings.NewReader(step.data))
			for {
				var m uevent.Message
				if err := d.Decode(&m); err != nil {
					if err == io.EOF {
						break
					}
					panic(err)
				}
				events <- &m
			}
		}()

		s.Consume(t.Context(), events)
		if !reflect.DeepEqual(got, want) {
			t.Fatalf("%s: %#v, want %#v", step.name, got, want)
		}
		if !slices.EqualFunc(c, step.c, maps.Equal) {
			t.Fatalf("%s: c = %#v, want %#v", step.name, c, step.c)
		}
		c = nil
	}
}
