> Dmitry Pavlenko wrote:
>> Hello Subversion community!

Hello Dmitry! Thanks for finding this. I confirm it.

>> I've run into an error: when performing 2 specially constructed updates one 
>> after another
>> within the same session, SVN fails with 
>> 
>>   $ ./ra-test 15
>>   svn_tests: E160016: Can't get entries of non-directory
>>   XFAIL: ra-test 15: check that there's no "Can't get entries" error
> 
>> error. I believe these updates constructed that way are valid, so the 
>> problem is
>> somewhere in FSFS code.

I agree.

Daniel Shahaf wrote:
> Could you please clarify whether the bug reproduces under other backends 
> (FSX and BDB)?

I found that the test passes under FSX and BDB; it only fails under FSFS.

I found that the RA method (local, svn, serf) makes no difference.

> You make all commits using the same EDITOR.  Is that allowed?

I found that it doesn't affect the outcome, in this case.

(Generally, as Brane said, it's undocumented and not a good idea. The attached 
version of the patch, 'cant_get_entries_test-j1.patch', uses a separate editor 
for each edit.)


-- 
- Julian
Index: subversion/tests/libsvn_ra/ra-test.c
===================================================================
--- subversion/tests/libsvn_ra/ra-test.c	(revision 1846979)
+++ subversion/tests/libsvn_ra/ra-test.c	(working copy)
@@ -1784,6 +1784,128 @@
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+cant_get_entries_of_non_directory(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_ra_session_t *session;
+
+  SVN_ERR(make_and_open_repos(&session,
+                              "cant_get_entries_of_non_directory", opts,
+                              pool));
+
+  {
+    const svn_delta_editor_t *editor;
+    void *edit_baton;
+    void *root_baton;
+    void *dir_baton;
+    void *file_baton;
+
+    SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+                                      apr_hash_make(pool), NULL,
+                                      NULL, NULL, FALSE, pool));
+    SVN_ERR(editor->open_root(edit_baton, 0, pool, &root_baton));
+    SVN_ERR(editor->add_directory("A", root_baton, NULL, SVN_INVALID_REVNUM,
+                                  pool, &dir_baton));
+    SVN_ERR(editor->add_file("A/mu", dir_baton, NULL, SVN_INVALID_REVNUM,
+                             pool, &file_baton));
+    SVN_ERR(editor->close_file(file_baton, NULL, pool));
+    SVN_ERR(editor->close_directory(dir_baton, pool));
+    SVN_ERR(editor->close_directory(root_baton, pool));
+    SVN_ERR(editor->close_edit(edit_baton, pool));
+  }
+  {
+    const svn_delta_editor_t *editor;
+    void *edit_baton;
+    void *root_baton;
+    void *dir_baton;
+    const char* repos_root_url;
+    const char* A_url;
+
+    SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, pool));
+    A_url = svn_path_url_add_component2(repos_root_url, "A", pool);
+
+    SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+                                      apr_hash_make(pool), NULL,
+                                      NULL, NULL, FALSE, pool));
+    SVN_ERR(editor->open_root(edit_baton, 1, pool, &root_baton));
+    SVN_ERR(editor->add_directory("B", root_baton, A_url, 1,
+                                  pool, &dir_baton));
+    SVN_ERR(editor->close_directory(dir_baton, pool));
+    SVN_ERR(editor->close_directory(root_baton, pool));
+    SVN_ERR(editor->close_edit(edit_baton, pool));
+  }
+  {
+    const svn_delta_editor_t *editor;
+    void *edit_baton;
+    void *root_baton;
+
+    SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+                                      apr_hash_make(pool), NULL,
+                                      NULL, NULL, FALSE, pool));
+    SVN_ERR(editor->open_root(edit_baton, 2, pool, &root_baton));
+    SVN_ERR(editor->delete_entry("B/mu", 2, root_baton, pool));
+    SVN_ERR(editor->close_directory(root_baton, pool));
+    SVN_ERR(editor->close_edit(edit_baton, pool));
+  }
+  {
+    const svn_delta_editor_t *editor;
+    void *edit_baton;
+    void *root_baton;
+    void *dir_baton;
+    void *subdir_baton;
+    void *file_baton;
+
+    SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+                                      apr_hash_make(pool), NULL,
+                                      NULL, NULL, FALSE, pool));
+    SVN_ERR(editor->open_root(edit_baton, 3, pool, &root_baton));
+    SVN_ERR(editor->open_directory("B", root_baton, 3, pool, &dir_baton));
+    SVN_ERR(editor->add_directory("B/mu", root_baton, NULL, SVN_INVALID_REVNUM,
+                                  pool, &subdir_baton));
+    SVN_ERR(editor->add_file("B/mu/iota", subdir_baton, NULL, SVN_INVALID_REVNUM,
+                             pool, &file_baton));
+    SVN_ERR(editor->close_file(file_baton, NULL, pool));
+    SVN_ERR(editor->close_directory(subdir_baton, pool));
+    SVN_ERR(editor->close_directory(dir_baton, pool));
+    SVN_ERR(editor->close_directory(root_baton, pool));
+    SVN_ERR(editor->close_edit(edit_baton, pool));
+  }
+  /* The following updates fail when executed in this order
+     one after another within the same session.
+
+     When commenting out one of the blocks the test passes
+     */
+  {
+    const svn_ra_reporter3_t *reporter;
+    void *report_baton;
+
+    SVN_ERR(svn_ra_do_update3(session, &reporter, &report_baton,
+                              3, "", svn_depth_infinity, TRUE, FALSE,
+                              svn_delta_default_editor(pool), NULL,
+                              pool, pool));
+    SVN_ERR(reporter->set_path(report_baton, "", 3, svn_depth_infinity, FALSE,
+                               NULL, pool));
+    SVN_ERR(reporter->set_path(report_baton, "B", 2, svn_depth_infinity, FALSE,
+                               NULL, pool));
+    SVN_ERR(reporter->finish_report(report_baton, pool));
+  }
+  {
+    const svn_ra_reporter3_t *reporter;
+    void *report_baton;
+
+    SVN_ERR(svn_ra_do_update3(session, &reporter, &report_baton,
+                              4, "", svn_depth_infinity, TRUE, FALSE,
+                              svn_delta_default_editor(pool), NULL,
+                              pool, pool));
+    SVN_ERR(reporter->set_path(report_baton, "", 4, svn_depth_infinity, FALSE,
+                               NULL, pool));
+    SVN_ERR(reporter->set_path(report_baton, "B", 3, svn_depth_infinity, FALSE,
+                               NULL, pool));
+    SVN_ERR(reporter->finish_report(report_baton, pool));
+  }
+  return SVN_NO_ERROR;
+}
+
 
 /* The test table.  */
 
@@ -1820,6 +1942,8 @@
                        "check how last change applies to empty commit"),
     SVN_TEST_OPTS_PASS(commit_locked_file,
                        "check commit editor for a locked file"),
+    SVN_TEST_OPTS_XFAIL(cant_get_entries_of_non_directory,
+                       "check that there's no \"Can't get entries\" error"),
     SVN_TEST_NULL
   };
 

Reply via email to