##// END OF EJS Templates
match: sort patterns before compiling them into a regex...
match: sort patterns before compiling them into a regex While investigating cripping performance for `hg cat` in some context, I discovered that, for large inputs, building a regex from out of order patterns result may result in a *much* slower regex and a much slower associated matcher's performance. So we are now sorting the patterns to help the regex engine. There is more to the story as we rely on regexp more than we should. See the next changeset for details. Benchmarks ========== In the following benchmark we are comparing the `hg cat` and `hg files` run time when matching against the full list of files in the repository. They are run: - without the rust extensions - with the standard python enfine (so without re2) sort vs non-sorted - Before this changeset (3f5137543773) --------------------------------------------------------- ###### hg files ############################################################### ### mercurial-2018-08-01-zstd-sparse-revlog sorted: 0.230092 seconds shuffled: 0.234235 seconds (+1.80%) ### pypy-2018-08-01-zstd-sparse-revlog sorted: 0.613567 seconds shuffled: 0.801880 seconds (+30.69%) ### mozilla-central-2018-08-01-zstd-sparse-revlog sorted: 62.474221 seconds shuffled: 1364.180218 seconds (+2083.59%) ### netbeans-2018-08-01-zstd-sparse-revlog sorted: 21.541828 seconds shuffled: 172.759857 seconds (+701.97%) ###### hg cat ################################################################# ### mercurial-2018-08-01-zstd-sparse-revlog sorted: 0.764407 seconds shuffled: 0.768924 seconds ### pypy-2018-08-01-zstd-sparse-revlog sorted: 2.065220 seconds shuffled: 2.276388 seconds (+10.22%) ### netbeans-2018-08-01-zstd-sparse-revlog sorted: 40.967983 seconds shuffled: 216.388709 seconds (+428.19%) ### mozilla-central-2018-08-01-zstd-sparse-revlog sorted: 105.228510 seconds shuffled: 1448.722784 seconds (+1276.74%) sort vs non-sorted - With this changeset ---------------------------------------- ###### hg files ############################################################### ### mercurial-2018-08-01-zstd-sparse-revlog all-list-pattern-sorted: 0.230069 all-list-pattern-shuffled: 0.231165 ### pypy-2018-08-01-zstd-sparse-revlog all-list-pattern-sorted: 0.616799 all-list-pattern-shuffled: 0.616393 ### netbeans-2018-08-01-zstd-sparse-revlog all-list-pattern-sorted: 21.586773 all-list-pattern-shuffled: 21.908197 ### mozilla-central-2018-08-01-zstd-sparse-revlog all-list-pattern-sorted: 61.279490 all-list-pattern-shuffled: 62.473549 ###### hg cat ################################################################# ### mercurial-2018-08-01-zstd-sparse-revlog sorted: 0.763883 seconds shuffled: 0.765848 seconds ### pypy-2018-08-01-zstd-sparse-revlog sorted: 2.070498 seconds shuffled: 2.069197 seconds ### netbeans-2018-08-01-zstd-sparse-revlog sorted: 41.392423 seconds shuffled: 41.648689 seconds ### mozilla-central-2018-08-01-zstd-sparse-revlog sorted: 103.315670 seconds shuffled: 104.369358 seconds

File last commit:

