boinc/tests/unit-tests/lib/test_str_util.cpp

401 lines
16 KiB
C++

#include "gtest/gtest.h"
#include "common_defs.h"
#include "str_util.h"
#include <string>
#include <ios>
namespace test_str_util {
// The fixture for testing class Foo.
class test_str_util : public ::testing::Test {
protected:
// You can remove any or all of the following functions if its body
// is empty.
test_str_util() {
// You can do set-up work for each test here.
}
virtual ~test_str_util() {
// You can do clean-up work that doesn't throw exceptions here.
}
// If the constructor and destructor are not enough for setting up
// and cleaning up each test, you can define the following methods:
virtual void SetUp() {
// Code here will be called immediately after the constructor (right
// before each test).
}
virtual void TearDown() {
// Code here will be called immediately after each test (right
// before the destructor).
}
// Objects declared here can be used by all tests in the test case for Foo.
#ifdef _WIN32
int setenv(const char* name, const char* value, int overwrite)
{
int errcode = 0;
if (!overwrite) {
size_t envsize = 0;
errcode = getenv_s(&envsize, NULL, 0, name);
if (errcode || envsize) return errcode;
}
return _putenv_s(name, value);
}
#endif
};
// Tests that Foo does Xyz.
TEST_F(test_str_util, ndays_to_string) {
char buf[128];
char *nilbuf {0};
EXPECT_TRUE(ndays_to_string(-1.0, 0, buf));
EXPECT_FALSE(ndays_to_string(0.0, -1, buf));
EXPECT_STREQ(buf, "");
EXPECT_TRUE(ndays_to_string(1.0, 0, nilbuf));
EXPECT_FALSE(ndays_to_string(0.0, 0, buf));
EXPECT_STREQ(buf, "0.00 sec ");
EXPECT_FALSE(ndays_to_string(5, -1, buf));
EXPECT_STREQ(buf, "5 days ");
EXPECT_FALSE(ndays_to_string(1.234567890, 0, buf));
EXPECT_STREQ(buf, "1 days 5 hr 37 min 46.67 sec ");
EXPECT_FALSE(ndays_to_string(12.34567890, 1, buf));
EXPECT_STREQ(buf, "12 days 8 hr 17.78 min ");
EXPECT_FALSE(ndays_to_string(123.4567890, 2, buf));
EXPECT_STREQ(buf, "123 days 10.96 hr ");
EXPECT_FALSE(ndays_to_string(1234.567890, 3, buf));
EXPECT_STREQ(buf, "3 yr 138.82 days ");
EXPECT_FALSE(ndays_to_string(12345.67890, 4, buf));
EXPECT_STREQ(buf, "33.801 yr ");
EXPECT_FALSE(ndays_to_string(12345.67890, 5, buf));
EXPECT_STREQ(buf, "");
EXPECT_FALSE(ndays_to_string(1234.56789012345, 0, buf));
EXPECT_STREQ(buf, "3 yr 138 days 13 hr 37 min 45.71 sec ");
}
TEST_F(test_str_util, secs_to_hmsf) {
char buf[128];
//char *nilbuf {0};
secs_to_hmsf(0.0, buf);
EXPECT_STREQ(buf, "0h00m00s00");
secs_to_hmsf(1.0, buf);
EXPECT_STREQ(buf, "0h00m01s00");
secs_to_hmsf(1.23456789, buf);
EXPECT_STREQ(buf, "0h00m01s23");
secs_to_hmsf(12345.6789, buf);
EXPECT_STREQ(buf, "3h25m45s67");
secs_to_hmsf(123456.789, buf);
EXPECT_STREQ(buf, "34h17m36s78");
}
TEST_F(test_str_util, nbytes_to_string) {
char buf[256];
nbytes_to_string(5.0, 0.0, buf, sizeof (buf));
EXPECT_STREQ(buf, "5 bytes");
nbytes_to_string(1024.0, 0.0, buf, sizeof (buf));
EXPECT_STREQ(buf, "1.00 KB");
nbytes_to_string(5.0*1024*1024, 0.0, buf, sizeof(buf));
EXPECT_STREQ(buf, "5.00 MB");
nbytes_to_string(15.0*1024*1024*1024, 0.0, buf, sizeof(buf));
EXPECT_STREQ(buf, "15.00 GB");
nbytes_to_string(50000000000000.0, 0.0, buf, sizeof (buf));
EXPECT_STREQ(buf, "45.47 TB");
nbytes_to_string(2.0, 48.0, buf, sizeof(buf));
EXPECT_STREQ(buf, "2/48 bytes");
nbytes_to_string(512.0, 1024.0, buf, sizeof (buf));
EXPECT_STREQ(buf, "0.50/1.00 KB");
nbytes_to_string(1024.0, 1.0 * 1024 * 1024, buf, sizeof (buf));
EXPECT_STREQ(buf, "0.00/1.00 MB");
nbytes_to_string(6.0*1024*1024*1024, 6.0*1024*1024*1024, buf, sizeof(buf));
EXPECT_STREQ(buf, "6.00/6.00 GB");
nbytes_to_string(24.0*1024*1024*1024*1024, 48.0*1024*1024*1024*1024, buf, sizeof(buf));
EXPECT_STREQ(buf, "24.00/48.00 TB");
}
TEST_F(test_str_util, parse_command_line) {;
char buf[256];
char* argv[100];
int ret;
char *nilbuf {0};
snprintf(buf, sizeof(buf), "one two three");
ret = parse_command_line(buf, argv);
EXPECT_EQ(ret, 3);
EXPECT_STREQ(argv[0], "one");
EXPECT_STREQ(argv[1], "two");
EXPECT_STREQ(argv[2], "three");
EXPECT_STREQ(argv[3], nilbuf);
EXPECT_STREQ(buf, "one");
snprintf(buf, sizeof(buf), "four \'five\' \"six\"");
ret = parse_command_line(buf, argv);
EXPECT_EQ(ret, 3);
EXPECT_STREQ(argv[0], "four");
EXPECT_STREQ(argv[1], "five");
EXPECT_STREQ(argv[2], "six");
EXPECT_STREQ(argv[3], nilbuf);
EXPECT_STREQ(buf, "four");
snprintf(buf, sizeof(buf), "seven \'eig ht\' \"ni ne\"");
ret = parse_command_line(buf, argv);
EXPECT_EQ(ret, 3);
EXPECT_STREQ(argv[0], "seven");
EXPECT_STREQ(argv[1], "eig ht");
EXPECT_STREQ(argv[2], "ni ne");
EXPECT_STREQ(argv[3], nilbuf);
EXPECT_STREQ(buf, "seven");
snprintf(buf, sizeof(buf), "tän \'elèv én\' \"tŵelv e\"");
ret = parse_command_line(buf, argv);
EXPECT_EQ(ret, 3);
EXPECT_STREQ(argv[0], "tän");
EXPECT_STREQ(argv[1], "elèv én");
EXPECT_STREQ(argv[2], "tŵelv e");
EXPECT_STREQ(argv[3], nilbuf);
EXPECT_STREQ(buf, "tän");
// function doesn't check syntax so this works too
snprintf(buf, sizeof(buf), "13\" \'\"4teen\'\" ");
ret = parse_command_line(buf, argv);
EXPECT_EQ(ret, 3);
EXPECT_STREQ(argv[0], "13\"");
EXPECT_STREQ(argv[1], "\"4teen");
EXPECT_STREQ(argv[2], " ");
EXPECT_STREQ(argv[3], nilbuf);
EXPECT_STREQ(buf, "13\"");
}
TEST_F(test_str_util, strip_whitespace) {
std::string tmp = " white space ";
strip_whitespace(tmp);
EXPECT_EQ(tmp, "white space");
tmp = "nospaces";
strip_whitespace(tmp);
EXPECT_EQ(tmp, "nospaces");
char buf[128] = " char space ";
strip_whitespace(buf);
EXPECT_STREQ(buf, "char space");
}
TEST_F(test_str_util, strip_quotes) {
std::string tmp = "\"\' white\' \"space\'\" ";
strip_quotes(tmp);
EXPECT_EQ(tmp, "white\' \"space");
tmp = "no\"space\'s";
strip_quotes(tmp);
EXPECT_EQ(tmp, "no\"space\'s");
tmp = "\"elèv\' én\"";
strip_quotes(tmp);
EXPECT_EQ(tmp, "elèv\' én");
char buf[128] = "\"\' char\' \"space\'\" ";
strip_quotes(buf);
EXPECT_STREQ(buf, "char\' \"space");
}
TEST_F(test_str_util, collapse_whitespace) {
std::string tmp = " white space ";
collapse_whitespace(tmp);
EXPECT_EQ(tmp, " white space ");
tmp = "nospaces";
collapse_whitespace(tmp);
EXPECT_EQ(tmp, "nospaces");
tmp = "inner spaces";
collapse_whitespace(tmp);
EXPECT_EQ(tmp, "inner spaces");
char buf[128] = " char spaces ";
collapse_whitespace(buf);
EXPECT_STREQ(buf, " char spaces ");
}
TEST_F(test_str_util, unescape_os_release) {
//a-f get unescaped, g-j not
char buf[128] = "a\\\\b\\$c\\\'d\\\"e\\`f\\\?g\\\th\\\bi\\12j";
unescape_os_release(buf);
EXPECT_STREQ(buf, "a\\b$c\'d\"e`f\\\?g\\\th\\\bi\\12j");
}
TEST_F(test_str_util, time_to_string) {
char* buf;
setenv("TZ", "UTC", 1);
tzset();
buf = time_to_string(false);
EXPECT_STREQ(buf, "---");
buf = time_to_string(1.0);
EXPECT_STREQ(buf, "01-Jan-1970 00:00:01");
buf = time_to_string(12345678910.0);
EXPECT_STREQ(buf, "21-Mar-2361 19:15:10");
}
TEST_F(test_str_util, precision_time_to_string) {
char* buf;
setenv("TZ", "UTC", 1);
tzset();
buf = precision_time_to_string(false);
EXPECT_STREQ(buf, "1970-01-01 00:00:00.0000");
buf = precision_time_to_string(1.0);
EXPECT_STREQ(buf, "1970-01-01 00:00:01.0000");
buf = precision_time_to_string(1555876749.1234);
EXPECT_STREQ(buf, "2019-04-21 19:59:09.1233");
buf = precision_time_to_string(12345678910.10000);
EXPECT_STREQ(buf, "2361-03-21 19:15:10.-2147483648");
}
TEST_F(test_str_util, timediff_format) {
std::string tmp;
tmp = timediff_format(false);
EXPECT_EQ(tmp, "00:00:00");
tmp = timediff_format(59.0);
EXPECT_EQ(tmp, "00:00:59");
tmp = timediff_format(3599.0);
EXPECT_EQ(tmp, "00:59:59");
tmp = timediff_format(3600.0);
EXPECT_EQ(tmp, "01:00:00");
tmp = timediff_format(123456.7);
EXPECT_EQ(tmp, "1 days 10:17:36");
}
TEST_F(test_str_util, mysql_timestamp) {
char buf[128];
//char *nilbuf {0};
mysql_timestamp(0.0, buf);
EXPECT_STREQ(buf, "19700101000000");
mysql_timestamp(1.0, buf);
EXPECT_STREQ(buf, "19700101000001");
mysql_timestamp(1555876749.1234, buf);
EXPECT_STREQ(buf, "20190421195909");
mysql_timestamp(12345678910.0, buf);
EXPECT_STREQ(buf, "23610321191510");
}
TEST_F(test_str_util, string_substitute) {
std::string tmp = "The quick brown fox jumps over the lazy dog";
char buf[256];
int ret = string_substitute(tmp.c_str(), buf, sizeof(buf), "brown", "red");
EXPECT_EQ(ret, 0);
EXPECT_STREQ(buf, "The quick red fox jumps over the lazy dog");
ret = string_substitute(tmp.c_str(), buf, 13, "brown", "red");
EXPECT_EQ(ret, ERR_BUFFER_OVERFLOW);
ret = string_substitute(tmp.c_str(), buf, 16, "brown", "red");
EXPECT_EQ(ret, ERR_BUFFER_OVERFLOW);
tmp = "Falsches Üben von Xylophonmusik quält jeden größeren Zwerg";
ret = string_substitute(tmp.c_str(), buf, sizeof(buf), "quält", "ärgert");
EXPECT_EQ(ret, 0);
EXPECT_STREQ(buf, "Falsches Üben von Xylophonmusik ärgert jeden größeren Zwerg");
}
TEST_F(test_str_util, strip_translation) {
char buf[256] = "_(\"The quick brown fox jumps over the lazy dog\")";
strip_translation(buf);
EXPECT_STREQ(buf, "The quick brown fox jumps over the lazy dog");
snprintf(buf, sizeof(buf), "The _(\"quick brown\") fox jumps over the _(\"lazy\") dog");
strip_translation(buf);
EXPECT_STREQ(buf, "The quick brown fox jumps over the lazy dog");
snprintf(buf, sizeof(buf), "The _\"quick brown\" ) fox jumps over the (_\"lazy\") dog");
strip_translation(buf);
EXPECT_STREQ(buf, "The _\"quick brown\" ) fox jumps over the (_\"lazy dog");
}
TEST_F(test_str_util, lf_terminate) {
char *buf;
buf = (char*)malloc(256);
strcpy(buf, "no\nlf ending");
buf = lf_terminate(buf);
EXPECT_STREQ(buf, "no\nlf ending\n");
strcpy(buf, "lf\n ending\n");
buf = lf_terminate(buf);
EXPECT_STREQ(buf, "lf\n ending\n");
}
TEST_F(test_str_util, parse_serialnum) {
char buf[256] = "[BOINC|1.2.3]", buf1[256], buf2[256], buf3[256];
//sprintf(tmp, "[BOINC|1.2.3]");
parse_serialnum(buf, buf1, buf2, buf3);
EXPECT_STREQ(buf, "[BOINC|1.2.3]");
EXPECT_STREQ(buf1, "[BOINC|1.2.3]");
EXPECT_STREQ(buf2, "");
EXPECT_STREQ(buf3, "");
strncpy(buf, "[BOINC|1.2.3][vbox|4.5.6abc]", sizeof(buf));
parse_serialnum(buf, buf1, buf2, buf3);
EXPECT_STREQ(buf1, "[BOINC|1.2.3]");
EXPECT_STREQ(buf2, "[vbox|4.5.6abc]");
EXPECT_STREQ(buf3, "");
strncpy(buf, "[BOINC|1.2.3][INTEL|Intel(R) HD Graphics|1|2406MB||201]", sizeof(buf));
parse_serialnum(buf, buf1, buf2, buf3);
EXPECT_STREQ(buf1, "[BOINC|1.2.3]");
EXPECT_STREQ(buf2, "");
EXPECT_STREQ(buf3, "[INTEL|Intel(R) HD Graphics|1|2406MB||201]");
strncpy(buf, "[vbox|4.5.6abc][INTEL|Intel(R) HD Graphics|1|2406MB||201][BOINC|1.2.3]", sizeof(buf));
parse_serialnum(buf, buf1, buf2, buf3);
EXPECT_STREQ(buf1, "[BOINC|1.2.3]");
EXPECT_STREQ(buf2, "[vbox|4.5.6abc]");
EXPECT_STREQ(buf3, "[INTEL|Intel(R) HD Graphics|1|2406MB||201]");
strncpy(buf, "[BOINC|1.2.3][INTEL|Intel(R) HD Graphics|1|2406MB||201][vbox|4.5.6abc]", sizeof(buf));
parse_serialnum(buf, buf1, buf2, buf3);
EXPECT_STREQ(buf1, "[BOINC|1.2.3]");
EXPECT_STREQ(buf2, "[vbox|4.5.6abc]");
EXPECT_STREQ(buf3, "[INTEL|Intel(R) HD Graphics|1|2406MB||201]");
strncpy(buf, "[BOINC|1.2.3][vbox|4.5.6abc][INTEL|Intel(R) HD Graphics|1|2406MB||201]", sizeof(buf));
parse_serialnum(buf, buf1, buf2, buf3);
EXPECT_STREQ(buf1, "[BOINC|1.2.3]");
EXPECT_STREQ(buf2, "[vbox|4.5.6abc]");
EXPECT_STREQ(buf3, "[INTEL|Intel(R) HD Graphics|1|2406MB||201]");
strncpy(buf, "[BOINC|7.6.22][CAL|ATI Radeon HD 5800/5900 series (Cypress/Hemlock)|2|1024MB|1.4.1848|102][vbox|5.1.26]", sizeof(buf));
parse_serialnum(buf, buf1, buf2, buf3);
EXPECT_STREQ(buf1, "[BOINC|7.6.22]");
EXPECT_STREQ(buf2, "[vbox|5.1.26]");
EXPECT_STREQ(buf3, "[CAL|ATI Radeon HD 5800/5900 series (Cypress/Hemlock)|2|1024MB|1.4.1848|102]");
strncpy(buf, "[BOINC|7.6.22[CAL|ATI Radeon HD 5800/5900 series (Cypress/Hemlock)|2|1024MB|1.4.1848|102][vbox|5.1.26]", sizeof(buf));
parse_serialnum(buf, buf1, buf2, buf3);
EXPECT_STREQ(buf1, "[BOINC|7.6.22[CAL|ATI Radeon HD 5800/5900 series (Cypress/Hemlock)|2|1024MB|1.4.1848|102]");
EXPECT_STREQ(buf2, "[vbox|5.1.26]");
EXPECT_STREQ(buf3, "");
strncpy(buf, "[BOINC|7.6.22][CAL|ATI Radeon HD 5800/5900 series [Cypress/Hemlock]|2|1024MB|1.4.1848|102][vbox|5.1.26]", sizeof(buf));
parse_serialnum(buf, buf1, buf2, buf3);
EXPECT_STREQ(buf1, "[BOINC|7.6.22]");
EXPECT_STREQ(buf2, "");
EXPECT_STREQ(buf3, "[CAL|ATI Radeon HD 5800/5900 series [Cypress/Hemlock]");
strncpy(buf, "[BOINC|7.6.22][CAL|ATI Radeon HD 5800/5900 series (Cypress/Hemlock)|2|1024MB|1.4.1848|102][extra|7.8.9][vbox|5.1.26]", sizeof(buf));
parse_serialnum(buf, buf1, buf2, buf3);
EXPECT_STREQ(buf1, "[BOINC|7.6.22]");
EXPECT_STREQ(buf2, "[vbox|5.1.26]");
//TODO: fix parse_serialnum so this doesn't happen:
EXPECT_STREQ(buf3, "[CAL|ATI Radeon HD 5800/5900 series (Cypress/Hemlock)|2|1024MB|1.4.1848|102][extra|7.8.9]");
}
TEST_F(test_str_util, is_valid_filename) {
//char tmp = "filename.txt";
bool ret = is_valid_filename("filename.txt");
EXPECT_TRUE(ret);
ret = is_valid_filename("../filename.txt");
EXPECT_FALSE(ret);
ret = is_valid_filename("../file\nname.txt");
EXPECT_FALSE(ret);
ret = is_valid_filename("/filename.txt");
EXPECT_FALSE(ret);
}
TEST_F(test_str_util, path_to_filename) {
std::string fname = "";
EXPECT_EQ(path_to_filename("/home/blah", fname), 0);
EXPECT_EQ(fname, "blah");
EXPECT_EQ(path_to_filename("hellokeith", fname), 0);
EXPECT_EQ(fname, "hellokeith");
fname = "";
EXPECT_EQ(path_to_filename("/home/blah/", fname), -2);
EXPECT_EQ(fname, "");
EXPECT_EQ(path_to_filename("", fname), -1);
EXPECT_EQ(fname, "");
char *buf;
EXPECT_EQ(path_to_filename("/home/blah", buf), 0);
EXPECT_STREQ(buf, "blah");
EXPECT_EQ(path_to_filename("hellokeith", buf), 0);
EXPECT_STREQ(buf, "hellokeith");
strcpy(buf, "");
EXPECT_EQ(path_to_filename("/home/blah/", buf), -2);
EXPECT_STREQ(buf, "");
EXPECT_EQ(path_to_filename("", buf), -1);
EXPECT_STREQ(buf, "");
}
} // namespace