Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add gtest, fix string trim function crash #42

Merged
merged 7 commits into from
Nov 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@ include(cmake/llhttp.cmake)
include(cmake/fmt.cmake)
include(cmake/spdlog.cmake)
include(cmake/folly.cmake)
include(cmake/gtest.cmake)
include(cmake/rocksdb.cmake)

enable_testing()

ADD_SUBDIRECTORY(src/pstd)
ADD_SUBDIRECTORY(src/net)
Expand Down
12 changes: 12 additions & 0 deletions cmake/gtest.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright (c) 2023-present, Qihoo, Inc. All rights reserved.
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.

FETCHCONTENT_DECLARE(
gtest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FETCHCONTENT_MAKEAVAILABLE(gtest)
15 changes: 13 additions & 2 deletions cmake/rocksdb.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,16 @@ FetchContent_Declare(
GIT_TAG v8.6.7
)

FetchContent_MakeAvailable(rocksdb)
include_directories(${rocksdb_SOURCE_DIR}/include)
FetchContent_MakeAvailableWithArgs(rocksdb
BUILD_TYPE=OFF
WITH_TESTS=OFF
WITH_BENCHMARK=OFF
WITH_BENCHMARK_TOOLS=OFF
WITH_TOOLS=OFF
WITH_CORE_TOOLS=OFF
WITH_TRACE_TOOLS=OFF
WITH_EXAMPLES=OFF
ROCKSDB_BUILD_SHARED=OFF
WITH_GFLAGS=OFF
WITH_LIBURING=OFF
)
3 changes: 2 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/net)
ADD_EXECUTABLE(pikiwidb ${PIKIWIDB_SRC})
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

TARGET_LINK_LIBRARIES(pikiwidb net; dl; leveldb; fmt; pikiwidb-folly)
TARGET_INCLUDE_DIRECTORIES(pikiwidb PRIVATE ${rocksdb_SOURCE_DIR}/include)
TARGET_LINK_LIBRARIES(pikiwidb net; dl; leveldb; fmt; pikiwidb-folly; rocksdb)
SET_TARGET_PROPERTIES(pikiwidb PROPERTIES LINKER_LANGUAGE CXX)
6 changes: 6 additions & 0 deletions src/pstd/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
# Copyright (c) 2023-present, Qihoo, Inc. All rights reserved.
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.

AUX_SOURCE_DIRECTORY(. STD_SRC)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
ADD_LIBRARY(pstd ${STD_SRC})

ADD_SUBDIRECTORY(tests)

TARGET_LINK_LIBRARIES(pstd; spdlog pthread)

SET_TARGET_PROPERTIES(pstd PROPERTIES LINKER_LANGUAGE CXX)
62 changes: 33 additions & 29 deletions src/pstd/pstd_string.cc
Original file line number Diff line number Diff line change
Expand Up @@ -574,41 +574,45 @@ bool ParseIpPortString(const std::string& ip_port, std::string& ip, int& port) {
return true;
}

