|
1 | 1 | package org.tron.common.backup; |
2 | 2 |
|
| 3 | +import static org.mockito.Mockito.mockStatic; |
| 4 | + |
3 | 5 | import java.lang.reflect.Field; |
| 6 | +import java.lang.reflect.Method; |
| 7 | +import java.net.InetAddress; |
4 | 8 | import java.net.InetSocketAddress; |
5 | 9 | import java.util.ArrayList; |
| 10 | +import java.util.Collections; |
6 | 11 | import java.util.List; |
| 12 | +import java.util.Map; |
| 13 | +import java.util.Set; |
7 | 14 | import java.util.concurrent.ExecutorService; |
8 | 15 | import java.util.concurrent.ScheduledExecutorService; |
9 | 16 | import org.junit.After; |
|
12 | 19 | import org.junit.Rule; |
13 | 20 | import org.junit.Test; |
14 | 21 | import org.junit.rules.TemporaryFolder; |
| 22 | +import org.mockito.MockedStatic; |
15 | 23 | import org.tron.common.TestConstants; |
16 | 24 | import org.tron.common.backup.BackupManager.BackupStatusEnum; |
17 | 25 | import org.tron.common.backup.message.KeepAliveMessage; |
|
20 | 28 | import org.tron.common.parameter.CommonParameter; |
21 | 29 | import org.tron.common.utils.PublicMethod; |
22 | 30 | import org.tron.core.config.args.Args; |
| 31 | +import org.tron.p2p.dns.lookup.LookUpTxt; |
23 | 32 |
|
24 | 33 | public class BackupManagerTest { |
25 | 34 |
|
@@ -140,4 +149,118 @@ public void testSendKeepAliveMessage() throws Exception { |
140 | 149 |
|
141 | 150 | Assert.assertEquals(BackupManager.BackupStatusEnum.INIT, manager.getStatus()); |
142 | 151 | } |
| 152 | + |
| 153 | + // ===== domain-handling tests for init() ===== |
| 154 | + |
| 155 | + @Test(timeout = 5000) |
| 156 | + public void testInitResolvesDomainsToMembers() throws Exception { |
| 157 | + CommonParameter.getInstance().setBackupMembers( |
| 158 | + Collections.singletonList("node.example.com")); |
| 159 | + InetAddress resolved = InetAddress.getByName("1.2.3.4"); |
| 160 | + try (MockedStatic<LookUpTxt> mock = mockStatic(LookUpTxt.class)) { |
| 161 | + mock.when(() -> LookUpTxt.lookUpIp("node.example.com", true)).thenReturn(resolved); |
| 162 | + manager.init(); |
| 163 | + } |
| 164 | + Set<String> members = getField(manager, "members"); |
| 165 | + Map<String, String> cache = getField(manager, "domainIpCache"); |
| 166 | + Assert.assertTrue(members.contains("1.2.3.4")); |
| 167 | + Assert.assertEquals("1.2.3.4", cache.get("node.example.com")); |
| 168 | + manager.stop(); |
| 169 | + } |
| 170 | + |
| 171 | + @Test(timeout = 5000) |
| 172 | + public void testInitSkipsUnresolvableDomain() throws Exception { |
| 173 | + CommonParameter.getInstance().setBackupMembers( |
| 174 | + Collections.singletonList("bad.invalid.domain")); |
| 175 | + try (MockedStatic<LookUpTxt> mock = mockStatic(LookUpTxt.class)) { |
| 176 | + mock.when(() -> LookUpTxt.lookUpIp("bad.invalid.domain", true)).thenReturn(null); |
| 177 | + mock.when(() -> LookUpTxt.lookUpIp("bad.invalid.domain", false)).thenReturn(null); |
| 178 | + manager.init(); |
| 179 | + } |
| 180 | + Set<String> members = getField(manager, "members"); |
| 181 | + Map<String, String> cache = getField(manager, "domainIpCache"); |
| 182 | + Assert.assertTrue("unresolvable domain should be silently dropped", members.isEmpty()); |
| 183 | + Assert.assertTrue(cache.isEmpty()); |
| 184 | + manager.stop(); |
| 185 | + } |
| 186 | + |
| 187 | + @Test(timeout = 5000) |
| 188 | + public void testInitSkipsDomainResolvingToLocalIp() throws Exception { |
| 189 | + String localIp = InetAddress.getLocalHost().getHostAddress(); |
| 190 | + CommonParameter.getInstance().setBackupMembers( |
| 191 | + Collections.singletonList("self.local.host")); |
| 192 | + InetAddress selfAddr = InetAddress.getByName(localIp); |
| 193 | + try (MockedStatic<LookUpTxt> mock = mockStatic(LookUpTxt.class)) { |
| 194 | + mock.when(() -> LookUpTxt.lookUpIp("self.local.host", true)).thenReturn(selfAddr); |
| 195 | + manager.init(); |
| 196 | + } |
| 197 | + Set<String> members = getField(manager, "members"); |
| 198 | + Assert.assertFalse("domain resolving to local IP should not be in members", |
| 199 | + members.contains(localIp)); |
| 200 | + manager.stop(); |
| 201 | + } |
| 202 | + |
| 203 | + // ===== refreshMemberIps() tests ===== |
| 204 | + |
| 205 | + @Test(timeout = 5000) |
| 206 | + public void testRefreshMemberIpsIpChanged() throws Exception { |
| 207 | + Set<String> members = getField(manager, "members"); |
| 208 | + Map<String, String> cache = getField(manager, "domainIpCache"); |
| 209 | + members.add("1.1.1.1"); |
| 210 | + cache.put("peer.tron.network", "1.1.1.1"); |
| 211 | + |
| 212 | + InetAddress newAddr = InetAddress.getByName("2.2.2.2"); |
| 213 | + try (MockedStatic<LookUpTxt> mock = mockStatic(LookUpTxt.class)) { |
| 214 | + mock.when(() -> LookUpTxt.lookUpIp("peer.tron.network", true)).thenReturn(newAddr); |
| 215 | + invokeRefreshMemberIps(manager); |
| 216 | + } |
| 217 | + Assert.assertFalse(members.contains("1.1.1.1")); |
| 218 | + Assert.assertTrue(members.contains("2.2.2.2")); |
| 219 | + Assert.assertEquals("2.2.2.2", cache.get("peer.tron.network")); |
| 220 | + } |
| 221 | + |
| 222 | + @Test(timeout = 5000) |
| 223 | + public void testRefreshMemberIpsIpUnchanged() throws Exception { |
| 224 | + Set<String> members = getField(manager, "members"); |
| 225 | + Map<String, String> cache = getField(manager, "domainIpCache"); |
| 226 | + members.add("1.1.1.1"); |
| 227 | + cache.put("peer.tron.network", "1.1.1.1"); |
| 228 | + |
| 229 | + InetAddress sameAddr = InetAddress.getByName("1.1.1.1"); |
| 230 | + try (MockedStatic<LookUpTxt> mock = mockStatic(LookUpTxt.class)) { |
| 231 | + mock.when(() -> LookUpTxt.lookUpIp("peer.tron.network", true)).thenReturn(sameAddr); |
| 232 | + invokeRefreshMemberIps(manager); |
| 233 | + } |
| 234 | + Assert.assertTrue(members.contains("1.1.1.1")); |
| 235 | + Assert.assertEquals("1.1.1.1", cache.get("peer.tron.network")); |
| 236 | + } |
| 237 | + |
| 238 | + @Test(timeout = 5000) |
| 239 | + public void testRefreshMemberIpsDnsFailure() throws Exception { |
| 240 | + Set<String> members = getField(manager, "members"); |
| 241 | + Map<String, String> cache = getField(manager, "domainIpCache"); |
| 242 | + members.add("1.1.1.1"); |
| 243 | + cache.put("peer.tron.network", "1.1.1.1"); |
| 244 | + |
| 245 | + try (MockedStatic<LookUpTxt> mock = mockStatic(LookUpTxt.class)) { |
| 246 | + mock.when(() -> LookUpTxt.lookUpIp("peer.tron.network", true)).thenReturn(null); |
| 247 | + mock.when(() -> LookUpTxt.lookUpIp("peer.tron.network", false)).thenReturn(null); |
| 248 | + invokeRefreshMemberIps(manager); |
| 249 | + } |
| 250 | + Assert.assertTrue("old IP should be kept on DNS failure", members.contains("1.1.1.1")); |
| 251 | + Assert.assertEquals("1.1.1.1", cache.get("peer.tron.network")); |
| 252 | + } |
| 253 | + |
| 254 | + @SuppressWarnings("unchecked") |
| 255 | + private <T> T getField(Object obj, String name) throws Exception { |
| 256 | + Field f = obj.getClass().getDeclaredField(name); |
| 257 | + f.setAccessible(true); |
| 258 | + return (T) f.get(obj); |
| 259 | + } |
| 260 | + |
| 261 | + private void invokeRefreshMemberIps(BackupManager mgr) throws Exception { |
| 262 | + Method m = mgr.getClass().getDeclaredMethod("refreshMemberIps"); |
| 263 | + m.setAccessible(true); |
| 264 | + m.invoke(mgr); |
| 265 | + } |
143 | 266 | } |
0 commit comments