~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/tests/libsvn_client/mtcc-test.c

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2015-08-07 21:32:47 UTC
  • mfrom: (0.2.15) (4.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20150807213247-ozyewtmgsr6tkewl
Tags: 1.9.0-1
* Upload to unstable
* New upstream release.
  + Security fixes
    - CVE-2015-3184: Mixed anonymous/authenticated path-based authz with
      httpd 2.4
    - CVE-2015-3187: svn_repos_trace_node_locations() reveals paths hidden
      by authz
* Add >= 2.7 requirement for python-all-dev Build-Depends, needed to run
  tests.
* Remove Build-Conflicts against ruby-test-unit.  (Closes: #791844)
* Remove patches/apache_module_dependency in favor of expressing the
  dependencies in authz_svn.load/dav_svn.load.
* Build-Depend on apache2-dev (>= 2.4.16) to ensure ap_some_authn_required()
  is available when building mod_authz_svn and Depend on apache2-bin (>=
  2.4.16) for runtime support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Regression tests for mtcc code in the libsvn_client library.
 
3
 *
 
4
 * ====================================================================
 
5
 *    Licensed to the Apache Software Foundation (ASF) under one
 
6
 *    or more contributor license agreements.  See the NOTICE file
 
7
 *    distributed with this work for additional information
 
8
 *    regarding copyright ownership.  The ASF licenses this file
 
9
 *    to you under the Apache License, Version 2.0 (the
 
10
 *    "License"); you may not use this file except in compliance
 
11
 *    with the License.  You may obtain a copy of the License at
 
12
 *
 
13
 *      http://www.apache.org/licenses/LICENSE-2.0
 
14
 *
 
15
 *    Unless required by applicable law or agreed to in writing,
 
16
 *    software distributed under the License is distributed on an
 
17
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
18
 *    KIND, either express or implied.  See the License for the
 
19
 *    specific language governing permissions and limitations
 
20
 *    under the License.
 
21
 * ====================================================================
 
22
 */
 
23
 
 
24
#include "svn_pools.h"
 
25
#include "svn_props.h"
 
26
#include "svn_client.h"
 
27
#include "private/svn_client_mtcc.h"
 
28
 
 
29
#include "../svn_test.h"
 
30
#include "../svn_test_fs.h"
 
31
 
 
32
/* Baton for verify_commit_callback*/
 
33
struct verify_commit_baton
 
34
{
 
35
  const svn_commit_info_t *commit_info;
 
36
  apr_pool_t *result_pool;
 
37
};
 
38
 
 
39
/* Commit result collector for verify_mtcc_commit */
 
40
static svn_error_t *
 
41
verify_commit_callback(const svn_commit_info_t *commit_info,
 
42
                       void *baton,
 
43
                       apr_pool_t *pool)
 
44
{
 
45
  struct verify_commit_baton *vcb = baton;
 
46
 
 
47
  vcb->commit_info = svn_commit_info_dup(commit_info, vcb->result_pool);
 
48
  return SVN_NO_ERROR;
 
49
}
 
50
 
 
51
/* Create a stream from a c string */
 
52
static svn_stream_t *
 
53
cstr_stream(const char *data, apr_pool_t *result_pool)
 
54
{
 
55
  return svn_stream_from_string(svn_string_create(data, result_pool),
 
56
                                result_pool);
 
57
}
 
58
 
 
59
static svn_error_t *
 
60
verify_mtcc_commit(svn_client__mtcc_t *mtcc,
 
61
                   svn_revnum_t expected_rev,
 
62
                   apr_pool_t *pool)
 
63
{
 
64
  struct verify_commit_baton vcb;
 
65
  vcb.commit_info = NULL;
 
66
  vcb.result_pool = pool;
 
67
 
 
68
  SVN_ERR(svn_client__mtcc_commit(NULL, verify_commit_callback, &vcb, mtcc, pool));
 
69
 
 
70
  SVN_TEST_ASSERT(vcb.commit_info != NULL);
 
71
  SVN_TEST_ASSERT(vcb.commit_info->revision == expected_rev);
 
72
 
 
73
  return SVN_NO_ERROR;
 
74
}
 
75
 
 
76
 
 
77
/* Constructs a greek tree as revision 1 in the repository at repos_url */
 
78
static svn_error_t *
 
79
make_greek_tree(const char *repos_url,
 
80
                apr_pool_t *scratch_pool)
 
81
{
 
82
  svn_client__mtcc_t *mtcc;
 
83
  svn_client_ctx_t *ctx;
 
84
  apr_pool_t *subpool;
 
85
  int i;
 
86
 
 
87
  subpool = svn_pool_create(scratch_pool);
 
88
 
 
89
  SVN_ERR(svn_client_create_context2(&ctx, NULL, subpool));
 
90
  SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, subpool));
 
91
 
 
92
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 0, ctx, subpool, subpool));
 
