1 /*
2  * Copyright (C) 2020-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "level_zero/tools/source/sysman/global_operations/global_operations_imp.h"
9 #include "level_zero/tools/test/unit_tests/sources/sysman/linux/mock_sysman_fixture.h"
10 
11 #include "mock_events.h"
12 
13 extern bool sysmanUltsEnable;
14 
15 using ::testing::Matcher;
16 
17 namespace L0 {
18 namespace ult {
19 
20 class SysmanEventsFixture : public SysmanDeviceFixture {
21   protected:
22     std::unique_ptr<Mock<EventsFsAccess>> pFsAccess;
23     FsAccess *pFsAccessOriginal = nullptr;
24     OsEvents *pOsEventsPrev = nullptr;
25     L0::EventsImp *pEventsImp;
26     GlobalOperations *pGlobalOperationsOriginal = nullptr;
27     std::unique_ptr<GlobalOperationsImp> pGlobalOperations;
28     std::unique_ptr<Mock<EventsSysfsAccess>> pSysfsAccess;
29     SysfsAccess *pSysfsAccessOriginal = nullptr;
30 
SetUp()31     void SetUp() override {
32         if (!sysmanUltsEnable) {
33             GTEST_SKIP();
34         }
35         SysmanDeviceFixture::SetUp();
36         pFsAccessOriginal = pLinuxSysmanImp->pFsAccess;
37         pFsAccess = std::make_unique<NiceMock<Mock<EventsFsAccess>>>();
38         pLinuxSysmanImp->pFsAccess = pFsAccess.get();
39 
40         pEventsImp = static_cast<L0::EventsImp *>(pSysmanDeviceImp->pEvents);
41         pOsEventsPrev = pEventsImp->pOsEvents;
42         pEventsImp->pOsEvents = nullptr;
43         pGlobalOperations = std::make_unique<GlobalOperationsImp>(pLinuxSysmanImp);
44         pGlobalOperationsOriginal = pSysmanDeviceImp->pGlobalOperations;
45         pSysmanDeviceImp->pGlobalOperations = pGlobalOperations.get();
46         pSysmanDeviceImp->pGlobalOperations->init();
47 
48         pSysfsAccessOriginal = pLinuxSysmanImp->pSysfsAccess;
49         pSysfsAccess = std::make_unique<NiceMock<Mock<EventsSysfsAccess>>>();
50         pLinuxSysmanImp->pSysfsAccess = pSysfsAccess.get();
51         ON_CALL(*pSysfsAccess.get(), readSymLink(_, _))
52             .WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<EventsSysfsAccess>::getValStringSymLinkSuccess));
53 
54         pEventsImp->init();
55     }
56 
TearDown()57     void TearDown() override {
58         if (!sysmanUltsEnable) {
59             GTEST_SKIP();
60         }
61         if (nullptr != pEventsImp->pOsEvents) {
62             delete pEventsImp->pOsEvents;
63         }
64         pEventsImp->pOsEvents = pOsEventsPrev;
65         pEventsImp = nullptr;
66         pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOriginal;
67         pLinuxSysmanImp->pFsAccess = pFsAccessOriginal;
68         pSysmanDeviceImp->pGlobalOperations = pGlobalOperationsOriginal;
69         SysmanDeviceFixture::TearDown();
70     }
71 };
72 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenAPIReturnsAfterReceivingEventWithinTimeout)73 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenAPIReturnsAfterReceivingEventWithinTimeout) {
74     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED));
75     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
76         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsOne));
77     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
78     phDevices[0] = device->toHandle();
79     uint32_t numDeviceEvents = 0;
80     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
81     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
82     EXPECT_EQ(1u, numDeviceEvents);
83     EXPECT_EQ(ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED, pDeviceEvents[0]);
84     delete[] phDevices;
85     delete[] pDeviceEvents;
86 }
87 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived)88 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived) {
89     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED));
90     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
91         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsZero));
92     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
93     phDevices[0] = device->toHandle();
94     uint32_t numDeviceEvents = 0;
95     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
96     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
97     EXPECT_EQ(0u, numDeviceEvents);
98 
99     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
100         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValFileNotFound));
101     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
102     EXPECT_EQ(0u, numDeviceEvents);
103 
104     delete[] phDevices;
105     delete[] pDeviceEvents;
106 }
107 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForCurrentlyUnsupportedEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived)108 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForCurrentlyUnsupportedEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived) {
109     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_TEMP_THRESHOLD2));
110     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
111         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsOne));
112     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
113     phDevices[0] = device->toHandle();
114     uint32_t numDeviceEvents = 0;
115     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
116     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
117     EXPECT_EQ(0u, numDeviceEvents);
118     delete[] phDevices;
119     delete[] pDeviceEvents;
120 }
121 
TEST_F(SysmanEventsFixture,GivenReadSymLinkCallFailsWhenGettingPCIBDFThenEmptyPciIdPathTagReceived)122 TEST_F(SysmanEventsFixture, GivenReadSymLinkCallFailsWhenGettingPCIBDFThenEmptyPciIdPathTagReceived) {
123     ON_CALL(*pSysfsAccess.get(), readSymLink(_, _))
124         .WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<EventsSysfsAccess>::getValStringSymLinkFailure));
125     PublicLinuxEventsImp linuxEventImp(pOsSysman);
126     EXPECT_TRUE(linuxEventImp.pciIdPathTag.empty());
127 }
128 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForDeviceDetachEventsThenEventListenAPIReturnsAfterReceivingEventWithinTimeout)129 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForDeviceDetachEventsThenEventListenAPIReturnsAfterReceivingEventWithinTimeout) {
130     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_DETACH));
131     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
132         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsOne));
133     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
134     phDevices[0] = device->toHandle();
135     uint32_t numDeviceEvents = 0;
136     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
137     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
138     EXPECT_EQ(1u, numDeviceEvents);
139     EXPECT_EQ(ZES_EVENT_TYPE_FLAG_DEVICE_DETACH, pDeviceEvents[0]);
140     delete[] phDevices;
141     delete[] pDeviceEvents;
142 }
143 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForDeviceDetachEventsThenAfterReceivingEventRegisterEventAgainToReceiveEvent)144 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForDeviceDetachEventsThenAfterReceivingEventRegisterEventAgainToReceiveEvent) {
145     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_DETACH));
146     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
147         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsOne));
148     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
149     phDevices[0] = device->toHandle();
150     uint32_t numDeviceEvents = 0;
151     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
152     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
153     EXPECT_EQ(1u, numDeviceEvents);
154     EXPECT_EQ(ZES_EVENT_TYPE_FLAG_DEVICE_DETACH, pDeviceEvents[0]);
155     numDeviceEvents = 0;
156     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
157     EXPECT_EQ(0u, numDeviceEvents);
158     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_DETACH));
159     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
160     EXPECT_EQ(1u, numDeviceEvents);
161     EXPECT_EQ(ZES_EVENT_TYPE_FLAG_DEVICE_DETACH, pDeviceEvents[0]);
162     delete[] phDevices;
163     delete[] pDeviceEvents;
164 }
165 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForDeviceDetachEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived)166 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForDeviceDetachEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived) {
167     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_DETACH));
168     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
169         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsZero));
170     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
171     phDevices[0] = device->toHandle();
172     uint32_t numDeviceEvents = 0;
173     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
174     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
175     EXPECT_EQ(0u, numDeviceEvents);
176 
177     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
178         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValFileNotFound));
179     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
180     EXPECT_EQ(0u, numDeviceEvents);
181 
182     delete[] phDevices;
183     delete[] pDeviceEvents;
184 }
185 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForDeviceAttachEventsThenEventListenAPIReturnsAfterReceivingEventWithinTimeout)186 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForDeviceAttachEventsThenEventListenAPIReturnsAfterReceivingEventWithinTimeout) {
187     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_ATTACH));
188     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
189         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsOne));
190     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
191     phDevices[0] = device->toHandle();
192     uint32_t numDeviceEvents = 0;
193     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
194     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
195     EXPECT_EQ(1u, numDeviceEvents);
196     EXPECT_EQ(ZES_EVENT_TYPE_FLAG_DEVICE_ATTACH, pDeviceEvents[0]);
197     delete[] phDevices;
198     delete[] pDeviceEvents;
199 }
200 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForDeviceAttachEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived)201 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForDeviceAttachEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived) {
202     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_ATTACH));
203     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
204         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsZero));
205     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
206     phDevices[0] = device->toHandle();
207     uint32_t numDeviceEvents = 0;
208     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
209     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
210     EXPECT_EQ(0u, numDeviceEvents);
211 
212     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
213         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValFileNotFound));
214     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
215     EXPECT_EQ(0u, numDeviceEvents);
216 
217     delete[] phDevices;
218     delete[] pDeviceEvents;
219 }
220 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForMemHealthEventsThenEventListenAPIReturnsAfterReceivingEventWithinTimeout)221 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForMemHealthEventsThenEventListenAPIReturnsAfterReceivingEventWithinTimeout) {
222     PublicLinuxEventsImp *pLinuxEventsImp = new PublicLinuxEventsImp(pOsSysman);
223     pLinuxEventsImp->eventRegister(ZES_EVENT_TYPE_FLAG_MEM_HEALTH);
224     pLinuxEventsImp->memHealthAtEventRegister = ZES_MEM_HEALTH_OK;
225     zes_event_type_flags_t events = 0;
226     uint32_t timeout = 1u;
227     EXPECT_TRUE(pLinuxEventsImp->eventListen(events, timeout));
228     EXPECT_EQ(events, ZES_EVENT_TYPE_FLAG_MEM_HEALTH);
229     delete pLinuxEventsImp;
230 }
231 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForMemHealthEventsAndMemHealthDidntOccurThenEventListenAPIReturnsWithinTimeout)232 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForMemHealthEventsAndMemHealthDidntOccurThenEventListenAPIReturnsWithinTimeout) {
233     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_MEM_HEALTH));
234     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
235     phDevices[0] = device->toHandle();
236     uint32_t numDeviceEvents = 0;
237     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
238     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
239     EXPECT_EQ(0u, numDeviceEvents);
240     delete[] phDevices;
241     delete[] pDeviceEvents;
242 }
243 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForAListOfEventsThenEventRegisterAPIReturnsProperErrorCodeInCaseEventsAreInvalid)244 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForAListOfEventsThenEventRegisterAPIReturnsProperErrorCodeInCaseEventsAreInvalid) {
245     zes_event_type_flags_t events1 = 0x7ffe;
246     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), events1));
247     zes_event_type_flags_t events2 = 0x1e240;
248     EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ENUMERATION, zesDeviceEventRegister(device->toHandle(), events2));
249 }
250 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenExAPIReturnsAfterReceivingEventWithinTimeout)251 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenExAPIReturnsAfterReceivingEventWithinTimeout) {
252     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED));
253     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
254         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsOne));
255     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
256     phDevices[0] = device->toHandle();
257     uint32_t numDeviceEvents = 0;
258     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
259     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListenEx(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
260     EXPECT_EQ(1u, numDeviceEvents);
261     EXPECT_EQ(ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED, pDeviceEvents[0]);
262     delete[] phDevices;
263     delete[] pDeviceEvents;
264 }
265 
TEST_F(SysmanEventsFixture,GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenExAPIWaitForTimeoutIfEventNotReceived)266 TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenExAPIWaitForTimeoutIfEventNotReceived) {
267     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED));
268     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
269         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsZero));
270     zes_device_handle_t *phDevices = new zes_device_handle_t[1];
271     phDevices[0] = device->toHandle();
272     uint32_t numDeviceEvents = 0;
273     zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1];
274     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListenEx(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
275     EXPECT_EQ(0u, numDeviceEvents);
276 
277     ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
278         .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValFileNotFound));
279     EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListenEx(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
280     EXPECT_EQ(0u, numDeviceEvents);
281 
282     delete[] phDevices;
283     delete[] pDeviceEvents;
284 }
285 
286 } // namespace ult
287 } // namespace L0
288