From 61a0c8ce3f37de784194ce204b20b60faeae37c5 Mon Sep 17 00:00:00 2001 From: Hubert Plociniczak Date: Tue, 24 Oct 2023 15:01:10 +0200 Subject: [PATCH] Error on invalid capability acquire/release request (#8133) `capability/acquire` with an invalid method `executionContext/canModify` would previously timeout because the capability router simply didn't support that kind of capability request. Now rather than timing out, indicating a failure on LS, we report an error. Closes #8038. --- .../capability/CapabilityRouter.scala | 6 ++ .../websocket/json/CapabilitiesTest.scala | 81 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/CapabilitiesTest.scala diff --git a/engine/language-server/src/main/scala/org/enso/languageserver/capability/CapabilityRouter.scala b/engine/language-server/src/main/scala/org/enso/languageserver/capability/CapabilityRouter.scala index 41abae3843..c325e17be3 100644 --- a/engine/language-server/src/main/scala/org/enso/languageserver/capability/CapabilityRouter.scala +++ b/engine/language-server/src/main/scala/org/enso/languageserver/capability/CapabilityRouter.scala @@ -4,6 +4,8 @@ import akka.actor.{Actor, ActorRef, Props} import com.typesafe.scalalogging.LazyLogging import org.enso.languageserver.capability.CapabilityProtocol.{ AcquireCapability, + CapabilityAcquisitionBadRequest, + CapabilityReleaseBadRequest, ReleaseCapability } import org.enso.languageserver.data.{ @@ -65,6 +67,10 @@ class CapabilityRouter( CapabilityRegistration(ReceivesSuggestionsDatabaseUpdates()) ) => suggestionsHandler.forward(msg) + case AcquireCapability(_, _) => + sender() ! CapabilityAcquisitionBadRequest + case ReleaseCapability(_, _) => + sender() ! CapabilityReleaseBadRequest } } diff --git a/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/CapabilitiesTest.scala b/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/CapabilitiesTest.scala new file mode 100644 index 0000000000..e9cb8acf63 --- /dev/null +++ b/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/CapabilitiesTest.scala @@ -0,0 +1,81 @@ +package org.enso.languageserver.websocket.json + +import io.circe.literal._ +import io.circe.parser.parse +import io.circe.syntax.EncoderOps +import org.enso.polyglot.runtime.Runtime.Api + +import java.util.UUID + +class CapabilitiesTest extends BaseServerTest { + + "capability/acquire" must { + + "return an error response to the client when requesting it for `executionContext/canModify`" in { + val client = getInitialisedWsClient() + val contextId = createExecutionContext(client) + client.send(json""" + { "jsonrpc": "2.0", + "method": "capability/acquire", + "id": 1, + "params": { + "method" : "executionContext/canModify", + "registerOptions": { + "contextId" : $contextId + } + } + } + """) + val response = parse(client.expectMessage()).rightValue.asObject.value + response("jsonrpc") shouldEqual Some("2.0".asJson) + response("id") shouldEqual Some(1.asJson) + val err = response("error").value.asObject.value + err("message") shouldEqual Some("Service error".asJson) + } + } + + "capability/release" must { + + "return an error response to the client when requesting it for `executionContext/canModify`" in { + val client = getInitialisedWsClient() + val contextId = createExecutionContext(client) + client.send(json""" + { "jsonrpc": "2.0", + "method": "capability/release", + "id": 1, + "params": { + "method" : "executionContext/canModify", + "registerOptions": { + "contextId" : $contextId + } + } + } + """) + val response = parse(client.expectMessage()).rightValue.asObject.value + response("jsonrpc") shouldEqual Some("2.0".asJson) + response("id") shouldEqual Some(1.asJson) + val err = response("error").value.asObject.value + err("message") shouldEqual Some("Service error".asJson) + } + } + + private def createExecutionContext(client: WsTestClient): UUID = { + client.send(ExecutionContextJsonMessages.executionContextCreateRequest(0)) + val (requestId, contextId) = + runtimeConnectorProbe.receiveN(1).head match { + case Api.Request(requestId, Api.CreateContextRequest(contextId)) => + (requestId, contextId) + case msg => + fail(s"Unexpected message: $msg") + } + + runtimeConnectorProbe.lastSender ! Api.Response( + requestId, + Api.CreateContextResponse(contextId) + ) + client.expectJson( + ExecutionContextJsonMessages.executionContextCreateResponse(0, contextId) + ) + contextId + } +}