aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-01-26 09:17:07 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-01-26 09:17:07 +0200
commit64e2a788645a8a5b30d82265ba8aa4fee88cca21 (patch)
tree346daad50b9f6b85781445d08aabf781ed410cf6
parent80f8b0d7653a9445c74aaf67d2ad87b8ebf7503a (diff)
More work on testing Debian implementation
-rw-r--r--bpkg/system-package-manager-debian.test.cxx232
-rw-r--r--bpkg/utility.hxx2
2 files changed, 218 insertions, 16 deletions
diff --git a/bpkg/system-package-manager-debian.test.cxx b/bpkg/system-package-manager-debian.test.cxx
index b44fdc1..a1cdbe3 100644
--- a/bpkg/system-package-manager-debian.test.cxx
+++ b/bpkg/system-package-manager-debian.test.cxx
@@ -6,6 +6,7 @@
#include <bpkg/types.hxx>
#include <bpkg/utility.hxx>
+#include <map>
#include <iostream>
#undef NDEBUG
@@ -22,13 +23,38 @@ namespace bpkg
//
// Where <command> is one of:
//
- // apt-cache-policy <pkg>... result comes from stdin
+ // apt-cache-policy <pkg>... result comes from stdin
//
- // apt-cache-show <pkg> <ver> result comes from stdin
+ // apt-cache-show <pkg> <ver> result comes from stdin
//
- // parse_name_value debian-name value from from stdin
+ // parse_name_value debian-name value from from stdin
//
- // main-from-dev <dev-pkg> <dev-ver> depends comes from stdin
+ // main-from-dev <dev-pkg> <dev-ver> depends comes from stdin
+ //
+ // build <query-pkg>... [--install [--no-fetch] <install-pkg>...]
+ //
+ // The stdin of the build command is used to read the simulation description
+ // which consists of lines in the following forms (blanks are ignored):
+ //
+ // manifest: <query-pkg> <file>
+ //
+ // Available package manifest for one of <query-pkg>. If none is
+ // specified, then a stub is automatically added.
+ //
+ // apt-cache-policy[-{fetched,installed}]: <sys-pkg>... <file>
+ //
+ // Values for simulation::apt_cache_policy_*. If <file> is the special `!`
+ // value, then make the entry empty.
+ //
+ // apt-cache-show[-fetched]: <sys-pkg> <sys-ver> <file>
+ //
+ // Values for simulation::apt_cache_show_*. If <file> is the special `!`
+ // value, then make the entry empty.
+ //
+ // apt-get-update-fail: true
+ // apt-get-install-fail: true
+ //
+ // Values for simulation::apt_get_{update,install}_fail_.
//
int
main (int argc, char* argv[])
@@ -38,19 +64,10 @@ namespace bpkg
string cmd (argv[1]);
- // @@ TODO: add option to customize.
+ // @@ TODO: add option to customize? Maybe option before command?
//
os_release osr {"debian", {}, "10", "", "Debian", "", ""};
- system_package_manager_debian::simulation s;
- system_package_manager_debian m (move (osr),
- false /* install */,
- false /* fetch */,
- nullopt /* progress */,
- false /* yes */,
- "sudo");
- m.simulate_ = &s;
-
if (cmd == "apt-cache-policy")
{
assert (argc >= 3); // <pkg>...
@@ -63,8 +80,17 @@ namespace bpkg
pps.push_back (package_policy (argv[i]));
}
+ system_package_manager_debian::simulation s;
s.apt_cache_policy_.emplace (move (key), path ("-"));
+ system_package_manager_debian m (move (osr),
+ false /* install */,
+ false /* fetch */,
+ nullopt /* progress */,
+ false /* yes */,
+ "sudo");
+ m.simulate_ = &s;
+
m.apt_cache_policy (pps);
for (const package_policy& pp: pps)
@@ -80,8 +106,17 @@ namespace bpkg
pair<string, string> key (argv[2], argv[3]);
+ system_package_manager_debian::simulation s;
s.apt_cache_show_.emplace (key, path ("-"));
+ system_package_manager_debian m (move (osr),
+ false /* install */,
+ false /* fetch */,
+ nullopt /* progress */,
+ false /* yes */,
+ "sudo");
+ m.simulate_ = &s;
+
cout << m.apt_cache_show (key.first, key.second) << '\n';
}
else if (cmd == "parse-name-value")
@@ -91,7 +126,8 @@ namespace bpkg
string v;
getline (cin, v);
- package_status s (m.parse_name_value (v, false, false));
+ package_status s (
+ system_package_manager_debian::parse_name_value (v, false, false));
if (!s.main.empty ()) cout << "main: " << s.main << '\n';
if (!s.dev.empty ()) cout << "dev: " << s.dev << '\n';
@@ -115,7 +151,171 @@ namespace bpkg
string d;
getline (cin, d);
- cout << m.main_from_dev (n, v, d) << '\n';
+ cout << system_package_manager_debian::main_from_dev (n, v, d) << '\n';
+ }
+ else if (cmd == "build")
+ {
+ assert (argc >= 3); // <query-pkg>...
+
+ strings qps;
+ map<string, available_packages> aps;
+
+ // Parse <query-pkg>...
+ //
+ int argi (2);
+ for (; argi != argc; ++argi)
+ {
+ string a (argv[argi]);
+
+ if (a.compare (0, 2, "--") == 0)
+ break;
+
+ aps.emplace (a, available_packages {});
+ qps.push_back (move (a));
+ }
+
+ // Parse --install [--no-fetch]
+ //
+ bool install (false);
+ bool fetch (true);
+
+ for (; argi != argc; ++argi)
+ {
+ string a (argv[argi]);
+
+ if (a == "--install") install = true;
+ else if (a == "--no-fetch") fetch = false;
+ else break;
+ }
+
+ // Parse the description.
+ //
+ system_package_manager_debian::simulation s;
+
+ for (string l; !eof (getline (cin, l)); )
+ {
+ if (l.empty ())
+ continue;
+
+ size_t p (l.find (':')); assert (p != string::npos);
+ string k (l, 0, p);
+
+ if (k == "manifest")
+ {
+ size_t q (l.rfind (' ')); assert (q != string::npos);
+ string n (l, p + 2, q - p - 2); trim (n);
+ string f (l, q + 1); trim (f);
+
+ auto i (aps.find (n));
+ if (i == aps.end ())
+ fail << "unknown package " << n << " in '" << l << "'";
+
+ // @@ TODO: parse manifest and make available package out of it.
+ }
+ else if (
+ map<strings, path>* policy =
+ k == "apt-cache-policy" ? &s.apt_cache_policy_ :
+ k == "apt-cache-policy-fetched" ? &s.apt_cache_policy_fetched_ :
+ k == "apt-cache-policy-installed" ? &s.apt_cache_policy_installed_ :
+ nullptr)
+ {
+ size_t q (l.rfind (' ')); assert (q != string::npos);
+ string n (l, p + 2, q - p - 2); trim (n);
+ string f (l, q + 1); trim (f);
+
+ strings ns;
+ for (size_t b (0), e (0); next_word (n, b, e); )
+ ns.push_back (string (n, b, e - b));
+
+ if (f == "!")
+ f.clear ();
+
+ policy->emplace (move (ns), path (move (f)));
+ }
+ else if (map<pair<string, string>, path>* show =
+ k == "apt-cache-show" ? &s.apt_cache_show_ :
+ k == "apt-cache-show-fetched" ? &s.apt_cache_show_fetched_ :
+ nullptr)
+ {
+ size_t q (l.rfind (' ')); assert (q != string::npos);
+ string n (l, p + 2, q - p - 2); trim (n);
+ string f (l, q + 1); trim (f);
+
+ q = n.find (' '); assert (q != string::npos);
+ pair<string, string> nv (string (n, 0, q), string (n, q + 1));
+ trim (nv.second);
+
+ if (f == "!")
+ f.clear ();
+
+ show->emplace (move (nv), path (move (f)));
+ }
+ else if (k == "apt-get-update-fail")
+ {
+ s.apt_get_update_fail_ = true;
+ }
+ else if (k == "apt-get-install-fail")
+ {
+ s.apt_get_install_fail_ = true;
+ }
+ else
+ fail << "unknown keyword '" << k << "' in simulation description";
+ }
+
+ // Fallback to stubs.
+ //
+ for (pair<const string, available_packages>& p: aps)
+ {
+ if (p.second.empty ())
+ {
+ // @@ TODO: add stub available package.
+ }
+ }
+
+ system_package_manager_debian m (move (osr),
+ install,
+ fetch,
+ nullopt /* progress */,
+ false /* yes */,
+ "sudo");
+ m.simulate_ = &s;
+
+ // Query each package.
+ //
+ for (const string& n: qps)
+ {
+ package_name pn (n);
+
+ const system_package_status* s (*m.pkg_status (pn, &aps[n]));
+
+ if (s == nullptr)
+ fail << "no system package for " << pn;
+
+ cout << pn << ' ' << s->version
+ << " (" << s->system_name << ' ' << s->system_version << ") ";
+
+ switch (s->status)
+ {
+ case package_status::installed: cout << "installed"; break;
+ case package_status::partially_installed: cout << "part installed"; break;
+ case package_status::not_installed: cout << "not installed"; break;
+ }
+
+ cout << '\n';
+ }
+
+ // Install if requested.
+ //
+ if (install)
+ {
+ assert (argi != argc); // <install-pkg>...
+
+ vector<package_name> ips;
+ for (; argi != argc; ++argi)
+ ips.push_back (package_name (argv[argi]));
+
+ m.pkg_install (ips);
+ }
}
else
fail << "unknown command '" << cmd << "'";
diff --git a/bpkg/utility.hxx b/bpkg/utility.hxx
index 896a67b..69a02d3 100644
--- a/bpkg/utility.hxx
+++ b/bpkg/utility.hxx
@@ -61,6 +61,8 @@ namespace bpkg
using butl::setenv;
using butl::unsetenv;
+ using butl::eof;
+
// <libbutl/process.hxx>
//
using butl::process_start_callback;