]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib\cache: removing of global instance of cache storage api
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Fri, 29 May 2015 11:12:17 +0000 (13:12 +0200)
committerGrigorii Demidov <grigorii.demidov@nic.cz>
Fri, 29 May 2015 11:12:17 +0000 (13:12 +0200)
daemon/bindings.c
lib/cache.c
lib/cache.h
modules/cachectl/cachectl.c
tests/test_cache.c
tests/test_integration.c

index ac0001241019e3e142692af28adcfd625806fbaf..3c936f6055cedc463c5ed13ea5c69a5ffc09c013 100644 (file)
@@ -299,7 +299,7 @@ static int cache_backends(lua_State *L)
        lua_newtable(L);
        for (unsigned i = 0; i < registry->len; ++i) {
                struct storage_api *storage = &registry->at[i];
-               lua_pushboolean(L, storage->api() == kr_cache_storage());
+               lua_pushboolean(L, storage->api() == engine->resolver.cache.api); /* kr_cache_storage()); */
                lua_setfield(L, -2, storage->prefix);
        }
        return 1;
@@ -309,7 +309,7 @@ static int cache_backends(lua_State *L)
 static int cache_count(lua_State *L)
 {
        struct engine *engine = engine_luaget(L);
-       const namedb_api_t *storage = kr_cache_storage();
+       const namedb_api_t *storage = engine->resolver.cache.api; /* kr_cache_storage(); */
 
        /* Fetch item count */
        struct kr_cache_txn txn;
@@ -390,9 +390,9 @@ static int cache_open(lua_State *L)
        kr_cache_close(&engine->resolver.cache);
 
        /* Reopen cache */
-       kr_cache_storage_set(storage->api);
+       /* kr_cache_storage_set(storage->api); */
        void *storage_opts = storage->opts_create(conf, cache_size);
-       int ret = kr_cache_open(&engine->resolver.cache, storage_opts, engine->pool);
+       int ret = kr_cache_open(&engine->resolver.cache, storage->api(), storage_opts, engine->pool);
        free(storage_opts);
        if (ret != 0) {
                format_error(L, "can't open cache");
index fb9c100e16506b68a25d16b74f1856de11d019bb..9f639d6d03d97a1e9f570a3f90382ae67a5228ba 100644 (file)
 
 /* Key size */
 #define KEY_SIZE (sizeof(uint8_t) + KNOT_DNAME_MAXLEN + sizeof(uint16_t))
+#define db_api(cache) (cache->api)
 
-/**
- * Used cache storage engine (default LMDB)
- * @todo namedb_t should change so it always contains a pointer
- *       to its API, so it can be carried around instead of keeping it in a
- *       global variable.
- */
-const namedb_api_t *(*kr_cache_storage)(void) = namedb_lmdb_api;
-#define db_api kr_cache_storage()
-
-int kr_cache_open(struct kr_cache *cache, void *opts, mm_ctx_t *mm)
+int kr_cache_open(struct kr_cache *cache, const namedb_api_t *api, void *opts, mm_ctx_t *mm)
 {
        if (!cache) {
                return kr_error(EINVAL);
        }
-       int ret = db_api->init(&cache->db, mm, opts);
+       db_api(cache) = (api == NULL) ? namedb_lmdb_api() : api;
+       int ret = db_api(cache)->init(&cache->db, mm, opts);
        if (ret != 0) {
                return ret;
        }
@@ -56,8 +49,8 @@ int kr_cache_open(struct kr_cache *cache, void *opts, mm_ctx_t *mm)
 void kr_cache_close(struct kr_cache *cache)
 {
        if (cache && cache->db) {
-               if (db_api) {
-                       db_api->deinit(cache->db);
+               if (db_api(cache)) {
+                       db_api(cache)->deinit(cache->db);
                }
                cache->db = NULL;
        }
@@ -65,7 +58,7 @@ void kr_cache_close(struct kr_cache *cache)
 
 int kr_cache_txn_begin(struct kr_cache *cache, struct kr_cache_txn *txn, unsigned flags)
 {
-       if (!cache || !cache->db || !txn) {
+       if (!cache || !cache->db || !db_api(cache) || !txn ) {
                return kr_error(EINVAL);
        }
 
@@ -75,16 +68,16 @@ int kr_cache_txn_begin(struct kr_cache *cache, struct kr_cache_txn *txn, unsigne
                cache->stats.txn_write += 1;
        }
        txn->owner = cache;
-       return db_api->txn_begin(cache->db, (namedb_txn_t *)txn, flags);
+       return db_api(cache)->txn_begin(cache->db, (namedb_txn_t *)txn, flags);
 }
 
 int kr_cache_txn_commit(struct kr_cache_txn *txn)
 {
-       if (!txn) {
+       if (!txn || !txn->owner) {
                return kr_error(EINVAL);
        }
 
-       int ret = db_api->txn_commit((namedb_txn_t *)txn);
+       int ret = db_api(txn->owner)->txn_commit((namedb_txn_t *)txn);
        if (ret != 0) {
                kr_cache_txn_abort(txn);
        }
@@ -93,8 +86,8 @@ int kr_cache_txn_commit(struct kr_cache_txn *txn)
 
 void kr_cache_txn_abort(struct kr_cache_txn *txn)
 {
-       if (txn) {
-               db_api->txn_abort((namedb_txn_t *)txn);
+       if (txn && txn->owner) {
+               db_api(txn->owner)->txn_abort((namedb_txn_t *)txn);
        }
 }
 
@@ -108,15 +101,18 @@ static size_t cache_key(uint8_t *buf, uint8_t tag, const knot_dname_t *name, uin
        return len + sizeof(type);
 }
 
-static struct kr_cache_entry *cache_entry(namedb_txn_t *txn, uint8_t tag, const knot_dname_t *name, uint16_t type)
+static struct kr_cache_entry *cache_entry(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *name, uint16_t type)
 {
        uint8_t keybuf[KEY_SIZE];
        size_t key_len = cache_key(keybuf, tag, name, type);
+       if (!txn || !txn->owner) {
+               return NULL;
+       }
 
        /* Look up and return value */
        namedb_val_t key = { keybuf, key_len };
        namedb_val_t val = { NULL, 0 };
-       int ret = db_api->find(txn, &key, &val, 0);
+       int ret = db_api(txn->owner)->find((namedb_txn_t *)txn, &key, &val, 0);
        if (ret != KNOT_EOK) {
                return NULL;
        }
@@ -131,7 +127,7 @@ struct kr_cache_entry *kr_cache_peek(struct kr_cache_txn *txn, uint8_t tag, cons
                return NULL;
        }
 
-       struct kr_cache_entry *entry = cache_entry((namedb_txn_t *)txn, tag, name, type);
+       struct kr_cache_entry *entry = cache_entry(txn, tag, name, type);
        if (!entry) {
                txn->owner->stats.miss += 1;
                return NULL;
@@ -170,7 +166,7 @@ static void entry_write(struct kr_cache_entry *dst, struct kr_cache_entry *heade
 int kr_cache_insert(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *name, uint16_t type,
                     struct kr_cache_entry *header, namedb_val_t data)
 {
-       if (!txn || !name || !tag || !header) {
+       if (!txn || !txn->owner || !name || !tag || !header) {
                return kr_error(EINVAL);
        }
 
@@ -182,8 +178,8 @@ int kr_cache_insert(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *n
 
        /* LMDB can do late write and avoid copy */
        txn->owner->stats.insert += 1;
-       if (db_api == namedb_lmdb_api()) {
-               int ret = db_api->insert((namedb_txn_t *)txn, &key, &entry, 0);
+       if (db_api(txn->owner) == namedb_lmdb_api()) {
+               int ret = db_api(txn->owner)->insert((namedb_txn_t *)txn, &key, &entry, 0);
                if (ret != 0) {
                        return ret;
                }
@@ -195,7 +191,7 @@ int kr_cache_insert(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *n
                        return kr_error(ENOMEM);
                }
                entry_write(entry.data, header, data);
-               int ret = db_api->insert((namedb_txn_t *)txn, &key, &entry, 0);
+               int ret = db_api(txn->owner)->insert((namedb_txn_t *)txn, &key, &entry, 0);
                free(entry.data);
                if (ret != 0) {
                        return ret;
@@ -207,7 +203,7 @@ int kr_cache_insert(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *n
 
 int kr_cache_remove(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *name, uint16_t type)
 {
-       if (!txn || !tag || !name ) {
+       if (!txn || !txn->owner || !tag || !name ) {
                return kr_error(EINVAL);
        }
 
@@ -215,16 +211,16 @@ int kr_cache_remove(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *n
        size_t key_len = cache_key(keybuf, tag, name, type);
        namedb_val_t key = { keybuf, key_len };
        txn->owner->stats.delete += 1;
-       return db_api->del((namedb_txn_t *)txn, &key);
+       return db_api(txn->owner)->del((namedb_txn_t *)txn, &key);
 }
 
 int kr_cache_clear(struct kr_cache_txn *txn)
 {
-       if (!txn) {
+       if (!txn || !txn->owner ) {
                return kr_error(EINVAL);
        }
 
-       return db_api->clear((namedb_txn_t *)txn);
+       return db_api(txn->owner)->clear((namedb_txn_t *)txn);
 }
 
 int kr_cache_peek_rr(struct kr_cache_txn *txn, knot_rrset_t *rr, uint32_t *timestamp)
index 55c2eb027d1250af9896ed5664501fae2e4fc436..1b7c48526ea6d9325412f6d6347931e452c649b7 100644 (file)
@@ -43,15 +43,16 @@ struct kr_cache_entry
  */
 struct kr_cache
 {
-    namedb_t *db;             /**< Storage instance */
-    struct {
-        uint32_t hit;         /**< Number of cache hits */
-        uint32_t miss;        /**< Number of cache misses */
-        uint32_t insert;      /**< Number of insertions */
-        uint32_t delete;      /**< Number of deletions */
-        uint32_t txn_read;    /**< Number of read transactions */
-        uint32_t txn_write;   /**< Number of write transactions */
-    } stats;
+       namedb_t *db;                 /**< Storage instance */
+       const namedb_api_t *api;      /**< Storage engine */
+       struct {
+               uint32_t hit;         /**< Number of cache hits */
+               uint32_t miss;        /**< Number of cache misses */
+               uint32_t insert;      /**< Number of insertions */
+               uint32_t delete;      /**< Number of deletions */
+               uint32_t txn_read;    /**< Number of read transactions */
+               uint32_t txn_write;   /**< Number of write transactions */
+       } stats;
 };
 
 /** Cache transaction */
@@ -61,22 +62,23 @@ struct kr_cache_txn {
 };
 
 /** Used storage backend for cache (default LMDB) */
-extern const namedb_api_t *(*kr_cache_storage)(void);
+//extern const namedb_api_t *(*kr_cache_storage)(void);
 
 /** Replace used cache storage backend. */
-static inline void kr_cache_storage_set(const namedb_api_t *(*api)(void))
-{
-       kr_cache_storage = api;
-}
+//static inline void kr_cache_storage_set(const namedb_api_t *(*api)(void))
+//{
+//     kr_cache_storage = api;
+//}
 
 /**
  * Open/create cache with provided storage options.
  * @param cache cache structure to be initialized
+ * @param api Storage engine
  * @param storage_opts Storage-specific options (may be NULL for default)
  * @param mm Memory context.
  * @return 0 or an error code
  */
-int kr_cache_open(struct kr_cache *cache, void *opts, mm_ctx_t *mm);
+int kr_cache_open(struct kr_cache *cache, const namedb_api_t *api, void *opts, mm_ctx_t *mm);
 
 /**
  * Close persistent cache.
index 39cf66110f414f699cc9a011308b43e6053d3a89..e7dc22c2b8c01e8f91f5ceb5ea870fd9c9c9c6e9 100644 (file)
@@ -51,7 +51,7 @@ static bool is_expired(struct kr_cache_entry *entry, uint32_t drift)
 static char* prune(void *env, struct kr_module *module, const char *args)
 {
        struct engine *engine = env;
-       const namedb_api_t *storage = kr_cache_storage();
+       const namedb_api_t *storage = engine->resolver.cache.api; /* kr_cache_storage(); */
 
        struct kr_cache_txn txn;
        int ret = kr_cache_txn_begin(&engine->resolver.cache, &txn, 0);
index a4125d834516c0ff8f8cb60b07e7a04534a44344..9312c74c2e20947bf37db52b4a1c1a0a3e09ec94 100644 (file)
@@ -39,32 +39,32 @@ namedb_val_t global_namedb_data = {namedb_data, NAMEDB_DATA_SIZE};
 #define CACHE_TIME 0
 
 /* Simulate init failure */
-static int test_init_failure(namedb_t **db_ptr, mm_ctx_t *mm, void *arg)
+static int fake_test_init(namedb_t **db_ptr, mm_ctx_t *mm, void *arg)
 {
-       return KNOT_EINVAL;
+       return mock();
 }
 
 /* Simulate commit failure */
-static int test_commit_failure(namedb_txn_t *txn)
+static int fake_test_commit(namedb_txn_t *txn)
 {
        return KNOT_ESPACE;
 }
 
 /* Dummy abort */
-static void test_abort(namedb_txn_t *txn)
+static void fake_test_abort(namedb_txn_t *txn)
 {
        return;
 }
 
 /* Stub for find */
-static int test_find(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, unsigned flags)
+static int fake_test_find(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, unsigned flags)
 {
        val->data = &global_fake_ce;
        return KNOT_EOK;
 }
 
 /* Stub for insert */
-static int test_ins(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, unsigned flags)
+static int fake_test_ins(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, unsigned flags)
 {
        int err = KNOT_EINVAL, res_cmp;
        struct kr_cache_entry *header = val->data;
@@ -81,19 +81,51 @@ static int test_ins(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, uns
        return err;
 }
 
+/* Fake api */
+static namedb_api_t *fake_namedb_lmdb_api(void)
+{
+       static namedb_api_t fake_api = {
+               "lmdb_fake_api",
+               fake_test_init, NULL,
+               NULL, fake_test_commit, fake_test_abort,
+               NULL, NULL, fake_test_find, fake_test_ins, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL
+       };
+
+       return &fake_api;
+}
+
 /* Test cache open */
-static void test_open(void **state)
+static int test_open(void **state, namedb_api_t *api)
 {
        static struct kr_cache cache;
        struct namedb_lmdb_opts opts;
        memset(&opts, 0, sizeof(opts));
        opts.path = global_env;
        opts.mapsize = CACHE_SIZE;
-       int ret = kr_cache_open(&cache, &opts, &global_mm);
-       assert_int_equal(ret, 0);
        *state = &cache;
+       return kr_cache_open(&cache, api, &opts, &global_mm);
+}
+
+/* fake api test open */
+static void test_open_fake_api(void **state)
+{
+       bool res;
+       will_return(fake_test_init,KNOT_EOK);
+       assert_int_equal(test_open(state, fake_namedb_lmdb_api()),KNOT_EOK);
+       res = (((struct kr_cache *)(*state))->api == fake_namedb_lmdb_api());
+       assert_true(res);
+}
+
+static void test_open_conventional_api(void **state)
+{
+       bool res;
+       assert_int_equal(test_open(state, NULL),KNOT_EOK);
+       res = (((struct kr_cache *)(*state))->api == namedb_lmdb_api());
+       assert_true(res);
 }
 
+
 /* Test cache teardown. */
 static void test_close(void **state)
 {
@@ -101,7 +133,6 @@ static void test_close(void **state)
        *state = NULL;
 }
 
-
 /* Open transaction */
 static struct kr_cache_txn *test_txn_write(void **state)
 {
@@ -118,46 +149,18 @@ static struct kr_cache_txn *test_txn_rdonly(void **state)
        return &global_txn;
 }
 
-/* Fake api */
-static const namedb_api_t *namedb_lmdb_api_fake(void)
+/* test invalid parameters and some api failures */
+static void test_fake_invalid (void **state)
 {
-       static const namedb_api_t api_fake = {
-               "lmdb_api_fake",
-               test_init_failure, NULL,
-               NULL, test_commit_failure, test_abort,
-               NULL, NULL, test_find, test_ins, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL
-       };
-
-       return &api_fake;
+//     knot_dname_t dname[] = "";
+//     assert_null(kr_cache_open(NULL, NULL, NULL));
+//     assert_int_equal(kr_cache_peek(&global_txn, KR_CACHE_USER, dname, KNOT_RRTYPE_TSIG, 0),
+//             &global_fake_ce);
+//     assert_int_not_equal(kr_cache_txn_commit(&global_txn), KNOT_EOK);
+       will_return(fake_test_init,KNOT_EINVAL);
+       assert_int_equal(test_open(state, fake_namedb_lmdb_api()),KNOT_EINVAL);
 }
 
-static void test_failures(void **state)
-{
-       const namedb_api_t *(*kr_cache_storage_saved)(void);
-       void *ret_cache_peek;
-       int ret_commit;
-       int ret_open;
-       knot_dname_t dname[] = "";
-
-       /* Get read transaction */
-       struct kr_cache_txn *txn = test_txn_rdonly(state);
-       /* save original api */
-       kr_cache_storage_saved = kr_cache_storage;
-       /* fake to simulate failures or constant success */
-       kr_cache_storage_set(namedb_lmdb_api_fake);
-
-       /* call kr_cache_peek() with no time constraint */
-       ret_cache_peek = kr_cache_peek(txn, KR_CACHE_USER, dname, KNOT_RRTYPE_TSIG, 0);
-       ret_open = kr_cache_open(NULL, NULL, NULL);
-       ret_commit = kr_cache_txn_commit(txn);
-
-       /* restore */
-       kr_cache_storage_set(kr_cache_storage_saved);
-       assert_int_equal(ret_cache_peek, &global_fake_ce);
-       assert_int_not_equal(ret_open, KNOT_EOK);
-       assert_int_not_equal(ret_commit, KNOT_EOK);
-}
 
 /* Test invalid parameters and some api failures. */
 static void test_invalid(void **state)
@@ -175,6 +178,7 @@ static void test_invalid(void **state)
        assert_int_not_equal(kr_cache_peek_rr(&global_txn, NULL, NULL), 0);
        assert_int_not_equal(kr_cache_insert_rr(&global_txn, NULL, 0), 0);
        assert_int_not_equal(kr_cache_insert_rr(NULL, NULL, 0), 0);
+       assert_int_equal(kr_cache_insert_rr(&global_txn, &global_rr, 0), 0);
        assert_int_not_equal(kr_cache_insert(NULL, KR_CACHE_USER, dname,
                KNOT_RRTYPE_TSIG, &global_fake_ce, global_namedb_data), 0);
        assert_int_not_equal(kr_cache_insert(&global_txn, 0, dname,
@@ -190,13 +194,9 @@ static void test_invalid(void **state)
 }
 
 /* Test cache write */
-static void test_insert(void **state)
+static void test_insert_rr(void **state)
 {
-       const namedb_api_t *(*kr_cache_storage_saved)(void);
-       int i, ret_cache_insert;
-       knot_dname_t dname[] = "";
        test_random_rr(&global_rr, CACHE_TTL);
-
        struct kr_cache_txn *txn = test_txn_write(state);
        int ret = kr_cache_insert_rr(txn, &global_rr, CACHE_TIME);
        if (ret == KNOT_EOK) {
@@ -204,26 +204,7 @@ static void test_insert(void **state)
        } else {
                kr_cache_txn_abort(txn);
        }
-
        assert_int_equal(ret, KNOT_EOK);
-
-       memset(&global_fake_ce,0xAA,sizeof(global_fake_ce));
-       srand(time(NULL));
-       for (i = 0; i < NAMEDB_DATA_SIZE; i += 4)
-       {
-           int r = rand();
-           namedb_data[i] = r;
-           namedb_data[i + 1] = r >> 8;
-           namedb_data[i + 2] = r >> 16;
-           namedb_data[i + 3] = r >> 24;
-       }
-
-       kr_cache_storage_saved = kr_cache_storage;
-       kr_cache_storage_set(namedb_lmdb_api_fake);
-       ret_cache_insert = kr_cache_insert(&global_txn, KR_CACHE_USER, dname,
-               KNOT_RRTYPE_TSIG, &global_fake_ce, global_namedb_data);
-       kr_cache_storage_set(kr_cache_storage_saved);
-       assert_int_equal(ret_cache_insert, KNOT_EOK);
 }
 
 /* Test cache read */
@@ -324,16 +305,15 @@ int main(void)
 
        /* Invalid input */
        const UnitTest tests_bad[] = {
-               group_test_setup(test_open),
-               unit_test(test_invalid),
-               unit_test(test_failures),
+               group_test_setup(test_open_fake_api),
+               unit_test(test_fake_invalid),
                group_test_teardown(test_close)
        };
 
        const UnitTest tests[] = {
                /* Cache persistence */
-               group_test_setup(test_open),
-               unit_test(test_insert),
+               group_test_setup(test_open_conventional_api),
+               unit_test(test_insert_rr),
                unit_test(test_query),
                /* Cache aging */
                unit_test(test_query_aged),
index 357129c8e501bfbafd53e8bcee95906d2e33eb75..1a322029675e268b8872aff17dfcdc57c9c9afb3 100644 (file)
@@ -71,8 +71,7 @@ static PyObject* init(PyObject* self, PyObject* args)
        memset(&opts, 0, sizeof(opts));
        opts.path = global_tmpdir;
        opts.mapsize = 100 * 4096;
-       kr_cache_storage_set(namedb_lmdb_api);
-       int ret = kr_cache_open(&global_context.cache, &opts, &global_mm);
+       int ret = kr_cache_open(&global_context.cache, NULL, &opts, &global_mm);
        assert(ret == 0);
 
        /* No configuration parsing support yet. */