r49730:6000f5b2 default
r51285:47686726 stable
Show More
storage.py
1454 lines | 46.6 KiB | text/x-python | PythonLexer
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 # storage.py - Testing of storage primitives.
#
# Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
import unittest
from ..node import (
hex,
nullrev,
)
Gregory Szorc
py3: manually import getattr where it is needed...
r43359 from ..pycompat import getattr
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 from .. import (
error,
mdiff,
Pulkit Goyal
interfaces: create a new folder for interfaces and move repository.py in it...
r43078 )
Augie Fackler
formatting: blacken the codebase...
r43346 from ..interfaces import repository
from ..utils import storageutil
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
class basetestcase(unittest.TestCase):
Gregory Szorc
py3: stop normalizing 2nd argument of *attr() to unicode...
r43373 if not getattr(unittest.TestCase, 'assertRaisesRegex', False):
Augie Fackler
formatting: blacken the codebase...
r43346 assertRaisesRegex = ( # camelcase-required
unittest.TestCase.assertRaisesRegexp
)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
class ifileindextests(basetestcase):
"""Generic tests for the ifileindex interface.
All file storage backends for index data should conform to the tests in this
class.
Use ``makeifileindextests()`` to create an instance of this type.
"""
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 def testempty(self):
f = self._makefilefn()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.assertEqual(len(f), 0, b'new file store has 0 length by default')
self.assertEqual(list(f), [], b'iter yields nothing by default')
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
gen = iter(f)
with self.assertRaises(StopIteration):
next(gen)
Gregory Szorc
filelog: add a hasnode() method (API)...
r40423 self.assertFalse(f.hasnode(None))
self.assertFalse(f.hasnode(0))
self.assertFalse(f.hasnode(nullrev))
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertFalse(f.hasnode(f.nullid))
Gregory Szorc
filelog: add a hasnode() method (API)...
r40423 self.assertFalse(f.hasnode(b'0'))
self.assertFalse(f.hasnode(b'a' * 20))
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 # revs() should evaluate to an empty list.
self.assertEqual(list(f.revs()), [])
revs = iter(f.revs())
with self.assertRaises(StopIteration):
next(revs)
self.assertEqual(list(f.revs(start=20)), [])
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 # parents() and parentrevs() work with f.nullid/nullrev.
self.assertEqual(f.parents(f.nullid), (f.nullid, f.nullid))
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.parentrevs(nullrev), (nullrev, nullrev))
with self.assertRaises(error.LookupError):
f.parents(b'\x01' * 20)
for i in range(-5, 5):
if i == nullrev:
continue
with self.assertRaises(IndexError):
f.parentrevs(i)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 # f.nullid/nullrev lookup always works.
self.assertEqual(f.rev(f.nullid), nullrev)
self.assertEqual(f.node(nullrev), f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
with self.assertRaises(error.LookupError):
f.rev(b'\x01' * 20)
for i in range(-5, 5):
if i == nullrev:
continue
with self.assertRaises(IndexError):
f.node(i)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(f.lookup(f.nullid), f.nullid)
self.assertEqual(f.lookup(nullrev), f.nullid)
self.assertEqual(f.lookup(hex(f.nullid)), f.nullid)
self.assertEqual(f.lookup(b'%d' % nullrev), f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Gregory Szorc
testing: add more testing for ifileindex.lookup()...
r40037 with self.assertRaises(error.LookupError):
f.lookup(b'badvalue')
Gregory Szorc
storageutil: implement file identifier resolution method (BC)...
r40038 with self.assertRaises(error.LookupError):
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f.lookup(hex(f.nullid)[0:12])
Gregory Szorc
testing: add more testing for ifileindex.lookup()...
r40037
with self.assertRaises(error.LookupError):
f.lookup(b'-2')
Gregory Szorc
storageutil: implement file identifier resolution method (BC)...
r40038 with self.assertRaises(error.LookupError):
f.lookup(b'0')
Gregory Szorc
testing: add more testing for ifileindex.lookup()...
r40037
with self.assertRaises(error.LookupError):
f.lookup(b'1')
with self.assertRaises(error.LookupError):
f.lookup(b'11111111111111111111111111111111111111')
for i in range(-5, 5):
if i == nullrev:
continue
with self.assertRaises(LookupError):
f.lookup(i)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.linkrev(nullrev), nullrev)
for i in range(-5, 5):
if i == nullrev:
continue
with self.assertRaises(IndexError):
f.linkrev(i)
self.assertFalse(f.iscensored(nullrev))
for i in range(-5, 5):
if i == nullrev:
continue
with self.assertRaises(IndexError):
f.iscensored(i)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(list(f.commonancestorsheads(f.nullid, f.nullid)), [])
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
with self.assertRaises(ValueError):
self.assertEqual(list(f.descendants([])), [])
self.assertEqual(list(f.descendants([nullrev])), [])
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(f.heads(), [f.nullid])
self.assertEqual(f.heads(f.nullid), [f.nullid])
self.assertEqual(f.heads(None, [f.nullid]), [f.nullid])
self.assertEqual(f.heads(f.nullid, [f.nullid]), [f.nullid])
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(f.children(f.nullid), [])
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
with self.assertRaises(error.LookupError):
f.children(b'\x01' * 20)
def testsinglerevision(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node = f.add(b'initial', None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(len(f), 1)
self.assertEqual(list(f), [0])
gen = iter(f)
self.assertEqual(next(gen), 0)
with self.assertRaises(StopIteration):
next(gen)
Gregory Szorc
filelog: add a hasnode() method (API)...
r40423 self.assertTrue(f.hasnode(node))
self.assertFalse(f.hasnode(hex(node)))
self.assertFalse(f.hasnode(nullrev))
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertFalse(f.hasnode(f.nullid))
Gregory Szorc
filelog: add a hasnode() method (API)...
r40423 self.assertFalse(f.hasnode(node[0:12]))
self.assertFalse(f.hasnode(hex(node)[0:20]))
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(list(f.revs()), [0])
self.assertEqual(list(f.revs(start=1)), [])
self.assertEqual(list(f.revs(start=0)), [0])
self.assertEqual(list(f.revs(stop=0)), [0])
self.assertEqual(list(f.revs(stop=1)), [0])
self.assertEqual(list(f.revs(1, 1)), [])
# TODO buggy
self.assertEqual(list(f.revs(1, 0)), [1, 0])
self.assertEqual(list(f.revs(2, 0)), [2, 1, 0])
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(f.parents(node), (f.nullid, f.nullid))
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.parentrevs(0), (nullrev, nullrev))
with self.assertRaises(error.LookupError):
f.parents(b'\x01' * 20)
with self.assertRaises(IndexError):
f.parentrevs(1)
self.assertEqual(f.rev(node), 0)
with self.assertRaises(error.LookupError):
f.rev(b'\x01' * 20)
self.assertEqual(f.node(0), node)
with self.assertRaises(IndexError):
f.node(1)
self.assertEqual(f.lookup(node), node)
self.assertEqual(f.lookup(0), node)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(f.lookup(-1), f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.lookup(b'0'), node)
self.assertEqual(f.lookup(hex(node)), node)
Gregory Szorc
storageutil: implement file identifier resolution method (BC)...
r40038
with self.assertRaises(error.LookupError):
f.lookup(hex(node)[0:12])
Gregory Szorc
testing: add more testing for ifileindex.lookup()...
r40037
Gregory Szorc
storageutil: consistently raise LookupError (API)...
r40039 with self.assertRaises(error.LookupError):
Gregory Szorc
testing: add more testing for ifileindex.lookup()...
r40037 f.lookup(-2)
with self.assertRaises(error.LookupError):
f.lookup(b'-2')
Gregory Szorc
storageutil: consistently raise LookupError (API)...
r40039 with self.assertRaises(error.LookupError):
Gregory Szorc
testing: add more testing for ifileindex.lookup()...
r40037 f.lookup(1)
with self.assertRaises(error.LookupError):
f.lookup(b'1')
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(f.linkrev(0), 0)
with self.assertRaises(IndexError):
f.linkrev(1)
self.assertFalse(f.iscensored(0))
with self.assertRaises(IndexError):
f.iscensored(1)
self.assertEqual(list(f.descendants([0])), [])
self.assertEqual(f.heads(), [node])
self.assertEqual(f.heads(node), [node])
self.assertEqual(f.heads(stop=[node]), [node])
with self.assertRaises(error.LookupError):
f.heads(stop=[b'\x01' * 20])
self.assertEqual(f.children(node), [])
def testmultiplerevisions(self):
fulltext0 = b'x' * 1024
fulltext1 = fulltext0 + b'y'
fulltext2 = b'y' + fulltext0 + b'z'
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(fulltext0, None, tr, 0, f.nullid, f.nullid)
node1 = f.add(fulltext1, None, tr, 1, node0, f.nullid)
node2 = f.add(fulltext2, None, tr, 3, node1, f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(len(f), 3)
self.assertEqual(list(f), [0, 1, 2])
gen = iter(f)
self.assertEqual(next(gen), 0)
self.assertEqual(next(gen), 1)
self.assertEqual(next(gen), 2)
with self.assertRaises(StopIteration):
next(gen)
self.assertEqual(list(f.revs()), [0, 1, 2])
self.assertEqual(list(f.revs(0)), [0, 1, 2])
self.assertEqual(list(f.revs(1)), [1, 2])
self.assertEqual(list(f.revs(2)), [2])
self.assertEqual(list(f.revs(3)), [])
self.assertEqual(list(f.revs(stop=1)), [0, 1])
self.assertEqual(list(f.revs(stop=2)), [0, 1, 2])
self.assertEqual(list(f.revs(stop=3)), [0, 1, 2])
self.assertEqual(list(f.revs(2, 0)), [2, 1, 0])
self.assertEqual(list(f.revs(2, 1)), [2, 1])
# TODO this is wrong
self.assertEqual(list(f.revs(3, 2)), [3, 2])
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(f.parents(node0), (f.nullid, f.nullid))
self.assertEqual(f.parents(node1), (node0, f.nullid))
self.assertEqual(f.parents(node2), (node1, f.nullid))
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(f.parentrevs(0), (nullrev, nullrev))
self.assertEqual(f.parentrevs(1), (0, nullrev))
self.assertEqual(f.parentrevs(2), (1, nullrev))
self.assertEqual(f.rev(node0), 0)
self.assertEqual(f.rev(node1), 1)
self.assertEqual(f.rev(node2), 2)
with self.assertRaises(error.LookupError):
f.rev(b'\x01' * 20)
self.assertEqual(f.node(0), node0)
self.assertEqual(f.node(1), node1)
self.assertEqual(f.node(2), node2)
with self.assertRaises(IndexError):
f.node(3)
self.assertEqual(f.lookup(node0), node0)
self.assertEqual(f.lookup(0), node0)
self.assertEqual(f.lookup(b'0'), node0)
self.assertEqual(f.lookup(hex(node0)), node0)
self.assertEqual(f.lookup(node1), node1)
self.assertEqual(f.lookup(1), node1)
self.assertEqual(f.lookup(b'1'), node1)
self.assertEqual(f.lookup(hex(node1)), node1)
self.assertEqual(f.linkrev(0), 0)
self.assertEqual(f.linkrev(1), 1)
self.assertEqual(f.linkrev(2), 3)
with self.assertRaises(IndexError):
f.linkrev(3)
self.assertFalse(f.iscensored(0))
self.assertFalse(f.iscensored(1))
self.assertFalse(f.iscensored(2))
with self.assertRaises(IndexError):
f.iscensored(3)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(f.commonancestorsheads(node1, f.nullid), [])
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.commonancestorsheads(node1, node0), [node0])
self.assertEqual(f.commonancestorsheads(node1, node1), [node1])
self.assertEqual(f.commonancestorsheads(node0, node1), [node0])
self.assertEqual(f.commonancestorsheads(node1, node2), [node1])
self.assertEqual(f.commonancestorsheads(node2, node1), [node1])
self.assertEqual(list(f.descendants([0])), [1, 2])
self.assertEqual(list(f.descendants([1])), [2])
self.assertEqual(list(f.descendants([0, 1])), [1, 2])
self.assertEqual(f.heads(), [node2])
self.assertEqual(f.heads(node0), [node2])
self.assertEqual(f.heads(node1), [node2])
self.assertEqual(f.heads(node2), [node2])
# TODO this behavior seems wonky. Is it correct? If so, the
# docstring for heads() should be updated to reflect desired
# behavior.
self.assertEqual(f.heads(stop=[node1]), [node1, node2])
self.assertEqual(f.heads(stop=[node0]), [node0, node2])
self.assertEqual(f.heads(stop=[node1, node2]), [node1, node2])
with self.assertRaises(error.LookupError):
f.heads(stop=[b'\x01' * 20])
self.assertEqual(f.children(node0), [node1])
self.assertEqual(f.children(node1), [node2])
self.assertEqual(f.children(node2), [])
def testmultipleheads(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(b'0', None, tr, 0, f.nullid, f.nullid)
node1 = f.add(b'1', None, tr, 1, node0, f.nullid)
node2 = f.add(b'2', None, tr, 2, node1, f.nullid)
node3 = f.add(b'3', None, tr, 3, node0, f.nullid)
node4 = f.add(b'4', None, tr, 4, node3, f.nullid)
node5 = f.add(b'5', None, tr, 5, node0, f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(len(f), 6)
self.assertEqual(list(f.descendants([0])), [1, 2, 3, 4, 5])
self.assertEqual(list(f.descendants([1])), [2])
self.assertEqual(list(f.descendants([2])), [])
self.assertEqual(list(f.descendants([3])), [4])
self.assertEqual(list(f.descendants([0, 1])), [1, 2, 3, 4, 5])
self.assertEqual(list(f.descendants([1, 3])), [2, 4])
self.assertEqual(f.heads(), [node2, node4, node5])
self.assertEqual(f.heads(node0), [node2, node4, node5])
self.assertEqual(f.heads(node1), [node2])
self.assertEqual(f.heads(node2), [node2])
self.assertEqual(f.heads(node3), [node4])
self.assertEqual(f.heads(node4), [node4])
self.assertEqual(f.heads(node5), [node5])
# TODO this seems wrong.
self.assertEqual(f.heads(stop=[node0]), [node0, node2, node4, node5])
self.assertEqual(f.heads(stop=[node1]), [node1, node2, node4, node5])
self.assertEqual(f.children(node0), [node1, node3, node5])
self.assertEqual(f.children(node1), [node2])
self.assertEqual(f.children(node2), [])
self.assertEqual(f.children(node3), [node4])
self.assertEqual(f.children(node4), [])
self.assertEqual(f.children(node5), [])
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 class ifiledatatests(basetestcase):
"""Generic tests for the ifiledata interface.
All file storage backends for data should conform to the tests in this
class.
Use ``makeifiledatatests()`` to create an instance of this type.
"""
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 def testempty(self):
f = self._makefilefn()
Gregory Szorc
revlog: add method for obtaining storage info (API)...
r39905 self.assertEqual(f.storageinfo(), {})
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
f.storageinfo(revisionscount=True, trackedsize=True),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 {b'revisionscount': 0, b'trackedsize': 0},
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
revlog: add method for obtaining storage info (API)...
r39905
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.size(nullrev), 0)
for i in range(-5, 5):
if i == nullrev:
continue
with self.assertRaises(IndexError):
f.size(i)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(f.revision(f.nullid), b'')
self.assertEqual(f.rawdata(f.nullid), b'')
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
with self.assertRaises(error.LookupError):
f.revision(b'\x01' * 20)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(f.read(f.nullid), b'')
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
with self.assertRaises(error.LookupError):
f.read(b'\x01' * 20)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertFalse(f.renamed(f.nullid))
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
with self.assertRaises(error.LookupError):
f.read(b'\x01' * 20)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertTrue(f.cmp(f.nullid, b''))
self.assertTrue(f.cmp(f.nullid, b'foo'))
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
with self.assertRaises(error.LookupError):
f.cmp(b'\x01' * 20, b'irrelevant')
Gregory Szorc
revlog: new API to emit revision data...
r39898 # Emitting empty list is an empty generator.
gen = f.emitrevisions([])
with self.assertRaises(StopIteration):
next(gen)
# Emitting null node yields nothing.
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 gen = f.emitrevisions([f.nullid])
Gregory Szorc
revlog: new API to emit revision data...
r39898 with self.assertRaises(StopIteration):
next(gen)
# Requesting unknown node fails.
with self.assertRaises(error.LookupError):
list(f.emitrevisions([b'\x01' * 20]))
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 def testsinglerevision(self):
fulltext = b'initial'
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node = f.add(fulltext, None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Gregory Szorc
revlog: add method for obtaining storage info (API)...
r39905 self.assertEqual(f.storageinfo(), {})
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
f.storageinfo(revisionscount=True, trackedsize=True),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 {b'revisionscount': 1, b'trackedsize': len(fulltext)},
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
revlog: add method for obtaining storage info (API)...
r39905
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.size(0), len(fulltext))
with self.assertRaises(IndexError):
f.size(1)
self.assertEqual(f.revision(node), fulltext)
rawdata: update callers in testing/storage.py...
r43046 self.assertEqual(f.rawdata(node), fulltext)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(f.read(node), fulltext)
self.assertFalse(f.renamed(node))
self.assertFalse(f.cmp(node, fulltext))
self.assertTrue(f.cmp(node, fulltext + b'extra'))
Gregory Szorc
revlog: new API to emit revision data...
r39898 # Emitting a single revision works.
gen = f.emitrevisions([node])
rev = next(gen)
self.assertEqual(rev.node, node)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p1node, f.nullid)
self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.linknode)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.basenode, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.baserevisionsize)
self.assertIsNone(rev.revision)
self.assertIsNone(rev.delta)
with self.assertRaises(StopIteration):
next(gen)
# Requesting revision data works.
gen = f.emitrevisions([node], revisiondata=True)
rev = next(gen)
self.assertEqual(rev.node, node)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p1node, f.nullid)
self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.linknode)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.basenode, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.baserevisionsize)
self.assertEqual(rev.revision, fulltext)
self.assertIsNone(rev.delta)
with self.assertRaises(StopIteration):
next(gen)
# Emitting an unknown node after a known revision results in error.
with self.assertRaises(error.LookupError):
list(f.emitrevisions([node, b'\x01' * 20]))
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 def testmultiplerevisions(self):
fulltext0 = b'x' * 1024
fulltext1 = fulltext0 + b'y'
fulltext2 = b'y' + fulltext0 + b'z'
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(fulltext0, None, tr, 0, f.nullid, f.nullid)
node1 = f.add(fulltext1, None, tr, 1, node0, f.nullid)
node2 = f.add(fulltext2, None, tr, 3, node1, f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Gregory Szorc
revlog: add method for obtaining storage info (API)...
r39905 self.assertEqual(f.storageinfo(), {})
self.assertEqual(
f.storageinfo(revisionscount=True, trackedsize=True),
{
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'revisionscount': 3,
b'trackedsize': len(fulltext0)
+ len(fulltext1)
+ len(fulltext2),
Augie Fackler
formatting: blacken the codebase...
r43346 },
)
Gregory Szorc
revlog: add method for obtaining storage info (API)...
r39905
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.size(0), len(fulltext0))
self.assertEqual(f.size(1), len(fulltext1))
self.assertEqual(f.size(2), len(fulltext2))
with self.assertRaises(IndexError):
f.size(3)
self.assertEqual(f.revision(node0), fulltext0)
rawdata: update callers in testing/storage.py...
r43046 self.assertEqual(f.rawdata(node0), fulltext0)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.revision(node1), fulltext1)
rawdata: update callers in testing/storage.py...
r43046 self.assertEqual(f.rawdata(node1), fulltext1)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.revision(node2), fulltext2)
rawdata: update callers in testing/storage.py...
r43046 self.assertEqual(f.rawdata(node2), fulltext2)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
with self.assertRaises(error.LookupError):
f.revision(b'\x01' * 20)
self.assertEqual(f.read(node0), fulltext0)
self.assertEqual(f.read(node1), fulltext1)
self.assertEqual(f.read(node2), fulltext2)
with self.assertRaises(error.LookupError):
f.read(b'\x01' * 20)
self.assertFalse(f.renamed(node0))
self.assertFalse(f.renamed(node1))
self.assertFalse(f.renamed(node2))
with self.assertRaises(error.LookupError):
f.renamed(b'\x01' * 20)
self.assertFalse(f.cmp(node0, fulltext0))
self.assertFalse(f.cmp(node1, fulltext1))
self.assertFalse(f.cmp(node2, fulltext2))
self.assertTrue(f.cmp(node1, fulltext0))
self.assertTrue(f.cmp(node2, fulltext1))
with self.assertRaises(error.LookupError):
f.cmp(b'\x01' * 20, b'irrelevant')
Gregory Szorc
revlog: new API to emit revision data...
r39898 # Nodes should be emitted in order.
gen = f.emitrevisions([node0, node1, node2], revisiondata=True)
rev = next(gen)
self.assertEqual(rev.node, node0)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p1node, f.nullid)
self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.linknode)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.basenode, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.baserevisionsize)
self.assertEqual(rev.revision, fulltext0)
self.assertIsNone(rev.delta)
rev = next(gen)
self.assertEqual(rev.node, node1)
self.assertEqual(rev.p1node, node0)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.linknode)
self.assertEqual(rev.basenode, node0)
self.assertIsNone(rev.baserevisionsize)
self.assertIsNone(rev.revision)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
rev.delta,
b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' + fulltext1,
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
rev = next(gen)
self.assertEqual(rev.node, node2)
self.assertEqual(rev.p1node, node1)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.linknode)
self.assertEqual(rev.basenode, node1)
self.assertIsNone(rev.baserevisionsize)
self.assertIsNone(rev.revision)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
rev.delta,
b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' + fulltext2,
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
with self.assertRaises(StopIteration):
next(gen)
# Request not in DAG order is reordered to be in DAG order.
gen = f.emitrevisions([node2, node1, node0], revisiondata=True)
rev = next(gen)
self.assertEqual(rev.node, node0)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p1node, f.nullid)
self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.linknode)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.basenode, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.baserevisionsize)
self.assertEqual(rev.revision, fulltext0)
self.assertIsNone(rev.delta)
rev = next(gen)
self.assertEqual(rev.node, node1)
self.assertEqual(rev.p1node, node0)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.linknode)
self.assertEqual(rev.basenode, node0)
self.assertIsNone(rev.baserevisionsize)
self.assertIsNone(rev.revision)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
rev.delta,
b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' + fulltext1,
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
rev = next(gen)
self.assertEqual(rev.node, node2)
self.assertEqual(rev.p1node, node1)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.linknode)
self.assertEqual(rev.basenode, node1)
self.assertIsNone(rev.baserevisionsize)
self.assertIsNone(rev.revision)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
rev.delta,
b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' + fulltext2,
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
with self.assertRaises(StopIteration):
next(gen)
# Unrecognized nodesorder value raises ProgrammingError.
with self.assertRaises(error.ProgrammingError):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 list(f.emitrevisions([], nodesorder=b'bad'))
Gregory Szorc
revlog: new API to emit revision data...
r39898
# nodesorder=storage is recognized. But we can't test it thoroughly
# because behavior is storage-dependent.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 res = list(
f.emitrevisions([node2, node1, node0], nodesorder=b'storage')
)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertEqual(len(res), 3)
self.assertEqual({o.node for o in res}, {node0, node1, node2})
# nodesorder=nodes forces the order.
Augie Fackler
formatting: blacken the codebase...
r43346 gen = f.emitrevisions(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 [node2, node0], nodesorder=b'nodes', revisiondata=True
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
revlog: new API to emit revision data...
r39898
rev = next(gen)
self.assertEqual(rev.node, node2)
self.assertEqual(rev.p1node, node1)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p2node, f.nullid)
self.assertEqual(rev.basenode, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.baserevisionsize)
self.assertEqual(rev.revision, fulltext2)
self.assertIsNone(rev.delta)
rev = next(gen)
self.assertEqual(rev.node, node0)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p1node, f.nullid)
self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 # Delta behavior is storage dependent, so we can't easily test it.
with self.assertRaises(StopIteration):
next(gen)
# assumehaveparentrevisions=False (the default) won't send a delta for
# the first revision.
gen = f.emitrevisions({node2, node1}, revisiondata=True)
rev = next(gen)
self.assertEqual(rev.node, node1)
self.assertEqual(rev.p1node, node0)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p2node, f.nullid)
self.assertEqual(rev.basenode, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.baserevisionsize)
self.assertEqual(rev.revision, fulltext1)
self.assertIsNone(rev.delta)
rev = next(gen)
self.assertEqual(rev.node, node2)
self.assertEqual(rev.p1node, node1)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertEqual(rev.basenode, node1)
self.assertIsNone(rev.baserevisionsize)
self.assertIsNone(rev.revision)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
rev.delta,
b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' + fulltext2,
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
with self.assertRaises(StopIteration):
next(gen)
# assumehaveparentrevisions=True allows delta against initial revision.
Augie Fackler
formatting: blacken the codebase...
r43346 gen = f.emitrevisions(
[node2, node1], revisiondata=True, assumehaveparentrevisions=True
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
rev = next(gen)
self.assertEqual(rev.node, node1)
self.assertEqual(rev.p1node, node0)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertEqual(rev.basenode, node0)
self.assertIsNone(rev.baserevisionsize)
self.assertIsNone(rev.revision)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
rev.delta,
b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' + fulltext1,
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
# forceprevious=True forces a delta against the previous revision.
# Special case for initial revision.
Augie Fackler
formatting: blacken the codebase...
r43346 gen = f.emitrevisions(
[node0], revisiondata=True, deltamode=repository.CG_DELTAMODE_PREV
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
rev = next(gen)
self.assertEqual(rev.node, node0)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p1node, f.nullid)
self.assertEqual(rev.p2node, f.nullid)
self.assertEqual(rev.basenode, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.baserevisionsize)
self.assertIsNone(rev.revision)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
rev.delta,
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' + fulltext0,
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
with self.assertRaises(StopIteration):
next(gen)
Augie Fackler
formatting: blacken the codebase...
r43346 gen = f.emitrevisions(
[node0, node2],
revisiondata=True,
deltamode=repository.CG_DELTAMODE_PREV,
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
rev = next(gen)
self.assertEqual(rev.node, node0)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p1node, f.nullid)
self.assertEqual(rev.p2node, f.nullid)
self.assertEqual(rev.basenode, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertIsNone(rev.baserevisionsize)
self.assertIsNone(rev.revision)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
rev.delta,
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' + fulltext0,
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
rev = next(gen)
self.assertEqual(rev.node, node2)
self.assertEqual(rev.p1node, node1)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(rev.p2node, f.nullid)
Gregory Szorc
revlog: new API to emit revision data...
r39898 self.assertEqual(rev.basenode, node0)
with self.assertRaises(StopIteration):
next(gen)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 def testrenamed(self):
fulltext0 = b'foo'
fulltext1 = b'bar'
fulltext2 = b'baz'
meta1 = {
b'copy': b'source0',
b'copyrev': b'a' * 40,
}
meta2 = {
b'copy': b'source1',
b'copyrev': b'b' * 40,
}
Augie Fackler
formatting: blacken the codebase...
r43346 stored1 = b''.join(
[
b'\x01\ncopy: source0\n',
b'copyrev: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\x01\n',
fulltext1,
]
)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Augie Fackler
formatting: blacken the codebase...
r43346 stored2 = b''.join(
[
b'\x01\ncopy: source1\n',
b'copyrev: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n\x01\n',
fulltext2,
]
)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(fulltext0, None, tr, 0, f.nullid, f.nullid)
node1 = f.add(fulltext1, meta1, tr, 1, node0, f.nullid)
node2 = f.add(fulltext2, meta2, tr, 2, f.nullid, f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 # Metadata header isn't recognized when parent isn't f.nullid.
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.size(1), len(stored1))
self.assertEqual(f.size(2), len(fulltext2))
self.assertEqual(f.revision(node1), stored1)
rawdata: update callers in testing/storage.py...
r43046 self.assertEqual(f.rawdata(node1), stored1)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 self.assertEqual(f.revision(node2), stored2)
rawdata: update callers in testing/storage.py...
r43046 self.assertEqual(f.rawdata(node2), stored2)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(f.read(node1), fulltext1)
self.assertEqual(f.read(node2), fulltext2)
# Returns False when first parent is set.
self.assertFalse(f.renamed(node1))
self.assertEqual(f.renamed(node2), (b'source1', b'\xbb' * 20))
self.assertTrue(f.cmp(node1, fulltext1))
self.assertTrue(f.cmp(node1, stored1))
self.assertFalse(f.cmp(node2, fulltext2))
self.assertTrue(f.cmp(node2, stored2))
def testmetadataprefix(self):
# Content with metadata prefix has extra prefix inserted in storage.
fulltext0 = b'\x01\nfoo'
stored0 = b'\x01\n\x01\n\x01\nfoo'
fulltext1 = b'\x01\nbar'
meta1 = {
b'copy': b'source0',
b'copyrev': b'b' * 40,
}
Augie Fackler
formatting: blacken the codebase...
r43346 stored1 = b''.join(
[
b'\x01\ncopy: source0\n',
b'copyrev: %s\n' % (b'b' * 40),
b'\x01\n\x01\nbar',
]
)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(fulltext0, {}, tr, 0, f.nullid, f.nullid)
node1 = f.add(fulltext1, meta1, tr, 1, f.nullid, f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
# TODO this is buggy.
self.assertEqual(f.size(0), len(fulltext0) + 4)
self.assertEqual(f.size(1), len(fulltext1))
self.assertEqual(f.revision(node0), stored0)
rawdata: update callers in testing/storage.py...
r43046 self.assertEqual(f.rawdata(node0), stored0)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(f.revision(node1), stored1)
rawdata: update callers in testing/storage.py...
r43046 self.assertEqual(f.rawdata(node1), stored1)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(f.read(node0), fulltext0)
self.assertEqual(f.read(node1), fulltext1)
self.assertFalse(f.cmp(node0, fulltext0))
self.assertTrue(f.cmp(node0, stored0))
self.assertFalse(f.cmp(node1, fulltext1))
self.assertTrue(f.cmp(node1, stored0))
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 def testbadnoderead(self):
f = self._makefilefn()
fulltext0 = b'foo\n' * 30
fulltext1 = fulltext0 + b'bar\n'
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(fulltext0, None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 node1 = b'\xaa' * 20
Augie Fackler
formatting: blacken the codebase...
r43346 self._addrawrevisionfn(
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f, tr, node1, node0, f.nullid, 1, rawtext=fulltext1
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
self.assertEqual(len(f), 2)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 self.assertEqual(f.parents(node1), (node0, f.nullid))
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
# revision() raises since it performs hash verification.
with self.assertRaises(error.StorageError):
f.revision(node1)
rawdata: update callers in testing/storage.py...
r43046 # rawdata() still verifies because there are no special storage
Gregory Szorc
revlog: clear revision cache on hash verification failure...
r40090 # settings.
with self.assertRaises(error.StorageError):
rawdata: update callers in testing/storage.py...
r43046 f.rawdata(node1)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
# read() behaves like revision().
Gregory Szorc
revlog: clear revision cache on hash verification failure...
r40090 with self.assertRaises(error.StorageError):
f.read(node1)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
# We can't test renamed() here because some backends may not require
# reading/validating the fulltext to return rename metadata.
def testbadnoderevisionraw(self):
rawdata: update callers in testing/storage.py...
r43046 # Like above except we test rawdata() first to isolate
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 # revision caching behavior.
f = self._makefilefn()
fulltext0 = b'foo\n' * 30
fulltext1 = fulltext0 + b'bar\n'
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(fulltext0, None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 node1 = b'\xaa' * 20
Augie Fackler
formatting: blacken the codebase...
r43346 self._addrawrevisionfn(
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f, tr, node1, node0, f.nullid, 1, rawtext=fulltext1
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
with self.assertRaises(error.StorageError):
rawdata: update callers in testing/storage.py...
r43046 f.rawdata(node1)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
with self.assertRaises(error.StorageError):
rawdata: update callers in testing/storage.py...
r43046 f.rawdata(node1)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
Matt Harbison
tests: fix a copy/paste name duplication in storage.py...
r44476 def testbadnoderevision(self):
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 # Like above except we test read() first to isolate revision caching
# behavior.
f = self._makefilefn()
fulltext0 = b'foo\n' * 30
fulltext1 = fulltext0 + b'bar\n'
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(fulltext0, None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 node1 = b'\xaa' * 20
Augie Fackler
formatting: blacken the codebase...
r43346 self._addrawrevisionfn(
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f, tr, node1, node0, f.nullid, 1, rawtext=fulltext1
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
with self.assertRaises(error.StorageError):
f.read(node1)
Gregory Szorc
revlog: clear revision cache on hash verification failure...
r40090 with self.assertRaises(error.StorageError):
f.read(node1)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
def testbadnodedelta(self):
f = self._makefilefn()
fulltext0 = b'foo\n' * 31
fulltext1 = fulltext0 + b'bar\n'
fulltext2 = fulltext1 + b'baz\n'
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(fulltext0, None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 node1 = b'\xaa' * 20
Augie Fackler
formatting: blacken the codebase...
r43346 self._addrawrevisionfn(
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f, tr, node1, node0, f.nullid, 1, rawtext=fulltext1
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
with self.assertRaises(error.StorageError):
f.read(node1)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node2 = storageutil.hashrevisionsha1(fulltext2, node1, f.nullid)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
with self._maketransactionfn() as tr:
Gregory Szorc
testing: switch to inserting deltas...
r40359 delta = mdiff.textdiff(fulltext1, fulltext2)
Augie Fackler
formatting: blacken the codebase...
r43346 self._addrawrevisionfn(
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f, tr, node2, node1, f.nullid, 2, delta=(1, delta)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
self.assertEqual(len(f), 3)
# Assuming a delta is stored, we shouldn't need to validate node1 in
# order to retrieve node2.
self.assertEqual(f.read(node2), fulltext2)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 def testcensored(self):
f = self._makefilefn()
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 stored1 = storageutil.packmeta(
{
b'censored': b'tombstone',
},
b'',
)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(b'foo', None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
# The node value doesn't matter since we can't verify it.
node1 = b'\xbb' * 20
Augie Fackler
formatting: blacken the codebase...
r43346 self._addrawrevisionfn(
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f, tr, node1, node0, f.nullid, 1, stored1, censored=True
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertTrue(f.iscensored(1))
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 with self.assertRaises(error.CensoredNodeError):
f.revision(1)
Gregory Szorc
revlog: clear revision cache on hash verification failure...
r40090 with self.assertRaises(error.CensoredNodeError):
rawdata: update callers in testing/storage.py...
r43046 f.rawdata(1)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 with self.assertRaises(error.CensoredNodeError):
f.read(1)
def testcensoredrawrevision(self):
rawdata: update callers in testing/storage.py...
r43046 # Like above, except we do the rawdata() request first to
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 # isolate revision caching behavior.
f = self._makefilefn()
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 stored1 = storageutil.packmeta(
{
b'censored': b'tombstone',
},
b'',
)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(b'foo', None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
# The node value doesn't matter since we can't verify it.
node1 = b'\xbb' * 20
Augie Fackler
formatting: blacken the codebase...
r43346 self._addrawrevisionfn(
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f, tr, node1, node0, f.nullid, 1, stored1, censored=True
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
with self.assertRaises(error.CensoredNodeError):
rawdata: update callers in testing/storage.py...
r43046 f.rawdata(1)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 class ifilemutationtests(basetestcase):
"""Generic tests for the ifilemutation interface.
All file storage backends that support writing should conform to this
interface.
Use ``makeifilemutationtests()`` to create an instance of this type.
"""
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 def testaddnoop(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(b'foo', None, tr, 0, f.nullid, f.nullid)
node1 = f.add(b'foo', None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 # Varying by linkrev shouldn't impact hash.
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node2 = f.add(b'foo', None, tr, 1, f.nullid, f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(node1, node0)
self.assertEqual(node2, node0)
self.assertEqual(len(f), 1)
def testaddrevisionbadnode(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
# Adding a revision with bad node value fails.
Gregory Szorc
error: introduce StorageError...
r39812 with self.assertRaises(error.StorageError):
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f.addrevision(
b'foo', tr, 0, f.nullid, f.nullid, node=b'\x01' * 20
)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
def testaddrevisionunknownflag(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
for i in range(15, 0, -1):
Gregory Szorc
repository: define and use revision flag constants...
r40083 if (1 << i) & ~repository.REVISION_FLAGS_KNOWN:
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 flags = 1 << i
break
Gregory Szorc
error: introduce StorageError...
r39812 with self.assertRaises(error.StorageError):
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f.addrevision(b'foo', tr, 0, f.nullid, f.nullid, flags=flags)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
def testaddgroupsimple(self):
f = self._makefilefn()
callbackargs = []
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 def cb(*args, **kwargs):
callbackargs.append((args, kwargs))
def linkmapper(node):
return 0
with self._maketransactionfn() as tr:
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373 nodes = []
Joerg Sonnenberger
revlog: change addgroup callbacks to take revision numbers...
r47259 def onchangeset(cl, rev):
node = cl.node(rev)
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373 nodes.append(node)
cb(cl, node)
Joerg Sonnenberger
revlog: change addgroup callbacks to take revision numbers...
r47259 def ondupchangeset(cl, rev):
nodes.append(cl.node(rev))
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373
f.addgroup(
[],
None,
tr,
addrevisioncb=onchangeset,
duplicaterevisioncb=ondupchangeset,
)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(nodes, [])
self.assertEqual(callbackargs, [])
self.assertEqual(len(f), 0)
fulltext0 = b'foo'
delta0 = mdiff.trivialdiffheader(len(fulltext0)) + fulltext0
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(fulltext0, None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
f = self._makefilefn()
deltas = [
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 (node0, f.nullid, f.nullid, f.nullid, f.nullid, delta0, 0, {}),
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 ]
with self._maketransactionfn() as tr:
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373 nodes = []
Joerg Sonnenberger
revlog: change addgroup callbacks to take revision numbers...
r47259 def onchangeset(cl, rev):
node = cl.node(rev)
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373 nodes.append(node)
cb(cl, node)
Joerg Sonnenberger
revlog: change addgroup callbacks to take revision numbers...
r47259 def ondupchangeset(cl, rev):
nodes.append(cl.node(rev))
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373
f.addgroup(
deltas,
linkmapper,
tr,
addrevisioncb=onchangeset,
duplicaterevisioncb=ondupchangeset,
)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
nodes,
[
b'\x49\xd8\xcb\xb1\x5c\xe2\x57\x92\x04\x47'
b'\x00\x6b\x46\x97\x8b\x7a\xf9\x80\xa9\x79'
],
)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(len(callbackargs), 1)
self.assertEqual(callbackargs[0][0][1], nodes[0])
self.assertEqual(list(f.revs()), [0])
self.assertEqual(f.rev(nodes[0]), 0)
self.assertEqual(f.node(0), nodes[0])
def testaddgroupmultiple(self):
f = self._makefilefn()
fulltexts = [
b'foo',
b'bar',
b'x' * 1024,
]
nodes = []
with self._maketransactionfn() as tr:
for fulltext in fulltexts:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 nodes.append(f.add(fulltext, None, tr, 0, f.nullid, f.nullid))
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
f = self._makefilefn()
deltas = []
for i, fulltext in enumerate(fulltexts):
delta = mdiff.trivialdiffheader(len(fulltext)) + fulltext
Raphaël Gomès
delta: add sidedata field to revision delta...
r47446 deltas.append(
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 (nodes[i], f.nullid, f.nullid, f.nullid, f.nullid, delta, 0, {})
Raphaël Gomès
delta: add sidedata field to revision delta...
r47446 )
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
with self._maketransactionfn() as tr:
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373 newnodes = []
Joerg Sonnenberger
revlog: change addgroup callbacks to take revision numbers...
r47259 def onchangeset(cl, rev):
newnodes.append(cl.node(rev))
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373
f.addgroup(
deltas,
lambda x: 0,
tr,
addrevisioncb=onchangeset,
duplicaterevisioncb=onchangeset,
)
self.assertEqual(newnodes, nodes)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
self.assertEqual(len(f), len(deltas))
self.assertEqual(list(f.revs()), [0, 1, 2])
self.assertEqual(f.rev(nodes[0]), 0)
self.assertEqual(f.rev(nodes[1]), 1)
self.assertEqual(f.rev(nodes[2]), 2)
self.assertEqual(f.node(0), nodes[0])
self.assertEqual(f.node(1), nodes[1])
self.assertEqual(f.node(2), nodes[2])
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 def testdeltaagainstcensored(self):
# Attempt to apply a delta made against a censored revision.
f = self._makefilefn()
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 stored1 = storageutil.packmeta(
{
b'censored': b'tombstone',
},
b'',
)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(b'foo\n' * 30, None, tr, 0, f.nullid, f.nullid)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
# The node value doesn't matter since we can't verify it.
node1 = b'\xbb' * 20
Augie Fackler
formatting: blacken the codebase...
r43346 self._addrawrevisionfn(
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f, tr, node1, node0, f.nullid, 1, stored1, censored=True
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
delta = mdiff.textdiff(b'bar\n' * 30, (b'bar\n' * 30) + b'baz\n')
Raphaël Gomès
delta: add sidedata field to revision delta...
r47446 deltas = [
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 (b'\xcc' * 20, node1, f.nullid, b'\x01' * 20, node1, delta, 0, {})
Raphaël Gomès
delta: add sidedata field to revision delta...
r47446 ]
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
with self._maketransactionfn() as tr:
with self.assertRaises(error.CensoredBaseError):
f.addgroup(deltas, lambda x: 0, tr)
def testcensorrevisionbasic(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(b'foo\n' * 30, None, tr, 0, f.nullid, f.nullid)
node1 = f.add(b'foo\n' * 31, None, tr, 1, node0, f.nullid)
node2 = f.add(b'foo\n' * 32, None, tr, 2, node1, f.nullid)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
with self._maketransactionfn() as tr:
f.censorrevision(tr, node1)
self.assertEqual(len(f), 3)
self.assertEqual(list(f.revs()), [0, 1, 2])
self.assertEqual(f.read(node0), b'foo\n' * 30)
Gregory Szorc
revlog: rewrite censoring logic...
r40092 self.assertEqual(f.read(node2), b'foo\n' * 32)
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087
Gregory Szorc
revlog: rewrite censoring logic...
r40092 with self.assertRaises(error.CensoredNodeError):
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 f.read(node1)
Gregory Szorc
testing: add file storage tests for getstrippoint() and strip()...
r40086 def testgetstrippointnoparents(self):
# N revisions where none have parents.
f = self._makefilefn()
with self._maketransactionfn() as tr:
for rev in range(10):
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f.add(b'%d' % rev, None, tr, rev, f.nullid, f.nullid)
Gregory Szorc
testing: add file storage tests for getstrippoint() and strip()...
r40086
for rev in range(10):
self.assertEqual(f.getstrippoint(rev), (rev, set()))
def testgetstrippointlinear(self):
# N revisions in a linear chain.
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 p1 = f.nullid
Gregory Szorc
testing: add file storage tests for getstrippoint() and strip()...
r40086
for rev in range(10):
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f.add(b'%d' % rev, None, tr, rev, p1, f.nullid)
Gregory Szorc
testing: add file storage tests for getstrippoint() and strip()...
r40086
for rev in range(10):
self.assertEqual(f.getstrippoint(rev), (rev, set()))
def testgetstrippointmultipleheads(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(b'0', None, tr, 0, f.nullid, f.nullid)
node1 = f.add(b'1', None, tr, 1, node0, f.nullid)
f.add(b'2', None, tr, 2, node1, f.nullid)
f.add(b'3', None, tr, 3, node0, f.nullid)
f.add(b'4', None, tr, 4, node0, f.nullid)
Gregory Szorc
testing: add file storage tests for getstrippoint() and strip()...
r40086
for rev in range(5):
self.assertEqual(f.getstrippoint(rev), (rev, set()))
def testgetstrippointearlierlinkrevs(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 node0 = f.add(b'0', None, tr, 0, f.nullid, f.nullid)
f.add(b'1', None, tr, 10, node0, f.nullid)
f.add(b'2', None, tr, 5, node0, f.nullid)
Gregory Szorc
testing: add file storage tests for getstrippoint() and strip()...
r40086
self.assertEqual(f.getstrippoint(0), (0, set()))
self.assertEqual(f.getstrippoint(1), (1, set()))
self.assertEqual(f.getstrippoint(2), (1, set()))
self.assertEqual(f.getstrippoint(3), (1, set()))
self.assertEqual(f.getstrippoint(4), (1, set()))
self.assertEqual(f.getstrippoint(5), (1, set()))
self.assertEqual(f.getstrippoint(6), (1, {2}))
self.assertEqual(f.getstrippoint(7), (1, {2}))
self.assertEqual(f.getstrippoint(8), (1, {2}))
self.assertEqual(f.getstrippoint(9), (1, {2}))
self.assertEqual(f.getstrippoint(10), (1, {2}))
self.assertEqual(f.getstrippoint(11), (3, set()))
def teststripempty(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
f.strip(0, tr)
self.assertEqual(len(f), 0)
def teststripall(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 p1 = f.nullid
Gregory Szorc
testing: add file storage tests for getstrippoint() and strip()...
r40086 for rev in range(10):
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 p1 = f.add(b'%d' % rev, None, tr, rev, p1, f.nullid)
Gregory Szorc
testing: add file storage tests for getstrippoint() and strip()...
r40086
self.assertEqual(len(f), 10)
with self._maketransactionfn() as tr:
f.strip(0, tr)
self.assertEqual(len(f), 0)
def teststrippartial(self):
f = self._makefilefn()
with self._maketransactionfn() as tr:
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 f.add(b'0', None, tr, 0, f.nullid, f.nullid)
node1 = f.add(b'1', None, tr, 5, f.nullid, f.nullid)
node2 = f.add(b'2', None, tr, 10, f.nullid, f.nullid)
Gregory Szorc
testing: add file storage tests for getstrippoint() and strip()...
r40086
self.assertEqual(len(f), 3)
with self._maketransactionfn() as tr:
f.strip(11, tr)
self.assertEqual(len(f), 3)
with self._maketransactionfn() as tr:
f.strip(10, tr)
self.assertEqual(len(f), 2)
with self.assertRaises(error.LookupError):
f.rev(node2)
with self._maketransactionfn() as tr:
f.strip(6, tr)
self.assertEqual(len(f), 2)
with self._maketransactionfn() as tr:
f.strip(3, tr)
self.assertEqual(len(f), 1)
with self.assertRaises(error.LookupError):
f.rev(node1)
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 def makeifileindextests(makefilefn, maketransactionfn, addrawrevisionfn):
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 """Create a unittest.TestCase class suitable for testing file storage.
``makefilefn`` is a callable which receives the test case as an
argument and returns an object implementing the ``ifilestorage`` interface.
``maketransactionfn`` is a callable which receives the test case as an
argument and returns a transaction object.
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 ``addrawrevisionfn`` is a callable which receives arguments describing a
low-level revision to add. This callable allows the insertion of
potentially bad data into the store in order to facilitate testing.
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 Returns a type that is a ``unittest.TestCase`` that can be used for
testing the object implementing the file storage interface. Simply
assign the returned value to a module-level attribute and a test loader
should find and run it automatically.
"""
d = {
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 '_makefilefn': makefilefn,
'_maketransactionfn': maketransactionfn,
'_addrawrevisionfn': addrawrevisionfn,
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 }
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 return type('ifileindextests', (ifileindextests,), d)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 def makeifiledatatests(makefilefn, maketransactionfn, addrawrevisionfn):
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 d = {
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 '_makefilefn': makefilefn,
'_maketransactionfn': maketransactionfn,
'_addrawrevisionfn': addrawrevisionfn,
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 }
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 return type('ifiledatatests', (ifiledatatests,), d)
Gregory Szorc
testing: add interface unit tests for file storage...
r39808
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
testing: add file storage integration for bad hashes and censoring...
r40087 def makeifilemutationtests(makefilefn, maketransactionfn, addrawrevisionfn):
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 d = {
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 '_makefilefn': makefilefn,
'_maketransactionfn': maketransactionfn,
'_addrawrevisionfn': addrawrevisionfn,
Gregory Szorc
testing: add interface unit tests for file storage...
r39808 }
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 return type('ifilemutationtests', (ifilemutationtests,), d)