// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/* Copyright (c) 2018 Mellanox Technologies. All rights reserved */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/objagg.h>

struct tokey {
	unsigned int id;
};

#define NUM_KEYS 32

static int key_id_index(unsigned int key_id)
{
	if (key_id >= NUM_KEYS) {
		WARN_ON(1);
		return 0;
	}
	return key_id;
}

#define BUF_LEN 128

struct world {
	unsigned int root_count;
	unsigned int delta_count;
	char next_root_buf[BUF_LEN];
	struct objagg_obj *objagg_objs[NUM_KEYS];
	unsigned int key_refs[NUM_KEYS];
};

struct root {
	struct tokey key;
	char buf[BUF_LEN];
};

struct delta {
	unsigned int key_id_diff;
};

static struct objagg_obj *world_obj_get(struct world *world,
					struct objagg *objagg,
					unsigned int key_id)
{
	struct objagg_obj *objagg_obj;
	struct tokey key;
	int err;

	key.id = key_id;
	objagg_obj = objagg_obj_get(objagg, &key);
	if (IS_ERR(objagg_obj)) {
		pr_err("Key %u: Failed to get object.\n", key_id);
		return objagg_obj;
	}
	if (!world->key_refs[key_id_index(key_id)]) {
		world->objagg_objs[key_id_index(key_id)] = objagg_obj;
	} else if (world->objagg_objs[key_id_index(key_id)] != objagg_obj) {
		pr_err("Key %u: Got another object for the same key.\n",
		       key_id);
		err = -EINVAL;
		goto err_key_id_check;
	}
	world->key_refs[key_id_index(key_id)]++;
	return objagg_obj;

err_key_id_check:
	objagg_obj_put(objagg, objagg_obj);
	return ERR_PTR(err);
}

static void world_obj_put(struct world *world, struct objagg *objagg,
			  unsigned int key_id)
{
	struct objagg_obj *objagg_obj;

	if (!world->key_refs[key_id_index(key_id)])
		return;
	objagg_obj = world->objagg_objs[key_id_index(key_id)];
	objagg_obj_put(objagg, objagg_obj);
	world->key_refs[key_id_index(key_id)]--;
}

#define MAX_KEY_ID_DIFF 5

static bool delta_check(void *priv, const void *parent_obj, const void *obj)
{
	const struct tokey *parent_key = parent_obj;
	const struct tokey *key = obj;
	int diff = key->id - parent_key->id;

	return diff >= 0 && diff <= MAX_KEY_ID_DIFF;
}

static void *delta_create(void *priv, void *parent_obj, void *obj)
{
	struct tokey *parent_key = parent_obj;
	struct world *world = priv;
	struct tokey *key = obj;
	int diff = key->id - parent_key->id;
	struct delta *delta;

	if (!delta_check(priv, parent_obj, obj))
		return ERR_PTR(-EINVAL);

	delta = kzalloc_obj(*delta);
	if (!delta)
		return ERR_PTR(-ENOMEM);
	delta->key_id_diff = diff;
	world->delta_count++;
	return delta;
}

static void delta_destroy(void *priv, void *delta_priv)
{
	struct delta *delta = delta_priv;
	struct world *world = priv;

	world->delta_count--;
	kfree(delta);
}

static void *root_create(void *priv, void *obj, unsigned int id)
{
	struct world *world = priv;
	struct tokey *key = obj;
	struct root *root;

	root = kzalloc_obj(*root);
	if (!root)
		return ERR_PTR(-ENOMEM);
	memcpy(&root->key, key, sizeof(root->key));
	memcpy(root->buf, world->next_root_buf, sizeof(root->buf));
	world->root_count++;
	return root;
}

static void root_destroy(void *priv, void *root_priv)
{
	struct root *root = root_priv;
	struct world *world = priv;

	world->root_count--;
	kfree(root);
}

