Ejemplo n.º 1
0
    def test_file_logging_rotation_5_files(self):
        """
        Only 5 logfiles are kept.
        """
        logfile = FilePath(self.mktemp()).child('foo.log')
        logfile.parent().makedirs()
        # This file will become foo.log.1
        with logfile.open('w') as f:
            f.write(b'0')
            f.truncate(int(MiB(100).to_Byte().value))
        # These file extensions will be incremented
        for i in range(1, 5):
            sibling = logfile.sibling(logfile.basename() + u'.' + unicode(i))
            with sibling.open('w') as f:
                f.write(bytes(i))

        d = self.run_script(EliotScript, options=['--logfile', logfile.path])

        def verify_logfiles(stdout_messages, logfile):
            logfile_dir = logfile.parent()
            self.assertEqual(
                # The contents of the files will now be an integer one less
                # than the integer in the file name.
                map(bytes, range(0, 4)),
                list(
                    logfile_dir.child('foo.log.{}'.format(i)).open().read(1)
                    for i in range(1, 5)))

        d.addCallback(verify_logfiles, logfile=logfile)

        return d
Ejemplo n.º 2
0
    def test_file_logging_rotation_5_files(self):
        """
        Only 5 logfiles are kept.
        """
        logfile = FilePath(self.mktemp()).child('foo.log')
        logfile.parent().makedirs()
        # This file will become foo.log.1
        with logfile.open('w') as f:
            f.write(b'0')
            f.truncate(int(MiB(100).to_Byte().value))
        # These file extensions will be incremented
        for i in range(1, 5):
            sibling = logfile.sibling(logfile.basename() + u'.' + unicode(i))
            with sibling.open('w') as f:
                f.write(bytes(i))

        d = self.run_script(EliotScript, options=['--logfile', logfile.path])

        def verify_logfiles(stdout_messages, logfile):
            logfile_dir = logfile.parent()
            self.assertEqual(
                # The contents of the files will now be an integer one less
                # than the integer in the file name.
                map(bytes, range(0, 4)),
                list(
                    logfile_dir.child('foo.log.{}'.format(i)).open().read(1)
                    for i
                    in range(1, 5)
                )
            )
        d.addCallback(verify_logfiles, logfile=logfile)

        return d
Ejemplo n.º 3
0
    def test_renamedSource(self):
        """
        Warnings emitted by a function defined in a file which has been renamed
        since it was initially compiled can still be flushed.

        This is testing the code which specifically supports working around the
        unfortunate behavior of CPython to write a .py source file name into
        the .pyc files it generates and then trust that it is correct in
        various places.  If source files are renamed, .pyc files may not be
        regenerated, but they will contain incorrect filenames.
        """
        package = FilePath(self.mktemp().encode("utf-8")).child(
            b"twisted_private_helper"
        )
        package.makedirs()
        package.child(b"__init__.py").setContent(b"")
        package.child(b"module.py").setContent(
            b"""
import warnings
def foo():
    warnings.warn("oh no")
"""
        )
        pathEntry = package.parent().path.decode("utf-8")
        sys.path.insert(0, pathEntry)
        self.addCleanup(sys.path.remove, pathEntry)

        # Import it to cause pycs to be generated
        from twisted_private_helper import module

        # Clean up the state resulting from that import; we're not going to use
        # this module, so it should go away.
        del sys.modules["twisted_private_helper"]
        del sys.modules[module.__name__]

        # Some Python versions have extra state related to the just
        # imported/renamed package.  Clean it up too.  See also
        # http://bugs.python.org/issue15912
        try:
            from importlib import invalidate_caches
        except ImportError:
            pass
        else:
            invalidate_caches()

        # Rename the source directory
        package.moveTo(package.sibling(b"twisted_renamed_helper"))

        # Import the newly renamed version
        from twisted_renamed_helper import module  # type: ignore[import]

        self.addCleanup(sys.modules.pop, "twisted_renamed_helper")
        self.addCleanup(sys.modules.pop, module.__name__)

        # Generate the warning
        module.foo()

        # Flush it
        self.assertEqual(len(self.flushWarnings([module.foo])), 1)
Ejemplo n.º 4
0
class TitleExtractionTests(unittest.TestCase):
    """
    Tests for title extraction in L{eridanusstd.linkdb}.
    """
    def setUp(self):
        self.path = FilePath(__file__)

    def test_extractTitle(self):
        data = self.path.sibling('index.html').open().read()
        self.assertEquals(linkdb._extractTitle(data), u'Google')
    def test_renamedSource(self):
        """
        Warnings emitted by a function defined in a file which has been renamed
        since it was initially compiled can still be flushed.

        This is testing the code which specifically supports working around the
        unfortunate behavior of CPython to write a .py source file name into
        the .pyc files it generates and then trust that it is correct in
        various places.  If source files are renamed, .pyc files may not be
        regenerated, but they will contain incorrect filenames.
        """
        package = FilePath(self.mktemp().encode('utf-8')).child(b'twisted_private_helper')
        package.makedirs()
        package.child(b'__init__.py').setContent(b'')
        package.child(b'module.py').setContent(b'''
import warnings
def foo():
    warnings.warn("oh no")
''')
        pathEntry = package.parent().path.decode('utf-8')
        sys.path.insert(0, pathEntry)
        self.addCleanup(sys.path.remove, pathEntry)

        # Import it to cause pycs to be generated
        from twisted_private_helper import module

        # Clean up the state resulting from that import; we're not going to use
        # this module, so it should go away.
        del sys.modules['twisted_private_helper']
        del sys.modules[module.__name__]

        # Some Python versions have extra state related to the just
        # imported/renamed package.  Clean it up too.  See also
        # http://bugs.python.org/issue15912
        try:
            from importlib import invalidate_caches
        except ImportError:
            pass
        else:
            invalidate_caches()

        # Rename the source directory
        package.moveTo(package.sibling(b'twisted_renamed_helper'))

        # Import the newly renamed version
        from twisted_renamed_helper import module
        self.addCleanup(sys.modules.pop, 'twisted_renamed_helper')
        self.addCleanup(sys.modules.pop, module.__name__)

        # Generate the warning
        module.foo()

        # Flush it
        self.assertEqual(len(self.flushWarnings([module.foo])), 1)
