Imported Upstream version 7.59.0
[platform/upstream/curl.git] / tests / dictserver.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 """ DICT server """
5
6 from __future__ import (absolute_import, division, print_function,
7                         unicode_literals)
8 import argparse
9 import os
10 import sys
11 import logging
12 try:  # Python 2
13     import SocketServer as socketserver
14 except ImportError:  # Python 3
15     import socketserver
16
17
18 log = logging.getLogger(__name__)
19 HOST = "localhost"
20
21 # The strings that indicate the test framework is checking our aliveness
22 VERIFIED_REQ = b"verifiedserver"
23 VERIFIED_RSP = "WE ROOLZ: {pid}"
24
25
26 def dictserver(options):
27     """
28     Starts up a TCP server with a DICT handler and serves DICT requests
29     forever.
30     """
31     if options.pidfile:
32         pid = os.getpid()
33         with open(options.pidfile, "w") as f:
34             f.write("{0}".format(pid))
35
36     local_bind = (HOST, options.port)
37     log.info("[DICT] Listening on %s", local_bind)
38
39     # Need to set the allow_reuse on the class, not on the instance.
40     socketserver.TCPServer.allow_reuse_address = True
41     server = socketserver.TCPServer(local_bind, DictHandler)
42     server.serve_forever()
43
44     return ScriptRC.SUCCESS
45
46
47 class DictHandler(socketserver.BaseRequestHandler):
48     """Handler class for DICT connections.
49
50     """
51     def handle(self):
52         """
53         Simple function which responds to all queries with a 552.
54         """
55         try:
56             # First, send a response to allow the server to continue.
57             rsp = "220 dictserver <xnooptions> <msgid@msgid>\n"
58             self.request.sendall(rsp.encode("utf-8"))
59
60             # Receive the request.
61             data = self.request.recv(1024).strip()
62             log.debug("[DICT] Incoming data: %r", data)
63
64             if VERIFIED_REQ in data:
65                 log.debug("[DICT] Received verification request from test "
66                           "framework")
67                 response_data = VERIFIED_RSP.format(pid=os.getpid())
68             else:
69                 log.debug("[DICT] Received normal request")
70                 response_data = "No matches"
71
72             # Send back a failure to find.
73             response = "552 {0}\n".format(response_data)
74             log.debug("[DICT] Responding with %r", response)
75             self.request.sendall(response.encode("utf-8"))
76
77         except IOError:
78             log.exception("[DICT] IOError hit during request")
79
80
81 def get_options():
82     parser = argparse.ArgumentParser()
83
84     parser.add_argument("--port", action="store", default=9016,
85                         type=int, help="port to listen on")
86     parser.add_argument("--verbose", action="store", type=int, default=0,
87                         help="verbose output")
88     parser.add_argument("--pidfile", action="store",
89                         help="file name for the PID")
90     parser.add_argument("--logfile", action="store",
91                         help="file name for the log")
92     parser.add_argument("--srcdir", action="store", help="test directory")
93     parser.add_argument("--id", action="store", help="server ID")
94     parser.add_argument("--ipv4", action="store_true", default=0,
95                         help="IPv4 flag")
96
97     return parser.parse_args()
98
99
100 def setup_logging(options):
101     """
102     Set up logging from the command line options
103     """
104     root_logger = logging.getLogger()
105     add_stdout = False
106
107     formatter = logging.Formatter("%(asctime)s %(levelname)-5.5s %(message)s")
108
109     # Write out to a logfile
110     if options.logfile:
111         handler = logging.FileHandler(options.logfile, mode="w")
112         handler.setFormatter(formatter)
113         handler.setLevel(logging.DEBUG)
114         root_logger.addHandler(handler)
115     else:
116         # The logfile wasn't specified. Add a stdout logger.
117         add_stdout = True
118
119     if options.verbose:
120         # Add a stdout logger as well in verbose mode
121         root_logger.setLevel(logging.DEBUG)
122         add_stdout = True
123     else:
124         root_logger.setLevel(logging.INFO)
125
126     if add_stdout:
127         stdout_handler = logging.StreamHandler(sys.stdout)
128         stdout_handler.setFormatter(formatter)
129         stdout_handler.setLevel(logging.DEBUG)
130         root_logger.addHandler(stdout_handler)
131
132
133 class ScriptRC(object):
134     """Enum for script return codes"""
135     SUCCESS = 0
136     FAILURE = 1
137     EXCEPTION = 2
138
139
140 class ScriptException(Exception):
141     pass
142
143
144 if __name__ == '__main__':
145     # Get the options from the user.
146     options = get_options()
147
148     # Setup logging using the user options
149     setup_logging(options)
150
151     # Run main script.
152     try:
153         rc = dictserver(options)
154     except Exception as e:
155         log.exception(e)
156         rc = ScriptRC.EXCEPTION
157
158     log.info("[DICT] Returning %d", rc)
159     sys.exit(rc)