tests/test-lfs-serve-access.t
changeset 37689 a7dbda94c86a
parent 37617 b03f2e0fdb88
child 37690 726c4102db9e
--- a/tests/test-lfs-serve-access.t	Sat Apr 14 10:43:19 2018 -0400
+++ b/tests/test-lfs-serve-access.t	Sat Apr 07 12:48:21 2018 -0400
@@ -4,7 +4,6 @@
   > [extensions]
   > lfs=
   > [lfs]
-  > url=http://localhost:$HGPORT/.git/info/lfs
   > track=all()
   > [web]
   > push_ssl = False
@@ -149,3 +148,187 @@
   $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
   $LOCALIP - - [$LOGDATE$] "POST /subdir/mount/point/.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
   $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e HTTP/1.1" 200 - (glob)
+
+  $ cat >> $TESTTMP/lfsstoreerror.py <<EOF
+  > import errno
+  > from hgext.lfs import blobstore
+  > 
+  > _numverifies = 0
+  > _readerr = True
+  > 
+  > def reposetup(ui, repo):
+  >     # Nothing to do with a remote repo
+  >     if not repo.local():
+  >         return
+  > 
+  >     store = repo.svfs.lfslocalblobstore
+  >     class badstore(store.__class__):
+  >         def download(self, oid, src):
+  >             '''Called in the server to handle reading from the client in a
+  >             PUT request.'''
+  >             origread = src.read
+  >             def _badread(nbytes):
+  >                 # Simulate bad data/checksum failure from the client
+  >                 return b'0' * len(origread(nbytes))
+  >             src.read = _badread
+  >             super(badstore, self).download(oid, src)
+  > 
+  >         def _read(self, vfs, oid, verify):
+  >             '''Called in the server to read data for a GET request, and then
+  >             calls self._verify() on it before returning.'''
+  >             global _readerr
+  >             # One time simulation of a read error
+  >             if _readerr:
+  >                 _readerr = False
+  >                 raise IOError(errno.EIO, '%s: I/O error' % oid)
+  >             # Simulate corrupt content on client download
+  >             blobstore._verify(oid, 'dummy content')
+  > 
+  >         def verify(self, oid):
+  >             '''Called in the server to populate the Batch API response,
+  >             letting the client re-upload if the file is corrupt.'''
+  >             # Fail verify in Batch API for one clone command and one push
+  >             # command with an IOError.  Then let it through to access other
+  >             # functions.  Checksum failure is tested elsewhere.
+  >             global _numverifies
+  >             _numverifies += 1
+  >             if _numverifies <= 2:
+  >                 raise IOError(errno.EIO, '%s: I/O error' % oid)
+  >             return super(badstore, self).verify(oid)
+  > 
+  >     store.__class__ = badstore
+  > EOF
+
+  $ rm -rf `hg config lfs.usercache`
+  $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
+  $ hg --config "lfs.usercache=$TESTTMP/servercache" \
+  >    --config extensions.lfsstoreerror=$TESTTMP/lfsstoreerror.py \
+  >    -R server serve -d \
+  >    -p $HGPORT1 --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+Test an I/O error in localstore.verify() (Batch API) with GET
+
+  $ hg clone http://localhost:$HGPORT1 httpclone2
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets 525251863cad
+  updating to branch default
+  abort: LFS server error for "lfs.bin": Internal server error!
+  [255]
+
+Test an I/O error in localstore.verify() (Batch API) with PUT
+
+  $ echo foo > client/lfs.bin
+  $ hg -R client ci -m 'mod lfs'
+  $ hg -R client push http://localhost:$HGPORT1
+  pushing to http://localhost:$HGPORT1/
+  searching for changes
+  abort: LFS server error for "unknown": Internal server error!
+  [255]
+TODO: figure out how to associate the file name in the error above
+
+Test a bad checksum sent by the client in the transfer API
+
+  $ hg -R client push http://localhost:$HGPORT1
+  pushing to http://localhost:$HGPORT1/
+  searching for changes
+  abort: HTTP error: HTTP Error 500: Internal Server Error (oid=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, action=upload)!
+  [255]
+
+  $ echo 'test lfs file' > server/lfs3.bin
+  $ hg --config experimental.lfs.disableusercache=True \
+  >    -R server ci -Aqm 'another lfs file'
+  $ hg -R client pull -q http://localhost:$HGPORT1
+
+Test an I/O error during the processing of the GET request
+
+  $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
+  >    -R client update -r tip
+  abort: HTTP error: HTTP Error 500: Internal Server Error (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)!
+  [255]
+
+Test a checksum failure during the processing of the GET request
+
+  $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
+  >    -R client update -r tip
+  abort: HTTP error: HTTP Error 500: Internal Server Error (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)!
+  [255]
+
+  $ $PYTHON $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
+
+  $ cat $TESTTMP/access.log
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
+  $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c HTTP/1.1" 500 - (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=525251863cad618e55d483555f3d00a2ca99597e&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
+  $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 500 - (glob)
+  $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 500 - (glob)
+
+  $ grep -v '  File "' $TESTTMP/errors.log
+  $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c': (glob)
+  Traceback (most recent call last):
+      self.do_write()
+      self.do_hgweb()
+      for chunk in self.server.application(env, self._start_response):
+      for r in self._runwsgi(req, res, repo):
+      rctx, req, res, self.check_perm)
+      return func(*(args + a), **kw)
+      lambda perm:
+      localstore.download(oid, req.bodyfh)
+      super(badstore, self).download(oid, src)
+      raise error.Abort(_('corrupt remote lfs object: %s') % oid)
+  Abort: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
+  
+  $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
+  Traceback (most recent call last):
+      self.do_write()
+      self.do_hgweb()
+      for chunk in self.server.application(env, self._start_response):
+      for r in self._runwsgi(req, res, repo):
+      rctx, req, res, self.check_perm)
+      return func(*(args + a), **kw)
+      lambda perm:
+      res.setbodybytes(localstore.read(oid))
+      blob = self._read(self.vfs, oid, verify)
+      raise IOError(errno.EIO, '%s: I/O error' % oid)
+  IOError: [Errno 5] 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d: I/O error
+  
+  $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
+  Traceback (most recent call last):
+      self.do_write()
+      self.do_hgweb()
+      for chunk in self.server.application(env, self._start_response):
+      for r in self._runwsgi(req, res, repo):
+      rctx, req, res, self.check_perm)
+      return func(*(args + a), **kw)
+      lambda perm:
+      res.setbodybytes(localstore.read(oid))
+      blob = self._read(self.vfs, oid, verify)
+      blobstore._verify(oid, 'dummy content')
+      hint=_('run hg verify'))
+  Abort: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d
+