aboutsummaryrefslogtreecommitdiff
path: root/tests/unit/libstore/protocol.hh
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-03-04 04:24:23 +0100
committereldritch horrors <pennae@lix.systems>2024-03-04 04:36:58 +0100
commit6897e238bd0c730af224b928ec8746781df67ad2 (patch)
tree50ce7ddeda203a12c7d67080ef611f56d59678c2 /tests/unit/libstore/protocol.hh
parentda0aa66d98b8b46253dd968cfaae61d872569c9b (diff)
Merge pull request #9099 from obsidiansystems/common-proto
Factor out bits of the worker protocol to use elsewhere (cherry picked from commit 4b1a97338f517f45e6169d3d8845c5caa5724e97) Change-Id: If93afa0f8b1cf9b0e705b34fa71e6fd708752758
Diffstat (limited to 'tests/unit/libstore/protocol.hh')
-rw-r--r--tests/unit/libstore/protocol.hh88
1 files changed, 88 insertions, 0 deletions
diff --git a/tests/unit/libstore/protocol.hh b/tests/unit/libstore/protocol.hh
new file mode 100644
index 000000000..0df819090
--- /dev/null
+++ b/tests/unit/libstore/protocol.hh
@@ -0,0 +1,88 @@
+#include <nlohmann/json.hpp>
+#include <gtest/gtest.h>
+
+#include "tests/libstore.hh"
+#include "characterization.hh"
+
+namespace nix {
+
+template<class Proto, const char * protocolDir>
+class ProtoTest : public LibStoreTest
+{
+ /**
+ * Read this as simply `using S = Inner::Serialise;`.
+ *
+ * See `LengthPrefixedProtoHelper::S` for the same trick, and its
+ * rationale.
+ */
+ template<typename U> using S = typename Proto::template Serialise<U>;
+
+public:
+ Path unitTestData = getUnitTestData() + "/libstore/" + protocolDir;
+
+ Path goldenMaster(std::string_view testStem) {
+ return unitTestData + "/" + testStem + ".bin";
+ }
+
+ /**
+ * Golden test for `T` reading
+ */
+ template<typename T>
+ void readTest(PathView testStem, T value)
+ {
+ if (testAccept())
+ {
+ GTEST_SKIP() << "Cannot read golden master because another test is also updating it";
+ }
+ else
+ {
+ auto expected = readFile(goldenMaster(testStem));
+
+ T got = ({
+ StringSource from { expected };
+ S<T>::read(
+ *store,
+ typename Proto::ReadConn { .from = from });
+ });
+
+ ASSERT_EQ(got, value);
+ }
+ }
+
+ /**
+ * Golden test for `T` write
+ */
+ template<typename T>
+ void writeTest(PathView testStem, const T & value)
+ {
+ auto file = goldenMaster(testStem);
+
+ StringSink to;
+ Proto::write(
+ *store,
+ typename Proto::WriteConn { .to = to },
+ value);
+
+ if (testAccept())
+ {
+ createDirs(dirOf(file));
+ writeFile(file, to.s);
+ GTEST_SKIP() << "Updating golden master";
+ }
+ else
+ {
+ auto expected = readFile(file);
+ ASSERT_EQ(to.s, expected);
+ }
+ }
+};
+
+#define CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VALUE) \
+ TEST_F(FIXTURE, NAME ## _read) { \
+ readTest(STEM, VALUE); \
+ } \
+ TEST_F(FIXTURE, NAME ## _write) { \
+ writeTest(STEM, VALUE); \
+ }
+
+}