Ejemplo n.º 6
0
class TitleExtractionTests(unittest.TestCase):
    """
    Tests for title extraction in L{eridanusstd.linkdb}.
    """
    def setUp(self):
        self.path = FilePath(__file__)


    def test_extractTitle(self):
        data = self.path.sibling('index.html').open().read()
        self.assertEquals(
            linkdb._extractTitle(data),
            u'Google')
Ejemplo n.º 7
0
class TwitterTestsMixin(object):
    """
    Mixin for Twitter tests.
    """
    def setUp(self):
        self.path = FilePath(__file__)
        self.store = Store()
        self.plugin = twitter_plugin.Twitter(store=self.store)


    def objectify(self, filename):
        """
        Read XML, from a file, and parse it with C{lxml.objectify}.
        """
        return lxml.objectify.fromstring(
            self.path.sibling(filename).getContent())
Ejemplo n.º 8
0
class CalculatorTests(unittest.TestCase):
    """
    Tests for L{eridanusstd.google.Calculator}.
    """
    def setUp(self):
        self.path = FilePath(__file__)
        self.calc = google.Calculator()
        self.fetchData = None
        self.patch(self.calc, '_fetch', self._fetch)


    def _fetch(self, url):
        """
        Patch L{eridanusstd.google.Calculator._fetch} to avoid network traffic.
        """
        return succeed((self.fetchData, dict()))


    def test_evaluateGood(self):
        """
        Evaluating a valid calculator expression yields a result.
        """
        def testExpression(filename, expected):
            self.fetchData = self.path.sibling(filename).open().read()
            # The value to evaluate is irrelevant since the page data comes
            # from "filename".
            d = self.calc.evaluate('an expression goes here')
            def checkResult(res):
                self.assertEquals(res, expected)
            return d.addCallback(checkResult)

        return gatherResults([
            testExpression('google_calc.html', u'sqrt(2 / (((((pi * 18 000) / (mi^2)) * 80) / year) * (30 minutes))) = 141.683342 meters'),
            testExpression('google_calc_2.html', u'1 googol = 1.0 \xd7 10^100')])


    def test_evaluateBad(self):
        """
        Evaluating expressions that do not yield a calculator result raise
        L{eridanusstd.errors.InvalidExpression}.
        """
        self.fetchData = FilePath(__file__).sibling(
            'google_calc_bad.html').open().read()
        d = self.calc.evaluate('davy jones')
        self.assertFailure(d, errors.InvalidExpression)
        return d
Ejemplo n.º 9
0
class UtilTests(TestCase):
    """
    Tests for L{eridanusstd.util}.
    """
    def setUp(self):
        self.path = FilePath(__file__)

    def test_parseHTML(self):
        """
        L{eridanusstd.util.parseHTML} will use the newer html5lib API if
        available and parse HTML content into an LXML element tree.
        """
        if not hasattr(html5lib, 'parse'):
            raise SkipTest('html5lib is too old')

        tree = util.parseHTML(self.path.sibling('index.html').open())
        self.assertIdentical(type(tree), type(etree.ElementTree()))
Ejemplo n.º 10
0
    def test_renamedSource(self):
        """
        Warnings emitted by a function defined in a file which has been renamed
        since it was initially compiled can still be flushed.

        This is testing the code which specifically supports working around the
        unfortunate behavior of CPython to write a .py source file name into
        the .pyc files it generates and then trust that it is correct in
        various places.  If source files are renamed, .pyc files may not be
        regenerated, but they will contain incorrect filenames.
        """
        package = FilePath(self.mktemp()).child('twisted_private_helper')
        package.makedirs()
        package.child('__init__.py').setContent('')
        package.child('module.py').setContent('''
import warnings
def foo():
    warnings.warn("oh no")
''')
        sys.path.insert(0, package.parent().path)
        self.addCleanup(sys.path.remove, package.parent().path)

        # Import it to cause pycs to be generated
        from twisted_private_helper import module

        # Clean up the state resulting from that import; we're not going to use
        # this module, so it should go away.
        del sys.modules['twisted_private_helper']
        del sys.modules[module.__name__]

        # Rename the source directory
        package.moveTo(package.sibling('twisted_renamed_helper'))

        # Import the newly renamed version
        from twisted_renamed_helper import module
        self.addCleanup(sys.modules.pop, 'twisted_renamed_helper')
        self.addCleanup(sys.modules.pop, module.__name__)

        # Generate the warning
        module.foo()

        # Flush it
        self.assertEqual(len(self.flushWarnings([module.foo])), 1)
