1 /* 2 * Xor Based Zero Run Length Encoding unit tests. 3 * 4 * Copyright 2013 Red Hat, Inc. and/or its affiliates 5 * 6 * Authors: 7 * Orit Wasserman <owasserm@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 * 12 */ 13 #include "qemu/osdep.h" 14 #include "qemu/cutils.h" 15 #include "../migration/xbzrle.h" 16 17 #define XBZRLE_PAGE_SIZE 4096 18 19 static void test_uleb(void) 20 { 21 uint32_t i, val; 22 uint8_t buf[2]; 23 int encode_ret, decode_ret; 24 25 for (i = 0; i <= 0x3fff; i++) { 26 encode_ret = uleb128_encode_small(&buf[0], i); 27 decode_ret = uleb128_decode_small(&buf[0], &val); 28 g_assert(encode_ret == decode_ret); 29 g_assert(i == val); 30 } 31 32 /* decode invalid value */ 33 buf[0] = 0x80; 34 buf[1] = 0x80; 35 36 decode_ret = uleb128_decode_small(&buf[0], &val); 37 g_assert(decode_ret == -1); 38 g_assert(val == 0); 39 } 40 41 static void test_encode_decode_zero(void) 42 { 43 uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); 44 uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE); 45 int i = 0; 46 int dlen = 0; 47 int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006); 48 49 for (i = diff_len; i > 0; i--) { 50 buffer[1000 + i] = i; 51 } 52 53 buffer[1000 + diff_len + 3] = 103; 54 buffer[1000 + diff_len + 5] = 105; 55 56 /* encode zero page */ 57 dlen = xbzrle_encode_buffer(buffer, buffer, XBZRLE_PAGE_SIZE, 58 compressed, XBZRLE_PAGE_SIZE); 59 g_assert(dlen == 0); 60 61 g_free(buffer); 62 g_free(compressed); 63 } 64 65 static void test_encode_decode_unchanged(void) 66 { 67 uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE); 68 uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); 69 int i = 0; 70 int dlen = 0; 71 int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006); 72 73 for (i = diff_len; i > 0; i--) { 74 test[1000 + i] = i + 4; 75 } 76 77 test[1000 + diff_len + 3] = 107; 78 test[1000 + diff_len + 5] = 109; 79 80 /* test unchanged buffer */ 81 dlen = xbzrle_encode_buffer(test, test, XBZRLE_PAGE_SIZE, 82 compressed, XBZRLE_PAGE_SIZE); 83 g_assert(dlen == 0); 84 85 g_free(test); 86 g_free(compressed); 87 } 88 89 static void test_encode_decode_1_byte(void) 90 { 91 uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); 92 uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); 93 uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE); 94 int dlen = 0, rc = 0; 95 uint8_t buf[2]; 96 97 test[XBZRLE_PAGE_SIZE - 1] = 1; 98 99 dlen = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, 100 compressed, XBZRLE_PAGE_SIZE); 101 g_assert(dlen == (uleb128_encode_small(&buf[0], 4095) + 2)); 102 103 rc = xbzrle_decode_buffer(compressed, dlen, buffer, XBZRLE_PAGE_SIZE); 104 g_assert(rc == XBZRLE_PAGE_SIZE); 105 g_assert(memcmp(test, buffer, XBZRLE_PAGE_SIZE) == 0); 106 107 g_free(buffer); 108 g_free(compressed); 109 g_free(test); 110 } 111 112 static void test_encode_decode_overflow(void) 113 { 114 uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE); 115 uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); 116 uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); 117 int i = 0, rc = 0; 118 119 for (i = 0; i < XBZRLE_PAGE_SIZE / 2 - 1; i++) { 120 test[i * 2] = 1; 121 } 122 123 /* encode overflow */ 124 rc = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, 125 compressed, XBZRLE_PAGE_SIZE); 126 g_assert(rc == -1); 127 128 g_free(buffer); 129 g_free(compressed); 130 g_free(test); 131 } 132 133 static void encode_decode_range(void) 134 { 135 uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); 136 uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE); 137 uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); 138 int i = 0, rc = 0; 139 int dlen = 0; 140 141 int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006); 142 143 for (i = diff_len; i > 0; i--) { 144 buffer[1000 + i] = i; 145 test[1000 + i] = i + 4; 146 } 147 148 buffer[1000 + diff_len + 3] = 103; 149 test[1000 + diff_len + 3] = 107; 150 151 buffer[1000 + diff_len + 5] = 105; 152 test[1000 + diff_len + 5] = 109; 153 154 /* test encode/decode */ 155 dlen = xbzrle_encode_buffer(test, buffer, XBZRLE_PAGE_SIZE, 156 compressed, XBZRLE_PAGE_SIZE); 157 158 rc = xbzrle_decode_buffer(compressed, dlen, test, XBZRLE_PAGE_SIZE); 159 g_assert(rc < XBZRLE_PAGE_SIZE); 160 g_assert(memcmp(test, buffer, XBZRLE_PAGE_SIZE) == 0); 161 162 g_free(buffer); 163 g_free(compressed); 164 g_free(test); 165 } 166 167 static void test_encode_decode(void) 168 { 169 int i; 170 171 for (i = 0; i < 10000; i++) { 172 encode_decode_range(); 173 } 174 } 175 176 int main(int argc, char **argv) 177 { 178 g_test_init(&argc, &argv, NULL); 179 g_test_rand_int(); 180 g_test_add_func("/xbzrle/uleb", test_uleb); 181 g_test_add_func("/xbzrle/encode_decode_zero", test_encode_decode_zero); 182 g_test_add_func("/xbzrle/encode_decode_unchanged", 183 test_encode_decode_unchanged); 184 g_test_add_func("/xbzrle/encode_decode_1_byte", test_encode_decode_1_byte); 185 g_test_add_func("/xbzrle/encode_decode_overflow", 186 test_encode_decode_overflow); 187 g_test_add_func("/xbzrle/encode_decode", test_encode_decode); 188 189 return g_test_run(); 190 } 191