93
 
 
94
  for (i = 0; svn_test__greek_tree_nodes[i].path; i++)
 
95
    {
 
96
      if (svn_test__greek_tree_nodes[i].contents)
 
97
        {
 
98
          SVN_ERR(svn_client__mtcc_add_add_file(
 
99
                                svn_test__greek_tree_nodes[i].path,
 
100
                                cstr_stream(
 
101
                                        svn_test__greek_tree_nodes[i].contents,
 
102
                                        subpool),
 
103
                                NULL /* src_checksum */,
 
104
                                mtcc, subpool));
 
105
        }
 
106
      else
 
107
        {
 
108
          SVN_ERR(svn_client__mtcc_add_mkdir(
 
109
                                svn_test__greek_tree_nodes[i].path,
 
110
                                mtcc, subpool));
 
111
        }
 
112
    }
 
113
 
 
114
  SVN_ERR(verify_mtcc_commit(mtcc, 1, subpool));
 
115
 
 
116
  svn_pool_clear(subpool);
 
117
  return SVN_NO_ERROR;
 
118
}
 
119
 
 
120
static svn_error_t *
 
121
test_mkdir(const svn_test_opts_t *opts,
 
122
           apr_pool_t *pool)
 
123
{
 
124
  svn_client__mtcc_t *mtcc;
 
125
  svn_client_ctx_t *ctx;
 
126
  const char *repos_url;
 
127
 
 
128
  SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-mkdir",
 
129
                                  opts, pool, pool));
 
130
 
 
131
  SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
 
132
  SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool));
 
133
 
 
134
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 0, ctx, pool, pool));
 
135
 
 
136
  SVN_ERR(svn_client__mtcc_add_mkdir("branches", mtcc, pool));
 
137
  SVN_ERR(svn_client__mtcc_add_mkdir("trunk", mtcc, pool));
 
138
  SVN_ERR(svn_client__mtcc_add_mkdir("branches/1.x", mtcc, pool));
 
139
  SVN_ERR(svn_client__mtcc_add_mkdir("tags", mtcc, pool));
 
140
  SVN_ERR(svn_client__mtcc_add_mkdir("tags/1.0", mtcc, pool));
 
141
  SVN_ERR(svn_client__mtcc_add_mkdir("tags/1.1", mtcc, pool));
 
142
 
 
143
  SVN_ERR(verify_mtcc_commit(mtcc, 1, pool));
 
144
 
 
145
  return SVN_NO_ERROR;
 
146
}
 
147
 
 
148
static svn_error_t *
 
149
test_mkgreek(const svn_test_opts_t *opts,
 
150
             apr_pool_t *pool)
 
151
{
 
152
  svn_client__mtcc_t *mtcc;
 
153
  svn_client_ctx_t *ctx;
 
154
  const char *repos_url;
 
155
 
 
156
  SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-mkgreek",
 
157
                                  opts, pool, pool));
 
158
 
 
159
  SVN_ERR(make_greek_tree(repos_url, pool));
 
160
 
 
161
  SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
 
162
  SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool));
 
163
 
 
164
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
 
165
 
 
166
  SVN_ERR(svn_client__mtcc_add_copy("A", 1, "greek_A", mtcc, pool));
 
167
 
 
168
  SVN_ERR(verify_mtcc_commit(mtcc, 2, pool));
 
169
 
 
170
  return SVN_NO_ERROR;
 
171
}
 
172
 
 
173
static svn_error_t *
 
174
test_swap(const svn_test_opts_t *opts,
 
175
          apr_pool_t *pool)
 
176
{
 
177
  svn_client__mtcc_t *mtcc;
 
178
  svn_client_ctx_t *ctx;
 
179
  const char *repos_url;
 
180
 
 
181
  SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-swap",
 
182
                                  opts, pool, pool));
 
183
 
 
184
  SVN_ERR(make_greek_tree(repos_url, pool));
 
185
 
 
186
  SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
 
187
  SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool));
 
188
 
 
189
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
 
190
 
 
191
  SVN_ERR(svn_client__mtcc_add_move("A/B", "B", mtcc, pool));
 
192
  SVN_ERR(svn_client__mtcc_add_move("A/D", "A/B", mtcc, pool));
 