Ejemplo n.º 11
0
class WarnAboutFunctionTests(SynchronousTestCase):
    """
    Tests for L{twisted.python.deprecate.warnAboutFunction} which allows the
    callers of a function to issue a C{DeprecationWarning} about that function.
    """
    def setUp(self):
        """
        Create a file that will have known line numbers when emitting warnings.
        """
        self.package = FilePath(self.mktemp().encode("utf-8")
                                ).child(b'twisted_private_helper')
        self.package.makedirs()
        self.package.child(b'__init__.py').setContent(b'')
        self.package.child(b'module.py').setContent(b'''
"A module string"

from twisted.python import deprecate

def testFunction():
    "A doc string"
    a = 1 + 2
    return a

def callTestFunction():
    b = testFunction()
    if b == 3:
        deprecate.warnAboutFunction(testFunction, "A Warning String")
''')
        # Python 3 doesn't accept bytes in sys.path:
        packagePath = self.package.parent().path.decode("utf-8")
        sys.path.insert(0, packagePath)
        self.addCleanup(sys.path.remove, packagePath)

        modules = sys.modules.copy()
        self.addCleanup(
            lambda: (sys.modules.clear(), sys.modules.update(modules)))

        # On Windows on Python 3, most FilePath interactions produce
        # DeprecationWarnings, so flush them here so that they don't interfere
        # with the tests.
        if platform.isWindows() and _PY3:
            self.flushWarnings()


    def test_warning(self):
        """
        L{deprecate.warnAboutFunction} emits a warning the file and line number
        of which point to the beginning of the implementation of the function
        passed to it.
        """
        def aFunc():
            pass
        deprecate.warnAboutFunction(aFunc, 'A Warning Message')
        warningsShown = self.flushWarnings()
        filename = __file__
        if filename.lower().endswith('.pyc'):
            filename = filename[:-1]
        self.assertSamePath(
            FilePath(warningsShown[0]["filename"]), FilePath(filename))
        self.assertEqual(warningsShown[0]["message"], "A Warning Message")


    def test_warningLineNumber(self):
        """
        L{deprecate.warnAboutFunction} emits a C{DeprecationWarning} with the
        number of a line within the implementation of the function passed to it.
        """
        from twisted_private_helper import module
        module.callTestFunction()
        warningsShown = self.flushWarnings()
        self.assertSamePath(
            FilePath(warningsShown[0]["filename"].encode("utf-8")),
            self.package.sibling(b'twisted_private_helper').child(b'module.py'))
        # Line number 9 is the last line in the testFunction in the helper
        # module.
        self.assertEqual(warningsShown[0]["lineno"], 9)
        self.assertEqual(warningsShown[0]["message"], "A Warning String")
        self.assertEqual(len(warningsShown), 1)


    def assertSamePath(self, first, second):
        """
        Assert that the two paths are the same, considering case normalization
        appropriate for the current platform.

        @type first: L{FilePath}
        @type second: L{FilePath}

        @raise C{self.failureType}: If the paths are not the same.
        """
        self.assertTrue(
            normcase(first.path) == normcase(second.path),
            "%r != %r" % (first, second))


    def test_renamedFile(self):
        """
        Even if the implementation of a deprecated function is moved around on
        the filesystem, the line number in the warning emitted by
        L{deprecate.warnAboutFunction} points to a line in the implementation of
        the deprecated function.
        """
        from twisted_private_helper import module
        # Clean up the state resulting from that import; we're not going to use
        # this module, so it should go away.
        del sys.modules['twisted_private_helper']
        del sys.modules[module.__name__]

        # Rename the source directory
        self.package.moveTo(self.package.sibling(b'twisted_renamed_helper'))

        # Make sure importlib notices we've changed importable packages:
        if invalidate_caches:
            invalidate_caches()

        # Import the newly renamed version
        from twisted_renamed_helper import module
        self.addCleanup(sys.modules.pop, 'twisted_renamed_helper')
        self.addCleanup(sys.modules.pop, module.__name__)

        module.callTestFunction()
        warningsShown = self.flushWarnings([module.testFunction])
        warnedPath = FilePath(warningsShown[0]["filename"].encode("utf-8"))
        expectedPath = self.package.sibling(
            b'twisted_renamed_helper').child(b'module.py')
        self.assertSamePath(warnedPath, expectedPath)
        self.assertEqual(warningsShown[0]["lineno"], 9)
        self.assertEqual(warningsShown[0]["message"], "A Warning String")
        self.assertEqual(len(warningsShown), 1)


    def test_filteredWarning(self):
        """
        L{deprecate.warnAboutFunction} emits a warning that will be filtered if
        L{warnings.filterwarning} is called with the module name of the
        deprecated function.
        """
        # Clean up anything *else* that might spuriously filter out the warning,
        # such as the "always" simplefilter set up by unittest._collectWarnings.
        # We'll also rely on trial to restore the original filters afterwards.
        del warnings.filters[:]

        warnings.filterwarnings(
            action="ignore", module="twisted_private_helper")

        from twisted_private_helper import module
        module.callTestFunction()

        warningsShown = self.flushWarnings()
        self.assertEqual(len(warningsShown), 0)


    def test_filteredOnceWarning(self):
        """
        L{deprecate.warnAboutFunction} emits a warning that will be filtered
        once if L{warnings.filterwarning} is called with the module name of the
        deprecated function and an action of once.
        """
        # Clean up anything *else* that might spuriously filter out the warning,
        # such as the "always" simplefilter set up by unittest._collectWarnings.
        # We'll also rely on trial to restore the original filters afterwards.
        del warnings.filters[:]

        warnings.filterwarnings(
            action="module", module="twisted_private_helper")

        from twisted_private_helper import module
        module.callTestFunction()
        module.callTestFunction()

        warningsShown = self.flushWarnings()
        self.assertEqual(len(warningsShown), 1)
        message = warningsShown[0]['message']
        category = warningsShown[0]['category']
        filename = warningsShown[0]['filename']
        lineno = warningsShown[0]['lineno']
        msg = warnings.formatwarning(message, category, filename, lineno)
        self.assertTrue(
            msg.endswith("module.py:9: DeprecationWarning: A Warning String\n"
                         "  return a\n"),
            "Unexpected warning string: %r" % (msg,))
