Ejemplo n.º 1
0
    def test_FactoryNode(self):
        class TestFactoryNode(FactoryNode):
            factories = odict()
            factories['foo'] = BaseNode
            factories['bar'] = BaseNode

        node = TestFactoryNode()

        # static factories
        self.assertTrue(
            str(node['foo']).startswith("<BaseNode object 'foo' at"))
        self.assertTrue(
            str(node['bar']).startswith("<BaseNode object 'bar' at"))
        self.expect_error(KeyError, lambda: node['baz'])
        self.assertEqual(list([it for it in node]), ['foo', 'bar'])
        self.assertTrue(IInvalidate.providedBy(node))
        self.assertEqual(node.values(), [node['foo'], node['bar']])

        # invalidate
        node.invalidate()
        self.assertEqual(node.storage.values(), [])
        self.assertEqual(node.values(), [node['foo'], node['bar']])
        self.assertEqual(node.storage.values(), [node['foo'], node['bar']])

        node.invalidate('foo')
        self.assertEqual(node.storage.values(), [node['bar']])
Ejemplo n.º 2
0
    def test_Invalidate(self):
        # When using default ``Invalidate``, Contents of node just gets
        # deleted. Be aware this implementation must not be used on persisting
        # nodes.

        # Build invalidating node
        @plumbing(
            Adopt,
            Invalidate,
            DefaultInit,
            Nodify,
            OdictStorage)
        class Node(object):
            pass

        # Test tree
        root = Node()
        root['c1'] = Node()
        root['c2'] = Node()
        root['c2']['d1'] = Node()
        root['c2']['d2'] = Node()

        self.assertTrue(IInvalidate.providedBy(root))
        self.assertFalse(ICache.providedBy(root))

        self.assertEqual(root.treerepr(), (
            '<class \'node.tests.test_cache.Node\'>: None\n'
            '  <class \'node.tests.test_cache.Node\'>: c1\n'
            '  <class \'node.tests.test_cache.Node\'>: c2\n'
            '    <class \'node.tests.test_cache.Node\'>: d1\n'
            '    <class \'node.tests.test_cache.Node\'>: d2\n'
        ))

        # Active invalidation of child by key
        root.invalidate(key='c1')
        self.assertEqual(root.treerepr(), (
            '<class \'node.tests.test_cache.Node\'>: None\n'
            '  <class \'node.tests.test_cache.Node\'>: c2\n'
            '    <class \'node.tests.test_cache.Node\'>: d1\n'
            '    <class \'node.tests.test_cache.Node\'>: d2\n'
        ))

        err = self.expect_error(KeyError, root.invalidate, key='c1')
        self.assertEqual(str(err), '\'c1\'')

        # Active invalidation of all children
        root['c2'].invalidate()
        self.assertEqual(root.treerepr(), (
            '<class \'node.tests.test_cache.Node\'>: None\n'
            '  <class \'node.tests.test_cache.Node\'>: c2\n'
        ))
Ejemplo n.º 3
0
    def test_VolatileStorageInvalidate(self):
        # When a node internally uses a volatile storage like ``DictStorage``
        # or ``OdictStorage``, some can use ``VolatileStorageInvalidate`` for
        # invalidation
        @plumbing(
            Adopt,
            VolatileStorageInvalidate,
            DefaultInit,
            Nodify,
            OdictStorage)
        class Node(object):
            pass

        # Test tree:
        root = Node()
        root['c1'] = Node()
        root['c2'] = Node()
        root['c2']['d1'] = Node()
        root['c2']['d2'] = Node()

        self.assertTrue(IInvalidate.providedBy(root))
        self.assertFalse(ICache.providedBy(root))

        self.assertEqual(root.treerepr(), (
            '<class \'node.tests.test_cache.Node\'>: None\n'
            '  <class \'node.tests.test_cache.Node\'>: c1\n'
            '  <class \'node.tests.test_cache.Node\'>: c2\n'
            '    <class \'node.tests.test_cache.Node\'>: d1\n'
            '    <class \'node.tests.test_cache.Node\'>: d2\n'
        ))

        # Active invalidation of child by key
        root.invalidate(key='c1')
        self.assertEqual(root.treerepr(), (
            '<class \'node.tests.test_cache.Node\'>: None\n'
            '  <class \'node.tests.test_cache.Node\'>: c2\n'
            '    <class \'node.tests.test_cache.Node\'>: d1\n'
            '    <class \'node.tests.test_cache.Node\'>: d2\n'
        ))

        err = self.expect_error(KeyError, root.invalidate, key='c1')
        self.assertEqual(str(err), '\'c1\'')

        # Active invalidation of all children
        root['c2'].invalidate()
        self.assertEqual(root.treerepr(), (
            '<class \'node.tests.test_cache.Node\'>: None\n'
            '  <class \'node.tests.test_cache.Node\'>: c2\n'
        ))