static int test_nodelta_obj_get(struct world *world, struct objagg *objagg,
				unsigned int key_id, bool should_create_root)
{
	unsigned int orig_root_count = world->root_count;
	struct objagg_obj *objagg_obj;
	const struct root *root;
	int err;

	if (should_create_root)
		get_random_bytes(world->next_root_buf,
			      sizeof(world->next_root_buf));

	objagg_obj = world_obj_get(world, objagg, key_id);
	if (IS_ERR(objagg_obj)) {
		pr_err("Key %u: Failed to get object.\n", key_id);
		return PTR_ERR(objagg_obj);
	}
	if (should_create_root) {
		if (world->root_count != orig_root_count + 1) {
			pr_err("Key %u: Root was not created\n", key_id);
			err = -EINVAL;
			goto err_check_root_count;
		}
	} else {
		if (world->root_count != orig_root_count) {
			pr_err("Key %u: Root was incorrectly created\n",
			       key_id);
			err = -EINVAL;
			goto err_check_root_count;
		}
	}
	root = objagg_obj_root_priv(objagg_obj);
	if (root->key.id != key_id) {
		pr_err("Key %u: Root has unexpected key id\n", key_id);
		err = -EINVAL;
		goto err_check_key_id;
	}
	if (should_create_root &&
	    memcmp(world->next_root_buf, root->buf, sizeof(root->buf))) {
		pr_err("Key %u: Buffer does not match the expected content\n",
		       key_id);
		err = -EINVAL;
		goto err_check_buf;
	}
	return 0;

err_check_buf:
err_check_key_id:
err_check_root_count:
	objagg_obj_put(objagg, objagg_obj);
	return err;
}

static int test_nodelta_obj_put(struct world *world, struct objagg *objagg,
				unsigned int key_id, bool should_destroy_root)
{
	unsigned int orig_root_count = world->root_count;

	world_obj_put(world, objagg, key_id);

	if (should_destroy_root) {
		if (world->root_count != orig_root_count - 1) {
			pr_err("Key %u: Root was not destroyed\n", key_id);
			return -EINVAL;
		}
	} else {
		if (world->root_count != orig_root_count) {
			pr_err("Key %u: Root was incorrectly destroyed\n",
			       key_id);
			return -EINVAL;
		}
	}
	return 0;
}

static int check_stats_zero(struct objagg *objagg)
{
	const struct objagg_stats *stats;
	int err = 0;

	stats = objagg_stats_get(objagg);
	if (IS_ERR(stats))
		return PTR_ERR(stats);

	if (stats->stats_info_count != 0) {
		pr_err("Stats: Object count is not zero while it should be\n");
		err = -EINVAL;
	}

	objagg_stats_put(stats);
	return err;
}

static int check_stats_nodelta(struct objagg *objagg)
{
	const struct objagg_stats *stats;
	int i;
	int err;

	stats = objagg_stats_get(objagg);
	if (IS_ERR(stats))
		return PTR_ERR(stats);

	if (stats->stats_info_count != NUM_KEYS) {
		pr_err("Stats: Unexpected object count (%u expected, %u returned)\n",
		       NUM_KEYS, stats->stats_info_count);
		err = -EINVAL;
		goto stats_put;
	}

	for (i = 0; i < stats->stats_info_count; i++) {
		if (stats->stats_info[i].stats.user_count != 2) {
			pr_err("Stats: incorrect user count\n");
			err = -EINVAL;
			goto stats_put;
		}
		if (stats->stats_info[i].stats.delta_user_count != 2) {
			pr_err("Stats: incorrect delta user count\n");
			err = -EINVAL;
			goto stats_put;
		}
	}
	err = 0;

stats_put:
	objagg_stats_put(stats);
	return err;
}

static bool delta_check_dummy(void *priv, const void *parent_obj,
			      const void *obj)
{
	return false;
}

static void *delta_create_dummy(void *priv, void *parent_obj, void *obj)
{
	return ERR_PTR(-EOPNOTSUPP);
}

static void delta_destroy_dummy(void *priv, void *delta_priv)
{
}

static const struct objagg_ops nodelta_ops = {
	.obj_size = sizeof(struct tokey),
	.delta_check = delta_check_dummy,
	.delta_create = delta_create_dummy,
	.delta_destroy = delta_destroy_dummy,
	.root_create = root_create,
	.root_destroy = root_destroy,
};

