Make a status test pass against old servers.
[svn.git] / subversion / tests / libsvn_ra_local / ra-local-test.c
blobfb88ff5d1afb668de9115971682add205cab293e
1 /*
2 * ra-local-test.c : basic tests for the RA LOCAL library
4 * ====================================================================
5 * Copyright (c) 2000-2004 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
21 #include <apr_general.h>
22 #include <apr_pools.h>
24 #ifdef _MSC_VER
25 #include <direct.h>
26 #define getcwd _getcwd
27 #else
28 #include <unistd.h> /* for getcwd() */
29 #endif
31 #include "svn_string.h"
32 #include "svn_utf.h"
33 #include "svn_error.h"
34 #include "svn_delta.h"
35 #include "svn_ra.h"
36 #include "svn_client.h"
38 #include "../svn_test.h"
39 #include "../svn_test_fs.h"
40 #include "../../libsvn_ra_local/ra_local.h"
42 /*-------------------------------------------------------------------*/
44 /** Helper routines. **/
47 /* Helper function. Set URL to a "file://" url for the current directory,
48 suffixed by the forward-slash-style relative path SUFFIX, performing all
49 allocation in POOL. */
50 static svn_error_t *
51 current_directory_url(const char **url,
52 const char *suffix,
53 apr_pool_t *pool)
55 /* 8KB is a lot, but it almost guarantees that any path will fit. */
56 char curdir[8192];
57 const char *utf8_ls_curdir, *utf8_is_curdir, *unencoded_url;
59 if (! getcwd(curdir, sizeof(curdir)))
60 return svn_error_create(SVN_ERR_BASE, NULL, "getcwd() failed");
62 #ifndef AS400_UTF8
63 SVN_ERR(svn_utf_cstring_to_utf8(&utf8_ls_curdir, curdir, pool));
64 #else
65 /* Even with the UTF support in V5R4 a few functions on OS400
66 still populate string reference arguments with ebcdic,
67 including _getcwd(). */
68 SVN_ERR (svn_utf_cstring_to_utf8_ex2(&utf8_ls_curdir, curdir,
69 (const char *)0, pool));
70 #endif
71 utf8_is_curdir = svn_path_internal_style(utf8_ls_curdir, pool);
73 unencoded_url = apr_psprintf(pool, "file://%s%s%s%s",
74 (utf8_is_curdir[0] != '/') ? "/" : "",
75 utf8_is_curdir,
76 (suffix[0] && suffix[0] != '/') ? "/" : "",
77 suffix);
79 *url = svn_path_uri_encode(unencoded_url, pool);
81 return SVN_NO_ERROR;
85 static svn_error_t *
86 make_and_open_local_repos(svn_ra_session_t **session,
87 const char *repos_name,
88 const char *fs_type,
89 apr_pool_t *pool)
91 svn_repos_t *repos;
92 const char *url;
93 svn_ra_callbacks2_t *cbtable;
95 SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
97 SVN_ERR(svn_test__create_repos(&repos, repos_name, fs_type, pool));
98 SVN_ERR(svn_ra_initialize(pool));
100 SVN_ERR(current_directory_url(&url, repos_name, pool));
102 SVN_ERR(svn_ra_open2(session,
103 url,
104 cbtable,
105 NULL,
106 NULL,
107 pool));
109 return SVN_NO_ERROR;
113 /*-------------------------------------------------------------------*/
115 /** The tests **/
117 /* Open an RA session to a local repository. */
118 static svn_error_t *
119 open_ra_session(const char **msg,
120 svn_boolean_t msg_only,
121 svn_test_opts_t *opts,
122 apr_pool_t *pool)
124 svn_ra_session_t *session;
126 *msg = "open an ra session to a local repository";
128 if (msg_only)
129 return SVN_NO_ERROR;
131 SVN_ERR(make_and_open_local_repos(&session,
132 "test-repo-open", opts->fs_type, pool));
134 return SVN_NO_ERROR;
138 /* Discover the youngest revision in a repository. */
139 static svn_error_t *
140 get_youngest_rev(const char **msg,
141 svn_boolean_t msg_only,
142 svn_test_opts_t *opts,
143 apr_pool_t *pool)
145 svn_ra_session_t *session;
146 svn_revnum_t latest_rev;
148 *msg = "get the youngest revision in a repository";
150 if (msg_only)
151 return SVN_NO_ERROR;
153 SVN_ERR(make_and_open_local_repos(&session,
154 "test-repo-getrev", opts->fs_type,
155 pool));
157 /* Get the youngest revision and make sure it's 0. */
158 SVN_ERR(svn_ra_get_latest_revnum(session, &latest_rev, pool));
160 if (latest_rev != 0)
161 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
162 "youngest rev isn't 0!");
164 return SVN_NO_ERROR;
168 /* Helper function. Run svn_ra_local__split_URL with interest only in
169 the return error code */
170 static apr_status_t
171 try_split_url(const char *url, apr_pool_t *pool)
173 svn_repos_t *repos;
174 const char *repos_path, *fs_path;
175 svn_error_t *err;
176 apr_status_t apr_err;
178 err = svn_ra_local__split_URL(&repos, &repos_path, &fs_path, url, pool);
180 if (! err)
181 return SVN_NO_ERROR;
183 apr_err = err->apr_err;
184 svn_error_clear(err);
185 return apr_err;
189 static svn_error_t *
190 split_url_syntax(const char **msg,
191 svn_boolean_t msg_only,
192 svn_test_opts_t *opts,
193 apr_pool_t *pool)
195 apr_status_t apr_err;
197 *msg = "svn_ra_local__split_URL: syntax validation";
199 if (msg_only)
200 return SVN_NO_ERROR;
202 /* TEST 1: Make sure we can recognize bad URLs (this should not
203 require a filesystem) */
205 /* Use `blah' for scheme instead of `file' */
206 apr_err = try_split_url("blah:///bin/svn", pool);
207 if (apr_err != SVN_ERR_RA_ILLEGAL_URL)
208 return svn_error_create
209 (SVN_ERR_TEST_FAILED, NULL,
210 "svn_ra_local__split_URL failed to catch bad URL (scheme)");
212 /* Use only single slash after scheme */
213 apr_err = try_split_url("file:/path/to/repos", pool);
214 if (apr_err != SVN_ERR_RA_ILLEGAL_URL)
215 return svn_error_create
216 (SVN_ERR_TEST_FAILED, NULL,
217 "svn_ra_local__split_URL failed to catch bad URL (slashes)");
219 /* Use only a hostname, with no path */
220 apr_err = try_split_url("file://hostname", pool);
221 if (apr_err != SVN_ERR_RA_ILLEGAL_URL)
222 return svn_error_create
223 (SVN_ERR_TEST_FAILED, NULL,
224 "svn_ra_local__split_URL failed to catch bad URL (no path)");
226 return SVN_NO_ERROR;
229 static svn_error_t *
230 split_url_bad_host(const char **msg,
231 svn_boolean_t msg_only,
232 svn_test_opts_t *opts,
233 apr_pool_t *pool)
235 apr_status_t apr_err;
237 *msg = "svn_ra_local__split_URL: invalid host names";
239 if (msg_only)
240 return SVN_NO_ERROR;
242 /* Give a hostname other than `' or `localhost' */
243 apr_err = try_split_url("file://myhost/repos/path", pool);
244 if (apr_err != SVN_ERR_RA_ILLEGAL_URL)
245 return svn_error_create
246 (SVN_ERR_TEST_FAILED, NULL,
247 "svn_ra_local__split_URL failed to catch bad URL (hostname)");
249 return SVN_NO_ERROR;
252 static svn_error_t *
253 split_url_host(const char **msg,
254 svn_boolean_t msg_only,
255 svn_test_opts_t *opts,
256 apr_pool_t *pool)
258 apr_status_t apr_err;
260 *msg = "svn_ra_local__split_URL: valid host names";
262 if (msg_only)
263 return SVN_NO_ERROR;
265 /* Make sure we *don't* fuss about a good URL (note that this URL
266 still doesn't point to an existing versioned resource) */
267 apr_err = try_split_url("file:///repos/path", pool);
268 if (apr_err == SVN_ERR_RA_ILLEGAL_URL)
269 return svn_error_create
270 (SVN_ERR_TEST_FAILED, NULL,
271 "svn_ra_local__split_URL cried foul about a good URL (no hostname)");
273 apr_err = try_split_url("file://localhost/repos/path", pool);
274 if (apr_err == SVN_ERR_RA_ILLEGAL_URL)
275 return svn_error_create
276 (SVN_ERR_TEST_FAILED, NULL,
277 "svn_ra_local__split_URL cried foul about a good URL (localhost)");
279 return SVN_NO_ERROR;
283 /* Helper function. Creates a repository in the current working
284 directory named REPOS_PATH, then assembes a URL that points to that
285 FS, plus additional cruft (IN_REPOS_PATH) that theoretically refers to a
286 versioned resource in that repository. Finally, it runs this URL
287 through svn_ra_local__split_URL to verify that it accurately
288 separates the filesystem path and the repository path cruft.
290 If IN_REPOS_PATH is NULL, we'll split the root URL and verify our
291 parts that way (noting that that in-repos-path that results should
292 be "/"). */
293 static svn_error_t *
294 check_split_url(const char *repos_path,
295 const char *in_repos_path,
296 const char *fs_type,
297 apr_pool_t *pool)
299 svn_repos_t *repos;
300 const char *url, *root_url, *repos_part, *in_repos_part;
302 /* Create a filesystem and repository */
303 SVN_ERR(svn_test__create_repos(&repos, repos_path, fs_type, pool));
305 SVN_ERR(current_directory_url(&root_url, repos_path, pool));
306 if (in_repos_path)
307 url = apr_pstrcat(pool, root_url, in_repos_path, NULL);
308 else
309 url = root_url;
311 /* Run this URL through our splitter... */
312 SVN_ERR(svn_ra_local__split_URL(&repos, &repos_part, &in_repos_part,
313 url, pool));
315 /* We better see the REPOS_PART looking just like our ROOT_URL. And
316 we better see in the IN_REPOS_PART either exactly the same as the
317 IN_REPOS_PATH provided us, or "/" if we weren't provided an
318 IN_REPOS_PATH. */
319 if ((strcmp(repos_part, root_url) == 0)
320 && ((in_repos_path && (strcmp(in_repos_part, in_repos_path) == 0))
321 || ((! in_repos_path) && (strcmp(in_repos_part, "/") == 0))))
322 return SVN_NO_ERROR;
324 return svn_error_createf
325 (SVN_ERR_TEST_FAILED, NULL,
326 "svn_ra_local__split_URL failed to properly split the URL\n"
327 "%s\n%s\n%s\n%s",
328 repos_part, root_url, in_repos_part,
329 in_repos_path ? in_repos_path : "(null)");
333 static svn_error_t *
334 split_url_test(const char **msg,
335 svn_boolean_t msg_only,
336 svn_test_opts_t *opts,
337 apr_pool_t *pool)
339 *msg = "test svn_ra_local__split_URL correctness";
341 if (msg_only)
342 return SVN_NO_ERROR;
344 /* TEST 2: Given well-formed URLs, make sure that we can correctly
345 find where the filesystem portion of the path ends and the
346 in-repository path begins. */
347 SVN_ERR(check_split_url("test-repo-split-fs1",
348 "/trunk/foobar/quux.c",
349 opts->fs_type,
350 pool));
351 SVN_ERR(check_split_url("test-repo-split-fs2",
352 "/alpha/beta/gamma/delta/epsilon/zeta/eta/theta",
353 opts->fs_type,
354 pool));
355 SVN_ERR(check_split_url("test-repo-split-fs3",
356 NULL,
357 opts->fs_type,
358 pool));
360 return SVN_NO_ERROR;
365 /* The test table. */
367 #if defined(WIN32) || defined(__CYGWIN__)
368 #define HAS_UNC_HOST 1
369 #else
370 #define HAS_UNC_HOST 0
371 #endif
373 struct svn_test_descriptor_t test_funcs[] =
375 SVN_TEST_NULL,
376 SVN_TEST_PASS(open_ra_session),
377 SVN_TEST_PASS(get_youngest_rev),
378 SVN_TEST_PASS(split_url_syntax),
379 SVN_TEST_SKIP(split_url_bad_host, HAS_UNC_HOST),
380 SVN_TEST_PASS(split_url_host),
381 SVN_TEST_PASS(split_url_test),
382 SVN_TEST_NULL