diff options
Diffstat (limited to 'src/tests/internal')
| -rw-r--r-- | src/tests/internal/list.c | 174 | ||||
| -rw-r--r-- | src/tests/internal/stdio.c | 208 | ||||
| -rw-r--r-- | src/tests/internal/stdlib.c | 114 |
3 files changed, 496 insertions, 0 deletions
diff --git a/src/tests/internal/list.c b/src/tests/internal/list.c new file mode 100644 index 0000000..836c69e --- /dev/null +++ b/src/tests/internal/list.c @@ -0,0 +1,174 @@ +/* Test program for lib/kernel/list.c. + + Attempts to test the list functionality that is not + sufficiently tested elsewhere in Pintos. + + This is not a test we will run on your submitted projects. + It is here for completeness. +*/ + +#undef NDEBUG +#include <debug.h> +#include <list.h> +#include <random.h> +#include <stdio.h> +#include "threads/test.h" + +/* Maximum number of elements in a linked list that we will + test. */ +#define MAX_SIZE 64 + +/* A linked list element. */ +struct value + { + struct list_elem elem; /* List element. */ + int value; /* Item value. */ + }; + +static void shuffle (struct value[], size_t); +static bool value_less (const struct list_elem *, const struct list_elem *, + void *); +static void verify_list_fwd (struct list *, int size); +static void verify_list_bkwd (struct list *, int size); + +/* Test the linked list implementation. */ +void +test (void) +{ + int size; + + printf ("testing various size lists:"); + for (size = 0; size < MAX_SIZE; size++) + { + int repeat; + + printf (" %d", size); + for (repeat = 0; repeat < 10; repeat++) + { + static struct value values[MAX_SIZE * 4]; + struct list list; + struct list_elem *e; + int i, ofs; + + /* Put values 0...SIZE in random order in VALUES. */ + for (i = 0; i < size; i++) + values[i].value = i; + shuffle (values, size); + + /* Assemble list. */ + list_init (&list); + for (i = 0; i < size; i++) + list_push_back (&list, &values[i].elem); + + /* Verify correct minimum and maximum elements. */ + e = list_min (&list, value_less, NULL); + ASSERT (size ? list_entry (e, struct value, elem)->value == 0 + : e == list_begin (&list)); + e = list_max (&list, value_less, NULL); + ASSERT (size ? list_entry (e, struct value, elem)->value == size - 1 + : e == list_begin (&list)); + + /* Sort and verify list. */ + list_sort (&list, value_less, NULL); + verify_list_fwd (&list, size); + + /* Reverse and verify list. */ + list_reverse (&list); + verify_list_bkwd (&list, size); + + /* Shuffle, insert using list_insert_ordered(), + and verify ordering. */ + shuffle (values, size); + list_init (&list); + for (i = 0; i < size; i++) + list_insert_ordered (&list, &values[i].elem, + value_less, NULL); + verify_list_fwd (&list, size); + + /* Duplicate some items, uniquify, and verify. */ + ofs = size; + for (e = list_begin (&list); e != list_end (&list); + e = list_next (e)) + { + struct value *v = list_entry (e, struct value, elem); + int copies = random_ulong () % 4; + while (copies-- > 0) + { + values[ofs].value = v->value; + list_insert (e, &values[ofs++].elem); + } + } + ASSERT ((size_t) ofs < sizeof values / sizeof *values); + list_unique (&list, NULL, value_less, NULL); + verify_list_fwd (&list, size); + } + } + + printf (" done\n"); + printf ("list: PASS\n"); +} + +/* Shuffles the CNT elements in ARRAY into random order. */ +static void +shuffle (struct value *array, size_t cnt) +{ + size_t i; + + for (i = 0; i < cnt; i++) + { + size_t j = i + random_ulong () % (cnt - i); + struct value t = array[j]; + array[j] = array[i]; + array[i] = t; + } +} + +/* Returns true if value A is less than value B, false + otherwise. */ +static bool +value_less (const struct list_elem *a_, const struct list_elem *b_, + void *aux UNUSED) +{ + const struct value *a = list_entry (a_, struct value, elem); + const struct value *b = list_entry (b_, struct value, elem); + + return a->value < b->value; +} + +/* Verifies that LIST contains the values 0...SIZE when traversed + in forward order. */ +static void +verify_list_fwd (struct list *list, int size) +{ + struct list_elem *e; + int i; + + for (i = 0, e = list_begin (list); + i < size && e != list_end (list); + i++, e = list_next (e)) + { + struct value *v = list_entry (e, struct value, elem); + ASSERT (i == v->value); + } + ASSERT (i == size); + ASSERT (e == list_end (list)); +} + +/* Verifies that LIST contains the values 0...SIZE when traversed + in reverse order. */ +static void +verify_list_bkwd (struct list *list, int size) +{ + struct list_elem *e; + int i; + + for (i = 0, e = list_rbegin (list); + i < size && e != list_rend (list); + i++, e = list_prev (e)) + { + struct value *v = list_entry (e, struct value, elem); + ASSERT (i == v->value); + } + ASSERT (i == size); + ASSERT (e == list_rend (list)); +} diff --git a/src/tests/internal/stdio.c b/src/tests/internal/stdio.c new file mode 100644 index 0000000..fb60cda --- /dev/null +++ b/src/tests/internal/stdio.c @@ -0,0 +1,208 @@ +/* Test program for printf() in lib/stdio.c. + + Attempts to test printf() functionality that is not + sufficiently tested elsewhere in Pintos. + + This is not a test we will run on your submitted projects. + It is here for completeness. +*/ + +#undef NDEBUG +#include <limits.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "threads/test.h" + +/* Number of failures so far. */ +static int failure_cnt; + +static void +checkf (const char *expect, const char *format, ...) +{ + char output[128]; + va_list args; + + printf ("\"%s\" -> \"%s\": ", format, expect); + + va_start (args, format); + vsnprintf (output, sizeof output, format, args); + va_end (args); + + if (strcmp (expect, output)) + { + printf ("\nFAIL: actual output \"%s\"\n", output); + failure_cnt++; + } + else + printf ("okay\n"); +} + +/* Test printf() implementation. */ +void +test (void) +{ + printf ("Testing formats:"); + + /* Check that commas show up in the right places, for positive + numbers. */ + checkf ("1", "%'d", 1); + checkf ("12", "%'d", 12); + checkf ("123", "%'d", 123); + checkf ("1,234", "%'d", 1234); + checkf ("12,345", "%'d", 12345); + checkf ("123,456", "%'ld", 123456L); + checkf ("1,234,567", "%'ld", 1234567L); + checkf ("12,345,678", "%'ld", 12345678L); + checkf ("123,456,789", "%'ld", 123456789L); + checkf ("1,234,567,890", "%'ld", 1234567890L); + checkf ("12,345,678,901", "%'lld", 12345678901LL); + checkf ("123,456,789,012", "%'lld", 123456789012LL); + checkf ("1,234,567,890,123", "%'lld", 1234567890123LL); + checkf ("12,345,678,901,234", "%'lld", 12345678901234LL); + checkf ("123,456,789,012,345", "%'lld", 123456789012345LL); + checkf ("1,234,567,890,123,456", "%'lld", 1234567890123456LL); + checkf ("12,345,678,901,234,567", "%'lld", 12345678901234567LL); + checkf ("123,456,789,012,345,678", "%'lld", 123456789012345678LL); + checkf ("1,234,567,890,123,456,789", "%'lld", 1234567890123456789LL); + + /* Check that commas show up in the right places, for positive + numbers. */ + checkf ("-1", "%'d", -1); + checkf ("-12", "%'d", -12); + checkf ("-123", "%'d", -123); + checkf ("-1,234", "%'d", -1234); + checkf ("-12,345", "%'d", -12345); + checkf ("-123,456", "%'ld", -123456L); + checkf ("-1,234,567", "%'ld", -1234567L); + checkf ("-12,345,678", "%'ld", -12345678L); + checkf ("-123,456,789", "%'ld", -123456789L); + checkf ("-1,234,567,890", "%'ld", -1234567890L); + checkf ("-12,345,678,901", "%'lld", -12345678901LL); + checkf ("-123,456,789,012", "%'lld", -123456789012LL); + checkf ("-1,234,567,890,123", "%'lld", -1234567890123LL); + checkf ("-12,345,678,901,234", "%'lld", -12345678901234LL); + checkf ("-123,456,789,012,345", "%'lld", -123456789012345LL); + checkf ("-1,234,567,890,123,456", "%'lld", -1234567890123456LL); + checkf ("-12,345,678,901,234,567", "%'lld", -12345678901234567LL); + checkf ("-123,456,789,012,345,678", "%'lld", -123456789012345678LL); + checkf ("-1,234,567,890,123,456,789", "%'lld", -1234567890123456789LL); + + /* Check signed integer conversions. */ + checkf (" 0", "%5d", 0); + checkf ("0 ", "%-5d", 0); + checkf (" +0", "%+5d", 0); + checkf ("+0 ", "%+-5d", 0); + checkf (" 0", "% 5d", 0); + checkf ("00000", "%05d", 0); + checkf (" ", "%5.0d", 0); + checkf (" 00", "%5.2d", 0); + checkf ("0", "%d", 0); + + checkf (" 1", "%5d", 1); + checkf ("1 ", "%-5d", 1); + checkf (" +1", "%+5d", 1); + checkf ("+1 ", "%+-5d", 1); + checkf (" 1", "% 5d", 1); + checkf ("00001", "%05d", 1); + checkf (" 1", "%5.0d", 1); + checkf (" 01", "%5.2d", 1); + checkf ("1", "%d", 1); + + checkf (" -1", "%5d", -1); + checkf ("-1 ", "%-5d", -1); + checkf (" -1", "%+5d", -1); + checkf ("-1 ", "%+-5d", -1); + checkf (" -1", "% 5d", -1); + checkf ("-0001", "%05d", -1); + checkf (" -1", "%5.0d", -1); + checkf (" -01", "%5.2d", -1); + checkf ("-1", "%d", -1); + + checkf ("12345", "%5d", 12345); + checkf ("12345", "%-5d", 12345); + checkf ("+12345", "%+5d", 12345); + checkf ("+12345", "%+-5d", 12345); + checkf (" 12345", "% 5d", 12345); + checkf ("12345", "%05d", 12345); + checkf ("12345", "%5.0d", 12345); + checkf ("12345", "%5.2d", 12345); + checkf ("12345", "%d", 12345); + + checkf ("123456", "%5d", 123456); + checkf ("123456", "%-5d", 123456); + checkf ("+123456", "%+5d", 123456); + checkf ("+123456", "%+-5d", 123456); + checkf (" 123456", "% 5d", 123456); + checkf ("123456", "%05d", 123456); + checkf ("123456", "%5.0d", 123456); + checkf ("123456", "%5.2d", 123456); + checkf ("123456", "%d", 123456); + + /* Check unsigned integer conversions. */ + checkf (" 0", "%5u", 0); + checkf (" 0", "%5o", 0); + checkf (" 0", "%5x", 0); + checkf (" 0", "%5X", 0); + checkf (" 0", "%#5o", 0); + checkf (" 0", "%#5x", 0); + checkf (" 0", "%#5X", 0); + checkf (" 00000000", "%#10.8x", 0); + + checkf (" 1", "%5u", 1); + checkf (" 1", "%5o", 1); + checkf (" 1", "%5x", 1); + checkf (" 1", "%5X", 1); + checkf (" 01", "%#5o", 1); + checkf (" 0x1", "%#5x", 1); + checkf (" 0X1", "%#5X", 1); + checkf ("0x00000001", "%#10.8x", 1); + + checkf ("123456", "%5u", 123456); + checkf ("361100", "%5o", 123456); + checkf ("1e240", "%5x", 123456); + checkf ("1E240", "%5X", 123456); + checkf ("0361100", "%#5o", 123456); + checkf ("0x1e240", "%#5x", 123456); + checkf ("0X1E240", "%#5X", 123456); + checkf ("0x0001e240", "%#10.8x", 123456); + + /* Character and string conversions. */ + checkf ("foobar", "%c%c%c%c%c%c", 'f', 'o', 'o', 'b', 'a', 'r'); + checkf (" left-right ", "%6s%s%-7s", "left", "-", "right"); + checkf ("trim", "%.4s", "trimoff"); + checkf ("%%", "%%%%"); + + /* From Cristian Cadar's automatic test case generator. */ + checkf (" abcdefgh", "%9s", "abcdefgh"); + checkf ("36657730000", "%- o", (unsigned) 036657730000); + checkf ("4139757568", "%- u", (unsigned) 4139757568UL); + checkf ("f6bfb000", "%- x", (unsigned) 0xf6bfb000); + checkf ("36657730000", "%-to", (ptrdiff_t) 036657730000); + checkf ("4139757568", "%-tu", (ptrdiff_t) 4139757568UL); + checkf ("-155209728", "%-zi", (size_t) -155209728); + checkf ("-155209728", "%-zd", (size_t) -155209728); + checkf ("036657730000", "%+#o", (unsigned) 036657730000); + checkf ("0xf6bfb000", "%+#x", (unsigned) 0xf6bfb000); + checkf ("-155209728", "% zi", (size_t) -155209728); + checkf ("-155209728", "% zd", (size_t) -155209728); + checkf ("4139757568", "% tu", (ptrdiff_t) 4139757568UL); + checkf ("036657730000", "% #o", (unsigned) 036657730000); + checkf ("0xf6bfb000", "% #x", (unsigned) 0xf6bfb000); + checkf ("0xf6bfb000", "%# x", (unsigned) 0xf6bfb000); + checkf ("-155209728", "%#zd", (size_t) -155209728); + checkf ("-155209728", "%0zi", (size_t) -155209728); + checkf ("4,139,757,568", "%'tu", (ptrdiff_t) 4139757568UL); + checkf ("-155,209,728", "%-'d", -155209728); + checkf ("-155209728", "%.zi", (size_t) -155209728); + checkf ("-155209728", "%zi", (size_t) -155209728); + checkf ("-155209728", "%zd", (size_t) -155209728); + checkf ("-155209728", "%+zi", (size_t) -155209728); + + if (failure_cnt == 0) + printf ("\nstdio: PASS\n"); + else + printf ("\nstdio: FAIL: %d tests failed\n", failure_cnt); +} diff --git a/src/tests/internal/stdlib.c b/src/tests/internal/stdlib.c new file mode 100644 index 0000000..ad0f0f9 --- /dev/null +++ b/src/tests/internal/stdlib.c @@ -0,0 +1,114 @@ +/* Test program for sorting and searching in lib/stdlib.c. + + Attempts to test the sorting and searching functionality that + is not sufficiently tested elsewhere in Pintos. + + This is not a test we will run on your submitted projects. + It is here for completeness. +*/ + +#undef NDEBUG +#include <debug.h> +#include <limits.h> +#include <random.h> +#include <stdlib.h> +#include <stdio.h> +#include "threads/test.h" + +/* Maximum number of elements in an array that we will test. */ +#define MAX_CNT 4096 + +static void shuffle (int[], size_t); +static int compare_ints (const void *, const void *); +static void verify_order (const int[], size_t); +static void verify_bsearch (const int[], size_t); + +/* Test sorting and searching implementations. */ +void +test (void) +{ + int cnt; + + printf ("testing various size arrays:"); + for (cnt = 0; cnt < MAX_CNT; cnt = cnt * 4 / 3 + 1) + { + int repeat; + + printf (" %zu", cnt); + for (repeat = 0; repeat < 10; repeat++) + { + static int values[MAX_CNT]; + int i; + + /* Put values 0...CNT in random order in VALUES. */ + for (i = 0; i < cnt; i++) + values[i] = i; + shuffle (values, cnt); + + /* Sort VALUES, then verify ordering. */ + qsort (values, cnt, sizeof *values, compare_ints); + verify_order (values, cnt); + verify_bsearch (values, cnt); + } + } + + printf (" done\n"); + printf ("stdlib: PASS\n"); +} + +/* Shuffles the CNT elements in ARRAY into random order. */ +static void +shuffle (int *array, size_t cnt) +{ + size_t i; + + for (i = 0; i < cnt; i++) + { + size_t j = i + random_ulong () % (cnt - i); + int t = array[j]; + array[j] = array[i]; + array[i] = t; + } +} + +/* Returns 1 if *A is greater than *B, + 0 if *A equals *B, + -1 if *A is less than *B. */ +static int +compare_ints (const void *a_, const void *b_) +{ + const int *a = a_; + const int *b = b_; + + return *a < *b ? -1 : *a > *b; +} + +/* Verifies that ARRAY contains the CNT ints 0...CNT-1. */ +static void +verify_order (const int *array, size_t cnt) +{ + int i; + + for (i = 0; (size_t) i < cnt; i++) + ASSERT (array[i] == i); +} + +/* Checks that bsearch() works properly in ARRAY. ARRAY must + contain the values 0...CNT-1. */ +static void +verify_bsearch (const int *array, size_t cnt) +{ + int not_in_array[] = {0, -1, INT_MAX, MAX_CNT, MAX_CNT + 1, MAX_CNT * 2}; + int i; + + /* Check that all the values in the array are found properly. */ + for (i = 0; (size_t) i < cnt; i++) + ASSERT (bsearch (&i, array, cnt, sizeof *array, compare_ints) + == array + i); + + /* Check that some values not in the array are not found. */ + not_in_array[0] = cnt; + for (i = 0; (size_t) i < sizeof not_in_array / sizeof *not_in_array; i++) + ASSERT (bsearch (¬_in_array[i], array, cnt, sizeof *array, compare_ints) + == NULL); +} |
