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>
26 #define getcwd _getcwd
28 #include <unistd.h> /* for getcwd() */
31 #include "svn_string.h"
33 #include "svn_error.h"
34 #include "svn_delta.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. */
51 current_directory_url(const char **url
,
55 /* 8KB is a lot, but it almost guarantees that any path will fit. */
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");
63 SVN_ERR(svn_utf_cstring_to_utf8(&utf8_ls_curdir
, curdir
, pool
));
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
));
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] != '/') ? "/" : "",
76 (suffix
[0] && suffix
[0] != '/') ? "/" : "",
79 *url
= svn_path_uri_encode(unencoded_url
, pool
);
86 make_and_open_local_repos(svn_ra_session_t
**session
,
87 const char *repos_name
,
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
,
113 /*-------------------------------------------------------------------*/
117 /* Open an RA session to a local repository. */
119 open_ra_session(const char **msg
,
120 svn_boolean_t msg_only
,
121 svn_test_opts_t
*opts
,
124 svn_ra_session_t
*session
;
126 *msg
= "open an ra session to a local repository";
131 SVN_ERR(make_and_open_local_repos(&session
,
132 "test-repo-open", opts
->fs_type
, pool
));
138 /* Discover the youngest revision in a repository. */
140 get_youngest_rev(const char **msg
,
141 svn_boolean_t msg_only
,
142 svn_test_opts_t
*opts
,
145 svn_ra_session_t
*session
;
146 svn_revnum_t latest_rev
;
148 *msg
= "get the youngest revision in a repository";
153 SVN_ERR(make_and_open_local_repos(&session
,
154 "test-repo-getrev", opts
->fs_type
,
157 /* Get the youngest revision and make sure it's 0. */
158 SVN_ERR(svn_ra_get_latest_revnum(session
, &latest_rev
, pool
));
161 return svn_error_create(SVN_ERR_FS_GENERAL
, NULL
,
162 "youngest rev isn't 0!");
168 /* Helper function. Run svn_ra_local__split_URL with interest only in
169 the return error code */
171 try_split_url(const char *url
, apr_pool_t
*pool
)
174 const char *repos_path
, *fs_path
;
176 apr_status_t apr_err
;
178 err
= svn_ra_local__split_URL(&repos
, &repos_path
, &fs_path
, url
, pool
);
183 apr_err
= err
->apr_err
;
184 svn_error_clear(err
);
190 split_url_syntax(const char **msg
,
191 svn_boolean_t msg_only
,
192 svn_test_opts_t
*opts
,
195 apr_status_t apr_err
;
197 *msg
= "svn_ra_local__split_URL: syntax validation";
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)");
230 split_url_bad_host(const char **msg
,
231 svn_boolean_t msg_only
,
232 svn_test_opts_t
*opts
,
235 apr_status_t apr_err
;
237 *msg
= "svn_ra_local__split_URL: invalid host names";
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)");
253 split_url_host(const char **msg
,
254 svn_boolean_t msg_only
,
255 svn_test_opts_t
*opts
,
258 apr_status_t apr_err
;
260 *msg
= "svn_ra_local__split_URL: valid host names";
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)");
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
294 check_split_url(const char *repos_path
,
295 const char *in_repos_path
,
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
));
307 url
= apr_pstrcat(pool
, root_url
, in_repos_path
, NULL
);
311 /* Run this URL through our splitter... */
312 SVN_ERR(svn_ra_local__split_URL(&repos
, &repos_part
, &in_repos_part
,
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
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))))
324 return svn_error_createf
325 (SVN_ERR_TEST_FAILED
, NULL
,
326 "svn_ra_local__split_URL failed to properly split the URL\n"
328 repos_part
, root_url
, in_repos_part
,
329 in_repos_path
? in_repos_path
: "(null)");
334 split_url_test(const char **msg
,
335 svn_boolean_t msg_only
,
336 svn_test_opts_t
*opts
,
339 *msg
= "test svn_ra_local__split_URL correctness";
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",
351 SVN_ERR(check_split_url("test-repo-split-fs2",
352 "/alpha/beta/gamma/delta/epsilon/zeta/eta/theta",
355 SVN_ERR(check_split_url("test-repo-split-fs3",
365 /* The test table. */
367 #if defined(WIN32) || defined(__CYGWIN__)
368 #define HAS_UNC_HOST 1
370 #define HAS_UNC_HOST 0
373 struct svn_test_descriptor_t test_funcs
[] =
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
),