1/*
2 * Copyright (c) 2023-2024 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
16#define private public
17#define protected public
18
19#include <gtest/gtest.h>
20
21#include "channel.h"
22#include "fi_log.h"
23
24#undef LOG_TAG
25#define LOG_TAG "ChannelTest"
26
27namespace OHOS {
28namespace Msdp {
29namespace DeviceStatus {
30namespace {
31constexpr size_t DEFAULT_WAIT_TIME { 10 };
32}
33using namespace testing::ext;
34
35class ChannelTest : public testing::Test {
36public:
37    static void SetUpTestCase() {}
38    static void TearDownTestCase() {}
39    void SetUp() {}
40    void TearDown() {}
41};
42
43/**
44 * @tc.name: ChannelTest001
45 * @tc.desc: test channel throuthput when sending speed is greater than receiving speed.
46 * @tc.type: FUNC
47 */
48HWTEST_F(ChannelTest, ChannelTest001, TestSize.Level0)
49{
50    CALL_TEST_DEBUG;
51    auto [sender, receiver] = Channel<size_t>::OpenChannel();
52    constexpr size_t count = Channel<size_t>::QUEUE_CAPACITY;
53    receiver.Enable();
54
55    std::thread worker([sender = sender, count]() mutable {
56        for (size_t index = 0; index < count; ++index) {
57            EXPECT_EQ(sender.Send(index), Channel<size_t>::NO_ERROR);
58        }
59    });
60    for (size_t expected = 0; expected < count;) {
61        size_t received = receiver.Receive();
62        EXPECT_EQ(received, expected);
63        if ((++expected % 10) == 0) {
64            std::this_thread::sleep_for(std::chrono::milliseconds(DEFAULT_WAIT_TIME));
65        }
66    }
67    if (worker.joinable()) {
68        worker.join();
69    }
70}
71
72/**
73 * @tc.name: ChannelTest002
74 * @tc.desc: test channel throuthput when sending speed is less than receiving speed.
75 * @tc.type: FUNC
76 */
77HWTEST_F(ChannelTest, ChannelTest002, TestSize.Level0)
78{
79    CALL_TEST_DEBUG;
80    auto [sender, receiver] = Channel<size_t>::OpenChannel();
81    constexpr size_t count = Channel<size_t>::QUEUE_CAPACITY;
82    receiver.Enable();
83
84    std::thread worker([sender = sender, count]() mutable {
85        for (size_t index = 0; index < count;) {
86            EXPECT_EQ(sender.Send(index), Channel<size_t>::NO_ERROR);
87            if ((++index % 10) == 0) {
88                std::this_thread::sleep_for(std::chrono::milliseconds(DEFAULT_WAIT_TIME));
89            }
90        }
91    });
92    for (size_t expected = 0; expected < count; ++expected) {
93        size_t received = receiver.Receive();
94        ASSERT_EQ(received, expected);
95    }
96    if (worker.joinable()) {
97        worker.join();
98    }
99}
100
101/**
102 * @tc.name: ChannelTest003
103 * @tc.desc: Disallow sending of events when channel is inactive.
104 * @tc.type: FUNC
105 */
106HWTEST_F(ChannelTest, ChannelTest003, TestSize.Level0)
107{
108    CALL_TEST_DEBUG;
109    auto [sender, receiver] = Channel<size_t>::OpenChannel();
110    const size_t data = 1;
111    EXPECT_EQ(sender.Send(data), Channel<size_t>::INACTIVE_CHANNEL);
112}
113
114/**
115 * @tc.name: ChannelTest004
116 * @tc.desc: Disallow sending of events when queue is full.
117 * @tc.type: FUNC
118 */
119HWTEST_F(ChannelTest, ChannelTest004, TestSize.Level0)
120{
121    CALL_TEST_DEBUG;
122    auto [sender, receiver] = Channel<size_t>::OpenChannel();
123    size_t data = 1;
124    receiver.Enable();
125
126    for (size_t index = 0; index < Channel<size_t>::QUEUE_CAPACITY; ++index) {
127        EXPECT_EQ(sender.Send(data++), Channel<size_t>::NO_ERROR);
128    };
129    EXPECT_EQ(sender.Send(data), Channel<size_t>::QUEUE_IS_FULL);
130}
131} // namespace DeviceStatus
132} // namespace Msdp
133} // namespace OHOS
134