1 /* test/test_bgzf.c -- bgzf unit tests
3 Copyright (C) 2017 Genome Research Ltd
5 Author: Robert Davies <rmd@sanger.ac.uk>
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 DEALINGS IN THE SOFTWARE.
30 #include <sys/types.h>
33 #include "htslib/bgzf.h"
34 #include "htslib/hfile.h"
36 const char *bgzf_suffix
= ".gz";
37 const char *idx_suffix
= ".gzi";
38 const char *tmp_suffix
= ".tmp";
51 const unsigned char *text
;
61 static FILE * try_fopen(const char *name
, const char *mode
) {
62 FILE *f
= fopen(name
, mode
);
64 fprintf(stderr
, "Couldn't open %s : %s\n", name
, strerror(errno
));
70 static int try_fclose(FILE **file
, const char *name
, const char *func
) {
71 FILE *to_close
= *file
;
73 if (fclose(to_close
) != 0) {
74 fprintf(stderr
, "%s : Error on closing %s : %s\n",
75 func
, name
, strerror(errno
));
82 static ssize_t
try_fread(FILE *in
, void *buf
, size_t len
,
83 const char *func
, const char *fname
) {
84 size_t got
= fread(buf
, 1, len
, in
);
85 if (got
== 0 && ferror(in
)) {
86 fprintf(stderr
, "%s : Error reading from %s : %s\n",
87 func
, fname
, strerror(errno
));
93 static int try_fseek_start(FILE *f
, const char *name
, const char *func
) {
94 if (0 != fseek(f
, 0, SEEK_SET
)) {
95 fprintf(stderr
, "%s : Couldn't seek on %s : %s\n",
96 func
, name
, strerror(errno
));
102 static BGZF
* try_bgzf_open(const char *name
, const char *mode
,
104 BGZF
* bgz
= bgzf_open(name
, mode
);
106 fprintf(stderr
, "%s : Couldn't bgzf_open %s with mode %s : %s\n",
107 func
, name
, mode
, strerror(errno
));
113 static BGZF
* try_bgzf_dopen(const char *name
, const char *mode
,
117 if (strchr(mode
, 'r')) {
118 fd
= open(name
, O_RDONLY
);
119 } else if (strchr(mode
, 'w')) {
120 fd
= open(name
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
121 } else if (strchr(mode
, 'a')) {
122 fd
= open(name
, O_WRONLY
| O_CREAT
| O_APPEND
, 0666);
128 fprintf(stderr
, "%s : Failed to open %s with mode %s : %s\n",
129 func
, name
, mode
, strerror(errno
));
133 bgz
= bgzf_dopen(fd
, mode
);
135 fprintf(stderr
, "%s : bgzf_dopen failed on %s mode %s : %s\n",
136 func
, name
, mode
, strerror(errno
));
144 static BGZF
* try_bgzf_hopen(const char *name
, const char *mode
,
146 hFILE
*hfp
= hopen(name
, mode
);
150 fprintf(stderr
, "%s : hopen failed on %s mode %s : %s\n",
151 func
, name
, mode
, strerror(errno
));
155 bgz
= bgzf_hopen(hfp
, mode
);
157 fprintf(stderr
, "%s : bgzf_hopen failed on %s mode %s : %s\n",
158 func
, name
, mode
, strerror(errno
));
159 hclose_abruptly(hfp
);
166 static int try_bgzf_close(BGZF
**bgz
, const char *name
, const char *func
) {
167 BGZF
*to_close
= *bgz
;
169 if (bgzf_close(to_close
) != 0) {
170 fprintf(stderr
, "%s : bgzf_close failed on %s : %s\n",
171 func
, name
, strerror(errno
));
177 static ssize_t
try_bgzf_read(BGZF
*fp
, void *data
, size_t length
,
178 const char *name
, const char *func
) {
179 ssize_t got
= bgzf_read(fp
, data
, length
);
181 fprintf(stderr
, "%s : Error from bgzf_read %s : %s\n",
182 func
, name
, strerror(errno
));
187 static ssize_t
try_bgzf_write(BGZF
*fp
, const void *data
, size_t length
,
188 const char *name
, const char *func
) {
189 ssize_t put
= bgzf_write(fp
, data
, length
);
190 if (put
< (ssize_t
) length
) {
191 fprintf(stderr
, "%s : %s %s : %s\n",
192 func
, put
< 0 ? "Error writing to" : "Short write on",
193 name
, strerror(errno
));
200 static int try_bgzf_compression(BGZF
*fp
, int expect
,
201 const char *name
, const char *func
) {
202 int res
= bgzf_compression(fp
);
205 "%s : Unexpected result %d from bgzf_compression on %s; "
207 func
, res
, name
, expect
);
213 static int try_bgzf_mt(BGZF
*bgz
, int nthreads
, const char *func
) {
214 if (bgzf_mt(bgz
, nthreads
, 64) != 0) {
215 fprintf(stderr
, "%s : Error from bgzf_mt : %s\n",
216 func
, strerror(errno
));
222 static int try_bgzf_index_build_init(BGZF
*bgz
,
223 const char *name
, const char *func
) {
224 if (bgzf_index_build_init(bgz
) != 0) {
225 fprintf(stderr
, "%s : Error from bgzf_index_build_init on %s : %s\n",
226 func
, name
, strerror(errno
));
232 static int try_bgzf_index_load(BGZF
*fp
, const char *bname
, const char *suffix
,
234 if (bgzf_index_load(fp
, bname
, suffix
) != 0) {
235 fprintf(stderr
, "%s : Couldn't bgzf_index_load %s%s : %s\n",
236 func
, bname
, suffix
? suffix
: "", strerror(errno
));
242 static int try_bgzf_index_dump(BGZF
*fp
, const char *bname
, const char *suffix
,
244 if (bgzf_index_dump(fp
, bname
, suffix
) != 0) {
245 fprintf(stderr
, "%s : Couldn't bgzf_index_dump %s%s : %s\n",
246 func
, bname
, suffix
? suffix
: "", strerror(errno
));
252 static int try_bgzf_useek(BGZF
*fp
, long uoffset
, int where
,
253 const char *name
, const char *func
) {
254 if (bgzf_useek(fp
, uoffset
, where
) < 0) {
255 fprintf(stderr
, "%s : Error from bgzf_useek(%s, %ld, %d) : %s\n",
256 func
, name
, uoffset
, where
, strerror(errno
));
262 static int try_bgzf_getc(BGZF
*fp
, size_t pos
, int expected
,
263 const char *name
, const char *func
) {
264 int c
= bgzf_getc(fp
);
267 "%s : Unexpected value (%d) from bgzf_getc on %s pos %zu; "
269 func
, c
, name
, pos
, expected
);
275 static int compare_buffers(const unsigned char *b1
, const unsigned char *b2
,
276 size_t l1
, size_t l2
,
277 const char *name1
, const char *name2
,
280 fprintf(stderr
, "%s : EOF on %s\n", func
, l1
< l2
? name1
: name2
);
283 if (memcmp(b1
, b2
, l1
) != 0) {
284 fprintf(stderr
, "%s : difference between %s and %s\n",
292 static void cleanup(Files
*f
, int retval
) {
293 /* Remove temp files if successful. If not, leave them for inspection */
294 if (retval
== EXIT_SUCCESS
) {
298 if (f
->f_plain
) fclose(f
->f_plain
);
299 if (f
->f_bgzf
) fclose(f
->f_bgzf
);
300 if (f
->f_idx
) fclose(f
->f_idx
);
302 free((unsigned char *) f
->text
);
305 static int setup(const char *src
, Files
*f
) {
306 size_t len
= (strlen(src
) + strlen(bgzf_suffix
) + strlen(idx_suffix
)
307 + strlen(tmp_suffix
) + 8);
309 const unsigned int max
= 50000;
311 size_t text_sz
= max
* 8 + 1;
313 mem
= calloc(5, len
);
319 snprintf(mem
, len
, "%s", src
);
320 snprintf(mem
+ len
* 1, len
, "%s%s", src
, bgzf_suffix
);
321 snprintf(mem
+ len
* 2, len
, "%s%s%s", src
, bgzf_suffix
, idx_suffix
);
322 snprintf(mem
+ len
* 3, len
, "%s%s%s", src
, tmp_suffix
, bgzf_suffix
);
323 snprintf(mem
+ len
* 4, len
, "%s%s%s%s",
324 src
, tmp_suffix
, bgzf_suffix
, idx_suffix
);
327 f
->src_bgzf
= mem
+ len
* 1;
328 f
->src_idx
= mem
+ len
* 2;
329 f
->tmp_bgzf
= mem
+ len
* 3;
330 f
->tmp_idx
= mem
+ len
* 4;
332 text
= malloc(text_sz
);
337 for (i
= 0; i
< max
; i
++) snprintf(text
+ i
*8, text_sz
- i
*8, "%07d\n", i
);
338 f
->text
= (unsigned char *) text
;
339 f
->ltext
= text_sz
- 1;
341 if ((f
->f_plain
= try_fopen(f
->src_plain
, "rb")) == NULL
) goto fail
;
342 if ((f
->f_bgzf
= try_fopen(f
->src_bgzf
, "rb")) == NULL
) goto fail
;
343 if ((f
->f_idx
= try_fopen(f
->src_idx
, "rb")) == NULL
) goto fail
;
351 static int test_read(Files
*f
) {
353 ssize_t bg_got
, f_got
;
354 unsigned char bg_buf
[BUFSZ
], f_buf
[BUFSZ
];
356 bgz
= try_bgzf_open(f
->src_bgzf
, "r", __func__
);
360 bg_got
= try_bgzf_read(bgz
, bg_buf
, BUFSZ
, f
->src_bgzf
, __func__
);
361 if (bg_got
< 0) goto fail
;
363 f_got
= try_fread(f
->f_plain
, f_buf
, BUFSZ
, __func__
, f
->src_plain
);
364 if (f_got
< 0) goto fail
;
366 if (compare_buffers(f_buf
, bg_buf
, f_got
, bg_got
,
367 f
->src_plain
, f
->src_bgzf
, __func__
) != 0) {
370 } while (bg_got
> 0 && f_got
> 0);
372 if (try_bgzf_close(&bgz
, f
->src_bgzf
, __func__
) != 0) return -1;
373 if (try_fseek_start(f
->f_plain
, f
->src_plain
, __func__
) != 0) return -1;
378 if (bgz
) bgzf_close(bgz
);
382 static int test_write_read(Files
*f
, const char *mode
, Open_method method
,
383 int nthreads
, int expected_compression
) {
385 ssize_t bg_put
, bg_got
;
387 unsigned char bg_buf
[BUFSZ
];
391 bgz
= try_bgzf_dopen(f
->tmp_bgzf
, mode
, __func__
);
394 bgz
= try_bgzf_hopen(f
->tmp_bgzf
, mode
, __func__
);
397 bgz
= try_bgzf_open(f
->tmp_bgzf
, mode
, __func__
);
402 if (nthreads
> 0 && try_bgzf_mt(bgz
, nthreads
, __func__
) != 0) goto fail
;
404 bg_put
= try_bgzf_write(bgz
, f
->text
, f
->ltext
, f
->tmp_bgzf
, __func__
);
405 if (bg_put
< 0) goto fail
;
407 if (try_bgzf_close(&bgz
, f
->tmp_bgzf
, __func__
) != 0) goto fail
;
411 bgz
= try_bgzf_dopen(f
->tmp_bgzf
, "r", __func__
);
414 bgz
= try_bgzf_hopen(f
->tmp_bgzf
, "r", __func__
);
417 bgz
= try_bgzf_open(f
->tmp_bgzf
, "r", __func__
);
422 if (nthreads
> 0 && try_bgzf_mt(bgz
, nthreads
, __func__
) != 0) goto fail
;
424 if (try_bgzf_compression(bgz
, expected_compression
,
425 f
->tmp_bgzf
, __func__
) != 0) {
430 bg_got
= try_bgzf_read(bgz
, bg_buf
, BUFSZ
, f
->tmp_bgzf
, __func__
);
431 if (bg_got
< 0) goto fail
;
433 if (pos
< f
->ltext
&&
434 memcmp(f
->text
+ pos
, bg_buf
,
435 pos
+ bg_got
< f
->ltext
? bg_got
: f
->ltext
- pos
) != 0) {
436 fprintf(stderr
, "%s : Got wrong data from %s, pos %zu\n",
437 __func__
, f
->tmp_bgzf
, pos
);
441 } while (bg_got
> 0);
444 fprintf(stderr
, "%s : bgzf_read got %zd bytes; expected %zd\n",
445 __func__
, pos
, bg_put
);
449 if (try_bgzf_close(&bgz
, f
->tmp_bgzf
, __func__
) != 0) goto fail
;
454 if (bgz
) bgzf_close(bgz
);
458 static int test_embed_eof(Files
*f
, const char *mode
, int nthreads
) {
460 ssize_t bg_put
, bg_got
;
461 size_t pos
= 0, half
= BUFSZ
< f
->ltext
? BUFSZ
: f
->ltext
/ 2;
462 char append_mode
[16];
463 unsigned char bg_buf
[BUFSZ
];
465 for (pos
= 0; pos
< sizeof(append_mode
) - 1 && mode
[pos
] != 0; pos
++) {
466 append_mode
[pos
] = mode
[pos
] == 'w' ? 'a' : mode
[pos
];
468 append_mode
[pos
] ='\0';
471 bgz
= try_bgzf_open(f
->tmp_bgzf
, mode
, __func__
);
474 if (nthreads
> 0 && try_bgzf_mt(bgz
, nthreads
, __func__
) != 0) goto fail
;
476 bg_put
= try_bgzf_write(bgz
, f
->text
, half
, f
->tmp_bgzf
, __func__
);
477 if (bg_put
< 0) goto fail
;
479 if (try_bgzf_close(&bgz
, f
->tmp_bgzf
, __func__
) != 0) goto fail
;
482 // Write second half. Append mode, so an EOF block should be in the
484 bgz
= try_bgzf_open(f
->tmp_bgzf
, append_mode
, __func__
);
487 if (nthreads
> 0 && try_bgzf_mt(bgz
, nthreads
, __func__
) != 0) goto fail
;
489 bg_put
= try_bgzf_write(bgz
, f
->text
+ half
, f
->ltext
- half
, f
->tmp_bgzf
,
491 if (bg_put
< 0) goto fail
;
493 if (try_bgzf_close(&bgz
, f
->tmp_bgzf
, __func__
) != 0) goto fail
;
497 bgz
= try_bgzf_open(f
->tmp_bgzf
, "r", __func__
);
500 if (nthreads
> 0 && try_bgzf_mt(bgz
, nthreads
, __func__
) != 0) goto fail
;
503 bg_got
= try_bgzf_read(bgz
, bg_buf
, BUFSZ
, f
->tmp_bgzf
, __func__
);
504 if (bg_got
< 0) goto fail
;
506 if (pos
< f
->ltext
&&
507 memcmp(f
->text
+ pos
, bg_buf
,
508 pos
+ bg_got
< f
->ltext
? bg_got
: f
->ltext
- pos
) != 0) {
509 fprintf(stderr
, "%s : Got wrong data from %s, pos %zu\n",
510 __func__
, f
->tmp_bgzf
, pos
);
514 } while (bg_got
> 0);
516 if (pos
!= f
->ltext
) {
517 fprintf(stderr
, "%s : bgzf_read got %zd bytes; expected %zd\n",
518 __func__
, pos
, f
->ltext
);
522 if (try_bgzf_close(&bgz
, f
->tmp_bgzf
, __func__
) != 0) goto fail
;
527 if (bgz
) bgzf_close(bgz
);
531 static int test_index_load_dump(Files
*f
) {
534 unsigned char buf_src
[BUFSZ
], buf_dest
[BUFSZ
];
535 ssize_t got_src
, got_dest
;
537 bgz
= try_bgzf_open(f
->src_bgzf
, "r", __func__
);
540 if (try_bgzf_index_load(bgz
, f
->src_bgzf
, idx_suffix
, __func__
) != 0) {
544 if (try_bgzf_index_dump(bgz
, f
->tmp_bgzf
, idx_suffix
, __func__
) != 0) {
548 fdest
= try_fopen(f
->tmp_idx
, "r");
550 got_src
= try_fread(f
->f_idx
, buf_src
, BUFSZ
, __func__
, f
->src_idx
);
551 if (got_src
< 0) goto fail
;
552 got_dest
= try_fread(fdest
, buf_dest
, BUFSZ
, __func__
, f
->tmp_idx
);
553 if (got_dest
< 0) goto fail
;
554 if (compare_buffers(buf_src
, buf_dest
, got_src
, got_dest
,
555 f
->src_idx
, f
->tmp_idx
, __func__
) != 0) goto fail
;
556 } while (got_src
> 0 && got_dest
> 0);
557 if (try_fclose(&fdest
, f
->tmp_idx
, __func__
) != 0) goto fail
;
559 if (try_bgzf_close(&bgz
, f
->src_bgzf
, __func__
) != 0) goto fail
;
564 if (fdest
) fclose(fdest
);
565 if (bgz
) bgzf_close(bgz
);
569 static int test_check_EOF(char *name
, int expected
) {
570 BGZF
*bgz
= try_bgzf_open(name
, "r", __func__
);
573 eof
= bgzf_check_EOF(bgz
);
574 if (eof
!= expected
) {
575 fprintf(stderr
, "%s : Unexpected result %d from bgzf_check_EOF on %s; "
577 __func__
, eof
, name
, expected
);
582 return try_bgzf_close(&bgz
, name
, __func__
);
585 static int test_index_seek_getc(Files
*f
, const char *mode
,
586 int cache_size
, int nthreads
) {
589 size_t i
, j
, iskip
= f
->ltext
/ 10;
590 int is_uncompressed
= strchr(mode
, 'u') != NULL
;
592 bgz
= try_bgzf_open(f
->tmp_bgzf
, mode
, __func__
);
595 if (try_bgzf_index_build_init(bgz
, f
->tmp_bgzf
, __func__
) != 0) goto fail
;
597 if (nthreads
> 0 && try_bgzf_mt(bgz
, nthreads
, __func__
) != 0) goto fail
;
599 bg_put
= try_bgzf_write(bgz
, f
->text
, f
->ltext
, f
->tmp_bgzf
, __func__
);
600 if (bg_put
< 0) goto fail
;
602 if (!is_uncompressed
) {
603 if (try_bgzf_index_dump(bgz
, f
->tmp_idx
, NULL
, __func__
) != 0) {
608 if (try_bgzf_close(&bgz
, f
->tmp_bgzf
, __func__
) != 0) goto fail
;
610 bgz
= try_bgzf_open(f
->tmp_bgzf
, "r", __func__
);
613 if (nthreads
> 0 && try_bgzf_mt(bgz
, nthreads
, __func__
) != 0) goto fail
;
615 if (!is_uncompressed
) {
616 if (try_bgzf_index_load(bgz
, f
->tmp_bgzf
, idx_suffix
, __func__
) != 0) {
621 for (i
= 0; i
< f
->ltext
; i
+= iskip
) {
622 if (try_bgzf_useek(bgz
, i
, SEEK_SET
, f
->tmp_bgzf
, __func__
) != 0) {
626 for (j
= 0; j
< 16 && i
+ j
< f
->ltext
; j
++) {
627 if (try_bgzf_getc(bgz
, i
+ j
, f
->text
[i
+ j
],
628 f
->tmp_bgzf
, __func__
) < 0) goto fail
;
632 if (try_bgzf_useek(bgz
, 0, SEEK_SET
, f
->tmp_bgzf
, __func__
) != 0) {
635 for (j
= 0; j
< 70000 && j
< f
->ltext
; j
++) { // Should force a block load
636 if (try_bgzf_getc(bgz
, j
, f
->text
[j
],
637 f
->tmp_bgzf
, __func__
) < 0) goto fail
;
640 if (cache_size
> 0) {
641 size_t mid
= f
->ltext
/ 2;
642 bgzf_set_cache_size(bgz
, cache_size
);
644 for (i
= 0; i
< 10; i
++) {
645 if (try_bgzf_useek(bgz
, 0, SEEK_SET
, f
->tmp_bgzf
, __func__
) != 0) {
648 for (j
= 0; j
< 64 && j
< f
->ltext
; j
++) {
649 if (try_bgzf_getc(bgz
, j
, f
->text
[j
],
650 f
->tmp_bgzf
, __func__
) < 0) goto fail
;
653 if (try_bgzf_useek(bgz
, mid
, SEEK_SET
,
654 f
->tmp_bgzf
, __func__
) != 0) {
657 for (j
= 0; j
< 64 && j
+ mid
< f
->ltext
; j
++) {
658 if (try_bgzf_getc(bgz
, j
+ mid
, f
->text
[j
+ mid
],
659 f
->tmp_bgzf
, __func__
) < 0) goto fail
;
664 if (try_bgzf_close(&bgz
, f
->tmp_bgzf
, __func__
) != 0) goto fail
;
669 if (bgz
) bgzf_close(bgz
);
673 static int test_bgzf_getline(Files
*f
, const char *mode
, int nthreads
) {
677 kstring_t str
= { 0, 0, NULL
};
678 const char *text
= (const char *) f
->text
;
680 bgz
= try_bgzf_open(f
->tmp_bgzf
, mode
, __func__
);
683 if (nthreads
> 0 && try_bgzf_mt(bgz
, nthreads
, __func__
) != 0) goto fail
;
685 bg_put
= try_bgzf_write(bgz
, f
->text
, f
->ltext
, f
->tmp_bgzf
, __func__
);
686 if (bg_put
< 0) goto fail
;
688 if (try_bgzf_close(&bgz
, f
->tmp_bgzf
, __func__
) != 0) goto fail
;
690 bgz
= try_bgzf_open(f
->tmp_bgzf
, "r", __func__
);
693 for (pos
= 0; pos
< f
->ltext
; ) {
694 const char *end
= strchr(text
+ pos
, '\n');
695 size_t l
= end
? end
- (text
+ pos
) : f
->ltext
- pos
;
698 if ((res
= bgzf_getline(bgz
, '\n', &str
)) < 0) {
699 fprintf(stderr
, "%s : %s from bgzf_getline on %s : %s\n",
700 __func__
, res
< -1 ? "Error" : "Unexpected EOF",
701 f
->tmp_bgzf
, res
< -1 ? strerror(errno
) : "EOF");
705 if (str
.l
!= l
|| memcmp(text
+ pos
, str
.s
, l
) != 0) {
707 "%s : Unexpected data from bgzf_getline on %s\n"
710 __func__
, f
->tmp_bgzf
, (int) l
, (char *) f
->text
+ pos
,
717 if (try_bgzf_close(&bgz
, f
->tmp_bgzf
, __func__
) != 0) goto fail
;
721 if (bgz
) bgzf_close(bgz
);
725 int main(int argc
, char **argv
) {
726 Files f
= { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 };
727 int retval
= EXIT_FAILURE
;
730 fprintf(stderr
, "Usage: %s <source file>\n", argv
[0]);
734 if (setup(argv
[1], &f
) != 0) goto out
;
736 // Try reading an existing file
737 if (test_check_EOF(f
.src_bgzf
, 1) != 0) goto out
;
738 if (test_read(&f
) != 0) goto out
;
740 // Try writing some data and reading it back
741 if (test_write_read(&f
, "wu", USE_BGZF_OPEN
, 0, 0) != 0) goto out
;
742 if (test_check_EOF(f
.tmp_bgzf
, 0) != 0) goto out
;
743 if (test_write_read(&f
, "w", USE_BGZF_OPEN
, 0, 2) != 0) goto out
;
744 if (test_check_EOF(f
.tmp_bgzf
, 1) != 0) goto out
;
745 if (test_write_read(&f
, "w0", USE_BGZF_OPEN
, 0, 2) != 0) goto out
;
746 if (test_check_EOF(f
.tmp_bgzf
, 1) != 0) goto out
;
747 if (test_write_read(&f
, "w1", USE_BGZF_DOPEN
, 0, 2) != 0) goto out
;
748 if (test_check_EOF(f
.tmp_bgzf
, 1) != 0) goto out
;
749 if (test_write_read(&f
, "w9", USE_BGZF_HOPEN
, 0, 2) != 0) goto out
;
750 if (test_check_EOF(f
.tmp_bgzf
, 1) != 0) goto out
;
751 if (test_write_read(&f
, "wg", USE_BGZF_OPEN
, 0, 1) != 0) goto out
;
752 if (test_check_EOF(f
.tmp_bgzf
, 0) != 0) goto out
;
754 // Try writing and reading with threads
755 if (test_write_read(&f
, "w", USE_BGZF_OPEN
, 1, 2) != 0) goto out
;
756 if (test_check_EOF(f
.tmp_bgzf
, 1) != 0) goto out
;
757 if (test_write_read(&f
, "w", USE_BGZF_OPEN
, 2, 2) != 0) goto out
;
758 if (test_check_EOF(f
.tmp_bgzf
, 1) != 0) goto out
;
760 // Embedded EOF block
761 if (test_embed_eof(&f
, "w", 0) != 0) goto out
;
762 if (test_embed_eof(&f
, "w", 1) != 0) goto out
;
763 if (test_embed_eof(&f
, "w", 2) != 0) goto out
;
765 // Index load and dump
766 if (test_index_load_dump(&f
) != 0) goto out
;
768 // Index building on the fly and bgzf_useek
769 if (test_index_seek_getc(&f
, "w", 1000000, 0) != 0) goto out
;
771 // Index building on the fly and bgzf_useek, with threads
772 // ** Not implemented yet **
773 // if (test_index_seek_getc(&f, "w", 1000000, 1) != 0) goto out;
774 // if (test_index_seek_getc(&f, "w", 1000000, 2) != 0) goto out;
776 // bgzf_useek on an uncompressed file
777 if (test_index_seek_getc(&f
, "wu", 0, 0) != 0) goto out
;
780 if (test_bgzf_getline(&f
, "w", 0) != 0) goto out
;
781 if (test_bgzf_getline(&f
, "w", 1) != 0) goto out
;
782 if (test_bgzf_getline(&f
, "w", 2) != 0) goto out
;
784 retval
= EXIT_SUCCESS
;