##// END OF EJS Templates
wireprotov2: define and implement "manifestdata" command...
wireprotov2: define and implement "manifestdata" command The added command can be used for obtaining manifest data. Given a manifest path and set of manifest nodes, data about manifests can be retrieved. Unlike changeset data, we wish to emit deltas to describe manifest revisions. So the command uses the relatively new API for building delta requests and emitting them. The code calls into deltaparent(), which I'm not very keen of. There's still work to be done in delta generation land so implementation details of storage (e.g. exactly one delta is stored/available) don't creep into higher levels. But we can worry about this later (there is already a TODO on imanifestorage tracking this). On the subject of parent deltas, the server assumes parent revisions exist on the receiving end. This is obviously wrong for shallow clone. I've added TODOs to add a mechanism to the command to allow clients to specify desired behavior. This shouldn't be too difficult to implement. Another big change is that the client must explicitly request manifest nodes to retrieve. This is a major departure from "getbundle," where the server derives relevant manifests as it iterates changesets and sends them automatically. As implemented, the client must transmit each requested node to the server. At 20 bytes per node, we're looking at 2 MB per 100,000 nodes. Plus wire encoding overhead. This isn't ideal for clients with limited upload bandwidth. I plan to address this in the future by allowing alternate mechanisms for defining the revisions to retrieve. One idea is to define a range of changeset revisions whose manifest revisions to retrieve (similar to how "changesetdata" works). We almost certainly want an API to look up an individual manifest by node. And that's where I've chosen to start with the implementation. Again, a theme of this early exchangev2 work is I want to start by building primitives for accessing raw repository data first and see how far we can get with those before we need more complexity. Differential Revision: https://phab.mercurial-scm.org/D4488

File last commit:

