comparison src/testdir/test_channel_lsp.py @ 33318:41e2414d2886 v9.0.1924

patch 9.0.1924: LSP server message still wrongly handled (after 9.0.1922) Commit: https://github.com/vim/vim/commit/1926ae41845c3b6e2045b29225365c8a2e4eb1da Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Thu Sep 21 16:36:28 2023 +0200 patch 9.0.1924: LSP server message still wrongly handled (after 9.0.1922) Problem: LSP server message still wrongly handled (after 9.0.1922) Solution: Handle 'method' messages properly, don't discard them, add tests. closes: #13141 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
author Christian Brabandt <cb@256bit.org>
date Thu, 21 Sep 2023 16:45:06 +0200
parents dd8da8f1c2bc
children
comparison
equal deleted inserted replaced
33317:e81313a3aacb 33318:41e2414d2886
27 def debuglog(self, msg): 27 def debuglog(self, msg):
28 if self.debug: 28 if self.debug:
29 with open("Xlspserver.log", "a") as myfile: 29 with open("Xlspserver.log", "a") as myfile:
30 myfile.write(msg) 30 myfile.write(msg)
31 31
32 def send_lsp_msg(self, msgid, resp_dict): 32 def send_lsp_req(self, msgid, method, params):
33 v = {'jsonrpc': '2.0', 'id': msgid, 'method': method}
34 if len(params) != 0:
35 v['params'] = params
36 s = json.dumps(v)
37 req = "Content-Length: " + str(len(s)) + "\r\n"
38 req += "Content-Type: application/vscode-jsonrpc; charset=utf-8\r\n"
39 req += "\r\n"
40 req += s
41 if self.debug:
42 self.debuglog("SEND: ({0} bytes) '{1}'\n".format(len(req), req))
43 self.request.sendall(req.encode('utf-8'))
44
45 def send_lsp_resp(self, msgid, resp_dict):
33 v = {'jsonrpc': '2.0', 'result': resp_dict} 46 v = {'jsonrpc': '2.0', 'result': resp_dict}
34 if msgid != -1: 47 if msgid != -1:
35 v['id'] = msgid 48 v['id'] = msgid
36 s = json.dumps(v) 49 s = json.dumps(v)
37 resp = "Content-Length: " + str(len(s)) + "\r\n" 50 resp = "Content-Length: " + str(len(s)) + "\r\n"
116 resp += s 129 resp += s
117 self.request.sendall(resp.encode('utf-8')) 130 self.request.sendall(resp.encode('utf-8'))
118 131
119 def do_ping(self, payload): 132 def do_ping(self, payload):
120 time.sleep(0.2) 133 time.sleep(0.2)
121 self.send_lsp_msg(payload['id'], 'alive') 134 self.send_lsp_resp(payload['id'], 'alive')
122 135
123 def do_echo(self, payload): 136 def do_echo(self, payload):
124 self.send_lsp_msg(-1, payload) 137 self.send_lsp_resp(-1, payload)
125 138
126 def do_simple_rpc(self, payload): 139 def do_simple_rpc(self, payload):
127 # test for a simple RPC request 140 # test for a simple RPC request
128 self.send_lsp_msg(payload['id'], 'simple-rpc') 141 self.send_lsp_resp(payload['id'], 'simple-rpc')
129 142
130 def do_rpc_with_notif(self, payload): 143 def do_rpc_with_notif(self, payload):
131 # test for sending a notification before replying to a request message 144 # test for sending a notification before replying to a request message
132 self.send_lsp_msg(-1, 'rpc-with-notif-notif') 145 self.send_lsp_resp(-1, 'rpc-with-notif-notif')
133 # sleep for some time to make sure the notification is delivered 146 # sleep for some time to make sure the notification is delivered
134 time.sleep(0.2) 147 time.sleep(0.2)
135 self.send_lsp_msg(payload['id'], 'rpc-with-notif-resp') 148 self.send_lsp_resp(payload['id'], 'rpc-with-notif-resp')
136 149
137 def do_wrong_payload(self, payload): 150 def do_wrong_payload(self, payload):
138 # test for sending a non dict payload 151 # test for sending a non dict payload
139 self.send_wrong_payload() 152 self.send_wrong_payload()
140 time.sleep(0.2) 153 time.sleep(0.2)
141 self.send_lsp_msg(-1, 'wrong-payload') 154 self.send_lsp_resp(-1, 'wrong-payload')
142 155
143 def do_large_payload(self, payload): 156 def do_large_payload(self, payload):
144 # test for sending a large (> 64K) payload 157 # test for sending a large (> 64K) payload
145 self.send_lsp_msg(payload['id'], payload) 158 self.send_lsp_resp(payload['id'], payload)
146 159
147 def do_rpc_resp_incorrect_id(self, payload): 160 def do_rpc_resp_incorrect_id(self, payload):
148 self.send_lsp_msg(-1, 'rpc-resp-incorrect-id-1') 161 self.send_lsp_resp(-1, 'rpc-resp-incorrect-id-1')
149 self.send_lsp_msg(-1, 'rpc-resp-incorrect-id-2') 162 self.send_lsp_resp(-1, 'rpc-resp-incorrect-id-2')
150 self.send_lsp_msg(1, 'rpc-resp-incorrect-id-3') 163 self.send_lsp_resp(1, 'rpc-resp-incorrect-id-3')
151 time.sleep(0.2) 164 time.sleep(0.2)
152 self.send_lsp_msg(payload['id'], 'rpc-resp-incorrect-id-4') 165 self.send_lsp_resp(payload['id'], 'rpc-resp-incorrect-id-4')
153 166
154 def do_simple_notif(self, payload): 167 def do_simple_notif(self, payload):
155 # notification message test 168 # notification message test
156 self.send_lsp_msg(-1, 'simple-notif') 169 self.send_lsp_resp(-1, 'simple-notif')
157 170
158 def do_multi_notif(self, payload): 171 def do_multi_notif(self, payload):
159 # send multiple notifications 172 # send multiple notifications
160 self.send_lsp_msg(-1, 'multi-notif1') 173 self.send_lsp_resp(-1, 'multi-notif1')
161 self.send_lsp_msg(-1, 'multi-notif2') 174 self.send_lsp_resp(-1, 'multi-notif2')
162 175
163 def do_msg_with_id(self, payload): 176 def do_msg_with_id(self, payload):
164 self.send_lsp_msg(payload['id'], 'msg-with-id') 177 self.send_lsp_resp(payload['id'], 'msg-with-id')
165 178
166 def do_msg_specific_cb(self, payload): 179 def do_msg_specific_cb(self, payload):
167 self.send_lsp_msg(payload['id'], 'msg-specific-cb') 180 self.send_lsp_resp(payload['id'], 'msg-specific-cb')
168 181
169 def do_server_req(self, payload): 182 def do_server_req(self, payload):
170 self.send_lsp_msg(201, {'method': 'checkhealth', 'params': {'a': 20}}) 183 self.send_lsp_resp(201, {'method': 'checkhealth', 'params': {'a': 20}})
171 184
172 def do_extra_hdr_fields(self, payload): 185 def do_extra_hdr_fields(self, payload):
173 self.send_extra_hdr_fields(payload['id'], 'extra-hdr-fields') 186 self.send_extra_hdr_fields(payload['id'], 'extra-hdr-fields')
174 187
175 def do_delayed_payload(self, payload): 188 def do_delayed_payload(self, payload):
187 def do_empty_header(self, payload): 200 def do_empty_header(self, payload):
188 self.send_empty_header(payload['id'], 'empty-header') 201 self.send_empty_header(payload['id'], 'empty-header')
189 202
190 def do_empty_payload(self, payload): 203 def do_empty_payload(self, payload):
191 self.send_empty_payload() 204 self.send_empty_payload()
205
206 def do_server_req_in_middle(self, payload):
207 # Send a notification message to the client in the middle of processing
208 # a request message from the client
209 self.send_lsp_req(-1, 'server-req-in-middle', {'text': 'server-notif'})
210 # Send a request message to the client in the middle of processing a
211 # request message from the client.
212 self.send_lsp_req(payload['id'], 'server-req-in-middle', {'text': 'server-req'})
213
214 def do_server_req_in_middle_resp(self, payload):
215 # After receiving a response from the client send the response to the
216 # client request.
217 self.send_lsp_resp(payload['id'], {'text': 'server-resp'})
192 218
193 def process_msg(self, msg): 219 def process_msg(self, msg):
194 try: 220 try:
195 decoded = json.loads(msg) 221 decoded = json.loads(msg)
196 if 'method' in decoded: 222 if 'method' in decoded:
211 'delayed-payload': self.do_delayed_payload, 237 'delayed-payload': self.do_delayed_payload,
212 'hdr-without-len': self.do_hdr_without_len, 238 'hdr-without-len': self.do_hdr_without_len,
213 'hdr-with-wrong-len': self.do_hdr_with_wrong_len, 239 'hdr-with-wrong-len': self.do_hdr_with_wrong_len,
214 'hdr-with-negative-len': self.do_hdr_with_negative_len, 240 'hdr-with-negative-len': self.do_hdr_with_negative_len,
215 'empty-header': self.do_empty_header, 241 'empty-header': self.do_empty_header,
216 'empty-payload': self.do_empty_payload 242 'empty-payload': self.do_empty_payload,
243 'server-req-in-middle': self.do_server_req_in_middle,
244 'server-req-in-middle-resp': self.do_server_req_in_middle_resp,
217 } 245 }
218 if decoded['method'] in test_map: 246 if decoded['method'] in test_map:
219 test_map[decoded['method']](decoded) 247 test_map[decoded['method']](decoded)
220 else: 248 else:
221 self.debuglog("Error: Unsupported method - " + decoded['method'] + "\n") 249 self.debuglog("Error: Unsupported method - " + decoded['method'] + "\n")