Ejemplo n.º 4
0
    def test_Invalidate(self):
        # When using default ``Invalidate``, Contents of node just gets
        # deleted. Be aware this implementation must not be used on persisting
        # nodes.

        # Build invalidating node
        @plumbing(Adopt, Invalidate, DefaultInit, Nodify, OdictStorage)
        class Node(object):
            pass

        # Test tree
        root = Node()
        root['c1'] = Node()
        root['c2'] = Node()
        root['c2']['d1'] = Node()
        root['c2']['d2'] = Node()

        self.assertTrue(IInvalidate.providedBy(root))
        self.assertFalse(ICache.providedBy(root))

        self.assertEqual(root.treerepr(),
                         ('<class \'node.tests.test_cache.Node\'>: None\n'
                          '  <class \'node.tests.test_cache.Node\'>: c1\n'
                          '  <class \'node.tests.test_cache.Node\'>: c2\n'
                          '    <class \'node.tests.test_cache.Node\'>: d1\n'
                          '    <class \'node.tests.test_cache.Node\'>: d2\n'))

        # Active invalidation of child by key
        root.invalidate(key='c1')
        self.assertEqual(root.treerepr(),
                         ('<class \'node.tests.test_cache.Node\'>: None\n'
                          '  <class \'node.tests.test_cache.Node\'>: c2\n'
                          '    <class \'node.tests.test_cache.Node\'>: d1\n'
                          '    <class \'node.tests.test_cache.Node\'>: d2\n'))

        err = self.expectError(KeyError, root.invalidate, key='c1')
        self.assertEqual(str(err), '\'c1\'')

        # Active invalidation of all children
        root['c2'].invalidate()
        self.assertEqual(root.treerepr(),
                         ('<class \'node.tests.test_cache.Node\'>: None\n'
                          '  <class \'node.tests.test_cache.Node\'>: c2\n'))
Ejemplo n.º 5
0
    def test_VolatileStorageInvalidate(self):
        # When a node internally uses a volatile storage like ``DictStorage``
        # or ``OdictStorage``, some can use ``VolatileStorageInvalidate`` for
        # invalidation
        @plumbing(Adopt, VolatileStorageInvalidate, DefaultInit, Nodify,
                  OdictStorage)
        class Node(object):
            pass

        # Test tree:
        root = Node()
        root['c1'] = Node()
        root['c2'] = Node()
        root['c2']['d1'] = Node()
        root['c2']['d2'] = Node()

        self.assertTrue(IInvalidate.providedBy(root))
        self.assertFalse(ICache.providedBy(root))

        self.assertEqual(root.treerepr(),
                         ('<class \'node.tests.test_cache.Node\'>: None\n'
                          '  <class \'node.tests.test_cache.Node\'>: c1\n'
                          '  <class \'node.tests.test_cache.Node\'>: c2\n'
                          '    <class \'node.tests.test_cache.Node\'>: d1\n'
                          '    <class \'node.tests.test_cache.Node\'>: d2\n'))

        # Active invalidation of child by key
        root.invalidate(key='c1')
        self.assertEqual(root.treerepr(),
                         ('<class \'node.tests.test_cache.Node\'>: None\n'
                          '  <class \'node.tests.test_cache.Node\'>: c2\n'
                          '    <class \'node.tests.test_cache.Node\'>: d1\n'
                          '    <class \'node.tests.test_cache.Node\'>: d2\n'))

        err = self.expectError(KeyError, root.invalidate, key='c1')
        self.assertEqual(str(err), '\'c1\'')

        # Active invalidation of all children
        root['c2'].invalidate()
        self.assertEqual(root.treerepr(),
                         ('<class \'node.tests.test_cache.Node\'>: None\n'
                          '  <class \'node.tests.test_cache.Node\'>: c2\n'))
Ejemplo n.º 6
0
    def test_FactoryNode(self):
        class TestFactoryNode(FactoryNode):
            factories = odict()
            factories['foo'] = BaseNode
            factories['bar'] = BaseNode
        node = TestFactoryNode()

        # static factories
        self.assertTrue(str(node['foo']).startswith("<BaseNode object 'foo' at"))
        self.assertTrue(str(node['bar']).startswith("<BaseNode object 'bar' at"))
        self.expect_error(KeyError, lambda: node['baz'])
        self.assertEqual(list([it for it in node]), ['foo', 'bar'])
        self.assertTrue(IInvalidate.providedBy(node))
        self.assertEqual(node.values(), [node['foo'], node['bar']])

        # invalidate
        node.invalidate()
        self.assertEqual(node.storage.values(), [])
        self.assertEqual(node.values(), [node['foo'], node['bar']])
        self.assertEqual(node.storage.values(), [node['foo'], node['bar']])

        node.invalidate('foo')
        self.assertEqual(node.storage.values(), [node['bar']])
