diff --git a/master/buildbot/steps/source/svn.py b/master/buildbot/steps/source/svn.py
index 23ba83018c7..3bef6a0fe97 100644
--- a/master/buildbot/steps/source/svn.py
+++ b/master/buildbot/steps/source/svn.py
@@ -182,7 +182,7 @@ def copy(self):
export_cmd.extend(["--revision", str(self.revision)])
if self.username:
export_cmd.extend(['--username', self.username])
- if self.password:
+ if self.password is not None:
export_cmd.extend(['--password', ('obfuscated', self.password, 'XXXXXX')])
if self.extra_args:
export_cmd.extend(self.extra_args)
@@ -212,7 +212,7 @@ def _dovccmd(self, command, collectStdout=False, abandonOnFailure=True):
command.extend(['--non-interactive', '--no-auth-cache'])
if self.username:
command.extend(['--username', self.username])
- if self.password:
+ if self.password is not None:
command.extend(['--password', ('obfuscated', self.password, 'XXXXXX')])
if self.depth:
command.extend(['--depth', self.depth])
diff --git a/master/buildbot/test/unit/test_steps_source_svn.py b/master/buildbot/test/unit/test_steps_source_svn.py
index e782a25356e..c297770c8c4 100644
--- a/master/buildbot/test/unit/test_steps_source_svn.py
+++ b/master/buildbot/test/unit/test_steps_source_svn.py
@@ -153,7 +153,7 @@ def test_corrupt_xml(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -186,7 +186,7 @@ def test_revision_noninteger(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -229,7 +229,7 @@ def test_revision_missing(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -265,7 +265,7 @@ def test_mode_incremental(self):
'--no-auth-cache', '--username', 'user',
'--password', ('obfuscated', 'pass', 'XXXXXX'), '--random'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -306,7 +306,7 @@ def test_mode_incremental_timeout(self):
'--no-auth-cache', '--username', 'user',
'--password', ('obfuscated', 'pass', 'XXXXXX'), '--random'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
timeout=1,
@@ -344,7 +344,7 @@ def test_mode_incremental_repourl_renderable(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/trunk""")
+ stdout="""http://svn.local/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -379,7 +379,7 @@ def test_mode_incremental_repourl_canonical(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/trunk/test%20app""")
+ stdout="""http://svn.local/trunk/test%20app""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -480,7 +480,7 @@ def test_mode_incremental_repourl_not_updatable_svninfo_mismatch(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio', # expecting ../trunk/app
- stdout="""http://svn.local/branch/foo/app""")
+ stdout="""http://svn.local/branch/foo/app""")
+ 0,
Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
+ 0,
@@ -519,7 +519,7 @@ def test_mode_incremental_given_revision(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--revision', '100',
@@ -557,7 +557,7 @@ def test_mode_incremental_win32path(self):
'--no-auth-cache', '--username', 'user',
'--password', ('obfuscated', 'pass', 'XXXXXX'), '--random'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -596,7 +596,7 @@ def test_mode_incremental_preferLastChangedRev(self):
'--no-auth-cache', '--username', 'user',
'--password', ('obfuscated', 'pass', 'XXXXXX'), '--random'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -639,7 +639,7 @@ def test_mode_incremental_preferLastChangedRev_butMissing(self):
'--no-auth-cache', '--username', 'user',
'--password', ('obfuscated', 'pass', 'XXXXXX'), '--random'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -736,7 +736,7 @@ def test_mode_full_fresh(self):
'--non-interactive',
'--no-auth-cache', '--depth', 'infinite'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn',
@@ -823,7 +823,7 @@ def test_mode_full_fresh_given_revision(self):
'--non-interactive',
'--no-auth-cache', '--depth', 'infinite'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn',
@@ -868,7 +868,7 @@ def test_mode_full_fresh_keep_on_purge(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn',
@@ -913,7 +913,7 @@ def test_mode_full_clean(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn',
@@ -956,7 +956,7 @@ def test_mode_full_clean_given_revision(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn',
@@ -1059,7 +1059,7 @@ def test_mode_full_clean_old_rmdir(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn',
@@ -1110,7 +1110,7 @@ def test_mode_full_clean_new_rmdir(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn',
@@ -1159,7 +1159,7 @@ def test_mode_full_copy(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='source',
command=['svn', 'update', '--non-interactive',
@@ -1203,7 +1203,7 @@ def test_mode_full_copy_given_revision(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='source',
command=['svn', 'update', '--revision', '100',
@@ -1245,7 +1245,7 @@ def test_mode_full_export(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='source',
command=['svn', 'update', '--non-interactive',
@@ -1298,7 +1298,7 @@ def test_mode_full_export_patch(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='source',
command=['svn', 'update', '--non-interactive',
@@ -1359,7 +1359,7 @@ def test_mode_full_export_timeout(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='source',
timeout=1,
@@ -1405,7 +1405,7 @@ def test_mode_full_export_given_revision(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='source',
command=['svn', 'update', '--revision', '100',
@@ -1450,7 +1450,7 @@ def test_mode_full_export_auth(self):
'--username', 'svn_username',
'--password', ('obfuscated', 'svn_password', 'XXXXXX')])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='source',
command=['svn', 'update', '--non-interactive',
@@ -1497,7 +1497,7 @@ def test_mode_incremental_with_env(self):
'--password', ('obfuscated', 'pass', 'XXXXXX'), '--random'],
env={'abc': '123'})
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -1540,7 +1540,7 @@ def test_mode_incremental_logEnviron(self):
'--password', ('obfuscated', 'pass', 'XXXXXX'), '--random'],
logEnviron=False)
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -1580,7 +1580,7 @@ def test_command_fails(self):
'--no-auth-cache', '--username', 'user',
'--password', ('obfuscated', 'pass', 'XXXXXX'), '--random'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn', 'update', '--non-interactive',
@@ -1685,7 +1685,7 @@ def test_cpdir_fails_copy(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='source',
command=['svn', 'update', '--non-interactive',
@@ -1720,7 +1720,7 @@ def test_rmdir_fails_purge(self):
'--non-interactive',
'--no-auth-cache'])
+ ExpectShell.log('stdio',
- stdout="""http://svn.local/app/trunk""")
+ stdout="""http://svn.local/app/trunk""")
+ 0,
ExpectShell(workdir='wkdir',
command=['svn',
@@ -1751,6 +1751,80 @@ def test_slave_connection_lost(self):
status_text=["update", "exception", "slave", "lost"])
return self.runStep()
+ def test_empty_password(self):
+ self.setupStep(
+ svn.SVN(repourl='http://svn.local/app/trunk',
+ mode='incremental', username='user',
+ password='', extra_args=['--random']))
+ self.expectCommands(
+ ExpectShell(workdir='wkdir',
+ command=['svn', '--version'])
+ + 0,
+ Expect('stat', dict(file='wkdir/.buildbot-patched',
+ logEnviron=True))
+ + 1,
+ Expect('stat', dict(file='wkdir/.svn',
+ logEnviron=True))
+ + 0,
+ ExpectShell(workdir='wkdir',
+ command=['svn', 'info', '--xml',
+ '--non-interactive',
+ '--no-auth-cache', '--username', 'user',
+ '--password', ('obfuscated', '', 'XXXXXX'), '--random'])
+ + ExpectShell.log('stdio',
+ stdout="""http://svn.local/app/trunk""")
+ + 0,
+ ExpectShell(workdir='wkdir',
+ command=['svn', 'update', '--non-interactive',
+ '--no-auth-cache', '--username', 'user',
+ '--password', ('obfuscated', '', 'XXXXXX'), '--random'])
+ + 0,
+ ExpectShell(workdir='wkdir',
+ command=['svn', 'info', '--xml'])
+ + ExpectShell.log('stdio',
+ stdout=self.svn_info_stdout_xml)
+ + 0,
+ )
+ self.expectOutcome(result=SUCCESS, status_text=["update"])
+ return self.runStep()
+
+ def test_omit_password(self):
+ self.setupStep(
+ svn.SVN(repourl='http://svn.local/app/trunk',
+ mode='incremental', username='user',
+ extra_args=['--random']))
+ self.expectCommands(
+ ExpectShell(workdir='wkdir',
+ command=['svn', '--version'])
+ + 0,
+ Expect('stat', dict(file='wkdir/.buildbot-patched',
+ logEnviron=True))
+ + 1,
+ Expect('stat', dict(file='wkdir/.svn',
+ logEnviron=True))
+ + 0,
+ ExpectShell(workdir='wkdir',
+ command=['svn', 'info', '--xml',
+ '--non-interactive',
+ '--no-auth-cache', '--username', 'user',
+ '--random'])
+ + ExpectShell.log('stdio',
+ stdout="""http://svn.local/app/trunk""")
+ + 0,
+ ExpectShell(workdir='wkdir',
+ command=['svn', 'update', '--non-interactive',
+ '--no-auth-cache', '--username', 'user',
+ '--random'])
+ + 0,
+ ExpectShell(workdir='wkdir',
+ command=['svn', 'info', '--xml'])
+ + ExpectShell.log('stdio',
+ stdout=self.svn_info_stdout_xml)
+ + 0,
+ )
+ self.expectOutcome(result=SUCCESS, status_text=["update"])
+ return self.runStep()
+
#
# svn.SVN.svnUriCanonicalize() test method factory
diff --git a/master/docs/manual/cfg-schedulers.rst b/master/docs/manual/cfg-schedulers.rst
index d9205753246..04c74095b20 100644
--- a/master/docs/manual/cfg-schedulers.rst
+++ b/master/docs/manual/cfg-schedulers.rst
@@ -920,6 +920,11 @@ The scheduler takes the following parameters:
taken as the property name, or ``AnyPropertyParameter``, which allows the
web user to specify the property name.
+``buttonName``
+
+ The name of the "submit" button on the resulting force-build form.
+ This defaults to "Force Build".
+
An example may be better than long explanation. What you need in your config
file is something like::
diff --git a/master/docs/relnotes/index.rst b/master/docs/relnotes/index.rst
index eaf3ec8fdc7..4c97f9ad9dc 100644
--- a/master/docs/relnotes/index.rst
+++ b/master/docs/relnotes/index.rst
@@ -238,6 +238,8 @@ Features
* Systemd unit files for Buildbot are available in the :bb:src:`contrib/` directory.
+* The :bb:sched:`ForceScheduler` now takes a ``buttonName`` argument to specify the name of the button on the force-build form.
+
Forward Compatibility
~~~~~~~~~~~~~~~~~~~~~