static int test_nodelta(void)
{
	struct world world = {};
	struct objagg *objagg;
	int i;
	int err;

	objagg = objagg_create(&nodelta_ops, NULL, &world);
	if (IS_ERR(objagg))
		return PTR_ERR(objagg);

	err = check_stats_zero(objagg);
	if (err)
		goto err_stats_first_zero;

	/* First round of gets, the root objects should be created */
	for (i = 0; i < NUM_KEYS; i++) {
		err = test_nodelta_obj_get(&world, objagg, i, true);
		if (err)
			goto err_obj_first_get;
	}

	/* Do the second round of gets, all roots are already created,
	 * make sure that no new root is created
	 */
	for (i = 0; i < NUM_KEYS; i++) {
		err = test_nodelta_obj_get(&world, objagg, i, false);
		if (err)
			goto err_obj_second_get;
	}

	err = check_stats_nodelta(objagg);
	if (err)
		goto err_stats_nodelta;

	for (i = NUM_KEYS - 1; i >= 0; i--) {
		err = test_nodelta_obj_put(&world, objagg, i, false);
		if (err)
			goto err_obj_first_put;
	}
	for (i = NUM_KEYS - 1; i >= 0; i--) {
		err = test_nodelta_obj_put(&world, objagg, i, true);
		if (err)
			goto err_obj_second_put;
	}

	err = check_stats_zero(objagg);
	if (err)
		goto err_stats_second_zero;

	objagg_destroy(objagg);
	return 0;

err_stats_nodelta:
err_obj_first_put:
err_obj_second_get:
	for (i--; i >= 0; i--)
		world_obj_put(&world, objagg, i);

	i = NUM_KEYS;
err_obj_first_get:
err_obj_second_put:
	for (i--; i >= 0; i--)
		world_obj_put(&world, objagg, i);
err_stats_first_zero:
err_stats_second_zero:
	objagg_destroy(objagg);
	return err;
}

static const struct objagg_ops delta_ops = {
	.obj_size = sizeof(struct tokey),
	.delta_check = delta_check,
	.delta_create = delta_create,
	.delta_destroy = delta_destroy,
	.root_create = root_create,
	.root_destroy = root_destroy,
};

enum action {
	ACTION_GET,
	ACTION_PUT,
};

enum expect_delta {
	EXPECT_DELTA_SAME,
	EXPECT_DELTA_INC,
	EXPECT_DELTA_DEC,
};

enum expect_root {
	EXPECT_ROOT_SAME,
	EXPECT_ROOT_INC,
	EXPECT_ROOT_DEC,
};

struct expect_stats_info {
	struct objagg_obj_stats stats;
	bool is_root;
	unsigned int key_id;
};

struct expect_stats {
	unsigned int info_count;
	struct expect_stats_info info[NUM_KEYS];
};

struct action_item {
	unsigned int key_id;
	enum action action;
	enum expect_delta expect_delta;
	enum expect_root expect_root;
	struct expect_stats expect_stats;
};

#define EXPECT_STATS(count, ...)		\
{						\
	.info_count = count,			\
	.info = { __VA_ARGS__ }			\
}

#define ROOT(key_id, user_count, delta_user_count)	\
	{{user_count, delta_user_count}, true, key_id}

#define DELTA(key_id, user_count)			\
	{{user_count, user_count}, false, key_id}

