225 lines
8.2 KiB
C++
225 lines
8.2 KiB
C++
/*
|
|
* Copyright (c) Huawei Technologies Co., Ltd. 2019-2020. All rights reserved.
|
|
* Description: ps llt
|
|
* Author: wujing
|
|
* Create: 2019-12-19
|
|
*/
|
|
#include "ps.h"
|
|
#include <ctime>
|
|
#include <cmath>
|
|
#include <random>
|
|
#include <gtest/gtest.h>
|
|
#include <gmock/gmock.h>
|
|
#include "grpc_client_mock.h"
|
|
#include "utils.h"
|
|
|
|
using ::testing::Args;
|
|
using ::testing::ByRef;
|
|
using ::testing::SetArgPointee;
|
|
using ::testing::DoAll;
|
|
using ::testing::NiceMock;
|
|
using ::testing::Return;
|
|
using ::testing::NotNull;
|
|
using ::testing::AtLeast;
|
|
using ::testing::Invoke;
|
|
using ::testing::_;
|
|
|
|
using namespace std;
|
|
|
|
class ContainerListUnitTest : public testing::Test {
|
|
public:
|
|
void SetUp() override
|
|
{
|
|
GrpcClient_SetMock(&m_grpcClient);
|
|
::testing::Mock::AllowLeak(&m_grpcClient);
|
|
}
|
|
void TearDown() override
|
|
{
|
|
GrpcClient_SetMock(nullptr);
|
|
}
|
|
|
|
NiceMock<MockGrpcClient> m_grpcClient;
|
|
};
|
|
|
|
namespace {
|
|
unsigned generate_random_pid()
|
|
{
|
|
constexpr int pid_start = 10000;
|
|
constexpr int pid_end = 10000;
|
|
static default_random_engine e(time(0));
|
|
static uniform_int_distribution<unsigned> u(pid_start, pid_end);
|
|
return u(e);
|
|
}
|
|
|
|
long long generate_random_created()
|
|
{
|
|
// unix nanos: 2019-01-01T00:00:00.000000000+08:00
|
|
constexpr int64_t start = 1546272000000000000ll;
|
|
// unix nanos: 2019-12-31T00:00:00.000000000+08:00
|
|
constexpr int64_t end = 1577721600000000000ll;
|
|
|
|
static default_random_engine e(time(0));
|
|
static uniform_int_distribution<long long> u(start, end);
|
|
return u(e);
|
|
}
|
|
|
|
string generate_random_string(int length)
|
|
{
|
|
static string chset = "abcdefghijklmnopqrstuvwxyz1234567890";
|
|
string result;
|
|
result.resize(length);
|
|
|
|
srand(time(NULL));
|
|
for (int i = 0; i < length; i++) {
|
|
static default_random_engine e(time(0));
|
|
static uniform_int_distribution<unsigned> u(0, chset.size() - 1);
|
|
result[i] = chset[u(e) % chset.length()];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int set_container_summary(struct isula_list_response *response, int index)
|
|
{
|
|
constexpr int id_len = 64;
|
|
constexpr int name_len = 8;
|
|
|
|
response->container_summary[index] = (struct isula_container_summary_info *)util_common_calloc_s(
|
|
sizeof(struct isula_container_summary_info));
|
|
if (response->container_summary[index] == nullptr) {
|
|
return -1;
|
|
}
|
|
response->container_summary[index]->id = util_strdup_s(generate_random_string(id_len).c_str());
|
|
response->container_summary[index]->name = util_strdup_s(generate_random_string(name_len).c_str());
|
|
response->container_summary[index]->runtime = util_strdup_s("lcr");
|
|
response->container_summary[index]->pid = generate_random_pid();
|
|
response->container_summary[index]->status = (Container_Status)CONTAINER_STATUS_RUNNING;
|
|
response->container_summary[index]->image = util_strdup_s("busybox:latest");
|
|
response->container_summary[index]->command = util_strdup_s("/bin/sh");
|
|
response->container_summary[index]->startat = util_strdup_s("2019-12-31T23:55:50.867369507+08:00");
|
|
response->container_summary[index]->finishat = util_strdup_s("2020-01-01T23:55:50.867369507+08:00");
|
|
response->container_summary[index]->exit_code = 0;
|
|
response->container_summary[index]->restart_count = 0;
|
|
response->container_summary[index]->created = generate_random_created();
|
|
response->container_summary[index]->health_state = util_strdup_s("(healthy)");
|
|
response->container_num++;
|
|
|
|
return 0;
|
|
}
|
|
} // namespace
|
|
|
|
int ContainerList(const struct isula_list_request *request,
|
|
struct isula_list_response *response, void *arg)
|
|
{
|
|
(void)request;
|
|
(void)arg;
|
|
constexpr int container_cnt = 5;
|
|
response->cc = 0;
|
|
response->server_errono = 0;
|
|
response->errmsg = nullptr;
|
|
response->container_summary = (struct isula_container_summary_info **)util_common_calloc_s(
|
|
sizeof(struct isula_container_summary_info *) * container_cnt);
|
|
if (response->container_summary == nullptr) {
|
|
return -1;
|
|
}
|
|
for (size_t i {}; i < container_cnt; ++i) {
|
|
if (set_container_summary(response, i)) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int invokeGrpcOpsInit(isula_connect_ops *ops)
|
|
{
|
|
if (ops == nullptr) {
|
|
return -1;
|
|
}
|
|
ops->container.list = &ContainerList;
|
|
return 0;
|
|
}
|
|
|
|
TEST_F(ContainerListUnitTest, test_cmd_list_main_all)
|
|
{
|
|
const char *argv[] = {"isula", "ps", "-a"};
|
|
const char *argv_failure[] = {"isula", "ps", "-k"};
|
|
isula_connect_ops ops;
|
|
|
|
ops.container.list = &ContainerList;
|
|
EXPECT_CALL(m_grpcClient, GrpcOpsInit(_))
|
|
.WillOnce(Return(-1))
|
|
.WillOnce(DoAll(SetArgPointee<0>(ByRef(ops)), Return(0)));
|
|
ASSERT_EQ(connect_client_ops_init(), -1);
|
|
ASSERT_EQ(connect_client_ops_init(), 0);
|
|
EXPECT_EXIT(cmd_list_main(sizeof(argv) / sizeof(argv[0]), const_cast<const char **>(argv)),
|
|
testing::ExitedWithCode(0), "");
|
|
|
|
EXPECT_CALL(m_grpcClient, GrpcOpsInit(_)).WillRepeatedly(Invoke(invokeGrpcOpsInit));
|
|
ASSERT_EQ(connect_client_ops_init(), 0);
|
|
EXPECT_EXIT(cmd_list_main(sizeof(argv) / sizeof(argv[0]), const_cast<const char **>(argv)),
|
|
testing::ExitedWithCode(0), "");
|
|
EXPECT_EXIT(cmd_list_main(sizeof(argv_failure) / sizeof(argv_failure[0]), const_cast<const char **>(argv_failure)),
|
|
testing::ExitedWithCode(125), "Unkown flag found");
|
|
testing::Mock::VerifyAndClearExpectations(&m_grpcClient);
|
|
}
|
|
|
|
TEST_F(ContainerListUnitTest, test_cmd_list_main_format)
|
|
{
|
|
const char *argv[] = {
|
|
"isula", "ps", "-a", "--format", "\"table XXX{{.ID}}AAA{{.Image}}"
|
|
" {{.Status}} {{.Pid}} {{.Command}} {{.Created}} {{.Ports}} {{.ExitCode}} "
|
|
"{{.RestartCount}} {{.StartAt}} {{.FinishAt}} {{.Runtime}} \t{{.Names}} \n{{.State}}\""
|
|
};
|
|
const char *argv_failure[] = {"isula", "ps", "--format", "\"{{.ID}} {{.XXX}}"};
|
|
|
|
EXPECT_CALL(m_grpcClient, GrpcOpsInit(_)).WillRepeatedly(Invoke(invokeGrpcOpsInit));
|
|
ASSERT_EQ(connect_client_ops_init(), 0);
|
|
EXPECT_EXIT(cmd_list_main(sizeof(argv) / sizeof(argv[0]), const_cast<const char **>(argv)),
|
|
testing::ExitedWithCode(0), "");
|
|
EXPECT_EXIT(cmd_list_main(sizeof(argv_failure) / sizeof(argv_failure[0]), const_cast<const char **>(argv_failure)),
|
|
testing::ExitedWithCode(1), "not support the field");
|
|
testing::Mock::VerifyAndClearExpectations(&m_grpcClient);
|
|
}
|
|
|
|
TEST_F(ContainerListUnitTest, test_cmd_list_main_notrunc)
|
|
{
|
|
const char *argv[] = {"isula", "ps", "-q", "--no-trunc"};
|
|
testing::internal::CaptureStdout();
|
|
|
|
EXPECT_CALL(m_grpcClient, GrpcOpsInit(_)).WillRepeatedly(Invoke(invokeGrpcOpsInit));
|
|
ASSERT_EQ(connect_client_ops_init(), 0);
|
|
EXPECT_EXIT(cmd_list_main(sizeof(argv) / sizeof(argv[0]), const_cast<const char **>(argv)),
|
|
testing::ExitedWithCode(0), "");
|
|
std::string output = testing::internal::GetCapturedStdout();
|
|
if (output.find("CONTAINER ID") != std::string::npos) {
|
|
ADD_FAILURE() << "the output of command('isula ps -q --no-trunc') should not include table headers";
|
|
}
|
|
std::cout << "Gtest Captured Stdout:" << std::endl << output;
|
|
testing::Mock::VerifyAndClearExpectations(&m_grpcClient);
|
|
}
|
|
|
|
TEST_F(ContainerListUnitTest, test_cmd_list_main_debug)
|
|
{
|
|
const char *argv[] = {"isula", "ps", "-a", "-D"};
|
|
testing::internal::CaptureStdout();
|
|
|
|
EXPECT_CALL(m_grpcClient, GrpcOpsInit(_)).WillRepeatedly(Invoke(invokeGrpcOpsInit));
|
|
ASSERT_EQ(connect_client_ops_init(), 0);
|
|
EXPECT_EXIT(cmd_list_main(sizeof(argv) / sizeof(argv[0]), const_cast<const char **>(argv)),
|
|
testing::ExitedWithCode(0), "");
|
|
std::string output = testing::internal::GetCapturedStdout();
|
|
std::vector<std::string> tableItems {"CONTAINER ID", "IMAGE", "COMMAND", "CREATED", "STATUS", "PORTS", "NAMES"};
|
|
for (const auto &elem : tableItems) {
|
|
if (output.find(elem) == std::string::npos) {
|
|
ADD_FAILURE() << "container list info should include " << elem;
|
|
}
|
|
}
|
|
if (output.find("healthy") == std::string::npos) {
|
|
FAIL() << "container list info should include healthy";
|
|
}
|
|
std::cout << "Gtest Captured Stdout:" << std::endl << output;
|
|
testing::Mock::VerifyAndClearExpectations(&m_grpcClient);
|
|
SUCCEED() << "test isula ps --debug success";
|
|
}
|
|
|