diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/ctor.cc | 14 | ||||
-rw-r--r-- | test/execute_test.cc | 65 | ||||
-rw-r--r-- | test/testprog.cc | 49 | ||||
-rw-r--r-- | test/tmpfile.h | 48 |
4 files changed, 171 insertions, 5 deletions
diff --git a/test/ctor.cc b/test/ctor.cc index 3649a10..ea5ae1e 100644 --- a/test/ctor.cc +++ b/test/ctor.cc @@ -11,12 +11,26 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) { { .type = ctor::target_type::unit_test, + .target = "testprog", + .sources = { + "testprog.cc", + }, + .flags = { + .cxxflags = { + "-std=c++20", "-O3", "-Wall", "-Werror", + }, + }, + }, + { + .type = ctor::target_type::unit_test, .target = "execute_test", .sources = { "execute_test.cc", "testmain.cc", "../src/execute.cc", + "../src/util.cc", }, + .depends = { "testprog", }, .flags = { .cxxflags = { "-std=c++20", "-O3", "-Wall", "-Werror", diff --git a/test/execute_test.cc b/test/execute_test.cc index 9da18dc..03b3c2a 100644 --- a/test/execute_test.cc +++ b/test/execute_test.cc @@ -1,6 +1,14 @@ #include <uunit.h> +#include <fstream> +#include <map> +#include <set> + #include <execute.h> +#include <util.h> + +#include "paths.h" +#include "tmpfile.h" class ExecuteTest : public uUnit @@ -8,14 +16,61 @@ class ExecuteTest public: ExecuteTest() { - uTEST(ExecuteTest::runit); + uTEST(ExecuteTest::return_value); + uTEST(ExecuteTest::env); + } + + void return_value() + { + auto cur_path = std::filesystem::path(paths::argv_0).parent_path(); + std::vector<std::string> paths{{cur_path.string()}}; + auto cmd = locate("testprog", paths); + uASSERT(!cmd.empty()); + + uASSERT_EQUAL(0, execute(cmd, {"retval", "0"}, {}, false)); + uASSERT_EQUAL(1, execute(cmd, {"retval", "1"}, {}, false)); + uASSERT_EQUAL(1, execute("no-such-binary", {}, {}, false)); } - void runit() + void env() { - uASSERT_EQUAL(0, execute("/bin/true", {}, false)); - uASSERT_EQUAL(1, execute("/bin/false", {}, false)); - uASSERT_EQUAL(1, execute("no-such-binary", {}, false)); + auto cur_path = std::filesystem::path(paths::argv_0).parent_path(); + std::vector<std::string> paths{{cur_path.string()}}; + auto cmd = locate("testprog", paths); + uASSERT(!cmd.empty()); + + tmp_file tmp; + + std::map<std::string, std::string> env; + + // New env vars + env["foo"] = "bar"; + env["bar"] = "42"; + + // Overwrite the exiting LANG var + env["LANG"] = "foo"; + + uASSERT_EQUAL(0, execute(cmd, {"envdump", tmp.get()}, env, false)); + + std::set<std::string> vars; + { + std::ifstream infile(tmp.get()); + std::string line; + while (std::getline(infile, line)) + { + vars.insert(line); + } + } + + // Check the two explicitly set vars + uASSERT(vars.find("foo=bar") != vars.end()); + uASSERT(vars.find("bar=42") != vars.end()); + + // Check the one that should have overwritten the existing one (probably LANG=en_US.UTF-8 or something) + uASSERT(vars.find("LANG=foo") != vars.end()); + + // Check that other vars are also there (ie. the env wasn't cleared on entry) + uASSERT(vars.size() > 3); } }; diff --git a/test/testprog.cc b/test/testprog.cc new file mode 100644 index 0000000..dbfb665 --- /dev/null +++ b/test/testprog.cc @@ -0,0 +1,49 @@ +#include <iostream> +#include <fstream> +#include <string> + +extern const char **environ; // see 'man environ' + +int main(int argc, const char* argv[]) +{ + if(argc < 2) + { + return 0; + } + + std::string cmd = argv[1]; + + if(cmd == "envdump") + { + if(argc < 3) + { + return 0; + } + std::ofstream ostrm(argv[2], std::ios::binary); + for(auto current = environ; *current; ++current) + { + ostrm << (*current) << "\n"; + } + } + + if(cmd == "retval") + { + if(argc < 3) + { + return 0; + } + return std::stoi(argv[2]); + } + + if(cmd == "abort") + { + abort(); + } + + if(cmd == "throw") + { + throw "ouch"; + } + + return 0; +} diff --git a/test/tmpfile.h b/test/tmpfile.h new file mode 100644 index 0000000..5d114d0 --- /dev/null +++ b/test/tmpfile.h @@ -0,0 +1,48 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#pragma once + +#include <cstdlib> +#include <unistd.h> + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#endif + +struct tmp_file +{ + tmp_file(const std::string& data = {}) + { + int fd; +#ifdef _WIN32 + char templ[] = "ctor_tmp_file-XXXXXX"; // buffer for filename + _mktemp_s(templ, sizeof(templ)); + fd = open(templ, O_CREAT | O_RDWR); +#else + char templ[] = "/tmp/ctor_tmp_file-XXXXXX"; // buffer for filename + fd = mkstemp(templ); +#endif + filename = templ; + auto sz = write(fd, data.data(), data.size()); + (void)sz; + close(fd); + } + + ~tmp_file() + { + unlink(filename.data()); + } + + const std::string& get() const + { + return filename; + } + +private: + std::string filename; +}; |