2 * Copyright (C) 2018-2021 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 #undef NDEBUG /* Keep test strong even for nbdkit built without assertions */
42 #include <nbdkit-filter.h>
45 #define DEBUG_FUNCTION nbdkit_debug ("%s: %s", layer, __func__)
47 /* Perform sanity checking on nbdkit_next stability */
48 static nbdkit_backend
*saved_backend
;
54 test_layers_filter_load (void)
60 test_layers_filter_unload (void)
66 test_layers_filter_config (nbdkit_next_config
*next
, nbdkit_backend
*nxdata
,
67 const char *key
, const char *value
)
70 return next (nxdata
, key
, value
);
74 test_layers_filter_config_complete (nbdkit_next_config_complete
*next
,
75 nbdkit_backend
*nxdata
)
81 #define test_layers_filter_config_help \
82 "test_layers_" layer "_config_help"
85 test_layers_filter_thread_model (void)
88 return NBDKIT_THREAD_MODEL_PARALLEL
;
92 test_layers_filter_get_ready (int thread_model
)
99 test_layers_filter_after_fork (nbdkit_backend
*backend
)
102 saved_backend
= backend
;
107 test_layers_filter_cleanup (nbdkit_backend
*backend
)
109 assert (backend
== saved_backend
);
114 test_layers_filter_preconnect (nbdkit_next_preconnect
*next
,
115 nbdkit_backend
*nxdata
, int readonly
)
117 assert (nxdata
== saved_backend
);
119 return next (nxdata
, readonly
);
123 test_layers_filter_list_exports (nbdkit_next_list_exports
*next
,
124 nbdkit_backend
*nxdata
,
125 int readonly
, int is_tls
,
126 struct nbdkit_exports
*exports
)
128 assert (nxdata
== saved_backend
);
130 return next (nxdata
, readonly
, exports
);
134 test_layers_filter_default_export (nbdkit_next_default_export
*next
,
135 nbdkit_backend
*nxdata
, int readonly
,
138 assert (nxdata
== saved_backend
);
140 return next (nxdata
, readonly
);
144 test_layers_filter_open (nbdkit_next_open
*next
, nbdkit_context
*nxdata
,
145 int readonly
, const char *exportname
, int is_tls
)
147 struct handle
*h
= calloc (1, sizeof *h
);
149 assert (nbdkit_context_get_backend (nxdata
) == saved_backend
);
155 /* Demonstrate our claim that next() is sugar for open-coding. */
156 if (strcmp (layer
, "filter2") == 0) {
157 nbdkit_backend
*backend
;
158 nbdkit_next
*n
, *old
;
160 backend
= nbdkit_context_get_backend (nxdata
);
161 assert (backend
!= NULL
);
162 n
= nbdkit_next_context_open (backend
, readonly
, exportname
, 0);
167 old
= nbdkit_context_set_next (nxdata
, n
);
168 assert (old
== NULL
);
171 else if (next (nxdata
, readonly
, exportname
) == -1) {
176 /* Debug after recursing, to show opposite order from .close */
183 test_layers_filter_close (void *handle
)
190 test_layers_filter_prepare (nbdkit_next
*next
,
191 void *handle
, int readonly
)
193 struct handle
*h
= handle
;
195 if (strcmp (layer
, "filter2") == 0)
196 assert (h
->next
== next
);
198 assert (h
->next
== NULL
);
206 test_layers_filter_finalize (nbdkit_next
*next
,
209 struct handle
*h
= handle
;
211 assert (h
->next
== next
);
217 test_layers_filter_get_size (nbdkit_next
*next
,
220 struct handle
*h
= handle
;
222 assert (h
->next
== next
);
224 return next
->get_size (next
);
228 test_layers_filter_can_write (nbdkit_next
*next
,
231 struct handle
*h
= handle
;
233 assert (h
->next
== next
);
235 return next
->can_write (next
);
239 test_layers_filter_can_flush (nbdkit_next
*next
,
242 struct handle
*h
= handle
;
244 assert (h
->next
== next
);
246 return next
->can_flush (next
);
250 test_layers_filter_is_rotational (nbdkit_next
*next
,
253 struct handle
*h
= handle
;
255 assert (h
->next
== next
);
257 return next
->is_rotational (next
);
261 test_layers_filter_can_trim (nbdkit_next
*next
,
264 struct handle
*h
= handle
;
266 assert (h
->next
== next
);
268 return next
->can_trim (next
);
272 test_layers_filter_can_zero (nbdkit_next
*next
,
275 struct handle
*h
= handle
;
277 assert (h
->next
== next
);
279 return next
->can_zero (next
);
283 test_layers_filter_can_fast_zero (nbdkit_next
*next
, void *handle
)
285 struct handle
*h
= handle
;
287 assert (h
->next
== next
);
289 return next
->can_fast_zero (next
);
293 test_layers_filter_can_fua (nbdkit_next
*next
,
296 struct handle
*h
= handle
;
298 assert (h
->next
== next
);
300 return next
->can_fua (next
);
304 test_layers_filter_can_multi_conn (nbdkit_next
*next
,
307 struct handle
*h
= handle
;
309 assert (h
->next
== next
);
311 return next
->can_multi_conn (next
);
315 test_layers_filter_can_extents (nbdkit_next
*next
,
318 struct handle
*h
= handle
;
320 assert (h
->next
== next
);
322 return next
->can_extents (next
);
326 test_layers_filter_can_cache (nbdkit_next
*next
,
329 struct handle
*h
= handle
;
331 assert (h
->next
== next
);
333 return next
->can_cache (next
);
337 test_layers_filter_pread (nbdkit_next
*next
,
338 void *handle
, void *buf
,
339 uint32_t count
, uint64_t offset
,
340 uint32_t flags
, int *err
)
342 struct handle
*h
= handle
;
344 assert (h
->next
== next
);
346 return next
->pread (next
, buf
, count
, offset
, flags
, err
);
350 test_layers_filter_pwrite (nbdkit_next
*next
,
352 const void *buf
, uint32_t count
, uint64_t offset
,
353 uint32_t flags
, int *err
)
355 struct handle
*h
= handle
;
357 assert (h
->next
== next
);
359 return next
->pwrite (next
, buf
, count
, offset
, flags
, err
);
363 test_layers_filter_flush (nbdkit_next
*next
,
365 uint32_t flags
, int *err
)
367 struct handle
*h
= handle
;
369 assert (h
->next
== next
);
371 return next
->flush (next
, flags
, err
);
375 test_layers_filter_trim (nbdkit_next
*next
,
376 void *handle
, uint32_t count
, uint64_t offset
,
377 uint32_t flags
, int *err
)
379 struct handle
*h
= handle
;
381 assert (h
->next
== next
);
383 return next
->trim (next
, count
, offset
, flags
, err
);
387 test_layers_filter_zero (nbdkit_next
*next
,
388 void *handle
, uint32_t count
, uint64_t offset
,
389 uint32_t flags
, int *err
)
391 struct handle
*h
= handle
;
393 assert (h
->next
== next
);
395 return next
->zero (next
, count
, offset
, flags
, err
);
399 test_layers_filter_extents (nbdkit_next
*next
,
400 void *handle
, uint32_t count
, uint64_t offset
,
401 uint32_t flags
, struct nbdkit_extents
*extents
,
404 struct handle
*h
= handle
;
406 assert (h
->next
== next
);
408 return next
->extents (next
, count
, offset
, flags
, extents
, err
);
412 test_layers_filter_cache (nbdkit_next
*next
,
413 void *handle
, uint32_t count
, uint64_t offset
,
414 uint32_t flags
, int *err
)
416 struct handle
*h
= handle
;
418 assert (h
->next
== next
);
420 return next
->cache (next
, count
, offset
, flags
, err
);
423 static struct nbdkit_filter filter
= {
424 .name
= "testlayers" layer
,
425 .load
= test_layers_filter_load
,
426 .unload
= test_layers_filter_unload
,
427 .config
= test_layers_filter_config
,
428 .config_complete
= test_layers_filter_config_complete
,
429 .config_help
= test_layers_filter_config_help
,
430 .thread_model
= test_layers_filter_thread_model
,
431 .get_ready
= test_layers_filter_get_ready
,
432 .after_fork
= test_layers_filter_after_fork
,
433 .cleanup
= test_layers_filter_cleanup
,
434 .preconnect
= test_layers_filter_preconnect
,
435 .list_exports
= test_layers_filter_list_exports
,
436 .default_export
= test_layers_filter_default_export
,
437 .open
= test_layers_filter_open
,
438 .close
= test_layers_filter_close
,
439 .prepare
= test_layers_filter_prepare
,
440 .finalize
= test_layers_filter_finalize
,
441 .get_size
= test_layers_filter_get_size
,
442 .can_write
= test_layers_filter_can_write
,
443 .can_flush
= test_layers_filter_can_flush
,
444 .is_rotational
= test_layers_filter_is_rotational
,
445 .can_trim
= test_layers_filter_can_trim
,
446 .can_zero
= test_layers_filter_can_zero
,
447 .can_fast_zero
= test_layers_filter_can_fast_zero
,
448 .can_fua
= test_layers_filter_can_fua
,
449 .can_multi_conn
= test_layers_filter_can_multi_conn
,
450 .can_extents
= test_layers_filter_can_extents
,
451 .can_cache
= test_layers_filter_can_cache
,
452 .pread
= test_layers_filter_pread
,
453 .pwrite
= test_layers_filter_pwrite
,
454 .flush
= test_layers_filter_flush
,
455 .trim
= test_layers_filter_trim
,
456 .zero
= test_layers_filter_zero
,
457 .extents
= test_layers_filter_extents
,
458 .cache
= test_layers_filter_cache
,
461 NBDKIT_REGISTER_FILTER(filter
)