README.md
1# Metrics Test
2
3The metrics test consists at testing aidl endpoint establishment
4and interaction between a vendorAtom Relayer (Metrics TA) in Trusty
5and vendorAtom Consumer in Normal World.
6The Consumer is expected to advertise itself to the relayer by sharing
7its iStats facet via the iStatsSetter interface (AIDL Callback pattern).
8Once the Consumer iStats facet is initialized, the Relayer can relay
9atoms to the Consumer asynchronously, as soon as receiving them
10from any Trusty TA.
11
12We are going to support testing in two modes:
13
141- Consumer as a Trusty TA first
15 Allows to test the Relayer as well as the atoms serialization
16 library (see `trusty/interfaces/atoms`).
17 Unfortunately asynchronous callback is not supported for Secure World
18 initiators due to the single-threaded limitation in Trusty user-space.
19 So for this test, we use the synchronous callback approach
20 (refer to the sequence diagram in section 1.)
21
222- Consumer as a Normal-World Daemon
23 Allows to test the desired architecture, with Consumer in Normal World
24 as the asynchronous callback initiator.
25 (refer to the sequence diagram in section 2.)
26
27## 1. Consumer as a Trusty TA
28
29
30```mermaid
31sequenceDiagram
32 participant test as Stats PORT_TEST<br/>(Secure World)
33 participant consumer as Consumer TA<br/>(Secure World)
34 participant relayer as Relayer TA<br/>(Secure World)
35 test->>consumer: share memory buffer
36 note over relayer: implements IStats as relayer
37 test->>+relayer: IStats:recordVendorAtom(atom)
38 relayer->>relayer: store IStats object
39 relayer-->>-test: return
40 test ->> test: wait until shared mem is updated
41 note over test, relayer: on Trusty, binder async callbacks are not yet supported<br/>(single-thread limitation)
42 note over test, relayer: Hence the consumer needs to regularly call setInterface for receiving atoms
43 loop every TIME_OUT_INTERVAL_MS
44 note over relayer: implements IStatsSetter
45 consumer->>+relayer: IStatsSetter::setInterface(this)
46 relayer->>relayer: atom = stored IStats object
47 note over consumer: implements IStats as final consumer
48 relayer->>+consumer: IStats:recordVendorAtom(atom)
49 consumer ->> consumer: write atom to shared mem
50 consumer -->> test: shared mem updated
51 consumer -->>-relayer: return rc
52 relayer -->>- consumer: return
53 end
54 test ->> test: verify shared mem == atom
55```
56
57
58
59### Build & Test
60
61
62```
63$ ./trusty/vendor/google/aosp/scripts/build.py qemu-generic-arm64-test-debug --skip-test
64$ ./build-root/build-qemu-generic-arm64-test-debug/run --verbose --headless --boot-test "com.android.trusty.stats.test"
65```
66
67### Debug Crash Backtrace
68
69
70```
71$ export A2L=$PWD/prebuilts/clang/host/linux-x86/llvm-binutils-stable/llvm-addr2line
72$ $A2L -e build-root/build-qemu-generic-arm64-test-debug/user_tasks/trusty/user/app/sample/stats-test/stats-test.syms.elf <address>
73```
74
75## 2. Consumer as a Normal-World Daemon
76
77
78```mermaid
79sequenceDiagram
80 participant test as GTest<br/>parent thread<br/>(Normal World)
81 participant consumer as Consumer<br/>forked thread<br/>(Normal World)
82 participant relayer as Relayer TA<br/>(Secure World)
83 participant port_test as Stats PORT_TEST<br/>(Secure World)
84 critical Initialisation process
85 test->>consumer: fork thread and share atom buffer
86 note over relayer: implements IStatsSetter
87 consumer->>+relayer: IStatsSetter::setInterface(this)
88 relayer->>relayer: atom = store IStats object
89 relayer -->>- consumer: return
90 option unit test process
91 test ->> test: wait for shared mem to be updated
92
93 port_test->>port_test: create an atom from canned data
94 note over relayer: implements IStats as relayer
95 port_test->>+relayer: IStats:recordVendorAtom(atom)
96 relayer->>relayer: use IStats object obtained during initialisation
97 relayer->>+consumer: IStats:recordVendorAtom(atom)
98 consumer ->> consumer: write atom to shared mem
99 consumer -->>- relayer: return rc
100 relayer -->>- port_test: return
101 test ->> test: verify shared mem holds the canned data
102 end
103
104```
105
106
107Implementation notes:
108
109* The Trusty Relayer from section 1. is updated to also
110expose an IStatsSetter port to the Normal World, store the Normal World IStats
111callback facet, and use it asynchronously upon receiving atoms from
112the Stats PORT_TEST.
113
114* The Trusty Stats PORT_TEST is reused as is.
115
116* The test sequence consists in starting the Normal-World GTest first, then
117 the Stats PORT_TEST. Both unit tests should provide a PASS verdict for the
118 test to succeed.
119