summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/ctor.cc14
-rw-r--r--test/execute_test.cc65
-rw-r--r--test/testprog.cc49
-rw-r--r--test/tmpfile.h48
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;
+};