// SPDX-License-Identifier: GPL-2.0 /* * KUnit test for the Kernel Hashtable structures. * * Copyright (C) 2022, Google LLC. * Author: Rae Moar <rmoar@google.com>
*/ #include <kunit/test.h>
#include <linux/hashtable.h>
struct hashtable_test_entry { int key; int data; struct hlist_node node; int visited;
};
staticvoid hashtable_test_hash_init(struct kunit *test)
{ /* Test the different ways of initialising a hashtable. */
DEFINE_HASHTABLE(hash1, 2);
DECLARE_HASHTABLE(hash2, 3);
/* When using DECLARE_HASHTABLE, must use hash_init to * initialize the hashtable.
*/
hash_init(hash2);
/* The deleted entry should not have been visited. */
KUNIT_EXPECT_EQ(test, b.visited, 0);
hash_del(&a.node);
/* The hashtable should be empty. */
KUNIT_EXPECT_TRUE(test, hash_empty(hash));
}
staticvoid hashtable_test_hash_for_each(struct kunit *test)
{ struct hashtable_test_entry entries[3]; struct hashtable_test_entry *x; int bkt, i, j, count;
DEFINE_HASHTABLE(hash, 3);
/* Add three entries to the hashtable. */ for (i = 0; i < 3; i++) {
entries[i].key = i;
entries[i].data = i + 10;
entries[i].visited = 0;
hash_add(hash, &entries[i].node, entries[i].key);
}
/* Add three entries to the hashtable. */ for (i = 0; i < 3; i++) {
entries[i].key = i;
entries[i].data = i + 10;
entries[i].visited = 0;
hash_add(hash, &entries[i].node, entries[i].key);
}
/* Delete entry during loop. */
hash_del(&x->node);
}
/* Should have visited each entry exactly once. */
KUNIT_EXPECT_EQ(test, count, 3); for (j = 0; j < 3; j++)
KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
}
staticvoid hashtable_test_hash_for_each_possible(struct kunit *test)
{ struct hashtable_test_entry entries[4]; struct hashtable_test_entry *x, *y; int buckets[2]; int bkt, i, j, count;
DEFINE_HASHTABLE(hash, 5);
/* Add three entries with key = 0 to the hashtable. */ for (i = 0; i < 3; i++) {
entries[i].key = 0;
entries[i].data = i;
entries[i].visited = 0;
hash_add(hash, &entries[i].node, entries[i].key);
}
count = 0;
hash_for_each_possible(hash, x, node, 0) {
x->visited += 1;
KUNIT_ASSERT_GE_MSG(test, x->data, 0, "Unexpected data in hashtable.");
KUNIT_ASSERT_LT_MSG(test, x->data, 4, "Unexpected data in hashtable.");
count++;
}
/* Should have visited each entry with key = 0 exactly once. */ for (j = 0; j < 3; j++)
KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
/* Save the buckets for the different keys. */
hash_for_each(hash, bkt, y, node) {
KUNIT_ASSERT_GE_MSG(test, y->key, 0, "Unexpected key in hashtable.");
KUNIT_ASSERT_LE_MSG(test, y->key, 1, "Unexpected key in hashtable.");
buckets[y->key] = bkt;
}
/* If entry with key = 1 is in the same bucket as the entries with * key = 0, check it was visited. Otherwise ensure that only three * entries were visited.
*/ if (buckets[0] == buckets[1]) {
KUNIT_EXPECT_EQ(test, count, 4);
KUNIT_EXPECT_EQ(test, entries[3].visited, 1);
} else {
KUNIT_EXPECT_EQ(test, count, 3);
KUNIT_EXPECT_EQ(test, entries[3].visited, 0);
}
}
staticvoid hashtable_test_hash_for_each_possible_safe(struct kunit *test)
{ struct hashtable_test_entry entries[4]; struct hashtable_test_entry *x, *y; struct hlist_node *tmp; int buckets[2]; int bkt, i, j, count;
DEFINE_HASHTABLE(hash, 5);
/* Add three entries with key = 0 to the hashtable. */ for (i = 0; i < 3; i++) {
entries[i].key = 0;
entries[i].data = i;
entries[i].visited = 0;
hash_add(hash, &entries[i].node, entries[i].key);
}
count = 0;
hash_for_each_possible_safe(hash, x, tmp, node, 0) {
x->visited += 1;
KUNIT_ASSERT_GE_MSG(test, x->data, 0, "Unexpected data in hashtable.");
KUNIT_ASSERT_LT_MSG(test, x->data, 4, "Unexpected data in hashtable.");
count++;
/* Delete entry during loop. */
hash_del(&x->node);
}
/* Should have visited each entry with key = 0 exactly once. */ for (j = 0; j < 3; j++)
KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
/* Save the buckets for the different keys. */
hash_for_each(hash, bkt, y, node) {
KUNIT_ASSERT_GE_MSG(test, y->key, 0, "Unexpected key in hashtable.");
KUNIT_ASSERT_LE_MSG(test, y->key, 1, "Unexpected key in hashtable.");
buckets[y->key] = bkt;
}
/* If entry with key = 1 is in the same bucket as the entries with * key = 0, check it was visited. Otherwise ensure that only three * entries were visited.
*/ if (buckets[0] == buckets[1]) {
KUNIT_EXPECT_EQ(test, count, 4);
KUNIT_EXPECT_EQ(test, entries[3].visited, 1);
} else {
KUNIT_EXPECT_EQ(test, count, 3);
KUNIT_EXPECT_EQ(test, entries[3].visited, 0);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.