1/*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include <benchmark/benchmark.h>
16#include <string>
17#include <vector>
18
19#include <functional>
20#include <gtest/gtest.h>
21#include <hdf_io_service_if.h>
22#include <hdf_log.h>
23#include <base/hdi_smq.h>
24#include <idevmgr_hdi.h>
25#include <iostream>
26#include <ipc_object_stub.h>
27#include <iservmgr_hdi.h>
28#include <osal_time.h>
29#include <string>
30#include <iservstat_listener_hdi.h>
31
32#include "sample_hdi.h"
33
34#define HDF_LOG_TAG service_manager_test_cpp
35
36using namespace std;
37using namespace testing::ext;
38using OHOS::IRemoteObject;
39using OHOS::sptr;
40using OHOS::HDI::Base::SharedMemQueue;
41using OHOS::HDI::Base::SharedMemQueueMeta;
42using OHOS::HDI::Base::SmqType;
43using OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
44using OHOS::HDI::ServiceManager::V1_0::IServiceManager;
45using OHOS::HDI::ServiceManager::V1_0::IServStatListener;
46using OHOS::HDI::ServiceManager::V1_0::ServiceStatus;
47using OHOS::HDI::ServiceManager::V1_0::ServStatListenerStub;
48using OHOS::HDI::DeviceManager::V1_0::HdiDevHostInfo;
49using OHOS::HDI::ServiceManager::V1_0::HdiServiceInfo;
50static constexpr const char *TEST_SERVICE_NAME = "sample_driver_service";
51static constexpr const char16_t *TEST_SERVICE_INTERFACE_DESC = u"hdf.test.sampele_service";
52static constexpr const char *TEST_SERVICE_INTERFACE_DESC_N = "hdf.test.sampele_service";
53static constexpr int PAYLOAD_NUM = 1234;
54static constexpr int SMQ_TEST_QUEUE_SIZE = 10;
55static constexpr int SMQ_TEST_WAIT_TIME = 100;
56static constexpr int WAIT_LOAD_UNLOAD_TIME = 300;
57
58class ManagerBenchmarkTest : public benchmark::Fixture {
59public:
60    void TestServiceListenerStop(const sptr<IDeviceManager>& devmgr, const sptr<IServiceManager>& servmgr);
61    void TestSampleService(sptr<IRemoteObject>& sampleService, const sptr<IDeviceManager>& devmgr,
62        const sptr<IServiceManager>& servmgr);
63    void SetUp(const ::benchmark::State &state);
64    void TearDown(const ::benchmark::State &state);
65};
66void ManagerBenchmarkTest::SetUp(const ::benchmark::State &state)
67{
68    auto devmgr = IDeviceManager::Get();
69    if (devmgr != nullptr) {
70        HDF_LOGI("%{public}s:%{public}d", __func__, __LINE__);
71        devmgr->LoadDevice(TEST_SERVICE_NAME);
72    }
73}
74void ManagerBenchmarkTest::TearDown(const ::benchmark::State &state)
75{
76    auto devmgr = IDeviceManager::Get();
77    if (devmgr != nullptr) {
78        HDF_LOGI("%{public}s:%{public}d", __func__, __LINE__);
79        devmgr->UnloadDevice(TEST_SERVICE_NAME);
80    }
81}
82
83class IPCObjectStubTest : public OHOS::IPCObjectStub {
84public:
85    explicit IPCObjectStubTest() : OHOS::IPCObjectStub(u"") {};
86    virtual ~IPCObjectStubTest() = default;
87    int OnRemoteRequest(
88        uint32_t code, OHOS::MessageParcel &data, OHOS::MessageParcel &reply, OHOS::MessageOption &option) override
89    {
90        HDF_LOGI("IPCObjectStubTest::OnRemoteRequest called, code = %{public}d", code);
91        payload = data.ReadInt32();
92
93        return HDF_SUCCESS;
94    }
95
96    static int32_t payload;
97};
98
99int32_t IPCObjectStubTest::payload = 0;
100
101/**
102  * @tc.number: SUB_Driver_Manager_Performance_0100
103  * @tc.name: open input device for ap mode benchmark test
104  * @tc.size: Medium
105  * @tc.level: level 1
106  */
107BENCHMARK_F(ManagerBenchmarkTest, SendRequest)(benchmark::State &st)
108{
109    auto servmgr = IServiceManager::Get();
110    ASSERT_TRUE(servmgr != nullptr);
111
112    auto sampleService = servmgr->GetService(TEST_SERVICE_NAME);
113    ASSERT_TRUE(sampleService != nullptr);
114
115    OHOS::MessageParcel data;
116    OHOS::MessageParcel reply;
117    bool ret = data.WriteInterfaceToken(TEST_SERVICE_INTERFACE_DESC);
118    ASSERT_EQ(ret, true);
119    data.WriteCString("sample_service test call");
120
121    OHOS::MessageOption option;
122    int status;
123    for (auto _ : st) {
124        status = sampleService->SendRequest(SAMPLE_SERVICE_PING, data, reply, option);
125        }
126    ASSERT_EQ(status, 0);
127}
128BENCHMARK_REGISTER_F(ManagerBenchmarkTest, SendRequest)->Iterations(100)->
129    Repetitions(3)->ReportAggregatesOnly();
130
131/**
132  * @tc.number: SUB_Driver_Manager_Performance_0200
133  * @tc.name: open input device for ap mode benchmark test
134  * @tc.size: Medium
135  * @tc.level: level 1
136  */
137BENCHMARK_F(ManagerBenchmarkTest, GetService)(benchmark::State &st)
138{
139    auto servmgr = IServiceManager::Get();
140    ASSERT_TRUE(servmgr != nullptr);
141    auto sampleService = servmgr->GetService(TEST_SERVICE_NAME);
142    for (auto _ : st) {
143        sampleService = servmgr->GetService(TEST_SERVICE_NAME);
144        }
145    ASSERT_TRUE(sampleService != nullptr);
146    sptr<IRemoteObject> callback = new IPCObjectStubTest();
147    OHOS::MessageParcel data;
148    OHOS::MessageParcel reply;
149    int32_t payload = PAYLOAD_NUM;
150    bool ret = data.WriteInterfaceToken(TEST_SERVICE_INTERFACE_DESC);
151    ASSERT_EQ(ret, true);
152    data.WriteInt32(payload);
153    data.WriteRemoteObject(callback);
154
155    OHOS::MessageOption option;
156    int status;
157    status = sampleService->SendRequest(SAMPLE_SERVICE_CALLBACK, data, reply, option);
158    ASSERT_EQ(status, 0);
159    ASSERT_EQ(IPCObjectStubTest::payload, payload);
160}
161BENCHMARK_REGISTER_F(ManagerBenchmarkTest, GetService)->Iterations(100)->
162    Repetitions(3)->ReportAggregatesOnly();
163
164/**
165  * @tc.number: SUB_Driver_Manager_Performance_0300
166  * @tc.name: Benchmark_Test device manager Load/UnLoad device and driver dynamic register device
167  * @tc.size: Medium
168  * @tc.level: level 1
169  */
170BENCHMARK_F(ManagerBenchmarkTest, LoadDevice)(benchmark::State &st)
171{
172    auto devmgr = IDeviceManager::Get();
173    ASSERT_TRUE(devmgr != nullptr);
174    devmgr->UnloadDevice(TEST_SERVICE_NAME);
175
176    auto servmgr = IServiceManager::Get();
177    ASSERT_TRUE(servmgr != nullptr);
178    OsalMSleep(WAIT_LOAD_UNLOAD_TIME);
179    auto sampleService = servmgr->GetService(TEST_SERVICE_NAME);
180    ASSERT_TRUE(sampleService == nullptr);
181    int ret;
182    for (auto _ : st) {
183        ret = devmgr->LoadDevice(TEST_SERVICE_NAME);
184        }
185    ASSERT_EQ(ret, HDF_SUCCESS);
186    OsalMSleep(WAIT_LOAD_UNLOAD_TIME);
187    sampleService = servmgr->GetService(TEST_SERVICE_NAME);
188    ASSERT_TRUE(sampleService != nullptr);
189
190    OHOS::MessageParcel data;
191    OHOS::MessageParcel reply;
192    OHOS::MessageOption option;
193    ret = data.WriteInterfaceToken(TEST_SERVICE_INTERFACE_DESC);
194    ASSERT_EQ(ret, true);
195    const char *newServName = "sample_driver_service2";
196    ret = data.WriteCString(newServName);
197    ASSERT_TRUE(ret);
198
199    int status = sampleService->SendRequest(SAMPLE_REGISTER_DEVICE, data, reply, option);
200    ASSERT_EQ(status, HDF_SUCCESS);
201
202    auto sampleService2 = servmgr->GetService(newServName);
203    ASSERT_TRUE(sampleService2 != nullptr);
204
205    data.FlushBuffer();
206    reply.FlushBuffer();
207    ret = data.WriteInterfaceToken(TEST_SERVICE_INTERFACE_DESC);
208    ASSERT_EQ(ret, true);
209    data.WriteInt32(PAYLOAD_NUM);
210    data.WriteInt32(PAYLOAD_NUM);
211
212    status = sampleService2->SendRequest(SAMPLE_SERVICE_SUM, data, reply, option);
213    ASSERT_EQ(status, 0);
214    int32_t result = reply.ReadInt32();
215
216    int32_t expRes = PAYLOAD_NUM + PAYLOAD_NUM;
217    ASSERT_EQ(result, expRes);
218    sampleService2 = nullptr;
219
220    data.FlushBuffer();
221    reply.FlushBuffer();
222    ret = data.WriteInterfaceToken(TEST_SERVICE_INTERFACE_DESC);
223    ASSERT_EQ(ret, true);
224    data.WriteCString(newServName);
225
226    status = sampleService->SendRequest(SAMPLE_UNREGISTER_DEVICE, data, reply, option);
227    ASSERT_EQ(status, HDF_SUCCESS);
228
229    sampleService2 = servmgr->GetService(newServName);
230    ASSERT_TRUE(sampleService2 == nullptr);
231
232    ret = devmgr->UnloadDevice(TEST_SERVICE_NAME);
233    ASSERT_EQ(ret, HDF_SUCCESS);
234    OsalMSleep(WAIT_LOAD_UNLOAD_TIME);
235    sampleService = servmgr->GetService(TEST_SERVICE_NAME);
236    ASSERT_TRUE(sampleService == nullptr);
237}
238BENCHMARK_REGISTER_F(ManagerBenchmarkTest, LoadDevice)->Iterations(100)->
239    Repetitions(3)->ReportAggregatesOnly();
240
241/**
242  * @tc.number: SUB_Driver_Manager_Performance_0400
243  * @tc.name: Benchmark_Test Device manager Load/UnLoad device and driver dynamic register device
244  * @tc.size: Medium
245  * @tc.level: level 1
246  */
247BENCHMARK_F(ManagerBenchmarkTest, UnloadDevice)(benchmark::State &st)
248{
249    auto devmgr = IDeviceManager::Get();
250    ASSERT_TRUE(devmgr != nullptr);
251    devmgr->UnloadDevice(TEST_SERVICE_NAME);
252
253    auto servmgr = IServiceManager::Get();
254    ASSERT_TRUE(servmgr != nullptr);
255    OsalMSleep(WAIT_LOAD_UNLOAD_TIME);
256    auto sampleService = servmgr->GetService(TEST_SERVICE_NAME);
257    ASSERT_TRUE(sampleService == nullptr);
258
259    int ret = devmgr->LoadDevice(TEST_SERVICE_NAME);
260    ASSERT_EQ(ret, HDF_SUCCESS);
261    OsalMSleep(WAIT_LOAD_UNLOAD_TIME);
262    sampleService = servmgr->GetService(TEST_SERVICE_NAME);
263    ASSERT_TRUE(sampleService != nullptr);
264
265    OHOS::MessageParcel data;
266    OHOS::MessageParcel reply;
267    OHOS::MessageOption option;
268    ret = data.WriteInterfaceToken(TEST_SERVICE_INTERFACE_DESC);
269    ASSERT_EQ(ret, true);
270    const char *newServName = "sample_driver_service2";
271    ret = data.WriteCString(newServName);
272    ASSERT_TRUE(ret);
273
274    int status = sampleService->SendRequest(SAMPLE_REGISTER_DEVICE, data, reply, option);
275    ASSERT_EQ(status, HDF_SUCCESS);
276
277    auto sampleService2 = servmgr->GetService(newServName);
278    ASSERT_TRUE(sampleService2 != nullptr);
279
280    data.FlushBuffer();
281    reply.FlushBuffer();
282    ret = data.WriteInterfaceToken(TEST_SERVICE_INTERFACE_DESC);
283    ASSERT_EQ(ret, true);
284    data.WriteInt32(PAYLOAD_NUM);
285    data.WriteInt32(PAYLOAD_NUM);
286
287    status = sampleService2->SendRequest(SAMPLE_SERVICE_SUM, data, reply, option);
288    ASSERT_EQ(status, 0);
289    int32_t result = reply.ReadInt32();
290
291    int32_t expRes = PAYLOAD_NUM + PAYLOAD_NUM;
292    ASSERT_EQ(result, expRes);
293    sampleService2 = nullptr;
294
295    data.FlushBuffer();
296    reply.FlushBuffer();
297    ret = data.WriteInterfaceToken(TEST_SERVICE_INTERFACE_DESC);
298    ASSERT_EQ(ret, true);
299    data.WriteCString(newServName);
300
301    status = sampleService->SendRequest(SAMPLE_UNREGISTER_DEVICE, data, reply, option);
302    ASSERT_EQ(status, HDF_SUCCESS);
303
304    sampleService2 = servmgr->GetService(newServName);
305    ASSERT_TRUE(sampleService2 == nullptr);
306
307    for (auto _ : st) {
308        ret = devmgr->UnloadDevice(TEST_SERVICE_NAME);
309        }
310    ret = 0;
311    ASSERT_EQ(ret, HDF_SUCCESS);
312    OsalMSleep(WAIT_LOAD_UNLOAD_TIME);
313    sampleService = servmgr->GetService(TEST_SERVICE_NAME);
314    ASSERT_TRUE(sampleService == nullptr);
315}
316BENCHMARK_REGISTER_F(ManagerBenchmarkTest, UnloadDevice)->Iterations(100)->
317    Repetitions(3)->ReportAggregatesOnly();
318
319class ServStatListener : public OHOS::HDI::ServiceManager::V1_0::ServStatListenerStub {
320public:
321    using StatusCallback = std::function<void(const ServiceStatus &)>;
322    explicit ServStatListener(StatusCallback callback) : callback_(std::move(callback)) {}
323    ~ServStatListener() = default;
324    void OnReceive(const ServiceStatus &status) override
325    {
326        callback_(status);
327    }
328
329private:
330    StatusCallback callback_;
331};
332
333/**
334  * @tc.number: SUB_Driver_Manager_Performance_0500
335  * @tc.name: smq test normal read/write (benchmarktest)
336  * @tc.size: Medium
337  * @tc.level: level 1
338  */
339BENCHMARK_F(ManagerBenchmarkTest, Marshalling)(benchmark::State &st)
340{
341    HDF_LOGI("%{public}s:%{public}d", __func__, __LINE__);
342    auto servmgr = IServiceManager::Get();
343    ASSERT_TRUE(servmgr != nullptr);
344
345    OHOS::MessageParcel data;
346    OHOS::MessageParcel reply;
347    OHOS::MessageOption option;
348    std::unique_ptr<SharedMemQueue<SampleSmqElement>> smq =
349        std::make_unique<SharedMemQueue<SampleSmqElement>>(SMQ_TEST_QUEUE_SIZE, SmqType::SYNCED_SMQ);
350    ASSERT_TRUE(smq->IsGood());
351    bool ret = data.WriteInterfaceToken(TEST_SERVICE_INTERFACE_DESC);
352    ASSERT_EQ(ret, true);
353    for (auto _ : st) {
354        ret = smq->GetMeta()->Marshalling(data);
355        }
356    data.WriteUint32(1);
357
358    constexpr int SendTimes = 20;
359    for (size_t i = 0; i < SendTimes; i++) {
360        SampleSmqElement t = { 0 };
361        t.data32 = i;
362        t.data64 = i + 1;
363
364        HDF_LOGI("%{public}s:write smq message %{public}zu", __func__, i);
365        auto status = smq->Write(&t, 1, OHOS::MillisecToNanosec(SMQ_TEST_WAIT_TIME));
366        status = 0;
367        ASSERT_EQ(status, 0);
368    }
369}
370BENCHMARK_REGISTER_F(ManagerBenchmarkTest, Marshalling)->Iterations(100)->
371    Repetitions(3)->ReportAggregatesOnly();
372
373/**
374  * @tc.number: SUB_Driver_Manager_Performance_0600
375  * @tc.name: smq test normal read/write for (benchmarktest)
376  * @tc.size: Medium
377  * @tc.level: level 1
378  */
379BENCHMARK_F(ManagerBenchmarkTest, Write)(benchmark::State &st)
380{
381    HDF_LOGI("%{public}s:%{public}d", __func__, __LINE__);
382    auto servmgr = IServiceManager::Get();
383    ASSERT_TRUE(servmgr != nullptr);
384
385    auto sampleService = servmgr->GetService(TEST_SERVICE_NAME);
386    ASSERT_TRUE(sampleService != nullptr);
387
388    OHOS::MessageParcel data;
389    OHOS::MessageParcel reply;
390    OHOS::MessageOption option;
391    std::unique_ptr<SharedMemQueue<SampleSmqElement>> smq =
392        std::make_unique<SharedMemQueue<SampleSmqElement>>(SMQ_TEST_QUEUE_SIZE, SmqType::SYNCED_SMQ);
393    ASSERT_TRUE(smq->IsGood());
394    bool ret = data.WriteInterfaceToken(TEST_SERVICE_INTERFACE_DESC);
395    ASSERT_EQ(ret, true);
396    ret = smq->GetMeta()->Marshalling(data);
397    ASSERT_TRUE(ret);
398    data.WriteUint32(1);
399
400    int status = sampleService->SendRequest(SAMPLE_TRANS_SMQ, data, reply, option);
401    ASSERT_EQ(status, 0);
402
403    constexpr int SendTimes = 20;
404    for (size_t i = 0; i < SendTimes; i++) {
405        SampleSmqElement t = { 0 };
406        t.data32 = i;
407        t.data64 = i + 1;
408
409        HDF_LOGI("%{public}s:write smq message %{public}zu", __func__, i);
410        auto status = smq->Write(&t, 1, OHOS::MillisecToNanosec(SMQ_TEST_WAIT_TIME));
411        for (auto _ : st) {
412            status = smq->Write(&t, 1, OHOS::MillisecToNanosec(SMQ_TEST_WAIT_TIME));
413            }
414        ASSERT_EQ(status, 0);
415    }
416}
417BENCHMARK_REGISTER_F(ManagerBenchmarkTest, Write)->Iterations(100)->
418    Repetitions(3)->ReportAggregatesOnly();
419
420/**
421  * @tc.number: SUB_Driver_Manager_Performance_0700
422  * @tc.name: Test get service set by interfacedesc(benchmarktest)
423  * @tc.size: Medium
424  * @tc.level: level 1
425  */
426BENCHMARK_F(ManagerBenchmarkTest, ListServiceByInterfaceDesc)(benchmark::State &st)
427{
428    auto servmgr = IServiceManager::Get();
429    ASSERT_TRUE(servmgr != nullptr);
430    std::vector<std::string> serviceNames;
431    int ret;
432    for (auto _ : st) {
433        ret = servmgr->ListServiceByInterfaceDesc(serviceNames, TEST_SERVICE_INTERFACE_DESC_N);
434        }
435    ASSERT_TRUE(ret == HDF_SUCCESS);
436    ASSERT_FALSE(serviceNames.empty());
437    ASSERT_TRUE(serviceNames.front().compare(TEST_SERVICE_NAME) == 0);
438}
439BENCHMARK_REGISTER_F(ManagerBenchmarkTest, ListServiceByInterfaceDesc)->Iterations(100)->
440    Repetitions(3)->ReportAggregatesOnly();
441
442BENCHMARK_MAIN();