blob: 3d45355870c83a14bf75e88c5713ac634dc42b73 [file] [log] [blame]
// Copyright 2023 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "persistent_mode_test_lib.h"
#ifdef _WIN32
#include "getopt.h"
#elif defined(_AIX)
#include "getopt.h"
#else
#include <getopt.h>
#endif
#include <string>
#include "util.h"
namespace persistent_mode_test {
namespace {
struct ServerState {
ServerState(const PersistentMode::Compatibility& compatibility,
int64_t connection_timeout_ms)
: server_(compatibility) {
server_.SetConnectionTimeoutMs(connection_timeout_ms);
}
void RunServerThenExit() {
server_.RunServerThenExit(
[this]() { return RestartCheck(); },
[this](const PersistentMode::BuildQuery& query) -> int {
return HandleQuery(query);
});
}
bool RestartCheck() { return false; };
int HandleQuery(const PersistentMode::BuildQuery& query) {
if (query.tool == "print-current-dir") {
fprintf(stdout, "%s", GetCurrentDir().c_str());
return 0;
}
if (query.tool == "get-env-vars") {
for (const auto& varname : query.args) {
const char* varvalue = query.config.environment.Get(varname.c_str());
if (!varvalue)
varvalue = "<UNSET>";
fprintf(stdout, "%s=%s\n", varname.c_str(), varvalue);
}
return 0;
}
fprintf(stderr, "UNKNOWN QUERY TYPE!\n");
return 1;
}
// Create new query to print the current directory.
static PersistentMode::BuildQuery MakeQuery1(const std::string& build_dir) {
PersistentMode::BuildQuery query;
query.tool = "print-current-dir";
return query;
}
// Create a new query to print the environment variables of the server
// process.
static PersistentMode::BuildQuery MakeQuery2(
const std::vector<std::string>& print_variables) {
PersistentMode::BuildQuery query;
query.tool = "get-env-vars";
query.args = print_variables;
return query;
}
PersistentMode::Server server_;
};
} // namespace
std::string GetServerExecutable() {
std::string result =
GetCurrentExecutableDir() + "/persistent_mode_test_helper";
#ifdef _WIN32
result += ".exe";
#endif
return result;
}
PersistentMode::Compatibility GetClientCompatibility(
const std::string& build_dir) {
PersistentMode::Compatibility result;
result.SetNinjaVersionForTest("version-1.0")
.SetInputFile("persistent_mode.input")
.SetBuildDir(build_dir);
return result;
}
PersistentMode::Compatibility GetServerCompatibility(
int argc, char** argv, int64_t* connection_timeout_ms) {
const char* progname = argv[0];
auto print_usage = [progname]() {
fprintf(stderr,
"Usage: %s [-C BUILD_DIR] [-f INPUT_FILE] [-t TIMEOUT_MILLIS] [-w "
"WARNING]+\n",
progname);
exit(1);
};
PersistentMode::Compatibility result;
int opt;
while ((opt = getopt(argc, argv, const_cast<char*>("C:f:w:t:"))) != -1) {
fprintf(stderr, "OPT %c\n", opt);
switch (opt) {
case 'C':
result.SetBuildDir(optarg);
break;
case 'f':
result.SetInputFile(optarg);
break;
case 'w':
if (!strcmp(optarg, "dupbuild=err")) {
result.SetFlagDupeEdgesShouldErr(true);
} else if (!strcmp(optarg, "dupbuild=warn")) {
result.SetFlagDupeEdgesShouldErr(false);
} else if (!strcmp(optarg, "phonycycle=err")) {
result.SetFlagPhonyCycleShouldErr(true);
} else if (!strcmp(optarg, "phonycycle=warn")) {
result.SetFlagPhonyCycleShouldErr(false);
} else {
Fatal("Unknown -d argument value: %s", optarg);
}
break;
case 't':
*connection_timeout_ms = static_cast<int64_t>(atoll(optarg));
break;
default:
print_usage();
}
}
fprintf(stderr, "argc=%d optind=%d\n", argc, optind);
argc -= optind;
argv += optind;
if (argc > 0)
print_usage();
// Must match the version in GetClientCompatibility().
result.SetNinjaVersionForTest("version-1.0");
return result;
}
PersistentMode::BuildQuery GetClientTestQuery1(const std::string& build_dir) {
return ServerState::MakeQuery1(build_dir);
}
PersistentMode::BuildQuery GetClientTestQuery2(
const std::vector<std::string>& print_variables) {
return ServerState::MakeQuery2(print_variables);
}
void RunServerThenExit(const PersistentMode::Compatibility& compatibility,
int64_t connection_timeout_ms) {
ServerState state(compatibility, connection_timeout_ms);
state.RunServerThenExit();
}
} // namespace persistent_mode_test