Browse files

sample use of interface tests

  • Loading branch information...
1 parent 9cbc09a commit d761521258457518d6246b9ac653f84ccd2666ad @djmitche djmitche committed Apr 8, 2012
View
8 master/buildbot/process/buildstep.py
@@ -85,13 +85,13 @@ def run(self, step, remote):
# when our parent Step calls our .lostRemote() method.
return self.deferred
- def useLog(self, loog, closeWhenFinished=False, logfileName=None):
- assert interfaces.ILogFile.providedBy(loog)
+ def useLog(self, log, closeWhenFinished=False, logfileName=None):
+ assert interfaces.ILogFile.providedBy(log)
if not logfileName:
- logfileName = loog.getName()
+ logfileName = log.getName()
assert logfileName not in self.logs
assert logfileName not in self.delayedLogs
- self.logs[logfileName] = loog
+ self.logs[logfileName] = log
self._closeWhenFinished[logfileName] = closeWhenFinished
def useLogDelayed(self, logfileName, activateCallBack, closeWhenFinished=False):
View
7 master/buildbot/status/logfile.py
@@ -392,13 +392,10 @@ def _generateChunks(self, f, offset, remaining, leftover,
else:
yield leftover
- def readlines(self, channel=STDOUT):
+ def readlines(self):
"""Return an iterator that produces newline-terminated lines,
excluding header chunks."""
- # TODO: make this memory-efficient, by turning it into a generator
- # that retrieves chunks as necessary, like a pull-driven version of
- # twisted.protocols.basic.LineReceiver
- alltext = "".join(self.getChunks([channel], onlyText=True))
+ alltext = "".join(self.getChunks([STDOUT], onlyText=True))
io = StringIO(alltext)
return io.readlines()
View
41 master/buildbot/test/fake/remotecommand.py
@@ -16,6 +16,7 @@
from twisted.internet import defer
from twisted.python import failure
from buildbot.status.logfile import STDOUT, STDERR, HEADER
+from cStringIO import StringIO
DEFAULT_TIMEOUT="DEFAULT_TIMEOUT"
@@ -36,10 +37,10 @@ def __init__(self, remote_command, args, collectStdout=False, ignore_updates=Fal
if collectStdout:
self.stdout = ''
- def useLog(self, loog, closeWhenFinished=False, logfileName=None):
+ def useLog(self, log, closeWhenFinished=False, logfileName=None):
if not logfileName:
- logfileName = loog.getName()
- self.logs[logfileName] = loog
+ logfileName = log.getName()
+ self.logs[logfileName] = log
def useLogDelayed(self, logfileName, activateCallBack, closeWhenFinished=False):
self.delayedLogs[logfileName] = (activateCallBack, closeWhenFinished)
@@ -78,39 +79,41 @@ def __init__(self, name, step):
def getName(self):
return self.name
- def addHeader(self, data):
- self.header += data
- self.chunks.append((HEADER, data))
+ def addHeader(self, text):
+ self.header += text
+ self.chunks.append((HEADER, text))
- def addStdout(self, data):
- self.stdout += data
- self.chunks.append((STDOUT, data))
+ def addStdout(self, text):
+ self.stdout += text
+ self.chunks.append((STDOUT, text))
if self.name in self.step.logobservers:
for obs in self.step.logobservers[self.name]:
- obs.outReceived(data)
+ obs.outReceived(text)
- def addStderr(self, data):
- self.stderr += data
- self.chunks.append((STDERR, data))
+ def addStderr(self, text):
+ self.stderr += text
+ self.chunks.append((STDERR, text))
if self.name in self.step.logobservers:
for obs in self.step.logobservers[self.name]:
- obs.errReceived(data)
+ obs.errReceived(text)
- def readlines(self): # TODO: remove channel arg from logfile.py
- return self.stdout.split('\n')
+ def readlines(self):
+ io = StringIO(self.stdout)
+ return io.readlines()
def getText(self):
- return self.stdout
+ return ''.join([ c for str,c in self.chunks
+ if str in (STDOUT, STDERR)])
def getChunks(self, channels=[], onlyText=False):
if onlyText:
return [ data
for (ch, data) in self.chunks
- if ch in channels ]
+ if not channels or ch in channels ]
else:
return [ (ch, data)
for (ch, data) in self.chunks
- if ch in channels ]
+ if not channels or ch in channels ]
def finish(self):
pass
View
144 master/buildbot/test/interfaces/test_logfile.py
@@ -0,0 +1,144 @@
+# This file is part of Buildbot. Buildbot is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright Buildbot Team Members
+
+import mock
+import textwrap
+from buildbot.status import logfile
+from buildbot.test.util import interfaces, dirs
+from buildbot.test.fake import remotecommand
+from twisted.trial import unittest
+
+# NOTE:
+#
+# This interface is considered private to Buildbot and may change without
+# warning in future versions.
+
+class Tests(interfaces.InterfaceTests):
+
+ def makeLogFile(self, name='n', logfilename='nLog'):
+ raise NotImplementedError
+
+ def addLogData(self, log):
+ log.addStdout('some text with\nembedded newlines\n')
+ log.addStdout('no newlines - ')
+ log.addHeader("won't see this\n")
+ log.addStdout('newlines\n')
+ log.addStderr('also hidden')
+
+ # tests
+
+ def test_signature_getName(self):
+ log = self.makeLogFile()
+ @self.assertArgSpecMatches(log.getName)
+ def getName(self):
+ pass
+
+ def test_signature_addHeader(self):
+ log = self.makeLogFile()
+ @self.assertArgSpecMatches(log.addHeader)
+ def addHeader(self, text):
+ pass
+
+ def test_signature_addStdout(self):
+ log = self.makeLogFile()
+ @self.assertArgSpecMatches(log.addStdout)
+ def addStdout(self, text):
+ pass
+
+ def test_signature_addStderr(self):
+ log = self.makeLogFile()
+ @self.assertArgSpecMatches(log.addStderr)
+ def addStderr(self, text):
+ pass
+
+ def test_signature_readlines(self):
+ log = self.makeLogFile()
+ @self.assertArgSpecMatches(log.readlines)
+ def readlines(self):
+ pass
+
+ def test_signature_getText(self):
+ log = self.makeLogFile()
+ @self.assertArgSpecMatches(log.getText)
+ def getText(self):
+ pass
+
+ def test_signature_getChunks(self):
+ log = self.makeLogFile()
+ @self.assertArgSpecMatches(log.getChunks)
+ def getChunks(self, channels=[], onlyText=False):
+ pass
+
+ def test_signature_finish(self):
+ log = self.makeLogFile()
+ @self.assertArgSpecMatches(log.finish)
+ def finish(self):
+ pass
+
+ def test_readlines(self):
+ log = self.makeLogFile()
+ self.addLogData(log)
+ self.assertEqual(list(log.readlines()), [
+ 'some text with\n',
+ 'embedded newlines\n',
+ 'no newlines - newlines\n'
+ ''
+ ])
+
+ def test_getText(self):
+ log = self.makeLogFile()
+ self.addLogData(log)
+ self.assertEqual(log.getText(), textwrap.dedent("""\
+ some text with
+ embedded newlines
+ no newlines - newlines
+ also hidden"""))
+
+
+class RealTests(Tests):
+
+ def test_getTextWithHeaders(self):
+ log = self.makeLogFile()
+ self.addLogData(log)
+ self.assertEqual(log.getTextWithHeaders(), textwrap.dedent("""\
+ some text with
+ embedded newlines
+ no newlines - won't see this
+ newlines
+ also hidden"""))
+
+class TestLogFile(unittest.TestCase, dirs.DirsMixin, RealTests):
+
+ def setUp(self):
+ self.setUpDirs('basedir')
+
+ def tearDown(self):
+ self.tearDownDirs()
+
+ def makeLogFile(self, name='n', logfilename='nLog'):
+ # this is one reason this interface sucks:
+ parent = mock.Mock(name='fake StepStatus')
+ parent.build.builder.basedir = 'basedir'
+ return logfile.LogFile(parent, name, logfilename)
+
+
+class TestFakeLogFile(unittest.TestCase, Tests):
+
+ def makeLogFile(self, name='n', logfilename='nLog'):
+ step = mock.Mock(name='fake step')
+ step.logobservers = []
+ return remotecommand.FakeLogFile(name, step)
+
+
View
65 master/buildbot/test/interfaces/test_remotecommand.py
@@ -0,0 +1,65 @@
+# This file is part of Buildbot. Buildbot is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright Buildbot Team Members
+
+from buildbot.process import buildstep
+from buildbot.test.util import interfaces
+from buildbot.test.fake import remotecommand
+from twisted.trial import unittest
+
+# NOTE:
+#
+# This interface is considered private to Buildbot and may change without
+# warning in future versions.
+
+class Tests(interfaces.InterfaceTests):
+
+ def makeRemoteCommand(self, name, args):
+ raise NotImplementedError
+
+ def test_signature_useLog(self):
+ rc = self.makeRemoteCommand('ping', {'arg':'val'})
+ @self.assertArgSpecMatches(rc.useLog)
+ def useLog(self, log, closeWhenFinished=False, logfileName=None):
+ pass
+
+ def test_signature_useLogDelayed(self):
+ rc = self.makeRemoteCommand('ping', {'arg':'val'})
+ @self.assertArgSpecMatches(rc.useLogDelayed)
+ def useLogDelayed(self, logfileName, activateCallBack,
+ closeWhenFinished=False):
+ pass
+
+ def test_signature_run(self):
+ rc = self.makeRemoteCommand('ping', {'arg':'val'})
+ @self.assertArgSpecMatches(rc.run)
+ def run(self, step, remote):
+ pass
+
+
+class RealTests(Tests):
+ pass
+
+
+class TestRunCommand(unittest.TestCase, RealTests):
+
+ def makeRemoteCommand(self, name, args):
+ return buildstep.RemoteCommand(name, args)
+
+
+class TestFakeRunCommand(unittest.TestCase, Tests):
+
+ def makeRemoteCommand(self, name, args):
+ return remotecommand.FakeRemoteCommand(name, args)
+
View
1 master/buildbot/test/util/interfaces.py
@@ -28,4 +28,5 @@ def wrap(template):
inspect.formatargspec(*template_argspec),
inspect.formatargspec(*actual_argspec))
self.fail(msg)
+ return template # just in case it's useful
return wrap

0 comments on commit d761521

Please sign in to comment.