diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/launch/LaunchListener.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/launch/LaunchListener.java deleted file mode 100644 index bb4953d1f8e2..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/launch/LaunchListener.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package io.ballerina.runtime.api.launch; - -/** - * This represents the Java SPI interface for listening Launcher events. - * - * @since 1.0 - */ -public interface LaunchListener { - - /** - * This is called before running the services or main. - * - * @param service A flag to indicate whether the program is a service. - */ - void beforeRunProgram(boolean service); - - /** - * This is called after running the services or main. - * - * @param service A flag to indicate whether the program is a service. - */ - void afterRunProgram(boolean service); - -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/launch/LaunchUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/launch/LaunchUtils.java index 8ecd1a6d728c..8ee2a98ad87b 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/launch/LaunchUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/launch/LaunchUtils.java @@ -19,7 +19,6 @@ package io.ballerina.runtime.internal.launch; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.launch.LaunchListener; import io.ballerina.runtime.internal.configurable.ConfigMap; import io.ballerina.runtime.internal.configurable.ConfigProvider; import io.ballerina.runtime.internal.configurable.ConfigResolver; @@ -43,7 +42,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.ServiceLoader; import java.util.Set; import static io.ballerina.runtime.api.constants.RuntimeConstants.DOT; @@ -66,14 +64,10 @@ public class LaunchUtils { private LaunchUtils() { } - public static void startListenersAndSignalHandler(boolean isService) { - // starts all listeners - startListeners(isService); - - // start TRAP signal handler which produces the strand dump - startTrapSignalHandler(); - } - + @SuppressWarnings("unused") + /* + * Used for codegen. This will handle trap signals for strand dump. + */ public static void startTrapSignalHandler() { try { Signal.handle(new Signal("TRAP"), signal -> outStream.println(StrandDump.getStrandDump())); @@ -83,16 +77,10 @@ public static void startTrapSignalHandler() { } } - public static void startListeners(boolean isService) { - ServiceLoader listeners = ServiceLoader.load(LaunchListener.class); - listeners.forEach(listener -> listener.beforeRunProgram(isService)); - } - - public static void stopListeners(boolean isService) { - ServiceLoader listeners = ServiceLoader.load(LaunchListener.class); - listeners.forEach(listener -> listener.afterRunProgram(isService)); - } - + @SuppressWarnings("unused") + /* + * Used for codegen adding module configurable data. + */ public static void addModuleConfigData(Map configurationData, Module m, VariableKey[] variableKeys) { VariableKey[] currKeys = configurationData.get(m); @@ -107,6 +95,10 @@ public static void addModuleConfigData(Map configurationD configurationData.put(m, mergedKeyArray); } + @SuppressWarnings("unused") + /* + * Used for codegen initialize configurable variables. + */ public static void initConfigurableVariables(Module rootModule, Map configurationData, String[] args, Path[] configFilePaths, String configContent) { @@ -159,6 +151,10 @@ private static String populateConfigDetails(List paths, Map conditionSupplier, - Supplier resultSupplier) { - boolean waitDone = false; - while (!waitDone) { - try { - strand.yield(); - waitDone = conditionSupplier.get(); - } finally { - strand.resume(); - } + public static Object handleNonIsolatedStrand(Strand strand, Supplier resultSupplier) { + boolean runnable = strand.isRunnable(); + if (runnable) { + strand.yield(); + + } + Object result = resultSupplier.get(); + if (runnable) { + strand.resume(); } - return resultSupplier.get(); + return result; } @SuppressWarnings("unused") @@ -69,7 +68,7 @@ public static Object handleWait(Strand strand, CompletableFuture complet if (strand.isIsolated) { return getFutureResult(completableFuture); } - return handleNonIsolatedStrand(strand, completableFuture::isDone, () -> getFutureResult(completableFuture)); + return handleNonIsolatedStrand(strand, () -> getFutureResult(completableFuture)); } @SuppressWarnings("unused") @@ -112,16 +111,7 @@ public static void handleWaitMultiple(Strand strand, Map fu getAllFutureResult(futureMap, alreadyWaitedKeys, target); } handleNonIsolatedStrand(strand, () -> { - for (CompletableFuture cFuture : cFutures) { - if (cFuture.isCompletedExceptionally()) { - getFutureResult(cFuture); - } - if (!cFuture.isDone()) { - return false; - } - } - return true; - }, () -> { + waitForAllFutureResult(cFutures.toArray(new CompletableFuture[0])); getAllFutureResult(futureMap, alreadyWaitedKeys, target); return null; }); @@ -132,14 +122,7 @@ public static Object handleWaitAny(Strand strand, CompletableFuture[] cFuture if (strand.isIsolated) { result = getAnyFutureResult(cFutures); } else { - result = handleNonIsolatedStrand(strand, () -> { - for (CompletableFuture completableFuture : cFutures) { - if (completableFuture.isDone()) { - return true; - } - } - return false; - }, () -> getAnyFutureResult(cFutures)); + result = handleNonIsolatedStrand(strand, () -> getAnyFutureResult(cFutures)); } if (cFutures.length > 1 && result instanceof BError) { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java index f58196e71fb7..1cedbb3291b2 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java @@ -75,24 +75,48 @@ public static Strand getStrand() { return daemonStrand; } public Object call(Module module, String functionName, Strand parentStrand, Object... args) { + boolean runnable = parentStrand.isRunnable(); + if (!runnable) { + parentStrand.resume(); + } ValueCreatorAndFunctionType functionType = getGetValueCreatorAndFunctionType(module, functionName); Object[] argsWithDefaultValues = getArgsWithDefaultValues(functionType.valueCreator(), functionType.functionType(), parentStrand, args); - return functionType.valueCreator().call(parentStrand, functionName, argsWithDefaultValues); + Object result = functionType.valueCreator().call(parentStrand, functionName, argsWithDefaultValues); + if (!runnable) { + parentStrand.yield(); + } + return result; } public Object call(BObject object, String methodName, Strand parentStrand, Object... args) { + boolean runnable = parentStrand.isRunnable(); + if (!runnable) { + parentStrand.resume(); + } ObjectType objectType = (ObjectType) TypeUtils.getImpliedType(object.getOriginalType()); MethodType methodType = getObjectMethodType(methodName, objectType); Object[] argsWithDefaultValues = getArgsWithDefaultValues(objectType, methodType, parentStrand, args); - return ((ObjectValue) object).call(parentStrand, methodName, argsWithDefaultValues); + Object result = ((ObjectValue) object).call(parentStrand, methodName, argsWithDefaultValues); + if (!runnable) { + parentStrand.yield(); + } + return result; } public Object call(FPValue fp, Strand parentStrand, Object... args) { + boolean runnable = parentStrand.isRunnable(); + if (!runnable) { + parentStrand.resume(); + } FunctionType functionType = (FunctionType) TypeUtils.getImpliedType(TypeUtils.getType(fp)); Object[] argsWithDefaultValues = getArgsWithDefaultValues(parentStrand, args, functionType); Object[] argsWithStrand = getArgsWithStrand(parentStrand, argsWithDefaultValues); - return fp.function.apply(argsWithStrand); + Object result = fp.function.apply(argsWithStrand); + if (!runnable) { + parentStrand.yield(); + } + return result; } public FutureValue startIsolatedWorker(String functionName, Module module, Strand parentStrand, String strandName, diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java index 8076cb72b015..ce9cac2f054b 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java @@ -44,7 +44,7 @@ public class Strand { private Map globalProps; public final boolean isIsolated; - public State state = State.YIELD; + public boolean cancelled; public Scheduler scheduler; public Strand parent; public TransactionLocalContext currentTrxContext; @@ -89,26 +89,30 @@ public Strand(String name, StrandMetadata metadata, Scheduler scheduler, Strand public void resume() { checkStrandCancelled(); - if (!this.isIsolated && this.state == State.YIELD) { + if (!this.isIsolated && !scheduler.globalNonIsolatedLock.isHeldByCurrentThread()) { this.scheduler.globalNonIsolatedLock.lock(); - this.state = State.RUNNABLE; + } } public void yield() { checkStrandCancelled(); - if (!this.isIsolated && this.state == State.RUNNABLE) { + if (!this.isIsolated && scheduler.globalNonIsolatedLock.isHeldByCurrentThread()) { scheduler.globalNonIsolatedLock.unlock(); - this.state = State.YIELD; } } public void done() { - if (!isIsolated && this.state == State.RUNNABLE) { + if (!isIsolated && scheduler.globalNonIsolatedLock.isHeldByCurrentThread()) { scheduler.globalNonIsolatedLock.unlock(); } } + public boolean isRunnable() { + return isIsolated || this.scheduler.globalNonIsolatedLock.isHeldByCurrentThread(); + } + + private TransactionLocalContext createTrxContextBranch(TransactionLocalContext currentTrxContext, int strandName) { TransactionLocalContext trxCtx = TransactionLocalContext @@ -181,20 +185,8 @@ public StrandMetadata getMetadata() { } public void checkStrandCancelled() { - if (this.state == State.CANCELLED) { + if (this.cancelled) { throw ErrorUtils.createCancelledFutureError(); } } - - /** - * Maintains the Strand state. - * - * @since 2201.11.0 - */ - public enum State { - RUNNABLE, - YIELD, - CANCELLED - } - } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerUtils.java index 11146e0d21d0..eb1f7d0d0a2f 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerUtils.java @@ -78,7 +78,10 @@ public static Object flush(Strand strand, WorkerChannelMap workerChannelMap, Str if (strand.isIsolated) { AsyncUtils.waitForAllFutureResult(futures); } else { - AsyncUtils.handleNonIsolatedStrand(strand, () -> isAllFuturesCompleted(futures), () -> null); + AsyncUtils.handleNonIsolatedStrand(strand, () -> { + AsyncUtils.waitForAllFutureResult(futures); + return null; + }); } for (WorkerChannel channel : channels) { @@ -95,7 +98,7 @@ public static Object receive(Strand strand, WorkerChannelMap workerChannelMap, S if (strand.isIsolated) { return channel.read(); } - return AsyncUtils.handleNonIsolatedStrand(strand, channel.getResultFuture()::isDone, channel::read); + return AsyncUtils.handleNonIsolatedStrand(strand, channel::read); } /* @@ -135,8 +138,11 @@ public static BMap multipleReceive(Strand strand, WorkerChannel AsyncUtils.waitForAllFutureResult(futures); return getMultipleReceiveResult(workerChannelMap, channelFieldNameMap, targetType, channels); } - return (BMap) AsyncUtils.handleNonIsolatedStrand(strand, () -> isAllFuturesCompleted(futures), - () -> getMultipleReceiveResult(workerChannelMap, channelFieldNameMap, targetType, channels)); + return (BMap) AsyncUtils.handleNonIsolatedStrand(strand, + () -> { + AsyncUtils.waitForAllFutureResult(futures); + return getMultipleReceiveResult(workerChannelMap, channelFieldNameMap, targetType, channels); + }); } /* @@ -207,18 +213,6 @@ private static Object getAlternativeReceiveResult(Strand strand, CompletableFutu return result; } - private static Boolean isAllFuturesCompleted(CompletableFuture[] futures) { - for (CompletableFuture future : futures) { - if (future.isCompletedExceptionally()) { - AsyncUtils.getFutureResult(future); - } - if (!future.isDone()) { - return false; - } - } - return true; - } - private static BMap getMultipleReceiveResult(WorkerChannelMap workerChannelMap, Map channelFieldNameMap, Type targetType, WorkerChannel[] channels) { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java index 2bd9ddb2b61c..130c0380382f 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java @@ -20,7 +20,6 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BString; @@ -54,7 +53,7 @@ public class RuntimeUtils { private static final String CRASH_LOGGER = "b7a.log.crash"; private static final PrintStream errStream = System.err; public static final String USER_DIR = System.getProperty("user.dir"); - private static final Logger crashLogger = Logger.getLogger(CRASH_LOGGER); + private static final Logger crashLogger = Logger.getLogger(CRASH_LOGGER); private static ConsoleHandler handler; /** @@ -67,20 +66,31 @@ public static boolean isByteLiteral(int intValue) { return (intValue >= BBYTE_MIN_VALUE && intValue <= BBYTE_MAX_VALUE); } - public static void handleFuture(FutureValue future) { + @SuppressWarnings("unused") + /* + * Used for codegen. This will handle future value in main method. + */ + public static void handleFutureAndExit(FutureValue future) { try { - handleErrorResult(getFutureValue(future)); + Object result = future.get(); + if (result instanceof ErrorValue error) { + errStream.println("error: " + error.getPrintableError()); + Runtime.getRuntime().exit(1); + } } catch (ErrorValue error) { printToConsole(error); + Runtime.getRuntime().exit(1); } } + @SuppressWarnings("unused") + /* + * Used for codegen. This will handle future value in tests. + */ public static boolean handleFutureAndReturnIsPanic(FutureValue future) { try { - Object result = getFutureValue(future); - if (result instanceof ErrorValue errorValue) { - errStream.println("error: " + errorValue.getPrintableError()); - } + Object result = future.get(); + handleErrorResult(result); } catch (ErrorValue error) { printToConsole(error); return true; @@ -88,16 +98,22 @@ public static boolean handleFutureAndReturnIsPanic(FutureValue future) { return false; } - public static void handleFutureAndExit(FutureValue future) { + @SuppressWarnings("unused") + /* + * Used for codegen. This will handle future value in init and stop methods. + */ + public static void handleFuture(FutureValue future) { try { - handleErrorResult(getFutureValue(future)); - Runtime.getRuntime().exit(0); + handleErrorResult(future.get()); } catch (ErrorValue error) { printToConsole(error); - Runtime.getRuntime().exit(1); } } + @SuppressWarnings("unused") + /* + * Used for codegen. This will handle throwable in main method. + */ public static void handleThrowable(Throwable throwable) { logBadSad(throwable); Runtime.getRuntime().exit(1); @@ -109,17 +125,6 @@ public static void handleErrorResult(Object result) { } } - public static Object getFutureValue(FutureValue future) { - try { - return future.completableFuture.get(); - } catch (Throwable e) { - if (e.getCause() instanceof BError bError) { - throw bError; - } - throw ErrorCreator.createError(e); - } - } - private static void printToConsole(ErrorValue throwable) { errStream.println("error: " + throwable.getPrintableStackTrace()); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FutureValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FutureValue.java index 3cfbb54136c0..979cf62d5478 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FutureValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FutureValue.java @@ -102,7 +102,7 @@ public BTypedesc getTypedesc() { @Override public void cancel() { - this.strand.state = Strand.State.CANCELLED; + this.strand.cancelled = true; if (this.strand.workerChannelMap != null) { this.strand.workerChannelMap.cancel(); } diff --git a/bvm/ballerina-runtime/src/main/java/module-info.java b/bvm/ballerina-runtime/src/main/java/module-info.java index 6fac73df7ed5..811d724b1f8b 100644 --- a/bvm/ballerina-runtime/src/main/java/module-info.java +++ b/bvm/ballerina-runtime/src/main/java/module-info.java @@ -25,7 +25,6 @@ exports io.ballerina.runtime.api.constants; exports io.ballerina.runtime.api.creators; exports io.ballerina.runtime.api.flags; - exports io.ballerina.runtime.api.launch; exports io.ballerina.runtime.api.types; exports io.ballerina.runtime.api.utils; exports io.ballerina.runtime.api.values; diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmPackageGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmPackageGen.java index d2ff747d9c56..5f9c36e2bd33 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmPackageGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmPackageGen.java @@ -387,7 +387,6 @@ private void generateModuleClasses(BIRPackage module, JarEntries jarEntries, Str initMethodGen.generateLambdaForModuleExecuteFunction(cw, moduleClass, jvmCastGen, mainFunc, testExecuteFunc); initMethodGen.generateLambdaForPackageInit(cw, module, moduleClass); - initMethodGen.generateGracefulExitMethod(cw); if (isTestable) { initMethodGen.generateGetTestExecutionState(cw, moduleClass); } @@ -705,7 +704,7 @@ CompiledJarFile generate(BIRPackage module) { // enrich current package with package initializers initMethodGen.enrichPkgWithInitializers(birFunctionMap, jvmClassMapping, moduleInitClass, module, - immediateImports, serviceEPAvailable, mainFunc, testExecuteFunc); + immediateImports, mainFunc, testExecuteFunc); TypeHashVisitor typeHashVisitor = new TypeHashVisitor(); AsyncDataCollector asyncDataCollector = new AsyncDataCollector(module); JvmConstantsGen jvmConstantsGen = new JvmConstantsGen(module, moduleInitClass, types, typeHashVisitor); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/InitMethodGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/InitMethodGen.java index ab1738027052..a36b71b9f4ac 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/InitMethodGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/InitMethodGen.java @@ -31,7 +31,6 @@ import org.wso2.ballerinalang.compiler.bir.codegen.internal.JavaClass; import org.wso2.ballerinalang.compiler.bir.codegen.model.BIRFunctionWrapper; import org.wso2.ballerinalang.compiler.bir.codegen.model.JIMethodCLICall; -import org.wso2.ballerinalang.compiler.bir.codegen.model.JIMethodCall; import org.wso2.ballerinalang.compiler.bir.codegen.split.JvmConstantsGen; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; import org.wso2.ballerinalang.compiler.bir.model.BIRNonTerminator; @@ -82,7 +81,6 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_INIT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_STOP_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.GET_TEST_EXECUTION_STATE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.GRACEFUL_EXIT_METHOD_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_FUTURE_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LAMBDA_PREFIX; @@ -105,7 +103,6 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.VALUE_CREATOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ADD_VALUE_CREATOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.CURRENT_MODULE_STOP; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_BAL_RUNTIME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MAIN_ARGS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_RUNTIME_REGISTRY; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_SCHEDULER; @@ -293,14 +290,14 @@ private void generateCallSchedulerStopDynamicListeners(MethodVisitor mv, String private void generateCallStopDynamicLambda(MethodVisitor mv, String lambdaName, String moduleInitClass, AsyncDataCollector asyncDataCollector, JvmConstantsGen jvmConstantsGen) { - addRuntimeRegistryAsParameter(mv, moduleInitClass); + addRuntimeRegistryAsParameter(mv); generateMethodBody(mv, moduleInitClass, lambdaName, asyncDataCollector, jvmConstantsGen); // handle future result mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESTATIC, RUNTIME_UTILS, HANDLE_FUTURE_METHOD, HANDLE_FUTURE, false); } - private void addRuntimeRegistryAsParameter(MethodVisitor mv, String initClass) { + private void addRuntimeRegistryAsParameter(MethodVisitor mv) { mv.visitIntInsn(BIPUSH, 2); mv.visitTypeInsn(ANEWARRAY, OBJECT); mv.visitVarInsn(ASTORE, 2); @@ -330,7 +327,7 @@ private void generateMethodBody(MethodVisitor mv, String initClass, String stopF public void enrichPkgWithInitializers(Map birFunctionMap, Map jvmClassMap, String typeOwnerClass, BIRNode.BIRPackage pkg, Set moduleImports, - boolean serviceEPAvailable, BIRNode.BIRFunction mainFunc, + BIRNode.BIRFunction mainFunc, BIRNode.BIRFunction testExecuteFunc) { JavaClass javaClass = jvmClassMap.get(typeOwnerClass); BIRNode.BIRFunction initFunc = generateDefaultFunction(moduleImports, pkg, MODULE_INIT_METHOD, @@ -347,17 +344,17 @@ public void enrichPkgWithInitializers(Map birFunctio birFunctionMap.put(JvmCodeGenUtil.getPackageName(pkg.packageID) + MODULE_START_METHOD, JvmPackageGen.getFunctionWrapper(startFunc, pkg.packageID, typeOwnerClass)); - BIRNode.BIRFunction execFunc = generateExecuteFunction(pkg, serviceEPAvailable, mainFunc, testExecuteFunc, - typeOwnerClass); + BIRNode.BIRFunction execFunc = generateExecuteFunction(pkg, mainFunc, testExecuteFunc + ); javaClass.functions.add(execFunc); pkg.functions.add(execFunc); birFunctionMap.put(JvmCodeGenUtil.getPackageName(pkg.packageID) + MODULE_EXECUTE_METHOD, JvmPackageGen.getFunctionWrapper(execFunc, pkg.packageID, typeOwnerClass)); } - private BIRNode.BIRFunction generateExecuteFunction(BIRNode.BIRPackage pkg, boolean serviceEPAvailable, + private BIRNode.BIRFunction generateExecuteFunction(BIRNode.BIRPackage pkg, BIRNode.BIRFunction mainFunc, - BIRNode.BIRFunction testExecuteFunc, String typeOwnerClass) { + BIRNode.BIRFunction testExecuteFunc) { BIRNode.BIRVariableDcl retVar = new BIRNode.BIRVariableDcl(null, errorOrNilType, new Name("%ret"), VarScope.FUNCTION, VarKind.RETURN, null); BIROperand retVarRef = new BIROperand(retVar); @@ -441,9 +438,7 @@ private BIRNode.BIRFunction generateExecuteFunction(BIRNode.BIRPackage pkg, bool if (testExecuteFunc != null) { lastBB = addTestExecuteInvocationWithGracefulExitCall(modExecFunc, pkg.packageID, retVarRef, functionArgs, - Collections.emptyList(), typeOwnerClass); - } else if (!serviceEPAvailable && !JvmPackageGen.isLangModule(pkg.packageID)) { - lastBB = addInvocationForGracefulExitCall(modExecFunc, typeOwnerClass); + Collections.emptyList()); } lastBB.terminator = new BIRTerminator.Return(null); return modExecFunc; @@ -555,32 +550,11 @@ private Name getNextVarId() { return new Name(varIdPrefix + nextVarId); } - private BIRNode.BIRBasicBlock addInvocationForGracefulExitCall(BIRNode.BIRFunction func, String typeOwnerClass) { - BIRNode.BIRBasicBlock lastBB = func.basicBlocks.getLast(); - BIRNode.BIRBasicBlock nextBB = addAndGetNextBasicBlock(func); - lastBB.terminator = getExitMethodCall(nextBB, typeOwnerClass); - return nextBB; - } - - private static JIMethodCall getExitMethodCall(BIRNode.BIRBasicBlock nextBB, String typeOwnerClass) { - JIMethodCall jiMethodCall = new JIMethodCall(null); - jiMethodCall.args = new ArrayList<>(); - jiMethodCall.varArgExist = false; - jiMethodCall.jClassName = typeOwnerClass; - jiMethodCall.jMethodVMSig = PASS_STRAND; - jiMethodCall.name = GRACEFUL_EXIT_METHOD_NAME; - jiMethodCall.invocationType = INVOKESTATIC; - jiMethodCall.thenBB = nextBB; - jiMethodCall.isInternal = true; - return jiMethodCall; - } - private BIRNode.BIRBasicBlock addTestExecuteInvocationWithGracefulExitCall(BIRNode.BIRFunction func, PackageID modId, BIROperand retVar, List args, List - calleeAnnotAttachments, - String typeOwnerClass) { + calleeAnnotAttachments) { BIRNode.BIRBasicBlock lastBB = func.basicBlocks.getLast(); BIRNode.BIRBasicBlock nextBB = addAndGetNextBasicBlock(func); if (JvmCodeGenUtil.isBuiltInPackage(modId)) { @@ -590,9 +564,7 @@ private BIRNode.BIRBasicBlock addTestExecuteInvocationWithGracefulExitCall(BIRNo } lastBB.terminator = new BIRTerminator.Call(null, InstructionKind.CALL, false, modId, new Name(TEST_EXECUTE_METHOD), args, retVar, nextBB, calleeAnnotAttachments, Collections.emptySet()); - BIRNode.BIRBasicBlock finalBB = addAndGetNextBasicBlock(func); - nextBB.terminator = getExitMethodCall(finalBB, typeOwnerClass); - return finalBB; + return nextBB; } private BIRNode.BIRBasicBlock addCheckedInvocationWithArgs(BIRNode.BIRFunction func, PackageID modId, @@ -647,18 +619,6 @@ public int incrementAndGetNextId() { return nextId++; } - public void generateGracefulExitMethod(ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_STATIC, GRACEFUL_EXIT_METHOD_NAME, PASS_STRAND, null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "scheduler", GET_SCHEDULER); - mv.visitFieldInsn(GETFIELD, SCHEDULER, "runtime", GET_BAL_RUNTIME); - mv.visitMethodInsn(INVOKEVIRTUAL, BAL_RUNTIME, GRACEFUL_EXIT_METHOD_NAME, "()V", false); - mv.visitInsn(RETURN); - JvmCodeGenUtil.visitMaxStackForMethod(mv, GRACEFUL_EXIT_METHOD_NAME, SCHEDULER); - mv.visitEnd(); - } - public void generateGetTestExecutionState(ClassWriter cw, String className) { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, GET_TEST_EXECUTION_STATE, "()J", null, null); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MainMethodGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MainMethodGen.java index 2d3dcb7dd346..d8cf82449d94 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MainMethodGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MainMethodGen.java @@ -180,8 +180,8 @@ public void generateMainMethod(BIRNode.BIRFunction userMainFunc, ClassWriter cw, generateJavaCompatibilityCheck(mv); generateBallerinaRuntimeInformation(mv); invokeConfigInit(mv, pkg.packageID); - // start all listeners and TRAP signal handler - startListenersAndSignalHandler(mv, serviceEPAvailable); + // TRAP signal handler + genStartTrapSignalHandler(mv); genRuntimeAndGetScheduler(mv, initClass, runtimeVarIndex, schedulerVarIndex); // register a shutdown hook to call package stop() method. @@ -193,17 +193,16 @@ public void generateMainMethod(BIRNode.BIRFunction userMainFunc, ClassWriter cw, // handle calling init and start during module initialization. generateSetModuleInitialedAndStarted(mv, runtimeVarIndex); generateExecuteFunctionCall(initClass, mv, userMainFunc, isTestable, schedulerVarIndex, futureVarIndex); - - if (hasInitFunction && !isTestable) { - setListenerFound(mv, serviceEPAvailable, runtimeVarIndex); - } - stopListeners(mv, serviceEPAvailable); - if (!serviceEPAvailable && !isTestable) { - JvmCodeGenUtil.generateExitRuntime(mv); - } - + handleFutureValue(mv, initClass, isTestable, futureVarIndex); if (isTestable) { generateModuleStopCall(initClass, mv, runtimeVarIndex); + } else { + if (hasInitFunction) { + setListenerFound(mv, serviceEPAvailable, runtimeVarIndex); + } + if (!serviceEPAvailable) { + JvmCodeGenUtil.generateExitRuntime(mv); + } } mv.visitLabel(tryCatchEnd); mv.visitInsn(RETURN); @@ -244,11 +243,6 @@ private void generateExecuteFunctionCall(String initClass, MethodVisitor mv, BIR genSubmitToScheduler(initClass, mv, userMainFunc, isTestable, futureVarIndex); } - private void stopListeners(MethodVisitor mv, boolean isServiceEPAvailable) { - mv.visitLdcInsn(isServiceEPAvailable); - mv.visitMethodInsn(INVOKESTATIC , LAUNCH_UTILS, "stopListeners", "(Z)V", false); - } - private void generateModuleStopCall(String initClass, MethodVisitor mv, int runtimeVarIndex) { mv.visitVarInsn(ALOAD, runtimeVarIndex); mv.visitMethodInsn(INVOKESTATIC, initClass, CURRENT_MODULE_STOP_METHOD, CURRENT_MODULE_STOP, false); @@ -306,9 +300,8 @@ private String getJavaVersion() { return Objects.requireNonNullElse(javaVersion, ""); } - private void startListenersAndSignalHandler(MethodVisitor mv, boolean isServiceEPAvailable) { - mv.visitLdcInsn(isServiceEPAvailable); - mv.visitMethodInsn(INVOKESTATIC, LAUNCH_UTILS, "startListenersAndSignalHandler", "(Z)V", false); + private void genStartTrapSignalHandler(MethodVisitor mv) { + mv.visitMethodInsn(INVOKESTATIC, LAUNCH_UTILS, "startTrapSignalHandler", VOID_METHOD_DESC, false); } private void genShutdownHook(MethodVisitor mv, String initClass, int runtimeVarIndex) { @@ -334,12 +327,13 @@ private void genRuntimeAndGetScheduler(MethodVisitor mv, String initClass, int r } private void setListenerFound(MethodVisitor mv, boolean serviceEPAvailable, int runtimeVarIndex) { - // need to set immortal=true and start the scheduler again + mv.visitVarInsn(ALOAD, runtimeVarIndex); if (serviceEPAvailable) { - mv.visitVarInsn(ALOAD, runtimeVarIndex); mv.visitInsn(ICONST_1); - mv.visitMethodInsn(INVOKEVIRTUAL , BAL_RUNTIME, WAIT_ON_LISTENERS_METHOD_NAME, "(Z)V", false); + } else { + mv.visitInsn(ICONST_0); } + mv.visitMethodInsn(INVOKEVIRTUAL , BAL_RUNTIME, WAIT_ON_LISTENERS_METHOD_NAME, "(Z)V", false); } private void loadCLIArgsForMain(MethodVisitor mv, List params, @@ -480,7 +474,6 @@ private void genSubmitToScheduler(String initClass, MethodVisitor mv, BIRNode.BI } mv.visitVarInsn(ASTORE, futureVarIndex); setDaemonStrand(mv, futureVarIndex); - handleFutureValue(mv, initClass, isTestable, futureVarIndex); } private void setDaemonStrand(MethodVisitor mv, int futureVarIndex) { @@ -489,9 +482,9 @@ private void setDaemonStrand(MethodVisitor mv, int futureVarIndex) { mv.visitFieldInsn(PUTSTATIC, SCHEDULER, DAEMON_STRAND_NAME, GET_STRAND); } - private void handleFutureValue(MethodVisitor mv, String initClass, boolean isTestFunction, int futureVarIndex) { + private void handleFutureValue(MethodVisitor mv, String initClass, boolean isTestable, int futureVarIndex) { mv.visitVarInsn(ALOAD, futureVarIndex); - if (isTestFunction) { + if (isTestable) { mv.visitMethodInsn(INVOKESTATIC, RUNTIME_UTILS, HANDLE_FUTURE_AND_RETURN_IS_PANIC_METHOD, HANDLE_FUTURE_AND_RETURN_IS_PANIC, false); Label ifLabel = new Label(); diff --git a/settings.gradle b/settings.gradle index e458b9bd1064..a43421552387 100644 --- a/settings.gradle +++ b/settings.gradle @@ -48,7 +48,6 @@ include(':jballerina-unit-test') include(':jballerina-semtype-test') include(':jballerina-benchmark-test') include(':ballerina-compiler-plugin-test') -//include(':ballerina-cli-utils') include(':ballerina-cli') include(':diagram-util') include(':syntax-api-calls-gen') @@ -84,14 +83,8 @@ include(':ballerina') include(':jballerina') include(':jballerina-tools') include(':nballerina-tools') -include(':test-launch-listener-01') -include(':test-launch-listener-02') -include(':test-launch-listener-03') -include(':test-launch-listener-04') include(':jballerina-integration-test') include(':central-client') -// include(':composer-integration-test') -// include(':ballerina-tools-integration-test') include(':testerina:testerina-runtime') include(':testerina:report-tools') include(':testerina-integration-test') @@ -248,16 +241,8 @@ project(':composer-library').projectDir = file('composer') project(':jballerina').projectDir = file('distribution/zip/jballerina') project(':jballerina-tools').projectDir = file('distribution/zip/jballerina-tools') project(':nballerina-tools').projectDir = file('distribution/zip/nballerina-tools') -project(':test-launch-listener-01').projectDir = file('tests/launch-listener-test-util-libs/test-launch-listener-01') -project(':test-launch-listener-02').projectDir = file('tests/launch-listener-test-util-libs/test-launch-listener-02') -project(':test-launch-listener-03').projectDir = file('tests/launch-listener-test-util-libs/test-launch-listener-03') -project(':test-launch-listener-04').projectDir = file('tests/launch-listener-test-util-libs/test-launch-listener-04') project(':jballerina-integration-test').projectDir = file('tests/jballerina-integration-test') project(':language-server-integration-tests').projectDir = file('tests/language-server-integration-tests') -// project(':composer-integration-test').projectDir = file('tests/composer-integration-test') -// project(':ballerina-tools-integration-test').projectDir = file('tests/ballerina-tools-integration-test') -//project(':ballerina-stringutils').projectDir = file('stdlib/stringutils') -//project(':ballerina-libs').projectDir = file('distribution/libs') project(':testerina:testerina-runtime').projectDir = file('misc/testerina/modules/testerina-runtime') project(':testerina:report-tools').projectDir = file('misc/testerina/modules/report-tools') project(':testerina-integration-test').projectDir = file('tests/testerina-integration-test') diff --git a/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/BRunUtil.java b/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/BRunUtil.java index 1a1688d7cec0..172108644ee0 100644 --- a/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/BRunUtil.java +++ b/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/BRunUtil.java @@ -32,7 +32,6 @@ import io.ballerina.runtime.internal.launch.LaunchUtils; import io.ballerina.runtime.internal.scheduling.Scheduler; import io.ballerina.runtime.internal.scheduling.Strand; -import io.ballerina.runtime.internal.util.RuntimeUtils; import io.ballerina.runtime.internal.values.ArrayValue; import io.ballerina.runtime.internal.values.BmpStringValue; import io.ballerina.runtime.internal.values.DecimalValue; @@ -192,7 +191,7 @@ private static Object invoke(CompileResult compileResult, BIRNode.BIRFunction fu final FutureValue future = runtime.scheduler.startNonIsolatedWorker(func, null, PredefinedTypes.TYPE_ANY, "test", new StrandMetadata(ANON_ORG, DOT, DEFAULT_MAJOR_VERSION.value, functionName), args); - return RuntimeUtils.getFutureValue(future); + return future.get(); } catch (ClassNotFoundException | NoSuchMethodException e) { throw new RuntimeException("Error while invoking function '" + functionName + "'", e); } catch (BError e) { @@ -352,8 +351,8 @@ public static void runInit(CompileResult compileResult) throws ClassNotFoundExce configurationDetails.paths, configurationDetails.configContent}); FutureValue future = runOnSchedule(initClazz, "$moduleInit", runtime); Scheduler.daemonStrand = future.strand; - RuntimeUtils.getFutureValue(future); - RuntimeUtils.getFutureValue(runOnSchedule(initClazz, "$moduleStart", runtime)); + future.get(); + runOnSchedule(initClazz, "$moduleStart", runtime).get(); } private static void callConfigInit(Class initClazz, Class[] paramTypes, Object[] args) { diff --git a/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/agent/BallerinaServerAgent.java b/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/agent/BallerinaServerAgent.java index 027f0dbc454a..2551055e84be 100644 --- a/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/agent/BallerinaServerAgent.java +++ b/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/agent/BallerinaServerAgent.java @@ -19,9 +19,11 @@ import javassist.ClassPool; import javassist.CtClass; +import javassist.CtConstructor; import javassist.CtField; -import javassist.CtMethod; import org.ballerinalang.test.agent.server.WebServer; +import org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants; +import org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures; import java.io.PrintStream; import java.lang.instrument.ClassFileTransformer; @@ -37,7 +39,7 @@ * @since 0.982.0 */ public class BallerinaServerAgent { - private static PrintStream outStream = System.err; + private static final PrintStream outStream = System.err; /** * Argument name for exist status. @@ -102,19 +104,17 @@ public static void premain(String args, Instrumentation instrumentation) { if (agentPort == -1) { throw new RuntimeException("Invalid agent port - " + agentPort); } - ClassFileTransformer transformer = new ClassFileTransformer() { @Override public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { - if ("io/ballerina/runtime/internal/scheduling/Scheduler".equals(className)) { + if (JvmConstants.BAL_RUNTIME.equals(className)) { try { ClassPool cp = ClassPool.getDefault(); - CtClass cc = cp.get("io.ballerina.runtime.internal.scheduling.Scheduler"); + CtClass cc = cp.get("io.ballerina.runtime.internal.BalRuntime"); cc.addField(CtField.make("boolean agentStarted;", cc)); - - CtMethod m = cc.getDeclaredMethod("start"); - m.insertBefore("if (!agentStarted) {" + + CtConstructor constructor = cc.getConstructor(JvmSignatures.INIT_RUNTIME); + constructor.insertBeforeBody("if (!agentStarted) {" + "org.ballerinalang.test.agent.BallerinaServerAgent.startAgentServer();" + "agentStarted = true;" + " }"); diff --git a/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/context/AgentManager.java b/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/context/AgentManager.java index feb532c0cc2f..89c5f68c347b 100644 --- a/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/context/AgentManager.java +++ b/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/context/AgentManager.java @@ -27,7 +27,7 @@ public class AgentManager { private static final String BALLERINA_AGENT_PORT_START_VALUE = "ballerina.agent.port.start.value"; - private static final String DEFAULT_AGENT_PORT_START = "7000"; + private static final String DEFAULT_AGENT_PORT_START = "7100"; private static AgentManager agentManager; diff --git a/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/context/BMainInstance.java b/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/context/BMainInstance.java index 67efc5739851..711fa526e29e 100644 --- a/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/context/BMainInstance.java +++ b/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/context/BMainInstance.java @@ -172,9 +172,6 @@ public void runMain(String sourceRoot, String packagePath, public void runMain(String sourceRoot, String packagePath, String[] flags, String[] args, LogLeecher[] leechers) throws BallerinaTestException { runMain(sourceRoot, packagePath, flags, args, null, new String[]{}, leechers); - for (LogLeecher leecher : leechers) { - leecher.waitForText(TIMEOUT); - } } @Override diff --git a/tests/jballerina-integration-test/build.gradle b/tests/jballerina-integration-test/build.gradle index c09ff3b5d20c..90f2d8f5fbeb 100644 --- a/tests/jballerina-integration-test/build.gradle +++ b/tests/jballerina-integration-test/build.gradle @@ -72,11 +72,6 @@ dependencies { testUtils project(path: ':ballerina-test-utils', configuration: 'shadow') jballerinaTools project(path: ':jballerina-tools', configuration: 'zip') - launchListenerTestUtils project(':test-launch-listener-01') - launchListenerTestUtils project(':test-launch-listener-02') - launchListenerTestUtils project(':test-launch-listener-03') - launchListenerTestUtils project(':test-launch-listener-04') - testLibs 'org.hsqldb:hsqldb:2.7.1' distributionBala project(path: ':ballerina-io-internal', configuration: 'distributionBala') @@ -121,12 +116,5 @@ tasks.register('copyToLib', Copy) { } test.dependsOn(copyToLib) - -tasks.register('createLaunchListenerUtilsLib', Copy) { - from configurations.launchListenerTestUtils - into "${buildDir}/launch-listener/libs" -} - -tasks.test.dependsOn(createLaunchListenerUtilsLib) tasks.compileTestJava.dependsOn(":ballerina-io-internal:copyInteropImports") generateMetadataFileForMavenJavaPublication.dependsOn(copyToLib) diff --git a/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/listener/LaunchListenerTestCase.java b/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/listener/LaunchListenerTestCase.java deleted file mode 100644 index e593f421d9b4..000000000000 --- a/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/listener/LaunchListenerTestCase.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.ballerinalang.test.listener; - -import org.ballerinalang.test.BaseTest; -import org.ballerinalang.test.context.BMainInstance; -import org.ballerinalang.test.context.BalServer; -import org.ballerinalang.test.context.BallerinaTestException; -import org.ballerinalang.test.context.LogLeecher; -import org.ballerinalang.test.util.BFileUtil; -import org.testng.annotations.Test; - -import java.nio.file.Path; -import java.nio.file.Paths; - -/** - * Test cases to verify launch listener init and shutdown failures. - * - * @since 1.3.0 - */ -public class LaunchListenerTestCase extends BaseTest { - - @Test(enabled = false, description = "Case1: Test launch listener for init failure with runtime exception") - public void testInitRuntimeFailure() throws BallerinaTestException { - - verify("test-launch-listener-01.jar", "hello_world_service.bal", "Oh no, something really went wrong."); - } - - @Test(enabled = false, description = "Case2: Test launch listener for init failure with error value") - public void testInitError() throws BallerinaTestException { - - verify("test-launch-listener-02.jar", "hello_world_service.bal", "error: An error in beforeRunProgram method"); - } - - @Test(enabled = false, description = "Case3: Test launch listener for shutdown failure with runtime exception") - public void testShutdownRuntimeFailure() throws BallerinaTestException { - - verify("test-launch-listener-03.jar", "hello_world.bal", "Oh no, something really went wrong."); - } - - @Test(enabled = false, description = "Case4: Test launch listener for shutdown failure with error value") - public void testShutdownError() throws BallerinaTestException { - - verify("test-launch-listener-04.jar", "hello_world.bal", "error: An error in afterRunProgram method"); - } - - private void verify(String jarName, String balFileName, String serverResponse) throws BallerinaTestException { - - Path launchListenerJarFilePath = Paths.get("build", "launch-listener", "libs", jarName); - - assert launchListenerJarFilePath.toFile().exists(); - - BalServer balServer = new BalServer(); - BMainInstance balClient = new BMainInstance(balServer); - - Path serverBreLib = Paths.get(balServer.getServerHome(), "bre", "lib", jarName); - BFileUtil.copy(launchListenerJarFilePath, serverBreLib); - - Path balFilepath = Paths.get("src", "test", "resources", "listener"); - String balFile = Paths.get(balFilepath.toString(), balFileName).toFile().getAbsolutePath(); - - LogLeecher clientLeecher = new LogLeecher(serverResponse, LogLeecher.LeecherType.ERROR); - - balClient.runMain("run", new String[]{balFile}, null, new String[]{}, - new LogLeecher[]{clientLeecher}, balFilepath.toString()); - clientLeecher.waitForText(20000); - } -} diff --git a/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java b/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java index 216155e31095..e403fb92734a 100644 --- a/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java +++ b/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java @@ -19,104 +19,170 @@ package org.ballerinalang.test.packaging; import org.ballerinalang.test.BaseTest; -import org.ballerinalang.test.context.BMainInstance; +import org.ballerinalang.test.context.BServerInstance; import org.ballerinalang.test.context.BallerinaTestException; import org.ballerinalang.test.context.LogLeecher; -import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import java.nio.file.Path; import java.nio.file.Paths; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; /** * Tests order of execution of listener methods. */ public class ModuleExecutionFlowTests extends BaseTest { - - private BMainInstance bMainInstance; - private final String sourceRoot = Paths.get("src", "test", "resources", "packaging").toAbsolutePath().toString(); - - @BeforeClass() - public void setUp() throws BallerinaTestException { - bMainInstance = new BMainInstance(balServer); - } + public static final int TIMEOUT = 1000; @Test public void testModuleExecutionOrder() throws BallerinaTestException { - runAndAssert("proj1"); + Path projectPath = Paths.get("src", "test", "resources", "packaging", "proj1"); + runAndAssert(projectPath); } @Test public void testModuleMainExecutionOrder() throws BallerinaTestException { - runAndAssert("proj6"); + Path projectPath = Paths.get("src", "test", "resources", "packaging", "proj6"); + runAndAssert(projectPath); } @Test public void testImportModuleHasListener() throws BallerinaTestException { - bMainInstance.runMain(this.sourceRoot, "proj2", null, null, new LogLeecher[]{new LogLeecher("Stopped module A", - LogLeecher.LeecherType.ERROR)}); + Path projectPath = Paths.get("src", "test", "resources", "packaging", "proj2"); + BServerInstance serverInstance = new BServerInstance(balServer); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); + LogLeecher errLeecherA = new LogLeecher("Stopped module A", LogLeecher.LeecherType.ERROR); + serverInstance.addErrorLogLeecher(errLeecherA); + serverInstance.shutdownServer(); + errLeecherA.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } - private void runAndAssert(String packagePath) throws BallerinaTestException { + private void runAndAssert(Path projectPath) throws BallerinaTestException { + BServerInstance serverInstance = new BServerInstance(balServer); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); LogLeecher errLeecherA = new LogLeecher("Stopped module A", LogLeecher.LeecherType.ERROR); LogLeecher errLeecherB = new LogLeecher("Stopped module B", LogLeecher.LeecherType.ERROR); LogLeecher errLeecherC = new LogLeecher("Stopped module C", LogLeecher.LeecherType.ERROR); - LogLeecher[] leechers = new LogLeecher[]{errLeecherA, errLeecherB, errLeecherC}; - bMainInstance.runMain(this.sourceRoot, packagePath, leechers); + serverInstance.addErrorLogLeecher(errLeecherA); + serverInstance.addErrorLogLeecher(errLeecherB); + serverInstance.addErrorLogLeecher(errLeecherC); + serverInstance.shutdownServer(); + errLeecherA.waitForText(TIMEOUT); + errLeecherB.waitForText(TIMEOUT); + errLeecherC.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test(description = "Test 'init' is called only once for each module at runtime") - public void testModuleDependencyChainForInit() throws BallerinaTestException { + public void testModuleDependencyChainForInit() throws BallerinaTestException, InterruptedException { + Path projectPath = Paths.get("src", "test", "resources", "packaging", "module_invocation_project"); + BServerInstance serverInstance = new BServerInstance(balServer); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), "module_invocation_project", null, null, + null); LogLeecher errLeecherCurrent = new LogLeecher("Stopped module current", LogLeecher.LeecherType.ERROR); LogLeecher errLeecherDep1 = new LogLeecher("Stopped module second dependent", LogLeecher.LeecherType.ERROR); LogLeecher errLeecherDep2 = new LogLeecher("Stopped module first dependent", LogLeecher.LeecherType.ERROR); LogLeecher errLeecherBasic = new LogLeecher("Stopped module basic", LogLeecher.LeecherType.ERROR); - LogLeecher[] leechers = new LogLeecher[]{errLeecherCurrent, errLeecherDep1, errLeecherDep2, errLeecherBasic}; - bMainInstance.runMain(this.sourceRoot, "module_invocation_project", null, null, leechers); + serverInstance.addErrorLogLeecher(errLeecherCurrent); + serverInstance.addErrorLogLeecher(errLeecherDep1); + serverInstance.addErrorLogLeecher(errLeecherDep2); + serverInstance.addErrorLogLeecher(errLeecherBasic); + CountDownLatch latch = new CountDownLatch(1); + latch.await(TIMEOUT, TimeUnit.MILLISECONDS); + serverInstance.shutdownServer(); + errLeecherCurrent.waitForText(TIMEOUT); + errLeecherDep1.waitForText(TIMEOUT); + errLeecherDep2.waitForText(TIMEOUT); + errLeecherBasic.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test public void testDynamicListenerExecution() throws BallerinaTestException { - runAssertDynamicListener("dynamic_listener_execution"); + Path projectPath = Paths.get("src", "test", "resources", "packaging", "dynamic_listener_execution"); + runAssertDynamicListener(projectPath); } @Test public void testDynamicListenerDeregister() throws BallerinaTestException { - runAssertDynamicListener("dynamic_listener_deregister"); + Path projectPath = Paths.get("src", "test", "resources", "packaging", "dynamic_listener_deregister"); + runAssertDynamicListener(projectPath); } @Test public void testMultipleDynamicListenersWithAsyncCall() throws BallerinaTestException { - runAssertDynamicListener("dynamic_listener_async_call_test_project"); + Path projectPath = Paths.get("src", "test", "resources", "packaging", + "dynamic_listener_async_call_test_project"); + runAssertDynamicListener(projectPath); } - private void runAssertDynamicListener(String packagePath) throws BallerinaTestException { + private void runAssertDynamicListener(Path projectPath) throws BallerinaTestException { + BServerInstance serverInstance = new BServerInstance(balServer); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); LogLeecher errLeecherA = new LogLeecher("Stopped module A", LogLeecher.LeecherType.ERROR); - LogLeecher[] leechers = new LogLeecher[]{errLeecherA}; - bMainInstance.runMain(this.sourceRoot, packagePath, null, null, leechers); + serverInstance.addErrorLogLeecher(errLeecherA); + serverInstance.shutdownServer(); + errLeecherA.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test public void testStopHandlerExecution() throws BallerinaTestException { + Path projectPath = Paths.get("src", "test", "resources", "packaging", "stop_handler_execution"); + BServerInstance serverInstance = new BServerInstance(balServer); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); LogLeecher infoLeecher1 = new LogLeecher("Stopped stopHandlerFunc3"); LogLeecher infoLeecher2 = new LogLeecher("Stopped stopHandlerFunc2"); LogLeecher infoLeecher3 = new LogLeecher("Stopped stopHandlerFunc1"); LogLeecher infoLeecher4 = new LogLeecher("Stopped inlineStopHandler"); - LogLeecher[] leechers = new LogLeecher[]{infoLeecher1, infoLeecher2, infoLeecher3, infoLeecher4}; - bMainInstance.runMain(this.sourceRoot, "stop_handler_execution", null, null, leechers); + serverInstance.addLogLeecher(infoLeecher4); + serverInstance.addLogLeecher(infoLeecher1); + serverInstance.addLogLeecher(infoLeecher2); + serverInstance.addLogLeecher(infoLeecher3); + serverInstance.shutdownServer(); + infoLeecher1.waitForText(TIMEOUT); + infoLeecher2.waitForText(TIMEOUT); + infoLeecher3.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test public void testModuleShutdownRegisteredWithStopHandlers() throws BallerinaTestException { + Path projectPath = Paths.get("src", "test", "resources", "packaging", "module_shutdown_order_project"); + + BServerInstance serverInstance = new BServerInstance(balServer); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); LogLeecher logLeecherA = new LogLeecher("Stopped current module"); LogLeecher logLeecherB = new LogLeecher("Stopped moduleB"); LogLeecher logLeecherC = new LogLeecher("Stopped moduleA"); LogLeecher logLeecherD = new LogLeecher("Stopped moduleC"); - LogLeecher[] leechers = new LogLeecher[]{logLeecherA, logLeecherB, logLeecherC, logLeecherD}; - bMainInstance.runMain(this.sourceRoot, "module_shutdown_order_project", null, null, leechers); + serverInstance.addLogLeecher(logLeecherA); + serverInstance.addLogLeecher(logLeecherB); + serverInstance.addLogLeecher(logLeecherC); + serverInstance.addLogLeecher(logLeecherD); + serverInstance.shutdownServer(); + logLeecherA.waitForText(TIMEOUT); + logLeecherB.waitForText(TIMEOUT); + logLeecherC.waitForText(TIMEOUT); + logLeecherD.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test public void testStopHandlerExecutionOrder() throws BallerinaTestException { + Path projectPath = Paths.get("src", "test", "resources", "packaging", + "stop_handler_execution_order_test"); + + BServerInstance serverInstance = new BServerInstance(balServer); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); LogLeecher logLeecherA = new LogLeecher("StopHandlerFunc3 in current module"); LogLeecher logLeecherB = new LogLeecher("stopHandlerFunc3 in moduleA"); LogLeecher logLeecherC = new LogLeecher("StopHandlerFunc5 in current module"); @@ -125,13 +191,34 @@ public void testStopHandlerExecutionOrder() throws BallerinaTestException { LogLeecher logLeecherF = new LogLeecher("Stopped current module"); LogLeecher logLeecherG = new LogLeecher("stopHandlerFunc1 in moduleA"); LogLeecher logLeecherH = new LogLeecher("Stopped moduleB", LogLeecher.LeecherType.ERROR); - LogLeecher[] leechers = new LogLeecher[]{logLeecherA, logLeecherB, logLeecherC, logLeecherD, logLeecherE, - logLeecherF, logLeecherG, logLeecherH}; - bMainInstance.runMain(this.sourceRoot, "stop_handler_execution_order_test", null, null, leechers); + serverInstance.addLogLeecher(logLeecherA); + serverInstance.addLogLeecher(logLeecherB); + serverInstance.addLogLeecher(logLeecherC); + serverInstance.addLogLeecher(logLeecherD); + serverInstance.addLogLeecher(logLeecherE); + serverInstance.addLogLeecher(logLeecherF); + serverInstance.addLogLeecher(logLeecherG); + serverInstance.addErrorLogLeecher(logLeecherH); + serverInstance.shutdownServer(); + logLeecherA.waitForText(TIMEOUT); + logLeecherB.waitForText(TIMEOUT); + logLeecherC.waitForText(TIMEOUT); + logLeecherD.waitForText(TIMEOUT); + logLeecherE.waitForText(TIMEOUT); + logLeecherF.waitForText(TIMEOUT); + logLeecherG.waitForText(TIMEOUT); + logLeecherH.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test public void testListenerStopHandlerShutdownOrderWithErrorReturn() throws BallerinaTestException { + Path projectPath = Paths.get("src", "test", "resources", "packaging", + "listener_stophandler_shutdown_order_project"); + + BServerInstance serverInstance = new BServerInstance(balServer); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); LogLeecher logLeecherA = new LogLeecher("Calling stop for static listener"); LogLeecher logLeecherB = new LogLeecher("error: error during the gracefulStop call of static listener", LogLeecher.LeecherType.ERROR); @@ -142,78 +229,178 @@ public void testListenerStopHandlerShutdownOrderWithErrorReturn() throws Balleri LogLeecher logLeecherF = new LogLeecher("error: error during the gracefulStop call of StopHandler2", LogLeecher.LeecherType.ERROR); LogLeecher logLeecherI = new LogLeecher("stopHandler1 called"); - LogLeecher[] leechers = new LogLeecher[]{logLeecherA, logLeecherB, logLeecherC, logLeecherD, logLeecherE, - logLeecherF, logLeecherI}; - bMainInstance.runMain(this.sourceRoot, "listener_stophandler_shutdown_order_project", null, null, leechers); + serverInstance.addLogLeecher(logLeecherA); + serverInstance.addErrorLogLeecher(logLeecherB); + serverInstance.addLogLeecher(logLeecherC); + serverInstance.addErrorLogLeecher(logLeecherD); + serverInstance.addLogLeecher(logLeecherE); + serverInstance.addErrorLogLeecher(logLeecherF); + serverInstance.addLogLeecher(logLeecherI); + serverInstance.shutdownServer(); + logLeecherA.waitForText(TIMEOUT); + logLeecherB.waitForText(TIMEOUT); + logLeecherC.waitForText(TIMEOUT); + logLeecherD.waitForText(TIMEOUT); + logLeecherE.waitForText(TIMEOUT); + logLeecherF.waitForText(TIMEOUT); + logLeecherI.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test public void testListenerStopHandlerAsyncCall() throws BallerinaTestException { + Path projectPath = Paths.get("src", "test", "resources", "packaging", + "listener_stophandler_async_call_test"); + + BServerInstance serverInstance = new BServerInstance(balServer); LogLeecher logLeecherA = new LogLeecher("calling gracefulStop for dynamic listener of current module"); LogLeecher logLeecherB = new LogLeecher("calling StopHandler2 of current module"); LogLeecher logLeecherC = new LogLeecher("calling StopHandler1 of current module"); LogLeecher logLeecherD = new LogLeecher("calling StopHandler2 of moduleA"); LogLeecher logLeecherE = new LogLeecher("calling StopHandler1 of moduleA"); - LogLeecher[] leechers = new LogLeecher[]{logLeecherA, logLeecherB, logLeecherC, logLeecherD, logLeecherE}; - bMainInstance.runMain(this.sourceRoot, "listener_stophandler_async_call_test", null, null, leechers); + serverInstance.addLogLeecher(logLeecherA); + serverInstance.addLogLeecher(logLeecherB); + serverInstance.addLogLeecher(logLeecherC); + serverInstance.addLogLeecher(logLeecherD); + serverInstance.addLogLeecher(logLeecherE); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); + serverInstance.shutdownServer(); + logLeecherA.waitForText(TIMEOUT); + logLeecherB.waitForText(TIMEOUT); + logLeecherC.waitForText(TIMEOUT); + logLeecherD.waitForText(TIMEOUT); + logLeecherE.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test public void testStopHandlerAsyncCall() throws BallerinaTestException { + Path projectPath = Paths.get("src", "test", "resources", "packaging", + "stop_handler_async_call_test"); + BServerInstance serverInstance = new BServerInstance(balServer); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); LogLeecher infoLeecher1 = new LogLeecher("Stopped stopHandlerFunc3"); LogLeecher infoLeecher2 = new LogLeecher("Stopped stopHandlerFunc4"); LogLeecher infoLeecher3 = new LogLeecher("Stopped stopHandlerFunc2"); LogLeecher infoLeecher4 = new LogLeecher("Stopped stopHandlerFunc1"); - LogLeecher[] leechers = new LogLeecher[]{infoLeecher1, infoLeecher2, infoLeecher3, infoLeecher4}; - bMainInstance.runMain(this.sourceRoot, "stop_handler_async_call_test", null, null, leechers); + serverInstance.addLogLeecher(infoLeecher1); + serverInstance.addLogLeecher(infoLeecher2); + serverInstance.addLogLeecher(infoLeecher3); + serverInstance.addLogLeecher(infoLeecher4); + serverInstance.shutdownServer(); + infoLeecher1.waitForText(TIMEOUT); + infoLeecher2.waitForText(TIMEOUT); + infoLeecher3.waitForText(TIMEOUT); + infoLeecher4.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test public void testModuleExecuteFunctionOrder() throws BallerinaTestException { + Path projectPath = Paths.get("src", "test", "resources", "packaging", "module_execute_invocation_project"); + BServerInstance serverInstance = new BServerInstance(balServer); LogLeecher listenerInitLeecher = new LogLeecher("Calling init for 'current'", LogLeecher.LeecherType.INFO); LogLeecher moduleInitLeecher = new LogLeecher("Initializing module 'current'", LogLeecher.LeecherType.INFO); LogLeecher mainLeecher = new LogLeecher("main function invoked for 'current' module", LogLeecher.LeecherType.INFO); LogLeecher listenerStartLeecher = new LogLeecher("Calling start for 'current'", LogLeecher.LeecherType.INFO); - LogLeecher[] leechers = new LogLeecher[]{listenerInitLeecher, moduleInitLeecher, mainLeecher, - listenerStartLeecher}; - bMainInstance.runMain(this.sourceRoot, "module_execute_invocation_project", null, null, leechers); + + serverInstance.addLogLeecher(listenerInitLeecher); + serverInstance.addLogLeecher(moduleInitLeecher); + serverInstance.addLogLeecher(mainLeecher); + serverInstance.addLogLeecher(listenerStartLeecher); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); + serverInstance.shutdownServer(); + + listenerInitLeecher.waitForText(TIMEOUT); + moduleInitLeecher.waitForText(TIMEOUT); + mainLeecher.waitForText(TIMEOUT); + listenerStartLeecher.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test public void testModuleInitWithBusyWorkerAndListener() throws BallerinaTestException { + Path projectPath = Paths.get("src", "test", "resources", "packaging", "module_init_worker_project"); + BServerInstance serverInstance = new BServerInstance(balServer); LogLeecher listenerInitLeecher = new LogLeecher("Calling init for 'current'", LogLeecher.LeecherType.INFO); LogLeecher moduleInitLeecher = new LogLeecher("Initializing module 'current'", LogLeecher.LeecherType.INFO); - LogLeecher mainLeecher = new LogLeecher("main function invoked for 'current' module", - LogLeecher.LeecherType.INFO); + LogLeecher mainLeecher = + new LogLeecher("main function invoked for 'current' module", LogLeecher.LeecherType.INFO); LogLeecher listenerStartLeecher = new LogLeecher("Calling start for 'current'", LogLeecher.LeecherType.INFO); LogLeecher workerLeecher = new LogLeecher("executing worker 'w1'", LogLeecher.LeecherType.INFO); - LogLeecher[] leechers = new LogLeecher[]{listenerInitLeecher, moduleInitLeecher, mainLeecher, - listenerStartLeecher, workerLeecher}; - bMainInstance.runMain(this.sourceRoot, "module_init_worker_project", null, null, leechers); + + serverInstance.addLogLeecher(listenerInitLeecher); + serverInstance.addLogLeecher(moduleInitLeecher); + serverInstance.addLogLeecher(mainLeecher); + serverInstance.addLogLeecher(listenerStartLeecher); + serverInstance.addLogLeecher(workerLeecher); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); + serverInstance.shutdownServer(); + + listenerInitLeecher.waitForText(TIMEOUT); + moduleInitLeecher.waitForText(TIMEOUT); + mainLeecher.waitForText(TIMEOUT); + listenerStartLeecher.waitForText(TIMEOUT); + workerLeecher.waitForText(TIMEOUT); + + serverInstance.removeAllLeechers(); } @Test public void testModuleInitWithBusyWorkerAndDynamicListener() throws BallerinaTestException { + Path projectPath = + Paths.get("src", "test", "resources", "packaging", "module_init_worker_dynamic_listener_project"); + BServerInstance serverInstance = new BServerInstance(balServer); LogLeecher moduleInitLeecher = new LogLeecher("Initializing module 'current'", LogLeecher.LeecherType.INFO); - LogLeecher mainLeecher = new LogLeecher("main function invoked for 'current' module", - LogLeecher.LeecherType.INFO); + LogLeecher mainLeecher = + new LogLeecher("main function invoked for 'current' module", LogLeecher.LeecherType.INFO); LogLeecher workerLeecher = new LogLeecher("executing worker 'w1'", LogLeecher.LeecherType.INFO); LogLeecher listenerInitLeecher = new LogLeecher("Calling init for 'dynamic'", LogLeecher.LeecherType.INFO); LogLeecher listenerStartLeecher = new LogLeecher("Calling start for 'dynamic'", LogLeecher.LeecherType.INFO); LogLeecher listenerStopLeecher = new LogLeecher("Calling stop for 'dynamic'", LogLeecher.LeecherType.INFO); - LogLeecher[] leechers = new LogLeecher[]{moduleInitLeecher, mainLeecher, workerLeecher, listenerInitLeecher, - listenerStartLeecher, listenerStopLeecher}; - bMainInstance.runMain(this.sourceRoot, "module_init_worker_dynamic_listener_project", null, null, leechers); + + serverInstance.addLogLeecher(moduleInitLeecher); + serverInstance.addLogLeecher(mainLeecher); + serverInstance.addLogLeecher(workerLeecher); + serverInstance.addLogLeecher(listenerInitLeecher); + serverInstance.addLogLeecher(listenerStartLeecher); + serverInstance.addLogLeecher(listenerStopLeecher); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); + serverInstance.shutdownServer(); + moduleInitLeecher.waitForText(TIMEOUT); + mainLeecher.waitForText(TIMEOUT); + workerLeecher.waitForText(TIMEOUT); + listenerInitLeecher.waitForText(TIMEOUT); + listenerStartLeecher.waitForText(TIMEOUT); + listenerStopLeecher.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } @Test public void testModuleInitWithBusyWorkerTerminating() throws BallerinaTestException { + Path projectPath = + Paths.get("src", "test", "resources", "packaging", "module_init_worker_no_listener_project"); + BServerInstance serverInstance = new BServerInstance(balServer); LogLeecher moduleInitLeecher = new LogLeecher("Initializing module 'current'", LogLeecher.LeecherType.INFO); - LogLeecher mainLeecher = new LogLeecher("main function invoked for 'current' module", - LogLeecher.LeecherType.INFO); + LogLeecher mainLeecher = + new LogLeecher("main function invoked for 'current' module", LogLeecher.LeecherType.INFO); LogLeecher workerLeecher = new LogLeecher("executing worker 'w1'", LogLeecher.LeecherType.INFO); - LogLeecher[] leechers = new LogLeecher[]{moduleInitLeecher, mainLeecher, workerLeecher}; - bMainInstance.runMain(this.sourceRoot, "module_init_worker_no_listener_project", null, null, leechers); + + serverInstance.addLogLeecher(moduleInitLeecher); + serverInstance.addLogLeecher(mainLeecher); + serverInstance.addLogLeecher(workerLeecher); + serverInstance.startServer(projectPath.toAbsolutePath().toString(), projectPath.getFileName().toString(), null, + null, null); + serverInstance.shutdownServer(); + moduleInitLeecher.waitForText(TIMEOUT); + mainLeecher.waitForText(TIMEOUT); + workerLeecher.waitForText(TIMEOUT); + serverInstance.removeAllLeechers(); } } diff --git a/tests/jballerina-integration-test/src/test/resources/packaging/module_init_worker_no_listener_project/main.bal b/tests/jballerina-integration-test/src/test/resources/packaging/module_init_worker_no_listener_project/main.bal index 660a8de12ce3..2ba27e7eeac2 100644 --- a/tests/jballerina-integration-test/src/test/resources/packaging/module_init_worker_no_listener_project/main.bal +++ b/tests/jballerina-integration-test/src/test/resources/packaging/module_init_worker_no_listener_project/main.bal @@ -14,34 +14,36 @@ // specific language governing permissions and limitations // under the License. +import ballerina/lang.runtime; import ballerina/jballerina.java; -isolated function init() { +function init() { print("Initializing module 'current'"); worker w1 { print("executing worker 'w1'"); while true { - + } } } -public isolated function main() { +public function main() { print("main function invoked for 'current' module"); + runtime:sleep(1000); } -isolated function print(string value) { +function print(string value) { handle strValue = java:fromString(value); handle stdout1 = stdout(); printInternal(stdout1, strValue); } -isolated function stdout() returns handle = @java:FieldGet { +function stdout() returns handle = @java:FieldGet { name: "out", 'class: "java/lang/System" } external; -isolated function printInternal(handle receiver, handle strValue) = @java:Method { +function printInternal(handle receiver, handle strValue) = @java:Method { name: "println", 'class: "java/io/PrintStream", paramTypes: ["java.lang.String"] diff --git a/tests/jballerina-integration-test/src/test/resources/testng.xml b/tests/jballerina-integration-test/src/test/resources/testng.xml index d4d68cf436a8..323d222cd163 100644 --- a/tests/jballerina-integration-test/src/test/resources/testng.xml +++ b/tests/jballerina-integration-test/src/test/resources/testng.xml @@ -47,11 +47,6 @@ - - - - - diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-01/build.gradle b/tests/launch-listener-test-util-libs/test-launch-listener-01/build.gradle deleted file mode 100644 index fb06a4d0e0d4..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-01/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -apply from: "$rootDir/gradle/javaProject.gradle" - -dependencies { - implementation project(':ballerina-runtime') -} - -jar { - archiveFileName = 'test-launch-listener-01.jar' -} - -description = 'Ballerina - Test - Launch Listener - 01' - -ext.moduleName = 'ballerina.test.listener' diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-01/src/main/java/module-info.java b/tests/launch-listener-test-util-libs/test-launch-listener-01/src/main/java/module-info.java deleted file mode 100644 index 8ad02894183a..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-01/src/main/java/module-info.java +++ /dev/null @@ -1,3 +0,0 @@ -module ballerina.test.listener { - requires io.ballerina.runtime; -} diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-01/src/main/java/org/ballerina/test/listener/TestLaunchListener.java b/tests/launch-listener-test-util-libs/test-launch-listener-01/src/main/java/org/ballerina/test/listener/TestLaunchListener.java deleted file mode 100644 index 45d5549c25d9..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-01/src/main/java/org/ballerina/test/listener/TestLaunchListener.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.ballerina.test.listener; - -import io.ballerina.runtime.api.launch.LaunchListener; -/** - * Test Launcher Listener used for testing purpose. - * - * @since 1.3.0 - */ -public class TestLaunchListener implements LaunchListener { - - @Override - public void beforeRunProgram(boolean service) { - throw new RuntimeException("A runtime failure in beforeRunProgram method"); - } - - @Override - public void afterRunProgram(boolean service) { - // Do nothing. - } -} diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-01/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener b/tests/launch-listener-test-util-libs/test-launch-listener-01/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener deleted file mode 100644 index 396269e3618c..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-01/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener +++ /dev/null @@ -1 +0,0 @@ -org.ballerina.test.listener.TestLaunchListener diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-02/build.gradle b/tests/launch-listener-test-util-libs/test-launch-listener-02/build.gradle deleted file mode 100644 index e51f707e7827..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-02/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -apply from: "$rootDir/gradle/javaProject.gradle" - -dependencies { - implementation project(':ballerina-runtime') -} - -jar { - archiveFileName = 'test-launch-listener-02.jar' -} - -description = 'Ballerina - Test - Launch Listener - 02' - -ext.moduleName = 'ballerina.test.listener' diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-02/src/main/java/module-info.java b/tests/launch-listener-test-util-libs/test-launch-listener-02/src/main/java/module-info.java deleted file mode 100644 index 8ad02894183a..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-02/src/main/java/module-info.java +++ /dev/null @@ -1,3 +0,0 @@ -module ballerina.test.listener { - requires io.ballerina.runtime; -} diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-02/src/main/java/org/ballerina/test/listener/TestLaunchListener.java b/tests/launch-listener-test-util-libs/test-launch-listener-02/src/main/java/org/ballerina/test/listener/TestLaunchListener.java deleted file mode 100644 index 6c39e33aced7..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-02/src/main/java/org/ballerina/test/listener/TestLaunchListener.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.ballerina.test.listener; - -import io.ballerina.runtime.api.creators.ErrorCreator; -import io.ballerina.runtime.api.launch.LaunchListener; -import io.ballerina.runtime.api.utils.StringUtils; - -/** - * Test Launcher Listener used for testing purpose. - * - * @since 1.3.0 - */ -public class TestLaunchListener implements LaunchListener { - - @Override - public void beforeRunProgram(boolean service) { - throw ErrorCreator.createError(StringUtils.fromString("An error in beforeRunProgram method")); - } - - @Override - public void afterRunProgram(boolean service) { - // Do nothing - } -} diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-02/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener b/tests/launch-listener-test-util-libs/test-launch-listener-02/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener deleted file mode 100644 index 396269e3618c..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-02/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener +++ /dev/null @@ -1 +0,0 @@ -org.ballerina.test.listener.TestLaunchListener diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-03/build.gradle b/tests/launch-listener-test-util-libs/test-launch-listener-03/build.gradle deleted file mode 100644 index c487fe4dd0a1..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-03/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -apply from: "$rootDir/gradle/javaProject.gradle" - -dependencies { - implementation project(':ballerina-runtime') -} - -jar { - archiveFileName = 'test-launch-listener-03.jar' -} - -description = 'Ballerina - Test - Launch Listener - 03' - -ext.moduleName = 'ballerina.test.listener' diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-03/src/main/java/module-info.java b/tests/launch-listener-test-util-libs/test-launch-listener-03/src/main/java/module-info.java deleted file mode 100644 index 8ad02894183a..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-03/src/main/java/module-info.java +++ /dev/null @@ -1,3 +0,0 @@ -module ballerina.test.listener { - requires io.ballerina.runtime; -} diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-03/src/main/java/org/ballerina/test/listener/TestLaunchListener.java b/tests/launch-listener-test-util-libs/test-launch-listener-03/src/main/java/org/ballerina/test/listener/TestLaunchListener.java deleted file mode 100644 index 2bde18b9d145..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-03/src/main/java/org/ballerina/test/listener/TestLaunchListener.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.ballerina.test.listener; - -import io.ballerina.runtime.api.launch.LaunchListener; -/** - * Test Launcher Listener used for testing purpose. - * - * @since 1.3.0 - */ -public class TestLaunchListener implements LaunchListener { - - - @Override - public void beforeRunProgram(boolean service) { - // Do nothing. - } - - @Override - public void afterRunProgram(boolean service) { - throw new RuntimeException("A runtime failure in afterRunProgram method"); - } -} diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-03/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener b/tests/launch-listener-test-util-libs/test-launch-listener-03/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener deleted file mode 100644 index 396269e3618c..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-03/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener +++ /dev/null @@ -1 +0,0 @@ -org.ballerina.test.listener.TestLaunchListener diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-04/build.gradle b/tests/launch-listener-test-util-libs/test-launch-listener-04/build.gradle deleted file mode 100644 index b9faf32637a8..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-04/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -apply from: "$rootDir/gradle/javaProject.gradle" - -dependencies { - implementation project(':ballerina-runtime') -} - -jar { - archiveFileName = 'test-launch-listener-04.jar' -} - -description = 'Ballerina - Test - Launch Listener - 04' - -ext.moduleName = 'ballerina.test.listener' diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-04/src/main/java/module-info.java b/tests/launch-listener-test-util-libs/test-launch-listener-04/src/main/java/module-info.java deleted file mode 100644 index 8ad02894183a..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-04/src/main/java/module-info.java +++ /dev/null @@ -1,3 +0,0 @@ -module ballerina.test.listener { - requires io.ballerina.runtime; -} diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-04/src/main/java/org/ballerina/test/listener/TestLaunchListener.java b/tests/launch-listener-test-util-libs/test-launch-listener-04/src/main/java/org/ballerina/test/listener/TestLaunchListener.java deleted file mode 100644 index f6548c0c42aa..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-04/src/main/java/org/ballerina/test/listener/TestLaunchListener.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.ballerina.test.listener; - -import io.ballerina.runtime.api.creators.ErrorCreator; -import io.ballerina.runtime.api.launch.LaunchListener; -import io.ballerina.runtime.api.utils.StringUtils; -/** - * Test Launcher Listener used for testing purpose. - * - * @since 1.3.0 - */ -public class TestLaunchListener implements LaunchListener { - - - @Override - public void beforeRunProgram(boolean service) { - // Do nothing - } - - @Override - public void afterRunProgram(boolean service) { - throw ErrorCreator.createError(StringUtils.fromString("An error in afterRunProgram method")); - } -} diff --git a/tests/launch-listener-test-util-libs/test-launch-listener-04/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener b/tests/launch-listener-test-util-libs/test-launch-listener-04/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener deleted file mode 100644 index 396269e3618c..000000000000 --- a/tests/launch-listener-test-util-libs/test-launch-listener-04/src/main/resources/META-INF/services/io.ballerina.runtime.api.launch.LaunchListener +++ /dev/null @@ -1 +0,0 @@ -org.ballerina.test.listener.TestLaunchListener