Skip to content

Commit

Permalink
Refactor testerina core ballerina module
Browse files Browse the repository at this point in the history
  • Loading branch information
gayaldassanayake committed May 21, 2024
1 parent ca6fd4b commit 27c521a
Show file tree
Hide file tree
Showing 17 changed files with 222 additions and 235 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ function testAssertFalse() {
@test:Config {}
function testAssertFail() {
if (true) {
if true {
return;
}
test:assertFail(msg = "AssertFailed");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@
// specific language governing permissions and limitations
// under the License.

enum SerialExecutionReason {
NONE_ISOLATED_TEST_FUNCTION = "non-isolated test function",
NONE_ISOLATED_DATA_PROVIDER_FUNCTION = "non-isolated data-provider function",
UNSAFE_TEST_PARAMETERS = "unsafe test parameters",
NON_ISOLATED_BEFORE_FUNCTION = "non-isolated before function",
NON_ISOLATED_AFTER_FUNCTION = "non-isolated after function",
NON_ISOLATED_BEFORE_GROUPS_FUNCTION = "non-isolated before-groups function",
NON_ISOLATED_AFTER_GROUPS_FUNCTION = "non-isolated after-groups function",
NON_ISOLATED_BEFORE_EACH_FUNCTION = "non-isolated before-each function",
NON_ISOLATED_AFTER_EACH_FUNCTION = "non-isolated after-each function"
}

type AnnotationProcessor function (string name, function f) returns boolean;

AnnotationProcessor[] annotationProcessors = [
Expand All @@ -26,21 +38,16 @@ AnnotationProcessor[] annotationProcessors = [
processConfigAnnotation
];

# Register a test function to run. This function is intended for internal use only.
#
# + name - test name
# + f - test function
public function registerTest(string name, function f) {
boolean annotationProcessed = false;
foreach AnnotationProcessor annotationProcessor in annotationProcessors {
if (annotationProcessor(name.trim(), f)) {
annotationProcessed = true;
if annotationProcessor(name.trim(), f) {
break;
}
}

//TODO: Enable dynamic registration upon approval
// Process the register functions under the test factory method.
// Currently the dynamic registration does not support groups filtration.
// if !annotationProcessed && filterGroups.length() == 0 {
// testRegistry.addFunction(name = name, executableFunction = f);
// }
}

function processConfigAnnotation(string name, function f) returns boolean {
Expand Down Expand Up @@ -72,31 +79,39 @@ function processConfigAnnotation(string name, function f) returns boolean {

// Register the reason for serial execution.
if !isTestFunctionIsolated {
reasonForSerialExecution.push("non-isolated test function");
reasonForSerialExecution.push(NONE_ISOLATED_TEST_FUNCTION);
}
if !isDataProviderIsolated {
reasonForSerialExecution.push("non-isolated data-provider function");
reasonForSerialExecution.push(NONE_ISOLATED_DATA_PROVIDER_FUNCTION);
}
if !isTestFunctionParamSafe {
reasonForSerialExecution.push("unsafe test parameters");
reasonForSerialExecution.push(UNSAFE_TEST_PARAMETERS);
}

// If the test function is not parallelizable, then print the reason for serial execution.
if !isSatisfiedParallelizableConditions && !(config?.serialExecution == () ? false : true)
&& executionManager.isParallelExecutionEnabled() {
if !isSatisfiedParallelizableConditions && config.serialExecution == ()
&& executionManager.isParallelExecutionEnabled() {
println(string `WARNING: Test function '${name}' cannot be parallelized, reason: ${string:'join(", ",
...reasonForSerialExecution)}`);
...reasonForSerialExecution)}`);
}

boolean enabled = config.enable && (filterGroups.length() == 0 ? true : hasGroup(config.groups, filterGroups))
&& (filterDisableGroups.length() == 0 ? true : !hasGroup(config.groups, filterDisableGroups))
&& hasTest(name);
// if enable field is true, and groups to filter exist, and groups to disable exist and test exists, then enable
boolean enabled = config.enable
&& (filterGroups.length() == 0 || hasGroup(config.groups, filterGroups))
&& (filterDisableGroups.length() == 0 || !hasGroup(config.groups, filterDisableGroups))
&& hasTest(name);
config.groups.forEach('group => groupStatusRegistry.incrementTotalTest('group, enabled));
dataDrivenTestParams[name] = params;

// if the serial execution field is set, or if parallel execution is disabled, or if not parallelizable, then
// set the serial execution to true.
boolean serialExecution = config?.serialExecution != ()
|| !executionManager.isParallelExecutionEnabled()
|| !isSatisfiedParallelizableConditions;

testRegistry.addFunction(name = name, executableFunction = f, before = config.before,
after = config.after, groups = config.groups.cloneReadOnly(), diagnostics = diagnostics,
dependsOn = config.dependsOn.cloneReadOnly(), serialExecution = ((config?.serialExecution != ())
|| !isSatisfiedParallelizableConditions || !executionManager.isParallelExecutionEnabled()),
dependsOn = config.dependsOn.cloneReadOnly(), serialExecution = serialExecution,
config = config.cloneReadOnly());
executionManager.createTestFunctionMetaData(functionName = name, dependsOnCount = config.dependsOn.length(),
enabled = enabled);
Expand All @@ -110,14 +125,14 @@ function isBeforeAfterFuncSetIsolated(TestConfig config, string[] reasonForSeria
if before !is () {
if before !is isolated function () returns any|error {
isBeforeAfterFunctionSetIsolated = false;
reasonForSerialExecution.push("non-isolated before function");
reasonForSerialExecution.push(NON_ISOLATED_BEFORE_FUNCTION);
}
}
(function () returns any|error)? after = config.after;
if after !is () {
if after !is isolated function () returns any|error {
isBeforeAfterFunctionSetIsolated = false;
reasonForSerialExecution.push("non-isolated after function");
reasonForSerialExecution.push(NON_ISOLATED_AFTER_FUNCTION);
}
}
foreach string 'group in config.groups {
Expand All @@ -126,7 +141,7 @@ function isBeforeAfterFuncSetIsolated(TestConfig config, string[] reasonForSeria
foreach TestFunction beforeGroupFunction in beforeGroupFunctions {
if beforeGroupFunction.executableFunction !is isolated function {
isBeforeAfterFunctionSetIsolated = false;
reasonForSerialExecution.push("non-isolated before-groups function");
reasonForSerialExecution.push(NON_ISOLATED_BEFORE_GROUPS_FUNCTION);
}
}
}
Expand All @@ -135,7 +150,7 @@ function isBeforeAfterFuncSetIsolated(TestConfig config, string[] reasonForSeria
foreach TestFunction afterGroupFunction in afterGroupFunctions {
if afterGroupFunction.executableFunction !is isolated function {
isBeforeAfterFunctionSetIsolated = false;
reasonForSerialExecution.push("non-isolated after-groups function");
reasonForSerialExecution.push(NON_ISOLATED_AFTER_GROUPS_FUNCTION);
}
}
}
Expand All @@ -144,14 +159,14 @@ function isBeforeAfterFuncSetIsolated(TestConfig config, string[] reasonForSeria
foreach TestFunction beforeEachFunction in beforeEachFunctions {
if beforeEachFunction.executableFunction !is isolated function {
isBeforeAfterFunctionSetIsolated = false;
reasonForSerialExecution.push("non-isolated before-each function");
reasonForSerialExecution.push(NON_ISOLATED_BEFORE_EACH_FUNCTION);
}
}
TestFunction[] afterEachFunctions = afterEachRegistry.getFunctions();
foreach TestFunction afterEachFunction in afterEachFunctions {
if afterEachFunction.executableFunction !is isolated function {
isBeforeAfterFunctionSetIsolated = false;
reasonForSerialExecution.push("non-isolated after-each function");
reasonForSerialExecution.push(NON_ISOLATED_AFTER_EACH_FUNCTION);
}
}
return isBeforeAfterFunctionSetIsolated;
Expand Down Expand Up @@ -223,26 +238,22 @@ function hasGroup(string[] groups, string[] filter) returns boolean {
}

isolated function hasTest(string name) returns boolean {
if testOptions.getHasFilteredTests() {
string testName = name;
int? testIndex = testOptions.getFilterTestIndex(testName);
if testIndex == () {
foreach string filter in testOptions.getFilterTests() {
if filter.includes(WILDCARD) {
boolean|error wildCardMatch = matchWildcard(testName, filter);
return (wildCardMatch is boolean && wildCardMatch && matchModuleName(filter));
}
if !testOptions.getHasFilteredTests() {
return true;
}
int? testIndex = testOptions.getFilterTestIndex(name);
if testIndex == () {
foreach string filter in testOptions.getFilterTests() {
if filter.includes(WILDCARD) {
return matchWildcard(name, filter) == true && matchModuleName(filter);
}
return false;
} else if matchModuleName(testName) {
return true;
}
return false;
}
return true;
return matchModuleName(name);
}

isolated function matchModuleName(string testName) returns boolean {
string? filterModule = testOptions.getFilterTestModule(testName);
return filterModule == () ? true : filterModule == getFullModuleName();
return filterModule == () || filterModule == getFullModuleName();
}
Loading

0 comments on commit 27c521a

Please sign in to comment.