mirror of
https://github.com/luxfi/chains.git
synced 2026-09-24 00:26:00 +00:00
quantumvm registered node's JSON-RPC codec — the one that raises the initial of the function named after the dot. That codec is now internal/codec, so the spelling quantumvm serves, quantumvm.getBlock for Service.GetBlock, is decided in this module. The spelling is unchanged: an initial that is already upper-case is refused, and an argument that will not read reports one message. identityvm, keyvm and bridgevm register gorilla's plain codec and keep it. Co-authored-by: Hanzo Dev <[email protected]>
112 lines
3.6 KiB
Go
112 lines
3.6 KiB
Go
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package codec
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gorilla/rpc/v2"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// call builds the JSON-RPC request a client would send for the named method.
|
|
func call(t *testing.T, method, params string) *http.Request {
|
|
t.Helper()
|
|
body := `{"jsonrpc":"2.0","id":1,"method":"` + method + `","params":` + params + `}`
|
|
r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(body))
|
|
r.Header.Set("Content-Type", "application/json")
|
|
return r
|
|
}
|
|
|
|
// TestMethod pins the spelling a client may use. Every name here is one
|
|
// quantumvm serves; a change to this table is a change to the wire.
|
|
func TestMethod(t *testing.T) {
|
|
for _, test := range []struct {
|
|
wire, method string
|
|
}{
|
|
{"quantumvm.getBlock", "quantumvm.GetBlock"},
|
|
{"quantumvm.generateCoronaKey", "quantumvm.GenerateCoronaKey"},
|
|
{"quantumvm.verifyQuantumSignature", "quantumvm.VerifyQuantumSignature"},
|
|
{"quantumvm.getPendingTransactions", "quantumvm.GetPendingTransactions"},
|
|
{"quantumvm.getHealth", "quantumvm.GetHealth"},
|
|
{"quantumvm.getConfig", "quantumvm.GetConfig"},
|
|
} {
|
|
t.Run(test.wire, func(t *testing.T) {
|
|
method, err := New().NewRequest(call(t, test.wire, "[{}]")).Method()
|
|
require.NoError(t, err)
|
|
require.Equal(t, test.method, method)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestMethodRaised refuses the spelling of the Go method itself, so a service
|
|
// answers to one name and not two.
|
|
func TestMethodRaised(t *testing.T) {
|
|
method, err := New().NewRequest(call(t, "quantumvm.GetBlock", "[{}]")).Method()
|
|
require.ErrorIs(t, err, errUppercaseMethod)
|
|
require.EqualError(t, err, "method must start with a non-uppercase letter")
|
|
require.Equal(t, "quantumvm.GetBlock", method)
|
|
}
|
|
|
|
// TestMethodWhole passes a name carrying no dot through untouched — the server
|
|
// rejects it, and the codec does not invent a class for it.
|
|
func TestMethodWhole(t *testing.T) {
|
|
method, err := New().NewRequest(call(t, "getBlock", "[{}]")).Method()
|
|
require.NoError(t, err)
|
|
require.Equal(t, "getBlock", method)
|
|
}
|
|
|
|
// TestReadRequest reports one message for arguments of the wrong shape.
|
|
func TestReadRequest(t *testing.T) {
|
|
request := New().NewRequest(call(t, "quantumvm.getBlock", `["not-an-object"]`))
|
|
_, err := request.Method()
|
|
require.NoError(t, err)
|
|
require.ErrorIs(t, request.ReadRequest(&Args{}), errInvalidArg)
|
|
}
|
|
|
|
type Args struct {
|
|
Height uint64 `json:"height"`
|
|
}
|
|
|
|
type Reply struct {
|
|
Height uint64 `json:"height"`
|
|
}
|
|
|
|
// service stands in for quantumvm's: an exported Go method, recording that it
|
|
// ran.
|
|
type service struct{ ran string }
|
|
|
|
func (s *service) GetBlock(_ *http.Request, a *Args, r *Reply) error {
|
|
s.ran = "GetBlock"
|
|
r.Height = a.Height
|
|
return nil
|
|
}
|
|
|
|
// TestServe drives the whole path a client takes: a lower-case name on the
|
|
// wire reaches the exported Go method and its answer comes back.
|
|
func TestServe(t *testing.T) {
|
|
server := rpc.NewServer()
|
|
server.RegisterCodec(New(), "application/json")
|
|
served := &service{}
|
|
require.NoError(t, server.RegisterService(served, "quantumvm"))
|
|
|
|
recorder := httptest.NewRecorder()
|
|
server.ServeHTTP(recorder, call(t, "quantumvm.getBlock", `[{"height":7}]`))
|
|
|
|
require.Equal(t, http.StatusOK, recorder.Code)
|
|
require.Equal(t, "GetBlock", served.ran)
|
|
|
|
var answer struct {
|
|
Result Reply `json:"result"`
|
|
Error *json.RawMessage `json:"error"`
|
|
}
|
|
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &answer))
|
|
require.Nil(t, answer.Error)
|
|
require.Equal(t, uint64(7), answer.Result.Height)
|
|
}
|