mirror of
https://github.com/NixOS/nix.git
synced 2025-12-07 01:21:00 +01:00
Merge pull request #13904 from NixOS/c-ffi-improvements
C ffi improvements
This commit is contained in:
commit
81e068ab8a
24 changed files with 210 additions and 141 deletions
|
|
@ -40,6 +40,8 @@ static T * unsafe_new_with_self(F && init)
|
|||
return new (p) T(init(static_cast<T *>(p)));
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
nix_err nix_libexpr_init(nix_c_context * context)
|
||||
{
|
||||
if (context)
|
||||
|
|
@ -287,3 +289,5 @@ void nix_gc_register_finalizer(void * obj, void * cd, void (*finalizer)(void * o
|
|||
GC_REGISTER_FINALIZER(obj, finalizer, cd, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include "nix_api_value.h"
|
||||
#include "nix/expr/search-path.hh"
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct nix_eval_state_builder
|
||||
{
|
||||
nix::ref<nix::Store> store;
|
||||
|
|
@ -61,4 +63,6 @@ struct nix_realised_string
|
|||
std::vector<StorePath> storePaths;
|
||||
};
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // NIX_API_EXPR_INTERNAL_H
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
extern "C" {
|
||||
|
||||
void nix_set_string_return(nix_string_return * str, const char * c)
|
||||
{
|
||||
str->str = c;
|
||||
|
|
@ -40,6 +42,8 @@ nix_err nix_external_add_string_context(nix_c_context * context, nix_string_cont
|
|||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
class NixCExternalValue : public nix::ExternalValueBase
|
||||
{
|
||||
NixCExternalValueDesc & desc;
|
||||
|
|
@ -170,6 +174,8 @@ public:
|
|||
virtual ~NixCExternalValue() override {};
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
ExternalValue * nix_create_external_value(nix_c_context * context, NixCExternalValueDesc * desc, void * v)
|
||||
{
|
||||
if (context)
|
||||
|
|
@ -198,3 +204,5 @@ void * nix_get_external_value_content(nix_c_context * context, ExternalValue * b
|
|||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ static void nix_c_primop_wrapper(
|
|||
v = vTmp;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
PrimOp * nix_alloc_primop(
|
||||
nix_c_context * context,
|
||||
PrimOpFun fun,
|
||||
|
|
@ -651,3 +653,5 @@ const StorePath * nix_realised_string_get_store_path(nix_realised_string * s, si
|
|||
{
|
||||
return &s->storePaths[i];
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ sources = files(
|
|||
'nix_api_expr.cc',
|
||||
'nix_api_external.cc',
|
||||
'nix_api_value.cc',
|
||||
'nix_api_value_internal.cc',
|
||||
'primops.cc',
|
||||
'search-path.cc',
|
||||
'trivial.cc',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#include "nix_api_store.h"
|
||||
#include "nix_api_store_internal.h"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_util_internal.h"
|
||||
#include "nix_api_expr.h"
|
||||
#include "nix_api_value.h"
|
||||
|
||||
|
|
@ -151,8 +149,8 @@ TEST_F(nix_api_expr_test, nix_expr_realise_context_bad_value)
|
|||
assert_ctx_ok();
|
||||
auto r = nix_string_realise(ctx, state, value, false);
|
||||
ASSERT_EQ(nullptr, r);
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_NIX_ERROR);
|
||||
ASSERT_THAT(ctx->last_err, testing::Optional(testing::HasSubstr("cannot coerce")));
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_ERR_NIX_ERROR);
|
||||
ASSERT_THAT(nix_err_msg(nullptr, ctx, nullptr), testing::HasSubstr("cannot coerce"));
|
||||
}
|
||||
|
||||
TEST_F(nix_api_expr_test, nix_expr_realise_context_bad_build)
|
||||
|
|
@ -168,8 +166,8 @@ TEST_F(nix_api_expr_test, nix_expr_realise_context_bad_build)
|
|||
assert_ctx_ok();
|
||||
auto r = nix_string_realise(ctx, state, value, false);
|
||||
ASSERT_EQ(nullptr, r);
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_NIX_ERROR);
|
||||
ASSERT_THAT(ctx->last_err, testing::Optional(testing::HasSubstr("failed with exit code 1")));
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_ERR_NIX_ERROR);
|
||||
ASSERT_THAT(nix_err_msg(nullptr, ctx, nullptr), testing::HasSubstr("failed with exit code 1"));
|
||||
}
|
||||
|
||||
TEST_F(nix_api_expr_test, nix_expr_realise_context)
|
||||
|
|
@ -381,12 +379,11 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_no_return)
|
|||
nix_value * result = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_value_call(ctx, state, primopValue, three, result);
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_NIX_ERROR);
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_ERR_NIX_ERROR);
|
||||
ASSERT_THAT(
|
||||
ctx->last_err,
|
||||
testing::Optional(
|
||||
testing::HasSubstr("Implementation error in custom function: return value was not initialized")));
|
||||
ASSERT_THAT(ctx->last_err, testing::Optional(testing::HasSubstr("badNoReturn")));
|
||||
nix_err_msg(nullptr, ctx, nullptr),
|
||||
testing::HasSubstr("Implementation error in custom function: return value was not initialized"));
|
||||
ASSERT_THAT(nix_err_msg(nullptr, ctx, nullptr), testing::HasSubstr("badNoReturn"));
|
||||
}
|
||||
|
||||
static void primop_bad_return_thunk(
|
||||
|
|
@ -419,12 +416,11 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_return_thunk)
|
|||
assert_ctx_ok();
|
||||
NIX_VALUE_CALL(ctx, state, result, primopValue, toString, four);
|
||||
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_NIX_ERROR);
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_ERR_NIX_ERROR);
|
||||
ASSERT_THAT(
|
||||
ctx->last_err,
|
||||
testing::Optional(
|
||||
testing::HasSubstr("Implementation error in custom function: return value must not be a thunk")));
|
||||
ASSERT_THAT(ctx->last_err, testing::Optional(testing::HasSubstr("badReturnThunk")));
|
||||
nix_err_msg(nullptr, ctx, nullptr),
|
||||
testing::HasSubstr("Implementation error in custom function: return value must not be a thunk"));
|
||||
ASSERT_THAT(nix_err_msg(nullptr, ctx, nullptr), testing::HasSubstr("badReturnThunk"));
|
||||
}
|
||||
|
||||
TEST_F(nix_api_expr_test, nix_value_call_multi_no_args)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
#include "nix_api_store.h"
|
||||
#include "nix_api_store_internal.h"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_util_internal.h"
|
||||
#include "nix_api_expr.h"
|
||||
#include "nix_api_expr_internal.h"
|
||||
#include "nix_api_value.h"
|
||||
#include "nix_api_external.h"
|
||||
|
||||
|
|
@ -39,7 +36,7 @@ private:
|
|||
std::string type_string = "nix-external<MyExternalValueDesc( ";
|
||||
type_string += std::to_string(obj->_x);
|
||||
type_string += " )>";
|
||||
res->str = &*type_string.begin();
|
||||
nix_set_string_return(res, &*type_string.begin());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
#include "nix_api_store.h"
|
||||
#include "nix_api_store_internal.h"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_util_internal.h"
|
||||
#include "nix_api_expr.h"
|
||||
#include "nix_api_value.h"
|
||||
#include "nix_api_expr_internal.h"
|
||||
|
||||
#include "nix/expr/tests/nix_api_expr.hh"
|
||||
#include "nix/util/tests/string_callback.hh"
|
||||
|
|
@ -16,14 +13,6 @@
|
|||
|
||||
namespace nixC {
|
||||
|
||||
TEST_F(nix_api_expr_test, as_nix_value_ptr)
|
||||
{
|
||||
// nix_alloc_value casts nix::Value to nix_value
|
||||
// It should be obvious from the decl that that works, but if it doesn't,
|
||||
// the whole implementation would be utterly broken.
|
||||
ASSERT_EQ(sizeof(nix::Value), sizeof(nix_value));
|
||||
}
|
||||
|
||||
TEST_F(nix_api_expr_test, nix_value_get_int_invalid)
|
||||
{
|
||||
ASSERT_EQ(0, nix_get_int(ctx, nullptr));
|
||||
|
|
@ -320,8 +309,10 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_error)
|
|||
|
||||
// Evaluate it
|
||||
nix_value_force(ctx, state, v);
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_NIX_ERROR);
|
||||
ASSERT_THAT(ctx->last_err.value(), testing::HasSubstr("attempt to call something which is not a function but"));
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_ERR_NIX_ERROR);
|
||||
ASSERT_THAT(
|
||||
nix_err_msg(nullptr, ctx, nullptr),
|
||||
testing::HasSubstr("attempt to call something which is not a function but"));
|
||||
|
||||
// Clean up
|
||||
nix_gc_decref(ctx, some_string);
|
||||
|
|
@ -380,7 +371,9 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg)
|
|||
// nix_get_attr_byname isn't lazy (it could have been) so it will throw the exception
|
||||
nix_value * foo = nix_get_attr_byname(ctx, r, state, "foo");
|
||||
ASSERT_EQ(nullptr, foo);
|
||||
ASSERT_THAT(ctx->last_err.value(), testing::HasSubstr("error message for test case nix_value_init_apply_lazy_arg"));
|
||||
ASSERT_THAT(
|
||||
nix_err_msg(nullptr, ctx, nullptr),
|
||||
testing::HasSubstr("error message for test case nix_value_init_apply_lazy_arg"));
|
||||
|
||||
// Clean up
|
||||
nix_gc_decref(ctx, f);
|
||||
|
|
|
|||
25
src/libexpr-tests/nix_api_value_internal.cc
Normal file
25
src/libexpr-tests/nix_api_value_internal.cc
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include "nix_api_store.h"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_expr.h"
|
||||
#include "nix_api_value.h"
|
||||
#include "nix_api_expr_internal.h"
|
||||
|
||||
#include "nix/expr/tests/nix_api_expr.hh"
|
||||
#include "nix/util/tests/string_callback.hh"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace nixC {
|
||||
|
||||
TEST_F(nix_api_expr_test, as_nix_value_ptr)
|
||||
{
|
||||
// nix_alloc_value casts nix::Value to nix_value
|
||||
// It should be obvious from the decl that that works, but if it doesn't,
|
||||
// the whole implementation would be utterly broken.
|
||||
ASSERT_EQ(sizeof(nix::Value), sizeof(nix_value));
|
||||
}
|
||||
|
||||
} // namespace nixC
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
#include "nix_api_fetchers_internal.hh"
|
||||
#include "nix_api_util_internal.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
nix_fetchers_settings * nix_fetchers_settings_new(nix_c_context * context)
|
||||
{
|
||||
try {
|
||||
|
|
@ -17,3 +19,5 @@ void nix_fetchers_settings_free(nix_fetchers_settings * settings)
|
|||
{
|
||||
delete settings;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "nix/flake/flake.hh"
|
||||
|
||||
extern "C" {
|
||||
|
||||
nix_flake_settings * nix_flake_settings_new(nix_c_context * context)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
|
|
@ -203,3 +205,5 @@ nix_value * nix_locked_flake_get_output_attrs(
|
|||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "nix/main/plugin.hh"
|
||||
|
||||
extern "C" {
|
||||
|
||||
nix_err nix_init_plugins(nix_c_context * context)
|
||||
{
|
||||
if (context)
|
||||
|
|
@ -14,3 +16,5 @@ nix_err nix_init_plugins(nix_c_context * context)
|
|||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "nix/store/globals.hh"
|
||||
|
||||
extern "C" {
|
||||
|
||||
nix_err nix_libstore_init(nix_c_context * context)
|
||||
{
|
||||
if (context)
|
||||
|
|
@ -91,7 +93,7 @@ nix_store_get_version(nix_c_context * context, Store * store, nix_get_string_cal
|
|||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
bool nix_store_is_valid_path(nix_c_context * context, Store * store, StorePath * path)
|
||||
bool nix_store_is_valid_path(nix_c_context * context, Store * store, const StorePath * path)
|
||||
{
|
||||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
|
|
@ -129,7 +131,7 @@ nix_err nix_store_realise(
|
|||
Store * store,
|
||||
StorePath * path,
|
||||
void * userdata,
|
||||
void (*callback)(void * userdata, const char *, const char *))
|
||||
void (*callback)(void * userdata, const char *, const StorePath *))
|
||||
{
|
||||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
|
|
@ -144,8 +146,8 @@ nix_err nix_store_realise(
|
|||
if (callback) {
|
||||
for (const auto & result : results) {
|
||||
for (const auto & [outputName, realisation] : result.builtOutputs) {
|
||||
auto op = store->ptr->printStorePath(realisation.outPath);
|
||||
callback(userdata, outputName.c_str(), op.c_str());
|
||||
StorePath p{realisation.outPath};
|
||||
callback(userdata, outputName.c_str(), &p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -180,3 +182,5 @@ nix_err nix_store_copy_closure(nix_c_context * context, Store * srcStore, Store
|
|||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ void nix_store_path_free(StorePath * p);
|
|||
* @param[in] path Path to check
|
||||
* @return true or false, error info in context
|
||||
*/
|
||||
bool nix_store_is_valid_path(nix_c_context * context, Store * store, StorePath * path);
|
||||
bool nix_store_is_valid_path(nix_c_context * context, Store * store, const StorePath * path);
|
||||
|
||||
/**
|
||||
* @brief Get the physical location of a store path
|
||||
|
|
@ -190,7 +190,7 @@ nix_err nix_store_realise(
|
|||
Store * store,
|
||||
StorePath * path,
|
||||
void * userdata,
|
||||
void (*callback)(void * userdata, const char * outname, const char * out));
|
||||
void (*callback)(void * userdata, const char * outname, const StorePath * out));
|
||||
|
||||
/**
|
||||
* @brief get the version of a nix store.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
#define NIX_API_STORE_INTERNAL_H
|
||||
#include "nix/store/store-api.hh"
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct Store
|
||||
{
|
||||
nix::ref<nix::Store> ptr;
|
||||
|
|
@ -12,4 +14,6 @@ struct StorePath
|
|||
nix::StorePath path;
|
||||
};
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -51,18 +51,10 @@ static void BM_UnparseRealDerivationFile(benchmark::State & state, const std::st
|
|||
|
||||
// Register benchmarks for actual test derivation files if they exist
|
||||
BENCHMARK_CAPTURE(
|
||||
BM_ParseRealDerivationFile,
|
||||
hello,
|
||||
getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value_or(NIX_UNIT_TEST_DATA) + "/derivation/hello.drv");
|
||||
BM_ParseRealDerivationFile, hello, getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value() + "/derivation/hello.drv");
|
||||
BENCHMARK_CAPTURE(
|
||||
BM_ParseRealDerivationFile,
|
||||
firefox,
|
||||
getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value_or(NIX_UNIT_TEST_DATA) + "/derivation/firefox.drv");
|
||||
BM_ParseRealDerivationFile, firefox, getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value() + "/derivation/firefox.drv");
|
||||
BENCHMARK_CAPTURE(
|
||||
BM_UnparseRealDerivationFile,
|
||||
hello,
|
||||
getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value_or(NIX_UNIT_TEST_DATA) + "/derivation/hello.drv");
|
||||
BM_UnparseRealDerivationFile, hello, getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value() + "/derivation/hello.drv");
|
||||
BENCHMARK_CAPTURE(
|
||||
BM_UnparseRealDerivationFile,
|
||||
firefox,
|
||||
getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value_or(NIX_UNIT_TEST_DATA) + "/derivation/firefox.drv");
|
||||
BM_UnparseRealDerivationFile, firefox, getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value() + "/derivation/firefox.drv");
|
||||
|
|
|
|||
|
|
@ -130,10 +130,13 @@ if get_option('benchmarks')
|
|||
link_args : linker_export_flags,
|
||||
install : true,
|
||||
cpp_pch : do_pch ? [ 'pch/precompiled-headers.hh' ] : [],
|
||||
cpp_args : [
|
||||
'-DNIX_UNIT_TEST_DATA="' + meson.current_source_dir() + '/data"',
|
||||
],
|
||||
)
|
||||
|
||||
benchmark('nix-store-benchmarks', benchmark_exe)
|
||||
benchmark(
|
||||
'nix-store-benchmarks',
|
||||
benchmark_exe,
|
||||
env : {
|
||||
'_NIX_TEST_UNIT_DATA' : meson.current_source_dir() / 'data',
|
||||
},
|
||||
)
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#include "nix_api_util.h"
|
||||
#include "nix_api_util_internal.h"
|
||||
#include "nix_api_store.h"
|
||||
#include "nix_api_store_internal.h"
|
||||
|
||||
#include "nix/store/tests/nix_api_store.hh"
|
||||
#include "nix/util/tests/string_callback.hh"
|
||||
|
|
@ -65,7 +63,7 @@ TEST_F(nix_api_store_test, nix_store_get_storedir)
|
|||
TEST_F(nix_api_store_test, InvalidPathFails)
|
||||
{
|
||||
nix_store_parse_path(ctx, store, "invalid-path");
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_NIX_ERROR);
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_ERR_NIX_ERROR);
|
||||
}
|
||||
|
||||
TEST_F(nix_api_store_test, ReturnsValidStorePath)
|
||||
|
|
@ -80,7 +78,7 @@ TEST_F(nix_api_store_test, ReturnsValidStorePath)
|
|||
TEST_F(nix_api_store_test, SetsLastErrCodeToNixOk)
|
||||
{
|
||||
StorePath * path = nix_store_parse_path(ctx, store, (nixStoreDir + PATH_SUFFIX).c_str());
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_OK);
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_OK);
|
||||
nix_store_path_free(path);
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +101,7 @@ TEST_F(nix_api_util_context, nix_store_open_dummy)
|
|||
{
|
||||
nix_libstore_init(ctx);
|
||||
Store * store = nix_store_open(ctx, "dummy://", nullptr);
|
||||
ASSERT_EQ(NIX_OK, ctx->last_err_code);
|
||||
ASSERT_EQ(NIX_OK, nix_err_code(ctx));
|
||||
ASSERT_STREQ("dummy://", store->ptr->config.getReference().render(/*withParams=*/true).c_str());
|
||||
|
||||
std::string str;
|
||||
|
|
@ -117,7 +115,7 @@ TEST_F(nix_api_util_context, nix_store_open_invalid)
|
|||
{
|
||||
nix_libstore_init(ctx);
|
||||
Store * store = nix_store_open(ctx, "invalid://", nullptr);
|
||||
ASSERT_EQ(NIX_ERR_NIX_ERROR, ctx->last_err_code);
|
||||
ASSERT_EQ(NIX_ERR_NIX_ERROR, nix_err_code(ctx));
|
||||
ASSERT_EQ(nullptr, store);
|
||||
nix_store_free(store);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include "nix_api_util_config.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
nix_c_context * nix_c_context_create()
|
||||
{
|
||||
return new nix_c_context();
|
||||
|
|
@ -156,3 +158,5 @@ nix_err call_nix_get_string_callback(const std::string str, nix_get_string_callb
|
|||
callback(str.c_str(), str.size(), user_data);
|
||||
return NIX_OK;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
#include "nix/util/error.hh"
|
||||
#include "nix_api_util.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct nix_c_context
|
||||
{
|
||||
nix_err last_err_code = NIX_OK;
|
||||
|
|
@ -47,4 +49,6 @@ nix_err call_nix_get_string_callback(const std::string str, nix_get_string_callb
|
|||
}
|
||||
#define NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_RES(nullptr)
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // NIX_API_UTIL_INTERNAL_H
|
||||
|
|
|
|||
|
|
@ -54,4 +54,12 @@ protected:
|
|||
#define assert_ctx_err() assert_ctx_err(__FILE__, __LINE__)
|
||||
};
|
||||
|
||||
static inline auto createOwnedNixContext()
|
||||
{
|
||||
return std::unique_ptr<nix_c_context, decltype([](nix_c_context * ctx) {
|
||||
if (ctx)
|
||||
nix_c_context_free(ctx);
|
||||
})>(nix_c_context_create(), {});
|
||||
}
|
||||
|
||||
} // namespace nixC
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ sources = files(
|
|||
'lru-cache.cc',
|
||||
'monitorfdhup.cc',
|
||||
'nix_api_util.cc',
|
||||
'nix_api_util_internal.cc',
|
||||
'pool.cc',
|
||||
'position.cc',
|
||||
'processes.cc',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#include "nix/util/config-global.hh"
|
||||
#include "nix/util/args.hh"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_util_internal.h"
|
||||
#include "nix/util/tests/nix_api_util.hh"
|
||||
#include "nix/util/tests/string_callback.hh"
|
||||
|
||||
|
|
@ -13,41 +12,6 @@
|
|||
|
||||
namespace nixC {
|
||||
|
||||
TEST_F(nix_api_util_context, nix_context_error)
|
||||
{
|
||||
std::string err_msg_ref;
|
||||
try {
|
||||
throw nix::Error("testing error");
|
||||
} catch (nix::Error & e) {
|
||||
err_msg_ref = e.what();
|
||||
nix_context_error(ctx);
|
||||
}
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_NIX_ERROR);
|
||||
ASSERT_EQ(ctx->name, "nix::Error");
|
||||
ASSERT_EQ(*ctx->last_err, err_msg_ref);
|
||||
ASSERT_EQ(ctx->info->msg.str(), "testing error");
|
||||
|
||||
try {
|
||||
throw std::runtime_error("testing exception");
|
||||
} catch (std::exception & e) {
|
||||
err_msg_ref = e.what();
|
||||
nix_context_error(ctx);
|
||||
}
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_UNKNOWN);
|
||||
ASSERT_EQ(*ctx->last_err, err_msg_ref);
|
||||
|
||||
nix_clear_err(ctx);
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_OK);
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_set_err_msg)
|
||||
{
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_OK);
|
||||
nix_set_err_msg(ctx, NIX_ERR_UNKNOWN, "unknown test error");
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_UNKNOWN);
|
||||
ASSERT_EQ(*ctx->last_err, "unknown test error");
|
||||
}
|
||||
|
||||
TEST(nix_api_util, nix_version_get)
|
||||
{
|
||||
ASSERT_EQ(std::string(nix_version_get()), PACKAGE_VERSION);
|
||||
|
|
@ -61,17 +25,9 @@ struct MySettings : nix::Config
|
|||
MySettings mySettings;
|
||||
static nix::GlobalConfig::Register rs(&mySettings);
|
||||
|
||||
static auto createOwnedNixContext()
|
||||
{
|
||||
return std::unique_ptr<nix_c_context, decltype([](nix_c_context * ctx) {
|
||||
if (ctx)
|
||||
nix_c_context_free(ctx);
|
||||
})>(nix_c_context_create(), {});
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_setting_get)
|
||||
{
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_OK);
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_OK);
|
||||
std::string setting_value;
|
||||
nix_err result = nix_setting_get(ctx, "invalid-key", OBSERVE_STRING(setting_value));
|
||||
ASSERT_EQ(result, NIX_ERR_KEY);
|
||||
|
|
@ -114,40 +70,6 @@ TEST_F(nix_api_util_context, nix_err_msg)
|
|||
ASSERT_EQ(sz, err_msg.size());
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_err_info_msg)
|
||||
{
|
||||
std::string err_info;
|
||||
|
||||
// no error
|
||||
EXPECT_THROW(nix_err_info_msg(NULL, ctx, OBSERVE_STRING(err_info)), nix::Error);
|
||||
|
||||
try {
|
||||
throw nix::Error("testing error");
|
||||
} catch (...) {
|
||||
nix_context_error(ctx);
|
||||
}
|
||||
auto new_ctx = createOwnedNixContext();
|
||||
nix_err_info_msg(new_ctx.get(), ctx, OBSERVE_STRING(err_info));
|
||||
ASSERT_STREQ("testing error", err_info.c_str());
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_err_name)
|
||||
{
|
||||
std::string err_name;
|
||||
|
||||
// no error
|
||||
EXPECT_THROW(nix_err_name(NULL, ctx, OBSERVE_STRING(err_name)), nix::Error);
|
||||
|
||||
try {
|
||||
throw nix::Error("testing error");
|
||||
} catch (...) {
|
||||
nix_context_error(ctx);
|
||||
}
|
||||
auto new_ctx = createOwnedNixContext();
|
||||
nix_err_name(new_ctx.get(), ctx, OBSERVE_STRING(err_name));
|
||||
ASSERT_EQ(std::string(err_name), "nix::Error");
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_err_code)
|
||||
{
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_OK);
|
||||
|
|
|
|||
85
src/libutil-tests/nix_api_util_internal.cc
Normal file
85
src/libutil-tests/nix_api_util_internal.cc
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
#include "nix/util/config-global.hh"
|
||||
#include "nix/util/args.hh"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_util_internal.h"
|
||||
#include "nix/util/tests/nix_api_util.hh"
|
||||
#include "nix/util/tests/string_callback.hh"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "util-tests-config.hh"
|
||||
|
||||
namespace nixC {
|
||||
|
||||
TEST_F(nix_api_util_context, nix_context_error)
|
||||
{
|
||||
std::string err_msg_ref;
|
||||
try {
|
||||
throw nix::Error("testing error");
|
||||
} catch (nix::Error & e) {
|
||||
err_msg_ref = e.what();
|
||||
nix_context_error(ctx);
|
||||
}
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_ERR_NIX_ERROR);
|
||||
ASSERT_EQ(ctx->name, "nix::Error");
|
||||
ASSERT_EQ(*ctx->last_err, err_msg_ref);
|
||||
ASSERT_EQ(ctx->info->msg.str(), "testing error");
|
||||
|
||||
try {
|
||||
throw std::runtime_error("testing exception");
|
||||
} catch (std::exception & e) {
|
||||
err_msg_ref = e.what();
|
||||
nix_context_error(ctx);
|
||||
}
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_ERR_UNKNOWN);
|
||||
ASSERT_EQ(*ctx->last_err, err_msg_ref);
|
||||
|
||||
nix_clear_err(ctx);
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_OK);
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_set_err_msg)
|
||||
{
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_OK);
|
||||
nix_set_err_msg(ctx, NIX_ERR_UNKNOWN, "unknown test error");
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_ERR_UNKNOWN);
|
||||
ASSERT_EQ(*ctx->last_err, "unknown test error");
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_err_info_msg)
|
||||
{
|
||||
std::string err_info;
|
||||
|
||||
// no error
|
||||
EXPECT_THROW(nix_err_info_msg(NULL, ctx, OBSERVE_STRING(err_info)), nix::Error);
|
||||
|
||||
try {
|
||||
throw nix::Error("testing error");
|
||||
} catch (...) {
|
||||
nix_context_error(ctx);
|
||||
}
|
||||
auto new_ctx = createOwnedNixContext();
|
||||
nix_err_info_msg(new_ctx.get(), ctx, OBSERVE_STRING(err_info));
|
||||
ASSERT_STREQ("testing error", err_info.c_str());
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_err_name)
|
||||
{
|
||||
std::string err_name;
|
||||
|
||||
// no error
|
||||
EXPECT_THROW(nix_err_name(NULL, ctx, OBSERVE_STRING(err_name)), nix::Error);
|
||||
|
||||
try {
|
||||
throw nix::Error("testing error");
|
||||
} catch (...) {
|
||||
nix_context_error(ctx);
|
||||
}
|
||||
auto new_ctx = createOwnedNixContext();
|
||||
nix_err_name(new_ctx.get(), ctx, OBSERVE_STRING(err_name));
|
||||
ASSERT_EQ(std::string(err_name), "nix::Error");
|
||||
}
|
||||
|
||||
} // namespace nixC
|
||||
Loading…
Add table
Add a link
Reference in a new issue