static const struct action_item action_items[] = {
	{
		1, ACTION_GET, EXPECT_DELTA_SAME, EXPECT_ROOT_INC,
		EXPECT_STATS(1, ROOT(1, 1, 1)),
	},	/* r: 1			d: */
	{
		7, ACTION_GET, EXPECT_DELTA_SAME, EXPECT_ROOT_INC,
		EXPECT_STATS(2, ROOT(1, 1, 1), ROOT(7, 1, 1)),
	},	/* r: 1, 7		d: */
	{
		3, ACTION_GET, EXPECT_DELTA_INC, EXPECT_ROOT_SAME,
		EXPECT_STATS(3, ROOT(1, 1, 2), ROOT(7, 1, 1),
				DELTA(3, 1)),
	},	/* r: 1, 7		d: 3^1 */
	{
		5, ACTION_GET, EXPECT_DELTA_INC, EXPECT_ROOT_SAME,
		EXPECT_STATS(4, ROOT(1, 1, 3), ROOT(7, 1, 1),
				DELTA(3, 1), DELTA(5, 1)),
	},	/* r: 1, 7		d: 3^1, 5^1 */
	{
		3, ACTION_GET, EXPECT_DELTA_SAME, EXPECT_ROOT_SAME,
		EXPECT_STATS(4, ROOT(1, 1, 4), ROOT(7, 1, 1),
				DELTA(3, 2), DELTA(5, 1)),
	},	/* r: 1, 7		d: 3^1, 3^1, 5^1 */
	{
		1, ACTION_GET, EXPECT_DELTA_SAME, EXPECT_ROOT_SAME,
		EXPECT_STATS(4, ROOT(1, 2, 5), ROOT(7, 1, 1),
				DELTA(3, 2), DELTA(5, 1)),
	},	/* r: 1, 1, 7		d: 3^1, 3^1, 5^1 */
	{
		30, ACTION_GET, EXPECT_DELTA_SAME, EXPECT_ROOT_INC,
		EXPECT_STATS(5, ROOT(1, 2, 5), ROOT(7, 1, 1), ROOT(30, 1, 1),
				DELTA(3, 2), DELTA(5, 1)),
	},	/* r: 1, 1, 7, 30	d: 3^1, 3^1, 5^1 */
	{
		8, ACTION_GET, EXPECT_DELTA_INC, EXPECT_ROOT_SAME,
		EXPECT_STATS(6, ROOT(1, 2, 5), ROOT(7, 1, 2), ROOT(30, 1, 1),
				DELTA(3, 2), DELTA(5, 1), DELTA(8, 1)),
	},	/* r: 1, 1, 7, 30	d: 3^1, 3^1, 5^1, 8^7 */
	{
		8, ACTION_GET, EXPECT_DELTA_SAME, EXPECT_ROOT_SAME,
		EXPECT_STATS(6, ROOT(1, 2, 5), ROOT(7, 1, 3), ROOT(30, 1, 1),
				DELTA(3, 2), DELTA(8, 2), DELTA(5, 1)),
	},	/* r: 1, 1, 7, 30	d: 3^1, 3^1, 5^1, 8^7, 8^7 */
	{
		3, ACTION_PUT, EXPECT_DELTA_SAME, EXPECT_ROOT_SAME,
		EXPECT_STATS(6, ROOT(1, 2, 4), ROOT(7, 1, 3), ROOT(30, 1, 1),
				DELTA(8, 2), DELTA(3, 1), DELTA(5, 1)),
	},	/* r: 1, 1, 7, 30	d: 3^1, 5^1, 8^7, 8^7 */
	{
		3, ACTION_PUT, EXPECT_DELTA_DEC, EXPECT_ROOT_SAME,
		EXPECT_STATS(5, ROOT(1, 2, 3), ROOT(7, 1, 3), ROOT(30, 1, 1),
				DELTA(8, 2), DELTA(5, 1)),
	},	/* r: 1, 1, 7, 30	d: 5^1, 8^7, 8^7 */
	{
		1, ACTION_PUT, EXPECT_DELTA_SAME, EXPECT_ROOT_SAME,
		EXPECT_STATS(5, ROOT(7, 1, 3), ROOT(1, 1, 2), ROOT(30, 1, 1),
				DELTA(8, 2), DELTA(5, 1)),
	},	/* r: 1, 7, 30		d: 5^1, 8^7, 8^7 */
	{
		1, ACTION_PUT, EXPECT_DELTA_SAME, EXPECT_ROOT_SAME,
		EXPECT_STATS(5, ROOT(7, 1, 3), ROOT(30, 1, 1), ROOT(1, 0, 1),
				DELTA(8, 2), DELTA(5, 1)),
	},	/* r: 7, 30		d: 5^1, 8^7, 8^7 */
	{
		5, ACTION_PUT, EXPECT_DELTA_DEC, EXPECT_ROOT_DEC,
		EXPECT_STATS(3, ROOT(7, 1, 3), ROOT(30, 1, 1),
				DELTA(8, 2)),
	},	/* r: 7, 30		d: 8^7, 8^7 */
	{
		5, ACTION_GET, EXPECT_DELTA_SAME, EXPECT_ROOT_INC,
		EXPECT_STATS(4, ROOT(7, 1, 3), ROOT(30, 1, 1), ROOT(5, 1, 1),
				DELTA(8, 2)),
	},	/* r: 7, 30, 5		d: 8^7, 8^7 */
	{
		6, ACTION_GET, EXPECT_DELTA_INC, EXPECT_ROOT_SAME,
		EXPECT_STATS(5, ROOT(7, 1, 3), ROOT(5, 1, 2), ROOT(30, 1, 1),
				DELTA(8, 2), DELTA(6, 1)),
	},	/* r: 7, 30, 5		d: 8^7, 8^7, 6^5 */
	{
		8, ACTION_GET, EXPECT_DELTA_SAME, EXPECT_ROOT_SAME,
		EXPECT_STATS(5, ROOT(7, 1, 4), ROOT(5, 1, 2), ROOT(30, 1, 1),
				DELTA(8, 3), DELTA(6, 1)),
	},	/* r: 7, 30, 5		d: 8^7, 8^7, 8^7, 6^5 */
	{
		8, ACTION_PUT, EXPECT_DELTA_SAME, EXPECT_ROOT_SAME,
		EXPECT_STATS(5, ROOT(7, 1, 3), ROOT(5, 1, 2), ROOT(30, 1, 1),
				DELTA(8, 2), DELTA(6, 1)),
	},	/* r: 7, 30, 5		d: 8^7, 8^7, 6^5 */
	{
		8, ACTION_PUT, EXPECT_DELTA_SAME, EXPECT_ROOT_SAME,
		EXPECT_STATS(5, ROOT(7, 1, 2), ROOT(5, 1, 2), ROOT(30, 1, 1),
				DELTA(8, 1), DELTA(6, 1)),
	},	/* r: 7, 30, 5		d: 8^7, 6^5 */
	{
		8, ACTION_PUT, EXPECT_DELTA_DEC, EXPECT_ROOT_SAME,
		EXPECT_STATS(4, ROOT(5, 1, 2), ROOT(7, 1, 1), ROOT(30, 1, 1),
				DELTA(6, 1)),
	},	/* r: 7, 30, 5		d: 6^5 */
	{
		8, ACTION_GET, EXPECT_DELTA_INC, EXPECT_ROOT_SAME,
		EXPECT_STATS(5, ROOT(5, 1, 3), ROOT(7, 1, 1), ROOT(30, 1, 1),
				DELTA(6, 1), DELTA(8, 1)),
	},	/* r: 7, 30, 5		d: 6^5, 8^5 */
	{
		7, ACTION_PUT, EXPECT_DELTA_SAME, EXPECT_ROOT_DEC,
		EXPECT_STATS(4, ROOT(5, 1, 3), ROOT(30, 1, 1),
				DELTA(6, 1), DELTA(8, 1)),
	},	/* r: 30, 5		d: 6^5, 8^5 */
	{
		30, ACTION_PUT, EXPECT_DELTA_SAME, EXPECT_ROOT_DEC,
		EXPECT_STATS(3, ROOT(5, 1, 3),
				DELTA(6, 1), DELTA(8, 1)),
	},	/* r: 5			d: 6^5, 8^5 */
	{
		5, ACTION_PUT, EXPECT_DELTA_SAME, EXPECT_ROOT_SAME,
		EXPECT_STATS(3, ROOT(5, 0, 2),
				DELTA(6, 1), DELTA(8, 1)),
	},	/* r:			d: 6^5, 8^5 */
	{
		6, ACTION_PUT, EXPECT_DELTA_DEC, EXPECT_ROOT_SAME,
		EXPECT_STATS(2, ROOT(5, 0, 1),
				DELTA(8, 1)),
	},	/* r:			d: 6^5 */
	{
		8, ACTION_PUT, EXPECT_DELTA_DEC, EXPECT_ROOT_DEC,
		EXPECT_STATS(0, ),
	},	/* r:			d: */
};

