| // SPDX-License-Identifier: GPL-2.0-or-later |
| /* |
| * |
| * BlueZ - Bluetooth protocol stack for Linux |
| * |
| * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> |
| * |
| * |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif |
| |
| #define _GNU_SOURCE |
| #include <stdio.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include <glib.h> |
| |
| #include "src/textfile.h" |
| #include "src/shared/tester.h" |
| |
| static const char test_pathname[] = "/tmp/textfile"; |
| |
| static void util_create_empty(void) |
| { |
| int fd; |
| |
| fd = creat(test_pathname, 0644); |
| if (fd < 0) |
| return; |
| |
| if (ftruncate(fd, 0) < 0) |
| goto done; |
| |
| done: |
| close(fd); |
| } |
| |
| static void util_create_pagesize(void) |
| { |
| char value[512]; |
| unsigned int i; |
| int fd, size; |
| |
| size = getpagesize(); |
| if (size < 0) |
| return; |
| |
| fd = creat(test_pathname, 0644); |
| if (fd < 0) |
| return; |
| |
| if (ftruncate(fd, 0) < 0) |
| goto done; |
| |
| memset(value, 0, sizeof(value)); |
| for (i = 0; i < (size / sizeof(value)); i++) { |
| if (write(fd, value, sizeof(value)) < 0) |
| break; |
| } |
| |
| done: |
| close(fd); |
| } |
| |
| static void test_pagesize(const void *data) |
| { |
| char key[18], *str; |
| int size; |
| |
| size = getpagesize(); |
| g_assert(size >= 4096); |
| |
| tester_debug("System uses a page size of %d bytes\n", size); |
| |
| util_create_pagesize(); |
| |
| sprintf(key, "11:11:11:11:11:11"); |
| str = textfile_get(test_pathname, key); |
| |
| tester_debug("%s\n", str); |
| |
| g_assert(str == NULL); |
| tester_test_passed(); |
| } |
| |
| static void test_delete(const void *data) |
| { |
| char key[18], value[512], *str; |
| |
| util_create_empty(); |
| |
| sprintf(key, "00:00:00:00:00:00"); |
| g_assert(textfile_del(test_pathname, key) == 0); |
| |
| memset(value, 0, sizeof(value)); |
| g_assert(textfile_put(test_pathname, key, value) == 0); |
| |
| str = textfile_get(test_pathname, key); |
| g_assert(str != NULL); |
| |
| tester_debug("%s\n", str); |
| |
| g_free(str); |
| tester_test_passed(); |
| } |
| |
| static void test_overwrite(const void *data) |
| { |
| char key[18], value[512], *str; |
| |
| util_create_empty(); |
| |
| sprintf(key, "00:00:00:00:00:00"); |
| memset(value, 0, sizeof(value)); |
| g_assert(textfile_put(test_pathname, key, value) == 0); |
| |
| snprintf(value, sizeof(value), "Test"); |
| g_assert(textfile_put(test_pathname, key, value) == 0); |
| |
| g_assert(textfile_put(test_pathname, key, value) == 0); |
| |
| g_assert(textfile_put(test_pathname, key, value) == 0); |
| |
| g_assert(textfile_del(test_pathname, key) == 0); |
| |
| str = textfile_get(test_pathname, key); |
| |
| tester_debug("%s\n", str); |
| |
| g_assert(str == NULL); |
| tester_test_passed(); |
| } |
| |
| static void check_entry(char *key, char *value, void *data) |
| { |
| unsigned int max = GPOINTER_TO_UINT(data); |
| unsigned int len; |
| |
| len = strtol(key + 16, NULL, 16); |
| if (len == 1) |
| len = max; |
| |
| if (g_test_verbose()) |
| g_print("%s %s\n", key, value); |
| |
| g_assert(strlen(value) == len); |
| } |
| |
| static void test_multiple(const void *data) |
| { |
| char key[18], value[512], *str; |
| unsigned int i, j, max = 10; |
| |
| util_create_empty(); |
| |
| for (i = 1; i < max + 1; i++) { |
| sprintf(key, "00:00:00:00:00:%02X", i); |
| |
| memset(value, 0, sizeof(value)); |
| for (j = 0; j < i; j++) |
| value[j] = 'x'; |
| |
| g_assert(textfile_put(test_pathname, key, value) == 0); |
| |
| str = textfile_get(test_pathname, key); |
| |
| tester_debug("%s %s\n", key, str); |
| |
| g_assert(str != NULL); |
| g_assert(strcmp(str, value) == 0); |
| |
| free(str); |
| } |
| |
| sprintf(key, "00:00:00:00:00:%02X", max); |
| |
| memset(value, 0, sizeof(value)); |
| for (j = 0; j < max; j++) |
| value[j] = 'y'; |
| |
| g_assert(textfile_put(test_pathname, key, value) == 0); |
| |
| str = textfile_get(test_pathname, key); |
| |
| tester_debug("%s %s\n", key, str); |
| |
| g_assert(str != NULL); |
| g_assert(strcmp(str, value) == 0); |
| |
| free(str); |
| |
| sprintf(key, "00:00:00:00:00:%02X", 1); |
| |
| memset(value, 0, sizeof(value)); |
| for (j = 0; j < max; j++) |
| value[j] = 'z'; |
| |
| g_assert(textfile_put(test_pathname, key, value) == 0); |
| |
| str = textfile_get(test_pathname, key); |
| |
| tester_debug("%s %s\n", key, str); |
| |
| g_assert(str != NULL); |
| g_assert(strcmp(str, value) == 0); |
| |
| free(str); |
| |
| for (i = 1; i < max + 1; i++) { |
| sprintf(key, "00:00:00:00:00:%02X", i); |
| str = textfile_get(test_pathname, key); |
| |
| tester_debug("%s %s\n", key, str); |
| |
| g_assert(str != NULL); |
| |
| if (i == 1) |
| g_assert(strlen(str) == max); |
| else |
| g_assert(strlen(str) == i); |
| |
| g_free(str); |
| } |
| |
| sprintf(key, "00:00:00:00:00:%02X", 2); |
| g_assert(textfile_del(test_pathname, key) == 0); |
| |
| sprintf(key, "00:00:00:00:00:%02X", max - 3); |
| g_assert(textfile_del(test_pathname, key) == 0); |
| |
| textfile_foreach(test_pathname, check_entry, GUINT_TO_POINTER(max)); |
| |
| sprintf(key, "00:00:00:00:00:%02X", 1); |
| g_assert(textfile_del(test_pathname, key) == 0); |
| |
| sprintf(key, "00:00:00:00:00:%02X", max); |
| g_assert(textfile_del(test_pathname, key) == 0); |
| |
| sprintf(key, "00:00:00:00:00:%02X", max + 1); |
| g_assert(textfile_del(test_pathname, key) == 0); |
| |
| textfile_foreach(test_pathname, check_entry, GUINT_TO_POINTER(max)); |
| tester_test_passed(); |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| tester_init(&argc, &argv); |
| |
| tester_add("/textfile/pagesize", NULL, NULL, test_pagesize, NULL); |
| tester_add("/textfile/delete", NULL, NULL, test_delete, NULL); |
| tester_add("/textfile/overwrite", NULL, NULL, test_overwrite, NULL); |
| tester_add("/textfile/multiple", NULL, NULL, test_multiple, NULL); |
| |
| return tester_run(); |
| } |