From a5180fcac14331a3195b8739f2d29c55447773ec Mon Sep 17 00:00:00 2001 From: liujialiang Date: Sat, 26 Nov 2022 12:58:54 +0800 Subject: [PATCH] Add test suit for RWLock RWLock is a part of libutils.z.so, but never has a test suit. So we add one for it. We prepare two test cases for RWLock to verify that it works well under two different mode(write-first or not). Signed-off-by: liujialiang --- base/test/unittest/common/BUILD.gn | 14 ++ .../unittest/common/utils_rwlock_test.cpp | 128 ++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 base/test/unittest/common/utils_rwlock_test.cpp diff --git a/base/test/unittest/common/BUILD.gn b/base/test/unittest/common/BUILD.gn index 0d7f4b4..f9f6cba 100644 --- a/base/test/unittest/common/BUILD.gn +++ b/base/test/unittest/common/BUILD.gn @@ -292,6 +292,19 @@ ohos_unittest("UtilsTimerTest") { ] } +############################################################################### +ohos_unittest("UtilsRWLockTest") { + module_out_path = module_output_path + sources = [ "utils_rwlock_test.cpp" ] + + configs = [ ":module_private_config" ] + + deps = [ + "//commonlibrary/c_utils/base:utils", + "//third_party/googletest:gtest_main", + ] +} + ############################################################################### group("unittest") { @@ -304,6 +317,7 @@ group("unittest") { ":UtilsDateTimeTest", ":UtilsDirectoryTest", ":UtilsParcelTest", + ":UtilsRWLockTest", ":UtilsRefbaseTest", ":UtilsSafeBlockQueueTest", ":UtilsSafeBlockQueueTrackingTest", diff --git a/base/test/unittest/common/utils_rwlock_test.cpp b/base/test/unittest/common/utils_rwlock_test.cpp new file mode 100644 index 0000000..dbd6d48 --- /dev/null +++ b/base/test/unittest/common/utils_rwlock_test.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include "rwlock.h" + +using namespace testing::ext; +using namespace std; + +namespace OHOS { +namespace { + +class UtilsRWLockTest : public testing::Test {}; + +// This class is designed for test RWLock. "buf" is protected by "rwLock". +class TestRWLock { +public: + TestRWLock():rwLock(), buf() {} + + explicit TestRWLock(bool writeFirst):rwLock(writeFirst), buf() {} + + void WriteStr(const string& str) + { + rwLock.LockWrite(); + for (auto it = str.begin(); it != str.end(); it++) { + buf.push_back(*it); + this_thread::sleep_for(std::chrono::milliseconds(1)); + } + rwLock.UnLockWrite(); + return; + } + + void ReadStr(string& str) + { + rwLock.LockRead(); + for (auto it = buf.begin(); it != buf.end(); it++) { + str.push_back(*it); + this_thread::sleep_for(std::chrono::milliseconds(1)); + } + rwLock.UnLockRead(); + return; + } +private: + Utils::RWLock rwLock; + string buf; +}; + +const string WRITE_IN_1("write1"); +const string WRITE_IN_2("write2"); + +/* + * @tc.name: testRWLock001 + * @tc.desc: RWLock here is under write-first mode. If there are some writing operation waiting, + * reading will never happen. Reading operations will happen at the same time, when all writing operations + * have finished. + */ +HWTEST_F(UtilsRWLockTest, testRWLock001, TestSize.Level1) +{ + TestRWLock test; + + thread first(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_1))); + this_thread::sleep_for(chrono::milliseconds(1)); + + string readOut1(""); + thread second(bind(&TestRWLock::ReadStr, ref(test), ref(readOut1))); + this_thread::sleep_for(chrono::milliseconds(1)); + + thread third(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_2))); + this_thread::sleep_for(chrono::milliseconds(1)); + + string readOut2(""); + thread fourth(bind(&TestRWLock::ReadStr, ref(test), ref(readOut2))); + + first.join(); + second.join(); + third.join(); + fourth.join(); + + EXPECT_EQ(readOut1, WRITE_IN_1 + WRITE_IN_2); + EXPECT_EQ(readOut2, WRITE_IN_1 + WRITE_IN_2); +} + +/* + * @tc.name: testRWLock002 + * @tc.desc: RWLock here is not under write-first mode. So if there are writing and reading operations in queue + * with a writing mission running, they will compete when the writing mission completing. But what we can ensure + * is that reading operations in queue will happen at the same time. + */ +HWTEST_F(UtilsRWLockTest, testRWLock002, TestSize.Level1) +{ + TestRWLock test(false); + + thread first(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_1))); + this_thread::sleep_for(chrono::milliseconds(1)); + + string readOut1(""); + thread second(bind(&TestRWLock::ReadStr, ref(test), ref(readOut1))); + this_thread::sleep_for(chrono::milliseconds(1)); + + thread third(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_2))); + this_thread::sleep_for(chrono::milliseconds(1)); + + string readOut2(""); + thread fourth(bind(&TestRWLock::ReadStr, ref(test), ref(readOut2))); + + first.join(); + second.join(); + third.join(); + fourth.join(); + + EXPECT_EQ(readOut1, readOut2); +} +} // namespace +} // namespace OHOS \ No newline at end of file -- Gitee