1 /*  test/split/test_parse_args.c -- split test cases.
2 
3     Copyright (C) 2014-2015 Genome Research Ltd.
4 
5     Author: Martin O. Pollard <mp15@sanger.ac.uk>
6 
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:
13 
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16 
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.  */
24 
25 #include <config.h>
26 
27 #include "../../bam_split.c"
28 #include "../test.h"
29 #include <stdlib.h>
30 #include <unistd.h>
31 
setup_test_1(int * argc,char *** argv)32 void setup_test_1(int* argc, char*** argv)
33 {
34     *argc = 1;
35     *argv = (char**)calloc(sizeof(char*), 1);
36     (*argv)[0] = strdup("prog_name");
37 }
38 
check_test_1(const parsed_opts_t * opts)39 bool check_test_1(const parsed_opts_t* opts) {
40     if ( opts->merged_input_name != NULL
41         || opts->unaccounted_header_name != NULL
42         || opts->unaccounted_name != NULL
43         || strcmp(opts->output_format_string,"%*_%#.%.")
44         || opts->verbose == true )
45         return false;
46     return true;
47 }
48 
setup_test_2(int * argc,char *** argv)49 void setup_test_2(int* argc, char*** argv)
50 {
51     *argc = 2;
52     *argv = (char**)calloc(sizeof(char*), 2);
53     (*argv)[0] = strdup("prog_name");
54     (*argv)[1] = strdup("merged.bam");
55 }
56 
check_test_2(const parsed_opts_t * opts)57 bool check_test_2(const parsed_opts_t* opts) {
58     if ( opts->merged_input_name == NULL
59         || strcmp(opts->merged_input_name, "merged.bam")
60         || opts->unaccounted_header_name != NULL
61         || opts->unaccounted_name != NULL
62         || strcmp(opts->output_format_string,"%*_%#.%.")
63         || opts->verbose == true )
64         return false;
65     return true;
66 }
67 
main(int argc,char ** argv)68 int main(int argc, char**argv)
69 {
70     // test state
71     const int NUM_TESTS = 2;
72     int verbose = 0;
73     int success = 0;
74     int failure = 0;
75 
76     int getopt_char;
77     while ((getopt_char = getopt(argc, argv, "v")) != -1) {
78         switch (getopt_char) {
79             case 'v':
80                 ++verbose;
81                 break;
82             default:
83                 printf(
84                        "usage: test_parse_args [-v]\n\n"
85                        " -v verbose output\n"
86                        );
87                 break;
88         }
89     }
90 
91     // Setup stdout and stderr redirect
92     kstring_t res_stdout = { 0, 0, NULL };
93     kstring_t res_stderr = { 0, 0, NULL };
94     FILE* orig_stdout = fdopen(dup(STDOUT_FILENO), "a"); // Save stderr
95     FILE* orig_stderr = fdopen(dup(STDERR_FILENO), "a"); // Save stderr
96     char* tempfname_stdout = (optind < argc)? argv[optind] : "test_parse_args.tmp.o";
97     char* tempfname_stderr = (optind < argc)? argv[optind] : "test_parse_args.tmp.e";
98     FILE* check_stdout = NULL;
99     FILE* check_stderr = NULL;
100 
101     // Cleanup getopt
102     optind = 1;
103 
104     // setup
105     if (verbose) fprintf(orig_stdout,"BEGIN test 1\n");  // test eliminating a tag that isn't there
106     int argc_1;
107     char** argv_1;
108     setup_test_1(&argc_1, &argv_1);
109     if (verbose > 1) {
110         fprintf(orig_stdout, "argc: %d\n", argc_1);
111     }
112     if (verbose) fprintf(orig_stdout,"RUN test 1\n");
113 
114     // test
115     xfreopen(tempfname_stdout, "w", stdout); // Redirect stdout to pipe
116     xfreopen(tempfname_stderr, "w", stderr); // Redirect stderr to pipe
117     parsed_opts_t* result_1 = parse_args(argc_1, argv_1);
118     fclose(stdout);
119     fclose(stderr);
120 
121     if (verbose) fprintf(orig_stdout, "END RUN test 1\n");
122     if (verbose > 1) {
123         fprintf(orig_stdout, "argc: %d\n", argc_1);
124     }
125 
126     // check result
127     res_stdout.l = res_stderr.l = 0;
128     check_stdout = fopen(tempfname_stdout, "r");
129     check_stderr = fopen(tempfname_stderr, "r");
130     if ( !result_1
131         && kgetline(&res_stdout, (kgets_func *)fgets, check_stdout) >= 0
132         && !feof(check_stdout)
133         && res_stdout.l > 0
134         && kgetline(&res_stderr, (kgets_func *)fgets, check_stderr) < 0
135         && (feof(check_stderr) || res_stderr.l == 0)) {
136         ++success;
137     } else {
138         ++failure;
139         if (verbose) fprintf(orig_stdout, "FAIL test 1\n");
140     }
141     fclose(check_stderr);
142     fclose(check_stdout);
143 
144     // teardown
145     cleanup_opts(result_1);
146     int i = 0;
147     for (i = 0; i < argc_1; ++i) {
148         free(argv_1[i]);
149     }
150     free(argv_1);
151     if (verbose) fprintf(orig_stdout, "END test 1\n");
152 
153     // Cleanup getopt
154     optind = 1;
155 
156     if (verbose) fprintf(orig_stdout, "BEGIN test 2\n");  // test eliminating a tag that is there
157     int argc_2;
158     char** argv_2;
159     setup_test_2(&argc_2, &argv_2);
160     if (verbose > 1) {
161         fprintf(orig_stdout, "argc: %d\n", argc_2);
162     }
163     if (verbose) fprintf(orig_stdout, "RUN test 2\n");
164 
165     // test
166     xfreopen(tempfname_stdout, "w", stdout); // Redirect stdout to pipe
167     xfreopen(tempfname_stderr, "w", stderr); // Redirect stderr to pipe
168     parsed_opts_t* result_2 = parse_args(argc_2, argv_2);
169     fclose(stdout);
170     fclose(stderr);
171 
172     if (verbose) fprintf(orig_stdout, "END RUN test 2\n");
173     if (verbose > 1) {
174         fprintf(orig_stdout, "argc: %d\n", argc_2);
175     }
176 
177     // check result
178     res_stdout.l = res_stderr.l = 0;
179     check_stdout = fopen(tempfname_stdout, "r");
180     check_stderr = fopen(tempfname_stderr, "r");
181     if ( result_2
182         && check_test_2(result_2)
183         && kgetline(&res_stdout, (kgets_func *)fgets, check_stdout) < 0
184         && (feof(check_stdout) || res_stdout.l == 0)
185         && kgetline(&res_stderr, (kgets_func *)fgets, check_stderr) < 0
186         && (feof(check_stderr) || res_stderr.l == 0)) {
187         ++success;
188     } else {
189         ++failure;
190         if (verbose) fprintf(orig_stdout, "FAIL test 2\n");
191     }
192     fclose(check_stdout);
193     fclose(check_stderr);
194 
195     // teardown
196     cleanup_opts(result_2);
197     int j = 0;
198     for (j = 0; j < argc_2; ++j) {
199         free(argv_2[j]);
200     }
201     free(argv_2);
202 
203     if (verbose) fprintf(orig_stdout, "END test 2\n");
204 
205 
206     // Cleanup
207     free(res_stdout.s);
208     free(res_stderr.s);
209     remove(tempfname_stdout);
210     remove(tempfname_stderr);
211     fclose(orig_stdout);
212     if (failure > 0)
213         fprintf(orig_stderr, "%d failures %d successes\n", failure, success);
214     fclose(orig_stderr);
215 
216     return (success == NUM_TESTS)? EXIT_SUCCESS : EXIT_FAILURE;
217 }
218