def init_ra_and_client(self): """Initializes the RA and client layers, because sometimes getting unified diffs runs the remote server out of open files. """ # while we're in here we'll recreate our pool self.pool = core.Pool() if self.username: core.svn_auth_set_parameter(self.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_USERNAME, self.username) if self.password: core.svn_auth_set_parameter(self.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_PASSWORD, self.password) self.client_context = client.create_context() self.client_context.auth_baton = self.auth_baton self.client_context.config = svn_config callbacks = RaCallbacks() callbacks.auth_baton = self.auth_baton self.callbacks = callbacks try: url = self.svn_url.encode('utf-8') scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) path=urllib.quote(path) url = urlparse.urlunparse((scheme, netloc, path, params, query, fragment)) self.ra = ra.open2(url, callbacks, svn_config, self.pool) except core.SubversionException, e: raise hgutil.Abort(e.args[0])
def init_ra_and_client(self): """Initializes the RA and client layers, because sometimes getting unified diffs runs the remote server out of open files. """ # while we're in here we'll recreate our pool self.pool = core.Pool() if self.username: core.svn_auth_set_parameter(self.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_USERNAME, self.username) if self.password: core.svn_auth_set_parameter(self.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_PASSWORD, self.password) self.client_context = client.create_context() self.client_context.auth_baton = self.auth_baton self.client_context.config = svn_config callbacks = RaCallbacks() callbacks.auth_baton = self.auth_baton self.callbacks = callbacks try: self.ra = ra.open2(self.svn_url, callbacks, svn_config, self.pool) except SubversionException, e: # e.child contains a detailed error messages msglist = [] svn_exc = e while svn_exc: if svn_exc.args[0]: msglist.append(svn_exc.args[0]) svn_exc = svn_exc.child msg = '\n'.join(msglist) raise common.SubversionConnectionException(msg)
def init_ra_and_client(self): """Initializes the RA and client layers, because sometimes getting unified diffs runs the remote server out of open files. """ # while we're in here we'll recreate our pool self.pool = core.Pool() if self.username: core.svn_auth_set_parameter(self.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_USERNAME, self.username) if self.password: core.svn_auth_set_parameter(self.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_PASSWORD, self.password) self.client_context = client.create_context() self.client_context.auth_baton = self.auth_baton self.client_context.config = svn_config callbacks = RaCallbacks() callbacks.auth_baton = self.auth_baton self.callbacks = callbacks try: self.ra = ra.open2(self.svn_url, callbacks, svn_config, self.pool) except SubversionException, e: # e.child contains a detailed error messages msglist = [] svn_exc = e while svn_exc: if svn_exc.args[0]: msglist.append(svn_exc.args[0]) svn_exc = svn_exc.child msg = '\n'.join(msglist) raise common.SubversionConnectionException(msg)
def test_lock(self): self.calls = 0 self.locks = 0 self.errors = 0 def callback(path, do_lock, lock, ra_err, pool): self.calls += 1 self.assertEqual(path, "trunk/README2.txt") if lock: self.assertEqual(lock.owner, "jrandom") self.locks += 1 if ra_err: self.assert_( ra_err.apr_err == core.SVN_ERR_FS_PATH_ALREADY_LOCKED or ra_err.apr_err == core.SVN_ERR_FS_NO_SUCH_LOCK) self.errors += 1 providers = [core.svn_auth_get_username_provider()] self.callbacks.auth_baton = core.svn_auth_open(providers) core.svn_auth_set_parameter(self.callbacks.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_USERNAME, "jrandom") self.ra_ctx = ra.open2(self.repos_uri, self.callbacks, {}) rev = fs.youngest_rev(self.fs) ra.lock(self.ra_ctx, {"trunk/README2.txt": rev}, "sleutel", False, callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 1) self.assertEqual(self.errors, 0) self.calls = 0 self.locks = 0 ra.lock(self.ra_ctx, {"trunk/README2.txt": rev}, "sleutel", False, callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 0) self.assertEqual(self.errors, 1) self.calls = 0 self.errors = 0 the_lock = fs.get_lock(self.fs, "/trunk/README2.txt") ra.unlock(self.ra_ctx, {"trunk/README2.txt": the_lock.token}, False, callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 0) self.assertEqual(self.errors, 0) self.calls = 0 ra.unlock(self.ra_ctx, {"trunk/README2.txt": the_lock.token}, False, callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 0) self.assertEqual(self.errors, 1)
def setUp(self): """Load a Subversion repository""" ra.initialize() self.temper = utils.Temper() # Isolate each test from the others with a fresh repository. # Open repository directly for cross-checking (self.repos, _, self.repos_uri) = self.temper.alloc_known_repo( 'trac/versioncontrol/tests/svnrepos.dump', suffix='-ra') self.fs = repos.fs(self.repos) self.callbacks = ra.Callbacks() self.ra_ctx = ra.open2(self.repos_uri, self.callbacks, {})
def setUp(self): """Load a Subversion repository""" ra.initialize() self.temper = utils.Temper() # Isolate each test from the others with a fresh repository. # Open repository directly for cross-checking (self.repos, _, self.repos_uri) = self.temper.alloc_known_repo( 'trac/versioncontrol/tests/svnrepos.dump', suffix='-ra') self.fs = repos.fs(self.repos) self.callbacks = ra.Callbacks() self.ra_ctx = ra.open2(self.repos_uri, self.callbacks, {})
def test_lock(self): self.calls = 0 self.locks = 0 self.errors = 0 def callback(path, do_lock, lock, ra_err, pool): self.calls += 1 self.assertEqual(path, "trunk/README2.txt") if lock: self.assertEqual(lock.owner, "jrandom") self.locks += 1 if ra_err: self.assert_(ra_err.apr_err == core.SVN_ERR_FS_PATH_ALREADY_LOCKED or ra_err.apr_err == core.SVN_ERR_FS_NO_SUCH_LOCK) self.errors += 1 providers = [core.svn_auth_get_username_provider()] self.callbacks.auth_baton = core.svn_auth_open(providers) core.svn_auth_set_parameter(self.callbacks.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_USERNAME, "jrandom") self.ra_ctx = ra.open2(self.repos_uri, self.callbacks, {}) rev = fs.youngest_rev(self.fs) ra.lock(self.ra_ctx, {"trunk/README2.txt":rev}, "sleutel", False, callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 1) self.assertEqual(self.errors, 0) self.calls = 0 self.locks = 0 ra.lock(self.ra_ctx, {"trunk/README2.txt":rev}, "sleutel", False, callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 0) self.assertEqual(self.errors, 1) self.calls = 0 self.errors = 0 the_lock = fs.get_lock(self.fs, "/trunk/README2.txt") ra.unlock(self.ra_ctx, {"trunk/README2.txt":the_lock.token}, False, callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 0) self.assertEqual(self.errors, 0) self.calls = 0 ra.unlock(self.ra_ctx, {"trunk/README2.txt":the_lock.token}, False, callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 0) self.assertEqual(self.errors, 1)
def setUp(self): """Load a Subversion repository""" # Isolate each test from the others with a fresh repository. # Eventually, we should move this into a shared TestCase base # class that all test cases in this directory can use. SubversionRepositoryTestSetup().setUp() ra.initialize() # Open repository directly for cross-checking self.repos = repos.open(REPOS_PATH) self.fs = repos.fs(self.repos) self.callbacks = ra.Callbacks() self.ra_ctx = ra.open2(REPOS_URL, self.callbacks, None, None)
def setUp(self): """Load a Subversion repository""" # Isolate each test from the others with a fresh repository. # Eventually, we should move this into a shared TestCase base # class that all test cases in this directory can use. SubversionRepositoryTestSetup().setUp() ra.initialize() # Open repository directly for cross-checking self.repos = repos.open(REPOS_PATH) self.fs = repos.fs(self.repos) self.callbacks = ra.Callbacks() self.ra_ctx = ra.open2(REPOS_URL, self.callbacks, None, None)
def init_ra_and_client(self): """Initializes the RA and client layers, because sometimes getting unified diffs runs the remote server out of open files. """ # while we're in here we'll recreate our pool self.pool = core.Pool() if self.username: core.svn_auth_set_parameter(self.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_USERNAME, self.username) if self.password: core.svn_auth_set_parameter(self.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_PASSWORD, self.password) self.client_context = client.create_context() self.client_context.auth_baton = self.auth_baton self.client_context.config = svn_config callbacks = RaCallbacks() callbacks.auth_baton = self.auth_baton self.callbacks = callbacks try: self.ra = ra.open2(self.svn_url, callbacks, svn_config, self.pool) except SubversionException, e: if e.apr_err == core.SVN_ERR_RA_SERF_SSL_CERT_UNTRUSTED: msg = ('Subversion does not trust the SSL certificate for this ' 'site; please try running \'svn ls %s\' first.' % self.svn_url) elif e.apr_err == core.SVN_ERR_RA_DAV_REQUEST_FAILED: msg = ('Failed to open Subversion repository; please try ' 'running \'svn ls %s\' for details.' % self.svn_url) else: msg = e.args[0] for k, v in vars(core).iteritems(): if k.startswith('SVN_ERR_') and v == e.apr_err: msg = '%s (%s)' % (msg, k) break raise common.SubversionConnectionException(msg)
def init_ra_and_client(self): """Initializes the RA and client layers, because sometimes getting unified diffs runs the remote server out of open files. """ # while we're in here we'll recreate our pool self.pool = core.Pool() if self.username: core.svn_auth_set_parameter(self.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_USERNAME, self.username) if self.password: core.svn_auth_set_parameter(self.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_PASSWORD, self.password) self.client_context = client.create_context() self.client_context.auth_baton = self.auth_baton self.client_context.config = svn_config callbacks = RaCallbacks() callbacks.auth_baton = self.auth_baton self.callbacks = callbacks try: self.ra = ra.open2(self.svn_url, callbacks, svn_config, self.pool) except SubversionException, e: if e.apr_err == core.SVN_ERR_RA_SERF_SSL_CERT_UNTRUSTED: msg = ( 'Subversion does not trust the SSL certificate for this ' 'site; please try running \'svn ls %s\' first.' % self.svn_url) elif e.apr_err == core.SVN_ERR_RA_DAV_REQUEST_FAILED: msg = ('Failed to open Subversion repository; please try ' 'running \'svn ls %s\' for details.' % self.svn_url) else: msg = e.args[0] for k, v in vars(core).iteritems(): if k.startswith('SVN_ERR_') and v == e.apr_err: msg = '%s (%s)' % (msg, k) break raise common.SubversionConnectionException(msg)
def test_diff_editor4(self): pool = None depth = core.svn_depth_infinity url = REPOS_URL # cause file_changed: Replace README.txt's contents. readme_path = '%s/trunk/README.txt' % self.path fp = open(readme_path, 'w') fp.write('hello\n') fp.close() # cause file_added: Create readme3. readme3_path = '%s/trunk/readme3' % self.path fp = open(readme3_path, 'w') fp.write('hello\n') fp.close() wc.add2( readme3_path, wc.adm_probe_retrieve(self.wc, os.path.dirname(readme3_path), pool), None, SVN_INVALID_REVNUM, # copyfrom None, # cancel_func None, # notify_func pool) # cause file_deleted: Delete README2.txt. readme2_path = '%s/trunk/README2.txt' % self.path wc.delete3( readme2_path, wc.adm_probe_retrieve(self.wc, os.path.dirname(readme2_path), pool), None, # cancel_func None, # notify_func False, # keep_local pool) # cause dir_props_changed: ps testprop testval dir1/dir2 dir2_path = '%s/trunk/dir1/dir2' % self.path wc.prop_set2( 'testprop', 'testval', dir2_path, wc.adm_probe_retrieve(self.wc, os.path.dirname(dir2_path), pool), False, # skip_checks pool) # TODO: cause dir_added/deleted # Save prop changes. got_prop_changes = [] def props_changed(path, propchanges): for (name, value) in propchanges.iteritems(): (kind, unused_prefix_len) = core.svn_property_kind(name) if kind != core.svn_prop_regular_kind: continue got_prop_changes.append( (path[len(self.path) + 1:], name, value)) # Save diffs. got_diffs = {} def write_diff(path, left, right): options = svn.diff.file_options_create() diff = svn.diff.file_diff_2(left, right, options, pool) original_header = modified_header = '' encoding = 'utf8' relative_to_dir = None sio = cStringIO.StringIO() svn.diff.file_output_unified3(sio, diff, left, right, original_header, modified_header, encoding, relative_to_dir, options.show_c_function, pool) got_diffs[path[len(self.path) + 1:]] = sio.getvalue().splitlines() # Diff callbacks that call props_changed and write_diff. contentstate = propstate = state = wc.notify_state_unknown class Callbacks(wc.DiffCallbacks2): def file_changed(self, adm_access, path, tmpfile1, tmpfile2, rev1, rev2, mimetype1, mimetype2, propchanges, originalprops): write_diff(path, tmpfile1, tmpfile2) return (contentstate, propstate) def file_added(self, adm_access, path, tmpfile1, tmpfile2, rev1, rev2, mimetype1, mimetype2, propchanges, originalprops): write_diff(path, tmpfile1, tmpfile2) return (contentstate, propstate) def file_deleted(self, adm_access, path, tmpfile1, tmpfile2, mimetype1, mimetype2, originalprops): write_diff(path, tmpfile1, tmpfile2) return state def dir_props_changed(self, adm_access, path, propchanges, original_props): props_changed(path, propchanges) return state diff_callbacks = Callbacks() # Setup wc diff editor. (editor, edit_baton) = wc.get_diff_editor4( self.wc, '', diff_callbacks, depth, False, # ignore_ancestry False, # use_text_base False, # reverse_order None, # cancel_func None, # changelists pool) # Setup ra_ctx. ra.initialize() ra_callbacks = ra.Callbacks() ra_ctx = ra.open2(url, ra_callbacks, None, None) # Use head rev for do_diff3 and set_path. head = ra.get_latest_revnum(ra_ctx) # Get diff reporter. (reporter, report_baton) = ra.do_diff3( ra_ctx, head, # versus_url revision '', # diff_target depth, False, # ignore_ancestry True, # text_deltas url, # versus_url editor, edit_baton, pool) # Report wc state (pretty plain). reporter.set_path( report_baton, '', head, depth, False, # start_empty None, # lock_token pool) reporter.finish_report(report_baton, pool) # Assert we got the right diff. expected_prop_changes = [('trunk/dir1/dir2', 'testprop', 'testval')] expected_diffs = { 'trunk/readme3': ['--- ', '+++ ', '@@ -0,0 +1 @@', '+hello'], 'trunk/README.txt': ['--- ', '+++ ', '@@ -1 +1 @@', '-A test.', '+hello'], 'trunk/README2.txt': ['--- ', '+++ ', '@@ -1 +0,0 @@', '-A test.'], } self.assertEqual(got_prop_changes, expected_prop_changes) self.assertEqual(got_diffs, expected_diffs)
def test_commit(self): # Replace README.txt's contents, using binary mode so we know the # exact contents even on Windows, and therefore the MD5 checksum. readme_path = '%s/trunk/README.txt' % self.path fp = open(readme_path, 'wb') fp.write('hello\n') fp.close() # Setup ra_ctx. ra.initialize() callbacks = ra.Callbacks() ra_ctx = ra.open2(REPOS_URL, callbacks, None, None) # Get commit editor. commit_info = [None] def commit_cb(_commit_info, pool): commit_info[0] = _commit_info (editor, edit_baton) = ra.get_commit_editor2(ra_ctx, 'log message', commit_cb, None, False) # Drive the commit. checksum = [None] def driver_cb(parent, path, pool): baton = editor.open_file(path, parent, -1, pool) adm_access = wc.adm_probe_retrieve(self.wc, readme_path, pool) (_, checksum[0]) = wc.transmit_text_deltas2(readme_path, adm_access, False, editor, baton, pool) return baton try: delta.path_driver(editor, edit_baton, -1, ['trunk/README.txt'], driver_cb) editor.close_edit(edit_baton) except: try: editor.abort_edit(edit_baton) except: # We already have an exception in progress, not much we can do # about this. pass raise (checksum, ) = checksum (commit_info, ) = commit_info # Assert the commit. self.assertEquals(binascii.b2a_hex(checksum), 'b1946ac92492d2347c6235b4d2611184') self.assertEquals(commit_info.revision, 13) # Bump working copy state. wc.process_committed4( readme_path, wc.adm_retrieve(self.wc, os.path.dirname(readme_path)), False, commit_info.revision, commit_info.date, commit_info.author, None, False, False, checksum) # Assert bumped state. entry = wc.entry(readme_path, self.wc, False) self.assertEquals(entry.revision, commit_info.revision) self.assertEquals(entry.schedule, wc.schedule_normal) self.assertEquals(entry.cmt_rev, commit_info.revision) self.assertEquals(entry.cmt_date, core.svn_time_from_cstring(commit_info.date))
def test_diff_editor4(self): pool = None depth = core.svn_depth_infinity url = REPOS_URL # cause file_changed: Replace README.txt's contents. readme_path = "%s/trunk/README.txt" % self.path fp = open(readme_path, "w") fp.write("hello\n") fp.close() # cause file_added: Create readme3. readme3_path = "%s/trunk/readme3" % self.path fp = open(readme3_path, "w") fp.write("hello\n") fp.close() wc.add2( readme3_path, wc.adm_probe_retrieve(self.wc, os.path.dirname(readme3_path), pool), None, SVN_INVALID_REVNUM, # copyfrom None, # cancel_func None, # notify_func pool, ) # cause file_deleted: Delete README2.txt. readme2_path = "%s/trunk/README2.txt" % self.path wc.delete3( readme2_path, wc.adm_probe_retrieve(self.wc, os.path.dirname(readme2_path), pool), None, # cancel_func None, # notify_func False, # keep_local pool, ) # cause dir_props_changed: ps testprop testval dir1/dir2 dir2_path = "%s/trunk/dir1/dir2" % self.path wc.prop_set2( "testprop", "testval", dir2_path, wc.adm_probe_retrieve(self.wc, os.path.dirname(dir2_path), pool), False, # skip_checks pool, ) # TODO: cause dir_added/deleted # Save prop changes. got_prop_changes = [] def props_changed(path, propchanges): for (name, value) in propchanges.iteritems(): (kind, unused_prefix_len) = core.svn_property_kind(name) if kind != core.svn_prop_regular_kind: continue got_prop_changes.append((path[len(self.path) + 1 :], name, value)) # Save diffs. got_diffs = {} def write_diff(path, left, right): options = svn.diff.file_options_create() diff = svn.diff.file_diff_2(left, right, options, pool) original_header = modified_header = "" encoding = "utf8" relative_to_dir = None sio = cStringIO.StringIO() svn.diff.file_output_unified3( sio, diff, left, right, original_header, modified_header, encoding, relative_to_dir, options.show_c_function, pool, ) got_diffs[path[len(self.path) + 1 :]] = sio.getvalue().splitlines() # Diff callbacks that call props_changed and write_diff. contentstate = propstate = state = wc.notify_state_unknown class Callbacks(wc.DiffCallbacks2): def file_changed( self, adm_access, path, tmpfile1, tmpfile2, rev1, rev2, mimetype1, mimetype2, propchanges, originalprops ): write_diff(path, tmpfile1, tmpfile2) return (contentstate, propstate) def file_added( self, adm_access, path, tmpfile1, tmpfile2, rev1, rev2, mimetype1, mimetype2, propchanges, originalprops ): write_diff(path, tmpfile1, tmpfile2) return (contentstate, propstate) def file_deleted(self, adm_access, path, tmpfile1, tmpfile2, mimetype1, mimetype2, originalprops): write_diff(path, tmpfile1, tmpfile2) return state def dir_props_changed(self, adm_access, path, propchanges, original_props): props_changed(path, propchanges) return state diff_callbacks = Callbacks() # Setup wc diff editor. (editor, edit_baton) = wc.get_diff_editor4( self.wc, "", diff_callbacks, depth, False, # ignore_ancestry False, # use_text_base False, # reverse_order None, # cancel_func None, # changelists pool, ) # Setup ra_ctx. ra.initialize() ra_callbacks = ra.Callbacks() ra_ctx = ra.open2(url, ra_callbacks, None, None) # Use head rev for do_diff3 and set_path. head = ra.get_latest_revnum(ra_ctx) # Get diff reporter. (reporter, report_baton) = ra.do_diff3( ra_ctx, head, # versus_url revision "", # diff_target depth, False, # ignore_ancestry True, # text_deltas url, # versus_url editor, edit_baton, pool, ) # Report wc state (pretty plain). reporter.set_path(report_baton, "", head, depth, False, None, pool) # start_empty # lock_token reporter.finish_report(report_baton, pool) # Assert we got the right diff. expected_prop_changes = [("trunk/dir1/dir2", "testprop", "testval")] expected_diffs = { "trunk/readme3": ["--- ", "+++ ", "@@ -0,0 +1 @@", "+hello"], "trunk/README.txt": ["--- ", "+++ ", "@@ -1 +1 @@", "-A test.", "+hello"], "trunk/README2.txt": ["--- ", "+++ ", "@@ -1 +0,0 @@", "-A test."], } self.assertEqual(got_prop_changes, expected_prop_changes) self.assertEqual(got_diffs, expected_diffs)
def test_commit(self): # Replace README.txt's contents, using binary mode so we know the # exact contents even on Windows, and therefore the MD5 checksum. readme_path = "%s/trunk/README.txt" % self.path fp = open(readme_path, "wb") fp.write("hello\n") fp.close() # Setup ra_ctx. ra.initialize() callbacks = ra.Callbacks() ra_ctx = ra.open2(REPOS_URL, callbacks, None, None) # Get commit editor. commit_info = [None] def commit_cb(_commit_info, pool): commit_info[0] = _commit_info (editor, edit_baton) = ra.get_commit_editor2(ra_ctx, "log message", commit_cb, None, False) # Drive the commit. checksum = [None] def driver_cb(parent, path, pool): baton = editor.open_file(path, parent, -1, pool) adm_access = wc.adm_probe_retrieve(self.wc, readme_path, pool) (_, checksum[0]) = wc.transmit_text_deltas2(readme_path, adm_access, False, editor, baton, pool) return baton try: delta.path_driver(editor, edit_baton, -1, ["trunk/README.txt"], driver_cb) editor.close_edit(edit_baton) except: try: editor.abort_edit(edit_baton) except: # We already have an exception in progress, not much we can do # about this. pass raise (checksum,) = checksum (commit_info,) = commit_info # Assert the commit. self.assertEquals(binascii.b2a_hex(checksum), "b1946ac92492d2347c6235b4d2611184") self.assertEquals(commit_info.revision, 13) # Bump working copy state. wc.process_committed4( readme_path, wc.adm_retrieve(self.wc, os.path.dirname(readme_path)), False, commit_info.revision, commit_info.date, commit_info.author, None, False, False, checksum, ) # Assert bumped state. entry = wc.entry(readme_path, self.wc, False) self.assertEquals(entry.revision, commit_info.revision) self.assertEquals(entry.schedule, wc.schedule_normal) self.assertEquals(entry.cmt_rev, commit_info.revision) self.assertEquals(entry.cmt_date, core.svn_time_from_cstring(commit_info.date))