Skip to content

Commit

Permalink
test: add ftp::test::server class
Browse files Browse the repository at this point in the history
  • Loading branch information
deniskovalchuk committed Mar 26, 2024
1 parent b641e98 commit d8bbf88
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 58 deletions.
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ set(sources
reply.cpp
test_helpers.cpp
test_helpers.hpp
test_server.hpp
utils.cpp)

source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${sources})
Expand Down
69 changes: 11 additions & 58 deletions test/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <boost/process.hpp>
#include <filesystem>
#include <memory>
#include <ftp/client.hpp>
Expand All @@ -33,6 +32,7 @@
#include <ftp/stream/istream_adapter.hpp>
#include <ftp/stream/ostream_adapter.hpp>
#include "test_helpers.hpp"
#include "test_server.hpp"

namespace
{
Expand Down Expand Up @@ -96,48 +96,29 @@ class client : public testing::Test
protected:
static void SetUpTestSuite()
{
std::optional<std::string> server_path = get_test_server_path();

if (!server_path)
return;

boost::filesystem::path python = get_python_path();

if (python.empty())
return;

std::filesystem::create_directory(server_root_dir_);

/* Run test server. Usage: python server.py port root_directory */
boost::process::ipstream server_output;
server_process_
= boost::process::child(python, server_path.value(), "2121", server_root_dir_,
boost::process::std_out > boost::process::null,
boost::process::std_err > server_output);

while (server_process_.running())
try
{
std::string line;
std::getline(server_output, line);

if (line.find("starting FTP server") != std::string::npos)
break;
server_.start(server_root_dir_, 2121);
}
catch (const std::exception & ex)
{
GTEST_SKIP() << "Skip. Test FTP server is not running: " << ex.what();
}
}

static void TearDownTestSuite()
{
if (server_process_.running())
if (server_.running())
{
server_process_.terminate();
server_.stop();
}

std::filesystem::remove_all(server_root_dir_);
}

void SetUp() override
{
if (!server_process_.running())
if (!server_.running())
{
GTEST_SKIP() << "Skip. Test FTP server is not running.";
}
Expand All @@ -156,36 +137,8 @@ class client : public testing::Test
}

private:
static std::optional<std::string> get_test_server_path()
{
const char *path = std::getenv("LIBFTP_TEST_SERVER_PATH");

if (path)
{
return { path };
}
else
{
return std::nullopt;
}
}

static boost::filesystem::path get_python_path()
{
boost::filesystem::path path = boost::process::search_path("python3");

if (path.empty())
{
return boost::process::search_path("python");
}
else
{
return path;
}
}

inline static std::string server_root_dir_ = "server_root";
inline static boost::process::child server_process_;
inline static ftp::test::server server_;
};

TEST_F(client, open_connection)
Expand Down
90 changes: 90 additions & 0 deletions test/test_server.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* MIT License
*
* Copyright (c) 2024 Denis Kovalchuk
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#ifndef LIBFTP_TEST_SERVER_HPP
#define LIBFTP_TEST_SERVER_HPP

#include <string>
#include <cstdint>
#include <stdexcept>
#include <boost/process.hpp>

namespace ftp::test
{

class server
{
public:
void start(const std::string & root_directory, std::uint16_t port)
{
const char *server_path = std::getenv("LIBFTP_TEST_SERVER_PATH");
if (!server_path)
{
throw std::runtime_error("LIBFTP_TEST_SERVER_PATH is not set.");
}

boost::filesystem::path python_path = boost::process::search_path("python3");
if (python_path.empty())
{
python_path = boost::process::search_path("python");
if (python_path.empty())
{
throw std::runtime_error("Python is not found.");
}
}

std::filesystem::create_directory(root_directory);

/* Usage: python server.py port root_directory */
boost::process::ipstream output;
process_ = boost::process::child(python_path, server_path, std::to_string(port), root_directory,
boost::process::std_out > boost::process::null,
boost::process::std_err > output);

while (process_.running())
{
std::string line;
std::getline(output, line);

if (line.find("starting FTP server") != std::string::npos)
break;
}
}

[[nodiscard]] bool running()
{
return process_.running();
}

void stop()
{
process_.terminate();
}

private:
boost::process::child process_;
};

} // namespace ftp::test
#endif //LIBFTP_TEST_SERVER_HPP

0 comments on commit d8bbf88

Please sign in to comment.