Skip to content

Commit

Permalink
remotecommand: parameterize the name of the stdio logfile
Browse files Browse the repository at this point in the history
this commits permits to record the name of the stdio used
by one remotecommand into a logfile different than 'stdio'.

Signed-off-by: Ion Alberdi <ion.alberdi@intel.com>
  • Loading branch information
Ion Alberdi committed Jan 23, 2014
1 parent edcdff3 commit 89033fc
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 30 deletions.
22 changes: 13 additions & 9 deletions master/buildbot/process/buildstep.py
Expand Up @@ -961,26 +961,29 @@ def bad(arg):

@defer.inlineCallbacks
def makeRemoteShellCommand(self, collectStdout=False, collectStderr=False,
stdioLogName='stdio',
**overrides):
kwargs = dict([(arg, getattr(self, arg))
for arg in self._shellMixinArgs])
kwargs.update(overrides)

stdio = yield self.addLog('stdio')

stdio = None
if stdioLogName is not None:
stdio = yield self.addLog(stdioLogName)
kwargs['command'] = flatten(kwargs['command'], (list, tuple))

# check for the usePTY flag
if kwargs['usePTY'] != 'slave-config':
if self.slaveVersionIsOlderThan("shell", "2.7"):
yield stdio.addHeader(
"NOTE: slave does not allow master to override usePTY\n")
if stdio is not None:
yield stdio.addHeader(
"NOTE: slave does not allow master to override usePTY\n")
del kwargs['usePTY']

# check for the interruptSignal flag
if kwargs["interruptSignal"] and self.slaveVersionIsOlderThan("shell", "2.15"):
yield stdio.addHeader(
"NOTE: slave does not allow master to specify interruptSignal\n")
if stdio is not None:
yield stdio.addHeader(
"NOTE: slave does not allow master to specify interruptSignal\n")
del kwargs['interruptSignal']

# lazylogfiles are handled below
Expand All @@ -990,7 +993,7 @@ def makeRemoteShellCommand(self, collectStdout=False, collectStderr=False,
builderEnv = self.build.builder.config.env
kwargs['env'] = yield self.build.render(builderEnv)
kwargs['env'].update(self.env)

kwargs['stdioLogName'] = stdioLogName
# default the workdir appropriately
if not self.workdir:
if callable(self.build.workdir):
Expand All @@ -1002,7 +1005,8 @@ def makeRemoteShellCommand(self, collectStdout=False, collectStderr=False,
cmd = remotecommand.RemoteShellCommand(**kwargs)

# set up logging
cmd.useLog(stdio, False)
if stdio is not None:
cmd.useLog(stdio, False)
for logname, remotefilename in self.logfiles.items():
if self.lazylogfiles:
# TODO/XXX: addLog's async.. refactor this whole thing
Expand Down
23 changes: 13 additions & 10 deletions master/buildbot/process/remotecommand.py
Expand Up @@ -35,7 +35,8 @@ class RemoteCommand(pb.Referenceable):
debug = False

def __init__(self, remote_command, args, ignore_updates=False,
collectStdout=False, collectStderr=False, decodeRC={0: SUCCESS}):
collectStdout=False, collectStderr=False, decodeRC={0: SUCCESS},
stdioLogName='stdio'):
self.logs = {}
self.delayedLogs = {}
self._closeWhenFinished = {}
Expand All @@ -44,7 +45,7 @@ def __init__(self, remote_command, args, ignore_updates=False,
self.stdout = ''
self.stderr = ''
self.updates = {}

self.stdioLogName = stdioLogName
self._startTime = None
self._remoteElapsed = None
self.remote_command = remote_command
Expand Down Expand Up @@ -193,20 +194,20 @@ def remote_complete(self, failure=None):
return None

def addStdout(self, data):
if 'stdio' in self.logs:
self.logs['stdio'].addStdout(data)
if self.stdioLogName is not None and self.stdioLogName in self.logs:
self.logs[self.stdioLogName].addStdout(data)
if self.collectStdout:
self.stdout += data

def addStderr(self, data):
if 'stdio' in self.logs:
self.logs['stdio'].addStderr(data)
if self.stdioLogName is not None and self.stdioLogName in self.logs:
self.logs[self.stdioLogName].addStderr(data)
if self.collectStderr:
self.stderr += data

def addHeader(self, data):
if 'stdio' in self.logs:
self.logs['stdio'].addHeader(data)
if self.stdioLogName is not None and self.stdioLogName in self.logs:
self.logs[self.stdioLogName].addHeader(data)

def addToLog(self, logname, data):
# Activate delayed logs on first data.
Expand Down Expand Up @@ -286,7 +287,8 @@ def __init__(self, workdir, command, env=None,
logfiles={}, usePTY="slave-config", logEnviron=True,
collectStdout=False, collectStderr=False,
interruptSignal=None,
initialStdin=None, decodeRC={0: SUCCESS}):
initialStdin=None, decodeRC={0: SUCCESS},
stdioLogName='stdio'):

self.command = command # stash .command, set it later
if isinstance(self.command, basestring):
Expand Down Expand Up @@ -322,7 +324,8 @@ def obfuscate(arg):
args['interruptSignal'] = interruptSignal
RemoteCommand.__init__(self, "shell", args, collectStdout=collectStdout,
collectStderr=collectStderr,
decodeRC=decodeRC)
decodeRC=decodeRC,
stdioLogName=stdioLogName)

