Line data Source code
1 : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2 : * Copyright (C) 2026 Frediano Ziglio
3 : *
4 : * This library is free software; you can redistribute it and/or
5 : * modify it under the terms of the GNU Library General Public
6 : * License as published by the Free Software Foundation; either
7 : * version 2 of the License, or (at your option) any later version.
8 : *
9 : * This library is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : * Library General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU Library General Public
15 : * License along with this library; if not, write to the
16 : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 : * Boston, MA 02111-1307, USA.
18 : */
19 :
20 : /**
21 : * This tests execute some command using tsql and freebcp to check behaviour
22 : */
23 :
24 : #include "common.h"
25 :
26 : #if HAVE_STRING_H
27 : #include <string.h>
28 : #endif /* HAVE_STRING_H */
29 :
30 : #ifdef HAVE_UNISTD_H
31 : #include <unistd.h>
32 : #endif
33 :
34 : #include <freetds/sysdep_private.h>
35 : #include <freetds/replacements.h>
36 :
37 : static bool
38 : read_login_info(void)
39 : {
40 10 : return read_login_info_base(&common_pwd, DEFAULT_PWD_PATH) != NULL;
41 : }
42 :
43 : static void
44 20 : cleanup(void)
45 : {
46 20 : unlink(output_fn());
47 20 : unlink(input_fn());
48 20 : unlink("error");
49 20 : }
50 :
51 : static void
52 10 : freebcp(const char *object_name, const char *input_data, const char *added_options)
53 : {
54 : char cmd[2048];
55 10 : char *const end = cmd + sizeof(cmd) - 1;
56 : char *p;
57 : FILE *f;
58 :
59 : /* empty input */
60 10 : f = fopen(input_fn(), "w");
61 10 : assert(f);
62 10 : fputs(input_data, f);
63 10 : fclose(f);
64 :
65 10 : strcpy(cmd, "freebcp" EXE_SUFFIX);
66 10 : p = strchr(cmd, 0);
67 10 : p = add_string(p, end, " ");
68 10 : p = quote_arg(p, end, object_name);
69 10 : p = add_string(p, end, " in ");
70 10 : p = add_string(p, end, input_fn());
71 10 : p = add_string(p, end, " ");
72 10 : p = add_string(p, end, added_options);
73 10 : p = add_server(p, end);
74 10 : *p = 0;
75 10 : printf("Executing: %s\n", cmd);
76 10 : if (system(cmd) != 0) {
77 0 : fprintf(stderr, "Failed command\n");
78 0 : exit(1);
79 : }
80 10 : unlink(input_fn());
81 10 : }
82 :
83 : static void
84 10 : compare_error(const char *content)
85 : {
86 : char line[1024];
87 10 : FILE *const f = fopen("error", "r");
88 10 : char *const lines = strdup(content);
89 10 : char *tokens = lines;
90 10 : int num_line = 0;
91 :
92 10 : assert(f);
93 10 : assert(lines);
94 60 : for (num_line = 1; fgets(line, sizeof(line), f); ++num_line) {
95 60 : size_t len = strlen(line);
96 : char *expected;
97 :
98 : /* Skip comments */
99 60 : if (strncmp(line, "#@ ", 3) == 0)
100 20 : continue;
101 40 : if (len > 4 && strcmp(line + len - 3, " @#") == 0)
102 0 : continue;
103 :
104 : /* chomp */
105 40 : if (len > 0 && line[len - 1] == '\n')
106 40 : line[--len] = 0;
107 :
108 : /* compare with expected line */
109 40 : expected = strsep(&tokens, "\n");
110 40 : if (!expected) {
111 0 : fprintf(stderr, "%d: Unexpected lines: '%s'\n", num_line, line);
112 0 : exit(1);
113 : }
114 40 : if (strcmp(line, expected) != 0) {
115 0 : fprintf(stderr, "%d: Wrong line\n exp: '%s'\n got: '%s'\n", num_line, expected, line);
116 0 : exit(1);
117 : }
118 : }
119 10 : free(lines);
120 10 : fclose(f);
121 10 : }
122 :
123 : static void
124 10 : test_error(void)
125 : {
126 : static const char clean[] = "IF OBJECT_ID('bcp_in') IS NOT NULL DROP TABLE bcp_in\n";
127 :
128 10 : tsql(clean);
129 10 : tsql("CREATE TABLE bcp_in(num INT NOT NULL)\n");
130 10 : freebcp("bcp_in", "123\nerror\nother error\n", "-c -e error ");
131 10 : compare_error("error\n\nother error\n\n");
132 10 : tsql(clean);
133 10 : }
134 :
135 10 : TEST_MAIN()
136 : {
137 10 : cleanup();
138 10 : update_path();
139 :
140 10 : if (!read_login_info())
141 : return 1;
142 :
143 10 : test_error();
144 :
145 10 : cleanup();
146 10 : return 0;
147 : }
|