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