static int check_expect(struct world *world,
			const struct action_item *action_item,
			unsigned int orig_delta_count,
			unsigned int orig_root_count)
{
	unsigned int key_id = action_item->key_id;

	switch (action_item->expect_delta) {
	case EXPECT_DELTA_SAME:
		if (orig_delta_count != world->delta_count) {
			pr_err("Key %u: Delta count changed while expected to remain the same.\n",
			       key_id);
			return -EINVAL;
		}
		break;
	case EXPECT_DELTA_INC:
		if (WARN_ON(action_item->action == ACTION_PUT))
			return -EINVAL;
		if (orig_delta_count + 1 != world->delta_count) {
			pr_err("Key %u: Delta count was not incremented.\n",
			       key_id);
			return -EINVAL;
		}
		break;
	case EXPECT_DELTA_DEC:
		if (WARN_ON(action_item->action == ACTION_GET))
			return -EINVAL;
		if (orig_delta_count - 1 != world->delta_count) {
			pr_err("Key %u: Delta count was not decremented.\n",
			       key_id);
			return -EINVAL;
		}
		break;
	}

	switch (action_item->expect_root) {
	case EXPECT_ROOT_SAME:
		if (orig_root_count != world->root_count) {
			pr_err("Key %u: Root count changed while expected to remain the same.\n",
			       key_id);
			return -EINVAL;
		}
		break;
	case EXPECT_ROOT_INC:
		if (WARN_ON(action_item->action == ACTION_PUT))
			return -EINVAL;
		if (orig_root_count + 1 != world->root_count) {
			pr_err("Key %u: Root count was not incremented.\n",
			       key_id);
			return -EINVAL;
		}
		break;
	case EXPECT_ROOT_DEC:
		if (WARN_ON(action_item->action == ACTION_GET))
			return -EINVAL;
		if (orig_root_count - 1 != world->root_count) {
			pr_err("Key %u: Root count was not decremented.\n",
			       key_id);
			return -EINVAL;
		}
	}

	return 0;
}