193
  SVN_ERR(svn_client__mtcc_add_copy("A/B", 1, "A/D", mtcc, pool));
 
194
 
 
195
  SVN_ERR(verify_mtcc_commit(mtcc, 2, pool));
 
196
 
 
197
  return SVN_NO_ERROR;
 
198
}
 
199
 
 
200
static svn_error_t *
 
201
test_propset(const svn_test_opts_t *opts,
 
202
             apr_pool_t *pool)
 
203
{
 
204
  svn_client__mtcc_t *mtcc;
 
205
  svn_client_ctx_t *ctx;
 
206
  const char *repos_url;
 
207
 
 
208
  SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-propset",
 
209
                                  opts, pool, pool));
 
210
 
 
211
  SVN_ERR(make_greek_tree(repos_url, pool));
 
212
 
 
213
  SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
 
214
  SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool));
 
215
 
 
216
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
 
217
 
 
218
  SVN_ERR(svn_client__mtcc_add_propset("iota", "key",
 
219
                                       svn_string_create("val", pool), FALSE,
 
220
                                       mtcc, pool));
 
221
  SVN_ERR(svn_client__mtcc_add_propset("A", "A-key",
 
222
                                       svn_string_create("val-A", pool), FALSE,
 
223
                                       mtcc, pool));
 
224
  SVN_ERR(svn_client__mtcc_add_propset("A/B", "B-key",
 
225
                                       svn_string_create("val-B", pool), FALSE,
 
226
                                       mtcc, pool));
 
227
 
 
228
  /* The repository ignores propdeletes of properties that aren't there,
 
229
     so this just works */
 
230
  SVN_ERR(svn_client__mtcc_add_propset("A/D", "D-key", NULL, FALSE,
 
231
                                       mtcc, pool));
 
232
 
 
233
  SVN_ERR(verify_mtcc_commit(mtcc, 2, pool));
 
234
 
 
235
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 2, ctx, pool, pool));
 
236
  SVN_TEST_ASSERT_ERROR(
 
237
      svn_client__mtcc_add_propset("A", SVN_PROP_MIME_TYPE,
 
238
                                   svn_string_create("text/plain", pool),
 
239
                                   FALSE, mtcc, pool),
 
240
      SVN_ERR_ILLEGAL_TARGET);
 
241
 
 
242
  SVN_TEST_ASSERT_ERROR(
 
243
      svn_client__mtcc_add_propset("iota", SVN_PROP_IGNORE,
 
244
                                   svn_string_create("iota", pool),
 
245
                                   FALSE, mtcc, pool),
 
246
      SVN_ERR_ILLEGAL_TARGET);
 
247
 
 
248
  SVN_ERR(svn_client__mtcc_add_propset("iota", SVN_PROP_EOL_STYLE,
 
249
                                       svn_string_create("LF", pool),
 
250
                                       FALSE, mtcc, pool));
 
251
 
 
252
  SVN_ERR(svn_client__mtcc_add_add_file("ok", cstr_stream("line\nline\n", pool),
 
253
                                        NULL, mtcc, pool));
 
254
  SVN_ERR(svn_client__mtcc_add_add_file("bad", cstr_stream("line\nno\r\n", pool),
 
255
                                        NULL, mtcc, pool));
 
256
 
 
257
  SVN_ERR(svn_client__mtcc_add_propset("ok", SVN_PROP_EOL_STYLE,
 
258
                                       svn_string_create("LF", pool),
 
259
                                       FALSE, mtcc, pool));
 
260
 
 
261
  SVN_TEST_ASSERT_ERROR(
 
262
          svn_client__mtcc_add_propset("bad", SVN_PROP_EOL_STYLE,
 
263
                                       svn_string_create("LF", pool),
 
264
                                       FALSE, mtcc, pool),
 
265
          SVN_ERR_ILLEGAL_TARGET);
 
266
 
 
267
  SVN_ERR(verify_mtcc_commit(mtcc, 3, pool));
 
268
 
 
269
  return SVN_NO_ERROR;
 
270
}
 
271
 
 
272
static svn_error_t *
 
273
test_update_files(const svn_test_opts_t *opts,
 
274
             apr_pool_t *pool)
 
275
{
 
276
  svn_client__mtcc_t *mtcc;
 
277
  svn_client_ctx_t *ctx;
 
278
  const char *repos_url;
 
279
 
 
280
  SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-update-files",
 
281
                                  opts, pool, pool));
 
282
  SVN_ERR(make_greek_tree(repos_url, pool));
 
283
 
 
284
  SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
 
285
  SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool));
 
286
 
 
287
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
 
