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

[WIP] enhance unit testing #4597

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions ci_tools/source_code_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def check(directory, bytes_to_check, exclude_dirs, exclude_extensions, exclude_f
".dll",
".exe",
".gif",
".gz",
".icns",
".ico",
".jar",
Expand Down
2 changes: 2 additions & 0 deletions tests/unit-tests/lib/test_base64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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");
}


Expand Down
12 changes: 10 additions & 2 deletions tests/unit-tests/lib/test_md5_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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


Binary file added tests/unit-tests/lib/test_md5_file.tar.gz
Binary file not shown.
67 changes: 67 additions & 0 deletions tests/unit-tests/lib/test_mem_usage.cpp
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

#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
137 changes: 137 additions & 0 deletions tests/unit-tests/lib/test_project_init.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// 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 <http://www.gnu.org/licenses/>.

#include <iostream>
#include <fstream>
#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:
std::string emptyFile = R"xxx(<project_init>
<url></url>
<name></name>
<account_key></account_key>
<embedded>0</embedded>
</project_init>
)xxx";
std::string exampleFile1 = R"xxx(<project_init>
<url>http://www.example.com</url>
<name>Example Project</name>
<account_key>1234567890abcdefghijklmnopqrstuvwxyz</account_key>
<embedded>0</embedded>
</project_init>
)xxx";
std::string exampleFile2 = R"xxx(<project_init>
<url>https://secure.example.com</url>
<name>Secure Example Project</name>
<account_key>zyxwvutsrqponmlkjihgfedcba0987654321</account_key>
<embedded>1</embedded>
</project_init>
)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) {
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;
ofs.close();
result = pi.init();
EXPECT_EQ(result, 0);
EXPECT_STREQ(pi.url, "https://secure.example.com/");
EXPECT_STREQ(pi.name, "Secure Example Project");
EXPECT_STREQ(pi.account_key, "zyxwvutsrqponmlkjihgfedcba0987654321");
EXPECT_EQ(pi.embedded, true);

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<char>(t)), std::istreambuf_iterator<char>());
EXPECT_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<char>(t2)), std::istreambuf_iterator<char>());
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");
EXPECT_EQ(t.is_open(), false);
result = pi.remove();
EXPECT_EQ(result, 0);
}




} // namespace
76 changes: 68 additions & 8 deletions tests/unit-tests/lib/test_url.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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);
Expand Down
8 changes: 5 additions & 3 deletions win_build/unittests_vs2019.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,15 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\tests\unit-tests\lib\test_base64.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_md5_file.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_mem_usage.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_parse.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_project_init.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_shmem.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_str_util.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_url.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_base64.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_util.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_md5_file.cpp" />
<ClCompile Include="..\tests\unit-tests\lib\test_shmem.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="libboinc_vs2019.vcxproj">
Expand Down