Ejemplo n.º 12
0
class WarnAboutFunctionTests(SynchronousTestCase):
    """
    Tests for L{twisted.python.deprecate.warnAboutFunction} which allows the
    callers of a function to issue a C{DeprecationWarning} about that function.
    """
    def setUp(self):
        """
        Create a file that will have known line numbers when emitting warnings.
        """
        self.package = FilePath(
            self.mktemp().encode("utf-8")).child(b'twisted_private_helper')
        self.package.makedirs()
        self.package.child(b'__init__.py').setContent(b'')
        self.package.child(b'module.py').setContent(b'''
"A module string"

from twisted.python import deprecate

def testFunction():
    "A doc string"
    a = 1 + 2
    return a

def callTestFunction():
    b = testFunction()
    if b == 3:
        deprecate.warnAboutFunction(testFunction, "A Warning String")
''')
        # Python 3 doesn't accept bytes in sys.path:
        packagePath = self.package.parent().path.decode("utf-8")
        sys.path.insert(0, packagePath)
        self.addCleanup(sys.path.remove, packagePath)

        modules = sys.modules.copy()
        self.addCleanup(lambda:
                        (sys.modules.clear(), sys.modules.update(modules)))

    def test_warning(self):
        """
        L{deprecate.warnAboutFunction} emits a warning the file and line number
        of which point to the beginning of the implementation of the function
        passed to it.
        """
        def aFunc():
            pass

        deprecate.warnAboutFunction(aFunc, 'A Warning Message')
        warningsShown = self.flushWarnings()
        filename = __file__
        if filename.lower().endswith('.pyc'):
            filename = filename[:-1]
        self.assertSamePath(FilePath(warningsShown[0]["filename"]),
                            FilePath(filename))
        self.assertEqual(warningsShown[0]["message"], "A Warning Message")

    def test_warningLineNumber(self):
        """
        L{deprecate.warnAboutFunction} emits a C{DeprecationWarning} with the
        number of a line within the implementation of the function passed to it.
        """
        from twisted_private_helper import module
        module.callTestFunction()
        warningsShown = self.flushWarnings()
        self.assertSamePath(
            FilePath(warningsShown[0]["filename"].encode("utf-8")),
            self.package.sibling(b'twisted_private_helper').child(
                b'module.py'))
        # Line number 9 is the last line in the testFunction in the helper
        # module.
        self.assertEqual(warningsShown[0]["lineno"], 9)
        self.assertEqual(warningsShown[0]["message"], "A Warning String")
        self.assertEqual(len(warningsShown), 1)

    def assertSamePath(self, first, second):
        """
        Assert that the two paths are the same, considering case normalization
        appropriate for the current platform.

        @type first: L{FilePath}
        @type second: L{FilePath}

        @raise C{self.failureType}: If the paths are not the same.
        """
        self.assertTrue(
            normcase(first.path) == normcase(second.path),
            "%r != %r" % (first, second))

    def test_renamedFile(self):
        """
        Even if the implementation of a deprecated function is moved around on
        the filesystem, the line number in the warning emitted by
        L{deprecate.warnAboutFunction} points to a line in the implementation of
        the deprecated function.
        """
        from twisted_private_helper import module
        # Clean up the state resulting from that import; we're not going to use
        # this module, so it should go away.
        del sys.modules['twisted_private_helper']
        del sys.modules[module.__name__]

        # Rename the source directory
        self.package.moveTo(self.package.sibling(b'twisted_renamed_helper'))

        # Make sure importlib notices we've changed importable packages:
        if invalidate_caches:
            invalidate_caches()

        # Import the newly renamed version
        from twisted_renamed_helper import module
        self.addCleanup(sys.modules.pop, 'twisted_renamed_helper')
        self.addCleanup(sys.modules.pop, module.__name__)

        module.callTestFunction()
        warningsShown = self.flushWarnings()
        warnedPath = FilePath(warningsShown[0]["filename"].encode("utf-8"))
        expectedPath = self.package.sibling(b'twisted_renamed_helper').child(
            b'module.py')
        self.assertSamePath(warnedPath, expectedPath)
        self.assertEqual(warningsShown[0]["lineno"], 9)
        self.assertEqual(warningsShown[0]["message"], "A Warning String")
        self.assertEqual(len(warningsShown), 1)

    def test_filteredWarning(self):
        """
        L{deprecate.warnAboutFunction} emits a warning that will be filtered if
        L{warnings.filterwarning} is called with the module name of the
        deprecated function.
        """
        # Clean up anything *else* that might spuriously filter out the warning,
        # such as the "always" simplefilter set up by unittest._collectWarnings.
        # We'll also rely on trial to restore the original filters afterwards.
        del warnings.filters[:]

        warnings.filterwarnings(action="ignore",
                                module="twisted_private_helper")

        from twisted_private_helper import module
        module.callTestFunction()

        warningsShown = self.flushWarnings()
        self.assertEqual(len(warningsShown), 0)

    def test_filteredOnceWarning(self):
        """
        L{deprecate.warnAboutFunction} emits a warning that will be filtered
        once if L{warnings.filterwarning} is called with the module name of the
        deprecated function and an action of once.
        """
        # Clean up anything *else* that might spuriously filter out the warning,
        # such as the "always" simplefilter set up by unittest._collectWarnings.
        # We'll also rely on trial to restore the original filters afterwards.
        del warnings.filters[:]

        warnings.filterwarnings(action="module",
                                module="twisted_private_helper")

        from twisted_private_helper import module
        module.callTestFunction()
        module.callTestFunction()

        warningsShown = self.flushWarnings()
        self.assertEqual(len(warningsShown), 1)
        message = warningsShown[0]['message']
        category = warningsShown[0]['category']
        filename = warningsShown[0]['filename']
        lineno = warningsShown[0]['lineno']
        msg = warnings.formatwarning(message, category, filename, lineno)
        self.assertTrue(
            msg.endswith("module.py:9: DeprecationWarning: A Warning String\n"
                         "  return a\n"),
            "Unexpected warning string: %r" % (msg, ))