288
 
 
289
  /* Update iota with knowledge of the old data */
 
290
  SVN_ERR(svn_client__mtcc_add_update_file(svn_test__greek_tree_nodes[0].path,
 
291
                                           cstr_stream("new-iota", pool),
 
292
                                           NULL,
 
293
                                           cstr_stream(
 
294
                                             svn_test__greek_tree_nodes[0]
 
295
                                                         .contents,
 
296
                                             pool),
 
297
                                           NULL,
 
298
                                           mtcc, pool));
 
299
 
 
300
  SVN_ERR(svn_client__mtcc_add_update_file("A/mu",
 
301
                                           cstr_stream("new-MU", pool),
 
302
                                           NULL,
 
303
                                           NULL, NULL,
 
304
                                           mtcc, pool));
 
305
 
 
306
  /* Set a property on the same node */
 
307
  SVN_ERR(svn_client__mtcc_add_propset("A/mu", "mu-key",
 
308
                                       svn_string_create("mu-A", pool), FALSE,
 
309
                                       mtcc, pool));
 
310
  /* And some other node */
 
311
  SVN_ERR(svn_client__mtcc_add_propset("A/B", "B-key",
 
312
                                       svn_string_create("val-B", pool), FALSE,
 
313
                                       mtcc, pool));
 
314
 
 
315
  SVN_ERR(verify_mtcc_commit(mtcc, 2, pool));
 
316
  return SVN_NO_ERROR;
 
317
}
 
318
 
 
319
static svn_error_t *
 
320
test_overwrite(const svn_test_opts_t *opts,
 
321
               apr_pool_t *pool)
 
322
{
 
323
  svn_client__mtcc_t *mtcc;
 
324
  svn_client_ctx_t *ctx;
 
325
  const char *repos_url;
 
326
 
 
327
  SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-overwrite",
 
328
                                  opts, pool, pool));
 
329
 
 
330
  SVN_ERR(make_greek_tree(repos_url, pool));
 
331
 
 
332
  SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
 
333
  SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool));
 
334
 
 
335
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
 
336
 
 
337
  SVN_ERR(svn_client__mtcc_add_copy("A", 1, "AA", mtcc, pool));
 
338
 
 
339
  SVN_TEST_ASSERT_ERROR(svn_client__mtcc_add_mkdir("AA/B", mtcc, pool),
 
340
                        SVN_ERR_FS_ALREADY_EXISTS);
 
341
 
 
342
  SVN_TEST_ASSERT_ERROR(svn_client__mtcc_add_mkdir("AA/D/H/chi", mtcc, pool),
 
343
                        SVN_ERR_FS_ALREADY_EXISTS);
 
344
 
 
345
  SVN_ERR(svn_client__mtcc_add_mkdir("AA/BB", mtcc, pool));
 
346
 
 
347
  SVN_ERR(verify_mtcc_commit(mtcc, 2, pool));
 
348
  return SVN_NO_ERROR;
 
349
}
 
350
 
 
351
static svn_error_t *
 
352
test_anchoring(const svn_test_opts_t *opts,
 
353
               apr_pool_t *pool)
 
354
{
 
355
  svn_client__mtcc_t *mtcc;
 
356
  svn_client_ctx_t *ctx;
 
357
  const char *repos_url;
 
358
 
 
359
  SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-anchoring",
 
360
                                  opts, pool, pool));
 
361
 
 
362
  SVN_ERR(make_greek_tree(repos_url, pool));
 
363
 
 
364
  SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
 
365
  SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool));
 
366
 
 
367
  /* Update a file as root operation */
 
368
  SVN_ERR(svn_client__mtcc_create(&mtcc,
 
369
                                  svn_path_url_add_component2(repos_url, "iota",
 
370
                                                              pool),
 
371
                                  1, ctx, pool, pool));
 
372
  SVN_ERR(svn_client__mtcc_add_update_file("",
 
373
                                           cstr_stream("new-iota", pool),
 
374
                                           NULL, NULL, NULL,
 
375
                                           mtcc, pool));
 
376
  SVN_ERR(svn_client__mtcc_add_propset("", "key",
 
377
                                       svn_string_create("value", pool),
 
378
                                       FALSE, mtcc, pool));
 
379
 
 
380
  SVN_ERR(verify_mtcc_commit(mtcc, 2, pool));
 
381
 
 
382
  /* Add a directory as root operation */
 
383
  SVN_ERR(svn_client__mtcc_create(&mtcc,
 
384
                                  svn_path_url_add_component2(repos_url, "BB",
 
385
                                                              pool),
 
386
                                  2, ctx, pool, pool));
 
