Skip to content

Commit 2bc4e02

Browse files
authored
Merge pull request #5213 from 317787106/test/net_coverage
test(net): add test cases of MessageHandler
2 parents 13bf1a0 + 7b67006 commit 2bc4e02

2 files changed

Lines changed: 382 additions & 0 deletions

File tree

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package org.tron.core.net.messagehandler;
2+
3+
import static org.mockito.Mockito.mock;
4+
5+
import com.google.protobuf.ByteString;
6+
import java.io.File;
7+
import java.lang.reflect.Field;
8+
import java.net.InetSocketAddress;
9+
import java.util.ArrayList;
10+
import java.util.Collections;
11+
import org.junit.AfterClass;
12+
import org.junit.Assert;
13+
import org.junit.Before;
14+
import org.junit.BeforeClass;
15+
import org.junit.Test;
16+
import org.mockito.Mockito;
17+
import org.springframework.context.ApplicationContext;
18+
import org.tron.common.application.TronApplicationContext;
19+
import org.tron.common.utils.FileUtil;
20+
import org.tron.common.utils.ReflectUtils;
21+
import org.tron.common.utils.Sha256Hash;
22+
import org.tron.consensus.pbft.message.PbftMessage;
23+
import org.tron.core.Constant;
24+
import org.tron.core.capsule.BlockCapsule;
25+
import org.tron.core.config.DefaultConfig;
26+
import org.tron.core.config.args.Args;
27+
import org.tron.core.net.P2pEventHandlerImpl;
28+
import org.tron.core.net.TronNetService;
29+
import org.tron.core.net.message.keepalive.PingMessage;
30+
import org.tron.core.net.peer.PeerConnection;
31+
import org.tron.core.net.peer.PeerManager;
32+
import org.tron.p2p.P2pConfig;
33+
import org.tron.p2p.base.Parameter;
34+
import org.tron.p2p.connection.Channel;
35+
36+
public class MessageHandlerTest {
37+
38+
private static TronApplicationContext context;
39+
private PeerConnection peer;
40+
private static P2pEventHandlerImpl p2pEventHandler;
41+
private static ApplicationContext ctx;
42+
private static String dbPath = "output-message-handler-test";
43+
44+
45+
@BeforeClass
46+
public static void init() throws Exception {
47+
Args.setParam(new String[] {"--output-directory", dbPath, "--debug"},
48+
Constant.TEST_CONF);
49+
context = new TronApplicationContext(DefaultConfig.class);
50+
p2pEventHandler = context.getBean(P2pEventHandlerImpl.class);
51+
ctx = (ApplicationContext) ReflectUtils.getFieldObject(p2pEventHandler, "ctx");
52+
53+
TronNetService tronNetService = context.getBean(TronNetService.class);
54+
Parameter.p2pConfig = new P2pConfig();
55+
ReflectUtils.setFieldValue(tronNetService, "p2pConfig", Parameter.p2pConfig);
56+
}
57+
58+
@AfterClass
59+
public static void destroy() {
60+
Args.clearParam();
61+
context.destroy();
62+
FileUtil.deleteDir(new File(dbPath));
63+
}
64+
65+
@Before
66+
public void clearPeers() {
67+
try {
68+
Field field = PeerManager.class.getDeclaredField("peers");
69+
field.setAccessible(true);
70+
field.set(PeerManager.class, Collections.synchronizedList(new ArrayList<>()));
71+
} catch (NoSuchFieldException | IllegalAccessException e) {
72+
//ignore
73+
}
74+
}
75+
76+
@Test
77+
public void testPbft() {
78+
InetSocketAddress a1 = new InetSocketAddress("127.0.0.1", 10001);
79+
Channel c1 = mock(Channel.class);
80+
Mockito.when(c1.getInetSocketAddress()).thenReturn(a1);
81+
Mockito.when(c1.getInetAddress()).thenReturn(a1.getAddress());
82+
p2pEventHandler.onConnect(c1);
83+
Assert.assertEquals(1, PeerManager.getPeers().size());
84+
Assert.assertFalse(c1.isDisconnect());
85+
86+
peer = PeerManager.getPeers().get(0);
87+
BlockCapsule blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH,
88+
System.currentTimeMillis(), ByteString.EMPTY);
89+
PbftMessage pbftMessage = PbftMessage.fullNodePrePrepareBlockMsg(blockCapsule, 0L);
90+
p2pEventHandler.onMessage(peer.getChannel(), pbftMessage.getSendBytes());
91+
92+
InetSocketAddress a2 = new InetSocketAddress("127.0.0.1", 10002);
93+
Channel c2 = mock(Channel.class);
94+
Mockito.when(c2.getInetSocketAddress()).thenReturn(a2);
95+
Mockito.when(c2.getInetAddress()).thenReturn(a2.getAddress());
96+
p2pEventHandler.onMessage(c2, pbftMessage.getSendBytes());
97+
98+
Assert.assertEquals(1, PeerManager.getPeers().size());
99+
}
100+
101+
@Test
102+
public void testPing() {
103+
InetSocketAddress a1 = new InetSocketAddress("127.0.0.1", 10001);
104+
Channel c1 = mock(Channel.class);
105+
Mockito.when(c1.getInetSocketAddress()).thenReturn(a1);
106+
Mockito.when(c1.getInetAddress()).thenReturn(a1.getAddress());
107+
PeerManager.add(ctx, c1);
108+
109+
PingMessage pingMessage = new PingMessage();
110+
p2pEventHandler.onMessage(c1, pingMessage.getSendBytes());
111+
Assert.assertEquals(1, PeerManager.getPeers().size());
112+
}
113+
}
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
package org.tron.core.net.services;
2+
3+
import static org.mockito.Mockito.mock;
4+
import static org.tron.core.net.message.handshake.HelloMessage.getEndpointFromNode;
5+
6+
import com.google.protobuf.ByteString;
7+
import java.io.File;
8+
import java.lang.reflect.Field;
9+
import java.lang.reflect.InvocationTargetException;
10+
import java.lang.reflect.Method;
11+
import java.net.InetSocketAddress;
12+
import java.util.ArrayList;
13+
import java.util.Collections;
14+
import java.util.Random;
15+
import org.junit.AfterClass;
16+
import org.junit.Assert;
17+
import org.junit.Before;
18+
import org.junit.BeforeClass;
19+
import org.junit.Test;
20+
import org.mockito.Mockito;
21+
import org.springframework.context.ApplicationContext;
22+
import org.tron.common.application.TronApplicationContext;
23+
import org.tron.common.utils.ByteArray;
24+
import org.tron.common.utils.FileUtil;
25+
import org.tron.common.utils.ReflectUtils;
26+
import org.tron.common.utils.Sha256Hash;
27+
import org.tron.consensus.pbft.message.PbftMessage;
28+
import org.tron.core.ChainBaseManager;
29+
import org.tron.core.Constant;
30+
import org.tron.core.capsule.BlockCapsule;
31+
import org.tron.core.config.DefaultConfig;
32+
import org.tron.core.config.args.Args;
33+
import org.tron.core.net.P2pEventHandlerImpl;
34+
import org.tron.core.net.TronNetService;
35+
import org.tron.core.net.message.handshake.HelloMessage;
36+
import org.tron.core.net.message.keepalive.PingMessage;
37+
import org.tron.core.net.peer.PeerConnection;
38+
import org.tron.core.net.peer.PeerManager;
39+
import org.tron.p2p.P2pConfig;
40+
import org.tron.p2p.base.Parameter;
41+
import org.tron.p2p.connection.Channel;
42+
import org.tron.p2p.discover.Node;
43+
import org.tron.p2p.utils.NetUtil;
44+
import org.tron.protos.Discover.Endpoint;
45+
import org.tron.protos.Protocol;
46+
import org.tron.protos.Protocol.HelloMessage.Builder;
47+
48+
public class HandShakeServiceTest {
49+
50+
private static TronApplicationContext context;
51+
private PeerConnection peer;
52+
private static P2pEventHandlerImpl p2pEventHandler;
53+
private static ApplicationContext ctx;
54+
private static String dbPath = "output-message-handler-test";
55+
56+
57+
@BeforeClass
58+
public static void init() throws Exception {
59+
Args.setParam(new String[] {"--output-directory", dbPath, "--debug"},
60+
Constant.TEST_CONF);
61+
context = new TronApplicationContext(DefaultConfig.class);
62+
p2pEventHandler = context.getBean(P2pEventHandlerImpl.class);
63+
ctx = (ApplicationContext) ReflectUtils.getFieldObject(p2pEventHandler, "ctx");
64+
65+
TronNetService tronNetService = context.getBean(TronNetService.class);
66+
Parameter.p2pConfig = new P2pConfig();
67+
ReflectUtils.setFieldValue(tronNetService, "p2pConfig", Parameter.p2pConfig);
68+
}
69+
70+
@AfterClass
71+
public static void destroy() {
72+
Args.clearParam();
73+
context.destroy();
74+
FileUtil.deleteDir(new File(dbPath));
75+
}
76+
77+
@Before
78+
public void clearPeers() {
79+
try {
80+
Field field = PeerManager.class.getDeclaredField("peers");
81+
field.setAccessible(true);
82+
field.set(PeerManager.class, Collections.synchronizedList(new ArrayList<>()));
83+
} catch (NoSuchFieldException | IllegalAccessException e) {
84+
//ignore
85+
}
86+
}
87+
88+
@Test
89+
public void testOkHelloMessage()
90+
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
91+
InetSocketAddress a1 = new InetSocketAddress("127.0.0.1", 10001);
92+
Channel c1 = mock(Channel.class);
93+
Mockito.when(c1.getInetSocketAddress()).thenReturn(a1);
94+
Mockito.when(c1.getInetAddress()).thenReturn(a1.getAddress());
95+
PeerManager.add(ctx, c1);
96+
peer = PeerManager.getPeers().get(0);
97+
98+
Method method = p2pEventHandler.getClass()
99+
.getDeclaredMethod("processMessage", PeerConnection.class, byte[].class);
100+
method.setAccessible(true);
101+
102+
//ok
103+
Node node = new Node(NetUtil.getNodeId(), a1.getAddress().getHostAddress(), null, a1.getPort());
104+
HelloMessage helloMessage = new HelloMessage(node, System.currentTimeMillis(),
105+
ChainBaseManager.getChainBaseManager());
106+
method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes());
107+
108+
//dup hello message
109+
peer.setHelloMessageReceive(helloMessage);
110+
method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes());
111+
112+
//dup peer
113+
peer.setHelloMessageReceive(null);
114+
Mockito.when(c1.isDisconnect()).thenReturn(true);
115+
method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes());
116+
}
117+
118+
@Test
119+
public void testInvalidHelloMessage() {
120+
InetSocketAddress a1 = new InetSocketAddress("127.0.0.1", 10001);
121+
Node node = new Node(NetUtil.getNodeId(), a1.getAddress().getHostAddress(), null, a1.getPort());
122+
Protocol.HelloMessage.Builder builder =
123+
getHelloMessageBuilder(node, System.currentTimeMillis(),
124+
ChainBaseManager.getChainBaseManager());
125+
//block hash is empty
126+
try {
127+
BlockCapsule.BlockId hid = ChainBaseManager.getChainBaseManager().getHeadBlockId();
128+
Protocol.HelloMessage.BlockId hBlockId = Protocol.HelloMessage.BlockId.newBuilder()
129+
.setHash(ByteString.copyFrom(new byte[0]))
130+
.setNumber(hid.getNum())
131+
.build();
132+
builder.setHeadBlockId(hBlockId);
133+
HelloMessage helloMessage = new HelloMessage(builder.build().toByteArray());
134+
Assert.assertTrue(!helloMessage.valid());
135+
} catch (Exception e) {
136+
Assert.fail();
137+
}
138+
}
139+
140+
@Test
141+
public void testRelayHelloMessage() throws NoSuchMethodException {
142+
InetSocketAddress a1 = new InetSocketAddress("127.0.0.1", 10001);
143+
Channel c1 = mock(Channel.class);
144+
Mockito.when(c1.getInetSocketAddress()).thenReturn(a1);
145+
Mockito.when(c1.getInetAddress()).thenReturn(a1.getAddress());
146+
PeerManager.add(ctx, c1);
147+
peer = PeerManager.getPeers().get(0);
148+
149+
Method method = p2pEventHandler.getClass()
150+
.getDeclaredMethod("processMessage", PeerConnection.class, byte[].class);
151+
method.setAccessible(true);
152+
153+
//address is empty
154+
Args.getInstance().fastForward = true;
155+
clearPeers();
156+
Node node2 = new Node(NetUtil.getNodeId(), a1.getAddress().getHostAddress(), null, 10002);
157+
Protocol.HelloMessage.Builder builder =
158+
getHelloMessageBuilder(node2, System.currentTimeMillis(),
159+
ChainBaseManager.getChainBaseManager());
160+
161+
try {
162+
HelloMessage helloMessage = new HelloMessage(builder.build().toByteArray());
163+
method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes());
164+
} catch (Exception e) {
165+
Assert.fail();
166+
}
167+
Args.getInstance().fastForward = false;
168+
}
169+
170+
@Test
171+
public void testLowAndGenesisBlockNum() throws NoSuchMethodException {
172+
InetSocketAddress a1 = new InetSocketAddress("127.0.0.1", 10001);
173+
Channel c1 = mock(Channel.class);
174+
Mockito.when(c1.getInetSocketAddress()).thenReturn(a1);
175+
Mockito.when(c1.getInetAddress()).thenReturn(a1.getAddress());
176+
PeerManager.add(ctx, c1);
177+
peer = PeerManager.getPeers().get(0);
178+
179+
Method method = p2pEventHandler.getClass()
180+
.getDeclaredMethod("processMessage", PeerConnection.class, byte[].class);
181+
method.setAccessible(true);
182+
183+
Node node2 = new Node(NetUtil.getNodeId(), a1.getAddress().getHostAddress(), null, 10002);
184+
185+
//lowestBlockNum > headBlockNum
186+
Protocol.HelloMessage.Builder builder =
187+
getHelloMessageBuilder(node2, System.currentTimeMillis(),
188+
ChainBaseManager.getChainBaseManager());
189+
builder.setLowestBlockNum(ChainBaseManager.getChainBaseManager().getLowestBlockNum() + 1);
190+
try {
191+
HelloMessage helloMessage = new HelloMessage(builder.build().toByteArray());
192+
method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes());
193+
} catch (Exception e) {
194+
Assert.fail();
195+
}
196+
197+
//genesisBlock is not equal
198+
builder = getHelloMessageBuilder(node2, System.currentTimeMillis(),
199+
ChainBaseManager.getChainBaseManager());
200+
BlockCapsule.BlockId gid = ChainBaseManager.getChainBaseManager().getGenesisBlockId();
201+
Protocol.HelloMessage.BlockId gBlockId = Protocol.HelloMessage.BlockId.newBuilder()
202+
.setHash(gid.getByteString())
203+
.setNumber(gid.getNum() + 1)
204+
.build();
205+
builder.setGenesisBlockId(gBlockId);
206+
try {
207+
HelloMessage helloMessage = new HelloMessage(builder.build().toByteArray());
208+
method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes());
209+
} catch (Exception e) {
210+
Assert.fail();
211+
}
212+
213+
//solidityBlock <= us, but not contained
214+
builder = getHelloMessageBuilder(node2, System.currentTimeMillis(),
215+
ChainBaseManager.getChainBaseManager());
216+
BlockCapsule.BlockId sid = ChainBaseManager.getChainBaseManager().getSolidBlockId();
217+
218+
Random gen = new Random();
219+
byte[] randomHash = new byte[Sha256Hash.LENGTH];
220+
gen.nextBytes(randomHash);
221+
222+
Protocol.HelloMessage.BlockId sBlockId = Protocol.HelloMessage.BlockId.newBuilder()
223+
.setHash(ByteString.copyFrom(randomHash))
224+
.setNumber(sid.getNum())
225+
.build();
226+
builder.setSolidBlockId(sBlockId);
227+
try {
228+
HelloMessage helloMessage = new HelloMessage(builder.build().toByteArray());
229+
method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes());
230+
} catch (Exception e) {
231+
Assert.fail();
232+
}
233+
}
234+
235+
private Protocol.HelloMessage.Builder getHelloMessageBuilder(Node from, long timestamp,
236+
ChainBaseManager chainBaseManager) {
237+
Endpoint fromEndpoint = getEndpointFromNode(from);
238+
239+
BlockCapsule.BlockId gid = chainBaseManager.getGenesisBlockId();
240+
Protocol.HelloMessage.BlockId gBlockId = Protocol.HelloMessage.BlockId.newBuilder()
241+
.setHash(gid.getByteString())
242+
.setNumber(gid.getNum())
243+
.build();
244+
245+
BlockCapsule.BlockId sid = chainBaseManager.getSolidBlockId();
246+
Protocol.HelloMessage.BlockId sBlockId = Protocol.HelloMessage.BlockId.newBuilder()
247+
.setHash(sid.getByteString())
248+
.setNumber(sid.getNum())
249+
.build();
250+
251+
BlockCapsule.BlockId hid = chainBaseManager.getHeadBlockId();
252+
Protocol.HelloMessage.BlockId hBlockId = Protocol.HelloMessage.BlockId.newBuilder()
253+
.setHash(hid.getByteString())
254+
.setNumber(hid.getNum())
255+
.build();
256+
Builder builder = Protocol.HelloMessage.newBuilder();
257+
builder.setFrom(fromEndpoint);
258+
builder.setVersion(Args.getInstance().getNodeP2pVersion());
259+
builder.setTimestamp(timestamp);
260+
builder.setGenesisBlockId(gBlockId);
261+
builder.setSolidBlockId(sBlockId);
262+
builder.setHeadBlockId(hBlockId);
263+
builder.setNodeType(chainBaseManager.getNodeType().getType());
264+
builder.setLowestBlockNum(chainBaseManager.isLiteNode()
265+
? chainBaseManager.getLowestBlockNum() : 0);
266+
267+
return builder;
268+
}
269+
}

0 commit comments

Comments
 (0)