static unsigned int obj_to_key_id(struct objagg_obj *objagg_obj)
{
	const struct tokey *root_key;
	const struct delta *delta;
	unsigned int key_id;

	root_key = objagg_obj_root_priv(objagg_obj);
	key_id = root_key->id;
	delta = objagg_obj_delta_priv(objagg_obj);
	if (delta)
		key_id += delta->key_id_diff;
	return key_id;
}

static int
check_expect_stats_nums(const struct objagg_obj_stats_info *stats_info,
			const struct expect_stats_info *expect_stats_info,
			const char **errmsg)
{
	if (stats_info->is_root != expect_stats_info->is_root) {
		if (errmsg)
			*errmsg = "Incorrect root/delta indication";
		return -EINVAL;
	}
	if (stats_info->stats.user_count !=
	    expect_stats_info->stats.user_count) {
		if (errmsg)
			*errmsg = "Incorrect user count";
		return -EINVAL;
	}
	if (stats_info->stats.delta_user_count !=
	    expect_stats_info->stats.delta_user_count) {
		if (errmsg)
			*errmsg = "Incorrect delta user count";
		return -EINVAL;
	}
	return 0;
}

static int
check_expect_stats_key_id(const struct objagg_obj_stats_info *stats_info,
			  const struct expect_stats_info *expect_stats_info,
			  const char **errmsg)
{
	if (obj_to_key_id(stats_info->objagg_obj) !=
	    expect_stats_info->key_id) {
		if (errmsg)
			*errmsg = "incorrect key id";
		return -EINVAL;
	}
	return 0;
}

static int check_expect_stats_neigh(const struct objagg_stats *stats,
				    const struct expect_stats *expect_stats,
				    int pos)
{
	int i;
	int err;

	for (i = pos - 1; i >= 0; i--) {
		err = check_expect_stats_nums(&stats->stats_info[i],
					      &expect_stats->info[pos], NULL);
		if (err)
			break;
		err = check_expect_stats_key_id(&stats->stats_info[i],
						&expect_stats->info[pos], NULL);
		if (!err)
			return 0;
	}
	for (i = pos + 1; i < stats->stats_info_count; i++) {
		err = check_expect_stats_nums(&stats->stats_info[i],
					      &expect_stats->info[pos], NULL);
		if (err)
			break;
		err = check_expect_stats_key_id(&stats->stats_info[i],
						&expect_stats->info[pos], NULL);
		if (!err)
			return 0;
	}
	return -EINVAL;
}

static int __check_expect_stats(const struct objagg_stats *stats,
				const struct expect_stats *expect_stats,
				const char **errmsg)
{
	int i;
	int err;

	if (stats->stats_info_count != expect_stats->info_count) {
		*errmsg = "Unexpected object count";
		return -EINVAL;
	}

	for (i = 0; i < stats->stats_info_count; i++) {
		err = check_expect_stats_nums(&stats->stats_info[i],
					      &expect_stats->info[i], errmsg);
		if (err)
			return err;
		err = check_expect_stats_key_id(&stats->stats_info[i],
						&expect_stats->info[i], errmsg);
		if (err) {
			/* It is possible that one of the neighbor stats with
			 * same numbers have the correct key id, so check it
			 */
			err = check_expect_stats_neigh(stats, expect_stats, i);
			if (err)
				return err;
		}
	}
	return 0;
}