387
  SVN_ERR(svn_client__mtcc_add_mkdir("", mtcc, pool));
 
388
  SVN_ERR(verify_mtcc_commit(mtcc, 3, pool));
 
389
 
 
390
  /* Add a file as root operation */
 
391
  SVN_ERR(svn_client__mtcc_create(&mtcc,
 
392
                                  svn_path_url_add_component2(repos_url, "new",
 
393
                                                              pool),
 
394
                                  3, ctx, pool, pool));
 
395
  SVN_ERR(svn_client__mtcc_add_add_file("", cstr_stream("new", pool), NULL,
 
396
                                        mtcc, pool));
 
397
  SVN_ERR(verify_mtcc_commit(mtcc, 4, pool));
 
398
 
 
399
  /* Delete as root operation */
 
400
  SVN_ERR(svn_client__mtcc_create(&mtcc,
 
401
                                  svn_path_url_add_component2(repos_url, "new",
 
402
                                                              pool),
 
403
                                  4, ctx, pool, pool));
 
404
  SVN_ERR(svn_client__mtcc_add_delete("", mtcc, pool));
 
405
  SVN_ERR(verify_mtcc_commit(mtcc, 5, pool));
 
406
 
 
407
  /* Propset file as root operation */
 
408
  SVN_ERR(svn_client__mtcc_create(&mtcc,
 
409
                                  svn_path_url_add_component2(repos_url, "A/mu",
 
410
                                                              pool),
 
411
                                  5, ctx, pool, pool));
 
412
  SVN_ERR(svn_client__mtcc_add_propset("", "key",
 
413
                                       svn_string_create("val", pool),
 
414
                                       FALSE, mtcc, pool));
 
415
  SVN_ERR(verify_mtcc_commit(mtcc, 6, pool));
 
416
 
 
417
  /* Propset dir as root operation */
 
418
  SVN_ERR(svn_client__mtcc_create(&mtcc,
 
419
                                  svn_path_url_add_component2(repos_url, "A",
 
420
                                                              pool),
 
421
                                  6, ctx, pool, pool));
 
422
  SVN_ERR(svn_client__mtcc_add_propset("", "key",
 
423
                                       svn_string_create("val", pool),
 
424
                                       FALSE, mtcc, pool));
 
425
  SVN_ERR(verify_mtcc_commit(mtcc, 7, pool));
 
426
 
 
427
  /* Propset reposroot as root operation */
 
428
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 7, ctx, pool, pool));
 
429
  SVN_ERR(svn_client__mtcc_add_propset("", "key",
 
430
                                       svn_string_create("val", pool),
 
431
                                       FALSE, mtcc, pool));
 
432
  SVN_ERR(verify_mtcc_commit(mtcc, 8, pool));
 
433
 
 
434
  return SVN_NO_ERROR;
 
435
}
 
436
 
 
437
static svn_error_t *
 
438
test_replace_tree(const svn_test_opts_t *opts,
 
439
                  apr_pool_t *pool)
 
440
{
 
441
  svn_client__mtcc_t *mtcc;
 
442
  svn_client_ctx_t *ctx;
 
443
  const char *repos_url;
 
444
 
 
445
  SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-replace_tree",
 
446
                                  opts, pool, pool));
 
447
 
 
448
  SVN_ERR(make_greek_tree(repos_url, pool));
 
449
 
 
450
  SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
 
451
  SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool));
 
452
 
 
453
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
 
454
 
 
455
  SVN_ERR(svn_client__mtcc_add_delete("A", mtcc, pool));
 
456
  SVN_ERR(svn_client__mtcc_add_delete("iota", mtcc, pool));
 
457
  SVN_ERR(svn_client__mtcc_add_mkdir("A", mtcc, pool));
 
458
  SVN_ERR(svn_client__mtcc_add_mkdir("A/B", mtcc, pool));
 
459
  SVN_ERR(svn_client__mtcc_add_mkdir("A/B/C", mtcc, pool));
 
460
  SVN_ERR(svn_client__mtcc_add_mkdir("M", mtcc, pool));
 
461
  SVN_ERR(svn_client__mtcc_add_mkdir("M/N", mtcc, pool));
 
462
  SVN_ERR(svn_client__mtcc_add_mkdir("M/N/O", mtcc, pool));
 
463
 
 
464
  SVN_ERR(verify_mtcc_commit(mtcc, 2, pool));
 
465
 
 
466
  return SVN_NO_ERROR;
 
467
}
 
468
 
 
469
/* Baton for handle_rev */
 
470
struct handle_rev_baton
 
