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