static int check_expect_stats(struct objagg *objagg,
			      const struct expect_stats *expect_stats,
			      const char **errmsg)
{
	const struct objagg_stats *stats;
	int err;

	stats = objagg_stats_get(objagg);
	if (IS_ERR(stats)) {
		*errmsg = "objagg_stats_get() failed.";
		return PTR_ERR(stats);
	}
	err = __check_expect_stats(stats, expect_stats, errmsg);
	objagg_stats_put(stats);
	return err;
}

static int test_delta_action_item(struct world *world,
				  struct objagg *objagg,
				  const struct action_item *action_item,
				  bool inverse)
{
	unsigned int orig_delta_count = world->delta_count;
	unsigned int orig_root_count = world->root_count;
	unsigned int key_id = action_item->key_id;
	enum action action = action_item->action;
	struct objagg_obj *objagg_obj;
	const char *errmsg;
	int err;

	if (inverse)
		action = action == ACTION_GET ? ACTION_PUT : ACTION_GET;

	switch (action) {
	case ACTION_GET:
		objagg_obj = world_obj_get(world, objagg, key_id);
		if (IS_ERR(objagg_obj))
			return PTR_ERR(objagg_obj);
		break;
	case ACTION_PUT:
		world_obj_put(world, objagg, key_id);
		break;
	}

	if (inverse)
		return 0;
	err = check_expect(world, action_item,
			   orig_delta_count, orig_root_count);
	if (err)
		goto errout;

	err = check_expect_stats(objagg, &action_item->expect_stats, &errmsg);
	if (err) {
		pr_err("Key %u: Stats: %s\n", action_item->key_id, errmsg);
		goto errout;
	}

	return 0;

errout:
	/* This can only happen when action is not inversed.
	 * So in case of an error, cleanup by doing inverse action.
	 */
	test_delta_action_item(world, objagg, action_item, true);
	return err;
}

static int test_delta(void)
{
	struct world world = {};
	struct objagg *objagg;
	int i;
	int err;

	objagg = objagg_create(&delta_ops, NULL, &world);
	if (IS_ERR(objagg))
		return PTR_ERR(objagg);

	for (i = 0; i < ARRAY_SIZE(action_items); i++) {
		err = test_delta_action_item(&world, objagg,
					     &action_items[i], false);
		if (err)
			goto err_do_action_item;
	}

	objagg_destroy(objagg);
	return 0;

err_do_action_item:
	for (i--; i >= 0; i--)
		test_delta_action_item(&world, objagg, &action_items[i], true);

	objagg_destroy(objagg);
	return err;
}

struct hints_case {
	const unsigned int *key_ids;
	size_t key_ids_count;
	struct expect_stats expect_stats;
	struct expect_stats expect_stats_hints;
};

static const unsigned int hints_case_key_ids[] = {
	1, 7, 3, 5, 3, 1, 30, 8, 8, 5, 6, 8,
};

static const struct hints_case hints_case = {
	.key_ids = hints_case_key_ids,
	.key_ids_count = ARRAY_SIZE(hints_case_key_ids),
	.expect_stats =
		EXPECT_STATS(7, ROOT(1, 2, 7), ROOT(7, 1, 4), ROOT(30, 1, 1),
				DELTA(8, 3), DELTA(3, 2),
				DELTA(5, 2), DELTA(6, 1)),
	.expect_stats_hints =
		EXPECT_STATS(7, ROOT(3, 2, 9), ROOT(1, 2, 2), ROOT(30, 1, 1),
				DELTA(8, 3), DELTA(5, 2),
				DELTA(6, 1), DELTA(7, 1)),
};

static void __pr_debug_stats(const struct objagg_stats *stats)
{
	int i;

	for (i = 0; i < stats->stats_info_count; i++)
		pr_debug("Stat index %d key %u: u %d, d %d, %s\n", i,
			 obj_to_key_id(stats->stats_info[i].objagg_obj),
			 stats->stats_info[i].stats.user_count,
			 stats->stats_info[i].stats.delta_user_count,
			 stats->stats_info[i].is_root ? "root" : "noroot");
}

static void pr_debug_stats(struct objagg *objagg)
{
	const struct objagg_stats *stats;

	stats = objagg_stats_get(objagg);
	if (IS_ERR(stats))
		return;
	__pr_debug_stats(stats);
	objagg_stats_put(stats);
}

