diff options
-rw-r--r-- | third_party/nix/src/libstore/CMakeLists.txt | 21 | ||||
-rw-r--r-- | third_party/nix/src/libstore/mock-binary-cache-store.cc | 91 | ||||
-rw-r--r-- | third_party/nix/src/libstore/mock-binary-cache-store.hh | 59 |
3 files changed, 170 insertions, 1 deletions
diff --git a/third_party/nix/src/libstore/CMakeLists.txt b/third_party/nix/src/libstore/CMakeLists.txt index 4bfbb165f6b2..246377cc9b8d 100644 --- a/third_party/nix/src/libstore/CMakeLists.txt +++ b/third_party/nix/src/libstore/CMakeLists.txt @@ -1,8 +1,11 @@ # -*- mode: cmake; -*- add_library(nixstore SHARED) +add_library(nixstoremock SHARED) set_property(TARGET nixstore PROPERTY CXX_STANDARD 17) +set_property(TARGET nixstoremock PROPERTY CXX_STANDARD 17) include_directories(${PROJECT_BINARY_DIR}) # for config.h target_include_directories(nixstore PUBLIC "${nix_SOURCE_DIR}/src") +target_include_directories(nixstoremock PUBLIC "${nix_SOURCE_DIR}/src") # The database schema is stored in schema.sql, but needs to be # available during the build as static data. @@ -101,8 +104,24 @@ target_link_libraries(nixstore sodium ) +target_sources(nixstoremock + PUBLIC + mock-binary-cache-store.hh + + PRIVATE + mock-binary-cache-store.cc +) + +target_link_libraries(nixstoremock + nixstore + + absl::btree + absl::flat_hash_map + glog +) + configure_file("nix-store.pc.in" "${PROJECT_BINARY_DIR}/nix-store.pc" @ONLY) INSTALL(FILES "${PROJECT_BINARY_DIR}/nix-store.pc" DESTINATION "${PKGCONFIG_INSTALL_DIR}") INSTALL(FILES ${HEADER_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/nix/libstore) -INSTALL(TARGETS nixstore DESTINATION ${CMAKE_INSTALL_LIBDIR}) +INSTALL(TARGETS nixstore nixstoremock DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/third_party/nix/src/libstore/mock-binary-cache-store.cc b/third_party/nix/src/libstore/mock-binary-cache-store.cc new file mode 100644 index 000000000000..995d61521c01 --- /dev/null +++ b/third_party/nix/src/libstore/mock-binary-cache-store.cc @@ -0,0 +1,91 @@ +#include "libstore/mock-binary-cache-store.hh" + +#include <glog/logging.h> + +namespace nix { + +MockBinaryCacheStore::MockBinaryCacheStore(const Params& params) + : BinaryCacheStore(params), contents_(), errorInjections_() {} + +std::string MockBinaryCacheStore::getUri() { return "mock://1"; } + +bool MockBinaryCacheStore::fileExists(const std::string& path) { + ThrowInjectedErrors(path); + + return contents_.find(path) != contents_.end(); +}; + +void MockBinaryCacheStore::upsertFile(const std::string& path, + const std::string& data, + const std::string& mimeType) { + ThrowInjectedErrors(path); + + contents_[path] = MemoryFile{data, mimeType}; +} + +void MockBinaryCacheStore::getFile( + const std::string& path, + Callback<std::shared_ptr<std::string>> callback) noexcept { + auto eit = errorInjections_.find(path); + if (eit != errorInjections_.end()) { + try { + eit->second(); + LOG(FATAL) << "thrower failed to throw"; + } catch (...) { + callback.rethrow(); + } + return; + } + + auto it = contents_.find(path); + if (it == contents_.end()) { + try { + throw NoSuchBinaryCacheFile(absl::StrCat( + "file '", path, "' was not added to the MockBinaryCache")); + } catch (...) { + callback.rethrow(); + } + return; + } + callback(std::make_shared<std::string>(it->second.data)); +} + +PathSet MockBinaryCacheStore::queryAllValidPaths() { + PathSet paths; + + for (auto it : contents_) { + paths.insert(it.first); + } + + return paths; +} + +void MockBinaryCacheStore::DeleteFile(const std::string& path) { + contents_.erase(path); +} + +// Same as upsert, but bypasses injected errors. +void MockBinaryCacheStore::SetFileContentsForTest(const std::string& path, + const std::string& data, + const std::string& mimeType) { + contents_[path] = MemoryFile{data, mimeType}; +} + +void MockBinaryCacheStore::PrepareErrorInjection( + const std::string& path, std::function<void()> err_factory) { + errorInjections_[path] = err_factory; +} + +void MockBinaryCacheStore::CancelErrorInjection(const std::string& path) { + errorInjections_.erase(path); +} + +void MockBinaryCacheStore::ThrowInjectedErrors(const std::string& path) { + auto it = errorInjections_.find(path); + if (it != errorInjections_.end()) { + it->second(); + LOG(FATAL) << "thrower failed to throw"; + } +} + +} // namespace nix diff --git a/third_party/nix/src/libstore/mock-binary-cache-store.hh b/third_party/nix/src/libstore/mock-binary-cache-store.hh new file mode 100644 index 000000000000..419077b6bbb0 --- /dev/null +++ b/third_party/nix/src/libstore/mock-binary-cache-store.hh @@ -0,0 +1,59 @@ +#pragma once + +#include <absl/container/btree_map.h> +#include <absl/container/flat_hash_map.h> + +#include "libstore/binary-cache-store.hh" + +namespace nix { + +// MockBinaryCacheStore implements a memory-based BinaryCacheStore, for use in +// tests. +class MockBinaryCacheStore : public BinaryCacheStore { + public: + MockBinaryCacheStore(const Params& params); + + // Store API + + std::string getUri() override; + + bool fileExists(const std::string& path) override; + + void upsertFile(const std::string& path, const std::string& data, + const std::string& mimeType) override; + + void getFile( + const std::string& path, + Callback<std::shared_ptr<std::string>> callback) noexcept override; + + PathSet queryAllValidPaths() override; + + // Test API + + // Remove a file from the store. + void DeleteFile(const std::string& path); + + // Same as upsert, but bypasses injected errors. + void SetFileContentsForTest(const std::string& path, const std::string& data, + const std::string& mimeType); + + void PrepareErrorInjection(const std::string& path, + std::function<void()> throw_func); + + void CancelErrorInjection(const std::string& path); + + // Internals + + private: + void ThrowInjectedErrors(const std::string& path); + + struct MemoryFile { + std::string data; + std::string mimeType; + }; + + absl::btree_map<std::string, MemoryFile> contents_; + absl::flat_hash_map<std::string, std::function<void()>> errorInjections_; +}; + +} // namespace nix |