Ejemplo n.º 13
0
class FeedUpdatesTests(unittest.TestCase):
    """
    Tests for L{eridanusstd.feedupdates} and
    L{eridanusstd.plugindefs.feedupdates}.
    """
    def setUp(self):
        self.path = FilePath(__file__)
        self.store = Store()
        self.plugin = feedupdates_plugin.FeedUpdates(store=self.store)
        object.__setattr__(
            self.plugin, 'superfeedrService', MockSuperfeedrService())
        self.source = MockSource(u'#quux')


    def test_subscribe(self):
        """
        Subscribing to a feed creates a L{SubscribedFeed} item with the
        appropriate attributes. Invalid values for the C{formatting} argument
        raise C{ValueError} and attempting to subscribe to the same feed twice
        from the same subscription source (e.g. an IRC channel) results in
        L{eridanusstd.errors.InvalidIdentifier} being raised.
        """
        self.assertRaises(ValueError,
            self.plugin.subscribe, self.source, u'wrong', u'url', u'not_valid')

        d = self.plugin.subscribe(self.source, u'foo', u'url', u'title')

        @d.addCallback
        def checkSubscription(sub):
            self.assertEquals(sub.id, u'foo')
            self.assertEquals(sub.url, u'url')
            self.assertEquals(sub.formatting, u'title')
            self.assertIdentical(sub.source, self.source)

        @d.addCallback
        def disallowDupes(dummy):
            self.assertRaises(errors.InvalidIdentifier,
                self.plugin.subscribe, self.source, u'foo', u'url', u'title')

        return d


    def test_unsubscribe(self):
        """
        Unsubscribing deletes the relevant L{SubscribedFeed} item. Attempting
        to unsubscribe from a nonexistant feed raises
        L{eridanusstd.errors.InvalidIdentifier}.
        """
        self.assertRaises(errors.InvalidIdentifier,
            self.plugin.unsubscribe, self.source, u'wrong')

        d = self.plugin.subscribe(self.source, u'foo', u'url', u'title')

        @d.addCallback
        def unsubscribeIt(sub):
            d = self.plugin.unsubscribe(self.source, u'foo')
            d.addCallback(lambda dummy: sub)
            return d

        @d.addCallback
        def unsubscibed(sub):
            self.assertIdentical(sub._unsubscribe, None)
            self.assertRaises(errors.InvalidIdentifier,
                self.plugin.unsubscribe, self.source, u'foo')

        return d


    def test_getSubscription(self):
        """
        L{FeedUpdates.getSubscription} finds
        the single subscription with the specified identifier attributed to the
        specified feed subscriber. L{FeedUpdates.getSubscriptions} retrieves
        all feeds for a given subsciber.
        """
        self.assertIdentical(
            self.plugin.getSubscription(u'notthere', self.source.channel),
            None)

        subs = []
        d = self.plugin.subscribe(self.source, u'foo', u'url', u'title')

        @d.addCallback
        def subscribed(sub):
            subs.append(sub)
            self.assertIdentical(
                self.plugin.getSubscription(u'foo', self.source.channel),
                sub)
            return self.plugin.subscribe(self.source, u'bar', u'url', u'title')


        @d.addCallback
        def subscribedAgain(sub):
            subs.append(sub)
            subs.sort(key=lambda s: s.id)
            self.assertEquals(
                list(self.plugin.getSubscriptions(self.source.channel)),
                subs)

        return d


    def parse(self, path):
        """
        Parse the XML document at C{path} into a C{list} of C{domish} objects.
        """
        elements = []
        stream = domish.ExpatElementStream()
        stream.DocumentStartEvent = lambda root: None
        stream.DocumentEndEvent = lambda: None
        stream.ElementEvent = elements.append
        stream.parse(path.open().read())
        return elements


    def test_itemsReceived(self):
        """
        C{FeedUpdates.itemsReceived} is called with some Superfeedr item domish
        instances, which then triggers C{source.notice}.
        """
        elements = self.parse(self.path.sibling('feedupdates_1.xml'))
        items = elements[0].elements(
            uri=u'http://jabber.org/protocol/pubsub#event', name=u'items')
        items = list(items.next().elements(
            uri='http://jabber.org/protocol/pubsub#event', name='item'))

        d = self.plugin.subscribe(self.source, u'foo', u'url', u'title')

        @d.addCallback
        def subscribed(sub):
            self.plugin.itemsReceived(sub, items)
            self.assertEquals(self.source.calls['notice'], len(items))

        return d
