aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--LICENSE2
-rw-r--r--build/root.build9
-rw-r--r--libbbot/build-target-config.cxx (renamed from libbbot/build-config.cxx)60
-rw-r--r--libbbot/build-target-config.hxx (renamed from libbbot/build-config.hxx)29
-rw-r--r--libbbot/manifest.cxx499
-rw-r--r--libbbot/manifest.hxx241
-rw-r--r--manifest12
-rw-r--r--tests/build/root.build9
-rw-r--r--tests/buildtab/driver.cxx12
-rw-r--r--tests/buildtab/testscript22
-rw-r--r--tests/manifest/driver.cxx10
-rw-r--r--tests/manifest/machine-header.testscript18
-rw-r--r--tests/manifest/result-request.testscript31
-rw-r--r--tests/manifest/result.testscript31
-rw-r--r--tests/manifest/task-request.testscript80
-rw-r--r--tests/manifest/task-response.testscript59
-rw-r--r--tests/manifest/task.testscript224
18 files changed, 1156 insertions, 198 deletions
diff --git a/.gitignore b/.gitignore
index c3de2e7..5046596 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,10 +5,16 @@
*.d
*.t
*.i
+*.i.*
*.ii
+*.ii.*
*.o
*.obj
+*.gcm
+*.pcm
+*.ifc
*.so
+*.dylib
*.dll
*.a
*.lib
diff --git a/LICENSE b/LICENSE
index 2cf3738..e63bcec 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2014-2020 the build2 authors (see the AUTHORS file).
+Copyright (c) 2014-2024 the build2 authors (see the AUTHORS file).
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/build/root.build b/build/root.build
index ad3f3a7..c9ab5dc 100644
--- a/build/root.build
+++ b/build/root.build
@@ -15,3 +15,12 @@ if ($cxx.target.system == 'win32-msvc')
if ($cxx.class == 'msvc')
cxx.coptions += /wd4251 /wd4275 /wd4800
+elif ($cxx.id == 'gcc')
+{
+ cxx.coptions += -Wno-maybe-uninitialized -Wno-free-nonheap-object # libbutl
+
+ if ($cxx.version.major >= 13)
+ cxx.coptions += -Wno-dangling-reference
+}
+elif ($cxx.id.type == 'clang' && $cxx.version.major >= 15)
+ cxx.coptions += -Wno-unqualified-std-cast-call
diff --git a/libbbot/build-config.cxx b/libbbot/build-target-config.cxx
index ff365e3..9e04a17 100644
--- a/libbbot/build-config.cxx
+++ b/libbbot/build-target-config.cxx
@@ -1,7 +1,7 @@
-// file : libbbot/build-config.cxx -*- C++ -*-
+// file : libbbot/build-target-config.cxx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
-#include <libbbot/build-config.hxx>
+#include <libbbot/build-target-config.hxx>
#include <map>
#include <string>
@@ -9,10 +9,10 @@
#include <utility> // move(), make_pair()
#include <stdexcept> // invalid_argument
-#include <libbutl/path.mxx>
-#include <libbutl/fdstream.mxx>
-#include <libbutl/tab-parser.mxx>
-#include <libbutl/string-parser.mxx>
+#include <libbutl/path.hxx>
+#include <libbutl/fdstream.hxx>
+#include <libbutl/tab-parser.hxx>
+#include <libbutl/string-parser.hxx>
#include <libbpkg/manifest.hxx> // build_class_term::validate_name()
@@ -23,10 +23,10 @@ using namespace butl;
namespace bbot
{
- LIBBBOT_EXPORT build_configs
+ LIBBBOT_EXPORT build_target_configs
parse_buildtab (istream& is, const string& name)
{
- build_configs r;
+ build_target_configs r;
tab_parser parser (is, name);
r.classes.push_back ("all");
@@ -56,33 +56,26 @@ namespace bbot
d);
};
- build_config config;
+ build_target_config config;
config.machine_pattern = move (tl[i++].value);
// If the machine pattern is a single dash character, then this is a
// placeholder entry. The only thing we are interested about it is the
// class inheritance information. Note that while all other information
- // is discarded, the configuration name and target must be present (can
- // also be dashes), so the classes field can be determined and parsed.
+ // is discarded, the target configuration name and target must be
+ // present (can also be dashes), so the classes field can be determined
+ // and parsed.
//
bool placeholder (config.machine_pattern == "-");
- // Configuration name, target[/environment] and classes fields are the
- // required ones.
+ // Target configuration name, target[/environment] and classes fields
+ // are the required ones.
//
if (i == n)
- bad_line ("no configuration name found");
+ bad_line ("no target configuration name found");
config.name = move (tl[i].value);
- // Make sure the name is unique.
- //
- for (const auto& c: r)
- {
- if (c.name == config.name)
- bad_line ("duplicate configuration name");
- }
-
if (++i == n)
bad_line ("no target found");
@@ -116,6 +109,14 @@ namespace bbot
bad_line (e.what ());
}
+ // Make sure the name/target combination is unique.
+ //
+ for (const auto& c: r)
+ {
+ if (c.name == config.name && c.target == config.target)
+ bad_line ("duplicate target configuration name/target");
+ }
+
if (++i == n)
bad_line ("no classes found");
@@ -189,9 +190,9 @@ namespace bbot
r.classes.push_back (c);
}
else if (j->second != base && !base.empty ())
- throw invalid_argument ("'" + c + "' new base '" + base +
+ throw invalid_argument ('\'' + c + "' new base '" + base +
"' does not match existing '" +
- j->second + "'");
+ j->second + '\'');
if (!placeholder)
config.classes.emplace_back (move (c));
@@ -221,7 +222,7 @@ namespace bbot
task_manifest::validate_regex (re);
config.warning_regexes.emplace_back (move (re));
}
- else // Configuration option or variable.
+ else // Target configuration option or variable.
config.args.emplace_back (move (v));
}
}
@@ -230,13 +231,14 @@ namespace bbot
bad_line (e.what ());
}
- // Save the configuration.
+ // Save the target configuration.
//
r.emplace_back (move (config));
}
// Erase entries for baseless classes (we were collecting them to make
- // sure that the class inheritance is consistent across configurations).
+ // sure that the class inheritance is consistent across target
+ // configurations).
//
for (auto i (r.class_inheritance_map.begin ());
i != r.class_inheritance_map.end (); )
@@ -250,11 +252,11 @@ namespace bbot
return r;
}
- build_configs
+ build_target_configs
parse_buildtab (const path& p)
{
ifdstream ifs (p);
- build_configs r (parse_buildtab (ifs, p.string ()));
+ build_target_configs r (parse_buildtab (ifs, p.string ()));
ifs.close (); // Throws on failure.
return r;
diff --git a/libbbot/build-config.hxx b/libbbot/build-target-config.hxx
index 3541388..27b555c 100644
--- a/libbbot/build-config.hxx
+++ b/libbbot/build-target-config.hxx
@@ -1,4 +1,4 @@
-// file : libbbot/build-config.hxx -*- C++ -*-
+// file : libbbot/build-target-config.hxx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
#ifndef LIBBBOT_BUILD_CONFIG_HXX
@@ -9,20 +9,20 @@
#include <vector>
#include <iosfwd>
-#include <libbutl/path.mxx>
-#include <libbutl/optional.mxx>
-#include <libbutl/tab-parser.mxx>
-#include <libbutl/target-triplet.mxx>
+#include <libbutl/path.hxx>
+#include <libbutl/optional.hxx>
+#include <libbutl/tab-parser.hxx>
+#include <libbutl/target-triplet.hxx>
#include <libbbot/export.hxx>
#include <libbbot/version.hxx>
namespace bbot
{
- // Build configuration matching specific machine names. Used by bbot
+ // Build target configuration matching specific machine names. Used by bbot
// controllers.
//
- struct build_config
+ struct build_target_config
{
std::string machine_pattern; // Machine name pattern.
std::string name; // Configuration name.
@@ -36,10 +36,10 @@ namespace bbot
std::vector<std::string> warning_regexes;
};
- struct build_configs: std::vector<build_config>
+ struct build_target_configs: std::vector<build_target_config>
{
- // List of all configuration class names. Starts with the all and default
- // classes. The rest follows in the same order as in the buildtab.
+ // List of all target configuration class names. Starts with the all and
+ // default classes. The rest follows in the same order as in the buildtab.
//
std::vector<std::string> classes;
@@ -53,14 +53,17 @@ namespace bbot
//
// buildtab consists of lines in the following format:
//
- // <machine-pattern> <config> <target>[/<environment>] <classes> [<config-arg>]* [<warning-regex>]*
+ // <machine-pattern> <target-config> <target>[/<environment>] <classes> [<tgt-config-arg>]* [<warning-regex>]*
+ //
+ // Note that each <target-config>/<target> pair is expected to be unique in
+ // the buildtab.
//
using butl::tab_parsing;
- LIBBBOT_EXPORT build_configs
+ LIBBBOT_EXPORT build_target_configs
parse_buildtab (std::istream&, const std::string& name);
- LIBBBOT_EXPORT build_configs
+ LIBBBOT_EXPORT build_target_configs
parse_buildtab (const butl::path&);
}
diff --git a/libbbot/manifest.cxx b/libbbot/manifest.cxx
index c01a84b..45a4668 100644
--- a/libbbot/manifest.cxx
+++ b/libbbot/manifest.cxx
@@ -7,20 +7,23 @@
#include <vector>
#include <string>
#include <cctype> // isxdigit()
+#include <limits> // numeric_limits
#include <cassert>
#include <sstream>
#include <cstddef> // size_t
#include <utility> // move()
#include <cstdint> // uint64_t
+#include <cstdlib> // strtoull()
+#include <algorithm> // find_if()
#include <stdexcept> // invalid_argument
-#include <libbutl/regex.mxx>
-#include <libbutl/base64.mxx>
-#include <libbutl/utility.mxx> // digit()
-#include <libbutl/tab-parser.mxx>
-#include <libbutl/string-parser.mxx>
-#include <libbutl/manifest-parser.mxx>
-#include <libbutl/manifest-serializer.mxx>
+#include <libbutl/regex.hxx>
+#include <libbutl/base64.hxx>
+#include <libbutl/utility.hxx> // digit()
+#include <libbutl/tab-parser.hxx>
+#include <libbutl/string-parser.hxx>
+#include <libbutl/manifest-parser.hxx>
+#include <libbutl/manifest-serializer.hxx>
using namespace std;
using namespace butl;
@@ -36,6 +39,29 @@ namespace bbot
using butl::optional;
+ // machine_role
+ //
+ string
+ to_string (machine_role r)
+ {
+ switch (r)
+ {
+ case machine_role::build: return "build";
+ case machine_role::auxiliary: return "auxiliary";
+ }
+
+ assert (false);
+ return string ();
+ }
+
+ machine_role
+ to_machine_role (const string& s)
+ {
+ if (s == "build") return machine_role::build;
+ else if (s == "auxiliary") return machine_role::auxiliary;
+ else throw invalid_argument ("invalid machine role '" + s + '\'');
+ }
+
// result_status
//
string
@@ -43,11 +69,13 @@ namespace bbot
{
switch (s)
{
- case result_status::success: return "success";
- case result_status::warning: return "warning";
- case result_status::error: return "error";
- case result_status::abort: return "abort";
- case result_status::abnormal: return "abnormal";
+ case result_status::skip: return "skip";
+ case result_status::success: return "success";
+ case result_status::warning: return "warning";
+ case result_status::error: return "error";
+ case result_status::abort: return "abort";
+ case result_status::abnormal: return "abnormal";
+ case result_status::interrupt: return "interrupt";
}
assert (false);
@@ -57,12 +85,39 @@ namespace bbot
result_status
to_result_status (const string& s)
{
- if (s == "success") return result_status::success;
- else if (s == "warning") return result_status::warning;
- else if (s == "error") return result_status::error;
- else if (s == "abort") return result_status::abort;
- else if (s == "abnormal") return result_status::abnormal;
- else throw invalid_argument ("invalid result status '" + s + "'");
+ if (s == "skip") return result_status::skip;
+ else if (s == "success") return result_status::success;
+ else if (s == "warning") return result_status::warning;
+ else if (s == "error") return result_status::error;
+ else if (s == "abort") return result_status::abort;
+ else if (s == "abnormal") return result_status::abnormal;
+ else if (s == "interrupt") return result_status::interrupt;
+ else throw invalid_argument ("invalid result status '" + s + '\'');
+ }
+
+ // interactive_mode
+ //
+ string
+ to_string (interactive_mode m)
+ {
+ switch (m)
+ {
+ case interactive_mode::false_: return "false";
+ case interactive_mode::true_: return "true";
+ case interactive_mode::both: return "both";
+ }
+
+ assert (false);
+ return string ();
+ }
+
+ interactive_mode
+ to_interactive_mode (const string& s)
+ {
+ if (s == "false") return interactive_mode::false_;
+ else if (s == "true") return interactive_mode::true_;
+ else if (s == "both") return interactive_mode::both;
+ else throw invalid_argument ("invalid interactive mode '" + s + '\'');
}
// Utility functions
@@ -104,6 +159,29 @@ namespace bbot
return true;
}
+ // Return nullopt if the string is not a valid 64-bit unsigned integer.
+ //
+ static optional<uint64_t>
+ parse_uint64 (const string& s)
+ {
+ if (!s.empty () && s[0] != '-' && s[0] != '+') // strtoull() allows these.
+ {
+ const char* b (s.c_str ());
+ char* e (nullptr);
+ errno = 0; // We must clear it according to POSIX.
+ uint64_t v (strtoull (b, &e, 10)); // Can't throw.
+
+ if (errno != ERANGE &&
+ e == b + s.size () &&
+ v <= numeric_limits<uint64_t>::max ())
+ {
+ return static_cast<uint64_t> (v);
+ }
+ }
+
+ return nullopt;
+ }
+
// machine_header_manifest
//
machine_header_manifest::
@@ -177,6 +255,42 @@ namespace bbot
summary = move (v);
}
+ else if (n == "role")
+ {
+ if (role)
+ bad_name ("machine role redefinition");
+
+ try
+ {
+ role = to_machine_role (v);
+ }
+ catch (const invalid_argument& e)
+ {
+ bad_value (e.what ());
+ }
+ }
+ else if (n == "ram-minimum")
+ {
+ if (ram_minimum)
+ bad_name ("machine minimum RAM redefinition");
+
+ ram_minimum = parse_uint64 (v);
+
+ if (!ram_minimum || *ram_minimum == 0)
+ bad_value (
+ "machine minimum RAM should be non-zero 64-bit unsigned integer");
+ }
+ else if (n == "ram-maximum")
+ {
+ if (ram_maximum)
+ bad_name ("machine maximum RAM redefinition");
+
+ ram_maximum = parse_uint64 (v);
+
+ if (!ram_maximum || *ram_maximum == 0)
+ bad_value (
+ "machine maximum RAM should be non-zero 64-bit unsigned integer");
+ }
else
{
switch (m)
@@ -217,6 +331,21 @@ namespace bbot
s.next ("name", name);
s.next ("summary", summary);
+ if (role)
+ s.next ("role", to_string (*role));
+
+ if (ram_minimum)
+ {
+ assert (*ram_minimum != 0);
+ s.next ("ram-minimum", std::to_string (*ram_minimum));
+ }
+
+ if (ram_maximum)
+ {
+ assert (*ram_maximum != 0);
+ s.next ("ram-maximum", std::to_string (*ram_maximum));
+ }
+
if (end_of_manifest)
s.next ("", ""); // End of manifest.
}
@@ -246,6 +375,11 @@ namespace bbot
if (nv.value != "1")
bad_value ("unsupported format version");
+ // Cache the interactive login manifest value and validate whether it's
+ // allowed later, after the interactive mode is parsed.
+ //
+ optional<name_value> interactive_login_nv;
+
// Parse the task request manifest.
//
for (nv = p.next (); !nv.empty (); nv = p.next ())
@@ -288,6 +422,31 @@ namespace bbot
e.what ());
}
}
+ else if (n == "interactive-mode")
+ {
+ if (interactive_mode)
+ bad_name ("task request interactive mode redefinition");
+
+ try
+ {
+ interactive_mode = to_interactive_mode (v);
+ }
+ catch (const invalid_argument&)
+ {
+ bad_value (
+ string ("invalid task request interactive mode '" + v + '\''));
+ }
+ }
+ else if (n == "interactive-login")
+ {
+ if (interactive_login_nv)
+ bad_name ("task request interactive login redefinition");
+
+ if (v.empty ())
+ bad_value ("empty task request interactive login");
+
+ interactive_login_nv = move (nv);
+ }
else if (n == "fingerprint")
{
if (fingerprint)
@@ -298,6 +457,17 @@ namespace bbot
fingerprint = move (v);
}
+ else if (n == "auxiliary-ram")
+ {
+ if (auxiliary_ram)
+ bad_name ("auxiliary machines RAM limit redefinition");
+
+ auxiliary_ram = parse_uint64 (v);
+
+ if (!auxiliary_ram)
+ bad_value (
+ "auxiliary machines RAM limit should be 64-bit unsigned integer");
+ }
else if (!iu)
bad_name ("unknown name '" + n + "' in task request manifest");
}
@@ -313,6 +483,22 @@ namespace bbot
if (toolchain_version.empty ())
bad_value ("no task request toolchain version specified");
+ if (effective_interactive_mode () != interactive_mode_type::false_)
+ {
+ if (!interactive_login_nv)
+ bad_value ("no task request interactive login specified");
+
+ interactive_login = move (interactive_login_nv->value);
+ }
+ else if (interactive_login_nv)
+ {
+ // Restore as bad_name() uses its line/column.
+ //
+ nv = move (*interactive_login_nv);
+
+ bad_name ("interactive login specified for non-interactive mode");
+ }
+
// Parse machine header manifests.
//
for (nv = p.next (); !nv.empty (); nv = p.next ())
@@ -338,9 +524,18 @@ namespace bbot
s.next ("toolchain-name", toolchain_name);
s.next ("toolchain-version", toolchain_version.string ());
+ if (interactive_mode)
+ s.next ("interactive-mode", to_string (*interactive_mode));
+
+ if (interactive_login)
+ s.next ("interactive-login", *interactive_login);
+
if (fingerprint)
s.next ("fingerprint", *fingerprint);
+ if (auxiliary_ram)
+ s.next ("auxiliary-ram", std::to_string (*auxiliary_ram));
+
s.next ("", ""); // End of manifest.
for (const machine_header_manifest& m: machines)
@@ -451,6 +646,11 @@ namespace bbot
optional<name_value> repo_url;
optional<repository_type> repo_type;
+ // We will also cache the requires values to parse them later, after the
+ // package name is parsed.
+ //
+ vector<name_value> reqs;
+
for (nv = p.next (); !nv.empty (); nv = p.next ())
{
string& n (nv.name);
@@ -511,7 +711,7 @@ namespace bbot
}
catch (const invalid_argument&)
{
- bad_value ("invalid task repository type '" + v + "'");
+ bad_value ("invalid task repository type '" + v + '\'');
}
}
else if (n == "trust")
@@ -521,37 +721,31 @@ namespace bbot
trust.emplace_back (move (v));
}
- else if (n == "test-exclude")
+ else if (n == "requires")
+ {
+ reqs.push_back (move (nv));
+ }
+ else if (n == "tests" || n == "examples" || n == "benchmarks")
{
- size_t p (v.find ('/'));
- if (p == string::npos)
- bad_value ("invalid test exclusion package: '/' is expected");
-
- package_name pn;
-
try
{
- pn = package_name (string (v, 0, p));
+ tests.push_back (test_dependency (move (v),
+ to_test_dependency_type (n)));
}
catch (const invalid_argument& e)
{
- bad_value (string ("invalid test exclusion package name: ") +
- e.what ());
+ bad_value (e.what ());
}
+ }
+ else if (n == "dependency-checksum")
+ {
+ if (dependency_checksum)
+ bad_name ("task dependency checksum redefinition");
- bpkg::version pv;
-
- try
- {
- pv = bpkg::version (string (v, p + 1));
- }
- catch (const invalid_argument& e)
- {
- bad_value (string ("invalid test exclusion package version: ") +
- e.what ());
- }
+ if (v.empty ())
+ bad_value ("empty task dependency checksum");
- test_exclusions.push_back (package {move (pn), move (pv)});
+ dependency_checksum = move (v);
}
else if (n == "machine")
{
@@ -563,6 +757,26 @@ namespace bbot
machine = move (v);
}
+ else if (n == "auxiliary-machine" ||
+ (n.size () > 18 && n.compare (0, 18, "auxiliary-machine-") == 0))
+ {
+ if (v.empty ())
+ bad_value ("empty task auxiliary machine name");
+
+ auxiliary_machine m {move (v),
+ n.size () > 18 ? string (n, 18) : string ()};
+
+ if (find_if (auxiliary_machines.begin (), auxiliary_machines.end (),
+ [&m] (const auxiliary_machine& am)
+ {
+ return am.environment_name == m.environment_name;
+ }) != auxiliary_machines.end ())
+ {
+ bad_name ("task auxiliary machine environment redefinition");
+ }
+
+ auxiliary_machines.push_back (move (m));
+ }
else if (n == "target")
{
if (!target.empty ())
@@ -587,15 +801,45 @@ namespace bbot
environment = move (v);
}
- else if (n == "config")
+ else if (n == "auxiliary-environment")
{
- if (!config.empty ())
- bad_name ("task configuration redefinition");
+ if (auxiliary_environment)
+ bad_name ("task auxiliary environment redefinition");
- config = parse_tab (v, [](const string&){}, "configuration");
+ if (v.empty ())
+ bad_value ("empty task auxiliary environment");
- if (config.empty ())
- bad_value ("empty task configuration");
+ auxiliary_environment = move (v);
+ }
+ else if (n == "config" || // @@ TMP Until toolchain 0.16.0 is released.
+ n == "target-config")
+ {
+ if (!target_config.empty ())
+ bad_name ("task target configuration redefinition");
+
+ target_config = parse_tab (v, [](const string&){}, "configuration");
+
+ if (target_config.empty ())
+ bad_value ("empty task target configuration");
+ }
+ else if (n == "package-config")
+ {
+ if (!package_config.empty ())
+ bad_name ("task package configuration redefinition");
+
+ package_config = move (v);
+ }
+ else if (n == "host")
+ {
+ if (host)
+ bad_name ("task host value redefinition");
+
+ if (v == "true")
+ host = true;
+ else if (v == "false")
+ host = false;
+ else
+ bad_value ("invalid task host value '" + v + '\'');
}
else if (n == "warning-regex")
{
@@ -607,6 +851,26 @@ namespace bbot
if (warning_regex.empty ())
bad_value ("empty task warning regex");
}
+ else if (n == "interactive")
+ {
+ if (interactive)
+ bad_name ("task interactive value redefinition");
+
+ if (v.empty ())
+ bad_value ("empty task interactive value");
+
+ interactive = move (v);
+ }
+ else if (n == "worker-checksum")
+ {
+ if (worker_checksum)
+ bad_name ("task worker checksum redefinition");
+
+ if (v.empty ())
+ bad_value ("empty task worker checksum");
+
+ worker_checksum = move (v);
+ }
else if (!iu)
bad_name ("unknown name '" + n + "' in task manifest");
}
@@ -642,6 +906,18 @@ namespace bbot
nv = move (*repo_url); // Restore as bad_value() uses its line/column.
bad_value (string ("invalid task repository URL: ") + e.what ());
}
+
+ // Parse the requirements.
+ //
+ for (const name_value& r: reqs)
+ {
+ requirements.push_back (
+ requirement_alternatives (r.value,
+ name,
+ p.name (),
+ r.value_line,
+ r.value_column));
+ }
}
void task_manifest::
@@ -672,15 +948,31 @@ namespace bbot
for (const string& v: trust)
s.next ("trust", v);
- for (const package& te: test_exclusions)
- s.next ("test-exclude", te.name.string () + '/' + te.version.string ());
+ for (const requirement_alternatives& r: requirements)
+ s.next ("requires", r.string ());
+
+ for (const test_dependency& t: tests)
+ s.next (to_string (t.type), t.string ());
+
+ if (dependency_checksum)
+ s.next ("dependency-checksum", *dependency_checksum);
s.next ("machine", machine);
+
+ for (const auxiliary_machine& am: auxiliary_machines)
+ s.next ((!am.environment_name.empty ()
+ ? "auxiliary-machine-" + am.environment_name
+ : "auxiliary-machine"),
+ am.name);
+
s.next ("target", target.string ());
if (environment)
s.next ("environment", *environment);
+ if (auxiliary_environment)
+ s.next ("auxiliary-environment", *auxiliary_environment);
+
// Serialize an optional value of the strings type as a space-separated
// string list.
//
@@ -701,16 +993,35 @@ namespace bbot
}
};
- serialize_list ("config", config);
+ // @@ TMP Always use 'target-config' name and always serialize
+ // package_config after toolchain 0.16.0 is released.
+ //
+ if (!package_config.empty ())
+ {
+ serialize_list ("target-config", target_config);
+ s.next ("package-config", package_config);
+ }
+ else
+ serialize_list ("config", target_config);
+
+ if (host)
+ s.next ("host", *host ? "true" : "false");
+
serialize_list ("warning-regex", warning_regex);
+ if (interactive)
+ s.next ("interactive", *interactive);
+
+ if (worker_checksum)
+ s.next ("worker-checksum", *worker_checksum);
+
s.next ("", ""); // End of manifest.
}
strings task_manifest::
- unquoted_config () const
+ unquoted_target_config () const
{
- return string_parser::unquote (config);
+ return string_parser::unquote (target_config);
}
strings task_manifest::
@@ -798,6 +1109,33 @@ namespace bbot
result_url = move (v);
}
+ else if (n.size () > 11 &&
+ n.compare (n.size () - 11, 11, "-upload-url") == 0)
+ {
+ n.resize (n.size () - 11);
+
+ if (find_if (upload_urls.begin (), upload_urls.end (),
+ [&n] (const upload_url& u) {return u.type == n;}) !=
+ upload_urls.end ())
+ {
+ bad_name ("task response upload url redefinition");
+ }
+
+ if (v.empty ())
+ bad_value ("empty task response upload url");
+
+ upload_urls.emplace_back (move (v), move (n));
+ }
+ else if (n == "agent-checksum")
+ {
+ if (agent_checksum)
+ bad_name ("task response agent checksum redefinition");
+
+ if (v.empty ())
+ bad_value ("empty task response agent checksum");
+
+ agent_checksum = move (v);
+ }
else if (!iu)
bad_name ("unknown name '" + n + "' in task response manifest");
}
@@ -825,10 +1163,16 @@ namespace bbot
if (result_url)
bad_value ("unexpected task response result url");
+
+ if (!upload_urls.empty ())
+ bad_value ("unexpected task response upload url");
+
+ if (agent_checksum)
+ bad_value ("unexpected task response agent checksum");
}
- // If session is not empty then the task manifest must follow, otherwise it
- // shouldn't.
+ // If session is not empty then the task manifest must follow, otherwise
+ // it shouldn't.
//
nv = p.next ();
@@ -864,6 +1208,12 @@ namespace bbot
if (result_url)
s.next ("result-url", *result_url);
+ for (const upload_url& u: upload_urls)
+ s.next (u.type + "-upload-url", u.url);
+
+ if (agent_checksum)
+ s.next ("agent-checksum", *agent_checksum);
+
s.next ("", ""); // End of manifest.
if (task)
@@ -1030,6 +1380,26 @@ namespace bbot
//
results[nlog++].log = move (v);
}
+ else if (n == "worker-checksum")
+ {
+ if (worker_checksum)
+ bad_name ("result worker checksum redefinition");
+
+ if (v.empty ())
+ bad_value ("empty result worker checksum");
+
+ worker_checksum = move (v);
+ }
+ else if (n == "dependency-checksum")
+ {
+ if (dependency_checksum)
+ bad_name ("result dependency checksum redefinition");
+
+ if (v.empty ())
+ bad_value ("empty result dependency checksum");
+
+ dependency_checksum = move (v);
+ }
else if (!iu)
bad_name ("unknown name '" + n + "' in result manifest");
}
@@ -1086,6 +1456,12 @@ namespace bbot
for (const auto& r: results)
s.next (r.operation + "-log", r.log);
+ if (worker_checksum)
+ s.next ("worker-checksum", *worker_checksum);
+
+ if (dependency_checksum)
+ s.next ("dependency-checksum", *dependency_checksum);
+
s.next ("", ""); // End of manifest.
}
@@ -1148,6 +1524,16 @@ namespace bbot
bad_value ("invalid result request challenge");
}
}
+ else if (n == "agent-checksum")
+ {
+ if (!agent_checksum.empty ())
+ bad_name ("result request agent checksum redefinition");
+
+ if (v.empty ())
+ bad_value ("empty result request agent checksum");
+
+ agent_checksum = move (v);
+ }
else if (!iu)
bad_name ("unknown name '" + n + "' in result request manifest");
}
@@ -1157,6 +1543,9 @@ namespace bbot
if (session.empty ())
bad_value ("no result request session specified");
+ if (agent_checksum.empty ())
+ bad_value ("no result request agent checksum specified");
+
nv = p.next ();
if (nv.empty ())
bad_value ("result manifest expected");
@@ -1183,6 +1572,8 @@ namespace bbot
if (challenge)
s.next ("challenge", base64_encode (*challenge));
+ s.next ("agent-checksum", agent_checksum);
+
s.next ("", ""); // End of manifest.
result.serialize (s);
diff --git a/libbbot/manifest.hxx b/libbbot/manifest.hxx
index daee743..909d47d 100644
--- a/libbbot/manifest.hxx
+++ b/libbbot/manifest.hxx
@@ -6,12 +6,13 @@
#include <string>
#include <vector>
+#include <cstdint> // uint*_t
#include <ostream>
-#include <libbutl/optional.mxx>
-#include <libbutl/small-vector.mxx>
-#include <libbutl/target-triplet.mxx>
-#include <libbutl/standard-version.mxx>
+#include <libbutl/optional.hxx>
+#include <libbutl/small-vector.hxx>
+#include <libbutl/target-triplet.hxx>
+#include <libbutl/standard-version.hxx>
#include <libbutl/manifest-forward.hxx>
#include <libbpkg/manifest.hxx> // version, repository_location
@@ -24,15 +25,57 @@ namespace bbot
{
using strings = std::vector<std::string>;
+ // The machine's role.
+ //
+ enum class machine_role: std::uint8_t
+ {
+ build,
+ auxiliary
+ };
+
+ LIBBBOT_EXPORT std::string
+ to_string (machine_role);
+
+ LIBBBOT_EXPORT machine_role
+ to_machine_role (const std::string&); // May throw invalid_argument.
+
+ inline std::ostream&
+ operator<< (std::ostream& os, machine_role r)
+ {
+ return os << to_string (r);
+ }
+
class LIBBBOT_EXPORT machine_header_manifest
{
public:
std::string id;
std::string name;
std::string summary;
+ butl::optional<machine_role> role;
+ butl::optional<std::uint64_t> ram_minimum; // In KiB, non-zero.
+ butl::optional<std::uint64_t> ram_maximum; // In KiB, non-zero.
- machine_header_manifest (std::string i, std::string n, std::string s)
- : id (std::move (i)), name (std::move (n)), summary (std::move (s)) {}
+ // Return the effective machine role. If the role is not explicitly
+ // specified, then the build role is assumed.
+ //
+ machine_role
+ effective_role () const noexcept
+ {
+ return role ? *role : machine_role::build;
+ }
+
+ machine_header_manifest (std::string i,
+ std::string n,
+ std::string s,
+ butl::optional<machine_role> r,
+ butl::optional<std::uint64_t> rmn,
+ butl::optional<std::uint64_t> rmx)
+ : id (std::move (i)),
+ name (std::move (n)),
+ summary (std::move (s)),
+ role (r),
+ ram_minimum (rmn),
+ ram_maximum (rmx) {}
public:
machine_header_manifest () = default; // VC export.
@@ -62,14 +105,40 @@ namespace bbot
using machine_header_manifests = std::vector<machine_header_manifest>;
+ // Agent's capability to perform (non-)interactive builds.
+ //
+ enum class interactive_mode: std::uint8_t
+ {
+ false_,
+ true_,
+ both
+ };
+
+ LIBBBOT_EXPORT std::string
+ to_string (interactive_mode);
+
+ LIBBBOT_EXPORT interactive_mode
+ to_interactive_mode (const std::string&); // May throw invalid_argument.
+
+ inline std::ostream&
+ operator<< (std::ostream& os, interactive_mode m)
+ {
+ return os << to_string (m);
+ }
+
class LIBBBOT_EXPORT task_request_manifest
{
public:
+ using interactive_mode_type = bbot::interactive_mode;
+
std::string agent;
std::string toolchain_name;
butl::standard_version toolchain_version;
+ butl::optional<interactive_mode_type> interactive_mode;
+ butl::optional<std::string> interactive_login;
+
// Agent's public key SHA256 fingerprint.
//
// @@ How the fingerpring for openssl public key will be produced? Seems
@@ -80,18 +149,37 @@ namespace bbot
//
butl::optional<std::string> fingerprint;
+ butl::optional<std::uint64_t> auxiliary_ram; // In KiB.
+
machine_header_manifests machines;
- task_request_manifest (std::string a,
- std::string n,
- butl::standard_version v,
- butl::optional<std::string> f,
- machine_header_manifests m)
- : agent (std::move (a)),
- toolchain_name (std::move (n)),
- toolchain_version (std::move (v)),
- fingerprint (std::move (f)),
- machines (std::move (m)) {}
+ // Return the effective interactive build mode. If the mode is not
+ // explicitly specified, then false is assumed.
+ //
+ interactive_mode_type
+ effective_interactive_mode () const noexcept
+ {
+ return interactive_mode
+ ? *interactive_mode
+ : interactive_mode_type::false_;
+ }
+
+ task_request_manifest (std::string ag,
+ std::string tn,
+ butl::standard_version tv,
+ butl::optional<interactive_mode_type> im,
+ butl::optional<std::string> il,
+ butl::optional<std::string> fp,
+ butl::optional<std::uint64_t> ar,
+ machine_header_manifests ms)
+ : agent (std::move (ag)),
+ toolchain_name (std::move (tn)),
+ toolchain_version (std::move (tv)),
+ interactive_mode (std::move (im)),
+ interactive_login (std::move (il)),
+ fingerprint (std::move (fp)),
+ auxiliary_ram (ar),
+ machines (std::move (ms)) {}
public:
task_request_manifest () = default; // VC export.
@@ -108,6 +196,14 @@ namespace bbot
bpkg::version version;
};
+ // Note: corresponds to build_auxiliary in the package manifest.
+ //
+ struct auxiliary_machine
+ {
+ std::string name;
+ std::string environment_name;
+ };
+
class LIBBBOT_EXPORT task_manifest
{
public:
@@ -123,22 +219,53 @@ namespace bbot
//
strings trust;
- // Separate tests, examples, and benchmarks packages that should be
- // excluded from building together with the primary package.
+ // The subset of the build task-relevant package manifest values (see
+ // bpkg::package_manifest for their semantics).
//
- butl::small_vector<package, 1> test_exclusions;
+ std::vector<bpkg::requirement_alternatives> requirements;
+ butl::small_vector<bpkg::test_dependency, 1> tests;
+
+ butl::optional<std::string> dependency_checksum;
std::string machine; // Build machine to use for building the package.
+ // The list of build auxiliary machines.
+ //
+ // Note that all entries in this list must have distinct environment names
+ // (with empty name being one of the possibilities).
+ //
+ // Also note that some auxiliary machines can potentially be used by the
+ // main package and some by the test packages. It is such package author's
+ // responsibility to make sure that the environment names specified in
+ // multiple package manifests do not clash. It is bbot controller's
+ // responsibility to verify that there is no clash, aborting the task if
+ // there is.
+ //
+ std::vector<auxiliary_machine> auxiliary_machines;
+
butl::target_triplet target; // Build target.
butl::optional<std::string> environment; // Build environment name.
+ // The environment variables describing the auxiliary machines.
+ //
+ butl::optional<std::string> auxiliary_environment;
+
// Build system configuration variables (in addition to build environment
// configuration variables).
+ //
// Note: could be quoted.
//
- strings config;
+ strings target_config;
+
+ // Whitespace separated list of potentially double/single-quoted package
+ // configuration arguments for bpkg-pkg-build command.
+ //
+ std::string package_config;
+
+ // If true, then this configuration is self-hosted.
+ //
+ butl::optional<bool> host;
// Regular expressions for detecting warnings in the operation result logs
// (in addition to the default list of expressions).
@@ -146,8 +273,12 @@ namespace bbot
//
strings warning_regex;
+ butl::optional<std::string> interactive; // Interactive build breakpoint.
+
+ butl::optional<std::string> worker_checksum;
+
strings
- unquoted_config () const;
+ unquoted_target_config () const;
strings
unquoted_warning_regex () const;
@@ -156,22 +287,38 @@ namespace bbot
bpkg::version vr,
bpkg::repository_location rl,
strings tr,
- butl::small_vector<package, 1> te,
+ std::vector<bpkg::requirement_alternatives> ra,
+ butl::small_vector<bpkg::test_dependency, 1> ts,
+ butl::optional<std::string> dc,
std::string mn,
+ std::vector<auxiliary_machine> ams,
butl::target_triplet tg,
butl::optional<std::string> en,
- strings cf,
- strings wr)
+ butl::optional<std::string> ae,
+ strings tc,
+ std::string pc,
+ butl::optional<bool> ht,
+ strings wr,
+ butl::optional<std::string> ir,
+ butl::optional<std::string> wc)
: name (std::move (nm)),
version (std::move (vr)),
repository (std::move (rl)),
trust (std::move (tr)),
- test_exclusions (std::move (te)),
+ requirements (std::move (ra)),
+ tests (std::move (ts)),
+ dependency_checksum (std::move (dc)),
machine (std::move (mn)),
+ auxiliary_machines (std::move (ams)),
target (std::move (tg)),
environment (std::move (en)),
- config (std::move (cf)),
- warning_regex (std::move (wr)){}
+ auxiliary_environment (std::move (ae)),
+ target_config (std::move (tc)),
+ package_config (std::move (pc)),
+ host (std::move (ht)),
+ warning_regex (std::move (wr)),
+ interactive (std::move (ir)),
+ worker_checksum (std::move (wc)) {}
public:
task_manifest () = default; // VC export.
@@ -190,6 +337,16 @@ namespace bbot
validate_regex (const std::string&);
};
+ class upload_url
+ {
+ public:
+ std::string url;
+ std::string type;
+
+ upload_url (std::string u, std::string t)
+ : url (std::move (u)), type (std::move (t)) {}
+ };
+
class LIBBBOT_EXPORT task_response_manifest
{
public:
@@ -197,19 +354,28 @@ namespace bbot
//
std::string session;
- // Challenge, result url and task are absent if session is empty.
+ // Challenge, result url, and task are absent and upload urls list is
+ // empty if session is empty.
//
butl::optional<std::string> challenge;
butl::optional<std::string> result_url;
+ std::vector<upload_url> upload_urls; // <type>-upload-url: <url>
+
+ butl::optional<std::string> agent_checksum;
+
butl::optional<task_manifest> task;
task_response_manifest (std::string s,
butl::optional<std::string> c,
butl::optional<std::string> u,
+ std::vector<upload_url> uus,
+ butl::optional<std::string> ac,
butl::optional<task_manifest> t)
: session (std::move (s)),
challenge (std::move (c)),
result_url (std::move (u)),
+ upload_urls (std::move (uus)),
+ agent_checksum (std::move (ac)),
task (std::move (t)) {}
public:
@@ -229,11 +395,13 @@ namespace bbot
// indicate whether one "overrides" the other in the "merge" operator|
// (see below).
//
+ skip,
success,
warning,
error,
abort,
- abnormal
+ abnormal,
+ interrupt
};
LIBBBOT_EXPORT std::string
@@ -292,14 +460,21 @@ namespace bbot
//
operation_results results;
+ butl::optional<std::string> worker_checksum;
+ butl::optional<std::string> dependency_checksum;
+
result_manifest (bpkg::package_name n,
bpkg::version v,
result_status s,
- operation_results r)
+ operation_results r,
+ butl::optional<std::string> wc,
+ butl::optional<std::string> dc)
: name (std::move (n)),
version (std::move (v)),
status (s),
- results (std::move (r)) {}
+ results (std::move (r)),
+ worker_checksum (std::move (wc)),
+ dependency_checksum (std::move (dc)) {}
public:
result_manifest () = default; // VC export.
@@ -321,13 +496,17 @@ namespace bbot
//
butl::optional<std::vector<char>> challenge;
+ std::string agent_checksum;
+
result_manifest result;
result_request_manifest (std::string s,
butl::optional<std::vector<char>> c,
+ std::string ac,
result_manifest r)
: session (std::move (s)),
challenge (std::move (c)),
+ agent_checksum (std::move (ac)),
result (std::move (r)) {}
public:
diff --git a/manifest b/manifest
index 725db70..a3de51d 100644
--- a/manifest
+++ b/manifest
@@ -1,6 +1,6 @@
: 1
name: libbbot
-version: 0.13.0
+version: 0.17.0-a.0.z
project: build2
summary: build2 build bot utility library
license: MIT
@@ -13,9 +13,9 @@ doc-url: https://build2.org/doc.xhtml
src-url: https://git.build2.org/cgit/libbbot/tree/
email: users@build2.org
build-warning-email: builds@build2.org
-builds: all
+builds: all : &host
requires: c++14
-depends: * build2 >= 0.13.0
-depends: * bpkg >= 0.13.0
-depends: libbutl ^0.13.0
-depends: libbpkg ^0.13.0
+depends: * build2 >= 0.16.0-
+depends: * bpkg >= 0.16.0-
+depends: libbutl [0.17.0-a.0.1 0.17.0-a.1)
+depends: libbpkg [0.17.0-a.0.1 0.17.0-a.1)
diff --git a/tests/build/root.build b/tests/build/root.build
index bb274d3..f97c101 100644
--- a/tests/build/root.build
+++ b/tests/build/root.build
@@ -13,6 +13,15 @@ if ($cxx.target.system == 'win32-msvc')
if ($cxx.class == 'msvc')
cxx.coptions += /wd4251 /wd4275 /wd4800
+elif ($cxx.id == 'gcc')
+{
+ cxx.coptions += -Wno-maybe-uninitialized -Wno-free-nonheap-object # libbutl
+
+ if ($cxx.version.major >= 13)
+ cxx.coptions += -Wno-dangling-reference
+}
+elif ($cxx.id.type == 'clang' && $cxx.version.major >= 15)
+ cxx.coptions += -Wno-unqualified-std-cast-call
# Every exe{} in this subproject is by default a test.
#
diff --git a/tests/buildtab/driver.cxx b/tests/buildtab/driver.cxx
index 13d0d71..1ea4331 100644
--- a/tests/buildtab/driver.cxx
+++ b/tests/buildtab/driver.cxx
@@ -2,12 +2,14 @@
// license : MIT; see accompanying LICENSE file
#include <ios> // ios::failbit, ios::badbit
-#include <cassert>
#include <iostream>
-#include <libbutl/utility.mxx> // operator<<(ostream,exception)
+#include <libbutl/utility.hxx> // operator<<(ostream,exception)
+
+#include <libbbot/build-target-config.hxx>
-#include <libbbot/build-config.hxx>
+#undef NDEBUG
+#include <cassert>
using namespace std;
using namespace butl;
@@ -25,9 +27,9 @@ try
cin.exceptions (ios::failbit | ios::badbit);
cout.exceptions (ios::failbit | ios::badbit);
- const build_configs& configs (parse_buildtab (cin, "cin"));
+ const build_target_configs& configs (parse_buildtab (cin, "cin"));
- for (const build_config& c: configs)
+ for (const build_target_config& c: configs)
{
cout << c.machine_pattern << ' ' << c.name << ' ' << c.target;
diff --git a/tests/buildtab/testscript b/tests/buildtab/testscript
index c9b5389..6c8b054 100644
--- a/tests/buildtab/testscript
+++ b/tests/buildtab/testscript
@@ -6,11 +6,13 @@
: Roundtrip buildtab.
:
{
- : all-fileds-combinations
+ : all-fields-combinations
:
$* <<EOI >>EOO
- windows*-vc_14* windows-vc_14-32 i686-microsoft-win32-msvc14.0 all
- windows*-vc_14* windows-vc_14-32-debug i686-microsoft-win32-msvc14.0 "" config.cc.coptions=/Z7 config.cc.loptions=/DEBUG ~"warning C4\d{3}: "
+ windows*-vc_14* windows-vc_14 i686-microsoft-win32-msvc14.0 all
+ windows*-vc_14* windows-vc_14-debug i686-microsoft-win32-msvc14.0 "" config.cc.coptions=/Z7 config.cc.loptions=/DEBUG ~"warning C4\d{3}: "
+
+ windows*-vc_14* windows-vc_14 x86_64-microsoft-win32-msvc14.0 all
linux_debian_8*-gcc_4.9 linux_debian_8-gcc_4.9 x86_64-linux-gnu "all default linux gcc gcc-4+:gcc-3+"
- - - gcc-5+:gcc-4+
@@ -21,8 +23,9 @@
windows_10*-clang_9.0_msvc_16.3 windows_10-clang_9.0_msvc_16.3_lld x86_64-microsoft-win32-msvc14.2/lld "all default windows clang"
EOI
- windows*-vc_14* windows-vc_14-32 i686-microsoft-win32-msvc14.0 all
- windows*-vc_14* windows-vc_14-32-debug i686-microsoft-win32-msvc14.0 "" config.cc.coptions=/Z7 config.cc.loptions=/DEBUG ~"warning C4\d{3}: "
+ windows*-vc_14* windows-vc_14 i686-microsoft-win32-msvc14.0 all
+ windows*-vc_14* windows-vc_14-debug i686-microsoft-win32-msvc14.0 "" config.cc.coptions=/Z7 config.cc.loptions=/DEBUG ~"warning C4\d{3}: "
+ windows*-vc_14* windows-vc_14 x86_64-microsoft-win32-msvc14.0 all
linux_debian_8*-gcc_4.9 linux_debian_8-gcc_4.9 x86_64-linux-gnu "all default linux gcc gcc-4+:gcc-3+"
linux_debian_9*-gcc_7.3 linux_debian_9-gcc_7.3 x86_64-linux-gnu "all default linux gcc gcc-7+:gcc-6+"
linux_debian_9*-gcc_7.3 linux_debian_9-gcc_7.3-O3 x86_64-linux-gnu "all default linux gcc optimized gcc-7+:gcc-6+" config.cc.coptions=-O3
@@ -52,14 +55,15 @@
$* <<EOI 2>>EOE == 1
windows*-vc_14*
EOI
- cin:1:16: error: no configuration name found
+ cin:1:16: error: no target configuration name found
EOE
: dup
:
- $* <<EOI 2>'cin:2:17: error: duplicate configuration name' == 1
- windows*-vc_14* windows-vc_14-32 i686-microsoft-win32-msvc14.0 default
- windows*-vc_14* windows-vc_14-32 i686-microsoft-win32-msvc14.0 default
+ $* <<EOI 2>'cin:3:31: error: duplicate target configuration name/target' == 1
+ windows*-vc_14* windows-vc_14 i686-microsoft-win32-msvc14.0 default
+ windows*-vc_14* windows-vc_14 x86_64-microsoft-win32-msvc14.0 default
+ windows*-vc_14* windows-vc_14 i686-microsoft-win32-msvc14.0 default
EOI
}
diff --git a/tests/manifest/driver.cxx b/tests/manifest/driver.cxx
index 821aa63..9c0fcf9 100644
--- a/tests/manifest/driver.cxx
+++ b/tests/manifest/driver.cxx
@@ -3,15 +3,17 @@
#include <ios> // ios_base::failbit, ios_base::badbit
#include <string>
-#include <cassert>
#include <iostream>
-#include <libbutl/utility.mxx> // operator<<(ostream,exception)
-#include <libbutl/manifest-parser.mxx>
-#include <libbutl/manifest-serializer.mxx>
+#include <libbutl/utility.hxx> // operator<<(ostream,exception)
+#include <libbutl/manifest-parser.hxx>
+#include <libbutl/manifest-serializer.hxx>
#include <libbbot/manifest.hxx>
+#undef NDEBUG
+#include <cassert>
+
using namespace std;
using namespace butl;
using namespace bbot;
diff --git a/tests/manifest/machine-header.testscript b/tests/manifest/machine-header.testscript
index 84295d2..559a107 100644
--- a/tests/manifest/machine-header.testscript
+++ b/tests/manifest/machine-header.testscript
@@ -13,6 +13,8 @@ test.options += -m
id: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
name: windows_10-msvc_14
summary: Windows 10 build 1607 with VC 14 update 3
+ role: build
+ ram-minimum: 4194304
EOF
}
@@ -52,6 +54,22 @@ EOI
summary: Windows
summary: Windows
EOI
+
+ : ram-maximum
+ :
+ $* <<EOI 2>'stdin:3:1: error: machine maximum RAM redefinition' == 1
+ : 1
+ ram-maximum: 4194304
+ ram-maximum: 4194304
+ EOI
+
+ : role
+ :
+ $* <<EOI 2>'stdin:3:1: error: machine role redefinition' == 1
+ : 1
+ role: build
+ role: auxiliary
+ EOI
}
: empty
diff --git a/tests/manifest/result-request.testscript b/tests/manifest/result-request.testscript
index e2c4a94..6d0e5b1 100644
--- a/tests/manifest/result-request.testscript
+++ b/tests/manifest/result-request.testscript
@@ -14,10 +14,12 @@ test.options += -rq
: 1
session: abcd
challenge: YQo=
+ agent-checksum: 1
:
name: libfoo
version: 1.0
status: error
+ worker-checksum: 1
EOF
: no-challenge
@@ -25,10 +27,12 @@ test.options += -rq
$* <<EOF >>EOF
: 1
session: abcd
+ agent-checksum: 1
:
name: libfoo
version: 1.0
status: error
+ worker-checksum: 1
EOF
}
@@ -51,6 +55,14 @@ test.options += -rq
challenge: YQo=
challenge: YQo=
EOI
+
+ : agent-checksum
+ :
+ $* <<EOI 2>'stdin:3:1: error: result request agent checksum redefinition' == 1
+ : 1
+ agent-checksum: 1
+ agent-checksum: 1
+ EOI
}
: invalid
@@ -76,6 +88,13 @@ test.options += -rq
: 1
challenge:
EOI
+
+ : empty-agent-checksum
+ :
+ $* <<EOI 2>'stdin:2:16: error: empty result request agent checksum' == 1
+ : 1
+ agent-checksum:
+ EOI
}
: unknown-name
@@ -95,11 +114,21 @@ EOI
challenge: YQo=
EOI
+
+ : agent-checksum
+ :
+ $* <<EOI 2>'stdin:4:1: error: no result request agent checksum specified' == 1
+ : 1
+ session: abc
+ challenge: YQo=
+ EOI
+
: result
:
- $* <<EOI 2>'stdin:4:1: error: result manifest expected' == 1
+ $* <<EOI 2>'stdin:5:1: error: result manifest expected' == 1
: 1
session: abc
challenge: YQo=
+ agent-checksum: 1
EOI
}
diff --git a/tests/manifest/result.testscript b/tests/manifest/result.testscript
index c530170..b48a691 100644
--- a/tests/manifest/result.testscript
+++ b/tests/manifest/result.testscript
@@ -18,18 +18,20 @@ test.options += -r
configure-status: success
update-status: warning
test-status: error
- configure-log: \
+ configure-log:\
conf line 1
conf line 2
\
- update-log: \
+ update-log:\
update line 1
update line 2
\
- test-log: \
+ test-log:\
test line 1
test line 2
\
+ worker-checksum: 1
+ dependency-checksum: 12345
EOF
: update-error
@@ -41,14 +43,16 @@ test.options += -r
status: error
configure-status: warning
update-status: error
- configure-log: \
+ configure-log:\
conf line 1
conf line 2
\
- update-log: \
+ update-log:\
update line 1
update line 2
\
+ worker-checksum: 1
+ dependency-checksum: 12345
EOF
: early-abort
@@ -106,12 +110,20 @@ test.options += -r
configure-log: configured
configure-log: configured
EOI
+
+ : worker-checksum
+ :
+ $* <<EOI 2>'stdin:3:1: error: result worker checksum redefinition' == 1
+ : 1
+ worker-checksum: 1
+ worker-checksum: 1
+ EOI
}
: invalid
:
{
- : name-empty
+ : empty-name
:
$* <<EOI 2>'stdin:2:6: error: invalid result package name: length is less than two characters' == 1
: 1
@@ -181,6 +193,13 @@ test.options += -r
update-log: log
EOI
}
+
+ : empty-worker-checksum
+ :
+ $* <<EOI 2>'stdin:2:17: error: empty result worker checksum' == 1
+ : 1
+ worker-checksum:
+ EOI
}
: unknown-name
diff --git a/tests/manifest/task-request.testscript b/tests/manifest/task-request.testscript
index 4b797f6..79f3982 100644
--- a/tests/manifest/task-request.testscript
+++ b/tests/manifest/task-request.testscript
@@ -15,7 +15,10 @@ test.options += -tq
agent: upsa
toolchain-name: queue
toolchain-version: 0.5.0
+ interactive-mode: both
+ interactive-login: 10.5.0.1:5901
fingerprint: 1105fb394ee870adb154b7abfbbae5755df7dcef6c81db34e8d1b68d2653734e
+ auxiliary-ram: 41943040
:
id: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
name: windows_10-msvc_14
@@ -70,6 +73,14 @@ test.options += -tq
fingerprint: 1105fb394ee870adb154b7abfbbae5755df7dcef6c81db34e8d1b68d2653734e
fingerprint: 1105fb394ee870adb154b7abfbbae5755df7dcef6c81db34e8d1b68d2653734e
EOI
+
+ : auxiliary-ram
+ :
+ $* <<EOI 2>'stdin:3:1: error: auxiliary machines RAM limit redefinition' == 1
+ : 1
+ auxiliary-ram: 41943040
+ auxiliary-ram: 41943040
+ EOI
}
: empty
@@ -88,6 +99,13 @@ test.options += -tq
: 1
toolchain-name:
EOI
+
+ : auxiliary-ram
+ :
+ $* <<EOI 2>'stdin:2:15: error: auxiliary machines RAM limit should be 64-bit unsigned integer' == 1
+ : 1
+ auxiliary-ram:
+ EOI
}
: invalid-toolchain-version
@@ -124,3 +142,65 @@ toolchain-name: queue
toolchain-version: 0.5.0
fingerprint: 1105fb394ee870adb154b7abfbbae5755df7dcef6c81db34e8d1b68d2653734e
EOI
+
+: interactive
+:
+{
+ : redefinition
+ :
+ {
+ : mode
+ :
+ $* <<EOI 2>'stdin:3:1: error: task request interactive mode redefinition' == 1
+ : 1
+ interactive-mode: true
+ interactive-mode: both
+ EOI
+
+ : login
+ :
+ $* <<EOI 2>'stdin:3:1: error: task request interactive login redefinition' == 1
+ : 1
+ interactive-login: 10.5.0.1:5901
+ interactive-login: 10.5.0.1:5901
+ EOI
+ }
+
+ : invalid
+ :
+ {
+ : mode
+ :
+ $* <<EOI 2>"stdin:2:19: error: invalid task request interactive mode 'on'" == 1
+ : 1
+ interactive-mode: on
+ EOI
+
+ : login
+ :
+ $* <<EOI 2>'stdin:2:19: error: empty task request interactive login' == 1
+ : 1
+ interactive-login:
+ EOI
+ }
+
+ : no-login
+ :
+ $* <<EOI 2>'stdin:6:1: error: no task request interactive login specified' == 1
+ : 1
+ agent: upsa
+ toolchain-name: queue
+ toolchain-version: 0.5.0
+ interactive-mode: both
+ EOI
+
+ : unexpected-login
+ :
+ $* <<EOI 2>'stdin:5:1: error: interactive login specified for non-interactive mode' == 1
+ : 1
+ agent: upsa
+ toolchain-name: queue
+ toolchain-version: 0.5.0
+ interactive-login: 10.5.0.1:5901
+ EOI
+}
diff --git a/tests/manifest/task-response.testscript b/tests/manifest/task-response.testscript
index e7dbdb9..7615127 100644
--- a/tests/manifest/task-response.testscript
+++ b/tests/manifest/task-response.testscript
@@ -18,6 +18,8 @@ test.options += -ts
session: abcd
challenge: cc6585375ef81898cc60791b11852e3d2ed9ebb82ebb0874010fe0e6f9ebdb73
result-url: https://cppget.org/?build-result
+ bindist-upload-url: https://cppget.org/?upload=bindist
+ agent-checksum: 1
:
name: libfoo
version: 1.0
@@ -26,7 +28,7 @@ test.options += -ts
target: x86_64-microsoft-win32-msvc14.0
EOF
- : no-challenge
+ : no-optional
:
$* <<EOF >>EOF
: 1
@@ -75,6 +77,23 @@ test.options += -ts
result-url: https://cppget.org/?build-result
result-url: https://cppget.org/?build-result
EOI
+
+ : upload-url
+ :
+ $* <<EOI 2>'stdin:4:1: error: task response upload url redefinition' == 1
+ : 1
+ bindist-upload-url: https://cppget.org/?upload=bindist
+ other-upload-url: https://cppget.org/?upload=other
+ bindist-upload-url: https://cppget.org/?upload=bindist
+ EOI
+
+ : agent-checksum
+ :
+ $* <<EOI 2>'stdin:3:1: error: task response agent checksum redefinition' == 1
+ : 1
+ agent-checksum: 1
+ agent-checksum: 1
+ EOI
}
: invalid
@@ -118,6 +137,44 @@ test.options += -ts
EOI
}
+ : upload-url
+ :
+ {
+ : empty
+ :
+ $* <<EOI 2>'stdin:2:20: error: empty task response upload url' == 1
+ : 1
+ bindist-upload-url:
+ EOI
+
+ : redundant
+ :
+ $* <<EOI 2>'stdin:4:1: error: unexpected task response upload url' == 1
+ : 1
+ session:
+ bindist-upload-url: https://cppget.org/?upload=bindist
+ EOI
+ }
+
+ : agent-checksum
+ :
+ {
+ : empty
+ :
+ $* <<EOI 2>'stdin:2:16: error: empty task response agent checksum' == 1
+ : 1
+ agent-checksum:
+ EOI
+
+ : redundant
+ :
+ $* <<EOI 2>'stdin:4:1: error: unexpected task response agent checksum' == 1
+ : 1
+ session:
+ agent-checksum: 1
+ EOI
+ }
+
: task-unexpected
:
$* <<EOI 2>'stdin:3:1: error: single task response manifest expected' == 1
diff --git a/tests/manifest/task.testscript b/tests/manifest/task.testscript
index 65ecd29..8320f59 100644
--- a/tests/manifest/task.testscript
+++ b/tests/manifest/task.testscript
@@ -12,18 +12,53 @@ test.options += -t
:
$* <<EOF >>EOF
: 1
- name: libfoo
+ name: foo
+ version: 1.0
+ repository-url: http://pkg.example.org/1/math
+ trust: AB:0D:3F:C1:B0:13:E4:0E:AD:4A:08:06:AE:F3:85:DB:E2:27:5F:83:11:47:A2:7\
+ 8:64:3C:73:60:F8:66:3A:A4
+ requires: host
+ tests: foo-tests
+ examples: foo-examples
+ dependency-checksum: 12345
+ machine: windows_10-msvc_14
+ auxiliary-machine-pgsql: x86_64-linux_debian_12-postgresql_16
+ auxiliary-machine: x86_64-linux_debian_12-mysql*
+ target: x86_64-microsoft-win32-msvc14.0
+ environment: lld
+ auxiliary-environment:\
+ PGSQL_DATABASE_HOST=192.168.0.1
+ PGSQL_DATABASE_PORT=1245
+ \
+ target-config: config.cc.coptions=/Z7 config.cc.loptions=/DEBUG
+ package-config: config.foo.network=true
+ warning-regex: '^warning: ' '^.+: warning: '
+ interactive: error
+ worker-checksum: 1
+ EOF
+
+ # @@ TMP Remove when toolchain 0.16.0 is released.
+ #
+ : no-package-config
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: foo
version: 1.0
repository-url: http://pkg.example.org/1/math
trust: AB:0D:3F:C1:B0:13:E4:0E:AD:4A:08:06:AE:F3:85:DB:E2:27:5F:83:11:47:A2:7\
8:64:3C:73:60:F8:66:3A:A4
- test-exclude: libfoo-tests/1.0
- test-exclude: libfoo-examples/1.0
+ requires: host
+ tests: foo-tests
+ examples: foo-examples
+ dependency-checksum: 12345
machine: windows_10-msvc_14
target: x86_64-microsoft-win32-msvc14.0
environment: lld
config: config.cc.coptions=/Z7 config.cc.loptions=/DEBUG
warning-regex: '^warning: ' '^.+: warning: '
+ interactive: error
+ worker-checksum: 1
EOF
: no-config-regex-environment
@@ -67,6 +102,53 @@ test.options += -t
target: x86_64-microsoft-win32-msvc14.0
EOO
+ : requires
+ :
+ {
+ $* <<EOF >>EOF
+ : 1
+ name: foo
+ version: 1.0
+ repository-url: http://pkg.example.org/1/math
+ requires: {c++ >= 14 windows}
+ requires: host
+ machine: windows
+ target: x86_64-microsoft-win32-msvc14.0
+ EOF
+ }
+
+ : requires-invalid
+ :
+ {
+ $* <<EOI 2>>EOE != 0
+ : 1
+ name: foo
+ version: 1.0
+ repository-url: http://pkg.example.org/1/math
+ requires: {c++ >= 14 windows
+ machine: windows
+ target: x86_64-microsoft-win32-msvc14.0
+ EOI
+ stdin:5:29: error: requirement or '}' expected
+ EOE
+ }
+
+ : tests
+ :
+ {
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 1.0
+ repository-url: http://pkg.example.org/1/math
+ tests: libfoo-tests
+ examples: libfoo-examples == 1.2.3
+ benchmarks: libfoo-benchmarks ~1.2.0
+ machine: windows
+ target: x86_64-microsoft-win32-msvc14.0
+ EOF
+ }
+
: config
:
{
@@ -95,6 +177,34 @@ test.options += -t
EOF
}
+ : host
+ :
+ {
+ : true
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 1.0
+ repository-url: http://pkg.example.org/1/math
+ machine: windows
+ target: x86_64-microsoft-win32-msvc14.0
+ host: true
+ EOF
+
+ : false
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 1.0
+ repository-url: http://pkg.example.org/1/math
+ machine: windows
+ target: x86_64-microsoft-win32-msvc14.0
+ host: false
+ EOF
+ }
+
: trust-yes
:
$* <<EOF >>EOF
@@ -144,6 +254,14 @@ test.options += -t
machine: windows_10-msvc_14
EOI
+ : auxiliary-machine
+ :
+ $* <<EOI 2>'stdin:3:1: error: task auxiliary machine environment redefinition' == 1
+ : 1
+ auxiliary-machine-pgsql: x86_64-linux_debian_12-postgresql_16
+ auxiliary-machine-pgsql: x86_64-linux_debian_12-postgresql_14
+ EOI
+
: target
:
$* <<EOI 2>'stdin:3:1: error: task target redefinition' == 1
@@ -152,14 +270,38 @@ test.options += -t
target: x86_64-microsoft-win32-msvc14.0
EOI
+ : auxiliary-environment
+ :
+ $* <<EOI 2>'stdin:7:1: error: task auxiliary environment redefinition' == 1
+ : 1
+ auxiliary-environment:
+ \
+ PGSQL_DATABASE_HOST=192.168.0.1
+ PGSQL_DATABASE_PORT=1245
+ \
+ auxiliary-environment:
+ \
+ PGSQL_DATABASE_HOST=192.168.0.1
+ PGSQL_DATABASE_PORT=1245
+ \
+ EOI
+
: config
:
- $* <<EOI 2>'stdin:3:1: error: task configuration redefinition' == 1
+ $* <<EOI 2>'stdin:3:1: error: task target configuration redefinition' == 1
: 1
config: config.cc.coptions=/Z7
config: config.cc.loptions=/DEBUG
EOI
+ : host
+ :
+ $* <<EOI 2>'stdin:3:1: error: task host value redefinition' == 1
+ : 1
+ host: true
+ host: false
+ EOI
+
: warning-regex
:
$* <<EOI 2>'stdin:3:1: error: task warning regex redefinition' == 1
@@ -167,6 +309,22 @@ test.options += -t
warning-regex: '^warning: '
warning-regex: '^.+: warning: '
EOI
+
+ : interactive
+ :
+ $* <<EOI 2>'stdin:3:1: error: task interactive value redefinition' == 1
+ : 1
+ interactive: error
+ interactive: warning
+ EOI
+
+ : worker-checksum
+ :
+ $* <<EOI 2>'stdin:3:1: error: task worker checksum redefinition' == 1
+ : 1
+ worker-checksum: 1
+ worker-checksum: 1
+ EOI
}
: invalid
@@ -224,37 +382,6 @@ test.options += -t
EOE
}
- : test-exclude
- :
- {
- : invalid-name
- :
- $* <<EOI 2>>EOE == 1
- : 1
- test-exclude: 0ibfoo-tests/1.0
- EOI
- stdin:2:15: error: invalid test exclusion package name: illegal first character (must be alphabetic)
- EOE
-
- : no-version
- :
- $* <<EOI 2>>EOE == 1
- : 1
- test-exclude: libfoo-tests
- EOI
- stdin:2:15: error: invalid test exclusion package: '/' is expected
- EOE
-
- : invalid-version
- :
- $* <<EOI 2>>EOE == 1
- : 1
- test-exclude: libfoo-tests/+1
- EOI
- stdin:2:15: error: invalid test exclusion package version: unexpected end
- EOE
- }
-
: machine-empty
:
$* <<EOI 2>'stdin:2:9: error: empty task machine' == 1
@@ -269,12 +396,12 @@ test.options += -t
target:
EOI
- : config
+ : target-config
:
{
: empty
:
- $* <<EOI 2>'stdin:2:8: error: empty task configuration' == 1
+ $* <<EOI 2>'stdin:2:8: error: empty task target configuration' == 1
: 1
config:
EOI
@@ -293,13 +420,20 @@ test.options += -t
:
$* <<EOI 2>'stdin:3:7: error: invalid task configuration: unterminated quoted string' == 1
: 1
- config: \
+ config:\
'abc=x
\
EOI
}
}
+ : host
+ :
+ $* <<EOI 2>"stdin:2:7: error: invalid task host value 'yes'" == 1
+ : 1
+ host: yes
+ EOI
+
: warning-regex
:
{
@@ -326,6 +460,20 @@ test.options += -t
: 1
trust: abc
EOI
+
+ : interactive
+ :
+ $* <<EOI 2>'stdin:2:13: error: empty task interactive value' == 1
+ : 1
+ interactive:
+ EOI
+
+ : worker-checksum
+ :
+ $* <<EOI 2>'stdin:2:17: error: empty task worker checksum' == 1
+ : 1
+ worker-checksum:
+ EOI
}
: unknown-name