feat: add JSON-RPC control adapter
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
rvboxv1 "github.com/rvbox/rvbox/gen/go/rvbox/v1"
|
||||
"github.com/rvbox/rvbox/internal/server/store"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
)
|
||||
|
||||
func TestJSONRPCUnaryMatchesControlService_HP_CTL_15(t *testing.T) {
|
||||
persistence, err := store.Open(context.Background(), store.Options{DataDir: filepath.Join(t.TempDir(), "state"), BusyTimeout: time.Second})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer persistence.Close()
|
||||
registerControlClient(t, persistence, "win-a", rvboxv1.Platform_PLATFORM_WINDOWS, rvboxv1.ShellType_SHELL_POWERSHELL, 9)
|
||||
service, err := NewService(Options{Store: persistence, CursorKey: bytesKey()})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
handler := httptest.NewServer(NewJSONRPCHandler(service, 1<<20))
|
||||
defer handler.Close()
|
||||
requestID := fixedIssue(0xaf).String()
|
||||
params, err := protojson.Marshal(&rvboxv1.RunCommandRequest{TargetClientId: "win-a", RequestId: requestID, Spec: &rvboxv1.ExecutionSpec{Source: &rvboxv1.ExecutionSpec_CommandText{CommandText: "echo rpc"}}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
body, _ := json.Marshal(map[string]any{"jsonrpc": "2.0", "id": 7, "method": "runCommand", "params": json.RawMessage(params)})
|
||||
response, err := http.Post(handler.URL, "application/json", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
encoded, _ := io.ReadAll(response.Body)
|
||||
var envelope struct {
|
||||
Result json.RawMessage `json:"result"`
|
||||
Error json.RawMessage `json:"error"`
|
||||
}
|
||||
if err := json.Unmarshal(encoded, &envelope); err != nil || len(envelope.Error) != 0 {
|
||||
t.Fatalf("JSON-RPC response = %s, %v", encoded, err)
|
||||
}
|
||||
result := &rvboxv1.RunCommandResponse{}
|
||||
if err := protojson.Unmarshal(envelope.Result, result); err != nil || result.GetIssueUuid() != requestID {
|
||||
t.Fatalf("JSON-RPC result = %s, %v", envelope.Result, err)
|
||||
}
|
||||
unknown, _ := json.Marshal(map[string]any{"jsonrpc": "2.0", "id": "x", "method": "notARealMethod", "params": map[string]any{}})
|
||||
unknownResponse, err := http.Post(handler.URL, "application/json", bytes.NewReader(unknown))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer unknownResponse.Body.Close()
|
||||
unknownBody, _ := io.ReadAll(unknownResponse.Body)
|
||||
if !bytes.Contains(unknownBody, []byte(`-32601`)) {
|
||||
t.Fatalf("unknown method response = %s", unknownBody)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONRPCRejectsOversizeAndMalformedRequests_BH_CTL_16(t *testing.T) {
|
||||
persistence, err := store.Open(context.Background(), store.Options{DataDir: filepath.Join(t.TempDir(), "state"), BusyTimeout: time.Second})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer persistence.Close()
|
||||
service, err := NewService(Options{Store: persistence, CursorKey: bytesKey()})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
handler := httptest.NewServer(NewJSONRPCHandler(service, 16))
|
||||
defer handler.Close()
|
||||
response, err := http.Post(handler.URL, "application/json", bytes.NewReader([]byte(`{"jsonrpc":"2.0","id":1,"method":"listClients","params":{}}`)))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
body, _ := io.ReadAll(response.Body)
|
||||
if !bytes.Contains(body, []byte(`-32600`)) {
|
||||
t.Fatalf("oversize response = %s", body)
|
||||
}
|
||||
malformed, err := http.Post(handler.URL, "application/json", bytes.NewReader([]byte(`{"jsonrpc":"2.0","id":1,"method":"listClients","params":{}}`[:16])))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer malformed.Body.Close()
|
||||
malformedBody, _ := io.ReadAll(malformed.Body)
|
||||
if !bytes.Contains(malformedBody, []byte(`-32700`)) {
|
||||
t.Fatalf("malformed response = %s", malformedBody)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user