Ejemplo n.º 14
0
class CreateSubversionRepositoryTests(TestCase):
    """
    Tests for L{createSubversionRepository}.

    @ivar commands: A list of the commands which have been executed.
    """
    def setUp(self):
        self.commands = []
        self.repository = FilePath(self.mktemp())
        self.workingCopy = self.repository.sibling('working')

    def runCommand(self, command):
        """
        Record the execution of a command.  Inspect the command and create a
        directory if it is an "svn co" command.
        """
        if self.workingCopy.isdir():
            children = list(self.workingCopy.walk())
            children.remove(self.workingCopy)
        else:
            children = None
        self.commands.append((command, children))
        if command.startswith("svn co "):
            self.workingCopy.makedirs()

    def test_emptyRepository(self):
        """
        L{createSubversionRepository} should create a repository with no
        entries or revisions if it is passed an empty dictionary.
        """
        createSubversionRepository(self.repository, {}, False,
                                   self.commands.append)
        self.assertEqual(self.commands,
                         ["svnadmin create " + self.repository.path])

    def _fileTest(self, entry, contents):
        """
        """
        createSubversionRepository(self.repository, {entry: contents}, False,
                                   self.runCommand)

        repo = self.repository.path
        wc = self.workingCopy.path
        self.assertEqual(self.commands, [
            ("svnadmin create " + repo, None),
            ("svn co file://" + repo + " " + wc, None),
            ("svn add " + self.workingCopy.child(entry).path,
             [self.workingCopy.child(entry)]),
            ("svn commit -m 'Create specified files' " + self.workingCopy.path,
             [self.workingCopy.child(entry)])
        ])

    def test_emptyFile(self):
        """
        L{createSubversionRepository} should create a repository with one empty
        file in it if passed a dictionary with one key mapped to the empty
        string.
        """
        entry = 'filename'
        contents = ''
        self._fileTest(entry, contents)
        self.assertEqual(self.workingCopy.child(entry).getContent(), contents)

    def test_fileWithContents(self):
        """
        L{createSubversionRepository} should create a repository with a file
        with the contents given as the corresponding value.
        """
        entry = 'filename'
        contents = 'some bytes\n'
        self._fileTest(entry, contents)
        self.assertEqual(self.workingCopy.child(entry).getContent(), contents)

    def test_directory(self):
        """
        L{createSubversionRepository} should create a directory for a key with
        a C{dict} as a value.
        """
        entry = 'dirname'
        contents = {}
        self._fileTest(entry, contents)
        self.assertTrue(self.workingCopy.child(entry).isdir())

    def test_directoryContainingFile(self):
        """
        For a key associated with a value of a C{dict} with a key associated
        with a value of a C{str}, L{createSubversionRepository} should create a
        directory containing a file with the specified string as its content.
        """
        directory = 'dirname'
        file = 'filename'
        content = 'bytes'
        createSubversionRepository(self.repository,
                                   {directory: {
                                       file: content
                                   }}, False, self.runCommand)

        repo = self.repository.path
        wc = self.workingCopy.path
        self.assertEqual(self.commands, [
            ("svnadmin create " + repo, None),
            ("svn co file://" + repo + " " + wc, None),
            ("svn add " + self.workingCopy.child(directory).path,
             [self.workingCopy.child(directory)]),
            ("svn add " + self.workingCopy.child(directory).child(file).path, [
                self.workingCopy.child(directory),
                self.workingCopy.child(directory).child(file)
            ]),
            ("svn commit -m 'Create specified files' " + self.workingCopy.path,
             [
                 self.workingCopy.child(directory),
                 self.workingCopy.child(directory).child(file)
             ])
        ])

    def test_workingCopyRemoved(self):
        """
        The temporary working copy should be deleted after
        L{createSubversionRepository} is finished using it to populate the
        repository if C{True} is passed for the I{cleanup} parameter.
        """
        createSubversionRepository(self.repository, {'file': 'bytes'}, True,
                                   self.runCommand)
        self.workingCopy.restat(False)
        self.assertFalse(self.workingCopy.exists())

    def test_commit(self):
        """
        Changes in the working copy passed to L{commit} are committed to the
        repository.
        """
        commit(self.workingCopy, "change stuff about", self.runCommand)
        self.assertEquals(self.commands,
                          [("svn commit -m 'change stuff about' " +
                            self.workingCopy.path, None)])
