github.com/ethersphere/bee/v2@v2.2.0/pkg/status/status_test.go (about) 1 // Copyright 2023 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package status_test 6 7 import ( 8 "bytes" 9 "context" 10 "testing" 11 12 "github.com/ethersphere/bee/v2/pkg/api" 13 "github.com/ethersphere/bee/v2/pkg/log" 14 "github.com/ethersphere/bee/v2/pkg/p2p/protobuf" 15 "github.com/ethersphere/bee/v2/pkg/p2p/streamtest" 16 "github.com/ethersphere/bee/v2/pkg/postage" 17 "github.com/ethersphere/bee/v2/pkg/status" 18 "github.com/ethersphere/bee/v2/pkg/status/internal/pb" 19 "github.com/ethersphere/bee/v2/pkg/swarm" 20 "github.com/ethersphere/bee/v2/pkg/topology" 21 "github.com/google/go-cmp/cmp" 22 ) 23 24 func TestStatus(t *testing.T) { 25 t.Parallel() 26 27 want := &pb.Snapshot{ 28 BeeMode: api.FullMode.String(), 29 ReserveSize: 128, 30 PullsyncRate: 64, 31 StorageRadius: 8, 32 BatchCommitment: 1024, 33 NeighborhoodSize: 1, 34 IsReachable: true, 35 LastSyncedBlock: 6092500, 36 } 37 38 sssMock := &statusSnapshotMock{want} 39 40 peersIterMock := new(topologyPeersIterNoopMock) 41 42 peer1 := status.NewService( 43 log.Noop, 44 nil, 45 peersIterMock, 46 want.BeeMode, 47 sssMock, 48 sssMock, 49 ) 50 51 peer1.SetSync(sssMock) 52 53 recorder := streamtest.New(streamtest.WithProtocols(peer1.Protocol())) 54 55 peer2 := status.NewService(log.Noop, recorder, peersIterMock, "", nil, nil) 56 57 address := swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c") 58 59 if _, err := peer2.PeerSnapshot(context.Background(), address); err != nil { 60 t.Fatalf("send msg get: unexpected error: %v", err) 61 } 62 63 records, err := recorder.Records(address, status.ProtocolName, status.ProtocolVersion, status.StreamName) 64 if err != nil { 65 t.Fatal(err) 66 } 67 if have, want := len(records), 1; want != have { 68 t.Fatalf("have %v records, want %v", have, want) 69 } 70 71 messages, err := protobuf.ReadMessages( 72 bytes.NewReader(records[0].In()), 73 func() protobuf.Message { return new(pb.Get) }, 74 ) 75 if err != nil { 76 t.Fatalf("read messages: unexpected error: %v", err) 77 } 78 if have, want := len(messages), 1; want != have { 79 t.Fatalf("have %v messages, want %v", have, want) 80 } 81 82 messages, err = protobuf.ReadMessages( 83 bytes.NewReader(records[0].Out()), 84 func() protobuf.Message { return new(pb.Snapshot) }, 85 ) 86 if err != nil { 87 t.Fatalf("read messages: unexpected error: %v", err) 88 } 89 have := messages[0].(*pb.Snapshot) 90 91 if diff := cmp.Diff(want, have); diff != "" { 92 t.Fatalf("unexpected snapshot (-want +have):\n%s", diff) 93 } 94 } 95 96 // TestStatusLightNode tests that the status service returns the correct 97 // information for a light node. 98 func TestStatusLightNode(t *testing.T) { 99 t.Parallel() 100 101 want := &pb.Snapshot{ 102 BeeMode: api.LightMode.String(), 103 ReserveSize: 0, 104 PullsyncRate: 0, 105 StorageRadius: 0, 106 BatchCommitment: 1024, 107 IsReachable: true, 108 NeighborhoodSize: 1, 109 LastSyncedBlock: 6092500, 110 } 111 112 sssMock := &statusSnapshotMock{&pb.Snapshot{ 113 ReserveSize: 100, // should be ignored 114 PullsyncRate: 100, // should be ignored 115 StorageRadius: 100, // should be ignored 116 BatchCommitment: 1024, 117 LastSyncedBlock: 6092500, 118 }} 119 120 peersIterMock := new(topologyPeersIterNoopMock) 121 122 peer1 := status.NewService( 123 log.Noop, 124 nil, 125 peersIterMock, 126 want.BeeMode, 127 sssMock, 128 nil, 129 ) 130 131 recorder := streamtest.New(streamtest.WithProtocols(peer1.Protocol())) 132 133 peer2 := status.NewService(log.Noop, recorder, peersIterMock, "", nil, nil) 134 135 address := swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c") 136 137 if _, err := peer2.PeerSnapshot(context.Background(), address); err != nil { 138 t.Fatalf("send msg get: unexpected error: %v", err) 139 } 140 141 records, err := recorder.Records(address, status.ProtocolName, status.ProtocolVersion, status.StreamName) 142 if err != nil { 143 t.Fatal(err) 144 } 145 if have, want := len(records), 1; want != have { 146 t.Fatalf("have %v records, want %v", have, want) 147 } 148 149 messages, err := protobuf.ReadMessages( 150 bytes.NewReader(records[0].In()), 151 func() protobuf.Message { return new(pb.Get) }, 152 ) 153 if err != nil { 154 t.Fatalf("read messages: unexpected error: %v", err) 155 } 156 if have, want := len(messages), 1; want != have { 157 t.Fatalf("have %v messages, want %v", have, want) 158 } 159 160 messages, err = protobuf.ReadMessages( 161 bytes.NewReader(records[0].Out()), 162 func() protobuf.Message { return new(pb.Snapshot) }, 163 ) 164 if err != nil { 165 t.Fatalf("read messages: unexpected error: %v", err) 166 } 167 have := messages[0].(*pb.Snapshot) 168 169 if diff := cmp.Diff(want, have); diff != "" { 170 t.Fatalf("unexpected snapshot (-want +have):\n%s", diff) 171 } 172 } 173 174 // topologyPeersIterNoopMock is noop topology.PeerIterator. 175 type topologyPeersIterNoopMock struct{} 176 177 func (m *topologyPeersIterNoopMock) EachConnectedPeer(_ topology.EachPeerFunc, _ topology.Select) error { 178 return nil 179 } 180 181 func (m *topologyPeersIterNoopMock) EachConnectedPeerRev(_ topology.EachPeerFunc, _ topology.Select) error { 182 return nil 183 } 184 185 func (m *topologyPeersIterNoopMock) IsReachable() bool { 186 return true 187 } 188 189 // statusSnapshotMock satisfies the following interfaces: 190 // - Reserve 191 // - SyncReporter 192 type statusSnapshotMock struct { 193 *pb.Snapshot 194 } 195 196 func (m *statusSnapshotMock) SyncRate() float64 { return m.Snapshot.PullsyncRate } 197 func (m *statusSnapshotMock) ReserveSize() int { return int(m.Snapshot.ReserveSize) } 198 func (m *statusSnapshotMock) StorageRadius() uint8 { return uint8(m.Snapshot.StorageRadius) } 199 func (m *statusSnapshotMock) Commitment() (uint64, error) { return m.Snapshot.BatchCommitment, nil } 200 func (m *statusSnapshotMock) GetChainState() *postage.ChainState { 201 return &postage.ChainState{Block: m.Snapshot.LastSyncedBlock} 202 } 203 func (m *statusSnapshotMock) ReserveSizeWithinRadius() uint64 { 204 return m.Snapshot.ReserveSizeWithinRadius 205 }