Merge pull request #80 from PatriosTheGreat/main

[cdc_rsync] [cdc_rsync_server] Add build ID
This commit is contained in:
Levon Ter-Grigoryan
2023-02-01 09:02:53 +01:00
committed by GitHub
10 changed files with 100 additions and 20 deletions

View File

@@ -159,6 +159,7 @@
<ClCompile Include="$(MSBuildThisFileDirectory)metrics\metrics.cc" /> <ClCompile Include="$(MSBuildThisFileDirectory)metrics\metrics.cc" />
<ClInclude Include="$(MSBuildThisFileDirectory)cdc_stream\stop_service_command.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)cdc_stream\stop_service_command.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)common\ansi_filter.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)common\ansi_filter.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)common\build_version.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)common\port_range_parser.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)common\port_range_parser.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)fastcdc\fastcdc.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)fastcdc\fastcdc.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)manifest\pending_assets_queue.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)manifest\pending_assets_queue.h" />

View File

@@ -131,6 +131,7 @@ cc_library(
hdrs = ["params.h"], hdrs = ["params.h"],
deps = [ deps = [
":cdc_rsync_client", ":cdc_rsync_client",
"//common:build_version",
"//common:port_range_parser", "//common:port_range_parser",
"@com_github_zstd//:zstd", "@com_github_zstd//:zstd",
"@com_google_absl//absl/status", "@com_google_absl//absl/status",

View File

@@ -19,6 +19,7 @@
#include "absl/status/status.h" #include "absl/status/status.h"
#include "absl/strings/str_format.h" #include "absl/strings/str_format.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include "common/build_version.h"
#include "common/path.h" #include "common/path.h"
#include "common/port_range_parser.h" #include "common/port_range_parser.h"
#include "common/remote_util.h" #include "common/remote_util.h"
@@ -38,8 +39,7 @@ void PrintError(const absl::FormatSpec<Args...>& format, Args... args) {
enum class OptionResult { kConsumedKey, kConsumedKeyValue, kError }; enum class OptionResult { kConsumedKey, kConsumedKeyValue, kError };
const char kHelpText[] = const char kHelpText[] =
R"(Synchronize files and directories R"(
Matching files are skipped based on file size and modified time. For partially Matching files are skipped based on file size and modified time. For partially
matching files only the differences are transferred. The destination directory matching files only the differences are transferred. The destination directory
can be the same Windows machine or a remote Windows or Linux device. can be the same Windows machine or a remote Windows or Linux device.
@@ -323,6 +323,8 @@ OptionResult HandleParameter(const std::string& key, const char* value,
bool ValidateParameters(const Parameters& params, bool help) { bool ValidateParameters(const Parameters& params, bool help) {
if (help) { if (help) {
std::cout << "cdc_rsync - Synchronize files and directories. Version: "
<< BUILD_VERSION << "\n";
std::cout << kHelpText; std::cout << kHelpText;
return false; return false;
} }

View File

@@ -100,6 +100,7 @@ cc_binary(
"//cdc_rsync/base:cdc_interface", "//cdc_rsync/base:cdc_interface",
"//cdc_rsync/base:message_pump", "//cdc_rsync/base:message_pump",
"//cdc_rsync/base:server_exit_code", "//cdc_rsync/base:server_exit_code",
"//common:build_version",
"//common:clock", "//common:clock",
"//common:gamelet_component", "//common:gamelet_component",
"//common:log", "//common:log",

View File

@@ -14,6 +14,7 @@
#include "cdc_rsync/base/server_exit_code.h" #include "cdc_rsync/base/server_exit_code.h"
#include "cdc_rsync_server/cdc_rsync_server.h" #include "cdc_rsync_server/cdc_rsync_server.h"
#include "common/build_version.h"
#include "common/gamelet_component.h" #include "common/gamelet_component.h"
#include "common/log.h" #include "common/log.h"
#include "common/status.h" #include "common/status.h"
@@ -60,10 +61,16 @@ ServerExitCode GetExitCode(const absl::Status& status) {
} // namespace cdc_ft } // namespace cdc_ft
int main(int argc, const char** argv) { int main(int argc, const char** argv) {
if (argc < 2) { if (argc < 5) {
printf("Usage: cdc_rsync_server <port> cdc_rsync_server <size> <time> \n"); printf("cdc_rsync_server - Remote component of cdc_rsync. Version: %s\n\n",
printf(" where <size> and <time> are the file size and modified\n"); BUILD_VERSION);
printf(" timestamp (Unix epoch) of the corresponding component.\n"); printf(
"Usage: cdc_rsync_server <port> <build_version> cdc_rsync_server "
"<size> <time> \n");
printf(" where <size> is the file size, <time> is the modified\n");
printf(
" timestamp (Unix epoch) and <build_version> is the build "
"version of the server.\n");
return cdc_ft::kServerExitCodeGenericStartup; return cdc_ft::kServerExitCodeGenericStartup;
} }
@@ -82,6 +89,7 @@ int main(int argc, const char** argv) {
cdc_ft::Log::Initialize( cdc_ft::Log::Initialize(
std::make_unique<cdc_ft::ConsoleLog>(cdc_ft::LogLevel::kWarning)); std::make_unique<cdc_ft::ConsoleLog>(cdc_ft::LogLevel::kWarning));
cdc_ft::CdcRsyncServer server; cdc_ft::CdcRsyncServer server;
if (!server.CheckComponents(components)) { if (!server.CheckComponents(components)) {
return cdc_ft::kServerExitCodeOutOfDate; return cdc_ft::kServerExitCodeOutOfDate;
} }

View File

@@ -44,6 +44,11 @@ cc_library(
], ],
) )
cc_library(
name = "build_version",
hdrs = ["build_version.h"],
)
cc_library( cc_library(
name = "dir_iter", name = "dir_iter",
srcs = ["dir_iter.cc"], srcs = ["dir_iter.cc"],
@@ -396,6 +401,7 @@ cc_library(
":path", ":path",
":platform", ":platform",
":status", ":status",
"//common:build_version",
"@com_google_absl//absl/status", "@com_google_absl//absl/status",
"@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/strings:str_format",
], ],

10
common/build_version.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef BUILD_VERSION
#define DEV_BUILD_VERSION "DEV"
#ifdef CDC_BUILD_VERSION
#define TO_STR(arg) #arg
#define TO_STR_VALUE(arg) TO_STR(arg)
#define BUILD_VERSION TO_STR_VALUE(CDC_BUILD_VERSION)
#else
#define BUILD_VERSION DEV_BUILD_VERSION
#endif
#endif

View File

@@ -18,20 +18,36 @@
#include "absl/strings/str_format.h" #include "absl/strings/str_format.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include "common/build_version.h"
#include "common/path.h" #include "common/path.h"
#include "common/status.h" #include "common/status.h"
namespace cdc_ft { namespace cdc_ft {
GameletComponent::GameletComponent(std::string filename, uint64_t size, GameletComponent::GameletComponent(std::string build_version,
std::string filename, uint64_t size,
time_t modified_time) time_t modified_time)
: filename(filename), size(size), modified_time(modified_time) {} : build_version(build_version),
filename(filename),
size(size),
modified_time(modified_time) {}
GameletComponent::~GameletComponent() = default; GameletComponent::~GameletComponent() = default;
bool GameletComponent::operator==(const GameletComponent& other) const { bool GameletComponent::operator==(const GameletComponent& other) const {
return filename == other.filename && size == other.size && if (filename != other.filename) {
modified_time == other.modified_time; return false;
}
// If either build version is the dev version, it means that the component was
// built locally, so that we can't compare build versions. Fall back to
// comparing file_size and modified_time.
if (build_version != DEV_BUILD_VERSION &&
build_version != DEV_BUILD_VERSION) {
return build_version == other.build_version;
}
return size == other.size && modified_time == other.modified_time;
} }
bool GameletComponent::operator!=(const GameletComponent& other) const { bool GameletComponent::operator!=(const GameletComponent& other) const {
@@ -49,7 +65,7 @@ absl::Status GameletComponent::Get(
absl::Status status = path::GetStats(path, &stats); absl::Status status = path::GetStats(path, &stats);
if (!status.ok()) if (!status.ok())
return WrapStatus(status, "GetStats() failed for '%s'", path); return WrapStatus(status, "GetStats() failed for '%s'", path);
components->emplace_back(path::BaseName(path), stats.size, components->emplace_back(BUILD_VERSION, path::BaseName(path), stats.size,
stats.modified_time); stats.modified_time);
} }
@@ -61,9 +77,9 @@ std::string GameletComponent::ToCommandLineArgs(
const std::vector<GameletComponent>& components) { const std::vector<GameletComponent>& components) {
std::string args; std::string args;
for (const GameletComponent& comp : components) { for (const GameletComponent& comp : components) {
args += args += absl::StrFormat("%s%s %s %u %d", args.empty() ? "" : " ",
absl::StrFormat("%s%s %u %d", args.empty() ? "" : " ", comp.build_version.c_str(), comp.filename.c_str(),
comp.filename.c_str(), comp.size, comp.modified_time); comp.size, comp.modified_time);
} }
return args; return args;
} }
@@ -72,9 +88,9 @@ std::string GameletComponent::ToCommandLineArgs(
std::vector<GameletComponent> GameletComponent::FromCommandLineArgs( std::vector<GameletComponent> GameletComponent::FromCommandLineArgs(
int argc, const char** argv) { int argc, const char** argv) {
std::vector<GameletComponent> components; std::vector<GameletComponent> components;
for (int n = 0; n + 2 < argc; n += 3) { for (int n = 0; n + 3 < argc; n += 4) {
components.emplace_back(argv[n], std::stol(argv[n + 1]), components.emplace_back(argv[n], argv[n + 1], std::stol(argv[n + 2]),
std::stol(argv[n + 2])); std::stol(argv[n + 3]));
} }
return components; return components;
} }

View File

@@ -28,11 +28,13 @@ namespace cdc_ft {
// The components are considered fresh if both the timestamp and the file size // The components are considered fresh if both the timestamp and the file size
// match. // match.
struct GameletComponent { struct GameletComponent {
std::string build_version;
std::string filename; std::string filename;
uint64_t size; uint64_t size;
int64_t modified_time; int64_t modified_time;
GameletComponent(std::string filename, uint64_t size, time_t modified_time); GameletComponent(std::string build_version, std::string filename,
uint64_t size, time_t modified_time);
~GameletComponent(); ~GameletComponent();
bool operator==(const GameletComponent& other) const; bool operator==(const GameletComponent& other) const;

View File

@@ -15,6 +15,7 @@
#include "common/gamelet_component.h" #include "common/gamelet_component.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include "common/build_version.h"
#include "common/log.h" #include "common/log.h"
#include "common/path.h" #include "common/path.h"
#include "common/status_test_macros.h" #include "common/status_test_macros.h"
@@ -43,14 +44,14 @@ class GameletComponentTest : public ::testing::Test {
path::Join(base_dir_, "other", "cdc_rsync_server"); path::Join(base_dir_, "other", "cdc_rsync_server");
}; };
TEST_F(GameletComponentTest, EqualityOperators) { TEST_F(GameletComponentTest, EqualityOperators_DevelopmentVersion) {
constexpr uint64_t size1 = 1001; constexpr uint64_t size1 = 1001;
constexpr uint64_t size2 = 1002; constexpr uint64_t size2 = 1002;
constexpr int64_t modified_time1 = 5001; constexpr int64_t modified_time1 = 5001;
constexpr int64_t modified_time2 = 5002; constexpr int64_t modified_time2 = 5002;
GameletComponent a("file1", size1, modified_time1); GameletComponent a(DEV_BUILD_VERSION, "file1", size1, modified_time1);
GameletComponent b = a; GameletComponent b = a;
EXPECT_TRUE(a == b && !(a != b)); EXPECT_TRUE(a == b && !(a != b));
@@ -65,6 +66,38 @@ TEST_F(GameletComponentTest, EqualityOperators) {
b = a; b = a;
b.modified_time = modified_time2; b.modified_time = modified_time2;
EXPECT_TRUE(!(a == b) && a != b); EXPECT_TRUE(!(a == b) && a != b);
b = a;
b.size = size2;
b.build_version = "Specified";
EXPECT_TRUE(!(a == b) && a != b);
a.build_version = "Specified";
EXPECT_TRUE(a == b && !(a != b));
}
TEST_F(GameletComponentTest, EqualityOperators_SpecifiedVersion) {
constexpr uint64_t size1 = 1001;
constexpr uint64_t size2 = 1002;
constexpr int64_t modified_time1 = 5001;
constexpr int64_t modified_time2 = 5002;
GameletComponent a("Specified", "file1", size1, modified_time1);
GameletComponent b = a;
EXPECT_TRUE(a == b && !(a != b));
b.filename = "file2";
EXPECT_TRUE(!(a == b) && a != b);
b = a;
b.size = size2;
EXPECT_TRUE(a == b && !(a != b));
b = a;
b.modified_time = modified_time2;
EXPECT_TRUE(a == b && !(a != b));
} }
TEST_F(GameletComponentTest, GetValidComponents) { TEST_F(GameletComponentTest, GetValidComponents) {