* Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
*
* 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.
*/
* Description: Status basic function test.
*/
#include "datasystem/common/rdma/rdma_util.h"
#include "datasystem/common/log/trace.h"
#include "datasystem/common/util/status_helper.h"
#include "ut/common.h"
namespace datasystem {
namespace ut {
class StatusTest : public CommonTest {
public:
static Status ReturnUnexpectedError(const std::string &msg)
{
RETURN_STATUS(StatusCode::K_UNKNOWN_ERROR, msg);
}
static Status ReturnNullError(const int *ptr)
{
RETURN_RUNTIME_ERROR_IF_NULL(ptr);
return Status::OK();
}
static Status ReturnIfNotOk(const Status &status)
{
RETURN_IF_NOT_OK(status);
return Status::OK();
}
static Status ReturnIfFail(bool condition, const std::string &msg)
{
CHECK_FAIL_RETURN_STATUS(condition, StatusCode::K_RUNTIME_ERROR, msg);
return Status::OK();
}
static Status ReturnIfFailPrintError(bool condition, const StatusCode &code, const std::string &msg)
{
CHECK_FAIL_RETURN_STATUS_PRINT_ERROR(condition, code, msg);
return Status::OK();
}
};
TEST_F(StatusTest, TestMarco)
{
LOG(INFO) << "Test Status Marco.";
{
Status status = ReturnUnexpectedError("Hello World!");
ASSERT_EQ(status.GetCode(), StatusCode::K_UNKNOWN_ERROR);
ASSERT_TRUE(status.GetMsg().find("Hello World!") != std::string::npos);
}
{
int *integerPtr = nullptr;
Status status = ReturnNullError(integerPtr);
ASSERT_EQ(status.GetCode(), StatusCode::K_RUNTIME_ERROR);
ASSERT_TRUE(status.GetMsg().find("The pointer [ptr] is null.") != std::string::npos);
int i = 1;
integerPtr = &i;
status = ReturnNullError(integerPtr);
ASSERT_EQ(status.GetCode(), StatusCode::K_OK);
}
{
Status s(StatusCode::K_UNKNOWN_ERROR, "Welcome to Wild Rift!");
Status status = ReturnIfNotOk(s);
ASSERT_EQ(status.GetCode(), StatusCode::K_UNKNOWN_ERROR);
ASSERT_TRUE(status.GetMsg().find("Welcome to Wild Rift!") != std::string::npos);
s = Status::OK();
status = ReturnIfNotOk(s);
ASSERT_EQ(status.GetCode(), StatusCode::K_OK);
}
{
Status status = ReturnIfFail(true, "The world is not black or white, but a delicious shade of grey.");
ASSERT_EQ(status.GetCode(), StatusCode::K_OK);
status = ReturnIfFail(false, "The world is not black or white, but a delicious shade of grey.");
ASSERT_EQ(status.GetCode(), StatusCode::K_RUNTIME_ERROR);
ASSERT_TRUE(status.GetMsg().find("The world is not black or white, but a delicious shade of grey.")
!= std::string::npos);
}
{
Status status = ReturnIfFailPrintError(true, K_OK, "It's cool.");
ASSERT_EQ(status.GetCode(), StatusCode::K_OK);
status = ReturnIfFailPrintError(false, K_INVALID, "It's cool.");
ASSERT_EQ(status.GetCode(), StatusCode::K_INVALID);
ASSERT_TRUE(status.GetMsg().find("It's cool.") != std::string::npos);
}
}
TEST_F(StatusTest, TestMoveConstructor)
{
LOG(INFO) << "Test Status move constructor";
{
Status one = Status::OK();
Status another = std::move(one);
ASSERT_TRUE(one.IsOk());
ASSERT_TRUE(another.IsOk());
}
{
Status one = Status(StatusCode::K_UNKNOWN_ERROR, "It's not lies that cut but the sharpness of the truth.");
Status another = std::move(one);
ASSERT_TRUE(one.IsOk());
ASSERT_FALSE(another.IsOk());
}
}
TEST_F(StatusTest, TestMoveAssignment)
{
LOG(INFO) << "Test Status move assignment";
{
Status one = Status::OK();
Status another(StatusCode::K_UNKNOWN_ERROR, "Morality is a beautiful servant and a dangerous master.");
another = one;
ASSERT_TRUE(one.IsOk());
ASSERT_TRUE(another.IsOk());
}
{
Status one(StatusCode::K_UNKNOWN_ERROR, "Morality is a beautiful servant and a dangerous master.");
Status another = Status::OK();
another = std::move(one);
ASSERT_TRUE(one.IsOk());
ASSERT_FALSE(another.IsOk());
ASSERT_EQ(another.GetMsg(), "Morality is a beautiful servant and a dangerous master.");
}
}
TEST_F(StatusTest, EventWaitForTimeoutReturnsDeadlineExceeded)
{
auto event = std::make_shared<Event>(1);
Status status = event->WaitFor(std::chrono::milliseconds(0));
ASSERT_EQ(status.GetCode(), StatusCode::K_RPC_DEADLINE_EXCEEDED);
ASSERT_TRUE(status.GetMsg().find("Timed out waiting for request") != std::string::npos);
}
TEST_F(StatusTest, EventWaitForSucceedsAfterNotify)
{
auto event = std::make_shared<Event>(2);
event->NotifyAll();
Status status = event->WaitFor(std::chrono::milliseconds(0));
ASSERT_TRUE(status.IsOk()) << status.ToString();
}
TEST_F(StatusTest, EventWaitAnyTimeoutReturnsDeadlineExceeded)
{
auto waiter = std::make_shared<EventWaiter>();
std::shared_ptr<Event> event;
Status status = waiter->WaitAny(std::chrono::milliseconds(0), event);
ASSERT_EQ(status.GetCode(), StatusCode::K_RPC_DEADLINE_EXCEEDED);
ASSERT_TRUE(status.GetMsg().find("Timed out waiting for any event") != std::string::npos);
}
TEST_F(StatusTest, EventWaitAnySucceedsAfterNotify)
{
auto waiter = std::make_shared<EventWaiter>();
auto event = std::make_shared<Event>(3, waiter);
event->NotifyAll();
std::shared_ptr<Event> notifiedEvent;
Status status = waiter->WaitAny(std::chrono::milliseconds(0), notifiedEvent);
ASSERT_TRUE(status.IsOk()) << status.ToString();
ASSERT_NE(notifiedEvent, nullptr);
ASSERT_EQ(notifiedEvent->GetRequestId(), 3);
}
TEST_F(StatusTest, TestOperatorEqual)
{
LOG(INFO) << "Test Status operator==";
{
Status one = Status::OK();
Status another = Status::OK();
ASSERT_TRUE(one == another);
}
{
Status one = Status::OK();
Status another(StatusCode::K_RUNTIME_ERROR, "Results are all that matters.");
ASSERT_FALSE(one == another);
}
{
Status one(StatusCode::K_RUNTIME_ERROR, "I will not be misled.");
Status another(StatusCode::K_RUNTIME_ERROR, "Results are all that matters.");
ASSERT_TRUE(one == another);
}
{
Status one(StatusCode::K_UNKNOWN_ERROR, "I will not be misled.");
Status another(StatusCode::K_RUNTIME_ERROR, "Results are all that matters.");
ASSERT_FALSE(one == another);
}
}
TEST_F(StatusTest, TestOperatorNotEqual)
{
LOG(INFO) << "Test Status operator!=";
{
Status one = Status::OK();
Status another = Status::OK();
ASSERT_FALSE(one != another);
}
{
Status one = Status::OK();
Status another(StatusCode::K_RUNTIME_ERROR, "Results are all that matters.");
ASSERT_TRUE(one != another);
}
{
Status one(StatusCode::K_RUNTIME_ERROR, "I will not be misled.");
Status another(StatusCode::K_RUNTIME_ERROR, "Results are all that matters.");
ASSERT_FALSE(one != another);
}
{
Status one(StatusCode::K_UNKNOWN_ERROR, "I will not be misled.");
Status another(StatusCode::K_RUNTIME_ERROR, "Results are all that matters.");
ASSERT_TRUE(one != another);
}
}
TEST_F(StatusTest, TestStreamOperator)
{
LOG(INFO) << "Test Status operator<<";
Status status(StatusCode::K_OUT_OF_MEMORY, "Fight for the First Lands!");
std::stringstream ss;
ss << status;
ASSERT_TRUE(ss.str().find("Fight for the First Lands!") != std::string::npos);
}
TEST_F(StatusTest, TestStatusLogForMat)
{
Status status(StatusCode::K_RUNTIME_ERROR, "This is a msg.");
status.AppendMsg("This is appended msg.");
ASSERT_EQ(status.GetMsg(), "This is a msg. This is appended msg.");
Status status1(StatusCode::K_RUNTIME_ERROR, "This is a msg");
status1.AppendMsg("This is appended msg.");
ASSERT_EQ(status1.GetMsg(), "This is a msg. This is appended msg.");
Status status3(StatusCode::K_RUNTIME_ERROR, "");
status3.AppendMsg("This is appended msg.");
ASSERT_EQ(status3.GetMsg(), " This is appended msg.");
TraceGuard traceGuard = Trace::Instance().SetTraceUUID();
Status status4(StatusCode::K_RUNTIME_ERROR, "This is a msg.");
ASSERT_TRUE(status4.GetMsg().find("This is a msg, traceId: ") != std::string::npos);
Status status5(StatusCode::K_RUNTIME_ERROR, "This is a msg");
ASSERT_TRUE(status5.GetMsg().find("This is a msg, traceId: ") != std::string::npos);
Status status6(StatusCode::K_RUNTIME_ERROR, status5.GetMsg());
auto traceIdTagPos = status6.GetMsg().find(", traceId: ");
ASSERT_NE(traceIdTagPos, std::string::npos);
ASSERT_EQ(status6.GetMsg().find(", traceId: ", traceIdTagPos + 1), std::string::npos);
}
}
}