Ejemplo n.º 15
0
class CreateSubversionRepositoryTests(TestCase):
    """
    Tests for L{createSubversionRepository}.

    @ivar commands: A list of the commands which have been executed.
    """

    def setUp(self):
        self.commands = []
        self.repository = FilePath(self.mktemp())
        self.workingCopy = self.repository.sibling('working')


    def runCommand(self, command):
        """
        Record the execution of a command.  Inspect the command and create a
        directory if it is an "svn co" command.
        """
        if self.workingCopy.isdir():
            children = list(self.workingCopy.walk())
            children.remove(self.workingCopy)
        else:
            children = None
        self.commands.append((command, children))
        if command.startswith("svn co "):
            self.workingCopy.makedirs()


    def test_emptyRepository(self):
        """
        L{createSubversionRepository} should create a repository with no
        entries or revisions if it is passed an empty dictionary.
        """
        createSubversionRepository(self.repository, {}, False, self.commands.append)
        self.assertEqual(
            self.commands,
            ["svnadmin create " + self.repository.path])


    def _fileTest(self, entry, contents):
        """
        """
        createSubversionRepository(
            self.repository, {entry: contents}, False, self.runCommand)

        repo = self.repository.path
        wc = self.workingCopy.path
        self.assertEqual(
            self.commands,
            [("svnadmin create " + repo, None),
             ("svn co file://" + repo + " " + wc, None),
             ("svn add " + self.workingCopy.child(entry).path,
              [self.workingCopy.child(entry)]),
             ("svn commit -m 'Create specified files' " + self.workingCopy.path,
              [self.workingCopy.child(entry)])])


    def test_emptyFile(self):
        """
        L{createSubversionRepository} should create a repository with one empty
        file in it if passed a dictionary with one key mapped to the empty
        string.
        """
        entry = 'filename'
        contents = ''
        self._fileTest(entry, contents)
        self.assertEqual(self.workingCopy.child(entry).getContent(), contents)


    def test_fileWithContents(self):
        """
        L{createSubversionRepository} should create a repository with a file
        with the contents given as the corresponding value.
        """
        entry = 'filename'
        contents = 'some bytes\n'
        self._fileTest(entry, contents)
        self.assertEqual(
            self.workingCopy.child(entry).getContent(), contents)


    def test_directory(self):
        """
        L{createSubversionRepository} should create a directory for a key with
        a C{dict} as a value.
        """
        entry = 'dirname'
        contents = {}
        self._fileTest(entry, contents)
        self.assertTrue(self.workingCopy.child(entry).isdir())


    def test_directoryContainingFile(self):
        """
        For a key associated with a value of a C{dict} with a key associated
        with a value of a C{str}, L{createSubversionRepository} should create a
        directory containing a file with the specified string as its content.
        """
        directory = 'dirname'
        file = 'filename'
        content = 'bytes'
        createSubversionRepository(
            self.repository,
            {directory: {file: content}},
            False,
            self.runCommand)

        repo = self.repository.path
        wc = self.workingCopy.path
        self.assertEqual(
            self.commands,
            [("svnadmin create " + repo, None),
             ("svn co file://" + repo + " " + wc, None),
             ("svn add " + self.workingCopy.child(directory).path,
              [self.workingCopy.child(directory)]),
             ("svn add " + self.workingCopy.child(directory).child(file).path,
              [self.workingCopy.child(directory),
               self.workingCopy.child(directory).child(file)]),
             ("svn commit -m 'Create specified files' " + self.workingCopy.path,
              [self.workingCopy.child(directory),
               self.workingCopy.child(directory).child(file)])])


    def test_workingCopyRemoved(self):
        """
        The temporary working copy should be deleted after
        L{createSubversionRepository} is finished using it to populate the
        repository if C{True} is passed for the I{cleanup} parameter.
        """
        createSubversionRepository(
            self.repository, {'file': 'bytes'}, True, self.runCommand)
        self.workingCopy.restat(False)
        self.assertFalse(self.workingCopy.exists())


    def test_commit(self):
        """
        Changes in the working copy passed to L{commit} are committed to the
        repository.
        """
        commit(self.workingCopy, "change stuff about", self.runCommand)
        self.assertEquals(
            self.commands,
            [("svn commit -m 'change stuff about' " + self.workingCopy.path, None)])
Ejemplo n.º 16
0
# Copyright ClusterHQ Inc.  See LICENSE file for details.

# Generate a v5 configuration.
# Hash to recreate: 1ce62d2dc43d631954d7583c574259e89997829e

from twisted.python.filepath import FilePath

from flocker.control._model import Configuration
from flocker.control._persistence import wire_encode
from flocker.control.test.test_persistence import TEST_DEPLOYMENTS

_VERSION = 5

if __name__ == "__main__":
    myfile = FilePath(__file__)
    for i, deployment in enumerate(TEST_DEPLOYMENTS, start=1):
        encoding = wire_encode(
            Configuration(version=_VERSION, deployment=deployment)
        )
        myfile.sibling(
            b"configuration_%d_v%d.json" % (i, _VERSION)
        ).setContent(encoding)
