tests/dummysmtpd.py
author Manuel Jacob <me@manueljacob.de>
Mon, 11 Jul 2022 01:51:20 +0200
branchstable
changeset 49378 094a5fa3cf52
parent 48875 6000f5b25c9b
child 50729 5644f6286618
permissions -rwxr-xr-x
procutil: make stream detection in make_line_buffered more correct and strict In make_line_buffered(), we don’t want to wrap the stream if we know that lines get flushed to the underlying raw stream already. Previously, the heuristic was too optimistic. It assumed that any stream which is not an instance of io.BufferedIOBase doesn’t need wrapping. However, there are buffered streams that aren’t instances of io.BufferedIOBase, like Mercurial’s own winstdout. The new logic is different in two ways: First, only for the check, if unwraps any combination of WriteAllWrapper and winstdout. Second, it skips wrapping the stream only if it is an instance of io.RawIOBase (or already wrapped). If it is an instance of io.BufferedIOBase, it gets wrapped. In any other case, the function raises an exception. This ensures that, if an unknown stream is passed or we add another wrapper in the future, we don’t wrap the stream if it’s already line buffered or not wrap the stream if it’s not line buffered. In fact, this was already helpful during development of this change. Without it, I possibly would have forgot that WriteAllWrapper needs to be ignored for the check, leading to unnecessary wrapping if stdout is unbuffered. The alternative would have been to always wrap unknown streams. However, I don’t think that anyone would benefit from being less strict. We can expect streams from the standard library to be subclassing either io.RawIOBase or io.BufferedIOBase, so running Mercurial in the standard way should not regress by this change. Py2exe might replace sys.stdout and sys.stderr, but that currently breaks Mercurial anyway and also these streams don’t claim to be interactive, so this function is not called for them.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47500
23f5ed6dbcb1 run-tests: stop writing a `python3` symlink pointing to python2
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45830
diff changeset
     1
#!/usr/bin/env python
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     2
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     3
"""dummy SMTP server for use in tests"""
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     4
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     5
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     6
import asyncore
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     7
import optparse
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     8
import smtpd
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     9
import ssl
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    10
import sys
35776
75bae69747f0 dummysmtpd: don't die on client connection errors
Matt Harbison <matt_harbison@yahoo.com>
parents: 30559
diff changeset
    11
import traceback
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    12
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    13
from mercurial import (
36566
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    14
    pycompat,
30506
d9d8d78e6bc9 server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 29556
diff changeset
    15
    server,
29556
1b8b6adb2365 tests: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29332
diff changeset
    16
    sslutil,
1b8b6adb2365 tests: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29332
diff changeset
    17
    ui as uimod,
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    18
)
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    19
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
    20
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    21
def log(msg):
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    22
    sys.stdout.write(msg)
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    23
    sys.stdout.flush()
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    24
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
    25
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    26
class dummysmtpserver(smtpd.SMTPServer):
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    27
    def __init__(self, localaddr):
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    28
        smtpd.SMTPServer.__init__(self, localaddr, remoteaddr=None)
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    29
39029
78f1899e4202 dummysmtpd: accept additional kwargs from stdlib smtpd
Augie Fackler <augie@google.com>
parents: 36566
diff changeset
    30
    def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    31
        log('%s from=%s to=%s\n' % (peer[0], mailfrom, ', '.join(rcpttos)))
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    32
35776
75bae69747f0 dummysmtpd: don't die on client connection errors
Matt Harbison <matt_harbison@yahoo.com>
parents: 30559
diff changeset
    33
    def handle_error(self):
75bae69747f0 dummysmtpd: don't die on client connection errors
Matt Harbison <matt_harbison@yahoo.com>
parents: 30559
diff changeset
    34
        # On Windows, a bad SSL connection sometimes generates a WSAECONNRESET.
75bae69747f0 dummysmtpd: don't die on client connection errors
Matt Harbison <matt_harbison@yahoo.com>
parents: 30559
diff changeset
    35
        # The default handler will shutdown this server, and then both the
75bae69747f0 dummysmtpd: don't die on client connection errors
Matt Harbison <matt_harbison@yahoo.com>
parents: 30559
diff changeset
    36
        # current connection and subsequent ones fail on the client side with
75bae69747f0 dummysmtpd: don't die on client connection errors
Matt Harbison <matt_harbison@yahoo.com>
parents: 30559
diff changeset
    37
        # "No connection could be made because the target machine actively
