mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
295 lines
5.8 KiB
Go
295 lines
5.8 KiB
Go
package aml
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestScopeVisit(t *testing.T) {
|
|
scopeMap := genTestScopes()
|
|
root := scopeMap[`\`].(*scopeEntity)
|
|
|
|
keepRecursing := func(Entity) bool { return true }
|
|
stopRecursing := func(Entity) bool { return false }
|
|
|
|
// Append special entities under IDE0
|
|
ide := scopeMap["IDE0"].(*scopeEntity)
|
|
ide.Append(&Device{})
|
|
ide.Append(&namedEntity{op: opProcessor})
|
|
ide.Append(&namedEntity{op: opProcessor})
|
|
ide.Append(&namedEntity{op: opPowerRes})
|
|
ide.Append(&namedEntity{op: opPowerRes})
|
|
ide.Append(&namedEntity{op: opPowerRes})
|
|
ide.Append(&namedEntity{op: opThermalZone})
|
|
ide.Append(&namedEntity{op: opThermalZone})
|
|
ide.Append(&namedEntity{op: opThermalZone})
|
|
ide.Append(&namedEntity{op: opThermalZone})
|
|
ide.Append(&Method{})
|
|
ide.Append(&Method{})
|
|
ide.Append(&Method{})
|
|
ide.Append(&Method{})
|
|
ide.Append(&Method{})
|
|
ide.Append(&methodInvocationEntity{
|
|
unnamedEntity: unnamedEntity{
|
|
args: []interface{}{
|
|
&constEntity{val: uint64(1)},
|
|
&constEntity{val: uint64(2)},
|
|
},
|
|
},
|
|
})
|
|
|
|
specs := []struct {
|
|
searchType EntityType
|
|
keepRecursingFn func(Entity) bool
|
|
wantHits int
|
|
}{
|
|
{EntityTypeAny, keepRecursing, 24},
|
|
{EntityTypeAny, stopRecursing, 1},
|
|
{
|
|
EntityTypeAny,
|
|
func(ent Entity) bool {
|
|
// Stop recursing after visiting the methodInvocationEntity
|
|
_, isInv := ent.(*methodInvocationEntity)
|
|
return !isInv
|
|
},
|
|
22,
|
|
},
|
|
|
|
{
|
|
EntityTypeAny,
|
|
func(ent Entity) bool {
|
|
// Stop recursing after visiting the first constEntity
|
|
_, isConst := ent.(*constEntity)
|
|
return !isConst
|
|
},
|
|
23,
|
|
},
|
|
{EntityTypeDevice, keepRecursing, 1},
|
|
{EntityTypeProcessor, keepRecursing, 2},
|
|
{EntityTypePowerResource, keepRecursing, 3},
|
|
{EntityTypeThermalZone, keepRecursing, 4},
|
|
{EntityTypeMethod, keepRecursing, 5},
|
|
}
|
|
|
|
for specIndex, spec := range specs {
|
|
var hits int
|
|
scopeVisit(0, root, spec.searchType, func(_ int, obj Entity) bool {
|
|
hits++
|
|
return spec.keepRecursingFn(obj)
|
|
})
|
|
|
|
if hits != spec.wantHits {
|
|
t.Errorf("[spec %d] expected visitor to be called %d times; got %d", specIndex, spec.wantHits, hits)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestScopeResolvePath(t *testing.T) {
|
|
scopeMap := genTestScopes()
|
|
|
|
specs := []struct {
|
|
curScope ScopeEntity
|
|
pathExpr string
|
|
wantParent Entity
|
|
wantName string
|
|
}{
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
`\_SB_`,
|
|
scopeMap[`\`],
|
|
"_SB_",
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
`^FOO`,
|
|
scopeMap[`PCI0`],
|
|
"FOO",
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
`^^FOO`,
|
|
scopeMap[`_SB_`],
|
|
"FOO",
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
`_ADR`,
|
|
scopeMap[`IDE0`],
|
|
"_ADR",
|
|
},
|
|
// Paths with dots
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
`\_SB_.PCI0.IDE0._ADR`,
|
|
scopeMap[`IDE0`],
|
|
"_ADR",
|
|
},
|
|
{
|
|
scopeMap["PCI0"].(*scopeEntity),
|
|
`IDE0._ADR`,
|
|
scopeMap[`IDE0`],
|
|
"_ADR",
|
|
},
|
|
{
|
|
scopeMap["PCI0"].(*scopeEntity),
|
|
`_CRS`,
|
|
scopeMap[`PCI0`],
|
|
"_CRS",
|
|
},
|
|
// Bad queries
|
|
{
|
|
scopeMap["PCI0"].(*scopeEntity),
|
|
`FOO.BAR.BAZ`,
|
|
nil,
|
|
"",
|
|
},
|
|
{
|
|
scopeMap["PCI0"].(*scopeEntity),
|
|
``,
|
|
nil,
|
|
"",
|
|
},
|
|
{
|
|
scopeMap["PCI0"].(*scopeEntity),
|
|
`\`,
|
|
nil,
|
|
"",
|
|
},
|
|
{
|
|
scopeMap["PCI0"].(*scopeEntity),
|
|
`^^^^^^^^^BADPATH`,
|
|
nil,
|
|
"",
|
|
},
|
|
}
|
|
|
|
root := scopeMap[`\`].(*scopeEntity)
|
|
for specIndex, spec := range specs {
|
|
gotParent, gotName := scopeResolvePath(spec.curScope, root, spec.pathExpr)
|
|
if !reflect.DeepEqual(gotParent, spec.wantParent) {
|
|
t.Errorf("[spec %d] expected lookup to return %#v; got %#v", specIndex, spec.wantParent, gotParent)
|
|
continue
|
|
}
|
|
|
|
if gotName != spec.wantName {
|
|
t.Errorf("[spec %d] expected lookup to return node name %q; got %q", specIndex, spec.wantName, gotName)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestScopeFind(t *testing.T) {
|
|
scopeMap := genTestScopes()
|
|
|
|
specs := []struct {
|
|
curScope ScopeEntity
|
|
lookup string
|
|
want Entity
|
|
}{
|
|
// Search rules do not apply for these cases
|
|
{
|
|
scopeMap["PCI0"].(*scopeEntity),
|
|
`\`,
|
|
scopeMap[`\`],
|
|
},
|
|
{
|
|
scopeMap["PCI0"].(*scopeEntity),
|
|
"IDE0._ADR",
|
|
scopeMap["_ADR"],
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
"^^PCI0.IDE0._ADR",
|
|
scopeMap["_ADR"],
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
`\_SB_.PCI0.IDE0._ADR`,
|
|
scopeMap["_ADR"],
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
`\_SB_.PCI0`,
|
|
scopeMap["PCI0"],
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
`^`,
|
|
scopeMap["PCI0"],
|
|
},
|
|
// Bad queries
|
|
{
|
|
scopeMap["_SB_"].(*scopeEntity),
|
|
"PCI0.USB._CRS",
|
|
nil,
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
"^^^^^^^^^^^^^^^^^^^",
|
|
nil,
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
`^^^^^^^^^^^FOO`,
|
|
nil,
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
"FOO",
|
|
nil,
|
|
},
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
"",
|
|
nil,
|
|
},
|
|
// Search rules apply for these cases
|
|
{
|
|
scopeMap["IDE0"].(*scopeEntity),
|
|
"_CRS",
|
|
scopeMap["_CRS"],
|
|
},
|
|
}
|
|
|
|
root := scopeMap[`\`].(*scopeEntity)
|
|
for specIndex, spec := range specs {
|
|
if got := scopeFind(spec.curScope, root, spec.lookup); !reflect.DeepEqual(got, spec.want) {
|
|
t.Errorf("[spec %d] expected lookup to return %#v; got %#v", specIndex, spec.want, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func genTestScopes() map[string]Entity {
|
|
// Setup the example tree from page 252 of the acpi 6.2 spec
|
|
// \
|
|
// SB
|
|
// \
|
|
// PCI0
|
|
// | _CRS
|
|
// \
|
|
// IDE0
|
|
// | _ADR
|
|
ideScope := &scopeEntity{name: `IDE0`}
|
|
pciScope := &scopeEntity{name: `PCI0`}
|
|
sbScope := &scopeEntity{name: `_SB_`}
|
|
rootScope := &scopeEntity{name: `\`}
|
|
|
|
adr := &namedEntity{name: `_ADR`}
|
|
crs := &namedEntity{name: `_CRS`}
|
|
|
|
// Setup tree
|
|
ideScope.Append(adr)
|
|
pciScope.Append(crs)
|
|
pciScope.Append(ideScope)
|
|
sbScope.Append(pciScope)
|
|
rootScope.Append(sbScope)
|
|
|
|
return map[string]Entity{
|
|
"IDE0": ideScope,
|
|
"PCI0": pciScope,
|
|
"_SB_": sbScope,
|
|
"\\": rootScope,
|
|
"_ADR": adr,
|
|
"_CRS": crs,
|
|
}
|
|
}
|