194 lines
5.1 KiB
Go
194 lines
5.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
_ "embed"
|
|
"encoding/json"
|
|
"github.com/asymmetric-research/solana-exporter/pkg/rpc"
|
|
"github.com/stretchr/testify/assert"
|
|
"sort"
|
|
"testing"
|
|
)
|
|
|
|
func TestSelectFromSchedule(t *testing.T) {
|
|
selected := SelectFromSchedule(
|
|
map[string][]int64{
|
|
"aaa": {0, 3, 6, 9, 12},
|
|
"bbb": {1, 4, 7, 10, 13},
|
|
"ccc": {2, 5, 8, 11, 14},
|
|
},
|
|
5,
|
|
10,
|
|
)
|
|
assert.Equal(t,
|
|
map[string][]int64{"aaa": {6, 9}, "bbb": {7, 10}, "ccc": {5, 8}},
|
|
selected,
|
|
)
|
|
}
|
|
|
|
func TestGetTrimmedLeaderSchedule(t *testing.T) {
|
|
_, client := rpc.NewMockClient(t,
|
|
map[string]any{
|
|
"getLeaderSchedule": map[string]any{
|
|
"aaa": []int{0, 3, 6, 9, 12},
|
|
"bbb": []int{1, 4, 7, 10, 13},
|
|
"ccc": []int{2, 5, 8, 11, 14},
|
|
},
|
|
},
|
|
nil, nil, nil, nil, nil,
|
|
)
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
schedule, err := GetTrimmedLeaderSchedule(ctx, client, []string{"aaa", "bbb"}, 10, 10)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, map[string][]int64{"aaa": {10, 13, 16, 19, 22}, "bbb": {11, 14, 17, 20, 23}}, schedule)
|
|
}
|
|
|
|
func TestCombineUnique(t *testing.T) {
|
|
var (
|
|
v1 = []string{"1", "2", "3"}
|
|
v2 = []string{"2", "3", "4"}
|
|
v3 = []string{"3", "4", "5"}
|
|
)
|
|
|
|
assert.Equal(t, []string{"1", "2", "3", "4", "5"}, CombineUnique(v1, v2, v3))
|
|
assert.Equal(t, []string{"2", "3", "4", "5"}, CombineUnique(nil, v2, v3))
|
|
assert.Equal(t, []string{"1", "2", "3", "4", "5"}, CombineUnique(v1, nil, v3))
|
|
|
|
}
|
|
|
|
func TestFetchBalances(t *testing.T) {
|
|
simulator, client := NewSimulator(t, 0)
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
fetchedBalances, err := FetchBalances(ctx, client, CombineUnique(simulator.Nodekeys, simulator.Votekeys))
|
|
assert.NoError(t, err)
|
|
assert.Equal(t,
|
|
map[string]float64{"aaa": 1, "bbb": 2, "ccc": 3, "AAA": 4, "BBB": 5, "CCC": 6},
|
|
fetchedBalances,
|
|
)
|
|
}
|
|
|
|
func TestGetAssociatedVoteAccounts(t *testing.T) {
|
|
simulator, client := NewSimulator(t, 1)
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
voteAccounts, err := GetAssociatedVoteAccounts(ctx, client, rpc.CommitmentFinalized, simulator.Nodekeys)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, simulator.Votekeys, voteAccounts)
|
|
}
|
|
|
|
func TestGetEpochBounds(t *testing.T) {
|
|
epoch := rpc.EpochInfo{AbsoluteSlot: 25, SlotIndex: 5, SlotsInEpoch: 10}
|
|
first, last := GetEpochBounds(&epoch)
|
|
assert.Equal(t, int64(20), first)
|
|
assert.Equal(t, int64(29), last)
|
|
}
|
|
|
|
//go:embed testdata/block-297609329.json
|
|
var blockJson []byte
|
|
|
|
func TestCountVoteTransactions(t *testing.T) {
|
|
var block rpc.Block
|
|
err := json.Unmarshal(blockJson, &block)
|
|
assert.NoError(t, err)
|
|
|
|
voteCount, err := CountVoteTransactions(&block)
|
|
assert.NoError(t, err)
|
|
// https://explorer.solana.com/block/297609329
|
|
assert.Equal(t, 1048, voteCount)
|
|
assert.Equal(t, 446, len(block.Transactions)-voteCount)
|
|
}
|
|
|
|
func TestEpochTrackedValidators_GetTrackedValidators(t *testing.T) {
|
|
etv := EpochTrackedValidators{
|
|
trackedNodekeys: map[int64]map[string]struct{}{
|
|
1: {"a": struct{}{}, "b": struct{}{}},
|
|
2: {"c": struct{}{}, "d": struct{}{}},
|
|
},
|
|
}
|
|
t.Run(
|
|
"simple_get",
|
|
func(t *testing.T) {
|
|
nodekeys, err := etv.GetTrackedValidators(1)
|
|
assert.NoError(t, err)
|
|
sort.Strings(nodekeys)
|
|
assert.Equal(t, []string{"a", "b"}, nodekeys)
|
|
},
|
|
)
|
|
t.Run(
|
|
"second-get",
|
|
func(t *testing.T) {
|
|
nodekeys, err := etv.GetTrackedValidators(2)
|
|
assert.NoError(t, err)
|
|
sort.Strings(nodekeys)
|
|
assert.Equal(t, []string{"c", "d"}, nodekeys)
|
|
},
|
|
)
|
|
t.Run(
|
|
"failed-get",
|
|
func(t *testing.T) {
|
|
_, err := etv.GetTrackedValidators(1)
|
|
assert.Error(t, err)
|
|
},
|
|
)
|
|
|
|
}
|
|
|
|
func TestEpochTrackedValidators_AddTrackedValidators(t *testing.T) {
|
|
etv := NewEpochTrackedValidators()
|
|
etv.AddTrackedNodekeys(1, []string{"a", "b"})
|
|
etv.AddTrackedNodekeys(2, []string{"c", "d"})
|
|
assert.Equal(t,
|
|
map[int64]map[string]struct{}{
|
|
1: {"a": struct{}{}, "b": struct{}{}},
|
|
2: {"c": struct{}{}, "d": struct{}{}},
|
|
},
|
|
etv.trackedNodekeys,
|
|
)
|
|
}
|
|
|
|
func TestBoolToFloat64(t *testing.T) {
|
|
assert.Equal(t, float64(1), BoolToFloat64(true))
|
|
assert.Equal(t, float64(0), BoolToFloat64(false))
|
|
}
|
|
|
|
func TestExtractHealthAndNumSlotsBehind(t *testing.T) {
|
|
t.Run("healthy-node", func(t *testing.T) {
|
|
health, healthErr, slots, slotsErr := ExtractHealthAndNumSlotsBehind("ok", nil)
|
|
assert.Equal(t, true, health)
|
|
assert.NoError(t, healthErr)
|
|
assert.Equal(t, slots, int64(0))
|
|
assert.NoError(t, slotsErr)
|
|
})
|
|
|
|
t.Run("unhealthy-node", func(t *testing.T) {
|
|
getHealthErr := rpc.Error{
|
|
Code: -32005,
|
|
Method: "getHealth",
|
|
Message: "Node is unhealthy",
|
|
}
|
|
t.Run("generic", func(t *testing.T) {
|
|
health, healthErr, slots, slotsErr := ExtractHealthAndNumSlotsBehind("", &getHealthErr)
|
|
assert.Equal(t, false, health)
|
|
assert.NoError(t, healthErr)
|
|
assert.Equal(t, slots, int64(0))
|
|
assert.Error(t, slotsErr)
|
|
})
|
|
|
|
getHealthErr.Data = map[string]any{"numSlotsBehind": 42}
|
|
t.Run("specific", func(t *testing.T) {
|
|
health, healthErr, slots, slotsErr := ExtractHealthAndNumSlotsBehind("", &getHealthErr)
|
|
assert.Equal(t, false, health)
|
|
assert.NoError(t, healthErr)
|
|
assert.Equal(t, int64(42), slots)
|
|
assert.NoError(t, slotsErr)
|
|
})
|
|
})
|
|
}
|