Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / tests / deflate_test.c
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 /** @file
23  *
24  * DEFLATE tests
25  *
26  */
27
28 /* Forcibly enable assertions */
29 #undef NDEBUG
30
31 #include <stdint.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ipxe/deflate.h>
35 #include <ipxe/test.h>
36
37 /** A DEFLATE test */
38 struct deflate_test {
39         /** Compression format */
40         enum deflate_format format;
41         /** Compressed data */
42         const void *compressed;
43         /** Length of compressed data */
44         size_t compressed_len;
45         /** Expected uncompressed data */
46         const void *expected;
47         /** Length of expected uncompressed data */
48         size_t expected_len;
49 };
50
51 /** A DEFLATE fragment list */
52 struct deflate_test_fragments {
53         /** Fragment lengths */
54         size_t len[8];
55 };
56
57 /** Define inline data */
58 #define DATA(...) { __VA_ARGS__ }
59
60 /** Define a DEFLATE test */
61 #define DEFLATE( name, FORMAT, COMPRESSED, EXPECTED )                   \
62         static const uint8_t name ## _compressed[] = COMPRESSED;        \
63         static const uint8_t name ## _expected[] = EXPECTED;            \
64         static struct deflate_test name = {                             \
65                 .format = FORMAT,                                       \
66                 .compressed = name ## _compressed,                      \
67                 .compressed_len = sizeof ( name ## _compressed ),       \
68                 .expected = name ## _expected,                          \
69                 .expected_len = sizeof ( name ## _expected ),           \
70         };
71
72 /* Empty file, no compression */
73 DEFLATE ( empty_literal, DEFLATE_RAW,
74           DATA ( 0x01, 0x00, 0x00, 0xff, 0xff ), DATA() );
75
76 /* "iPXE" string, no compression */
77 DEFLATE ( literal, DEFLATE_RAW,
78           DATA ( 0x01, 0x04, 0x00, 0xfb, 0xff, 0x69, 0x50, 0x58, 0x45 ),
79           DATA ( 0x69, 0x50, 0x58, 0x45 ) );
80
81 /* "iPXE" string, no compression, split into two literals */
82 DEFLATE ( split_literal, DEFLATE_RAW,
83           DATA ( 0x00, 0x02, 0x00, 0xfd, 0xff, 0x69, 0x50, 0x01, 0x02, 0x00,
84                  0xfd, 0xff, 0x58, 0x45 ),
85           DATA ( 0x69, 0x50, 0x58, 0x45 ) );
86
87 /* Empty file */
88 DEFLATE ( empty, DEFLATE_RAW, DATA ( 0x03, 0x00 ), DATA() );
89
90 /* "Hello world" */
91 DEFLATE ( hello_world, DEFLATE_RAW,
92           DATA ( 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca,
93                  0x49, 0x01, 0x00 ),
94           DATA ( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c,
95                  0x64 ) );
96
97 /* "Hello hello world" */
98 DEFLATE ( hello_hello_world, DEFLATE_RAW,
99           DATA ( 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0x57, 0xc8, 0x00, 0x93, 0xe5,
100                  0xf9, 0x45, 0x39, 0x29, 0x00 ),
101           DATA ( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x68, 0x65, 0x6c, 0x6c,
102                  0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64 ) );
103
104 /* "This specification defines a lossless compressed data format" */
105 DEFLATE ( rfc_sentence, DEFLATE_RAW,
106           DATA ( 0x0d, 0xc6, 0xdb, 0x09, 0x00, 0x21, 0x0c, 0x04, 0xc0, 0x56,
107                  0xb6, 0x28, 0x1b, 0x08, 0x79, 0x70, 0x01, 0x35, 0xe2, 0xa6,
108                  0x7f, 0xce, 0xf9, 0x9a, 0xf1, 0x25, 0xc1, 0xe3, 0x9a, 0x91,
109                  0x2a, 0x9d, 0xb5, 0x61, 0x1e, 0xb9, 0x9d, 0x10, 0xcc, 0x22,
110                  0xa7, 0x93, 0xd0, 0x5a, 0xe7, 0xbe, 0xb8, 0xc1, 0xa4, 0x05,
111                  0x51, 0x77, 0x49, 0xff ),
112           DATA ( 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69,
113                  0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64,
114                  0x65, 0x66, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x61, 0x20, 0x6c,
115                  0x6f, 0x73, 0x73, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x63, 0x6f,
116                  0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x64,
117                  0x61, 0x74, 0x61, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74 ) );
118
119 /* "ZLIB Compressed Data Format Specification" */
120 DEFLATE ( zlib, DEFLATE_ZLIB,
121           DATA ( 0x78, 0x01, 0x8b, 0xf2, 0xf1, 0x74, 0x52, 0x70, 0xce, 0xcf,
122                  0x2d, 0x28, 0x4a, 0x2d, 0x2e, 0x4e, 0x4d, 0x51, 0x70, 0x49,
123                  0x2c, 0x49, 0x54, 0x70, 0xcb, 0x2f, 0xca, 0x4d, 0x2c, 0x51,
124                  0x08, 0x2e, 0x48, 0x4d, 0xce, 0x4c, 0xcb, 0x4c, 0x4e, 0x2c,
125                  0xc9, 0xcc, 0xcf, 0x03, 0x00, 0x2c, 0x0e, 0x0e, 0xeb ),
126           DATA ( 0x5a, 0x4c, 0x49, 0x42, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x72,
127                  0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x44, 0x61, 0x74, 0x61,
128                  0x20, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x53, 0x70,
129                  0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
130                  0x6e ) );
131
132 /* "ZLIB Compressed Data Format Specification" fragment list */
133 static struct deflate_test_fragments zlib_fragments[] = {
134         { { -1UL, } },
135         { { 0, 1, 5, -1UL, } },
136         { { 0, 0, 1, 0, 0, 1, -1UL } },
137         { { 10, 8, 4, 7, 11, -1UL } },
138         { { 45, -1UL } },
139         { { 48, -1UL } },
140 };
141
142 /**
143  * Report DEFLATE test result
144  *
145  * @v deflate           Decompressor
146  * @v test              Deflate test
147  * @v frags             Fragment list, or NULL
148  * @v file              Test code file
149  * @v line              Test code line
150  */
151 static void deflate_okx ( struct deflate *deflate,
152                           struct deflate_test *test,
153                           struct deflate_test_fragments *frags,
154                           const char *file, unsigned int line ) {
155         uint8_t data[ test->expected_len ];
156         struct deflate_chunk in;
157         struct deflate_chunk out;
158         size_t frag_len = -1UL;
159         size_t offset = 0;
160         size_t remaining = test->compressed_len;
161         unsigned int i;
162
163         /* Initialise decompressor */
164         deflate_init ( deflate, test->format );
165
166         /* Initialise output chunk */
167         deflate_chunk_init ( &out, virt_to_user ( data ), 0, sizeof ( data ) );
168
169         /* Process input (in fragments, if applicable) */
170         for ( i = 0 ; i < ( sizeof ( frags->len ) /
171                             sizeof ( frags->len[0] ) ) ; i++ ) {
172
173                 /* Initialise input chunk */
174                 if ( frags )
175                         frag_len = frags->len[i];
176                 if ( frag_len > remaining )
177                         frag_len = remaining;
178                 deflate_chunk_init ( &in, virt_to_user ( test->compressed ),
179                                      offset, ( offset + frag_len ) );
180
181                 /* Decompress this fragment */
182                 okx ( deflate_inflate ( deflate, &in, &out ) == 0, file, line );
183                 okx ( in.len == ( offset + frag_len ), file, line );
184                 okx ( in.offset == in.len, file, line );
185
186                 /* Move to next fragment */
187                 offset = in.offset;
188                 remaining -= frag_len;
189                 if ( ! remaining )
190                         break;
191
192                 /* Check that decompression has not terminated early */
193                 okx ( ! deflate_finished ( deflate ), file, line );
194         }
195
196         /* Check decompression has terminated as expected */
197         okx ( deflate_finished ( deflate ), file, line );
198         okx ( offset == test->compressed_len, file, line );
199         okx ( out.offset == test->expected_len, file, line );
200         okx ( memcmp ( data, test->expected, test->expected_len ) == 0,
201              file, line );
202 }
203 #define deflate_ok( deflate, test, frags ) \
204         deflate_okx ( deflate, test, frags, __FILE__, __LINE__ )
205
206 /**
207  * Perform DEFLATE self-test
208  *
209  */
210 static void deflate_test_exec ( void ) {
211         struct deflate *deflate;
212         unsigned int i;
213
214         /* Allocate shared structure */
215         deflate = malloc ( sizeof ( *deflate ) );
216         ok ( deflate != NULL );
217
218         /* Perform self-tests */
219         if ( deflate ) {
220
221                 /* Test as a single pass */
222                 deflate_ok ( deflate, &empty_literal, NULL );
223                 deflate_ok ( deflate, &literal, NULL );
224                 deflate_ok ( deflate, &split_literal, NULL );
225                 deflate_ok ( deflate, &empty, NULL );
226                 deflate_ok ( deflate, &hello_world, NULL );
227                 deflate_ok ( deflate, &hello_hello_world, NULL );
228                 deflate_ok ( deflate, &rfc_sentence, NULL );
229                 deflate_ok ( deflate, &zlib, NULL );
230
231                 /* Test fragmentation */
232                 for ( i = 0 ; i < ( sizeof ( zlib_fragments ) /
233                                     sizeof ( zlib_fragments[0] ) ) ; i++ ) {
234                         deflate_ok ( deflate, &zlib, &zlib_fragments[i] );
235                 }
236         }
237
238         /* Free shared structure */
239         free ( deflate );
240 }
241
242 /** DEFLATE self-test */
243 struct self_test deflate_test __self_test = {
244         .name = "deflate",
245         .exec = deflate_test_exec,
246 };