Mercurial > vim
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") |