From 00367d9f7ad702abb856b23f360cc28a0edd7cb8 Mon Sep 17 00:00:00 2001 From: Christian Beer Date: Sun, 26 Dec 2021 22:15:40 +0100 Subject: [PATCH 1/8] [Unit tests] Add testcase to check base64 padding --- tests/unit-tests/lib/test_base64.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit-tests/lib/test_base64.cpp b/tests/unit-tests/lib/test_base64.cpp index 8bd84960d13..1ef02cae793 100644 --- a/tests/unit-tests/lib/test_base64.cpp +++ b/tests/unit-tests/lib/test_base64.cpp @@ -59,6 +59,7 @@ namespace test_base64 { EXPECT_EQ(r_base64_encode("Bòíncüñ"), "QsOyw61uY8O8w7E="); EXPECT_EQ(r_base64_encode("äöüß"), "w6TDtsO8w58="); EXPECT_EQ(r_base64_encode("new\nline"), "bmV3CmxpbmU="); + EXPECT_EQ(r_base64_encode("BoincServerTestMessage"), "Qm9pbmNTZXJ2ZXJUZXN0TWVzc2FnZQ=="); } TEST_F(test_base64, r_base64_decode) { @@ -67,6 +68,7 @@ namespace test_base64 { EXPECT_EQ(r_base64_decode("QsOyw61uY8O8w7E="), "Bòíncüñ"); EXPECT_EQ(r_base64_decode("w6TDtsO8w58="), "äöüß"); EXPECT_EQ(r_base64_decode("bmV3CmxpbmU="), "new\nline"); + EXPECT_EQ(r_base64_decode("Qm9pbmNTZXJ2ZXJUZXN0TWVzc2FnZQ=="), "BoincServerTestMessage"); } From 8e746e5720acdc69b6ae58af998360d4bb36d097 Mon Sep 17 00:00:00 2001 From: Christian Beer Date: Sun, 26 Dec 2021 22:31:36 +0100 Subject: [PATCH 2/8] [unit tests] enhance md5_file test with gzipped file --- tests/unit-tests/lib/test_md5_file.cpp | 12 ++++++++++-- tests/unit-tests/lib/test_md5_file.tar.gz | Bin 0 -> 560 bytes 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 tests/unit-tests/lib/test_md5_file.tar.gz diff --git a/tests/unit-tests/lib/test_md5_file.cpp b/tests/unit-tests/lib/test_md5_file.cpp index 030808aaab9..9dc66519563 100644 --- a/tests/unit-tests/lib/test_md5_file.cpp +++ b/tests/unit-tests/lib/test_md5_file.cpp @@ -75,8 +75,16 @@ namespace test_md5_file { EXPECT_EQ(result, 0); EXPECT_STREQ(output, "3b13c74a05696e71f9aeb4e6f10cbae8"); EXPECT_EQ(bytes, 737); +#ifdef _WIN32 + const string md5_gzfile_path = "../../../../tests/unit-tests/lib/test_md5_file.tar.gz"; +#else + const string md5_gzfile_path = "../unit-tests/lib/test_md5_file.tar.gz"; +#endif + result = md5_file(md5_gzfile_path.c_str(), output, bytes, true); + EXPECT_EQ(result, 0); + // Our md5 implementation is skipping the gzip header so the output might be different from other tools + EXPECT_STREQ(output, "29c539de433805ab07a3267e3c44dd69"); + EXPECT_EQ(bytes, 560); } } // namespace - - diff --git a/tests/unit-tests/lib/test_md5_file.tar.gz b/tests/unit-tests/lib/test_md5_file.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..2c43446f0bf947c2f84a30bfccaa8161cb97eb5d GIT binary patch literal 560 zcmV-00?+*)iwFQr+sI)61MO5@Yui8&%(H&QJ|&CZiEh4Bw1{ z*Rex59EA{$!pR^UhZ9N!;bb@-T|w{%w0wicSf)uzUTJPDXYxCBKgyrHz}NVnAg#Co zH+!I1Gi^bYaJPz=Q{Stst>5+4GQ7UPI?XNf>^4&zY?UB5fKdNSG*~V$VpU%#qfh00ud&$S+JvD7o)ko|g|GE*?GNmN3of|eAH`=A?K} Date: Sun, 26 Dec 2021 22:43:32 +0100 Subject: [PATCH 3/8] [unit tests] add simple test for mem_usage.cpp --- tests/unit-tests/lib/test_mem_usage.cpp | 67 +++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 tests/unit-tests/lib/test_mem_usage.cpp diff --git a/tests/unit-tests/lib/test_mem_usage.cpp b/tests/unit-tests/lib/test_mem_usage.cpp new file mode 100644 index 00000000000..0021b5d6144 --- /dev/null +++ b/tests/unit-tests/lib/test_mem_usage.cpp @@ -0,0 +1,67 @@ +// This file is part of BOINC. +// http://boinc.berkeley.edu +// Copyright (C) 2021 University of California +// +// BOINC is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// BOINC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with BOINC. If not, see . + +#include "gtest/gtest.h" +#include "mem_usage.h" + +using namespace std; + +namespace test_mem_usage { + + // The fixture for testing class Foo. + + class test_mem_usage : public ::testing::Test { + protected: + // You can remove any or all of the following functions if its body + // is empty. + + test_mem_usage() { + // You can do set-up work for each test here. + } + + virtual ~test_mem_usage() { + // 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. + }; + + // Test shmem functions for Windows/Unix/Linux/Mac V5 applications + TEST_F(test_mem_usage, mem_usage) { + double vm_usage; + double resident_set; + + int result = mem_usage(vm_usage, resident_set); + EXPECT_EQ(result, 0); + EXPECT_GT(vm_usage, 1024); //assumes at least 1kb of memory usage + EXPECT_GT(resident_set, 1024); //assumes at least 1kb of memory usage + } + +} // namespace From 337c017bb32ae6c7658062541406a79fd73b13b5 Mon Sep 17 00:00:00 2001 From: Christian Beer Date: Sun, 26 Dec 2021 23:08:42 +0100 Subject: [PATCH 4/8] [unit tests] add missing tests for url.cpp --- tests/unit-tests/lib/test_url.cpp | 76 +++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/tests/unit-tests/lib/test_url.cpp b/tests/unit-tests/lib/test_url.cpp index 4e51a0b72e8..15143eed164 100644 --- a/tests/unit-tests/lib/test_url.cpp +++ b/tests/unit-tests/lib/test_url.cpp @@ -169,30 +169,90 @@ namespace test_url { EXPECT_STREQ(url.c_str(), "http://bad.example.com/"); } + TEST_F(test_url, is_https_transition) { + char url1[1024]; + char url2[1024]; + + //Check for correct transition + strncpy(url1, "http://www.example.com/", sizeof (url1)); + strncpy(url2, "https://www.example.com/", sizeof (url2)); + EXPECT_EQ(is_https_transition(url1, url2), true); + //Check for wrong transition + EXPECT_EQ(is_https_transition(url2, url1), false); + + //Check for wrong transition + strncpy(url1, "https://www.example.com/", sizeof (url1)); + strncpy(url2, "https://www.example.com/", sizeof (url2)); + EXPECT_EQ(is_https_transition(url1, url2), false); + + //Check for wrong domain name + strncpy(url1, "http://www.example.com/", sizeof (url1)); + strncpy(url2, "https://www.newname.org/", sizeof (url2)); + EXPECT_EQ(is_https_transition(url1, url2), false); + + //Check for wrong domain name + strncpy(url1, "http://www.example.com/", sizeof (url1)); + strncpy(url2, "http://www.newname.org/", sizeof (url2)); + EXPECT_EQ(is_https_transition(url1, url2), false); + + //Check for wrong domain name + strncpy(url1, "https://www.example.com/", sizeof (url1)); + strncpy(url2, "https://www.newname.org/", sizeof (url2)); + EXPECT_EQ(is_https_transition(url1, url2), false); + } + + TEST_F(test_url, urls_match) { + char url1[1024]; + char url2[1024]; + + //Check identical urls except protocol + strncpy(url1, "http://www.example.com/", sizeof (url1)); + strncpy(url2, "https://www.example.com/", sizeof (url2)); + EXPECT_EQ(urls_match(url1, url2), true); + EXPECT_EQ(urls_match(url2, url1), true); + //Check if protocol is really ignored + strncpy(url1, "socks://www.example.com/", sizeof (url1)); + strncpy(url2, "shoes://www.example.com/", sizeof (url2)); + EXPECT_EQ(urls_match(url1, url2), true); + EXPECT_EQ(urls_match(url2, url1), true); + + //Check for wrong input + strncpy(url1, "www.example.com/", sizeof (url1)); + strncpy(url2, "www.example.com//", sizeof (url2)); + EXPECT_EQ(urls_match(url1, url2), false); + EXPECT_EQ(urls_match(url2, url1), false); + + //Check for wrong domain name + strncpy(url1, "http://www.example.com/", sizeof (url1)); + strncpy(url2, "https://www.newname.org/", sizeof (url2)); + EXPECT_EQ(urls_match(url1, url2), false); + EXPECT_EQ(urls_match(url2, url1), false); + } + TEST_F(test_url, valid_master_url) { char url[1024]; - - //Check for a good unsecure url. + + //Check for a good unsecure url. strncpy(url, "http://www.example.com/", sizeof (url)); EXPECT_EQ(valid_master_url(url), true); - + //Check for a good secure url strncpy(url, "https://www.example.com/", sizeof (url)); EXPECT_EQ(valid_master_url(url), true); - + //Check for no http or https. strncpy(url, "hxxp://www.example.com/", sizeof (url)); EXPECT_EQ(valid_master_url(url), false); - + //Check if missing final slash. strncpy(url, "http://www.example.com", sizeof (url)); EXPECT_EQ(valid_master_url(url), false); - + //Check if it has no . in the name strncpy(url, "http://example/", sizeof (url)); EXPECT_EQ(valid_master_url(url), false); } - + TEST_F(test_url, escape_project_url) { char buf[1024]; char url[1024]; @@ -201,7 +261,7 @@ namespace test_url { strncpy(url, "https://secure.example.com", sizeof (url)); escape_project_url(url, buf); EXPECT_STREQ(buf, "secure.example.com"); - + //Testing url with bad character at the end removed. strncpy(url, "https://secure.example.com/Dollar$", sizeof (url)); escape_project_url(url, buf); From e1f81f75262763daf786cd8be381ea8aba8ba016 Mon Sep 17 00:00:00 2001 From: Christian Beer Date: Mon, 27 Dec 2021 00:31:50 +0100 Subject: [PATCH 5/8] [unit tests] Add test for project_init.cpp This also checks basic file reading and writing. --- tests/unit-tests/lib/test_project_init.cpp | 128 +++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 tests/unit-tests/lib/test_project_init.cpp diff --git a/tests/unit-tests/lib/test_project_init.cpp b/tests/unit-tests/lib/test_project_init.cpp new file mode 100644 index 00000000000..8a6d7586413 --- /dev/null +++ b/tests/unit-tests/lib/test_project_init.cpp @@ -0,0 +1,128 @@ +// This file is part of BOINC. +// http://boinc.berkeley.edu +// Copyright (C) 2020 University of California +// +// BOINC is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// BOINC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with BOINC. If not, see . + +#include +#include +#include "gtest/gtest.h" +#include "project_init.h" + +using namespace std; + +namespace test_project_init { + + // The fixture for testing class Foo. + + class test_project_init : public ::testing::Test { + protected: + PROJECT_INIT pi; + std::string emptyFile = R"xxx( + + + + 0 + +)xxx"; + std::string exampleFile1 = R"xxx( + http://www.example.com + Example Project + 1234567890abcdefghijklmnopqrstuvwxyz + 0 + +)xxx"; + std::string exampleFile2 = R"xxx( + https://secure.example.com + Secure Example Project + zyxwvutsrqponmlkjihgfedcba0987654321 + 1 + +)xxx"; + // You can remove any or all of the following functions if its body + // is empty. + + test_project_init() { + // You can do set-up work for each test here. + + } + + virtual ~test_project_init() { + // 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. + }; + + TEST_F(test_project_init, init) { + int result = pi.init(); + EXPECT_EQ(result, 0); + + std::ofstream ofs ("project_init.xml", std::ofstream::out); + ofs << exampleFile2; + ofs.close(); + result = pi.init(); + EXPECT_EQ(result, 0); + EXPECT_STREQ(pi.url, "https://secure.example.com/"); + ASSERT_STREQ(pi.name, "Secure Example Project"); + ASSERT_STREQ(pi.account_key, "zyxwvutsrqponmlkjihgfedcba0987654321"); + ASSERT_EQ(pi.embedded, true); + + pi.remove(); + pi.init(); + } + + TEST_F(test_project_init, write) { + int result = pi.write(); + EXPECT_EQ(result, 0); + std::ifstream t("project_init.xml"); + std::string genfile((std::istreambuf_iterator(t)), std::istreambuf_iterator()); + ASSERT_EQ(emptyFile, genfile); + + strncpy(pi.url, "http://www.example.com", sizeof (pi.url)); + strncpy(pi.name, "Example Project", sizeof (pi.name)); + strncpy(pi.account_key, "1234567890abcdefghijklmnopqrstuvwxyz", sizeof (pi.account_key)); + result = pi.write(); + EXPECT_EQ(result, 0); + std::ifstream t2("project_init.xml"); + std::string genfile2((std::istreambuf_iterator(t2)), std::istreambuf_iterator()); + ASSERT_EQ(exampleFile1, genfile2); + } + + TEST_F(test_project_init, remove) { + int result = pi.remove(); + EXPECT_EQ(result, 0); + std::ifstream t("project_init.xml"); + ASSERT_EQ(t.is_open(), false); + result = pi.remove(); + EXPECT_EQ(result, 0); + } + + + + +} // namespace From 86429c69b8477af6bf354a30ecdb191f289a2cf7 Mon Sep 17 00:00:00 2001 From: Christian Beer Date: Mon, 27 Dec 2021 10:20:14 +0100 Subject: [PATCH 6/8] [CI] exclude gzipped files from source code check --- ci_tools/source_code_check.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ci_tools/source_code_check.py b/ci_tools/source_code_check.py index 4a1c9e53527..fa58288b41f 100644 --- a/ci_tools/source_code_check.py +++ b/ci_tools/source_code_check.py @@ -81,6 +81,7 @@ def check(directory, bytes_to_check, exclude_dirs, exclude_extensions, exclude_f ".dll", ".exe", ".gif", + ".gz", ".icns", ".ico", ".jar", From ed5175329c73959578f2e379728f8f2b3876c6ff Mon Sep 17 00:00:00 2001 From: Christian Beer Date: Mon, 27 Dec 2021 10:30:36 +0100 Subject: [PATCH 7/8] [unit tests] add tests for mem_usage.cpp and project_init.cpp to Windows Rearranged the lines alphabetically to better compare it with the source files. --- win_build/unittests_vs2019.vcxproj | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/win_build/unittests_vs2019.vcxproj b/win_build/unittests_vs2019.vcxproj index 3101424f224..b3c73e5a005 100644 --- a/win_build/unittests_vs2019.vcxproj +++ b/win_build/unittests_vs2019.vcxproj @@ -156,13 +156,15 @@ + + + + + - - - From 82755318d15c8c2a1fed9809e564ec63030a992f Mon Sep 17 00:00:00 2001 From: Christian Beer Date: Mon, 27 Dec 2021 10:53:56 +0100 Subject: [PATCH 8/8] [unit tests] make tests more self contained in test_project_init Also uses EXPECT_instead of ASSERT_ because with ASSERT_ the test immediately stops not executing the remaining tests of a suite. It's better to execute all tests and get a better picture what is failing. --- tests/unit-tests/lib/test_project_init.cpp | 27 ++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/tests/unit-tests/lib/test_project_init.cpp b/tests/unit-tests/lib/test_project_init.cpp index 8a6d7586413..64f75c8ca5f 100644 --- a/tests/unit-tests/lib/test_project_init.cpp +++ b/tests/unit-tests/lib/test_project_init.cpp @@ -28,7 +28,6 @@ namespace test_project_init { class test_project_init : public ::testing::Test { protected: - PROJECT_INIT pi; std::string emptyFile = R"xxx( @@ -79,8 +78,13 @@ namespace test_project_init { }; TEST_F(test_project_init, init) { + PROJECT_INIT pi; int result = pi.init(); EXPECT_EQ(result, 0); + EXPECT_STREQ(pi.url, ""); + EXPECT_STREQ(pi.name, ""); + EXPECT_STREQ(pi.account_key, ""); + EXPECT_EQ(pi.embedded, false); std::ofstream ofs ("project_init.xml", std::ofstream::out); ofs << exampleFile2; @@ -88,20 +92,21 @@ namespace test_project_init { result = pi.init(); EXPECT_EQ(result, 0); EXPECT_STREQ(pi.url, "https://secure.example.com/"); - ASSERT_STREQ(pi.name, "Secure Example Project"); - ASSERT_STREQ(pi.account_key, "zyxwvutsrqponmlkjihgfedcba0987654321"); - ASSERT_EQ(pi.embedded, true); + EXPECT_STREQ(pi.name, "Secure Example Project"); + EXPECT_STREQ(pi.account_key, "zyxwvutsrqponmlkjihgfedcba0987654321"); + EXPECT_EQ(pi.embedded, true); - pi.remove(); - pi.init(); + std::remove("project_init.xml"); // delete file } TEST_F(test_project_init, write) { + PROJECT_INIT pi; + pi.init(); int result = pi.write(); EXPECT_EQ(result, 0); std::ifstream t("project_init.xml"); std::string genfile((std::istreambuf_iterator(t)), std::istreambuf_iterator()); - ASSERT_EQ(emptyFile, genfile); + EXPECT_EQ(emptyFile, genfile); strncpy(pi.url, "http://www.example.com", sizeof (pi.url)); strncpy(pi.name, "Example Project", sizeof (pi.name)); @@ -110,14 +115,18 @@ namespace test_project_init { EXPECT_EQ(result, 0); std::ifstream t2("project_init.xml"); std::string genfile2((std::istreambuf_iterator(t2)), std::istreambuf_iterator()); - ASSERT_EQ(exampleFile1, genfile2); + EXPECT_EQ(exampleFile1, genfile2); + std::remove("project_init.xml"); // delete file } TEST_F(test_project_init, remove) { + PROJECT_INIT pi; + pi.init(); + pi.write(); int result = pi.remove(); EXPECT_EQ(result, 0); std::ifstream t("project_init.xml"); - ASSERT_EQ(t.is_open(), false); + EXPECT_EQ(t.is_open(), false); result = pi.remove(); EXPECT_EQ(result, 0); }