tests: initial tests import
From zephyr commit f5409dec01c84aa8eda1830c64309abe3d5868d0. Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
18f7bb4286
commit
5ab38f1157
35 changed files with 3454 additions and 0 deletions
5
tests/test-bindings-2/multidir.yaml
Normal file
5
tests/test-bindings-2/multidir.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Binding in test-bindings-2/
|
||||
|
||||
compatible: "in-dir-2"
|
||||
7
tests/test-bindings/bar-bus.yaml
Normal file
7
tests/test-bindings/bar-bus.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Bar bus controller
|
||||
|
||||
compatible: "bar-bus"
|
||||
|
||||
bus: "bar"
|
||||
20
tests/test-bindings/child-binding-with-compat.yaml
Normal file
20
tests/test-bindings/child-binding-with-compat.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: child-binding with separate compatible than the parent
|
||||
|
||||
compatible: "top-binding-with-compat"
|
||||
|
||||
child-binding:
|
||||
compatible: child-compat
|
||||
description: child node
|
||||
properties:
|
||||
child-prop:
|
||||
type: int
|
||||
required: true
|
||||
|
||||
child-binding:
|
||||
description: grandchild node
|
||||
properties:
|
||||
grandchild-prop:
|
||||
type: int
|
||||
required: true
|
||||
19
tests/test-bindings/child-binding.yaml
Normal file
19
tests/test-bindings/child-binding.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: child-binding test
|
||||
|
||||
compatible: "top-binding"
|
||||
|
||||
child-binding:
|
||||
description: child node
|
||||
properties:
|
||||
child-prop:
|
||||
type: int
|
||||
required: true
|
||||
|
||||
child-binding:
|
||||
description: grandchild node
|
||||
properties:
|
||||
grandchild-prop:
|
||||
type: int
|
||||
required: true
|
||||
8
tests/test-bindings/child.yaml
Normal file
8
tests/test-bindings/child.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
include: [grandchild-1.yaml, grandchild-2.yaml, grandchild-3.yaml]
|
||||
|
||||
properties:
|
||||
bar:
|
||||
required: true
|
||||
type: int
|
||||
36
tests/test-bindings/defaults.yaml
Normal file
36
tests/test-bindings/defaults.yaml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Property default value test
|
||||
|
||||
compatible: "defaults"
|
||||
|
||||
properties:
|
||||
int:
|
||||
type: int
|
||||
required: false
|
||||
default: 123
|
||||
|
||||
array:
|
||||
type: array
|
||||
required: false
|
||||
default: [1, 2, 3]
|
||||
|
||||
uint8-array:
|
||||
type: uint8-array
|
||||
required: false
|
||||
default: [0x89, 0xAB, 0xCD]
|
||||
|
||||
string:
|
||||
type: string
|
||||
required: false
|
||||
default: "hello"
|
||||
|
||||
string-array:
|
||||
type: string-array
|
||||
required: false
|
||||
default: ["hello", "there"]
|
||||
|
||||
default-not-used:
|
||||
type: int
|
||||
required: false
|
||||
default: 123
|
||||
15
tests/test-bindings/deprecated.yaml
Normal file
15
tests/test-bindings/deprecated.yaml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Property deprecated value test
|
||||
|
||||
compatible: "test-deprecated"
|
||||
|
||||
properties:
|
||||
oldprop:
|
||||
type: int
|
||||
deprecated: true
|
||||
required: false
|
||||
|
||||
curprop:
|
||||
type: int
|
||||
required: false
|
||||
5
tests/test-bindings/device-on-any-bus.yaml
Normal file
5
tests/test-bindings/device-on-any-bus.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Device on any bus
|
||||
|
||||
compatible: "on-any-bus"
|
||||
7
tests/test-bindings/device-on-bar-bus.yaml
Normal file
7
tests/test-bindings/device-on-bar-bus.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Device on bar bus
|
||||
|
||||
compatible: "on-bus"
|
||||
|
||||
on-bus: "bar"
|
||||
7
tests/test-bindings/device-on-foo-bus.yaml
Normal file
7
tests/test-bindings/device-on-foo-bus.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Device on foo bus
|
||||
|
||||
compatible: "on-bus"
|
||||
|
||||
on-bus: "foo"
|
||||
36
tests/test-bindings/enums.yaml
Normal file
36
tests/test-bindings/enums.yaml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Property enum test
|
||||
|
||||
compatible: "enums"
|
||||
|
||||
properties:
|
||||
int-enum:
|
||||
type: int
|
||||
enum:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
||||
string-enum: # not tokenizable
|
||||
type: string
|
||||
enum:
|
||||
- foo bar
|
||||
- foo_bar
|
||||
|
||||
tokenizable-lower-enum: # tokenizable in lowercase only
|
||||
type: string
|
||||
enum:
|
||||
- bar
|
||||
- BAR
|
||||
|
||||
tokenizable-enum: # tokenizable in lower and uppercase
|
||||
type: string
|
||||
enum:
|
||||
- bar
|
||||
- whitespace is ok
|
||||
- 123 is ok
|
||||
|
||||
no-enum:
|
||||
type: string
|
||||
4
tests/test-bindings/false-positive.yaml
Normal file
4
tests/test-bindings/false-positive.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# A file that mentions a 'compatible' string without actually implementing it.
|
||||
# Used to check for issues with how we optimize binding loading.
|
||||
|
||||
# props
|
||||
7
tests/test-bindings/foo-bus.yaml
Normal file
7
tests/test-bindings/foo-bus.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Foo bus controller
|
||||
|
||||
compatible: "foo-bus"
|
||||
|
||||
bus: "foo"
|
||||
4
tests/test-bindings/foo-optional.yaml
Normal file
4
tests/test-bindings/foo-optional.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
properties:
|
||||
foo:
|
||||
type: int
|
||||
required: false
|
||||
4
tests/test-bindings/foo-required.yaml
Normal file
4
tests/test-bindings/foo-required.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
properties:
|
||||
foo:
|
||||
type: int
|
||||
required: true
|
||||
8
tests/test-bindings/gpio-dst.yaml
Normal file
8
tests/test-bindings/gpio-dst.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: GPIO destination for mapping test
|
||||
|
||||
compatible: "gpio-dst"
|
||||
|
||||
gpio-cells:
|
||||
- val
|
||||
9
tests/test-bindings/gpio-src.yaml
Normal file
9
tests/test-bindings/gpio-src.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: GPIO source for mapping test
|
||||
|
||||
compatible: "gpio-src"
|
||||
|
||||
properties:
|
||||
foo-gpios:
|
||||
type: phandle-array
|
||||
10
tests/test-bindings/grandchild-1.yaml
Normal file
10
tests/test-bindings/grandchild-1.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
properties:
|
||||
foo:
|
||||
required: false
|
||||
type: int
|
||||
|
||||
baz:
|
||||
required: true
|
||||
type: int
|
||||
6
tests/test-bindings/grandchild-2.yaml
Normal file
6
tests/test-bindings/grandchild-2.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
properties:
|
||||
baz:
|
||||
required: true
|
||||
type: int
|
||||
6
tests/test-bindings/grandchild-3.yaml
Normal file
6
tests/test-bindings/grandchild-3.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
properties:
|
||||
qaz:
|
||||
required: true
|
||||
type: int
|
||||
8
tests/test-bindings/interrupt-1-cell.yaml
Normal file
8
tests/test-bindings/interrupt-1-cell.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Interrupt controller with one cell
|
||||
|
||||
compatible: "interrupt-one-cell"
|
||||
|
||||
interrupt-cells:
|
||||
- one
|
||||
9
tests/test-bindings/interrupt-2-cell.yaml
Normal file
9
tests/test-bindings/interrupt-2-cell.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Interrupt controller with two cells
|
||||
|
||||
compatible: "interrupt-two-cell"
|
||||
|
||||
interrupt-cells:
|
||||
- one
|
||||
- two
|
||||
10
tests/test-bindings/interrupt-3-cell.yaml
Normal file
10
tests/test-bindings/interrupt-3-cell.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Interrupt controller with three cells
|
||||
|
||||
compatible: "interrupt-three-cell"
|
||||
|
||||
interrupt-cells:
|
||||
- one
|
||||
- two
|
||||
- three
|
||||
5
tests/test-bindings/multidir.yaml
Normal file
5
tests/test-bindings/multidir.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Binding in test-bindings/
|
||||
|
||||
compatible: "in-dir-1"
|
||||
7
tests/test-bindings/order-1.yaml
Normal file
7
tests/test-bindings/order-1.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Include ordering test
|
||||
|
||||
compatible: "order-1"
|
||||
|
||||
include: ["foo-required.yaml", "foo-optional.yaml"]
|
||||
7
tests/test-bindings/order-2.yaml
Normal file
7
tests/test-bindings/order-2.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Include ordering test
|
||||
|
||||
compatible: "order-2"
|
||||
|
||||
include: ["foo-optional.yaml", "foo-required.yaml"]
|
||||
13
tests/test-bindings/parent.yaml
Normal file
13
tests/test-bindings/parent.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Parent binding
|
||||
|
||||
compatible: "binding-include-test"
|
||||
|
||||
include: child.yaml
|
||||
|
||||
properties:
|
||||
foo:
|
||||
# Changed from not being required in grandchild-1.yaml
|
||||
required: true
|
||||
# Type set in grandchild
|
||||
7
tests/test-bindings/phandle-array-controller-0.yaml
Normal file
7
tests/test-bindings/phandle-array-controller-0.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Controller with zero data values
|
||||
|
||||
compatible: "phandle-array-controller-0"
|
||||
|
||||
phandle-array-foo-cells: []
|
||||
11
tests/test-bindings/phandle-array-controller-1.yaml
Normal file
11
tests/test-bindings/phandle-array-controller-1.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Controller with one data value
|
||||
|
||||
compatible: "phandle-array-controller-1"
|
||||
|
||||
phandle-array-foo-cells:
|
||||
- one
|
||||
|
||||
gpio-cells:
|
||||
- gpio-one
|
||||
9
tests/test-bindings/phandle-array-controller-2.yaml
Normal file
9
tests/test-bindings/phandle-array-controller-2.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Controller with two data values
|
||||
|
||||
compatible: "phandle-array-controller-2"
|
||||
|
||||
phandle-array-foo-cells:
|
||||
- one
|
||||
- two
|
||||
50
tests/test-bindings/props.yaml
Normal file
50
tests/test-bindings/props.yaml
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
description: Device.props test
|
||||
|
||||
compatible: "props"
|
||||
|
||||
properties:
|
||||
nonexistent-boolean:
|
||||
type: boolean
|
||||
|
||||
existent-boolean:
|
||||
type: boolean
|
||||
|
||||
int:
|
||||
type: int
|
||||
const: 1
|
||||
|
||||
array:
|
||||
type: array
|
||||
|
||||
uint8-array:
|
||||
type: uint8-array
|
||||
|
||||
string:
|
||||
type: string
|
||||
const: "foo"
|
||||
|
||||
string-array:
|
||||
type: string-array
|
||||
|
||||
phandle-ref:
|
||||
type: phandle
|
||||
|
||||
phandle-refs:
|
||||
type: phandles
|
||||
|
||||
phandle-array-foos:
|
||||
type: phandle-array
|
||||
|
||||
phandle-array-foo-names:
|
||||
type: string-array
|
||||
|
||||
# There's some slight special-casing for GPIOs in that 'foo-gpios = ...'
|
||||
# gets resolved to #gpio-cells rather than #foo-gpio-cells, so test that
|
||||
# too
|
||||
foo-gpios:
|
||||
type: phandle-array
|
||||
|
||||
path:
|
||||
type: path
|
||||
19
tests/test-multidir.dts
Normal file
19
tests/test-multidir.dts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Nordic Semiconductor
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// Used by testedtlib.py. Dedicated file for testing having multiple binding
|
||||
// directories.
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
in-dir-1 {
|
||||
compatible = "in-dir-1";
|
||||
};
|
||||
in-dir-2 {
|
||||
compatible = "in-dir-2";
|
||||
};
|
||||
};
|
||||
430
tests/test.dts
Normal file
430
tests/test.dts
Normal file
|
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Nordic Semiconductor
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// Used by testedtlib.py
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
//
|
||||
// Interrupts
|
||||
//
|
||||
|
||||
interrupt-parent-test {
|
||||
controller {
|
||||
compatible = "interrupt-three-cell";
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-controller;
|
||||
};
|
||||
node {
|
||||
interrupts = <1 2 3 4 5 6>;
|
||||
interrupt-names = "foo", "bar";
|
||||
interrupt-parent = <&{/interrupt-parent-test/controller}>;
|
||||
};
|
||||
};
|
||||
interrupts-extended-test {
|
||||
controller-0 {
|
||||
compatible = "interrupt-one-cell";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
controller-1 {
|
||||
compatible = "interrupt-two-cell";
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-controller;
|
||||
};
|
||||
controller-2 {
|
||||
compatible = "interrupt-three-cell";
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-controller;
|
||||
};
|
||||
node {
|
||||
interrupts-extended = <
|
||||
&{/interrupts-extended-test/controller-0} 1
|
||||
&{/interrupts-extended-test/controller-1} 2 3
|
||||
&{/interrupts-extended-test/controller-2} 4 5 6>;
|
||||
};
|
||||
};
|
||||
interrupt-map-test {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
controller-0 {
|
||||
compatible = "interrupt-one-cell";
|
||||
#address-cells = <1>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
controller-1 {
|
||||
compatible = "interrupt-two-cell";
|
||||
#address-cells = <2>;
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-controller;
|
||||
};
|
||||
controller-2 {
|
||||
compatible = "interrupt-three-cell";
|
||||
#address-cells = <3>;
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-controller;
|
||||
};
|
||||
nexus {
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-map = <
|
||||
0 0 0 0 &{/interrupt-map-test/controller-0} 0 0
|
||||
0 0 0 1 &{/interrupt-map-test/controller-1} 0 0 0 1
|
||||
0 0 0 2 &{/interrupt-map-test/controller-2} 0 0 0 0 0 2
|
||||
0 1 0 0 &{/interrupt-map-test/controller-0} 0 3
|
||||
0 1 0 1 &{/interrupt-map-test/controller-1} 0 0 0 4
|
||||
0 1 0 2 &{/interrupt-map-test/controller-2} 0 0 0 0 0 5>;
|
||||
};
|
||||
node@0 {
|
||||
reg = <0 0>;
|
||||
interrupts = <0 0 0 1 0 2>;
|
||||
interrupt-parent = <&{/interrupt-map-test/nexus}>;
|
||||
};
|
||||
node@1 {
|
||||
reg = <0 1>;
|
||||
interrupts-extended = <
|
||||
&{/interrupt-map-test/nexus} 0 0
|
||||
&{/interrupt-map-test/nexus} 0 1
|
||||
&{/interrupt-map-test/nexus} 0 2>;
|
||||
};
|
||||
};
|
||||
interrupt-map-bitops-test {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
controller {
|
||||
compatible = "interrupt-two-cell";
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-controller;
|
||||
};
|
||||
nexus {
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-map = <
|
||||
6 6 6 6 &{/interrupt-map-bitops-test/controller} 2 1
|
||||
>;
|
||||
interrupt-map-mask = <0xE 0x7 0xE 0x7>;
|
||||
// Not specified in the DT spec., but shows up due to
|
||||
// common code with GPIO. Might as well test it here.
|
||||
interrupt-map-pass-thru = <1 2 3 3>;
|
||||
};
|
||||
// Child unit specifier: 00000007 0000000E 00000007 0000000E
|
||||
// Mask: 0000000E 00000007 0000000E 00000007
|
||||
// Pass-thru: 00000001 00000002 00000003 00000003
|
||||
node@70000000E {
|
||||
reg = <0x7 0xE>;
|
||||
interrupt-parent = <&{/interrupt-map-bitops-test/nexus}>;
|
||||
interrupts = <0x7 0xE>;
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// 'reg'
|
||||
//
|
||||
|
||||
reg-zero-address-cells {
|
||||
#address-cells = <0>;
|
||||
#size-cells = <1>;
|
||||
|
||||
node {
|
||||
reg = <1 2>;
|
||||
};
|
||||
};
|
||||
reg-zero-size-cells {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
node {
|
||||
reg = <1 2>;
|
||||
};
|
||||
};
|
||||
// Use implied #size-cells = <1>
|
||||
reg-ranges {
|
||||
#address-cells = <2>;
|
||||
|
||||
parent {
|
||||
#address-cells = <1>;
|
||||
ranges = <1 0xA 0xB 1 /* 1 -> 0xA 0xB */
|
||||
2 0xC 0xD 2 /* 2..3 -> 0xC 0xD */
|
||||
4 0xE 0xF 1 /* 4 -> 0xE 0xF */
|
||||
>;
|
||||
|
||||
node {
|
||||
reg = <5 1 /* Matches no range */
|
||||
4 1 /* Matches third range */
|
||||
3 1 /* Matches second range */
|
||||
2 1 /* Matches second range */
|
||||
1 1 /* Matches first range */
|
||||
0 1 /* Matches no range */
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
// Build up <3 2 1> address with nested 'ranges'
|
||||
reg-nested-ranges {
|
||||
#address-cells = <3>;
|
||||
|
||||
grandparent {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges = <0 0 3 0 0 2 2>;
|
||||
|
||||
parent {
|
||||
#address-cells = <1>;
|
||||
ranges = <0 2 0 2>;
|
||||
|
||||
node {
|
||||
reg = <1 1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// 'pinctrl-<index>'
|
||||
//
|
||||
|
||||
pinctrl {
|
||||
dev {
|
||||
pinctrl-0 = <>;
|
||||
pinctrl-1 = <&{/pinctrl/pincontroller/state-1}>;
|
||||
pinctrl-2 = <&{/pinctrl/pincontroller/state-1}
|
||||
&{/pinctrl/pincontroller/state-2}>;
|
||||
pinctrl-names = "zero", "one", "two";
|
||||
};
|
||||
pincontroller {
|
||||
state-1 {
|
||||
};
|
||||
state-2 {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// For testing Node.parent and Node.children
|
||||
//
|
||||
|
||||
parent {
|
||||
child-1 {
|
||||
};
|
||||
child-2 {
|
||||
grandchild {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// For testing 'include:'
|
||||
//
|
||||
|
||||
binding-include {
|
||||
compatible = "binding-include-test";
|
||||
foo = <0>;
|
||||
bar = <1>;
|
||||
baz = <2>;
|
||||
qaz = <3>;
|
||||
};
|
||||
|
||||
//
|
||||
// For testing Node.props (derived from 'properties:' in the binding)
|
||||
//
|
||||
|
||||
props {
|
||||
compatible = "props";
|
||||
existent-boolean;
|
||||
int = <1>;
|
||||
array = <1 2 3>;
|
||||
uint8-array = [ 12 34 ];
|
||||
string = "foo";
|
||||
string-array = "foo", "bar", "baz";
|
||||
phandle-ref = < &{/ctrl-1} >;
|
||||
phandle-refs = < &{/ctrl-1} &{/ctrl-2} >;
|
||||
phandle-array-foos = < &{/ctrl-1} 1 &{/ctrl-2} 2 3 >;
|
||||
foo-gpios = < &{/ctrl-1} 1 >;
|
||||
path = &{/ctrl-1};
|
||||
};
|
||||
|
||||
ctrl-1 {
|
||||
compatible = "phandle-array-controller-1";
|
||||
#phandle-array-foo-cells = <1>;
|
||||
#gpio-cells = <1>;
|
||||
};
|
||||
|
||||
ctrl-2 {
|
||||
compatible = "phandle-array-controller-2";
|
||||
#phandle-array-foo-cells = <2>;
|
||||
};
|
||||
|
||||
props-2 {
|
||||
compatible = "props";
|
||||
phandle-array-foos = < &{/ctrl-0-1} 0 &{/ctrl-0-2} >;
|
||||
phandle-array-foo-names = "a", "missing", "b";
|
||||
};
|
||||
|
||||
ctrl-0-1 {
|
||||
compatible = "phandle-array-controller-0";
|
||||
#phandle-array-foo-cells = <0>;
|
||||
};
|
||||
|
||||
ctrl-0-2 {
|
||||
compatible = "phandle-array-controller-0";
|
||||
#phandle-array-foo-cells = <0>;
|
||||
};
|
||||
|
||||
//
|
||||
// Test <prefix>-map, via gpio-map
|
||||
//
|
||||
|
||||
gpio-map {
|
||||
source {
|
||||
compatible = "gpio-src";
|
||||
foo-gpios = <&{/gpio-map/connector} 3 4
|
||||
&{/gpio-map/connector} 1 2>;
|
||||
};
|
||||
connector {
|
||||
#gpio-cells = <2>;
|
||||
// Use different data lengths for source and
|
||||
// destination to make it a bit trickier
|
||||
gpio-map = <1 2 &{/gpio-map/destination} 5
|
||||
3 4 &{/gpio-map/destination} 6>;
|
||||
};
|
||||
destination {
|
||||
compatible = "gpio-dst";
|
||||
gpio-controller;
|
||||
#gpio-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// For testing Node.props with 'default:' values in binding
|
||||
//
|
||||
|
||||
defaults {
|
||||
compatible = "defaults";
|
||||
// Should override the 'default:' in the binding
|
||||
default-not-used = <234>;
|
||||
};
|
||||
|
||||
//
|
||||
// For testing 'enum:'
|
||||
//
|
||||
|
||||
enums {
|
||||
compatible = "enums";
|
||||
int-enum = <1>;
|
||||
string-enum = "foo_bar";
|
||||
tokenizable-enum = "123 is ok";
|
||||
tokenizable-lower-enum = "bar";
|
||||
no-enum = "baz";
|
||||
};
|
||||
|
||||
//
|
||||
// For testing 'bus:' and 'on-bus:'
|
||||
//
|
||||
|
||||
buses {
|
||||
// The 'node' nodes below will map to different bindings since
|
||||
// they appear on different buses
|
||||
foo-bus {
|
||||
compatible = "foo-bus";
|
||||
node1 {
|
||||
compatible = "on-bus", "on-any-bus";
|
||||
nested {
|
||||
compatible = "on-bus";
|
||||
};
|
||||
};
|
||||
node2 {
|
||||
compatible = "on-any-bus", "on-bus";
|
||||
};
|
||||
};
|
||||
bar-bus {
|
||||
compatible = "bar-bus";
|
||||
node {
|
||||
compatible = "on-bus";
|
||||
};
|
||||
};
|
||||
no-bus-node {
|
||||
compatible = "on-any-bus";
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// Node with 'child-binding:' in binding (along with a recursive
|
||||
// 'child-binding:')
|
||||
//
|
||||
|
||||
child-binding {
|
||||
compatible = "top-binding";
|
||||
child-1 {
|
||||
child-prop = <1>;
|
||||
grandchild {
|
||||
grandchild-prop = <2>;
|
||||
};
|
||||
};
|
||||
child-2 {
|
||||
child-prop = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// zephyr,user binding inference
|
||||
//
|
||||
|
||||
zephyr,user {
|
||||
boolean;
|
||||
bytes = [81 82 83];
|
||||
number = <23>;
|
||||
numbers = <1>, <2>, <3>;
|
||||
string = "text";
|
||||
strings = "a", "b", "c";
|
||||
handle = <&{/ctrl-1}>;
|
||||
phandles = <&{/ctrl-1}>, <&{/ctrl-2}>;
|
||||
phandle-array-foos = <&{/ctrl-2} 1 2>;
|
||||
};
|
||||
|
||||
//
|
||||
// For testing that neither 'include: [foo.yaml, bar.yaml]' nor
|
||||
// 'include: [bar.yaml, foo.yaml]' causes errors when one of the files
|
||||
// has 'required: true' and the other 'required: false'
|
||||
//
|
||||
|
||||
include-order {
|
||||
node-1 {
|
||||
compatible = "order-1";
|
||||
foo = <1>;
|
||||
};
|
||||
node-2 {
|
||||
compatible = "order-2";
|
||||
foo = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// For testing deprecated property
|
||||
//
|
||||
test-deprecated {
|
||||
compatible = "test-deprecated";
|
||||
oldprop = <4>; /* deprecated property */
|
||||
curprop = <5>;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// For testing deprecated features
|
||||
//
|
||||
|
||||
deprecated {
|
||||
compatible = "deprecated";
|
||||
required = <1>;
|
||||
required-2 = <2>;
|
||||
#foo-cells = <2>;
|
||||
sub-node {
|
||||
foos = <&{/deprecated} 1 2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
2246
tests/testdtlib.py
Normal file
2246
tests/testdtlib.py
Normal file
File diff suppressed because it is too large
Load diff
400
tests/testedtlib.py
Normal file
400
tests/testedtlib.py
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
# Copyright (c) 2019 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import io
|
||||
from logging import WARNING
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
import edtlib
|
||||
|
||||
# Test suite for edtlib.py.
|
||||
#
|
||||
# Run it using pytest (https://docs.pytest.org/en/stable/usage.html):
|
||||
#
|
||||
# $ pytest testedtlib.py
|
||||
#
|
||||
# See the comment near the top of testdtlib.py for additional pytest advice.
|
||||
#
|
||||
# test.dts is the main test file. test-bindings/ and test-bindings-2/ has
|
||||
# bindings. The tests mostly use string comparisons via the various __repr__()
|
||||
# methods.
|
||||
|
||||
def hpath(filename):
|
||||
'''Convert 'filename' to the host path syntax.'''
|
||||
return os.fspath(Path(filename))
|
||||
|
||||
def test_warnings(caplog):
|
||||
'''Tests for situations that should cause warnings.'''
|
||||
|
||||
edtlib.EDT("test.dts", ["test-bindings"])
|
||||
|
||||
enums_hpath = hpath('test-bindings/enums.yaml')
|
||||
expected_warnings = [
|
||||
f"'oldprop' is marked as deprecated in 'properties:' in {hpath('test-bindings/deprecated.yaml')} for node /test-deprecated.",
|
||||
"unit address and first address in 'reg' (0x1) don't match for /reg-zero-size-cells/node",
|
||||
"unit address and first address in 'reg' (0x5) don't match for /reg-ranges/parent/node",
|
||||
"unit address and first address in 'reg' (0x30000000200000001) don't match for /reg-nested-ranges/grandparent/parent/node",
|
||||
f"compatible 'enums' in binding '{enums_hpath}' has non-tokenizable enum for property 'string-enum': 'foo bar', 'foo_bar'",
|
||||
f"compatible 'enums' in binding '{enums_hpath}' has enum for property 'tokenizable-lower-enum' that is only tokenizable in lowercase: 'bar', 'BAR'",
|
||||
]
|
||||
assert caplog.record_tuples == [('edtlib', WARNING, warning_message)
|
||||
for warning_message in expected_warnings]
|
||||
|
||||
def test_interrupts():
|
||||
'''Tests for the interrupts property.'''
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
filenames = {i: hpath(f'test-bindings/interrupt-{i}-cell.yaml')
|
||||
for i in range(1, 4)}
|
||||
|
||||
assert str(edt.get_node("/interrupt-parent-test/node").interrupts) == \
|
||||
f"[<ControllerAndData, name: foo, controller: <Node /interrupt-parent-test/controller in 'test.dts', binding {filenames[3]}>, data: OrderedDict([('one', 1), ('two', 2), ('three', 3)])>, <ControllerAndData, name: bar, controller: <Node /interrupt-parent-test/controller in 'test.dts', binding {filenames[3]}>, data: OrderedDict([('one', 4), ('two', 5), ('three', 6)])>]"
|
||||
|
||||
assert str(edt.get_node("/interrupts-extended-test/node").interrupts) == \
|
||||
f"[<ControllerAndData, controller: <Node /interrupts-extended-test/controller-0 in 'test.dts', binding {filenames[1]}>, data: OrderedDict([('one', 1)])>, <ControllerAndData, controller: <Node /interrupts-extended-test/controller-1 in 'test.dts', binding {filenames[2]}>, data: OrderedDict([('one', 2), ('two', 3)])>, <ControllerAndData, controller: <Node /interrupts-extended-test/controller-2 in 'test.dts', binding {filenames[3]}>, data: OrderedDict([('one', 4), ('two', 5), ('three', 6)])>]"
|
||||
|
||||
assert str(edt.get_node("/interrupt-map-test/node@0").interrupts) == \
|
||||
f"[<ControllerAndData, controller: <Node /interrupt-map-test/controller-0 in 'test.dts', binding {filenames[1]}>, data: OrderedDict([('one', 0)])>, <ControllerAndData, controller: <Node /interrupt-map-test/controller-1 in 'test.dts', binding {filenames[2]}>, data: OrderedDict([('one', 0), ('two', 1)])>, <ControllerAndData, controller: <Node /interrupt-map-test/controller-2 in 'test.dts', binding {filenames[3]}>, data: OrderedDict([('one', 0), ('two', 0), ('three', 2)])>]"
|
||||
|
||||
assert str(edt.get_node("/interrupt-map-test/node@1").interrupts) == \
|
||||
f"[<ControllerAndData, controller: <Node /interrupt-map-test/controller-0 in 'test.dts', binding {filenames[1]}>, data: OrderedDict([('one', 3)])>, <ControllerAndData, controller: <Node /interrupt-map-test/controller-1 in 'test.dts', binding {filenames[2]}>, data: OrderedDict([('one', 0), ('two', 4)])>, <ControllerAndData, controller: <Node /interrupt-map-test/controller-2 in 'test.dts', binding {filenames[3]}>, data: OrderedDict([('one', 0), ('two', 0), ('three', 5)])>]"
|
||||
|
||||
assert str(edt.get_node("/interrupt-map-bitops-test/node@70000000E").interrupts) == \
|
||||
f"[<ControllerAndData, controller: <Node /interrupt-map-bitops-test/controller in 'test.dts', binding {filenames[2]}>, data: OrderedDict([('one', 3), ('two', 2)])>]"
|
||||
|
||||
def test_reg():
|
||||
'''Tests for the regs property'''
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
|
||||
assert str(edt.get_node("/reg-zero-address-cells/node").regs) == \
|
||||
"[<Register, size: 0x1>, <Register, size: 0x2>]"
|
||||
|
||||
assert str(edt.get_node("/reg-zero-size-cells/node").regs) == \
|
||||
"[<Register, addr: 0x1>, <Register, addr: 0x2>]"
|
||||
|
||||
assert str(edt.get_node("/reg-ranges/parent/node").regs) == \
|
||||
"[<Register, addr: 0x5, size: 0x1>, <Register, addr: 0xe0000000f, size: 0x1>, <Register, addr: 0xc0000000e, size: 0x1>, <Register, addr: 0xc0000000d, size: 0x1>, <Register, addr: 0xa0000000b, size: 0x1>, <Register, addr: 0x0, size: 0x1>]"
|
||||
|
||||
assert str(edt.get_node("/reg-nested-ranges/grandparent/parent/node").regs) == \
|
||||
"[<Register, addr: 0x30000000200000001, size: 0x1>]"
|
||||
|
||||
def test_pinctrl():
|
||||
'''Test 'pinctrl-<index>'.'''
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
|
||||
assert str(edt.get_node("/pinctrl/dev").pinctrls) == \
|
||||
"[<PinCtrl, name: zero, configuration nodes: []>, <PinCtrl, name: one, configuration nodes: [<Node /pinctrl/pincontroller/state-1 in 'test.dts', no binding>]>, <PinCtrl, name: two, configuration nodes: [<Node /pinctrl/pincontroller/state-1 in 'test.dts', no binding>, <Node /pinctrl/pincontroller/state-2 in 'test.dts', no binding>]>]"
|
||||
|
||||
def test_hierarchy():
|
||||
'''Test Node.parent and Node.children'''
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
|
||||
assert edt.get_node("/").parent is None
|
||||
|
||||
assert str(edt.get_node("/parent/child-1").parent) == \
|
||||
"<Node /parent in 'test.dts', no binding>"
|
||||
|
||||
assert str(edt.get_node("/parent/child-2/grandchild").parent) == \
|
||||
"<Node /parent/child-2 in 'test.dts', no binding>"
|
||||
|
||||
assert str(edt.get_node("/parent").children) == \
|
||||
"OrderedDict([('child-1', <Node /parent/child-1 in 'test.dts', no binding>), ('child-2', <Node /parent/child-2 in 'test.dts', no binding>)])"
|
||||
|
||||
assert edt.get_node("/parent/child-1").children == {}
|
||||
|
||||
def test_include():
|
||||
'''Test 'include:' and the legacy 'inherits: !include ...' in bindings'''
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
|
||||
assert str(edt.get_node("/binding-include").description) == \
|
||||
"Parent binding"
|
||||
|
||||
assert str(edt.get_node("/binding-include").props) == \
|
||||
"OrderedDict([('foo', <Property, name: foo, type: int, value: 0>), ('bar', <Property, name: bar, type: int, value: 1>), ('baz', <Property, name: baz, type: int, value: 2>), ('qaz', <Property, name: qaz, type: int, value: 3>)])"
|
||||
|
||||
def test_bus():
|
||||
'''Test 'bus:' and 'on-bus:' in bindings'''
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
|
||||
assert edt.get_node("/buses/foo-bus").bus == "foo"
|
||||
|
||||
# foo-bus does not itself appear on a bus
|
||||
assert edt.get_node("/buses/foo-bus").on_bus is None
|
||||
assert edt.get_node("/buses/foo-bus").bus_node is None
|
||||
|
||||
# foo-bus/node1 is not a bus node...
|
||||
assert edt.get_node("/buses/foo-bus/node1").bus is None
|
||||
# ...but is on a bus
|
||||
assert edt.get_node("/buses/foo-bus/node1").on_bus == "foo"
|
||||
assert edt.get_node("/buses/foo-bus/node1").bus_node.path == \
|
||||
"/buses/foo-bus"
|
||||
|
||||
# foo-bus/node2 is not a bus node...
|
||||
assert edt.get_node("/buses/foo-bus/node2").bus is None
|
||||
# ...but is on a bus
|
||||
assert edt.get_node("/buses/foo-bus/node2").on_bus == "foo"
|
||||
|
||||
# no-bus-node is not a bus node...
|
||||
assert edt.get_node("/buses/no-bus-node").bus is None
|
||||
# ... and is not on a bus
|
||||
assert edt.get_node("/buses/no-bus-node").on_bus is None
|
||||
|
||||
# Same compatible string, but different bindings from being on different
|
||||
# buses
|
||||
assert str(edt.get_node("/buses/foo-bus/node1").binding_path) == \
|
||||
hpath("test-bindings/device-on-foo-bus.yaml")
|
||||
assert str(edt.get_node("/buses/foo-bus/node2").binding_path) == \
|
||||
hpath("test-bindings/device-on-any-bus.yaml")
|
||||
assert str(edt.get_node("/buses/bar-bus/node").binding_path) == \
|
||||
hpath("test-bindings/device-on-bar-bus.yaml")
|
||||
assert str(edt.get_node("/buses/no-bus-node").binding_path) == \
|
||||
hpath("test-bindings/device-on-any-bus.yaml")
|
||||
|
||||
# foo-bus/node/nested also appears on the foo-bus bus
|
||||
assert edt.get_node("/buses/foo-bus/node1/nested").on_bus == "foo"
|
||||
assert str(edt.get_node("/buses/foo-bus/node1/nested").binding_path) == \
|
||||
hpath("test-bindings/device-on-foo-bus.yaml")
|
||||
|
||||
def test_child_binding():
|
||||
'''Test 'child-binding:' in bindings'''
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
child1 = edt.get_node("/child-binding/child-1")
|
||||
child2 = edt.get_node("/child-binding/child-2")
|
||||
grandchild = edt.get_node("/child-binding/child-1/grandchild")
|
||||
|
||||
assert str(child1.binding_path) == hpath("test-bindings/child-binding.yaml")
|
||||
assert str(child1.description) == "child node"
|
||||
assert str(child1.props) == "OrderedDict([('child-prop', <Property, name: child-prop, type: int, value: 1>)])"
|
||||
|
||||
assert str(child2.binding_path) == hpath("test-bindings/child-binding.yaml")
|
||||
assert str(child2.description) == "child node"
|
||||
assert str(child2.props) == "OrderedDict([('child-prop', <Property, name: child-prop, type: int, value: 3>)])"
|
||||
|
||||
assert str(grandchild.binding_path) == hpath("test-bindings/child-binding.yaml")
|
||||
assert str(grandchild.description) == "grandchild node"
|
||||
assert str(grandchild.props) == "OrderedDict([('grandchild-prop', <Property, name: grandchild-prop, type: int, value: 2>)])"
|
||||
|
||||
binding_file = Path("test-bindings/child-binding.yaml").resolve()
|
||||
top = edtlib.Binding(binding_file, {})
|
||||
child = top.child_binding
|
||||
assert Path(top.path) == binding_file
|
||||
assert Path(child.path) == binding_file
|
||||
assert top.compatible == 'top-binding'
|
||||
assert child.compatible is None
|
||||
|
||||
binding_file = Path("test-bindings/child-binding-with-compat.yaml").resolve()
|
||||
top = edtlib.Binding(binding_file, {})
|
||||
child = top.child_binding
|
||||
assert Path(top.path) == binding_file
|
||||
assert Path(child.path) == binding_file
|
||||
assert top.compatible == 'top-binding-with-compat'
|
||||
assert child.compatible == 'child-compat'
|
||||
|
||||
def test_props():
|
||||
'''Test Node.props (derived from DT and 'properties:' in the binding)'''
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
filenames = {i: hpath(f'test-bindings/phandle-array-controller-{i}.yaml')
|
||||
for i in range(0, 4)}
|
||||
|
||||
assert str(edt.get_node("/props").props["int"]) == \
|
||||
"<Property, name: int, type: int, value: 1>"
|
||||
|
||||
assert str(edt.get_node("/props").props["existent-boolean"]) == \
|
||||
"<Property, name: existent-boolean, type: boolean, value: True>"
|
||||
|
||||
assert str(edt.get_node("/props").props["nonexistent-boolean"]) == \
|
||||
"<Property, name: nonexistent-boolean, type: boolean, value: False>"
|
||||
|
||||
assert str(edt.get_node("/props").props["array"]) == \
|
||||
"<Property, name: array, type: array, value: [1, 2, 3]>"
|
||||
|
||||
assert str(edt.get_node("/props").props["uint8-array"]) == \
|
||||
r"<Property, name: uint8-array, type: uint8-array, value: b'\x124'>"
|
||||
|
||||
assert str(edt.get_node("/props").props["string"]) == \
|
||||
"<Property, name: string, type: string, value: 'foo'>"
|
||||
|
||||
assert str(edt.get_node("/props").props["string-array"]) == \
|
||||
"<Property, name: string-array, type: string-array, value: ['foo', 'bar', 'baz']>"
|
||||
|
||||
assert str(edt.get_node("/props").props["phandle-ref"]) == \
|
||||
f"<Property, name: phandle-ref, type: phandle, value: <Node /ctrl-1 in 'test.dts', binding {filenames[1]}>>"
|
||||
|
||||
assert str(edt.get_node("/props").props["phandle-refs"]) == \
|
||||
f"<Property, name: phandle-refs, type: phandles, value: [<Node /ctrl-1 in 'test.dts', binding {filenames[1]}>, <Node /ctrl-2 in 'test.dts', binding {filenames[2]}>]>"
|
||||
|
||||
assert str(edt.get_node("/props").props["phandle-array-foos"]) == \
|
||||
f"<Property, name: phandle-array-foos, type: phandle-array, value: [<ControllerAndData, controller: <Node /ctrl-1 in 'test.dts', binding {filenames[1]}>, data: OrderedDict([('one', 1)])>, <ControllerAndData, controller: <Node /ctrl-2 in 'test.dts', binding {filenames[2]}>, data: OrderedDict([('one', 2), ('two', 3)])>]>"
|
||||
|
||||
assert str(edt.get_node("/props-2").props["phandle-array-foos"]) == \
|
||||
("<Property, name: phandle-array-foos, type: phandle-array, value: ["
|
||||
f"<ControllerAndData, name: a, controller: <Node /ctrl-0-1 in 'test.dts', binding {filenames[0]}>, data: OrderedDict()>, "
|
||||
"None, "
|
||||
f"<ControllerAndData, name: b, controller: <Node /ctrl-0-2 in 'test.dts', binding {filenames[0]}>, data: OrderedDict()>]>")
|
||||
|
||||
assert str(edt.get_node("/props").props["foo-gpios"]) == \
|
||||
f"<Property, name: foo-gpios, type: phandle-array, value: [<ControllerAndData, controller: <Node /ctrl-1 in 'test.dts', binding {filenames[1]}>, data: OrderedDict([('gpio-one', 1)])>]>"
|
||||
|
||||
assert str(edt.get_node("/props").props["path"]) == \
|
||||
f"<Property, name: path, type: path, value: <Node /ctrl-1 in 'test.dts', binding {filenames[1]}>>"
|
||||
|
||||
def test_nexus():
|
||||
'''Test <prefix>-map via gpio-map (the most common case).'''
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
filename = hpath('test-bindings/gpio-dst.yaml')
|
||||
|
||||
assert str(edt.get_node("/gpio-map/source").props["foo-gpios"]) == \
|
||||
f"<Property, name: foo-gpios, type: phandle-array, value: [<ControllerAndData, controller: <Node /gpio-map/destination in 'test.dts', binding {filename}>, data: OrderedDict([('val', 6)])>, <ControllerAndData, controller: <Node /gpio-map/destination in 'test.dts', binding {filename}>, data: OrderedDict([('val', 5)])>]>"
|
||||
|
||||
def test_prop_defaults():
|
||||
'''Test property default values given in bindings'''
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
|
||||
assert str(edt.get_node("/defaults").props) == \
|
||||
r"OrderedDict([('int', <Property, name: int, type: int, value: 123>), ('array', <Property, name: array, type: array, value: [1, 2, 3]>), ('uint8-array', <Property, name: uint8-array, type: uint8-array, value: b'\x89\xab\xcd'>), ('string', <Property, name: string, type: string, value: 'hello'>), ('string-array', <Property, name: string-array, type: string-array, value: ['hello', 'there']>), ('default-not-used', <Property, name: default-not-used, type: int, value: 234>)])"
|
||||
|
||||
def test_prop_enums():
|
||||
'''test properties with enum: in the binding'''
|
||||
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"])
|
||||
props = edt.get_node('/enums').props
|
||||
int_enum = props['int-enum']
|
||||
string_enum = props['string-enum']
|
||||
tokenizable_enum = props['tokenizable-enum']
|
||||
tokenizable_lower_enum = props['tokenizable-lower-enum']
|
||||
no_enum = props['no-enum']
|
||||
|
||||
assert int_enum.val == 1
|
||||
assert int_enum.enum_index == 0
|
||||
assert not int_enum.spec.enum_tokenizable
|
||||
assert not int_enum.spec.enum_upper_tokenizable
|
||||
|
||||
assert string_enum.val == 'foo_bar'
|
||||
assert string_enum.enum_index == 1
|
||||
assert not string_enum.spec.enum_tokenizable
|
||||
assert not string_enum.spec.enum_upper_tokenizable
|
||||
|
||||
assert tokenizable_enum.val == '123 is ok'
|
||||
assert tokenizable_enum.val_as_token == '123_is_ok'
|
||||
assert tokenizable_enum.enum_index == 2
|
||||
assert tokenizable_enum.spec.enum_tokenizable
|
||||
assert tokenizable_enum.spec.enum_upper_tokenizable
|
||||
|
||||
assert tokenizable_lower_enum.val == 'bar'
|
||||
assert tokenizable_lower_enum.val_as_token == 'bar'
|
||||
assert tokenizable_lower_enum.enum_index == 0
|
||||
assert tokenizable_lower_enum.spec.enum_tokenizable
|
||||
assert not tokenizable_lower_enum.spec.enum_upper_tokenizable
|
||||
|
||||
assert no_enum.enum_index is None
|
||||
assert not no_enum.spec.enum_tokenizable
|
||||
assert not no_enum.spec.enum_upper_tokenizable
|
||||
|
||||
def test_binding_inference():
|
||||
'''Test inferred bindings for special zephyr-specific nodes.'''
|
||||
warnings = io.StringIO()
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"], warnings)
|
||||
|
||||
assert str(edt.get_node("/zephyr,user").props) == r"OrderedDict()"
|
||||
|
||||
edt = edtlib.EDT("test.dts", ["test-bindings"], warnings,
|
||||
infer_binding_for_paths=["/zephyr,user"])
|
||||
filenames = {i: hpath(f'test-bindings/phandle-array-controller-{i}.yaml')
|
||||
for i in range(1, 3)}
|
||||
|
||||
assert str(edt.get_node("/zephyr,user").props) == \
|
||||
rf"OrderedDict([('boolean', <Property, name: boolean, type: boolean, value: True>), ('bytes', <Property, name: bytes, type: uint8-array, value: b'\x81\x82\x83'>), ('number', <Property, name: number, type: int, value: 23>), ('numbers', <Property, name: numbers, type: array, value: [1, 2, 3]>), ('string', <Property, name: string, type: string, value: 'text'>), ('strings', <Property, name: strings, type: string-array, value: ['a', 'b', 'c']>), ('handle', <Property, name: handle, type: phandle, value: <Node /ctrl-1 in 'test.dts', binding {filenames[1]}>>), ('phandles', <Property, name: phandles, type: phandles, value: [<Node /ctrl-1 in 'test.dts', binding {filenames[1]}>, <Node /ctrl-2 in 'test.dts', binding {filenames[2]}>]>), ('phandle-array-foos', <Property, name: phandle-array-foos, type: phandle-array, value: [<ControllerAndData, controller: <Node /ctrl-2 in 'test.dts', binding {filenames[2]}>, data: OrderedDict([('one', 1), ('two', 2)])>]>)])"
|
||||
|
||||
def test_multi_bindings():
|
||||
'''Test having multiple directories with bindings'''
|
||||
edt = edtlib.EDT("test-multidir.dts", ["test-bindings", "test-bindings-2"])
|
||||
|
||||
assert str(edt.get_node("/in-dir-1").binding_path) == \
|
||||
hpath("test-bindings/multidir.yaml")
|
||||
|
||||
assert str(edt.get_node("/in-dir-2").binding_path) == \
|
||||
hpath("test-bindings-2/multidir.yaml")
|
||||
|
||||
def test_dependencies():
|
||||
''''Test dependency relations'''
|
||||
edt = edtlib.EDT("test-multidir.dts", ["test-bindings", "test-bindings-2"])
|
||||
|
||||
assert edt.get_node("/").dep_ordinal == 0
|
||||
assert edt.get_node("/in-dir-1").dep_ordinal == 1
|
||||
assert edt.get_node("/") in edt.get_node("/in-dir-1").depends_on
|
||||
assert edt.get_node("/in-dir-1") in edt.get_node("/").required_by
|
||||
|
||||
def test_slice_errs(tmp_path):
|
||||
'''Test error messages from the internal _slice() helper'''
|
||||
|
||||
dts_file = tmp_path / "error.dts"
|
||||
|
||||
verify_error("""
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
|
||||
sub {
|
||||
reg = <3>;
|
||||
};
|
||||
};
|
||||
""",
|
||||
dts_file,
|
||||
f"'reg' property in <Node /sub in '{dts_file}'> has length 4, which is not evenly divisible by 12 (= 4*(<#address-cells> (= 1) + <#size-cells> (= 2))). Note that #*-cells properties come either from the parent node or from the controller (in the case of 'interrupts').")
|
||||
|
||||
verify_error("""
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
sub {
|
||||
interrupts = <1>;
|
||||
interrupt-parent = < &{/controller} >;
|
||||
};
|
||||
controller {
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
};
|
||||
""",
|
||||
dts_file,
|
||||
f"'interrupts' property in <Node /sub in '{dts_file}'> has length 4, which is not evenly divisible by 8 (= 4*<#interrupt-cells>). Note that #*-cells properties come either from the parent node or from the controller (in the case of 'interrupts').")
|
||||
|
||||
verify_error("""
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
|
||||
sub-1 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <3>;
|
||||
ranges = <4 5>;
|
||||
|
||||
sub-2 {
|
||||
reg = <1 2 3 4 5>;
|
||||
};
|
||||
};
|
||||
};
|
||||
""",
|
||||
dts_file,
|
||||
f"'ranges' property in <Node /sub-1 in '{dts_file}'> has length 8, which is not evenly divisible by 24 (= 4*(<#address-cells> (= 2) + <#address-cells for parent> (= 1) + <#size-cells> (= 3))). Note that #*-cells properties come either from the parent node or from the controller (in the case of 'interrupts').")
|
||||
|
||||
def verify_error(dts, dts_file, expected_err):
|
||||
# Verifies that parsing a file 'dts_file' with the contents 'dts'
|
||||
# (a string) raises an EDTError with the message 'expected_err'.
|
||||
#
|
||||
# The path 'dts_file' is written with the string 'dts' before the
|
||||
# test is run.
|
||||
|
||||
with open(dts_file, "w", encoding="utf-8") as f:
|
||||
f.write(dts)
|
||||
f.flush() # Can't have unbuffered text IO, so flush() instead
|
||||
|
||||
with pytest.raises(edtlib.EDTError) as e:
|
||||
edtlib.EDT(dts_file, [])
|
||||
|
||||
assert str(e.value) == expected_err
|
||||
Loading…
Add table
Add a link
Reference in a new issue