static void pr_debug_hints_stats(struct objagg_hints *objagg_hints)
{
	const struct objagg_stats *stats;

	stats = objagg_hints_stats_get(objagg_hints);
	if (IS_ERR(stats))
		return;
	__pr_debug_stats(stats);
	objagg_stats_put(stats);
}

static int check_expect_hints_stats(struct objagg_hints *objagg_hints,
				    const struct expect_stats *expect_stats,
				    const char **errmsg)
{
	const struct objagg_stats *stats;
	int err;

	stats = objagg_hints_stats_get(objagg_hints);
	if (IS_ERR(stats)) {
		*errmsg = "objagg_hints_stats_get() failed.";
		return PTR_ERR(stats);
	}
	err = __check_expect_stats(stats, expect_stats, errmsg);
	objagg_stats_put(stats);
	return err;
}

static int test_hints_case2(const struct hints_case *hints_case,
			    struct objagg_hints *hints, struct objagg *objagg)
{
	struct objagg_obj *objagg_obj;
	struct world world2 = {};
	struct objagg *objagg2;
	const char *errmsg;
	int i;
	int err;

	pr_debug_hints_stats(hints);
	err = check_expect_hints_stats(hints, &hints_case->expect_stats_hints,
				       &errmsg);
	if (err) {
		pr_err("Hints stats: %s\n", errmsg);
		return err;
	}

	objagg2 = objagg_create(&delta_ops, hints, &world2);
	if (IS_ERR(objagg2))
		return PTR_ERR(objagg2);

	for (i = 0; i < hints_case->key_ids_count; i++) {
		objagg_obj = world_obj_get(&world2, objagg2,
					   hints_case->key_ids[i]);
		if (IS_ERR(objagg_obj)) {
			err = PTR_ERR(objagg_obj);
			goto err_world2_obj_get;
		}
	}

	pr_debug_stats(objagg2);
	err = check_expect_stats(objagg2, &hints_case->expect_stats_hints,
				 &errmsg);
	if (err) {
		pr_err("Stats2: %s\n", errmsg);
		goto err_check_expect_stats2;
	}

	err = 0;

err_check_expect_stats2:
err_world2_obj_get:
	for (i--; i >= 0; i--)
		world_obj_put(&world2, objagg, hints_case->key_ids[i]);
	i = hints_case->key_ids_count;
	objagg_destroy(objagg2);

	return err;
}

static int test_hints_case(const struct hints_case *hints_case)
{
	struct objagg_obj *objagg_obj;
	struct objagg_hints *hints;
	struct world world = {};
	struct objagg *objagg;
	const char *errmsg;
	int i;
	int err;

	objagg = objagg_create(&delta_ops, NULL, &world);
	if (IS_ERR(objagg))
		return PTR_ERR(objagg);

	for (i = 0; i < hints_case->key_ids_count; i++) {
		objagg_obj = world_obj_get(&world, objagg,
					   hints_case->key_ids[i]);
		if (IS_ERR(objagg_obj)) {
			err = PTR_ERR(objagg_obj);
			goto err_world_obj_get;
		}
	}

	pr_debug_stats(objagg);
	err = check_expect_stats(objagg, &hints_case->expect_stats, &errmsg);
	if (err) {
		pr_err("Stats: %s\n", errmsg);
		goto err_check_expect_stats;
	}

	hints = objagg_hints_get(objagg, OBJAGG_OPT_ALGO_SIMPLE_GREEDY);
	if (IS_ERR(hints)) {
		err = PTR_ERR(hints);
		goto err_hints_get;
	}

	err = test_hints_case2(hints_case, hints, objagg);

	objagg_hints_put(hints);
err_hints_get:
err_check_expect_stats:
err_world_obj_get:
	for (i--; i >= 0; i--)
		world_obj_put(&world, objagg, hints_case->key_ids[i]);

	objagg_destroy(objagg);
	return err;
}
static int test_hints(void)
{
	return test_hints_case(&hints_case);
}

static int __init test_objagg_init(void)
{
	int err;

	err = test_nodelta();
	if (err)
		return err;
	err = test_delta();
	if (err)
		return err;
	return test_hints();
}

static void __exit test_objagg_exit(void)
{
}

module_init(test_objagg_init);
module_exit(test_objagg_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
MODULE_DESCRIPTION("Test module for objagg");