def _start(self):
self.args['command'] = self.command
Expand Down
6 changes: 2 additions & 4 deletions master/buildbot/steps/shellsequence.py
Expand Up @@ -99,10 +99,8 @@ def runShellSequence(self, commands):
# stick the command in self.command so that describe can use it
self.command = command

# TODO/XXX: logfile arg is ignored, because RemoteCommand will
# always log standard streams to the log named 'stdio'

cmd = yield self.makeRemoteShellCommand(command=command)
cmd = yield self.makeRemoteShellCommand(command=command,
stdioLogName=arg.logfile)
yield self.runCommand(cmd)
overall_result, terminate = results.computeResultAndTermination(
arg, cmd.results(), overall_result)
Expand Down
10 changes: 7 additions & 3 deletions master/buildbot/test/fake/remotecommand.py
Expand Up @@ -29,7 +29,8 @@ class FakeRemoteCommand(object):

def __init__(self, remote_command, args,
ignore_updates=False, collectStdout=False, collectStderr=False,
decodeRC={0: SUCCESS}):
decodeRC={0: SUCCESS},
stdioLogName='stdio'):
# copy the args and set a few defaults
self.remote_command = remote_command
self.args = args.copy()
Expand All @@ -40,6 +41,7 @@ def __init__(self, remote_command, args,
self.collectStderr = collectStderr
self.updates = {}
self.decodeRC = decodeRC
self.stdioLogName = stdioLogName
if collectStdout:
self.stdout = ''
if collectStderr:
Expand Down Expand Up @@ -84,7 +86,8 @@ def __init__(self, workdir, command, env=None,
timeout=20 * 60, maxTime=None, sigtermTime=None, logfiles={},
usePTY="slave-config", logEnviron=True, collectStdout=False,
collectStderr=False,
interruptSignal=None, initialStdin=None, decodeRC={0: SUCCESS}):
interruptSignal=None, initialStdin=None, decodeRC={0: SUCCESS},
stdioLogName='stdio'):
args = dict(workdir=workdir, command=command, env=env or {},
want_stdout=want_stdout, want_stderr=want_stderr,
initial_stdin=initialStdin,
Expand All @@ -93,7 +96,8 @@ def __init__(self, workdir, command, env=None,
FakeRemoteCommand.__init__(self, "shell", args,
collectStdout=collectStdout,
collectStderr=collectStderr,
decodeRC=decodeRC)
decodeRC=decodeRC,
stdioLogName=stdioLogName)


class ExpectRemoteRef(object):
Expand Down
24 changes: 20 additions & 4 deletions master/buildbot/test/unit/test_remotecommand.py
Expand Up @@ -16,6 +16,7 @@
from buildbot.process import remotecommand
from buildbot.status.results import SUCCESS
from buildbot.test.fake import remotecommand as fakeremotecommand
from buildbot.test.fake import logfile
from buildbot.test.util import interfaces
from twisted.trial import unittest

Expand All @@ -29,14 +30,16 @@ class Tests(interfaces.InterfaceTests):

remoteCommandClass = None

def makeRemoteCommand(self):
return self.remoteCommandClass('ping', {'arg': 'val'})
def makeRemoteCommand(self, stdioLogName='stdio'):
return self.remoteCommandClass('ping', {'arg': 'val'},
stdioLogName=stdioLogName)

def test_signature_RemoteCommand_constructor(self):
@self.assertArgSpecMatches(self.remoteCommandClass.__init__)
def __init__(self, remote_command, args, ignore_updates=False,
collectStdout=False, collectStderr=False,
decodeRC={0: SUCCESS}):
decodeRC={0: SUCCESS},
stdioLogName='stdio'):
pass

def test_signature_RemoteShellCommand_constructor(self):
Expand All @@ -45,7 +48,8 @@ def __init__(self, workdir, command, env=None, want_stdout=1,
want_stderr=1, timeout=20 * 60, maxTime=None, sigtermTime=None, logfiles={},
usePTY="slave-config", logEnviron=True, collectStdout=False,
collectStderr=False, interruptSignal=None, initialStdin=None,
decodeRC={0: SUCCESS}):
decodeRC={0: SUCCESS},
stdioLogName='stdio'):
pass

def test_signature_run(self):
Expand Down Expand Up @@ -101,6 +105,18 @@ class TestRunCommand(unittest.TestCase, Tests):
remoteCommandClass = remotecommand.RemoteCommand
remoteShellCommandClass = remotecommand.RemoteShellCommand

def test_notStdioLog(self):
logname = 'notstdio'
cmd = self.makeRemoteCommand(stdioLogName=logname)
log = logfile.FakeLogFile(logname, 'dummy')
cmd.useLog(log)
cmd.addStdout('some stdout')
self.failUnlessEqual(log.stdout, 'some stdout')
cmd.addStderr('some stderr')
self.failUnlessEqual(log.stderr, 'some stderr')
cmd.addHeader('some header')
self.failUnlessEqual(log.header, 'some header')


class TestFakeRunCommand(unittest.TestCase, Tests):

Expand Down

0 comments on commit 89033fc

Please sign in to comment.