471
{
 
472
  svn_revnum_t last;
 
473
  svn_boolean_t up;
 
474
  svn_boolean_t first;
 
475
 
 
476
  /* Per revision handler */
 
477
  svn_txdelta_window_handler_t inner_handler;
 
478
  void *inner_baton;
 
479
 
 
480
  /* Swapped between revisions to reconstruct data */
 
481
  svn_stringbuf_t *cur;
 
482
  svn_stringbuf_t *prev;
 
483
 
 
484
  /* Pool for some test stuff */
 
485
  apr_pool_t *pool;
 
486
};
 
487
 
 
488
/* Implement svn_txdelta_window_handler_t */
 
489
static svn_error_t *
 
490
handle_rev_delta(svn_txdelta_window_t *window,
 
491
                 void * baton)
 
492
{
 
493
  struct handle_rev_baton *hrb = baton;
 
494
 
 
495
  SVN_ERR(hrb->inner_handler(window, hrb->inner_baton));
 
496
 
 
497
  if (!window)
 
498
    {
 
499
      int expected_rev;
 
500
      const char *expected;
 
501
 
 
502
      /* Some revisions don't update the revision body */
 
503
      switch (hrb->last)
 
504
        {
 
505
          case 5:
 
506
            expected_rev = 4;
 
507
            break;
 
508
          case 7: /* Not reported */
 
509
          case 8:
 
510
            expected_rev = 6;
 
511
            break;
 
512
          default:
 
513
            expected_rev = (int)hrb->last;
 
514
        }
 
515
 
 
516
      expected = apr_psprintf(hrb->pool, "revision-%d", expected_rev);
 
517
 
 
518
      SVN_TEST_STRING_ASSERT(hrb->cur->data, expected);
 
519
    }
 
520
 
 
521
  return SVN_NO_ERROR;
 
522
}
 
523
 
 
524
/* Helper for test_file_revs_both_ways */
 
525
static svn_error_t *
 
526
handle_rev(void *baton,
 
527
           const char *path,
 
528
           svn_revnum_t rev,
 
529
           apr_hash_t *rev_props,
 
530
           svn_boolean_t result_of_merge,
 
531
           svn_txdelta_window_handler_t *delta_handler,
 
532
           void **delta_baton,
 
533
           apr_array_header_t *prop_diffs,
 
534
           apr_pool_t *pool)
 
535
{
 
536
  struct handle_rev_baton *hrb = baton;
 
537
  svn_revnum_t expected_rev = hrb->up ? (hrb->last + 1) : (hrb->last - 1);
 
538
 
 
539
  if (expected_rev == 7)
 
540
    expected_rev = hrb->up ? 8 : 6;
 
541
 
 
542
  SVN_TEST_ASSERT(rev == expected_rev);
 
543
  SVN_TEST_ASSERT(apr_hash_count(rev_props) >= 3);
 
544
  SVN_TEST_STRING_ASSERT(path, (rev < 5) ? "/iota" : "/mu");
 
545
 
 
546
  if (!hrb->first
 
547
      && (rev == (hrb->up ? 5 : 4) || rev == (hrb->up ? 8 : 6)))
 
548
    SVN_TEST_ASSERT(delta_handler == NULL);
 
549
  else
 
550
    SVN_TEST_ASSERT(delta_handler != NULL);
 
551
 
 
552
  if (delta_handler)
 
553
    {
 
554
      svn_stringbuf_t *tmp;
 
555
 
 
556
      *delta_handler = handle_rev_delta;
 
557
      *delta_baton = hrb;
 
558
 
 
559
      /* Swap string buffers, to use previous as original */
 
560
      tmp = hrb->prev;
 
561
      hrb->prev = hrb->cur;
 
562
      hrb->cur = tmp;
 
563
 
 
564
      svn_stringbuf_setempty(hrb->cur);
 
565
 
 
566
      svn_txdelta_apply(svn_stream_from_stringbuf(hrb->prev, pool),
 
567
                        svn_stream_from_stringbuf(hrb->cur, pool),
 
568
                        NULL, NULL, pool,
 
569
                        &hrb->inner_handler,
 
570
                        &hrb->inner_baton);
 
571
    }
 
572
 
 
573
  hrb->last = rev;
 
574
  hrb->first = FALSE;
 
575
 
 
576
  return SVN_NO_ERROR;
 
577
}
 
578
 
 
579
static svn_error_t *
 
580
test_file_revs_both_ways(const svn_test_opts_t *opts,
 
581
                         apr_pool_t *pool)
 