Ejemplo n.º 17
0
# Copyright ClusterHQ Inc.  See LICENSE file for details.

# Generate a v4 configuration.
# Hash to recreate: 90c95c82febaceda87aed770923b284fc71f0e3f

from twisted.python.filepath import FilePath

from flocker.control._model import Configuration
from flocker.control._persistence import wire_encode
from flocker.control.test.test_persistence import TEST_DEPLOYMENTS

_VERSION = 4

if __name__ == "__main__":
    myfile = FilePath(__file__)
    for i, deployment in enumerate(TEST_DEPLOYMENTS, start=1):
        encoding = wire_encode(
            Configuration(version=_VERSION, deployment=deployment)
        )
        myfile.sibling(
            b"configuration_%d_v%d.json" % (i, _VERSION)
        ).setContent(encoding)
Ejemplo n.º 18
0
class FeedUpdatesTests(unittest.TestCase):
    """
    Tests for L{eridanusstd.feedupdates} and
    L{eridanusstd.plugindefs.feedupdates}.
    """
    def setUp(self):
        self.path = FilePath(__file__)
        self.store = Store()
        self.plugin = feedupdates_plugin.FeedUpdates(store=self.store)
        object.__setattr__(self.plugin, 'superfeedrService',
                           MockSuperfeedrService())
        self.source = MockSource(u'#quux')

    def test_subscribe(self):
        """
        Subscribing to a feed creates a L{SubscribedFeed} item with the
        appropriate attributes. Invalid values for the C{formatting} argument
        raise C{ValueError} and attempting to subscribe to the same feed twice
        from the same subscription source (e.g. an IRC channel) results in
        L{eridanusstd.errors.InvalidIdentifier} being raised.
        """
        self.assertRaises(ValueError, self.plugin.subscribe, self.source,
                          u'wrong', u'url', u'not_valid')

        d = self.plugin.subscribe(self.source, u'foo', u'url', u'title')

        @d.addCallback
        def checkSubscription(sub):
            self.assertEquals(sub.id, u'foo')
            self.assertEquals(sub.url, u'url')
            self.assertEquals(sub.formatting, u'title')
            self.assertIdentical(sub.source, self.source)

        @d.addCallback
        def disallowDupes(dummy):
            self.assertRaises(errors.InvalidIdentifier, self.plugin.subscribe,
                              self.source, u'foo', u'url', u'title')

        return d

    def test_unsubscribe(self):
        """
        Unsubscribing deletes the relevant L{SubscribedFeed} item. Attempting
        to unsubscribe from a nonexistant feed raises
        L{eridanusstd.errors.InvalidIdentifier}.
        """
        self.assertRaises(errors.InvalidIdentifier, self.plugin.unsubscribe,
                          self.source, u'wrong')

        d = self.plugin.subscribe(self.source, u'foo', u'url', u'title')

        @d.addCallback
        def unsubscribeIt(sub):
            d = self.plugin.unsubscribe(self.source, u'foo')
            d.addCallback(lambda dummy: sub)
            return d

        @d.addCallback
        def unsubscibed(sub):
            self.assertIdentical(sub._unsubscribe, None)
            self.assertRaises(errors.InvalidIdentifier,
                              self.plugin.unsubscribe, self.source, u'foo')

        return d

    def test_getSubscription(self):
        """
        L{FeedUpdates.getSubscription} finds
        the single subscription with the specified identifier attributed to the
        specified feed subscriber. L{FeedUpdates.getSubscriptions} retrieves
        all feeds for a given subsciber.
        """
        self.assertIdentical(
            self.plugin.getSubscription(u'notthere', self.source.channel),
            None)

        subs = []
        d = self.plugin.subscribe(self.source, u'foo', u'url', u'title')

        @d.addCallback
        def subscribed(sub):
            subs.append(sub)
            self.assertIdentical(
                self.plugin.getSubscription(u'foo', self.source.channel), sub)
            return self.plugin.subscribe(self.source, u'bar', u'url', u'title')

        @d.addCallback
        def subscribedAgain(sub):
            subs.append(sub)
            subs.sort(key=lambda s: s.id)
            self.assertEquals(
                list(self.plugin.getSubscriptions(self.source.channel)), subs)

        return d

    def parse(self, path):
        """
        Parse the XML document at C{path} into a C{list} of C{domish} objects.
        """
        elements = []
        stream = domish.ExpatElementStream()
        stream.DocumentStartEvent = lambda root: None
        stream.DocumentEndEvent = lambda: None
        stream.ElementEvent = elements.append
        stream.parse(path.open().read())
        return elements

    def test_itemsReceived(self):
        """
        C{FeedUpdates.itemsReceived} is called with some Superfeedr item domish
        instances, which then triggers C{source.notice}.
        """
        elements = self.parse(self.path.sibling('feedupdates_1.xml'))
        items = elements[0].elements(
            uri=u'http://jabber.org/protocol/pubsub#event', name=u'items')
        items = list(items.next().elements(
            uri='http://jabber.org/protocol/pubsub#event', name='item'))

        d = self.plugin.subscribe(self.source, u'foo', u'url', u'title')

        @d.addCallback
        def subscribed(sub):
            self.plugin.itemsReceived(sub, items)
            self.assertEquals(self.source.calls['notice'], len(items))

        return d