Ejemplo n.º 7
0
    def test_Cache(self):
        # Build a node with active invalidation and cache functionality
        @plumbing(Adopt, Cache, Invalidate, DefaultInit, Nodify, OdictStorage)
        class Node(object):
            pass

        root = Node()
        root['c1'] = Node()
        root['c2'] = Node()
        root['c2']['d1'] = Node()
        root['c2']['d2'] = Node()

        self.assertTrue(IInvalidate.providedBy(root))
        self.assertTrue(ICache.providedBy(root))

        # We just accessed 'c2' above, only cached value on root at the moment
        self.assertEqual(list(root.cache.keys()), ['c2'])
        expected = '<Node object \'c2\' at'
        self.assertTrue(str(root.cache['c2']).startswith(expected))

        expected = '<Node object \'c1\' at'
        self.assertTrue(str(root['c1']).startswith(expected))

        # After accessing 'c1', it is cached as well:
        self.checkOutput(
            """\
        [('c1', <Node object 'c1' at ...>),
        ('c2', <Node object 'c2' at ...>)]
        """, str(sorted(root.cache.items())))

        # Invalidate plumbing removes item from cache
        root.invalidate(key='c1')
        self.assertEqual(list(root.cache.keys()), ['c2'])

        root.invalidate()
        self.assertEqual(root.cache, {})

        self.assertEqual(root.treerepr(),
                         ('<class \'node.tests.test_cache.Node\'>: None\n'))

        # Test invalidation plumbing hook with missing cache values
        root['x1'] = Node()
        root['x2'] = Node()
        self.assertEqual(root.treerepr(),
                         ('<class \'node.tests.test_cache.Node\'>: None\n'
                          '  <class \'node.tests.test_cache.Node\'>: x1\n'
                          '  <class \'node.tests.test_cache.Node\'>: x2\n'))

        self.checkOutput(
            """\
        [('x1', <Node object 'x1' at ...>),
        ('x2', <Node object 'x2' at ...>)]
        """, str(sorted(root.cache.items())))

        del root.cache['x1']
        del root.cache['x2']

        root.invalidate(key='x1')
        self.assertEqual(root.treerepr(),
                         ('<class \'node.tests.test_cache.Node\'>: None\n'
                          '  <class \'node.tests.test_cache.Node\'>: x2\n'))

        del root.cache['x2']
        root.invalidate()
        self.assertEqual(root.treerepr(),
                         ('<class \'node.tests.test_cache.Node\'>: None\n'))
Ejemplo n.º 8
0
    def test_Cache(self):
        # Build a node with active invalidation and cache functionality
        @plumbing(
            Adopt,
            Cache,
            Invalidate,
            DefaultInit,
            Nodify,
            OdictStorage)
        class Node(object):
            pass

        root = Node()
        root['c1'] = Node()
        root['c2'] = Node()
        root['c2']['d1'] = Node()
        root['c2']['d2'] = Node()

        self.assertTrue(IInvalidate.providedBy(root))
        self.assertTrue(ICache.providedBy(root))

        # We just accessed 'c2' above, only cached value on root at the moment
        self.assertEqual(list(root.cache.keys()), ['c2'])
        expected = '<Node object \'c2\' at'
        self.assertTrue(str(root.cache['c2']).startswith(expected))

        expected = '<Node object \'c1\' at'
        self.assertTrue(str(root['c1']).startswith(expected))

        # After accessing 'c1', it is cached as well:
        self.check_output("""\
        [('c1', <Node object 'c1' at ...>),
        ('c2', <Node object 'c2' at ...>)]
        """, str(sorted(root.cache.items())))

        # Invalidate plumbing removes item from cache
        root.invalidate(key='c1')
        self.assertEqual(list(root.cache.keys()), ['c2'])

        root.invalidate()
        self.assertEqual(root.cache, {})

        self.assertEqual(root.treerepr(), (
            '<class \'node.tests.test_cache.Node\'>: None\n'
        ))

        # Test invalidation plumbing hook with missing cache values
        root['x1'] = Node()
        root['x2'] = Node()
        self.assertEqual(root.treerepr(), (
            '<class \'node.tests.test_cache.Node\'>: None\n'
            '  <class \'node.tests.test_cache.Node\'>: x1\n'
            '  <class \'node.tests.test_cache.Node\'>: x2\n'
        ))

        self.check_output("""\
        [('x1', <Node object 'x1' at ...>),
        ('x2', <Node object 'x2' at ...>)]
        """, str(sorted(root.cache.items())))

        del root.cache['x1']
        del root.cache['x2']

        root.invalidate(key='x1')
        self.assertEqual(root.treerepr(), (
            '<class \'node.tests.test_cache.Node\'>: None\n'
            '  <class \'node.tests.test_cache.Node\'>: x2\n'
        ))

        del root.cache['x2']
        root.invalidate()
        self.assertEqual(root.treerepr(), (
            '<class \'node.tests.test_cache.Node\'>: None\n'
        ))