( )⚙ D2721 util: observable proxy objects for sockets

This is an archive of the discontinued Mercurial Phabricator instance.

util: observable proxy objects for sockets
ClosedPublic

Authored by indygreg on Mar 8 2018, 12:31 AM.

Details

Summary

We previously introduced proxy objects and observers for file objects
to help implement low-level tests for the SSH wire protocol.

In this commit, we do the same for sockets in order to help test the
HTTP server.

We only proxy/observe some socket methods. I didn't feel like
implementing all the methods because there are so many of them and
implementing them will provide no short term value. We can always
implement them later.

  1. no-check-commit because we implement foo_bar methods on stdlib types

Diff Detail

Repository
rHG Mercurial
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

indygreg created this revision.Mar 8 2018, 12:31 AM
indygreg updated this revision to Diff 6972.Mar 12 2018, 8:07 PM
indygreg planned changes to this revision.Mar 13 2018, 1:38 PM

I have significant changes to this series in flight. It's worth holding off on review.

indygreg requested review of this revision.

This series should now be ready to review.

fileobjectproxy needed __nonzero__()/__bool__(). Does socketproxy need it for consistency?

indygreg updated this revision to Diff 7007.Mar 13 2018, 9:15 PM
durin42 accepted this revision.Mar 19 2018, 9:36 PM
This revision is now accepted and ready to land.Mar 19 2018, 9:36 PM
This revision was automatically updated to reflect the committed changes.
pulkit added a subscriber: pulkit.May 20 2018, 5:08 AM
pulkit added inline comments.
mercurial/util.py
1019

If I am understanding this correctly, this can lead to TypeError: not enough arguments for format string

pulkit added inline comments.May 20 2018, 5:27 AM
mercurial/util.py
1014

While debugging the test failure on Python 3.6, the caller at line 751 can pass 5 positional arguments.

Here is the traceback after running test-wireproto-command-branchmap.t:

+  ** Unknown exception encountered with possibly-broken third-party extension drawdag
+  ** which supports versions unknown of Mercurial.
+  ** Please disable drawdag and try your action again.
+  ** If that fixes the bug please report it to the extension author.
+  ** Python 3.6.5 (default, Mar 29 2018, 03:28:50) [GCC 5.4.0 20160609]
+  ** Mercurial Distributed SCM (version 4.6+251-5a87bf0bd343)
+  ** Extensions loaded: drawdag
+  Traceback (most recent call last):
+    File "/tmp/hgtests.esettwc6/install/bin/hg", line 41, in <module>
+      dispatch.run()
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/dispatch.py", line 90, in run
+      status = dispatch(req)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/dispatch.py", line 213, in dispatch
+      ret = _runcatch(req) or 0
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/dispatch.py", line 354, in _runcatch
+      return _callcatch(ui, _runcatchfunc)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/dispatch.py", line 362, in _callcatch
+      return scmutil.callcatch(ui, func)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/scmutil.py", line 161, in callcatch
+      return func()
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/dispatch.py", line 344, in _runcatchfunc
+      return _dispatch(req)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/dispatch.py", line 974, in _dispatch
+      cmdpats, cmdoptions)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/dispatch.py", line 730, in runcommand
+      ret = _runcommand(ui, options, cmd, d)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/dispatch.py", line 982, in _runcommand
+      return cmdfunc()
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/dispatch.py", line 971, in <lambda>
+      d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/util.py", line 1550, in check
+      return func(*args, **kwargs)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/debugcommands.py", line 2932, in debugwireproto
+      peer = httppeer.makepeer(ui, path, opener=opener)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/httppeer.py", line 951, in makepeer
+      respurl, info = performhandshake(ui, url, opener, requestbuilder)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/httppeer.py", line 871, in performhandshake
+      resp = sendrequest(ui, opener, req)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/httppeer.py", line 311, in sendrequest
+      res = opener.open(req)
+    File "/usr/lib/python3.6/urllib/request.py", line 526, in open
+      response = self._open(req, data)
+    File "/usr/lib/python3.6/urllib/request.py", line 544, in _open
+      '_open', req)
+    File "/usr/lib/python3.6/urllib/request.py", line 504, in _call_chain
+      result = func(*args)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/url.py", line 331, in http_open
+      return self.do_open(self._makeconnection, req)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/keepalive.py", line 240, in do_open
+      self._start_transaction(h, req)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/url.py", line 301, in _start_transaction
+      return keepalive.HTTPHandler._start_transaction(self, h, req)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/keepalive.py", line 343, in _start_transaction
+      h.endheaders()
+    File "/usr/lib/python3.6/http/client.py", line 1234, in endheaders
+      self._send_output(message_body, encode_chunked=encode_chunked)
+    File "/usr/lib/python3.6/http/client.py", line 1026, in _send_output
+      self.send(msg)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/keepalive.py", line 563, in safesend
+      self.connect()
+    File "/usr/lib/python3.6/http/client.py", line 937, in connect
+      self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/util.py", line 738, in setsockopt
+      r'setsockopt', *args, **kwargs)
+    File "/tmp/hgtests.esettwc6/install/lib/python/mercurial/util.py", line 679, in _observedcall
+      fn(res, *args, **kwargs)
+  TypeError: setsockopt() takes 4 positional arguments but 5 were given
+  [1]

I am not sure whether this exact code path is tested on Python 2 or not. Can you have a look?