|
1 | 1 | #include <stdio.h> |
2 | 2 | #include <stdlib.h> |
| 3 | +#include <string.h> |
3 | 4 | #include <assert.h> |
4 | 5 | #include <unistd.h> |
5 | 6 | #include <fcntl.h> |
|
9 | 10 | #include "util.h" |
10 | 11 | #include "criu-log.h" |
11 | 12 | #include "bfd.h" |
| 13 | +#include "compression.h" |
| 14 | +#include "page.h" |
12 | 15 |
|
13 | 16 | int parse_statement(int i, char *line, char **configuration); |
14 | 17 |
|
@@ -92,6 +95,72 @@ static void test_bwrite(void) |
92 | 95 | free(read_buf); |
93 | 96 | } |
94 | 97 |
|
| 98 | +#ifdef CONFIG_LZ4 |
| 99 | +static void test_compress_roundtrip(const char *page, int acceleration) |
| 100 | +{ |
| 101 | + char compressed[PAGE_COMPRESSED_SIZE_BOUND]; |
| 102 | + char decompressed[PAGE_SIZE]; |
| 103 | + int cs; |
| 104 | + |
| 105 | + cs = compress_data(page, PAGE_SIZE, compressed, |
| 106 | + PAGE_COMPRESSED_SIZE_BOUND, acceleration); |
| 107 | + assert(cs > 0); |
| 108 | + assert(cs <= PAGE_COMPRESSED_SIZE_BOUND); |
| 109 | + assert(decompress_data(compressed, cs, PAGE_SIZE, decompressed) == 0); |
| 110 | + assert(memcmp(page, decompressed, PAGE_SIZE) == 0); |
| 111 | +} |
| 112 | + |
| 113 | +static void test_compression(void) |
| 114 | +{ |
| 115 | + char cbuf[PAGE_COMPRESSED_SIZE_BOUND]; |
| 116 | + char page[PAGE_SIZE]; |
| 117 | + int cs; |
| 118 | + int accels[] = { 1, 4, 100 }; |
| 119 | + |
| 120 | + /* Zero-page detection */ |
| 121 | + memset(page, 0, PAGE_SIZE); |
| 122 | + assert(page_is_all_zero(page) == true); |
| 123 | + page[PAGE_SIZE - 1] = 1; |
| 124 | + assert(page_is_all_zero(page) == false); |
| 125 | + page[PAGE_SIZE - 1] = 0; |
| 126 | + page[0] = 0x42; |
| 127 | + assert(page_is_all_zero(page) == false); |
| 128 | + |
| 129 | + |
| 130 | + for (int a = 0; a < 3; a++) { |
| 131 | + int accel = accels[a]; |
| 132 | + |
| 133 | + /* Zero-filled page: should compress well */ |
| 134 | + memset(cbuf, 0, sizeof(cbuf)); |
| 135 | + memset(page, 0, PAGE_SIZE); |
| 136 | + cs = compress_data(page, PAGE_SIZE, |
| 137 | + cbuf, PAGE_COMPRESSED_SIZE_BOUND, accel); |
| 138 | + assert(cs > 0 && cs < PAGE_SIZE); |
| 139 | + test_compress_roundtrip(page, accel); |
| 140 | + |
| 141 | + /* Repeating pattern */ |
| 142 | + for (int i = 0; i < PAGE_SIZE; i++) |
| 143 | + page[i] = i & 0xff; |
| 144 | + test_compress_roundtrip(page, accel); |
| 145 | + |
| 146 | + /* Pseudo-random data (incompressible) */ |
| 147 | + srand(42); |
| 148 | + for (int i = 0; i < PAGE_SIZE; i++) |
| 149 | + page[i] = rand() & 0xff; |
| 150 | + test_compress_roundtrip(page, accel); |
| 151 | + |
| 152 | + /* Single non-zero byte */ |
| 153 | + memset(page, 0, PAGE_SIZE); |
| 154 | + page[0] = 0x42; |
| 155 | + cs = compress_data(page, PAGE_SIZE, |
| 156 | + (char[PAGE_COMPRESSED_SIZE_BOUND]){0}, |
| 157 | + PAGE_COMPRESSED_SIZE_BOUND, accel); |
| 158 | + assert(cs > 0 && cs < PAGE_SIZE); |
| 159 | + test_compress_roundtrip(page, accel); |
| 160 | + } |
| 161 | +} |
| 162 | +#endif |
| 163 | + |
95 | 164 | int main(int argc, char *argv[], char *envp[]) |
96 | 165 | { |
97 | 166 | char **configuration; |
@@ -230,6 +299,10 @@ int main(int argc, char *argv[], char *envp[]) |
230 | 299 | /* leaves punctuation in returned string as is */ |
231 | 300 | assert(!strcmp(get_relative_path("./a////.///./b//././c", "a"), "b//././c")); |
232 | 301 |
|
| 302 | +#ifdef CONFIG_LZ4 |
| 303 | + test_compression(); |
| 304 | +#endif |
| 305 | + |
233 | 306 | pr_msg("OK\n"); |
234 | 307 | return 0; |
235 | 308 | } |
0 commit comments