// Trim charlist
std::string StringTrim(const std::string& ori, const std::string& charlist) {
// Trim charList
std::string StringTrim(const std::string& ori, const std::string& charList) {
if (ori.empty()) {
return ori;
}

size_t pos = 0;
int rpos = ori.size() - 1;
while (pos < ori.size()) {
bool meet = false;
for (char c : charlist) {
if (ori.at(pos) == c) {
meet = true;
break;
}
}
if (!meet) {
break;
}
++pos;
auto begin = ori.find_first_not_of(charList);
if (begin == std::string::npos) {
return "";
}
while (rpos >= 0) {
loveyacper marked this conversation as resolved.
Show resolved Hide resolved
bool meet = false;
for (char c : charlist) {
if (ori.at(rpos) == c) {
meet = true;
break;
}
}
if (!meet) {
break;
}
--rpos;

auto end = ori.find_last_not_of(charList);
return ori.substr(begin, end - begin + 1);
}

// Trim charList from left
std::string StringTrimLeft(const std::string& ori, const std::string& charList) {
if (ori.empty()) {
return ori;
}

auto begin = ori.find_first_not_of(charList);
if (begin == std::string::npos) {
return "";
}
return ori.substr(begin, ori.size() - begin);
}

// Trim charList from right
std::string StringTrimRight(const std::string& ori, const std::string& charList) {
if (ori.empty()) {
return ori;
}

auto end = ori.find_last_not_of(charList);
if (end == std::string::npos) {
return "";
}
return ori.substr(pos, rpos - pos + 1);
return ori.substr(0, end + 1);
}

bool StringHasSpaces(const std::string& str) {
Expand Down
4 changes: 3 additions & 1 deletion src/pstd/pstd_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ std::string& StringToUpper(std::string& ori);
std::string IpPortString(const std::string& ip, int port);
std::string ToRead(const std::string& str);
bool ParseIpPortString(const std::string& ip_port, std::string& ip, int& port);
std::string StringTrim(const std::string& ori, const std::string& charlist = " ");
std::string StringTrim(const std::string& ori, const std::string& charList = " ");
std::string StringTrimLeft(const std::string& ori, const std::string& charList = " ");
std::string StringTrimRight(const std::string& ori, const std::string& charList = " ");
std::string RandomHexChars(size_t len);
std::string RandomString(size_t len);
std::string RandomStringWithNumber(size_t len);
Expand Down
2 changes: 1 addition & 1 deletion src/pstd/pstd_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void InitRandom() {
gen.seed(rd());
}

int RandomInt(int max) { return RandomInt(0, max + 1); }
int RandomInt(int max) { return RandomInt(0, max); }

int RandomInt(int min, int max) {
std::uniform_int_distribution<> dist(min, max);
Expand Down
1 change: 1 addition & 0 deletions src/pstd/pstd_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#pragma once

#include <algorithm>
#include <chrono>
#include <random>

Expand Down
32 changes: 32 additions & 0 deletions src/pstd/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright (c) 2023-present, Qihoo, Inc. All rights reserved.
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.

cmake_minimum_required(VERSION 3.18)

include(GoogleTest)
set(CMAKE_CXX_STANDARD 20)

aux_source_directory(.. DIR_SRCS)

file(GLOB_RECURSE PSTD_TEST_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/*.cc")

foreach (pstd_test_source ${PSTD_TEST_SOURCE})
get_filename_component(pstd_test_filename ${pstd_test_source} NAME)
string(REPLACE ".cc" "" pstd_test_name ${pstd_test_filename})

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_executable(${pstd_test_name} ${pstd_test_source})
target_include_directories(${pstd_test_name}
PUBLIC ${PROJECT_SOURCE_DIR}/src
)

add_dependencies(${pstd_test_name} pstd gtest)
target_link_libraries(${pstd_test_name}
PUBLIC pstd
PUBLIC gtest
)
gtest_discover_tests(${pstd_test_name}
WORKING_DIRECTORY .)
endforeach ()
149 changes: 149 additions & 0 deletions src/pstd/tests/pstd_string_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright (c) 2015-present, Qihoo, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.

// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include <climits>

#include <gtest/gtest.h>
#include "pstd/pstd_string.h"

class StringTest : public ::testing::Test {};

TEST_F(StringTest, StringTrim) {
ASSERT_EQ(pstd::StringTrim(" computer "), "computer");
ASSERT_EQ(pstd::StringTrim(" comp uter "), "comp uter");
ASSERT_EQ(pstd::StringTrim(" \n computer \n ", "\n "), "computer");
ASSERT_EQ(pstd::StringTrim("\n", "\r\n "), "");
}

TEST_F(StringTest, StringTrimLeft) {
ASSERT_EQ(pstd::StringTrimLeft(" computer"), "computer");
ASSERT_EQ(pstd::StringTrimLeft(" computer "), "computer ");
ASSERT_EQ(pstd::StringTrimLeft(" comp uter "), "comp uter ");
ASSERT_EQ(pstd::StringTrimLeft(" comp uter"), "comp uter");
ASSERT_EQ(pstd::StringTrimLeft(" \n computer \n ", "\n "), "computer \n ");
ASSERT_EQ(pstd::StringTrimLeft("\n", "\r\n "), "");
}

TEST_F(StringTest, StringTrimRight) {
ASSERT_EQ(pstd::StringTrimRight("computer "), "computer");
ASSERT_EQ(pstd::StringTrimRight(" computer "), " computer");
ASSERT_EQ(pstd::StringTrimRight(" comp uter "), " comp uter");
ASSERT_EQ(pstd::StringTrimRight("comp uter "), "comp uter");
ASSERT_EQ(pstd::StringTrimRight(" \n computer \n ", "\n "), " \n computer");
ASSERT_EQ(pstd::StringTrimRight("\n", "\r\n "), "");
}

TEST_F(StringTest, ParseIpPort) {
std::string ip;
int port;
ASSERT_TRUE(pstd::ParseIpPortString("192.168.1.1:9221", ip, port));
ASSERT_EQ(ip, "192.168.1.1");
ASSERT_EQ(port, 9221);
}

TEST_F(StringTest, test_string2ll) {
char buf[32];
long long v;

/* May not start with +. */
strcpy(buf, "+1");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 0);

/* Leading space. */
strcpy(buf, " 1");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 0);

/* Trailing space. */
strcpy(buf, "1 ");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);

strcpy(buf, "-1");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, -1);

strcpy(buf, "0");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, 0);

strcpy(buf, "1");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, 1);

strcpy(buf, "99");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, 99);

strcpy(buf, "-99");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, -99);

strcpy(buf, "-9223372036854775808");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, LLONG_MIN);

strcpy(buf, "-9223372036854775809"); /* overflow */
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 0);

strcpy(buf, "9223372036854775807");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, LLONG_MAX);

strcpy(buf, "9223372036854775808"); /* overflow */
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 0);
}

TEST_F(StringTest, test_string2l) {
char buf[32];
long v;

/* May not start with +. */
strcpy(buf, "+1");
ASSERT_EQ(pstd::String2int(buf, &v), 0);

strcpy(buf, "-1");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, -1);

strcpy(buf, "0");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, 0);

strcpy(buf, "1");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, 1);

strcpy(buf, "99");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, 99);

strcpy(buf, "-99");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, -99);

#if LONG_MAX != LLONG_MAX
strcpy(buf, "-2147483648");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, LONG_MIN);

strcpy(buf, "-2147483649"); /* overflow */
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 0);

strcpy(buf, "2147483647");
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 1);
ASSERT_EQ(v, LONG_MAX);

strcpy(buf, "2147483648"); /* overflow */
ASSERT_EQ(pstd::String2int(buf, strlen(buf), &v), 0);
#endif
}

int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Loading
Loading