582
{
 
583
  svn_client__mtcc_t *mtcc;
 
584
  svn_client_ctx_t *ctx;
 
585
  apr_pool_t *subpool = svn_pool_create(pool);
 
586
  const char *repos_url;
 
587
  svn_ra_session_t *ra;
 
588
  struct handle_rev_baton hrb;
 
589
 
 
590
  SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-file-revs",
 
591
                                  opts, pool, subpool));
 
592
 
 
593
  SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
 
594
  SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool));
 
595
 
 
596
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 0, ctx, subpool, subpool));
 
597
  SVN_ERR(svn_client__mtcc_add_add_file("iota",
 
598
                                        cstr_stream("revision-1", subpool),
 
599
                                        NULL /* src_checksum */,
 
600
                                        mtcc, subpool));
 
601
  SVN_ERR(verify_mtcc_commit(mtcc, 1, subpool));
 
602
  svn_pool_clear(subpool);
 
603
 
 
604
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, subpool, subpool));
 
605
  SVN_ERR(svn_client__mtcc_add_update_file("iota",
 
606
                                           cstr_stream("revision-2", subpool),
 
607
                                           NULL /* src_checksum */, NULL, NULL,
 
608
                                           mtcc, subpool));
 
609
  SVN_ERR(verify_mtcc_commit(mtcc, 2, subpool));
 
610
  svn_pool_clear(subpool);
 
611
 
 
612
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 2, ctx, subpool, subpool));
 
613
  SVN_ERR(svn_client__mtcc_add_update_file("iota",
 
614
                                           cstr_stream("revision-3", subpool),
 
615
                                           NULL /* src_checksum */, NULL, NULL,
 
616
                                           mtcc, subpool));
 
617
  SVN_ERR(verify_mtcc_commit(mtcc, 3, subpool));
 
618
  svn_pool_clear(subpool);
 
619
 
 
620
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 3, ctx, subpool, subpool));
 
621
  SVN_ERR(svn_client__mtcc_add_update_file("iota",
 
622
                                           cstr_stream("revision-4", subpool),
 
623
                                           NULL /* src_checksum */, NULL, NULL,
 
624
                                           mtcc, subpool));
 
625
  SVN_ERR(verify_mtcc_commit(mtcc, 4, subpool));
 
626
  svn_pool_clear(subpool);
 
627
 
 
628
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 4, ctx, subpool, subpool));
 
629
  SVN_ERR(svn_client__mtcc_add_move("iota", "mu", mtcc, subpool));
 
630
  SVN_ERR(verify_mtcc_commit(mtcc, 5, subpool));
 
631
  svn_pool_clear(subpool);
 
632
 
 
633
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 5, ctx, subpool, subpool));
 
634
  SVN_ERR(svn_client__mtcc_add_update_file("mu",
 
635
                                           cstr_stream("revision-6", subpool),
 
636
                                           NULL /* src_checksum */, NULL, NULL,
 
637
                                           mtcc, subpool));
 
638
  SVN_ERR(verify_mtcc_commit(mtcc, 6, subpool));
 
639
  svn_pool_clear(subpool);
 
640
 
 
641
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 6, ctx, subpool, subpool));
 
642
  SVN_ERR(svn_client__mtcc_add_delete("mu", mtcc, subpool));
 
643
  SVN_ERR(verify_mtcc_commit(mtcc, 7, subpool));
 
644
  svn_pool_clear(subpool);
 
645
 
 
646
  SVN_ERR(svn_client_open_ra_session2(&ra, repos_url, NULL, ctx, pool, subpool));
 
647
 
 
648
  hrb.prev = svn_stringbuf_create("", pool);
 
649
  hrb.cur = svn_stringbuf_create("", pool);
 
650
  hrb.pool = pool;
 
651
 
 
652
  svn_pool_clear(subpool);
 
653
  hrb.up = FALSE;
 
654
  hrb.last = 5;
 
655
  hrb.first = TRUE;
 
656
  svn_stringbuf_setempty(hrb.prev);
 
657
  svn_stringbuf_setempty(hrb.cur);
 
658
  SVN_ERR(svn_ra_get_file_revs2(ra, "iota", 4, 1, FALSE,
 
659
                                handle_rev, &hrb,
 
660
                                subpool));
 
661
  SVN_TEST_ASSERT(hrb.last == 1);
 
662
 
 
663
  svn_pool_clear(subpool);
 
664
  hrb.up = TRUE;
 
665
  hrb.last = 0;
 
666
  hrb.first = TRUE;
 
667
  svn_stringbuf_setempty(hrb.prev);
 
668
  svn_stringbuf_setempty(hrb.cur);
 
