mirror of
https://github.com/nestriness/cdc-file-transfer.git
synced 2026-01-30 14:45:37 +02:00
[cdc_rsync] [cdc_rsync_server] Add build ID
Build id is an optional unique identifier specified during cdc_rsync build via CDC_BUILD_VERSION definition. If build id specified on both client and server components it will be used to check the version of server component instead of file size + modified time.
This commit is contained in:
@@ -159,6 +159,7 @@
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)metrics\metrics.cc" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)cdc_stream\stop_service_command.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)fastcdc\fastcdc.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)manifest\pending_assets_queue.h" />
|
||||
|
||||
@@ -131,6 +131,7 @@ cc_library(
|
||||
hdrs = ["params.h"],
|
||||
deps = [
|
||||
":cdc_rsync_client",
|
||||
"//common:build_version",
|
||||
"//common:port_range_parser",
|
||||
"@com_github_zstd//:zstd",
|
||||
"@com_google_absl//absl/status",
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "common/build_version.h"
|
||||
#include "common/path.h"
|
||||
#include "common/port_range_parser.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 };
|
||||
|
||||
const char kHelpText[] =
|
||||
R"(Synchronize files and directories
|
||||
|
||||
R"(
|
||||
Matching files are skipped based on file size and modified time. For partially
|
||||
matching files only the differences are transferred. The destination directory
|
||||
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) {
|
||||
if (help) {
|
||||
std::cout << "cdc_rsync - Synchronize files and directories. Version: "
|
||||
<< BUILD_VERSION << "\n";
|
||||
std::cout << kHelpText;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -100,6 +100,7 @@ cc_binary(
|
||||
"//cdc_rsync/base:cdc_interface",
|
||||
"//cdc_rsync/base:message_pump",
|
||||
"//cdc_rsync/base:server_exit_code",
|
||||
"//common:build_version",
|
||||
"//common:clock",
|
||||
"//common:gamelet_component",
|
||||
"//common:log",
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "cdc_rsync/base/server_exit_code.h"
|
||||
#include "cdc_rsync_server/cdc_rsync_server.h"
|
||||
#include "common/build_version.h"
|
||||
#include "common/gamelet_component.h"
|
||||
#include "common/log.h"
|
||||
#include "common/status.h"
|
||||
@@ -60,10 +61,16 @@ ServerExitCode GetExitCode(const absl::Status& status) {
|
||||
} // namespace cdc_ft
|
||||
|
||||
int main(int argc, const char** argv) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: cdc_rsync_server <port> cdc_rsync_server <size> <time> \n");
|
||||
printf(" where <size> and <time> are the file size and modified\n");
|
||||
printf(" timestamp (Unix epoch) of the corresponding component.\n");
|
||||
if (argc < 5) {
|
||||
printf("cdc_rsync_server - Remote component of cdc_rsync. Version: %s\n\n",
|
||||
BUILD_VERSION);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -82,6 +89,7 @@ int main(int argc, const char** argv) {
|
||||
cdc_ft::Log::Initialize(
|
||||
std::make_unique<cdc_ft::ConsoleLog>(cdc_ft::LogLevel::kWarning));
|
||||
cdc_ft::CdcRsyncServer server;
|
||||
|
||||
if (!server.CheckComponents(components)) {
|
||||
return cdc_ft::kServerExitCodeOutOfDate;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,11 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "build_version",
|
||||
hdrs = ["build_version.h"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "dir_iter",
|
||||
srcs = ["dir_iter.cc"],
|
||||
@@ -395,6 +400,7 @@ cc_library(
|
||||
":path",
|
||||
":platform",
|
||||
":status",
|
||||
"//common:build_version",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
],
|
||||
|
||||
10
common/build_version.h
Normal file
10
common/build_version.h
Normal 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
|
||||
@@ -18,20 +18,36 @@
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "common/build_version.h"
|
||||
#include "common/path.h"
|
||||
#include "common/status.h"
|
||||
|
||||
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)
|
||||
: filename(filename), size(size), modified_time(modified_time) {}
|
||||
: build_version(build_version),
|
||||
filename(filename),
|
||||
size(size),
|
||||
modified_time(modified_time) {}
|
||||
|
||||
GameletComponent::~GameletComponent() = default;
|
||||
|
||||
bool GameletComponent::operator==(const GameletComponent& other) const {
|
||||
return filename == other.filename && size == other.size &&
|
||||
modified_time == other.modified_time;
|
||||
if (filename != other.filename) {
|
||||
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 {
|
||||
@@ -49,7 +65,7 @@ absl::Status GameletComponent::Get(
|
||||
absl::Status status = path::GetStats(path, &stats);
|
||||
if (!status.ok())
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -61,9 +77,9 @@ std::string GameletComponent::ToCommandLineArgs(
|
||||
const std::vector<GameletComponent>& components) {
|
||||
std::string args;
|
||||
for (const GameletComponent& comp : components) {
|
||||
args +=
|
||||
absl::StrFormat("%s%s %u %d", args.empty() ? "" : " ",
|
||||
comp.filename.c_str(), comp.size, comp.modified_time);
|
||||
args += absl::StrFormat("%s%s %s %u %d", args.empty() ? "" : " ",
|
||||
comp.build_version.c_str(), comp.filename.c_str(),
|
||||
comp.size, comp.modified_time);
|
||||
}
|
||||
return args;
|
||||
}
|
||||
@@ -72,9 +88,9 @@ std::string GameletComponent::ToCommandLineArgs(
|
||||
std::vector<GameletComponent> GameletComponent::FromCommandLineArgs(
|
||||
int argc, const char** argv) {
|
||||
std::vector<GameletComponent> components;
|
||||
for (int n = 0; n + 2 < argc; n += 3) {
|
||||
components.emplace_back(argv[n], std::stol(argv[n + 1]),
|
||||
std::stol(argv[n + 2]));
|
||||
for (int n = 0; n + 3 < argc; n += 4) {
|
||||
components.emplace_back(argv[n], argv[n + 1], std::stol(argv[n + 2]),
|
||||
std::stol(argv[n + 3]));
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
@@ -28,11 +28,13 @@ namespace cdc_ft {
|
||||
// The components are considered fresh if both the timestamp and the file size
|
||||
// match.
|
||||
struct GameletComponent {
|
||||
std::string build_version;
|
||||
std::string filename;
|
||||
uint64_t size;
|
||||
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();
|
||||
|
||||
bool operator==(const GameletComponent& other) const;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "common/gamelet_component.h"
|
||||
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "common/build_version.h"
|
||||
#include "common/log.h"
|
||||
#include "common/path.h"
|
||||
#include "common/status_test_macros.h"
|
||||
@@ -43,14 +44,14 @@ class GameletComponentTest : public ::testing::Test {
|
||||
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 size2 = 1002;
|
||||
|
||||
constexpr int64_t modified_time1 = 5001;
|
||||
constexpr int64_t modified_time2 = 5002;
|
||||
|
||||
GameletComponent a("file1", size1, modified_time1);
|
||||
GameletComponent a(DEV_BUILD_VERSION, "file1", size1, modified_time1);
|
||||
|
||||
GameletComponent b = a;
|
||||
EXPECT_TRUE(a == b && !(a != b));
|
||||
@@ -65,6 +66,38 @@ TEST_F(GameletComponentTest, EqualityOperators) {
|
||||
b = a;
|
||||
b.modified_time = modified_time2;
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user