Files
indexer/key/adapter_test.go

949 lines
23 KiB
Go

// Copyright (c) 2025 Lux Industries Inc
// SPDX-License-Identifier: MIT
package key
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/luxfi/indexer/dag"
)
// TestNew tests the adapter constructor
func TestNew(t *testing.T) {
endpoint := "http://localhost:9650/v1/chain/K/rpc"
adapter := New(endpoint)
if adapter == nil {
t.Fatal("New returned nil adapter")
}
if adapter.rpcEndpoint != endpoint {
t.Errorf("rpcEndpoint = %q, want %q", adapter.rpcEndpoint, endpoint)
}
if adapter.httpClient == nil {
t.Error("httpClient should not be nil")
}
if adapter.httpClient.Timeout != 30*time.Second {
t.Errorf("httpClient.Timeout = %v, want 30s", adapter.httpClient.Timeout)
}
}
// TestConstants tests the package constants
func TestConstants(t *testing.T) {
tests := []struct {
name string
got interface{}
want interface{}
}{
{"DefaultPort", DefaultPort, 4900},
{"DefaultDatabase", DefaultDatabase, "explorer_kchain"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.got != tt.want {
t.Errorf("%s = %v, want %v", tt.name, tt.got, tt.want)
}
})
}
}
// TestKeyStatusConstants tests key status constants
func TestKeyStatusConstants(t *testing.T) {
tests := []struct {
name string
got KeyStatus
want string
}{
{"KeyStatusActive", KeyStatusActive, "active"},
{"KeyStatusInactive", KeyStatusInactive, "inactive"},
{"KeyStatusRotating", KeyStatusRotating, "rotating"},
{"KeyStatusRevoked", KeyStatusRevoked, "revoked"},
{"KeyStatusPending", KeyStatusPending, "pending"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if string(tt.got) != tt.want {
t.Errorf("%s = %q, want %q", tt.name, tt.got, tt.want)
}
})
}
}
// TestAlgorithmTypeConstants tests algorithm type constants
func TestAlgorithmTypeConstants(t *testing.T) {
tests := []struct {
name string
got AlgorithmType
want string
}{
{"AlgorithmTypeKeyExchange", AlgorithmTypeKeyExchange, "key-exchange"},
{"AlgorithmTypeSigning", AlgorithmTypeSigning, "signing"},
{"AlgorithmTypeEncryption", AlgorithmTypeEncryption, "encryption"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if string(tt.got) != tt.want {
t.Errorf("%s = %q, want %q", tt.name, tt.got, tt.want)
}
})
}
}
// TestAdapterImplementsInterface verifies Adapter implements dag.Adapter
func TestAdapterImplementsInterface(t *testing.T) {
var _ dag.Adapter = (*Adapter)(nil)
}
// TestParseVertex tests parsing K-Chain vertex data
func TestParseVertex(t *testing.T) {
adapter := New("http://localhost:9650")
tests := []struct {
name string
input json.RawMessage
wantID string
wantType string
wantErr bool
}{
{
name: "valid keys vertex",
input: json.RawMessage(`{
"id": "vertex123",
"parentIds": ["parent1"],
"height": 100,
"timestamp": 1700000000000000000,
"status": "accepted",
"data": {
"keys": [{"id": "key1", "algorithm": "ml-kem-768"}]
}
}`),
wantID: "vertex123",
wantType: "keys",
wantErr: false,
},
{
name: "valid key operations vertex",
input: json.RawMessage(`{
"id": "vertex456",
"parentIds": [],
"height": 50,
"timestamp": 1700000000000000000,
"status": "pending",
"data": {
"keyOperations": [{"id": "op1", "operation": "create"}]
}
}`),
wantID: "vertex456",
wantType: "key_operations",
wantErr: false,
},
{
name: "valid encryption vertex",
input: json.RawMessage(`{
"id": "vertex789",
"parentIds": ["p1"],
"height": 25,
"timestamp": 1700000000000000000,
"status": "accepted",
"data": {
"encryptionRequests": [{"id": "enc1", "keyId": "k1"}]
}
}`),
wantID: "vertex789",
wantType: "encryption",
wantErr: false,
},
{
name: "valid signatures vertex",
input: json.RawMessage(`{
"id": "vertexabc",
"parentIds": [],
"height": 10,
"timestamp": 1700000000000000000,
"status": "accepted",
"data": {
"signatureRequests": [{"id": "sig1", "keyId": "k1"}]
}
}`),
wantID: "vertexabc",
wantType: "signatures",
wantErr: false,
},
{
name: "empty data vertex",
input: json.RawMessage(`{
"id": "empty",
"parentIds": [],
"height": 1,
"timestamp": 1700000000000000000,
"status": "accepted",
"data": {}
}`),
wantID: "empty",
wantType: "generic",
wantErr: false,
},
{
name: "invalid JSON",
input: json.RawMessage(`{invalid`),
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vertex, err := adapter.ParseVertex(tt.input)
if tt.wantErr {
if err == nil {
t.Error("expected error but got nil")
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if vertex.ID != tt.wantID {
t.Errorf("ID = %q, want %q", vertex.ID, tt.wantID)
}
if vertex.Type != tt.wantType {
t.Errorf("Type = %q, want %q", vertex.Type, tt.wantType)
}
})
}
}
// TestGetRecentVertices tests fetching recent vertices
func TestGetRecentVertices(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var req map[string]interface{}
json.NewDecoder(r.Body).Decode(&req)
method := req["method"].(string)
if method != "kvm.getRecentVertices" {
t.Errorf("expected method kvm.getRecentVertices, got %s", method)
}
json.NewEncoder(w).Encode(map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"result": []map[string]interface{}{
{"id": "v1", "height": 100},
{"id": "v2", "height": 99},
},
})
}))
defer server.Close()
adapter := New(server.URL)
ctx := context.Background()
vertices, err := adapter.GetRecentVertices(ctx, 5)
if err != nil {
t.Fatalf("GetRecentVertices failed: %v", err)
}
if len(vertices) != 2 {
t.Errorf("got %d vertices, want 2", len(vertices))
}
}
// TestGetVertexByID tests fetching a vertex by ID
func TestGetVertexByID(t *testing.T) {
vertexID := "vertex123"
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var req map[string]interface{}
json.NewDecoder(r.Body).Decode(&req)
method := req["method"].(string)
if method != "kvm.getVertex" {
t.Errorf("expected method kvm.getVertex, got %s", method)
}
json.NewEncoder(w).Encode(map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"result": map[string]interface{}{
"id": vertexID,
"height": 100,
},
})
}))
defer server.Close()
adapter := New(server.URL)
ctx := context.Background()
result, err := adapter.GetVertexByID(ctx, vertexID)
if err != nil {
t.Fatalf("GetVertexByID failed: %v", err)
}
if result == nil {
t.Fatal("expected non-nil result")
}
}
// TestListKeys tests listing keys
func TestListKeys(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var req map[string]interface{}
json.NewDecoder(r.Body).Decode(&req)
if req["method"] != "kvm.listKeys" {
t.Errorf("expected method kvm.listKeys, got %v", req["method"])
}
json.NewEncoder(w).Encode(map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"result": map[string]interface{}{
"keys": []map[string]interface{}{
{"id": "key1", "name": "my-key", "algorithm": "ml-kem-768", "status": "active"},
{"id": "key2", "name": "my-key2", "algorithm": "ml-dsa-65", "status": "active"},
},
"total": 2,
},
})
}))
defer server.Close()
adapter := New(server.URL)
ctx := context.Background()
keys, err := adapter.ListKeys(ctx, "", "", 0, 10)
if err != nil {
t.Fatalf("ListKeys failed: %v", err)
}
if len(keys) != 2 {
t.Errorf("got %d keys, want 2", len(keys))
}
if keys[0].Algorithm != "ml-kem-768" {
t.Errorf("first key algorithm = %q, want ml-kem-768", keys[0].Algorithm)
}
}
// TestGetKeyByID tests fetching a key by ID
func TestGetKeyByID(t *testing.T) {
keyID := "key123"
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var req map[string]interface{}
json.NewDecoder(r.Body).Decode(&req)
if req["method"] != "kvm.getKeyByID" {
t.Errorf("expected method kvm.getKeyByID, got %v", req["method"])
}
json.NewEncoder(w).Encode(map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"result": map[string]interface{}{
"id": keyID,
"name": "my-key",
"algorithm": "ml-kem-768",
"status": "active",
},
})
}))
defer server.Close()
adapter := New(server.URL)
ctx := context.Background()
key, err := adapter.GetKeyByID(ctx, keyID)
if err != nil {
t.Fatalf("GetKeyByID failed: %v", err)
}
if key.ID != keyID {
t.Errorf("ID = %q, want %q", key.ID, keyID)
}
if key.Algorithm != "ml-kem-768" {
t.Errorf("Algorithm = %q, want ml-kem-768", key.Algorithm)
}
}
// TestListAlgorithms tests listing supported algorithms
func TestListAlgorithms(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var req map[string]interface{}
json.NewDecoder(r.Body).Decode(&req)
if req["method"] != "kvm.listAlgorithms" {
t.Errorf("expected method kvm.listAlgorithms, got %v", req["method"])
}
json.NewEncoder(w).Encode(map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"result": map[string]interface{}{
"algorithms": []map[string]interface{}{
{
"name": "ml-kem-768",
"type": "key-exchange",
"securityLevel": 192,
"postQuantum": true,
"thresholdSupport": false,
},
{
"name": "frost-secp256k1",
"type": "signing",
"securityLevel": 128,
"postQuantum": false,
"thresholdSupport": true,
},
},
},
})
}))
defer server.Close()
adapter := New(server.URL)
ctx := context.Background()
algorithms, err := adapter.ListAlgorithms(ctx)
if err != nil {
t.Fatalf("ListAlgorithms failed: %v", err)
}
if len(algorithms) != 2 {
t.Errorf("got %d algorithms, want 2", len(algorithms))
}
if algorithms[0].Name != "ml-kem-768" {
t.Errorf("first algorithm name = %q, want ml-kem-768", algorithms[0].Name)
}
if !algorithms[0].PostQuantum {
t.Error("ml-kem-768 should be PostQuantum")
}
if !algorithms[1].ThresholdSupport {
t.Error("frost-secp256k1 should have ThresholdSupport")
}
}
// TestKeyStruct tests Key JSON serialization
func TestKeyStruct(t *testing.T) {
key := Key{
ID: "key123",
Name: "my-key",
Algorithm: "ml-kem-768",
KeyType: "encapsulation",
PublicKey: "0xpublic",
Threshold: 3,
TotalShares: 5,
Status: KeyStatusActive,
Tags: []string{"production", "pq"},
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
data, err := json.Marshal(key)
if err != nil {
t.Fatalf("Marshal failed: %v", err)
}
var decoded Key
if err := json.Unmarshal(data, &decoded); err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
if decoded.ID != key.ID {
t.Errorf("ID = %q, want %q", decoded.ID, key.ID)
}
if decoded.Algorithm != key.Algorithm {
t.Errorf("Algorithm = %q, want %q", decoded.Algorithm, key.Algorithm)
}
if decoded.Threshold != key.Threshold {
t.Errorf("Threshold = %d, want %d", decoded.Threshold, key.Threshold)
}
if decoded.Status != key.Status {
t.Errorf("Status = %q, want %q", decoded.Status, key.Status)
}
if len(decoded.Tags) != len(key.Tags) {
t.Errorf("Tags length = %d, want %d", len(decoded.Tags), len(key.Tags))
}
}
// TestKeyOperationStruct tests KeyOperation JSON serialization
func TestKeyOperationStruct(t *testing.T) {
op := KeyOperation{
ID: "op123",
KeyID: "key1",
Operation: "create",
Initiator: "0xadmin",
Participants: []string{"0xp1", "0xp2", "0xp3"},
Success: true,
Error: "",
Timestamp: time.Now(),
}
data, err := json.Marshal(op)
if err != nil {
t.Fatalf("Marshal failed: %v", err)
}
var decoded KeyOperation
if err := json.Unmarshal(data, &decoded); err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
if decoded.ID != op.ID {
t.Errorf("ID = %q, want %q", decoded.ID, op.ID)
}
if decoded.Operation != op.Operation {
t.Errorf("Operation = %q, want %q", decoded.Operation, op.Operation)
}
if len(decoded.Participants) != len(op.Participants) {
t.Errorf("Participants length = %d, want %d", len(decoded.Participants), len(op.Participants))
}
}
// TestEncryptionRequestStruct tests EncryptionRequest JSON serialization
func TestEncryptionRequestStruct(t *testing.T) {
req := EncryptionRequest{
ID: "enc123",
KeyID: "key1",
Requester: "0xuser",
DataSize: 1024,
Success: true,
Timestamp: time.Now(),
}
data, err := json.Marshal(req)
if err != nil {
t.Fatalf("Marshal failed: %v", err)
}
var decoded EncryptionRequest
if err := json.Unmarshal(data, &decoded); err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
if decoded.ID != req.ID {
t.Errorf("ID = %q, want %q", decoded.ID, req.ID)
}
if decoded.DataSize != req.DataSize {
t.Errorf("DataSize = %d, want %d", decoded.DataSize, req.DataSize)
}
}
// TestSignatureRequestStruct tests SignatureRequest JSON serialization
func TestSignatureRequestStruct(t *testing.T) {
req := SignatureRequest{
ID: "sig123",
KeyID: "key1",
Signers: []string{"0xs1", "0xs2", "0xs3"},
MessageHash: "0xhash",
Algorithm: "frost-secp256k1",
Success: true,
Timestamp: time.Now(),
}
data, err := json.Marshal(req)
if err != nil {
t.Fatalf("Marshal failed: %v", err)
}
var decoded SignatureRequest
if err := json.Unmarshal(data, &decoded); err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
if decoded.ID != req.ID {
t.Errorf("ID = %q, want %q", decoded.ID, req.ID)
}
if decoded.Algorithm != req.Algorithm {
t.Errorf("Algorithm = %q, want %q", decoded.Algorithm, req.Algorithm)
}
if len(decoded.Signers) != len(req.Signers) {
t.Errorf("Signers length = %d, want %d", len(decoded.Signers), len(req.Signers))
}
}
// TestAlgorithmStruct tests Algorithm JSON serialization
func TestAlgorithmStruct(t *testing.T) {
alg := Algorithm{
Name: "ml-dsa-65",
Type: "signing",
SecurityLevel: 192,
KeySize: 0,
SignatureSize: 3309,
PostQuantum: true,
ThresholdSupport: false,
Description: "ML-DSA-65 post-quantum digital signature",
Standards: []string{"NIST FIPS 204"},
}
data, err := json.Marshal(alg)
if err != nil {
t.Fatalf("Marshal failed: %v", err)
}
var decoded Algorithm
if err := json.Unmarshal(data, &decoded); err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
if decoded.Name != alg.Name {
t.Errorf("Name = %q, want %q", decoded.Name, alg.Name)
}
if decoded.SecurityLevel != alg.SecurityLevel {
t.Errorf("SecurityLevel = %d, want %d", decoded.SecurityLevel, alg.SecurityLevel)
}
if decoded.PostQuantum != alg.PostQuantum {
t.Errorf("PostQuantum = %v, want %v", decoded.PostQuantum, alg.PostQuantum)
}
if len(decoded.Standards) != len(alg.Standards) {
t.Errorf("Standards length = %d, want %d", len(decoded.Standards), len(alg.Standards))
}
}
// TestInferVertexType tests vertex type inference
func TestInferVertexType(t *testing.T) {
adapter := New("http://localhost:9650")
tests := []struct {
name string
data json.RawMessage
wantType string
}{
{
name: "keys type",
data: json.RawMessage(`{"keys": [{"id": "k1"}]}`),
wantType: "keys",
},
{
name: "key_operations type",
data: json.RawMessage(`{"keyOperations": [{"id": "op1"}]}`),
wantType: "key_operations",
},
{
name: "encryption type",
data: json.RawMessage(`{"encryptionRequests": [{"id": "e1"}]}`),
wantType: "encryption",
},
{
name: "signatures type",
data: json.RawMessage(`{"signatureRequests": [{"id": "s1"}]}`),
wantType: "signatures",
},
{
name: "generic type",
data: json.RawMessage(`{}`),
wantType: "generic",
},
{
name: "invalid JSON",
data: json.RawMessage(`{invalid`),
wantType: "unknown",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotType := adapter.inferVertexType(tt.data)
if gotType != tt.wantType {
t.Errorf("inferVertexType() = %q, want %q", gotType, tt.wantType)
}
})
}
}
// TestNetworkError tests error handling for network failures
func TestNetworkError(t *testing.T) {
adapter := New("http://localhost:99999")
ctx := context.Background()
_, err := adapter.GetRecentVertices(ctx, 5)
if err == nil {
t.Error("expected error for unreachable server")
}
}
// TestContextCancellation tests context cancellation handling
func TestContextCancellation(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(5 * time.Second)
}))
defer server.Close()
adapter := New(server.URL)
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
_, err := adapter.GetRecentVertices(ctx, 5)
if err == nil {
t.Error("expected error for cancelled context")
}
}
// TestRPCError tests RPC error response handling
func TestRPCError(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"error": map[string]interface{}{
"code": -32000,
"message": "internal error",
},
})
}))
defer server.Close()
adapter := New(server.URL)
ctx := context.Background()
_, err := adapter.GetVertexByID(ctx, "test")
if err == nil {
t.Error("expected error for RPC error response")
}
}
// TestVertexNotFound tests vertex not found case
func TestVertexNotFound(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"result": []interface{}{},
})
}))
defer server.Close()
adapter := New(server.URL)
ctx := context.Background()
_, err := adapter.GetVertexByID(ctx, "nonexistent")
if err == nil {
t.Error("expected error for nonexistent vertex")
}
}
// TestKeyNotFound tests key not found case
func TestKeyNotFound(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"result": []interface{}{},
})
}))
defer server.Close()
adapter := New(server.URL)
ctx := context.Background()
_, err := adapter.GetKeyByID(ctx, "nonexistent")
if err == nil {
t.Error("expected error for nonexistent key")
}
}
// TestVertexDataParsing tests parsing complete vertex data
func TestVertexDataParsing(t *testing.T) {
adapter := New("http://localhost:9650")
input := json.RawMessage(`{
"id": "complete_vertex",
"parentIds": ["p1"],
"height": 500,
"timestamp": 1700000000000000000,
"status": "accepted",
"data": {
"keys": [
{
"id": "k1",
"name": "test-key",
"algorithm": "ml-kem-768",
"status": "active",
"threshold": 2,
"totalShares": 3
}
],
"keyOperations": [
{
"id": "op1",
"keyId": "k1",
"operation": "create",
"success": true
}
]
}
}`)
vertex, err := adapter.ParseVertex(input)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if vertex.ID != "complete_vertex" {
t.Errorf("ID = %q, want complete_vertex", vertex.ID)
}
var data vertexData
if err := json.Unmarshal(vertex.Data, &data); err != nil {
t.Fatalf("failed to parse vertex data: %v", err)
}
if len(data.Keys) != 1 {
t.Errorf("Keys count = %d, want 1", len(data.Keys))
}
if len(data.KeyOperations) != 1 {
t.Errorf("KeyOperations count = %d, want 1", len(data.KeyOperations))
}
if data.Keys[0].Algorithm != "ml-kem-768" {
t.Errorf("Key algorithm = %q, want ml-kem-768", data.Keys[0].Algorithm)
}
if data.KeyOperations[0].Operation != "create" {
t.Errorf("Operation = %q, want create", data.KeyOperations[0].Operation)
}
}
// TestPostQuantumAlgorithms tests parsing PQ algorithm configurations
func TestPostQuantumAlgorithms(t *testing.T) {
pqAlgorithms := []string{
"ml-kem-512", "ml-kem-768", "ml-kem-1024",
"ml-dsa-44", "ml-dsa-65", "ml-dsa-87",
"corona",
}
for _, alg := range pqAlgorithms {
t.Run(alg, func(t *testing.T) {
key := Key{
ID: "k1",
Algorithm: alg,
Status: KeyStatusActive,
}
data, err := json.Marshal(key)
if err != nil {
t.Fatalf("Marshal failed: %v", err)
}
var decoded Key
if err := json.Unmarshal(data, &decoded); err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
if decoded.Algorithm != alg {
t.Errorf("Algorithm = %q, want %q", decoded.Algorithm, alg)
}
})
}
}
// TestThresholdKeyConfiguration tests threshold key configuration
func TestThresholdKeyConfiguration(t *testing.T) {
tests := []struct {
threshold int
totalShares int
valid bool
}{
{1, 1, true}, // 1-of-1
{2, 3, true}, // 2-of-3
{3, 5, true}, // 3-of-5
{5, 7, true}, // 5-of-7
{10, 15, true}, // 10-of-15
}
for _, tt := range tests {
name := fmt.Sprintf("%d-of-%d", tt.threshold, tt.totalShares)
t.Run(name, func(t *testing.T) {
key := Key{
ID: "k1",
Algorithm: "frost-secp256k1",
Threshold: tt.threshold,
TotalShares: tt.totalShares,
Status: KeyStatusActive,
}
if key.Threshold > key.TotalShares {
t.Error("threshold should not exceed totalShares")
}
})
}
}
// Benchmarks
func BenchmarkParseVertex(b *testing.B) {
adapter := New("http://localhost:9650")
input := json.RawMessage(`{
"id": "benchmark_vertex",
"parentIds": ["p1", "p2"],
"height": 1000,
"timestamp": 1700000000000000000,
"status": "accepted",
"data": {
"keys": [
{"id": "k1", "name": "key1", "algorithm": "ml-kem-768", "status": "active"},
{"id": "k2", "name": "key2", "algorithm": "ml-dsa-65", "status": "active"}
],
"keyOperations": [
{"id": "op1", "keyId": "k1", "operation": "create", "success": true}
]
}
}`)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = adapter.ParseVertex(input)
}
}
func BenchmarkInferVertexType(b *testing.B) {
adapter := New("http://localhost:9650")
inputs := []json.RawMessage{
json.RawMessage(`{"keys": [{"id": "k1"}]}`),
json.RawMessage(`{"keyOperations": [{"id": "op1"}]}`),
json.RawMessage(`{"encryptionRequests": [{"id": "e1"}]}`),
json.RawMessage(`{"signatureRequests": [{"id": "s1"}]}`),
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, input := range inputs {
adapter.inferVertexType(input)
}
}
}
func BenchmarkCallRPC(b *testing.B) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"result": []map[string]interface{}{{"id": "v1"}},
})
}))
defer server.Close()
adapter := New(server.URL)
ctx := context.Background()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = adapter.GetRecentVertices(ctx, 10)
}
}