util: Convert cache test to use gtest

Replace a bunch of helper functions for checking results with ones
from GTest.

Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14054>
This commit is contained in:
Caio Oliveira 2021-12-03 13:34:08 -08:00 committed by Marge Bot
parent 88e97d75d0
commit 51351760c2
3 changed files with 80 additions and 192 deletions

View File

@ -354,6 +354,12 @@ if with_tests
)
endif
if with_shader_cache
files_util_tests += files(
'tests/cache_test.cpp',
)
endif
test(
'util_tests',
executable(
@ -393,7 +399,6 @@ if with_tests
env: ['BUILD_FULL_PATH='+process_test_exe_full_path]
)
subdir('tests/cache')
subdir('tests/hash_table')
subdir('tests/vma')
subdir('tests/format')

View File

@ -1,34 +0,0 @@
# Copyright © 2017 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
if with_shader_cache
test(
'cache',
executable(
'cache_test',
'cache_test.c',
c_args : [c_msvc_compat_args, no_override_init_args],
gnu_symbol_visibility : 'hidden',
include_directories : [inc_include, inc_src],
dependencies : [dep_clock, dep_thread, idep_mesautil],
),
suite : ['util'],
)
endif

View File

@ -23,6 +23,8 @@
/* A collection of unit tests for cache.c */
#include <gtest/gtest.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
@ -38,71 +40,8 @@
#include "util/mesa-sha1.h"
#include "util/disk_cache.h"
bool error = false;
#ifdef ENABLE_SHADER_CACHE
static void
expect_true(bool result, const char *test)
{
if (!result) {
fprintf(stderr, "Error: Test '%s' failed: Expected=true"
", Actual=false\n", test);
error = true;
}
}
static void
expect_false(bool result, const char *test)
{
if (result) {
fprintf(stderr, "Error: Test '%s' failed: Expected=false"
", Actual=true\n", test);
error = true;
}
}
static void
expect_equal(uint64_t actual, uint64_t expected, const char *test)
{
if (actual != expected) {
fprintf(stderr, "Error: Test '%s' failed: Expected=%" PRIu64
", Actual=%" PRIu64 "\n",
test, expected, actual);
error = true;
}
}
static void
expect_null(void *ptr, const char *test)
{
if (ptr != NULL) {
fprintf(stderr, "Error: Test '%s' failed: Result=%p, but expected NULL.\n",
test, ptr);
error = true;
}
}
static void
expect_non_null(void *ptr, const char *test)
{
if (ptr == NULL) {
fprintf(stderr, "Error: Test '%s' failed: Result=NULL, but expected something else.\n",
test);
error = true;
}
}
static void
expect_equal_str(const char *actual, const char *expected, const char *test)
{
if (strcmp(actual, expected)) {
fprintf(stderr, "Error: Test '%s' failed:\n\t"
"Expected=\"%s\", Actual=\"%s\"\n",
test, expected, actual);
error = true;
}
}
/* Callback for nftw used in rmrf_local below.
*/
static int
@ -153,7 +92,7 @@ check_directories_created(const char *cache_dir)
}
}
expect_true(sub_dirs_created, "create sub dirs");
EXPECT_TRUE(sub_dirs_created) << "create sub dirs";
}
static bool
@ -178,7 +117,7 @@ cache_exists(struct disk_cache *cache)
char data[] = "some test data";
if (!cache)
return NULL;
return false;
disk_cache_compute_key(cache, data, sizeof(data), key);
disk_cache_put(cache, key, data, sizeof(data), NULL);
@ -202,7 +141,7 @@ test_disk_cache_create(const char *cache_dir_name)
*/
setenv("MESA_GLSL_CACHE_DISABLE", "true", 1);
cache = disk_cache_create("test", "make_check", 0);
expect_null(cache, "disk_cache_create with MESA_GLSL_CACHE_DISABLE set");
EXPECT_EQ(cache, nullptr) << "disk_cache_create with MESA_GLSL_CACHE_DISABLE set";
unsetenv("MESA_GLSL_CACHE_DISABLE");
@ -212,8 +151,9 @@ test_disk_cache_create(const char *cache_dir_name)
*/
unsetenv("MESA_GLSL_CACHE_DISABLE");
cache = disk_cache_create("test", "make_check", 0);
expect_null(cache, "disk_cache_create with MESA_GLSL_CACHE_DISABLE unset "
" and SHADER_CACHE_DISABLE_BY_DEFAULT build option");
EXPECT_EQ(cache, nullptr)
<< "disk_cache_create with MESA_GLSL_CACHE_DISABLE unset "
"and SHADER_CACHE_DISABLE_BY_DEFAULT build option";
/* For remaining tests, ensure that the cache is enabled. */
setenv("MESA_GLSL_CACHE_DISABLE", "false", 1);
@ -226,7 +166,7 @@ test_disk_cache_create(const char *cache_dir_name)
unsetenv("XDG_CACHE_HOME");
cache = disk_cache_create("test", "make_check", 0);
expect_non_null(cache, "disk_cache_create with no environment variables");
EXPECT_NE(cache, nullptr) << "disk_cache_create with no environment variables";
disk_cache_destroy(cache);
@ -234,26 +174,25 @@ test_disk_cache_create(const char *cache_dir_name)
/* Android doesn't try writing to disk (just calls the cache callbacks), so
* the directory tests below don't apply.
*/
exit(error ? 1 : 0);
return;
#endif
/* Test with XDG_CACHE_HOME set */
setenv("XDG_CACHE_HOME", CACHE_TEST_TMP "/xdg-cache-home", 1);
cache = disk_cache_create("test", "make_check", 0);
expect_false(cache_exists(cache), "disk_cache_create with XDG_CACHE_HOME set "
"with a non-existing parent directory");
EXPECT_FALSE(cache_exists(cache))
<< "disk_cache_create with XDG_CACHE_HOME set with a non-existing parent directory";
err = mkdir(CACHE_TEST_TMP, 0755);
if (err != 0) {
fprintf(stderr, "Error creating %s: %s\n", CACHE_TEST_TMP, strerror(errno));
error = true;
return;
GTEST_FAIL();
}
disk_cache_destroy(cache);
cache = disk_cache_create("test", "make_check", 0);
expect_true(cache_exists(cache), "disk_cache_create with XDG_CACHE_HOME "
"set");
EXPECT_TRUE(cache_exists(cache))
<< "disk_cache_create with XDG_CACHE_HOME set";
char *path;
asprintf(&path, "%s%s", CACHE_TEST_TMP "/xdg-cache-home/", cache_dir_name);
@ -264,24 +203,22 @@ test_disk_cache_create(const char *cache_dir_name)
/* Test with MESA_GLSL_CACHE_DIR set */
err = rmrf_local(CACHE_TEST_TMP);
expect_equal(err, 0, "Removing " CACHE_TEST_TMP);
EXPECT_EQ(err, 0) << "Removing " CACHE_TEST_TMP;
setenv("MESA_GLSL_CACHE_DIR", CACHE_TEST_TMP "/mesa-glsl-cache-dir", 1);
cache = disk_cache_create("test", "make_check", 0);
expect_false(cache_exists(cache), "disk_cache_create with MESA_GLSL_CACHE_DIR"
" set with a non-existing parent directory");
EXPECT_FALSE(cache_exists(cache))
<< "disk_cache_create with MESA_GLSL_CACHE_DIR set with a non-existing parent directory";
err = mkdir(CACHE_TEST_TMP, 0755);
if (err != 0) {
fprintf(stderr, "Error creating %s: %s\n", CACHE_TEST_TMP, strerror(errno));
error = true;
return;
GTEST_FAIL();
}
disk_cache_destroy(cache);
cache = disk_cache_create("test", "make_check", 0);
expect_true(cache_exists(cache), "disk_cache_create with "
"MESA_GLSL_CACHE_DIR set");
EXPECT_TRUE(cache_exists(cache)) << "disk_cache_create with MESA_GLSL_CACHE_DIR set";
asprintf(&path, "%s%s", CACHE_TEST_TMP "/mesa-glsl-cache-dir/",
cache_dir_name);
@ -314,9 +251,9 @@ test_put_and_get(bool test_cache_size_limit)
disk_cache_compute_key(cache, blob, sizeof(blob), blob_key);
/* Ensure that disk_cache_get returns nothing before anything is added. */
result = disk_cache_get(cache, blob_key, &size);
expect_null(result, "disk_cache_get with non-existent item (pointer)");
expect_equal(size, 0, "disk_cache_get with non-existent item (size)");
result = (char *) disk_cache_get(cache, blob_key, &size);
EXPECT_EQ(result, nullptr) << "disk_cache_get with non-existent item (pointer)";
EXPECT_EQ(size, 0) << "disk_cache_get with non-existent item (size)";
/* Simple test of put and get. */
disk_cache_put(cache, blob_key, blob, sizeof(blob), NULL);
@ -324,9 +261,9 @@ test_put_and_get(bool test_cache_size_limit)
/* disk_cache_put() hands things off to a thread so wait for it. */
disk_cache_wait_for_idle(cache);
result = disk_cache_get(cache, blob_key, &size);
expect_equal_str(blob, result, "disk_cache_get of existing item (pointer)");
expect_equal(size, sizeof(blob), "disk_cache_get of existing item (size)");
result = (char *) disk_cache_get(cache, blob_key, &size);
EXPECT_STREQ(blob, result) << "disk_cache_get of existing item (pointer)";
EXPECT_EQ(size, sizeof(blob)) << "disk_cache_get of existing item (size)";
free(result);
@ -337,9 +274,9 @@ test_put_and_get(bool test_cache_size_limit)
/* disk_cache_put() hands things off to a thread so wait for it. */
disk_cache_wait_for_idle(cache);
result = disk_cache_get(cache, string_key, &size);
expect_equal_str(result, string, "2nd disk_cache_get of existing item (pointer)");
expect_equal(size, sizeof(string), "2nd disk_cache_get of existing item (size)");
result = (char *) disk_cache_get(cache, string_key, &size);
EXPECT_STREQ(result, string) << "2nd disk_cache_get of existing item (pointer)";
EXPECT_EQ(size, sizeof(string)) << "2nd disk_cache_get of existing item (size)";
free(result);
@ -352,7 +289,7 @@ test_put_and_get(bool test_cache_size_limit)
setenv("MESA_GLSL_CACHE_MAX_SIZE", "1K", 1);
cache = disk_cache_create("test", "make_check", 0);
one_KB = calloc(1, 1024);
one_KB = (uint8_t *) calloc(1, 1024);
/* Obviously the SHA-1 hash of 1024 zero bytes isn't particularly
* interesting. But we do have want to take some special care with
@ -381,9 +318,9 @@ test_put_and_get(bool test_cache_size_limit)
/* disk_cache_put() hands things off to a thread so wait for it. */
disk_cache_wait_for_idle(cache);
result = disk_cache_get(cache, one_KB_key, &size);
expect_non_null(result, "3rd disk_cache_get of existing item (pointer)");
expect_equal(size, 1024, "3rd disk_cache_get of existing item (size)");
result = (char *) disk_cache_get(cache, one_KB_key, &size);
EXPECT_NE(result, nullptr) << "3rd disk_cache_get of existing item (pointer)";
EXPECT_EQ(size, 1024) << "3rd disk_cache_get of existing item (size)";
free(result);
@ -403,9 +340,9 @@ test_put_and_get(bool test_cache_size_limit)
contains_1KB_file = true;
}
expect_true(contains_1KB_file,
"disk_cache_put eviction last file == MAX_SIZE (1KB)");
expect_equal(count, 1, "disk_cache_put eviction with MAX_SIZE=1K");
EXPECT_TRUE(contains_1KB_file)
<< "disk_cache_put eviction last file == MAX_SIZE (1KB)";
EXPECT_EQ(count, 1) << "disk_cache_put eviction with MAX_SIZE=1K";
/* Now increase the size to 1M, add back both items, and ensure all
* three that have been added are available via disk_cache_get.
@ -431,10 +368,10 @@ test_put_and_get(bool test_cache_size_limit)
if (does_cache_contain(cache, one_KB_key))
count++;
expect_equal(count, 3, "no eviction before overflow with MAX_SIZE=1M");
EXPECT_EQ(count, 3) << "no eviction before overflow with MAX_SIZE=1M";
/* Finally, check eviction again after adding an object of size 1M. */
one_MB = calloc(1024, 1024);
one_MB = (uint8_t *) calloc(1024, 1024);
disk_cache_compute_key(cache, one_MB, 1024 * 1024, one_MB_key);
one_MB_key[0] = blob_key[0];
@ -462,9 +399,9 @@ test_put_and_get(bool test_cache_size_limit)
contains_1MB_file = true;
}
expect_true(contains_1MB_file,
"disk_cache_put eviction last file == MAX_SIZE (1MB)");
expect_equal(count, 1, "eviction after overflow with MAX_SIZE=1M");
EXPECT_TRUE(contains_1MB_file)
<< "disk_cache_put eviction last file == MAX_SIZE (1MB)";
EXPECT_EQ(count, 1) << "eviction after overflow with MAX_SIZE=1M";
disk_cache_destroy(cache);
}
@ -491,36 +428,36 @@ test_put_key_and_get_key(void)
/* First test that disk_cache_has_key returns false before disk_cache_put_key */
result = disk_cache_has_key(cache, key_a);
expect_equal(result, 0, "disk_cache_has_key before key added");
EXPECT_EQ(result, 0) << "disk_cache_has_key before key added";
/* Then a couple of tests of disk_cache_put_key followed by disk_cache_has_key */
disk_cache_put_key(cache, key_a);
result = disk_cache_has_key(cache, key_a);
expect_equal(result, 1, "disk_cache_has_key after key added");
EXPECT_EQ(result, 1) << "disk_cache_has_key after key added";
disk_cache_put_key(cache, key_b);
result = disk_cache_has_key(cache, key_b);
expect_equal(result, 1, "2nd disk_cache_has_key after key added");
EXPECT_EQ(result, 1) << "2nd disk_cache_has_key after key added";
/* Test that a key with the same two bytes as an existing key
* forces an eviction.
*/
disk_cache_put_key(cache, key_a_collide);
result = disk_cache_has_key(cache, key_a_collide);
expect_equal(result, 1, "put_key of a colliding key lands in the cache");
EXPECT_EQ(result, 1) << "put_key of a colliding key lands in the cache";
result = disk_cache_has_key(cache, key_a);
expect_equal(result, 0, "put_key of a colliding key evicts from the cache");
EXPECT_EQ(result, 0) << "put_key of a colliding key evicts from the cache";
/* And finally test that we can re-add the original key to re-evict
* the colliding key.
*/
disk_cache_put_key(cache, key_a);
result = disk_cache_has_key(cache, key_a);
expect_equal(result, 1, "put_key of original key lands again");
EXPECT_EQ(result, 1) << "put_key of original key lands again";
result = disk_cache_has_key(cache, key_a_collide);
expect_equal(result, 0, "put_key of orginal key evicts the colliding key");
EXPECT_EQ(result, 0) << "put_key of orginal key evicts the colliding key";
disk_cache_destroy(cache);
}
@ -551,13 +488,13 @@ test_put_and_get_between_instances()
disk_cache_compute_key(cache1, blob, sizeof(blob), blob_key);
/* Ensure that disk_cache_get returns nothing before anything is added. */
result = disk_cache_get(cache1, blob_key, &size);
expect_null(result, "disk_cache_get(cache1) with non-existent item (pointer)");
expect_equal(size, 0, "disk_cache_get(cach1) with non-existent item (size)");
result = (char *) disk_cache_get(cache1, blob_key, &size);
EXPECT_EQ(result, nullptr) << "disk_cache_get(cache1) with non-existent item (pointer)";
EXPECT_EQ(size, 0) << "disk_cache_get(cach1) with non-existent item (size)";
result = disk_cache_get(cache2, blob_key, &size);
expect_null(result, "disk_cache_get(cache2) with non-existent item (pointer)");
expect_equal(size, 0, "disk_cache_get(cache2) with non-existent item (size)");
result = (char *) disk_cache_get(cache2, blob_key, &size);
EXPECT_EQ(result, nullptr) << "disk_cache_get(cache2) with non-existent item (pointer)";
EXPECT_EQ(size, 0) << "disk_cache_get(cache2) with non-existent item (size)";
/* Simple test of put and get. */
disk_cache_put(cache1, blob_key, blob, sizeof(blob), NULL);
@ -565,9 +502,9 @@ test_put_and_get_between_instances()
/* disk_cache_put() hands things off to a thread so wait for it. */
disk_cache_wait_for_idle(cache1);
result = disk_cache_get(cache2, blob_key, &size);
expect_equal_str(blob, result, "disk_cache_get(cache2) of existing item (pointer)");
expect_equal(size, sizeof(blob), "disk_cache_get of(cache2) existing item (size)");
result = (char *) disk_cache_get(cache2, blob_key, &size);
EXPECT_STREQ(blob, result) << "disk_cache_get(cache2) of existing item (pointer)";
EXPECT_EQ(size, sizeof(blob)) << "disk_cache_get of(cache2) existing item (size)";
free(result);
@ -578,9 +515,9 @@ test_put_and_get_between_instances()
/* disk_cache_put() hands things off to a thread so wait for it. */
disk_cache_wait_for_idle(cache2);
result = disk_cache_get(cache1, string_key, &size);
expect_equal_str(result, string, "2nd disk_cache_get(cache1) of existing item (pointer)");
expect_equal(size, sizeof(string), "2nd disk_cache_get(cache1) of existing item (size)");
result = (char *) disk_cache_get(cache1, string_key, &size);
EXPECT_STREQ(result, string) << "2nd disk_cache_get(cache1) of existing item (pointer)";
EXPECT_EQ(size, sizeof(string)) << "2nd disk_cache_get(cache1) of existing item (size)";
free(result);
@ -589,32 +526,27 @@ test_put_and_get_between_instances()
}
#endif /* ENABLE_SHADER_CACHE */
static void
test_multi_file_cache(void)
TEST(Cache, MultiFile)
{
int err;
printf("Test multi file disk cache - Start\n");
#ifndef ENABLE_SHADER_CACHE
GTEST_SKIP() << "ENABLE_SHADER_CACHE not defined.";
#else
test_disk_cache_create(CACHE_DIR_NAME);
test_put_and_get(true);
test_put_key_and_get_key();
printf("Test multi file disk cache - End\n");
err = rmrf_local(CACHE_TEST_TMP);
expect_equal(err, 0, "Removing " CACHE_TEST_TMP " again");
int err = rmrf_local(CACHE_TEST_TMP);
EXPECT_EQ(err, 0) << "Removing " CACHE_TEST_TMP " again";
#endif
}
static void
test_single_file_cache(void)
TEST(Cache, SingleFile)
{
int err;
printf("Test single file disk cache - Start\n");
#ifndef ENABLE_SHADER_CACHE
GTEST_SKIP() << "ENABLE_SHADER_CACHE not defined.";
#else
setenv("MESA_DISK_CACHE_SINGLE_FILE", "true", 1);
test_disk_cache_create(CACHE_DIR_NAME_SF);
@ -630,22 +562,7 @@ test_single_file_cache(void)
setenv("MESA_DISK_CACHE_SINGLE_FILE", "false", 1);
printf("Test single file disk cache - End\n");
err = rmrf_local(CACHE_TEST_TMP);
expect_equal(err, 0, "Removing " CACHE_TEST_TMP " again");
}
int
main(void)
{
#ifdef ENABLE_SHADER_CACHE
test_multi_file_cache();
test_single_file_cache();
#endif /* ENABLE_SHADER_CACHE */
return error ? 1 : 0;
int err = rmrf_local(CACHE_TEST_TMP);
EXPECT_EQ(err, 0) << "Removing " CACHE_TEST_TMP " again";
#endif
}