75bae69747f0 dummysmtpd: don't die on client connection errors
Matt Harbison <matt_harbison@yahoo.com>
parents: 30559
diff changeset
    38
        # refused it".  If we eat the error, then the client properly aborts in
75bae69747f0 dummysmtpd: don't die on client connection errors
Matt Harbison <matt_harbison@yahoo.com>
parents: 30559
diff changeset
    39
        # the expected way, and the server is available for subsequent requests.
75bae69747f0 dummysmtpd: don't die on client connection errors
Matt Harbison <matt_harbison@yahoo.com>
parents: 30559
diff changeset
    40
        traceback.print_exc()
75bae69747f0 dummysmtpd: don't die on client connection errors
Matt Harbison <matt_harbison@yahoo.com>
parents: 30559
diff changeset
    41
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
    42
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    43
class dummysmtpsecureserver(dummysmtpserver):
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    44
    def __init__(self, localaddr, certfile):
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    45
        dummysmtpserver.__init__(self, localaddr)
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    46
        self._certfile = certfile
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    47
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    48
    def handle_accept(self):
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    49
        pair = self.accept()
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    50
        if not pair:
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    51
            return
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    52
        conn, addr = pair
30559
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30506
diff changeset
    53
        ui = uimod.ui.load()
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    54
        try:
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    55
            # wrap_socket() would block, but we don't care
29556
1b8b6adb2365 tests: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29332
diff changeset
    56
            conn = sslutil.wrapserversocket(conn, ui, certfile=self._certfile)
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    57
        except ssl.SSLError:
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    58
            log('%s ssl error\n' % addr[0])
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    59
            conn.close()
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    60
            return
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    61
        smtpd.SMTPChannel(self, conn, addr)
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    62
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
    63
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    64
def run():
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    65
    try:
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    66
        asyncore.loop()
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    67
    except KeyboardInterrupt:
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    68
        pass
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    69
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
    70
36566
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    71
def _encodestrsonly(v):
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    72
    if isinstance(v, type(u'')):
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    73
        return v.encode('ascii')
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    74
    return v
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    75
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
    76
36566
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    77
def bytesvars(obj):
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    78
    unidict = vars(obj)
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    79
    bd = {k.encode('ascii'): _encodestrsonly(v) for k, v in unidict.items()}
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    80
    if bd[b'daemon_postexec'] is not None:
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    81
        bd[b'daemon_postexec'] = [
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
    82
            _encodestrsonly(v) for v in bd[b'daemon_postexec']
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
    83
        ]
36566
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    84
    return bd
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
    85
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
    86
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    87
def main():
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    88
    op = optparse.OptionParser()
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    89
    op.add_option('-d', '--daemon', action='store_true')
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    90
    op.add_option('--daemon-postexec', action='append')
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    91
    op.add_option('-p', '--port', type=int, default=8025)
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    92
    op.add_option('-a', '--address', default='localhost')
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    93
    op.add_option('--pid-file', metavar='FILE')
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    94
    op.add_option('--tls', choices=['none', 'smtps'], default='none')
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    95
    op.add_option('--certificate', metavar='FILE')
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    96
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    97
    opts, args = op.parse_args()
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    98
    if opts.tls == 'smtps' and not opts.certificate:
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    99
        op.error('--certificate must be specified')
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   100
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   101
    addr = (opts.address, opts.port)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
   102
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   103
    def init():
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   104
        if opts.tls == 'none':
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   105
            dummysmtpserver(addr)
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   106
        else:
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   107
            dummysmtpsecureserver(addr, opts.certificate)
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   108
        log('listening at %s:%d\n' % addr)
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   109
36566
ed96d1116302 tests: help dummysmtpd work on python 3
Augie Fackler <augie@google.com>
parents: 35776
diff changeset
   110
    server.runservice(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
   111
        bytesvars(opts),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
   112
        initfn=init,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
   113
        runfn=run,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
   114
        runargs=[pycompat.sysexecutable, pycompat.fsencode(__file__)]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
   115
        + pycompat.sysargv[1:],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
   116
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39029
diff changeset
   117
29332
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   118
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   119
if __name__ == '__main__':
2bb0ddd8267b tests: add dummy SMTP daemon for SSL tests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   120
    main()