669
  SVN_ERR(svn_ra_get_file_revs2(ra, "iota", 1, 4, FALSE,
 
670
                                handle_rev, &hrb,
 
671
                                subpool));
 
672
  SVN_TEST_ASSERT(hrb.last == 4);
 
673
 
 
674
  svn_pool_clear(subpool);
 
675
  hrb.up = FALSE;
 
676
  hrb.last = 7;
 
677
  hrb.first = TRUE;
 
678
  svn_stringbuf_setempty(hrb.prev);
 
679
  svn_stringbuf_setempty(hrb.cur);
 
680
  SVN_ERR(svn_ra_get_file_revs2(ra, "mu", 6, 1, FALSE,
 
681
                                handle_rev, &hrb,
 
682
                                subpool));
 
683
  SVN_TEST_ASSERT(hrb.last == 1);
 
684
 
 
685
  svn_pool_clear(subpool);
 
686
  hrb.up = TRUE;
 
687
  hrb.last = 0;
 
688
  hrb.first = TRUE;
 
689
  svn_stringbuf_setempty(hrb.prev);
 
690
  svn_stringbuf_setempty(hrb.cur);
 
691
  SVN_ERR(svn_ra_get_file_revs2(ra, "mu", 1, 6, FALSE,
 
692
                                handle_rev, &hrb,
 
693
                                subpool));
 
694
  SVN_TEST_ASSERT(hrb.last == 6);
 
695
 
 
696
  /* Ressurect mu */
 
697
  svn_pool_clear(subpool);
 
698
  SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 7, ctx, subpool, subpool));
 
699
  SVN_ERR(svn_client__mtcc_add_copy("mu", 6, "mu", mtcc, subpool));
 
700
  SVN_ERR(verify_mtcc_commit(mtcc, 8, subpool));
 
701
 
 
702
  svn_pool_clear(subpool);
 
703
  hrb.up = TRUE;
 
704
  hrb.last = 0;
 
705
  hrb.first = TRUE;
 
706
  svn_stringbuf_setempty(hrb.prev);
 
707
  svn_stringbuf_setempty(hrb.cur);
 
708
  SVN_ERR(svn_ra_get_file_revs2(ra, "mu", 1, SVN_INVALID_REVNUM, FALSE,
 
709
                                handle_rev, &hrb,
 
710
                                subpool));
 
711
  SVN_TEST_ASSERT(hrb.last == 8);
 
712
 
 
713
  svn_pool_clear(subpool);
 
714
  hrb.up = FALSE;
 
715
  hrb.last = 9;
 
716
  hrb.first = TRUE;
 
717
  svn_stringbuf_setempty(hrb.prev);
 
718
  svn_stringbuf_setempty(hrb.cur);
 
719
  SVN_ERR(svn_ra_get_file_revs2(ra, "mu", SVN_INVALID_REVNUM, 1, FALSE,
 
720
                                handle_rev, &hrb,
 
721
                                subpool));
 
722
  SVN_TEST_ASSERT(hrb.last == 1);
 
723
 
 
724
  return SVN_NO_ERROR;
 
725
}
 
726
 
 
727
/* ========================================================================== */
 
728
 
 
729
 
 
730
static int max_threads = 3;
 
731
 
 
732
static struct svn_test_descriptor_t test_funcs[] =
 
733
  {
 
734
    SVN_TEST_NULL,
 
735
    SVN_TEST_OPTS_PASS(test_mkdir,
 
736
                       "test mtcc mkdir"),
 
737
    SVN_TEST_OPTS_PASS(test_mkgreek,
 
738
                       "test making greek tree"),
 
739
    SVN_TEST_OPTS_PASS(test_swap,
 
740
                       "swapping some trees"),
 
741
    SVN_TEST_OPTS_PASS(test_propset,
 
742
                       "test propset and propdel"),
 
743
    SVN_TEST_OPTS_PASS(test_update_files,
 
744
                       "test update files"),
 
745
    SVN_TEST_OPTS_PASS(test_overwrite,
 
746
                       "test overwrite"),
 
747
    SVN_TEST_OPTS_PASS(test_anchoring,
 
748
                       "test mtcc anchoring for root operations"),
 
749
    SVN_TEST_OPTS_PASS(test_replace_tree,
 
750
                       "test mtcc replace tree"),
 
751
    SVN_TEST_OPTS_PASS(test_file_revs_both_ways,
 
752
                       "test ra_get_file_revs2 both ways"),
 
753
    SVN_TEST_NULL
 
754
  };
 
755
 
 
756
SVN_TEST_MAIN