From f46f90f06b65dfd8188f9a067b782f4611d4eace Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Wed, 27 Mar 2024 09:01:06 +0100 Subject: [PATCH] NashornJsInvokeServiceTest added givenSimpleScriptMultiThreadTestPerformance --- .../script/NashornJsInvokeServiceTest.java | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/service/script/NashornJsInvokeServiceTest.java b/application/src/test/java/org/thingsboard/server/service/script/NashornJsInvokeServiceTest.java index bb9dc57d3c..28834a0ab7 100644 --- a/application/src/test/java/org/thingsboard/server/service/script/NashornJsInvokeServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/script/NashornJsInvokeServiceTest.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.service.script; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.jupiter.api.Test; @@ -28,9 +30,12 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.controller.AbstractControllerTest; import org.thingsboard.server.dao.service.DaoSqlTest; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -80,6 +85,44 @@ class NashornJsInvokeServiceTest extends AbstractControllerTest { .isLessThan(TimeUnit.MINUTES.toMillis(1)); // effective exec time is about 500ms } + @Test + void givenSimpleScriptMultiThreadTestPerformance() throws ExecutionException, InterruptedException, TimeoutException { + int iterations = 1000*4; + List> futures = new ArrayList<>(iterations); + UUID scriptId = evalScript("return msg.temperature > 20 ;"); + // warmup + log.info("Warming up 1000 times..."); + + var warmupWatch = TbStopWatch.create(); + for (int i = 0; i < 1000; i++) { + futures.add(invokeScriptAsync(scriptId, "{\"temperature\":" + i + "}")); + } + List results = Futures.allAsList(futures).get(1, TimeUnit.MINUTES); + for (int i = 0; i < 1000; i++) { + boolean expected = i > 20; + boolean result = Boolean.parseBoolean(results.get(i).toString()); + Assert.assertEquals(expected, result); + } + log.info("Warming up finished in {} ms", warmupWatch.stopAndGetTotalTimeMillis()); + futures.clear(); + + log.info("Starting performance test..."); + var watch = TbStopWatch.create(); + for (int i = 0; i < iterations; i++) { + futures.add(invokeScriptAsync(scriptId, "{\"temperature\":" + i + "}")); + } + results = Futures.allAsList(futures).get(1, TimeUnit.MINUTES); + for (int i = 0; i < iterations; i++) { + boolean expected = i > 20; + boolean result = Boolean.parseBoolean(results.get(i).toString()); + Assert.assertEquals(expected, result); + } + long duration = watch.stopAndGetTotalTimeMillis(); + log.info("Performance test with {} invocations took: {} ms", iterations, duration); + assertThat(duration).as("duration ms") + .isLessThan(TimeUnit.MINUTES.toMillis(1)); // effective exec time is about 500ms + } + @Test void givenTooBigScriptForEval_thenReturnError() { String hugeScript = "var a = 'qwertyqwertywertyqwabababer'; return {a: a};"; @@ -127,7 +170,11 @@ class NashornJsInvokeServiceTest extends AbstractControllerTest { } private String invokeScript(UUID scriptId, String msg) throws ExecutionException, InterruptedException { - return invokeService.invokeScript(TenantId.SYS_TENANT_ID, null, scriptId, msg, "{}", POST_TELEMETRY_REQUEST.name()).get().toString(); + return invokeScriptAsync(scriptId, msg).get().toString(); + } + + private ListenableFuture invokeScriptAsync(UUID scriptId, String msg) { + return invokeService.invokeScript(TenantId.SYS_TENANT_ID, null, scriptId, msg, "{}", POST_TELEMETRY_REQUEST.name()); } }