diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2025-12-28 21:48:09 +0100 |
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2025-12-28 23:57:19 +0100 |
| commit | 7ef83fab5d9515db2aa302f00844acd2703b5765 (patch) | |
| tree | 2c93620dc80aa654ed7d5979fe35af86894aef20 /test | |
| parent | 3294ff2f9b7aa92b6dccc653c590ce27fa434f8c (diff) | |
WIPsuite_on_cpp
Diffstat (limited to 'test')
| -rw-r--r-- | test/suite/ctor_files/ctor.cc.generated | 48 | ||||
| -rw-r--r-- | test/suite/test.cc | 425 |
2 files changed, 473 insertions, 0 deletions
diff --git a/test/suite/ctor_files/ctor.cc.generated b/test/suite/ctor_files/ctor.cc.generated new file mode 100644 index 0000000..5f82fd4 --- /dev/null +++ b/test/suite/ctor_files/ctor.cc.generated @@ -0,0 +1,48 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#include <ctor.h> +#include <filesystem> +#include <iostream> + +namespace +{ +ctor::build_configurations ctorConfigs(const ctor::settings& settings) +{ + return + { + { + .target = "world", + .sources = { + { "world.cc", ctor::source_type::generated }, + }, + }, + { + .target = "foo", + .sources = { + { "foo.cc", ctor::source_type::generated }, + }, + }, + { + .target = "this_is_unused", + .sources = { + {"hello.cc", ctor::output_file{"world.cc"}}, + {"hello.cc", ctor::output_file{"foo.cc"}}, + }, + .function = [](const std::string& input, + const std::string& output, + const ctor::build_configuration& config, + const ctor::settings& settings) + { + namespace fs = std::filesystem; + std::cout << "Input: " << input << '\n'; + std::cout << "Output: " << output << '\n'; + fs::copy_file(input, output, fs::copy_options::overwrite_existing); + return 0; + } + }, + }; +} +} + +REG(ctorConfigs); diff --git a/test/suite/test.cc b/test/suite/test.cc new file mode 100644 index 0000000..ff9ecd6 --- /dev/null +++ b/test/suite/test.cc @@ -0,0 +1,425 @@ +#include "../../src/util.cc" +#include "../../src/pointerlist.cc" +#include "../../src/execute.cc" + +#include <iostream> +#include <string> +#include <filesystem> +#include <thread> +#include <chrono> +#include <sstream> + +//function fail +//{ +// echo "*** Failure at line $1" +// exit 1 +//} +// +//function ctor +//{ +// echo "*** Running: ./ctor $*" +// ./ctor $* +//} + +std::vector<std::string> tokenize(const std::string& str) +{ + std::vector<std::string> tokens; + std::stringstream ss(str); + std::string token; + while(getline(ss, token, ' ')) + { + tokens.push_back(token); + } + return tokens; +} + +int fail(int value = 1, + const std::source_location location = std::source_location::current()) +{ + std::cout << "*** Failure at line " << location.line() << '\n'; + return value; +} + +int main() +{ + using namespace std::chrono_literals; + ctor::settings settings{}; + settings.verbose = 2; + auto paths = get_paths(); + + //: ${CXX:=g++} + std::string CXX = "g++"; + get_env("CXX", CXX); + //: ${CTORDIR:=../../build} + std::string CTORDIR = "../../build"; + get_env("CTORDIR", CTORDIR); + //: ${BUILDDIR:=build} + std::string BUILDDIR = "build"; + get_env("BUILDDIR", BUILDDIR); + + std::string CXXFLAGS; + get_env("CXXFLAGS", CXXFLAGS); + + std::string LDFLAGS; + get_env("LDFLAGS", LDFLAGS); + + // + //CXX=$(which $CXX) + auto cxx_prog = locate(CXX, paths); + // + // + //STAT_FORMAT="-c %Y" + //if [[ "$OSTYPE" == "darwin"* ]]; then + // # Mac OSX + // STAT_FORMAT="-f %B" + //fi + // + //# Wipe the board + //rm -Rf ${BUILDDIR} + std::filesystem::remove_all(BUILDDIR); + //rm -f configuration.cc + std::filesystem::remove("configuration.cc"); + std::filesystem::remove("config.h"); + //rm -f ctor + std::filesystem::remove("ctor"); + + // + //echo "** ctor_files/ctor.cc.base" + std::cout << "** ctor_files/ctor.cc.base\n"; + //cp ctor_files/ctor.cc.base ctor.cc + std::filesystem::copy("ctor_files/ctor.cc.base", "ctor.cc", + std::filesystem::copy_options::overwrite_existing); + // + //# Compile bootstrap binary + //$CXX -pthread $LDFLAGS $CXXFLAGS -std=c++20 -L${CTORDIR} -lctor -I../../src ctor.cc -o ctor || fail ${LINENO} + std::vector<std::string> args = + {"-pthread", "-std=c++20", "-L", CTORDIR, "-lctor", "-I", "../../src", + "ctor.cc", "-o", "ctor"}; + + // TODO: + if(!CXXFLAGS.empty()) + { + auto tokens = tokenize(CXXFLAGS); + for(const auto& token : tokens) + { + args.push_back(token); + } + } + if(!LDFLAGS.empty()) + { + auto tokens = tokenize(LDFLAGS); + for(const auto& token : tokens) + { + args.push_back(token); + } + } + + auto ret = execute(settings, cxx_prog, args); + if(ret != 0) + { + return fail(ret); + } + // + //# No build files should have been created yet + //[ -d ${BUILDDIR} ] && fail ${LINENO} + if(std::filesystem::exists(BUILDDIR)) + { + return fail(); + } + // + //# capture md5 sum of ctor binary before configure is called + //MD5=`md5sum ctor` + auto ctor_bin = readFile("ctor"); + //ctor configure --ctor-includedir ../../src --ctor-libdir=${CTORDIR} --build-dir=${BUILDDIR} + args = {"configure", "--ctor-includedir", "../../src", + "--ctor-libdir="+CTORDIR, "--build-dir="+BUILDDIR}; + ret = execute(settings, "./ctor", args); + if(ret != 0) + { + return fail(ret); + } + // + //# ctor should be rebuilt at this point, so md5 sum should have changed + //(echo $MD5 | md5sum --status -c) && fail ${LINENO} + auto ctor_bin2 = readFile("ctor"); + if(ctor_bin == ctor_bin2) + { + return fail(); + } + + // + //# configuration.cc should have been generated now + //[ ! -f configuration.cc ] && fail ${LINENO} + if(!std::filesystem::exists("configuration.cc")) + { + return fail(); + } + if(!std::filesystem::exists("config.h")) + { + return fail(); + } + + // + //# Shouldn't compile anything yet - only configure + //[ -f ${BUILDDIR}/hello-hello_cc.o ] && fail ${LINENO} + if(std::filesystem::exists(BUILDDIR+"/hello-hello_cc.o")) + { + return fail(); + } + + // + //MD5=`md5sum ctor` + ctor_bin = readFile("ctor"); + // + //# Run normally to build project + //ctor -v + args = {"-v"}; + ret = execute(settings, "./ctor", args); + if(ret != 0) + { + return fail(ret); + } + + // + //# Compiled object should now exist + //[ ! -f ${BUILDDIR}/hello-hello_cc.o ] && fail ${LINENO} + if(!std::filesystem::exists(BUILDDIR+"/hello-hello_cc.o")) + { + return fail(); + } + // + //# ctor should not have been rebuilt, so md5 sum should be the same + //(echo $MD5 | md5sum --status -c) || fail ${LINENO} + ctor_bin2 = readFile("ctor"); + if(ctor_bin != ctor_bin2) + { + return fail(); + } + + std::this_thread::sleep_for(1100ms); + // + //MOD1=`stat $STAT_FORMAT ${BUILDDIR}/hello-hello_cc.o` + auto time = std::filesystem::last_write_time(BUILDDIR+"/hello-hello_cc.o"); + //touch hello.cc + std::filesystem::last_write_time("hello.cc", time + 1s); + //sleep 1.1 + std::this_thread::sleep_for(1100ms); + // + //# Run normally to rebuild hello.cc + //ctor -v + args = {"-v"}; + ret = execute(settings, "./ctor", args); + if(ret != 0) + { + return fail(ret); + } + // + //# Object file should have been recompiled + //MOD2=`stat $STAT_FORMAT ${BUILDDIR}/hello-hello_cc.o` + auto time2 = std::filesystem::last_write_time(BUILDDIR+"/hello-hello_cc.o"); + //[[ $MOD1 == $MOD2 ]] && fail ${LINENO} + if(time == time2) + { + return fail(); + } + // + //# Replace -DFOO with -DBAR in foo external.cxxflags + //echo "** ctor_files/ctor.cc.bar" + std::cout << "** ctor_files/ctor.cc.bar\n"; + //cp ctor_files/ctor.cc.bar ctor.cc + std::filesystem::copy("ctor_files/ctor.cc.bar", "ctor.cc", + std::filesystem::copy_options::overwrite_existing); + // + //MD5C=`md5sum configuration.cc` + auto configuration_cc_bin = readFile("configuration.cc"); + //MD5=`md5sum ctor` + ctor_bin = readFile("ctor"); + //MOD1=`stat $STAT_FORMAT build/hello-hello_cc.o` + time = std::filesystem::last_write_time(BUILDDIR+"/hello-hello_cc.o"); + //sleep 1.1 + std::this_thread::sleep_for(1100ms); + // + //# Run normally to reconfigure, rebuild ctor and rebuild hello.cc + //ctor -v + args = {"-v"}; + ret = execute(settings, "./ctor", args); + if(ret != 0) + { + return fail(ret); + } + // + //MOD2=`stat $STAT_FORMAT ${BUILDDIR}/hello-hello_cc.o` + time2 = std::filesystem::last_write_time(BUILDDIR+"/hello-hello_cc.o"); + //[[ $MOD1 == $MOD2 ]] && fail ${LINENO} + if(time == time2) + { + return fail(); + } + //(echo $MD5C | md5sum --status -c) && fail ${LINENO} + auto configuration_cc_bin2 = readFile("configuration.cc"); + if(configuration_cc_bin == configuration_cc_bin2) + { + return fail(); + } + //(echo $MD5 | md5sum --status -c) && fail ${LINENO} + ctor_bin2 = readFile("ctor"); + if(ctor_bin == ctor_bin2) + { + return fail(); + } + // + //echo "** ctor_files/ctor.cc.multi" + std::cout << "** ctor_files/ctor.cc.multi\n"; + //cp ctor_files/ctor.cc.multi ctor.cc + std::filesystem::copy("ctor_files/ctor.cc.multi", "ctor.cc", + std::filesystem::copy_options::overwrite_existing); + + // + //MD5C=`md5sum configuration.cc` + configuration_cc_bin = readFile("configuration.cc"); + //MD5=`md5sum ctor` + ctor_bin = readFile("ctor"); + //MOD1=`stat $STAT_FORMAT ${BUILDDIR}/hello-hello_cc.o` + time = std::filesystem::last_write_time(BUILDDIR+"/hello-hello_cc.o"); + //sleep 1.1 + std::this_thread::sleep_for(1100ms); + // + //# Run normally to reconfigure, rebuild ctor and rebuild hello.cc + //ctor -v + args = {"-v"}; + ret = execute(settings, "./ctor", args); + if(ret != 0) + { + return fail(ret); + } + // + //MOD2=`stat $STAT_FORMAT ${BUILDDIR}/hello-hello_cc.o` + time2 = std::filesystem::last_write_time(BUILDDIR+"/hello-hello_cc.o"); + //[[ $MOD1 == $MOD2 ]] && fail ${LINENO} + if(time == time2) + { + return fail(); + } + //(echo $MD5C | md5sum --status -c) && fail ${LINENO} + configuration_cc_bin2 = readFile("configuration.cc"); + if(configuration_cc_bin == configuration_cc_bin2) + { + return fail(); + } + //(echo $MD5 | md5sum --status -c) && fail ${LINENO} + ctor_bin2 = readFile("ctor"); + if(ctor_bin == ctor_bin2) + { + return fail(); + } + // + //# now touching foobar.h, should retrigger re-configuration + //touch foobar.h + time = std::filesystem::last_write_time("ctor"); + std::filesystem::last_write_time("foobar.h", time + 1s); + // + //MOD1=`stat $STAT_FORMAT ctor` + time = std::filesystem::last_write_time("ctor"); + //sleep 1.1 + std::this_thread::sleep_for(1100ms); + // + //# Run normally to reconfigure, rebuild ctor and rebuild hello.cc + //ctor -v + args = {"-v"}; + ret = execute(settings, "./ctor", args); + if(ret != 0) + { + return fail(ret); + } + // + //MOD2=`stat $STAT_FORMAT ctor` + time2 = std::filesystem::last_write_time("ctor"); + //[[ $MOD1 == $MOD2 ]] && fail ${LINENO} + if(time == time2) + { + return fail(); + } + // + //echo "** ctor_files/ctor.cc.generated" + std::cout << "** ctor_files/ctor.cc.generated\n"; + //cp ctor_files/ctor.cc.generated ctor.cc + std::filesystem::copy("ctor_files/ctor.cc.generated", "ctor.cc", + std::filesystem::copy_options::overwrite_existing); + //rm -f ${BUILDDIR}/world.cc ${BUILDDIR}/foo.cc + std::filesystem::remove(BUILDDIR+"/world.cc"); + std::filesystem::remove(BUILDDIR+"/foo.cc"); + + // + //MD5C=`md5sum configuration.cc` + configuration_cc_bin = readFile("configuration.cc"); + //MD5=`md5sum ctor` + ctor_bin = readFile("ctor"); + //sleep 1.1 + std::this_thread::sleep_for(1100ms); + // + //# Run normally to reconfigure, rebuild ctor and build world.cc + //ctor -v world + args = {"-v", "world"}; + ret = execute(settings, "./ctor", args); + if(ret != 0) + { + return fail(ret); + } + //(echo $MD5C | md5sum --status -c) && fail ${LINENO} + configuration_cc_bin2 = readFile("configuration.cc"); + if(configuration_cc_bin == configuration_cc_bin2) + { + return fail(); + } + //(echo $MD5 | md5sum --status -c) && fail ${LINENO} + ctor_bin2 = readFile("ctor"); + if(ctor_bin == ctor_bin2) + { + return fail(); + } + // + //# foo.cc should not be generated at this point + //ls ${BUILDDIR}/foo.cc + //[[ $? != 0 ]] || fail ${LINENO} + if(std::filesystem::exists(BUILDDIR+"/foo.cc")) + { + return fail(); + } + // + //MOD1W=`stat $STAT_FORMAT ${BUILDDIR}/world.cc` + auto time_w = std::filesystem::last_write_time(BUILDDIR+"/world.cc"); + //MOD1=`stat $STAT_FORMAT ${BUILDDIR}/${BUILDDIR}/world-world_cc.o` + auto time_wo = std::filesystem::last_write_time(BUILDDIR+"/"+BUILDDIR+"/world-world_cc.o"); + // + //sleep 1.1 + std::this_thread::sleep_for(1100ms); + // + //# now touching hello.cc, should trigger regeneration of world.cc and rebuild + //touch hello.cc + std::filesystem::last_write_time("hello.cc", time_w + 1s); + //ctor -v world + args = {"-v", "world"}; + ret = execute(settings, "./ctor", args); + if(ret != 0) + { + return fail(ret); + } + // + //MOD2W=`stat $STAT_FORMAT ${BUILDDIR}/world.cc` + auto time_w2 = std::filesystem::last_write_time(BUILDDIR+"/world.cc"); + //MOD2=`stat $STAT_FORMAT ${BUILDDIR}/${BUILDDIR}/world-world_cc.o` + auto time_wo2 = std::filesystem::last_write_time(BUILDDIR+"/"+BUILDDIR+"/world-world_cc.o"); + //[[ $MOD1W == $MOD2W ]] && fail ${LINENO} + if(time_w == time_w2) + { + return fail(); + } + //[[ $MOD1 == $MOD2 ]] && fail ${LINENO} + if(time_wo == time_wo2) + { + return fail(); + } + // + //exit 0 + return 0; +} |