r36799:ffa3026d default
r39673:c7a7c7e8 default
Show More
test-atomictempfile.py
125 lines | 4.2 KiB | text/x-python | PythonLexer
/ tests / test-atomictempfile.py
Pulkit Goyal
py3: make tests/test-atomictempfile.py use absolute_import
r29194 from __future__ import absolute_import
import glob
Greg Ward
atomictempfile: avoid infinite recursion in __del__()....
r14007 import os
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391 import shutil
Augie Fackler
cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime...
r36799 import stat
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391 import tempfile
Idan Kamara
test-atomictempfile: convert to unit test
r18666 import unittest
Pulkit Goyal
py3: make tests/test-atomictempfile.py use absolute_import
r29194 from mercurial import (
Pulkit Goyal
py3: use range instead on xrange on py3 in tests/test-atomictempfile.py...
r36299 pycompat,
Pulkit Goyal
py3: make tests/test-atomictempfile.py use absolute_import
r29194 util,
)
atomictempfile = util.atomictempfile
Greg Ward
atomictempfile: avoid infinite recursion in __del__()....
r14007
Pulkit Goyal
py3: use range instead on xrange on py3 in tests/test-atomictempfile.py...
r36299 if pycompat.ispy3:
xrange = range
Idan Kamara
test-atomictempfile: convert to unit test
r18666 class testatomictempfile(unittest.TestCase):
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391 def setUp(self):
Augie Fackler
tests: add missing b prefixes in test-atomictempfile.py...
r36634 self._testdir = tempfile.mkdtemp(b'atomictempfiletest')
self._filename = os.path.join(self._testdir, b'testfilename')
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391
def tearDown(self):
shutil.rmtree(self._testdir, True)
Martijn Pieters
atomictempfile: remove test ordering...
r29392 def testsimple(self):
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391 file = atomictempfile(self._filename)
self.assertFalse(os.path.isfile(self._filename))
tempfilename = file._tempname
self.assertTrue(tempfilename in glob.glob(
Augie Fackler
tests: add missing b prefixes in test-atomictempfile.py...
r36634 os.path.join(self._testdir, b'.testfilename-*')))
Greg Ward
atomictempfile: avoid infinite recursion in __del__()....
r14007
timeless
tests: mark test-atomictempfile.py write as binary
r29188 file.write(b'argh\n')
Idan Kamara
test-atomictempfile: convert to unit test
r18666 file.close()
Greg Ward
atomictempfile: avoid infinite recursion in __del__()....
r14007
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391 self.assertTrue(os.path.isfile(self._filename))
self.assertTrue(tempfilename not in glob.glob(
Augie Fackler
tests: add missing b prefixes in test-atomictempfile.py...
r36634 os.path.join(self._testdir, b'.testfilename-*')))
Greg Ward
atomictempfile: avoid infinite recursion in __del__()....
r14007
Idan Kamara
test-atomictempfile: convert to unit test
r18666 # discard() removes the temp file without making the write permanent
Martijn Pieters
atomictempfile: remove test ordering...
r29392 def testdiscard(self):
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391 file = atomictempfile(self._filename)
Idan Kamara
test-atomictempfile: convert to unit test
r18666 (dir, basename) = os.path.split(file._tempname)
Greg Ward
atomictempfile: avoid infinite recursion in __del__()....
r14007
timeless
tests: mark test-atomictempfile.py write as binary
r29188 file.write(b'yo\n')
Idan Kamara
test-atomictempfile: convert to unit test
r18666 file.discard()
Greg Ward
atomictempfile: avoid infinite recursion in __del__()....
r14007
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391 self.assertFalse(os.path.isfile(self._filename))
Augie Fackler
tests: add missing b prefixes in test-atomictempfile.py...
r36634 self.assertTrue(basename not in os.listdir(b'.'))
Idan Kamara
test-atomictempfile: convert to unit test
r18666
# if a programmer screws up and passes bad args to atomictempfile, they
# get a plain ordinary TypeError, not infinite recursion
Martijn Pieters
atomictempfile: remove test ordering...
r29392 def testoops(self):
Gregory Szorc
tests: use context manager form of assertRaises...
r32279 with self.assertRaises(TypeError):
atomictempfile()
Greg Ward
atomictempfile: avoid infinite recursion in __del__()....
r14007
FUJIWARA Katsunori
util: make atomictempfile avoid ambiguity of file stat if needed...
r29201 # checkambig=True avoids ambiguity of timestamp
Martijn Pieters
atomictempfile: remove test ordering...
r29392 def testcheckambig(self):
FUJIWARA Katsunori
util: make atomictempfile avoid ambiguity of file stat if needed...
r29201 def atomicwrite(checkambig):
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391 f = atomictempfile(self._filename, checkambig=checkambig)
Augie Fackler
tests: add missing b prefixes in test-atomictempfile.py...
r36634 f.write(b'FOO')
FUJIWARA Katsunori
util: make atomictempfile avoid ambiguity of file stat if needed...
r29201 f.close()
# try some times, because reproduction of ambiguity depends on
# "filesystem time"
for i in xrange(5):
atomicwrite(False)
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391 oldstat = os.stat(self._filename)
Augie Fackler
cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime...
r36799 if oldstat[stat.ST_CTIME] != oldstat[stat.ST_MTIME]:
FUJIWARA Katsunori
util: make atomictempfile avoid ambiguity of file stat if needed...
r29201 # subsequent changing never causes ambiguity
continue
repetition = 3
# repeat atomic write with checkambig=True, to examine
Mads Kiilerich
spelling: fixes of non-dictionary words
r30332 # whether st_mtime is advanced multiple times as expected
FUJIWARA Katsunori
util: make atomictempfile avoid ambiguity of file stat if needed...
r29201 for j in xrange(repetition):
atomicwrite(True)
Martijn Pieters
atomictempfile: use a tempdir to keep the test environment clean...
r29391 newstat = os.stat(self._filename)
Augie Fackler
cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime...
r36799 if oldstat[stat.ST_CTIME] != newstat[stat.ST_CTIME]:
FUJIWARA Katsunori
util: make atomictempfile avoid ambiguity of file stat if needed...
r29201 # timestamp ambiguity was naturally avoided while repetition
continue
# st_mtime should be advanced "repetition" times, because
Mads Kiilerich
spelling: fixes of non-dictionary words
r30332 # all atomicwrite() occurred at same time (in sec)
Augie Fackler
cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime...
r36799 oldtime = (oldstat[stat.ST_MTIME] + repetition) & 0x7fffffff
self.assertTrue(newstat[stat.ST_MTIME] == oldtime)
FUJIWARA Katsunori
util: make atomictempfile avoid ambiguity of file stat if needed...
r29201 # no more examination is needed, if assumption above is true
break
else:
# This platform seems too slow to examine anti-ambiguity
# of file timestamp (or test happened to be executed at
# bad timing). Exit silently in this case, because running
# on other faster platforms can detect problems
pass
Martijn Pieters
atomictempfile: add read to the supported file operations
r29393 def testread(self):
with open(self._filename, 'wb') as f:
f.write(b'foobar\n')
Augie Fackler
tests: add missing b prefixes in test-atomictempfile.py...
r36634 file = atomictempfile(self._filename, mode=b'rb')
Martijn Pieters
atomictempfile: add read to the supported file operations
r29393 self.assertTrue(file.read(), b'foobar\n')
file.discard()
Martijn Pieters
atomictempfile: add context manager support...
r29394 def testcontextmanagersuccess(self):
"""When the context closes, the file is closed"""
Augie Fackler
tests: add missing b prefixes in test-atomictempfile.py...
r36634 with atomictempfile(b'foo') as f:
self.assertFalse(os.path.isfile(b'foo'))
Martijn Pieters
atomictempfile: add context manager support...
r29394 f.write(b'argh\n')
Augie Fackler
tests: add missing b prefixes in test-atomictempfile.py...
r36634 self.assertTrue(os.path.isfile(b'foo'))
Martijn Pieters
atomictempfile: add context manager support...
r29394
def testcontextmanagerfailure(self):
"""On exception, the file is discarded"""
try:
Augie Fackler
tests: add missing b prefixes in test-atomictempfile.py...
r36634 with atomictempfile(b'foo') as f:
self.assertFalse(os.path.isfile(b'foo'))
Martijn Pieters
atomictempfile: add context manager support...
r29394 f.write(b'argh\n')
raise ValueError
except ValueError:
pass
Augie Fackler
tests: add missing b prefixes in test-atomictempfile.py...
r36634 self.assertFalse(os.path.isfile(b'foo'))
Martijn Pieters
atomictempfile: add context manager support...
r29394
Greg Ward
atomictempfile: avoid infinite recursion in __del__()....
r14007 if __name__ == '__main__':
Pulkit Goyal
py3: make tests/test-atomictempfile.py use absolute_import
r29194 import silenttestrunner
Idan Kamara
test-atomictempfile: convert to unit test
r18666 silenttestrunner.main(__name__)