Mark many merge tests as skip-against-old-server.
[svn.git] / subversion / tests / libsvn_fs_base / strings-reps-test.c
blob7dc521a8d58e2cc96b446a571470384149a4293c
1 /* strings-reps-test.c --- test `strings' and `representations' interfaces
3 * ====================================================================
4 * Copyright (c) 2000-2004 CollabNet. All rights reserved.
6 * This software is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at http://subversion.tigris.org/license-1.html.
9 * If newer versions of this license are posted there, you may use a
10 * newer version instead, at your option.
12 * This software consists of voluntary contributions made by many
13 * individuals. For exact contribution history, see the revision
14 * history and logs, available at http://subversion.tigris.org/.
15 * ====================================================================
18 #include <stdlib.h>
19 #include <stdarg.h>
20 #include <string.h>
21 #include <stdio.h>
23 #include <apr.h>
25 #include "svn_error.h"
27 #include "../svn_test.h"
28 #include "../svn_test_fs.h"
29 #include "../../libsvn_fs_base/util/skel.h"
30 #include "../../libsvn_fs_base/util/fs_skels.h"
31 #include "../../libsvn_fs_base/bdb/strings-table.h"
32 #include "../../libsvn_fs_base/bdb/reps-table.h"
36 /*-----------------------------------------------------------------*/
37 /* Helper functions and batons for reps-table testing. */
38 struct rep_args
40 const char *key;
41 svn_fs_t *fs;
42 skel_t *skel;
46 static svn_error_t *
47 txn_body_write_new_rep(void *baton, trail_t *trail)
49 struct rep_args *b = (struct rep_args *) baton;
50 representation_t *rep;
51 SVN_ERR(svn_fs_base__parse_representation_skel(&rep, b->skel,
52 trail->pool));
53 return svn_fs_bdb__write_new_rep(&(b->key), b->fs, rep, trail, trail->pool);
57 static svn_error_t *
58 txn_body_write_rep(void *baton, trail_t *trail)
60 struct rep_args *b = (struct rep_args *) baton;
61 representation_t *rep;
62 SVN_ERR(svn_fs_base__parse_representation_skel(&rep, b->skel,
63 trail->pool));
64 return svn_fs_bdb__write_rep(b->fs, b->key, rep, trail, trail->pool);
68 static svn_error_t *
69 txn_body_read_rep(void *baton, trail_t *trail)
71 struct rep_args *b = (struct rep_args *) baton;
72 representation_t *rep;
73 SVN_ERR(svn_fs_bdb__read_rep(&rep, b->fs, b->key, trail, trail->pool));
74 return svn_fs_base__unparse_representation_skel(&(b->skel), rep,
75 trail->pool);
79 static svn_error_t *
80 txn_body_delete_rep(void *baton, trail_t *trail)
82 struct rep_args *b = (struct rep_args *) baton;
83 return svn_fs_bdb__delete_rep(b->fs, b->key, trail, trail->pool);
88 /* Representation Table Test functions. */
90 static svn_error_t *
91 write_new_rep(const char **msg,
92 svn_boolean_t msg_only,
93 svn_test_opts_t *opts,
94 apr_pool_t *pool)
96 struct rep_args args;
97 const char *rep = "((fulltext 0 ) a83t2Z0q)";
98 svn_fs_t *fs;
100 *msg = "write a new rep, get a new key back";
102 if (msg_only)
103 return SVN_NO_ERROR;
105 /* Create a new fs and repos */
106 SVN_ERR(svn_test__create_fs
107 (&fs, "test-repo-write-new-rep",
108 "bdb", pool));
110 /* Set up transaction baton */
111 args.fs = fs;
112 args.skel = svn_fs_base__parse_skel(rep, strlen(rep), pool);
113 args.key = NULL;
115 /* Write new rep to reps table. */
116 SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_write_new_rep, &args,
117 pool));
119 if (args.key == NULL)
120 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
121 "error writing new representation");
123 return SVN_NO_ERROR;
127 static svn_error_t *
128 write_rep(const char **msg,
129 svn_boolean_t msg_only,
130 svn_test_opts_t *opts,
131 apr_pool_t *pool)
133 struct rep_args new_args;
134 struct rep_args args;
135 const char *new_rep = "((fulltext 0 ) a83t2Z0q)";
136 const char *rep = "((fulltext 0 ) kfogel31337)";
137 svn_fs_t *fs;
139 *msg = "write a new rep, then overwrite it";
141 if (msg_only)
142 return SVN_NO_ERROR;
144 /* Create a new fs and repos */
145 SVN_ERR(svn_test__create_fs
146 (&fs, "test-repo-write-rep",
147 "bdb", pool));
149 /* Set up transaction baton */
150 new_args.fs = fs;
151 new_args.skel = svn_fs_base__parse_skel(new_rep, strlen(new_rep), pool);
152 new_args.key = NULL;
154 /* Write new rep to reps table. */
155 SVN_ERR(svn_fs_base__retry_txn(new_args.fs,
156 txn_body_write_new_rep, &new_args, pool));
158 /* Make sure we got a valid key. */
159 if (new_args.key == NULL)
160 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
161 "error writing new representation");
163 /* Set up transaction baton for re-writing reps. */
164 args.fs = new_args.fs;
165 args.skel = svn_fs_base__parse_skel(rep, strlen(rep), pool);
166 args.key = new_args.key;
168 /* Overwrite first rep in reps table. */
169 SVN_ERR(svn_fs_base__retry_txn(new_args.fs,
170 txn_body_write_rep, &args, pool));
172 return SVN_NO_ERROR;
176 static svn_error_t *
177 read_rep(const char **msg,
178 svn_boolean_t msg_only,
179 svn_test_opts_t *opts,
180 apr_pool_t *pool)
182 struct rep_args new_args;
183 struct rep_args args;
184 struct rep_args read_args;
185 svn_stringbuf_t *skel_data;
186 svn_fs_t *fs;
188 const char *rep = "((fulltext 0 ) kfogel31337)";
189 const char *new_rep_before = "((fulltext 0 ) a83t2Z0)";
191 /* This test also tests the introduction of checksums into skels that
192 didn't have them. */
194 /* Get writeable strings. */
195 char *rep_after = apr_pstrdup
196 (pool, "((fulltext 0 (md5 16 XXXXXXXXXXXXXXXX)) kfogel31337");
197 char *new_rep_after = apr_pstrdup
198 (pool, "((fulltext 0 (md5 16 XXXXXXXXXXXXXXXX)) a83t2Z0");
199 int rep_after_len = strlen(rep_after);
200 int new_rep_after_len = strlen(new_rep_after);
202 /* Replace the fake fake checksums with the real fake checksums.
203 And someday, when checksums are actually calculated, we can
204 replace the real fake checksums with real real checksums. */
206 char *p;
208 for (p = rep_after; *p; p++)
209 if (*p == 'X')
210 *p = '\0';
212 for (p = new_rep_after; *p; p++)
213 if (*p == 'X')
214 *p = '\0';
217 *msg = "write and overwrite a new rep; confirm with reads";
219 if (msg_only)
220 return SVN_NO_ERROR;
222 /* Create a new fs and repos */
223 SVN_ERR(svn_test__create_fs
224 (&fs, "test-repo-read-rep",
225 "bdb", pool));
227 /* Set up transaction baton */
228 new_args.fs = fs;
229 new_args.skel = svn_fs_base__parse_skel(new_rep_before,
230 strlen(new_rep_before), pool);
231 new_args.key = NULL;
233 /* Write new rep to reps table. */
234 SVN_ERR(svn_fs_base__retry_txn(new_args.fs,
235 txn_body_write_new_rep, &new_args, pool));
237 /* Make sure we got a valid key. */
238 if (new_args.key == NULL)
239 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
240 "error writing new representation");
242 /* Read the new rep back from the reps table. */
243 read_args.fs = new_args.fs;
244 read_args.skel = NULL;
245 read_args.key = new_args.key;
246 SVN_ERR(svn_fs_base__retry_txn(new_args.fs,
247 txn_body_read_rep, &read_args, pool));
249 /* Make sure the skel matches. */
250 if (! read_args.skel)
251 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
252 "error reading new representation");
254 skel_data = svn_fs_base__unparse_skel(read_args.skel, pool);
255 if (memcmp(skel_data->data, new_rep_after, new_rep_after_len) != 0)
256 return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
257 "representation corrupted (first check)");
259 /* Set up transaction baton for re-writing reps. */
260 args.fs = new_args.fs;
261 args.skel = svn_fs_base__parse_skel(rep, strlen(rep), pool);
262 args.key = new_args.key;
264 /* Overwrite first rep in reps table. */
265 SVN_ERR(svn_fs_base__retry_txn(new_args.fs,
266 txn_body_write_rep, &args, pool));
268 /* Read the new rep back from the reps table (using the same FS and
269 key as the first read...let's make sure this thing didn't get
270 written to the wrong place). */
271 read_args.skel = NULL;
272 SVN_ERR(svn_fs_base__retry_txn(new_args.fs,
273 txn_body_read_rep, &read_args, pool));
275 /* Make sure the skel matches. */
276 if (! read_args.skel)
277 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
278 "error reading new representation");
280 skel_data = svn_fs_base__unparse_skel(read_args.skel, pool);
281 if (memcmp(skel_data->data, rep_after, rep_after_len) != 0)
282 return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
283 "representation corrupted (second check)");
285 return SVN_NO_ERROR;
289 static svn_error_t *
290 delete_rep(const char **msg,
291 svn_boolean_t msg_only,
292 svn_test_opts_t *opts,
293 apr_pool_t *pool)
295 struct rep_args new_args;
296 struct rep_args delete_args;
297 struct rep_args read_args;
298 const char *new_rep = "((fulltext 0 ) a83t2Z0q)";
299 svn_fs_t *fs;
300 svn_error_t *err;
302 *msg = "write, then delete, a new rep; confirm deletion";
304 if (msg_only)
305 return SVN_NO_ERROR;
307 /* Create a new fs and repos */
308 SVN_ERR(svn_test__create_fs
309 (&fs, "test-repo-delete-rep",
310 "bdb", pool));
312 /* Set up transaction baton */
313 new_args.fs = fs;
314 new_args.skel = svn_fs_base__parse_skel(new_rep, strlen(new_rep), pool);
315 new_args.key = NULL;
317 /* Write new rep to reps table. */
318 SVN_ERR(svn_fs_base__retry_txn(new_args.fs,
319 txn_body_write_new_rep, &new_args, pool));
321 /* Make sure we got a valid key. */
322 if (new_args.key == NULL)
323 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
324 "error writing new representation");
326 /* Delete the rep we just wrote. */
327 delete_args.fs = new_args.fs;
328 delete_args.key = new_args.key;
329 SVN_ERR(svn_fs_base__retry_txn(new_args.fs,
330 txn_body_delete_rep, &delete_args, pool));
332 /* Try to read the new rep back from the reps table. */
333 read_args.fs = new_args.fs;
334 read_args.skel = NULL;
335 read_args.key = new_args.key;
336 err = svn_fs_base__retry_txn(new_args.fs,
337 txn_body_read_rep, &read_args, pool);
339 /* We better have an error... */
340 if ((! err) && (read_args.skel))
341 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
342 "error deleting representation");
343 svn_error_clear(err);
345 return SVN_NO_ERROR;
349 /* ------------------------------------------------------------------- */
350 /* Helper functions and batons for strings-table testing. */
352 static svn_error_t *
353 verify_expected_record(svn_fs_t *fs,
354 const char *key,
355 const char *expected_text,
356 apr_size_t expected_len,
357 trail_t *trail)
359 apr_size_t size;
360 char buf[100];
361 svn_stringbuf_t *text;
362 svn_filesize_t offset = 0;
363 svn_filesize_t string_size;
365 /* Check the string size. */
366 SVN_ERR(svn_fs_bdb__string_size(&string_size, fs, key,
367 trail, trail->pool));
368 if (string_size > SVN_MAX_OBJECT_SIZE)
369 return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
370 "record size is too large "
371 "(got %" SVN_FILESIZE_T_FMT ", "
372 "limit is %" APR_SIZE_T_FMT ")",
373 string_size, SVN_MAX_OBJECT_SIZE);
374 size = (apr_size_t) string_size;
375 if (size != expected_len)
376 return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
377 "record has unexpected size "
378 "(got %" APR_SIZE_T_FMT ", "
379 "expected %" APR_SIZE_T_FMT ")",
380 size, expected_len);
382 /* Read the string back in 100-byte chunks. */
383 text = svn_stringbuf_create("", trail->pool);
384 while (1)
386 size = sizeof(buf);
387 SVN_ERR(svn_fs_bdb__string_read(fs, key, buf, offset, &size,
388 trail, trail->pool));
389 if (size == 0)
390 break;
391 svn_stringbuf_appendbytes(text, buf, size);
392 offset += size;
395 /* Check the size and contents of the read data. */
396 if (text->len != expected_len)
397 return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
398 "record read returned unexpected size "
399 "(got %" APR_SIZE_T_FMT ", "
400 "expected %" APR_SIZE_T_FMT ")",
401 size, expected_len);
402 if (memcmp(expected_text, text->data, expected_len))
403 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
404 "record read returned unexpected data");
406 return SVN_NO_ERROR;
410 struct string_args
412 svn_fs_t *fs;
413 const char *key;
414 const char *text;
415 apr_size_t len;
419 static svn_error_t *
420 txn_body_verify_string(void *baton, trail_t *trail)
422 struct string_args *b = (struct string_args *) baton;
423 return verify_expected_record(b->fs, b->key, b->text, b->len, trail);
427 static svn_error_t *
428 txn_body_string_append(void *baton, trail_t *trail)
430 struct string_args *b = (struct string_args *) baton;
431 return svn_fs_bdb__string_append(b->fs, &(b->key), b->len,
432 b->text, trail, trail->pool);
436 static svn_error_t *
437 txn_body_string_clear(void *baton, trail_t *trail)
439 struct string_args *b = (struct string_args *) baton;
440 return svn_fs_bdb__string_clear(b->fs, b->key, trail, trail->pool);
444 static svn_error_t *
445 txn_body_string_delete(void *baton, trail_t *trail)
447 struct string_args *b = (struct string_args *) baton;
448 return svn_fs_bdb__string_delete(b->fs, b->key, trail, trail->pool);
452 static svn_error_t *
453 txn_body_string_size(void *baton, trail_t *trail)
455 struct string_args *b = (struct string_args *) baton;
456 svn_filesize_t string_size;
457 SVN_ERR(svn_fs_bdb__string_size(&string_size, b->fs, b->key,
458 trail, trail->pool));
459 if (string_size > SVN_MAX_OBJECT_SIZE)
460 return svn_error_createf
461 (SVN_ERR_FS_GENERAL, NULL,
462 "txn_body_string_size: string size is too large "
463 "(got %" SVN_FILESIZE_T_FMT ", limit is %" APR_SIZE_T_FMT ")",
464 string_size, SVN_MAX_OBJECT_SIZE);
465 b->len = (apr_size_t) string_size;
466 return SVN_NO_ERROR;
470 static svn_error_t *
471 txn_body_string_append_fail(void *baton, trail_t *trail)
473 struct string_args *b = (struct string_args *) baton;
474 SVN_ERR(svn_fs_bdb__string_append(b->fs, &(b->key), b->len,
475 b->text, trail, trail->pool));
476 return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
477 "la dee dah, la dee day...");
480 static svn_error_t *
481 txn_body_string_copy(void *baton, trail_t *trail)
483 struct string_args *b = (struct string_args *) baton;
484 return svn_fs_bdb__string_copy(b->fs, &(b->key), b->key,
485 trail, trail->pool);
489 static const char *bigstring1 =
490 " Alice opened the door and found that it led into a small\n"
491 "passage, not much larger than a rat-hole: she knelt down and\n"
492 "looked along the passage into the loveliest garden you ever saw.\n"
493 "How she longed to get out of that dark hall, and wander about\n"
494 "among those beds of bright flowers and those cool fountains, but\n"
495 "she could not even get her head though the doorway; 'and even if\n"
496 "my head would go through,' thought poor Alice, 'it would be of\n"
497 "very little use without my shoulders. Oh, how I wish\n"
498 "I could shut up like a telescope! I think I could, if I only\n"
499 "know how to begin.' For, you see, so many out-of-the-way things\n"
500 "had happened lately, that Alice had begun to think that very few\n"
501 "things indeed were really impossible.";
503 static const char *bigstring2 =
504 " There seemed to be no use in waiting by the little door, so she\n"
505 "went back to the table, half hoping she might find another key on\n"
506 "it, or at any rate a book of rules for shutting people up like\n"
507 "telescopes: this time she found a little bottle on it, ('which\n"
508 "certainly was not here before,' said Alice,) and round the neck\n"
509 "of the bottle was a paper label, with the words 'DRINK ME'\n"
510 "beautifully printed on it in large letters.";
512 static const char *bigstring3 =
513 " It was all very well to say 'Drink me,' but the wise little\n"
514 "Alice was not going to do THAT in a hurry. 'No, I'll look\n"
515 "first,' she said, 'and see whether it's marked \"poison\" or not';\n"
516 "for she had read several nice little histories about children who\n"
517 "had got burnt, and eaten up by wild beasts and other unpleasant\n"
518 "things, all because they WOULD not remember the simple rules\n"
519 "their friends had taught them: such as, that a red-hot poker\n"
520 "will burn you if you hold it too long; and that if you cut your\n"
521 "finger VERY deeply with a knife, it usually bleeds; and she had\n"
522 "never forgotten that, if you drink much from a bottle marked\n"
523 "'poison,' it is almost certain to disagree with you, sooner or\n"
524 "later.";
527 static svn_error_t *
528 test_strings(const char **msg,
529 svn_boolean_t msg_only,
530 svn_test_opts_t *opts,
531 apr_pool_t *pool)
533 struct string_args args;
534 svn_fs_t *fs;
535 svn_stringbuf_t *string;
537 *msg = "test many strings table functions together";
539 if (msg_only)
540 return SVN_NO_ERROR;
542 /* Create a new fs and repos */
543 SVN_ERR(svn_test__create_fs
544 (&fs, "test-repo-test-strings",
545 "bdb", pool));
547 /* The plan (after each step below, verify the size and contents of
548 the string):
550 1. Write a new string (string1).
551 2. Append string2 to string.
552 3. Clear string.
553 4. Append string3 to string.
554 5. Delete string (verify by size requested failure).
555 6. Write a new string (string1), appending string2, string3, and
556 string4.
559 /* 1. Write a new string (string1). */
560 args.fs = fs;
561 args.key = NULL;
562 args.text = bigstring1;
563 args.len = strlen(bigstring1);
564 SVN_ERR(svn_fs_base__retry_txn(args.fs,
565 txn_body_string_append, &args, pool));
567 /* Make sure a key was returned. */
568 if (! args.key)
569 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
570 "write of new string failed to return new key");
572 /* Verify record's size and contents. */
573 SVN_ERR(svn_fs_base__retry_txn(args.fs,
574 txn_body_verify_string, &args, pool));
576 /* Append a second string to our first one. */
577 args.text = bigstring2;
578 args.len = strlen(bigstring2);
579 SVN_ERR(svn_fs_base__retry_txn(args.fs,
580 txn_body_string_append, &args, pool));
582 /* Verify record's size and contents. */
583 string = svn_stringbuf_create(bigstring1, pool);
584 svn_stringbuf_appendcstr(string, bigstring2);
585 args.text = string->data;
586 args.len = string->len;
587 SVN_ERR(svn_fs_base__retry_txn(args.fs,
588 txn_body_verify_string, &args, pool));
590 /* Clear the record */
591 SVN_ERR(svn_fs_base__retry_txn(args.fs,
592 txn_body_string_clear, &args, pool));
594 /* Verify record's size and contents. */
595 args.text = "";
596 args.len = 0;
597 SVN_ERR(svn_fs_base__retry_txn(args.fs,
598 txn_body_verify_string, &args, pool));
600 /* Append a third string to our first one. */
601 args.text = bigstring3;
602 args.len = strlen(bigstring3);
603 SVN_ERR(svn_fs_base__retry_txn(args.fs,
604 txn_body_string_append, &args, pool));
606 /* Verify record's size and contents. */
607 SVN_ERR(svn_fs_base__retry_txn(args.fs,
608 txn_body_verify_string, &args, pool));
610 /* Delete our record...she's served us well. */
611 SVN_ERR(svn_fs_base__retry_txn(args.fs,
612 txn_body_string_delete, &args, pool));
614 /* Now, we expect a size request on this record to fail with
615 SVN_ERR_FS_NO_SUCH_STRING. */
617 svn_error_t *err = svn_fs_base__retry_txn(args.fs, txn_body_string_size,
618 &args, pool);
620 if (! err)
621 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
622 "query unexpectedly successful");
623 if (err->apr_err != SVN_ERR_FS_NO_SUCH_STRING)
624 return svn_error_create(SVN_ERR_FS_GENERAL, err,
625 "query failed with unexpected error");
626 svn_error_clear(err);
629 return SVN_NO_ERROR;
633 static svn_error_t *
634 write_null_string(const char **msg,
635 svn_boolean_t msg_only,
636 svn_test_opts_t *opts,
637 apr_pool_t *pool)
639 struct string_args args;
640 svn_fs_t *fs;
642 *msg = "write a null string";
644 if (msg_only)
645 return SVN_NO_ERROR;
647 /* Create a new fs and repos */
648 SVN_ERR(svn_test__create_fs
649 (&fs, "test-repo-test-strings",
650 "bdb", pool));
652 args.fs = fs;
653 args.key = NULL;
654 args.text = NULL;
655 args.len = 0;
656 SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_string_append, &args,
657 pool));
659 return SVN_NO_ERROR;
663 static svn_error_t *
664 abort_string(const char **msg,
665 svn_boolean_t msg_only,
666 svn_test_opts_t *opts,
667 apr_pool_t *pool)
669 struct string_args args, args2;
670 svn_fs_t *fs;
672 *msg = "write a string, then abort during an overwrite";
674 if (msg_only)
675 return SVN_NO_ERROR;
677 /* Create a new fs and repos */
678 SVN_ERR(svn_test__create_fs
679 (&fs, "test-repo-abort-string",
680 "bdb", pool));
682 /* The plan:
684 1. Write a new string (string1).
685 2. Overwrite string1 with string2, but then ABORT the transaction.
686 3. Read string to make sure it is still string1.
689 /* 1. Write a new string (string1). */
690 args.fs = fs;
691 args.key = NULL;
692 args.text = bigstring1;
693 args.len = strlen(bigstring1);
694 SVN_ERR(svn_fs_base__retry_txn(args.fs,
695 txn_body_string_append, &args, pool));
697 /* Make sure a key was returned. */
698 if (! args.key)
699 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
700 "write of new string failed to return new key");
702 /* Verify record's size and contents. */
703 SVN_ERR(svn_fs_base__retry_txn(args.fs,
704 txn_body_verify_string, &args, pool));
706 /* Append a second string to our first one. */
707 args2.fs = fs;
708 args2.key = args.key;
709 args2.text = bigstring2;
710 args2.len = strlen(bigstring2);
712 svn_error_t *err;
714 /* This function is *supposed* to fail with SVN_ERR_TEST_FAILED */
715 err = svn_fs_base__retry_txn(args.fs, txn_body_string_append_fail,
716 &args2, pool);
717 if ((! err) || (err->apr_err != SVN_ERR_TEST_FAILED))
718 return svn_error_create(SVN_ERR_TEST_FAILED, err,
719 "failed to intentionally abort a trail");
720 svn_error_clear(err);
723 /* Verify that record's size and contents are still that of string1 */
724 SVN_ERR(svn_fs_base__retry_txn(args.fs,
725 txn_body_verify_string, &args, pool));
727 return SVN_NO_ERROR;
730 static svn_error_t *
731 copy_string(const char **msg,
732 svn_boolean_t msg_only,
733 svn_test_opts_t *opts,
734 apr_pool_t *pool)
736 struct string_args args;
737 svn_fs_t *fs;
738 const char *old_key;
740 *msg = "create and copy a string";
742 if (msg_only)
743 return SVN_NO_ERROR;
745 /* Create a new fs and repos */
746 SVN_ERR(svn_test__create_fs
747 (&fs, "test-repo-copy-string",
748 "bdb", pool));
750 /* Write a new string (string1). */
751 args.fs = fs;
752 args.key = NULL;
753 args.text = bigstring1;
754 args.len = strlen(bigstring1);
755 SVN_ERR(svn_fs_base__retry_txn(args.fs,
756 txn_body_string_append, &args, pool));
758 /* Make sure a key was returned. */
759 if (! (old_key = args.key))
760 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
761 "write of new string failed to return new key");
763 /* Now copy that string into a new location. */
764 SVN_ERR(svn_fs_base__retry_txn(args.fs,
765 txn_body_string_copy, &args, pool));
767 /* Make sure a different key was returned. */
768 if ((! args.key) || (! strcmp(old_key, args.key)))
769 return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
770 "copy of string failed to return new key");
772 /* Verify record's size and contents. */
773 SVN_ERR(svn_fs_base__retry_txn(args.fs,
774 txn_body_verify_string, &args, pool));
776 return SVN_NO_ERROR;
781 /* The test table. */
783 struct svn_test_descriptor_t test_funcs[] =
785 SVN_TEST_NULL,
786 SVN_TEST_PASS(write_new_rep),
787 SVN_TEST_PASS(write_rep),
788 SVN_TEST_PASS(read_rep),
789 SVN_TEST_PASS(delete_rep),
790 SVN_TEST_PASS(test_strings),
791 SVN_TEST_PASS(write_null_string),
792 SVN_TEST_PASS(abort_string),
793 SVN_TEST_PASS(copy_string),
794 SVN_TEST_NULL