feat(3p/nix): add MockBinaryCacheStore
This adds an implementation of BinaryCacheStore to be used by tests exercising both the logic inherent to BinaryCacheStore and more general Store tests. A new library target, nixstoremock, is created to indicate that this file is intended only for use in tests and not in user-facing code. Change-Id: Ib68f777238843a4f3a2303db8a69735fbc22d161 Reviewed-on: https://cl.tvl.fyi/c/depot/+/1645 Tested-by: BuildkiteCI Reviewed-by: glittershark <grfn@gws.fyi>
This commit is contained in:
parent
28c7e926ea
commit
3c3527e16b
3 changed files with 170 additions and 1 deletions
21
third_party/nix/src/libstore/CMakeLists.txt
vendored
21
third_party/nix/src/libstore/CMakeLists.txt
vendored
|
@ -1,8 +1,11 @@
|
||||||
# -*- mode: cmake; -*-
|
# -*- mode: cmake; -*-
|
||||||
add_library(nixstore SHARED)
|
add_library(nixstore SHARED)
|
||||||
|
add_library(nixstoremock SHARED)
|
||||||
set_property(TARGET nixstore PROPERTY CXX_STANDARD 17)
|
set_property(TARGET nixstore PROPERTY CXX_STANDARD 17)
|
||||||
|
set_property(TARGET nixstoremock PROPERTY CXX_STANDARD 17)
|
||||||
include_directories(${PROJECT_BINARY_DIR}) # for config.h
|
include_directories(${PROJECT_BINARY_DIR}) # for config.h
|
||||||
target_include_directories(nixstore PUBLIC "${nix_SOURCE_DIR}/src")
|
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
|
# The database schema is stored in schema.sql, but needs to be
|
||||||
# available during the build as static data.
|
# available during the build as static data.
|
||||||
|
@ -101,8 +104,24 @@ target_link_libraries(nixstore
|
||||||
sodium
|
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)
|
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 "${PROJECT_BINARY_DIR}/nix-store.pc" DESTINATION "${PKGCONFIG_INSTALL_DIR}")
|
||||||
|
|
||||||
INSTALL(FILES ${HEADER_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/nix/libstore)
|
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})
|
||||||
|
|
91
third_party/nix/src/libstore/mock-binary-cache-store.cc
vendored
Normal file
91
third_party/nix/src/libstore/mock-binary-cache-store.cc
vendored
Normal file
|
@ -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
|
59
third_party/nix/src/libstore/mock-binary-cache-store.hh
vendored
Normal file
59
third_party/nix/src/libstore/mock-binary-cache-store.hh
vendored
Normal file
|
@ -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
|
Loading…
Reference in a new issue