Skip to content

Commit 608b516

Browse files
author
Sunny Jiao
committed
update
1 parent eee5b2e commit 608b516

File tree

1 file changed

+21
-208
lines changed

1 file changed

+21
-208
lines changed

framework/src/test/java/org/tron/core/services/RpcApiServicesTest.java

Lines changed: 21 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ public class RpcApiServicesTest {
155155

156156
@BeforeClass
157157
public static void init() throws IOException {
158-
System.out.println("========== [BEFORE_CLASS] Starting init() ==========");
159-
System.err.println("========== [BEFORE_CLASS] Starting init() ==========");
160158
Args.setParam(new String[] {"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF);
161159
Assert.assertEquals(5, getInstance().getRpcMaxRstStream());
162160
Assert.assertEquals(10, getInstance().getRpcSecondsPerWindow());
@@ -206,35 +204,20 @@ public static void init() throws IOException {
206204
manager.getAccountStore().put(ownerCapsule.createDbKey(), ownerCapsule);
207205
manager.getDynamicPropertiesStore().saveAllowShieldedTransaction(1);
208206
manager.getDynamicPropertiesStore().saveAllowShieldedTRC20Transaction(1);
209-
System.out.println("========== [BEFORE_CLASS] Creating Application... ==========");
210-
System.err.println("========== [BEFORE_CLASS] Creating Application... ==========");
211207
appTest = ApplicationFactory.create(context);
212-
System.out.println("========== [BEFORE_CLASS] Starting Application... ==========");
213-
System.err.println("========== [BEFORE_CLASS] Starting Application... ==========");
214208
appTest.startup();
215-
System.out.println("========== [BEFORE_CLASS] Application started ==========");
216-
System.err.println("========== [BEFORE_CLASS] Application started ==========");
217209

218-
// Initialize stress test channels (increased to 30 for more pressure)
219-
System.out.println("========== [BEFORE_CLASS] Initializing stress test channels... ==========");
220-
System.err.println("========== [BEFORE_CLASS] Initializing stress test channels... ==========");
221-
int stressChannelCount = 30;
210+
// Initialize stress test channels (increased to 100 for maximum pressure)
211+
int stressChannelCount = 100;
222212
stressChannels = new ManagedChannel[stressChannelCount];
223213
stressStubs = new WalletBlockingStub[stressChannelCount];
224214
for (int i = 0; i < stressChannelCount; i++) {
225-
if (i % 10 == 0) {
226-
System.out.println("========== [BEFORE_CLASS] Creating stress channel " + i + "/" + stressChannelCount + " ==========");
227-
System.err.println("========== [BEFORE_CLASS] Creating stress channel " + i + "/" + stressChannelCount + " ==========");
228-
}
229215
stressChannels[i] = ManagedChannelBuilder.forTarget(fullNode)
230216
.usePlaintext()
231217
.intercept(new TimeoutInterceptor(5000))
232218
.build();
233219
stressStubs[i] = WalletGrpc.newBlockingStub(stressChannels[i]);
234220
}
235-
System.out.println("========== [BEFORE_CLASS] Initialized " + stressChannelCount + " stress test channels ==========");
236-
System.err.println("========== [BEFORE_CLASS] Initialized " + stressChannelCount + " stress test channels ==========");
237-
logger.info("Initialized {} stress test channels", stressChannelCount);
238221
}
239222

240223
@AfterClass
@@ -263,14 +246,10 @@ public static void destroy() {
263246

264247
@Before
265248
public void start() {
266-
logger.debug("========== Starting test: {} ==========", name.getMethodName());
267-
System.out.println("========== Starting test: " + name.getMethodName() + " ==========");
268249
}
269250

270251
@After
271252
public void end() throws InterruptedException {
272-
logger.debug("========== Ending test: {} ==========", name.getMethodName());
273-
System.out.println("========== Ending test: " + name.getMethodName() + " ==========");
274253
}
275254

276255
@Test
@@ -428,213 +407,47 @@ public void testGetCanDelegatedMaxSize() {
428407
}
429408

430409
/**
431-
* Stress test to reproduce potential gRPC-Java ThreadlessExecutor bug.
432-
* This test creates multiple channels and executes concurrent requests to increase
433-
* the probability of triggering the callback submission failure issue.
410+
* Continuous stress test that runs until it hangs (to reproduce the bug).
411+
* Maximum stress on gRPC-Java-Netty event handling - no logging overhead.
434412
*/
435-
@Test(timeout = 60000) // 60 seconds timeout
436-
public void testStressMultipleChannels() throws InterruptedException {
437-
System.out.println("========== Starting stress test with multiple channels ==========");
438-
logger.info("========== Starting stress test with multiple channels ==========");
439-
440-
int threadCount = 50; // Increased from 20 to 50
441-
int requestsPerThread = 100; // Increased from 50 to 100
442-
int totalRequests = threadCount * requestsPerThread;
443-
444-
System.out.println("Thread count: " + threadCount + ", Requests per thread: " + requestsPerThread + ", Total requests: " + totalRequests);
445-
446-
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
447-
CountDownLatch latch = new CountDownLatch(totalRequests);
448-
AtomicInteger successCount = new AtomicInteger(0);
449-
AtomicInteger failureCount = new AtomicInteger(0);
450-
List<Exception> exceptions = new ArrayList<>();
451-
413+
@Test(timeout = 300000) // 5 minutes timeout - will hang if bug occurs
414+
public void testContinuousStressUntilHang() throws InterruptedException {
452415
CanDelegatedMaxSizeRequestMessage message = CanDelegatedMaxSizeRequestMessage.newBuilder()
453416
.setType(0).setOwnerAddress(ownerAddress).build();
454-
455-
// Submit requests using all available channels
456-
for (int i = 0; i < totalRequests; i++) {
417+
418+
// Maximum stress: 200 threads × 500 requests = 100,000 requests per iteration
419+
int threadCount = 200;
420+
int requestsPerIteration = 500;
421+
int iterationTotalRequests = threadCount * requestsPerIteration;
422+
423+
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
424+
CountDownLatch latch = new CountDownLatch(iterationTotalRequests);
425+
426+
for (int i = 0; i < iterationTotalRequests; i++) {
457427
final int requestId = i;
458428
executor.submit(() -> {
459429
try {
460-
// Distribute requests across all channels
430+
// Distribute requests across all channels to maximize event loop pressure
461431
if (requestId % 3 == 0) {
462-
// Use blockingStubFull
463432
assertNotNull(blockingStubFull.getCanDelegatedMaxSize(message));
464433
} else if (requestId % 3 == 1 && stressStubs != null && stressStubs.length > 0) {
465-
// Use stress stubs
466434
assertNotNull(stressStubs[requestId % stressStubs.length].getCanDelegatedMaxSize(message));
467435
} else {
468-
// Use blockingStubSolidity (WalletSolidityBlockingStub)
469436
assertNotNull(blockingStubSolidity.getCanDelegatedMaxSize(message));
470437
}
471-
472-
successCount.incrementAndGet();
473-
} catch (Exception e) {
474-
failureCount.incrementAndGet();
475-
synchronized (exceptions) {
476-
exceptions.add(e);
477-
}
478-
logger.error("Request {} failed", requestId, e);
479438
} finally {
480439
latch.countDown();
481440
}
482441
});
483442
}
484-
485-
// Wait for all requests to complete with timeout (increased to 55 seconds)
486-
boolean completed = latch.await(55, TimeUnit.SECONDS);
487-
443+
444+
// Wait for completion - if this hangs, the bug is reproduced!
445+
latch.await(120, TimeUnit.SECONDS);
446+
488447
executor.shutdown();
489448
if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
490449
executor.shutdownNow();
491450
}
492-
493-
System.out.println("========== Stress test completed ==========");
494-
System.out.println("Total requests: " + totalRequests);
495-
System.out.println("Success: " + successCount.get() + ", Failure: " + failureCount.get());
496-
System.out.println("Completed: " + completed);
497-
498-
logger.info("========== Stress test completed ==========");
499-
logger.info("Total requests: {}", totalRequests);
500-
logger.info("Success: {}, Failure: {}", successCount.get(), failureCount.get());
501-
logger.info("Completed: {}", completed);
502-
503-
if (!exceptions.isEmpty()) {
504-
System.out.println("First exception: " + exceptions.get(0).getMessage());
505-
logger.error("First exception: {}", exceptions.get(0).getMessage(), exceptions.get(0));
506-
}
507-
508-
// Assert that all requests completed
509-
Assert.assertTrue("Not all requests completed in time. Success: " + successCount.get()
510-
+ ", Failure: " + failureCount.get() + ", Completed: " + completed,
511-
completed);
512-
513-
// Log if there were failures (might indicate the bug)
514-
if (failureCount.get() > 0) {
515-
System.out.println("WARNING: Stress test detected " + failureCount.get() + " failures, which might indicate the ThreadlessExecutor bug");
516-
logger.warn("Stress test detected {} failures, which might indicate the ThreadlessExecutor bug",
517-
failureCount.get());
518-
}
519-
}
520-
521-
/**
522-
* Continuous stress test that runs until it hangs (to reproduce the bug).
523-
* This test will keep running until it times out or hangs, increasing the probability
524-
* of reproducing the ThreadlessExecutor callback submission failure.
525-
*/
526-
@Test(timeout = 300000) // 5 minutes timeout - will hang if bug occurs
527-
public void testContinuousStressUntilHang() throws InterruptedException {
528-
System.out.println("========== [TEST] Starting CONTINUOUS stress test (will run until hang) ==========");
529-
System.err.println("========== [TEST] Starting CONTINUOUS stress test (will run until hang) ==========");
530-
logger.info("========== Starting CONTINUOUS stress test (will run until hang) ==========");
531-
532-
CanDelegatedMaxSizeRequestMessage message = CanDelegatedMaxSizeRequestMessage.newBuilder()
533-
.setType(0).setOwnerAddress(ownerAddress).build();
534-
535-
int iteration = 0;
536-
int totalRequests = 0;
537-
int totalSuccess = 0;
538-
int totalFailures = 0;
539-
long startTime = System.currentTimeMillis();
540-
541-
// Run continuously until timeout or hang
542-
while (true) {
543-
iteration++;
544-
final int currentIteration = iteration; // Make final for lambda
545-
System.out.println("\n========== Iteration " + currentIteration + " ==========");
546-
System.err.println("\n========== Iteration " + currentIteration + " ==========");
547-
System.out.flush();
548-
System.err.flush();
549-
logger.info("========== Iteration {} ==========", currentIteration);
550-
551-
// Each iteration: 50 threads × 100 requests = 5000 requests
552-
int threadCount = 50;
553-
int requestsPerIteration = 100;
554-
int iterationTotalRequests = threadCount * requestsPerIteration;
555-
556-
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
557-
CountDownLatch latch = new CountDownLatch(iterationTotalRequests);
558-
AtomicInteger successCount = new AtomicInteger(0);
559-
AtomicInteger failureCount = new AtomicInteger(0);
560-
561-
long iterationStartTime = System.currentTimeMillis();
562-
563-
for (int i = 0; i < iterationTotalRequests; i++) {
564-
final int requestId = i;
565-
executor.submit(() -> {
566-
try {
567-
// Distribute requests across all channels
568-
if (requestId % 3 == 0) {
569-
assertNotNull(blockingStubFull.getCanDelegatedMaxSize(message));
570-
} else if (requestId % 3 == 1 && stressStubs != null && stressStubs.length > 0) {
571-
assertNotNull(stressStubs[requestId % stressStubs.length].getCanDelegatedMaxSize(message));
572-
} else {
573-
assertNotNull(blockingStubSolidity.getCanDelegatedMaxSize(message));
574-
}
575-
successCount.incrementAndGet();
576-
} catch (Exception e) {
577-
failureCount.incrementAndGet();
578-
logger.error("Request {} failed in iteration {}", requestId, currentIteration, e);
579-
} finally {
580-
latch.countDown();
581-
}
582-
});
583-
}
584-
585-
System.out.println("All requests submitted, waiting for completion...");
586-
System.err.println("All requests submitted, waiting for completion...");
587-
System.out.flush();
588-
System.err.flush();
589-
590-
// Wait for completion with timeout - if this hangs, the bug is reproduced!
591-
boolean completed = latch.await(60, TimeUnit.SECONDS);
592-
593-
executor.shutdown();
594-
if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
595-
executor.shutdownNow();
596-
}
597-
598-
long iterationTime = System.currentTimeMillis() - iterationStartTime;
599-
totalRequests += iterationTotalRequests;
600-
totalSuccess += successCount.get();
601-
totalFailures += failureCount.get();
602-
603-
System.out.println("Iteration " + currentIteration + " completed in " + iterationTime + "ms");
604-
System.err.println("Iteration " + currentIteration + " completed in " + iterationTime + "ms");
605-
System.out.println(" Requests: " + iterationTotalRequests + ", Success: " + successCount.get() + ", Failure: " + failureCount.get());
606-
System.err.println(" Requests: " + iterationTotalRequests + ", Success: " + successCount.get() + ", Failure: " + failureCount.get());
607-
System.out.println(" Completed: " + completed);
608-
System.err.println(" Completed: " + completed);
609-
System.out.println("Total so far - Requests: " + totalRequests + ", Success: " + totalSuccess + ", Failure: " + totalFailures);
610-
System.err.println("Total so far - Requests: " + totalRequests + ", Success: " + totalSuccess + ", Failure: " + totalFailures);
611-
System.out.println("Elapsed time: " + (System.currentTimeMillis() - startTime) + "ms");
612-
System.err.println("Elapsed time: " + (System.currentTimeMillis() - startTime) + "ms");
613-
614-
logger.info("Iteration {} completed in {}ms", currentIteration, iterationTime);
615-
logger.info(" Requests: {}, Success: {}, Failure: {}", iterationTotalRequests, successCount.get(), failureCount.get());
616-
logger.info("Total so far - Requests: {}, Success: {}, Failure: {}", totalRequests, totalSuccess, totalFailures);
617-
618-
if (!completed) {
619-
System.out.println("\n!!! WARNING: Iteration " + currentIteration + " did not complete in time - THIS MIGHT BE THE BUG !!!");
620-
System.err.println("\n!!! WARNING: Iteration " + currentIteration + " did not complete in time - THIS MIGHT BE THE BUG !!!");
621-
logger.error("!!! WARNING: Iteration {} did not complete in time - THIS MIGHT BE THE BUG !!!", currentIteration);
622-
// Continue anyway to see if it recovers
623-
}
624-
625-
if (failureCount.get() > 0) {
626-
System.out.println("WARNING: Iteration " + currentIteration + " had " + failureCount.get() + " failures");
627-
System.err.println("WARNING: Iteration " + currentIteration + " had " + failureCount.get() + " failures");
628-
logger.warn("Iteration {} had {} failures", currentIteration, failureCount.get());
629-
}
630-
631-
// Force flush output
632-
System.out.flush();
633-
System.err.flush();
634-
635-
// Small delay between iterations to avoid overwhelming the system
636-
Thread.sleep(100);
637-
}
638451
}
639452

640453
@Test

0 commit comments

Comments
 (0)