From 64e2a788645a8a5b30d82265ba8aa4fee88cca21 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 26 Jan 2023 09:17:07 +0200 Subject: More work on testing Debian implementation --- bpkg/system-package-manager-debian.test.cxx | 232 ++++++++++++++++++++++++++-- bpkg/utility.hxx | 2 + 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 #include +#include #include #undef NDEBUG @@ -22,13 +23,38 @@ namespace bpkg // // Where is one of: // - // apt-cache-policy ... result comes from stdin + // apt-cache-policy ... result comes from stdin // - // apt-cache-show result comes from stdin + // apt-cache-show 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 depends comes from stdin + // main-from-dev depends comes from stdin + // + // build ... [--install [--no-fetch] ...] + // + // 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: + // + // Available package manifest for one of . If none is + // specified, then a stub is automatically added. + // + // apt-cache-policy[-{fetched,installed}]: ... + // + // Values for simulation::apt_cache_policy_*. If is the special `!` + // value, then make the entry empty. + // + // apt-cache-show[-fetched]: + // + // Values for simulation::apt_cache_show_*. If 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); // ... @@ -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 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); // ... + + strings qps; + map aps; + + // Parse ... + // + 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* 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, 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 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& 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); // ... + + vector 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; + // // using butl::process_start_callback; -- cgit v1.1