#include "unit_test.h" #include #include "slow5_extra.h" #include "slow5_misc.h" int slow5_open_valid(void) { struct slow5_file *s5p = slow5_open("test/data/exp/aux_array/exp_lossless_end_reason.slow5", "r"); ASSERT(s5p); ASSERT(slow5_idx_load(s5p) == 0); struct slow5_rec *read = NULL; ASSERT(slow5_get("a649a4ae-c43d-492a-b6a1-a5b8b8076be4", &read, s5p) == 0); int err; uint8_t end_reason = slow5_aux_get_enum(read, "end_reason", &err); /* TODO call this slow5_read_get_enum */ ASSERT(end_reason == 4); // signal_positive ASSERT(err == 0); uint8_t n; char **end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "end_reason", &n); /* TODO this api naming is horrible */ ASSERT(end_reason_labels); ASSERT(n == 6); ASSERT(strcmp(end_reason_labels[end_reason], "signal_positive") == 0); for (int i = 0; i < n; ++ i) { ASSERT(printf("%s,", end_reason_labels[i]) == strlen(end_reason_labels[i]) + 1); } ASSERT(printf("\n") == 1); /* TODO make something like this * struct slow5_rec_aux_data end_reason_data = slow5_rec_get_aux_data(read, s5p->header->aux_meta, "end_reason"); * instead of the following * freeing end_reason data before setting */ khint_t pos = kh_get(slow5_s2a, read->aux_map, "end_reason"); struct slow5_rec_aux_data end_reason_data = kh_val(read->aux_map, pos); free(end_reason_data.data); end_reason = 0; ASSERT(slow5_rec_set(read, s5p->header->aux_meta, "end_reason", &end_reason) == 0); end_reason = slow5_aux_get_enum(read, "end_reason", &err); ASSERT(end_reason == 0); // unknown ASSERT(err == 0); ASSERT(strcmp(end_reason_labels[end_reason], "unknown") == 0); end_reason = 100; ASSERT(slow5_rec_set(read, s5p->header->aux_meta, "end_reason", &end_reason) == -4); slow5_rec_free(read); ASSERT(slow5_close(s5p) == 0); return EXIT_SUCCESS; } int slow5_get_enum_labels_invalid(void) { struct slow5_file *s5p = slow5_open("test/data/exp/aux_array/exp_lossless_end_reason.slow5", "r"); ASSERT(s5p); uint8_t n; char **end_reason_labels; /* SLOW5_ERR_ARG */ end_reason_labels = slow5_get_aux_enum_labels(NULL, "end_reason", &n); ASSERT(!end_reason_labels); ASSERT(slow5_errno = SLOW5_ERR_ARG); end_reason_labels = slow5_get_aux_enum_labels(s5p->header, NULL, &n); ASSERT(!end_reason_labels); ASSERT(slow5_errno = SLOW5_ERR_ARG); end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "end_reason", NULL); ASSERT(end_reason_labels); ASSERT(strcmp(end_reason_labels[4], "signal_positive") == 0); /* SLOW5_ERR_TYPE */ end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "test_array", &n); ASSERT(!end_reason_labels); ASSERT(slow5_errno = SLOW5_ERR_TYPE); /* SLOW5_ERR_FLD */ end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "whatisthis", &n); ASSERT(!end_reason_labels); ASSERT(slow5_errno = SLOW5_ERR_NOFLD); ASSERT(slow5_close(s5p) == 0); return EXIT_SUCCESS; } int slow5_get_enum_labels_invalid_noaux(void) { struct slow5_file *s5p = slow5_open("test/data/exp/two_rg/exp_default.slow5", "r"); ASSERT(s5p); uint8_t n; char **end_reason_labels; /* SLOW5_ERR_NOAUX */ end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "end_reason", &n); ASSERT(!end_reason_labels); ASSERT(slow5_errno = SLOW5_ERR_NOAUX); ASSERT(slow5_close(s5p) == 0); return EXIT_SUCCESS; } int slow5_get_enum_labels_invalid_noenum(void) { struct slow5_file *s5p = slow5_open("test/data/exp/aux_array/exp_lossless.slow5", "r"); ASSERT(s5p); uint8_t n; char **end_reason_labels; /* SLOW5_ERR_TYPE */ end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "end_reason", &n); ASSERT(!end_reason_labels); ASSERT(slow5_errno = SLOW5_ERR_ARG); ASSERT(slow5_close(s5p) == 0); return EXIT_SUCCESS; } int enum_parse_valid(void) { char valid_enum1[] = "enum{label}"; char *valid_enum1_labels[] = { "label" }; char valid_enum2[] = "enum{label1,label2}"; char *valid_enum2_labels[] = { "label1", "label2" }; char valid_enum3[] = "enum{x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w}"; char *valid_enum3_labels[] = {"x","y","z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w"}; char valid_enum4[] = "enum*{label}"; char *valid_enum4_labels[] = { "label" }; char valid_enum5[] = "enum*{label1,label2}"; char *valid_enum5_labels[] = { "label1", "label2" }; char valid_enum6[] = "enum*{x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w}"; char *valid_enum6_labels[] = {"x","y","z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w"}; uint8_t n; char **labels = slow5_aux_meta_enum_parse(valid_enum1, SLOW5_ENUM, &n); ASSERT(labels); ASSERT(n == SLOW5_LENGTH(valid_enum1_labels)); for (uint16_t i = 0; i < n; ++ i) { ASSERT(strcmp(labels[i], valid_enum1_labels[i]) == 0); free(labels[i]); } free(labels); labels = slow5_aux_meta_enum_parse(valid_enum2, SLOW5_ENUM, &n); ASSERT(labels); ASSERT(n == SLOW5_LENGTH(valid_enum2_labels)); for (uint16_t i = 0; i < n; ++ i) { ASSERT(strcmp(labels[i], valid_enum2_labels[i]) == 0); free(labels[i]); } free(labels); labels = slow5_aux_meta_enum_parse(valid_enum3, SLOW5_ENUM, &n); ASSERT(labels); ASSERT(n == SLOW5_LENGTH(valid_enum3_labels)); for (uint16_t i = 0; i < n; ++ i) { ASSERT(strcmp(labels[i], valid_enum3_labels[i]) == 0); free(labels[i]); } free(labels); labels = slow5_aux_meta_enum_parse(valid_enum4, SLOW5_ENUM_ARRAY, &n); ASSERT(labels); ASSERT(n == SLOW5_LENGTH(valid_enum4_labels)); for (uint16_t i = 0; i < n; ++ i) { ASSERT(strcmp(labels[i], valid_enum4_labels[i]) == 0); free(labels[i]); } free(labels); labels = slow5_aux_meta_enum_parse(valid_enum5, SLOW5_ENUM_ARRAY, &n); ASSERT(labels); ASSERT(n == SLOW5_LENGTH(valid_enum5_labels)); for (uint16_t i = 0; i < n; ++ i) { ASSERT(strcmp(labels[i], valid_enum5_labels[i]) == 0); free(labels[i]); } free(labels); labels = slow5_aux_meta_enum_parse(valid_enum6, SLOW5_ENUM_ARRAY, &n); ASSERT(labels); ASSERT(n == SLOW5_LENGTH(valid_enum6_labels)); for (uint16_t i = 0; i < n; ++ i) { ASSERT(strcmp(labels[i], valid_enum6_labels[i]) == 0); free(labels[i]); } free(labels); return EXIT_SUCCESS; } int enum_parse_invalid(void) { char invalid_enum1[] = "enum"; char invalid_enum2[] = "enum{"; char invalid_enum3[] = "enum}"; char invalid_enum4[] = "enum*"; char invalid_enum5[] = "enum{}"; char invalid_enum6[] = "enum{a,}"; char invalid_enum7[] = "enum{,}"; char invalid_enum8[] = "enum{,,,}"; char invalid_enum9[] = "enum{*}"; char invalid_enum10[] = "enum{abcd, efg}"; char invalid_enum11[] = "enum{123,}"; char invalid_enum12[] = "enum{abc,efg ,hi}"; char invalid_enum13[] = "enum{ x}"; char invalid_enum14[] = "enum{x }"; char invalid_enum15[] = "enum{x }"; char invalid_enum16[] = "enum{ x }"; char invalid_enum17[] = "enum{ x}"; char invalid_enum18[] = "enum{abc;efg;hij}"; char invalid_enum19[] = "enum(abc,efg,hij)"; char invalid_enum20[] = "enum{123}"; uint8_t n; char **labels = slow5_aux_meta_enum_parse(invalid_enum1, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum2, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum3, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum4, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum4, SLOW5_ENUM_ARRAY, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum5, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum6, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum7, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum8, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum9, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum10, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum11, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum12, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum13, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum14, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum15, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum16, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum17, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum18, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum19, SLOW5_ENUM, &n); ASSERT(!labels); labels = slow5_aux_meta_enum_parse(invalid_enum20, SLOW5_ENUM, &n); ASSERT(!labels); return EXIT_SUCCESS; } int slow5_enum_parse_duplicate(void) { char invalid_enum1[] = "enum{a,a}"; uint8_t n; char **labels = slow5_aux_meta_enum_parse(invalid_enum1, SLOW5_ENUM, &n); ASSERT(!labels); struct slow5_file *s5p = slow5_open("test/data/exp/aux_array/exp_lossless_end_reason_dup.slow5", "r"); ASSERT(!s5p); ASSERT(slow5_errno == SLOW5_ERR_HDRPARSE); return EXIT_SUCCESS; } int slow5_get_set_enum_array(void) { struct slow5_file *s5p = slow5_open("test/data/exp/aux_array/exp_lossless_end_reason.slow5", "r"); ASSERT(s5p); ASSERT(slow5_idx_load(s5p) == 0); uint8_t enum_array_valid[] = { 0, 1, 2, 3, 4, 5 }; uint8_t enum_array_invalid[] = { 0, 1, 2, 3, 4, 5, 6 }; const char *enum_labels[] = {"unk","par","mux","unblock","plus","neg"}; const char *enum_labels_bad[] = {"unk","par","mux","unblock","+","-"}; struct slow5_rec *read = NULL; ASSERT(slow5_get("a649a4ae-c43d-492a-b6a1-a5b8b8076be4", &read, s5p) == 0); ASSERT(slow5_aux_meta_add_enum(s5p->header->aux_meta, "end_reasons", SLOW5_ENUM_ARRAY, enum_labels_bad, SLOW5_LENGTH(enum_labels_bad)) == -4); ASSERT(slow5_aux_meta_add_enum(s5p->header->aux_meta, "end_reasons", SLOW5_ENUM_ARRAY, enum_labels, SLOW5_LENGTH(enum_labels)) == 0); ASSERT(slow5_rec_set_array(read, s5p->header->aux_meta, "end_reasons", enum_array_valid, SLOW5_LENGTH(enum_array_valid)) == 0); slow5_press_method_t method = {SLOW5_COMPRESS_NONE, SLOW5_COMPRESS_NONE}; slow5_hdr_print(s5p->header, SLOW5_FORMAT_ASCII, method); slow5_rec_print(read, s5p->header->aux_meta, SLOW5_FORMAT_ASCII, NULL); ASSERT(slow5_rec_set_array(read, s5p->header->aux_meta, "end_reasons", enum_array_invalid, SLOW5_LENGTH(enum_array_invalid)) == -4); slow5_rec_free(read); ASSERT(slow5_close(s5p) == 0); return EXIT_SUCCESS; } int main(void) { slow5_set_log_level(SLOW5_LOG_OFF); slow5_set_exit_condition(SLOW5_EXIT_OFF); struct command tests[] = { CMD(slow5_open_valid) CMD(slow5_get_enum_labels_invalid) CMD(slow5_get_enum_labels_invalid_noaux) CMD(slow5_get_enum_labels_invalid_noenum) CMD(enum_parse_valid) CMD(enum_parse_invalid) CMD(slow5_enum_parse_duplicate) CMD(slow5_get_set_enum_array) }; return RUN_TESTS(tests); }