Skip to content

Commit

Permalink
Add node intensive async test.
Browse files Browse the repository at this point in the history
  • Loading branch information
viferga committed Jan 30, 2024
1 parent bf91ec6 commit 8302fe1
Show file tree
Hide file tree
Showing 4 changed files with 386 additions and 0 deletions.
1 change: 1 addition & 0 deletions source/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ add_subdirectory(metacall_node_event_loop_signal_test)
add_subdirectory(metacall_node_call_test)
add_subdirectory(metacall_node_inline_test)
add_subdirectory(metacall_node_async_test)
add_subdirectory(metacall_node_async_multiple_test)
add_subdirectory(metacall_node_reentrant_test)
add_subdirectory(metacall_node_port_test)
add_subdirectory(metacall_node_port_await_test)
Expand Down
147 changes: 147 additions & 0 deletions source/tests/metacall_node_async_multiple_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Check if this loader is enabled
if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_NODE OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_NODE)
return()
endif()

#
# Executable name and options
#

# Target name
set(target metacall-node-async-multiple-test)
message(STATUS "Test ${target}")

#
# Compiler warnings
#

include(Warnings)

#
# Compiler security
#

include(SecurityFlags)

#
# Sources
#

set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target}")
set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source")

set(sources
${source_path}/main.cpp
${source_path}/metacall_node_async_multiple_test.cpp
)

# Group source files
set(header_group "Header Files (API)")
set(source_group "Source Files")
source_group_by_path(${include_path} "\\\\.h$|\\\\.hpp$"
${header_group} ${headers})
source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$"
${source_group} ${sources})

#
# Create executable
#

# Build executable
add_executable(${target}
${sources}
)

# Create namespaced alias
add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target})

#
# Project options
#

set_target_properties(${target}
PROPERTIES
${DEFAULT_PROJECT_OPTIONS}
FOLDER "${IDE_FOLDER}"
)

#
# Include directories
#

target_include_directories(${target}
PRIVATE
${DEFAULT_INCLUDE_DIRECTORIES}
${PROJECT_BINARY_DIR}/source/include
)

#
# Libraries
#

target_link_libraries(${target}
PRIVATE
${DEFAULT_LIBRARIES}

GTest

${META_PROJECT_NAME}::metacall
)

#
# Compile definitions
#

target_compile_definitions(${target}
PRIVATE
${DEFAULT_COMPILE_DEFINITIONS}
)

#
# Compile options
#

target_compile_options(${target}
PRIVATE
${DEFAULT_COMPILE_OPTIONS}
)

#
# Linker options
#

target_link_libraries(${target}
PRIVATE
${DEFAULT_LINKER_OPTIONS}
)

#
# Define test
#

add_test(NAME ${target}
COMMAND $<TARGET_FILE:${target}>
)

#
# Define dependencies
#

add_dependencies(${target}
node_loader
)

#
# Define test properties
#

set_property(TEST ${target}
PROPERTY LABELS ${target}
)

include(TestEnvironmentVariables)

test_environment_variables(${target}
""
${TESTS_ENVIRONMENT_VARIABLES}
)
28 changes: 28 additions & 0 deletions source/tests/metacall_node_async_multiple_test/source/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* MetaCall Library by Parra Studios
* A library for providing a foreign function interface calls.
*
* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <[email protected]>
*
* 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.
*
*/

#include <gtest/gtest.h>

int main(int argc, char *argv[])
{
::testing::InitGoogleTest(&argc, argv);

return RUN_ALL_TESTS();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* MetaCall Library by Parra Studios
* A library for providing a foreign function interface calls.
*
* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <[email protected]>
*
* 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.
*
*/

#include <gtest/gtest.h>

#include <metacall/metacall.h>
#include <metacall/metacall_loaders.h>
#include <metacall/metacall_value.h>

#include <atomic>

std::atomic<int> success_callbacks{};

class metacall_node_async_multiple_test : public testing::Test
{
public:
};

TEST_F(metacall_node_async_multiple_test, DefaultConstructor)
{
const size_t iteration_size = 1000;

struct async_context
{
int value;
} ctx = {
234
};

metacall_print_info();

ASSERT_EQ((int)0, (int)metacall_initialize());

/* NodeJS */
#if defined(OPTION_BUILD_LOADERS_NODE)
{
const char buffer[] =
"const util = require('util');\n"
"const delay = ms => new Promise(resolve => setTimeout(resolve, ms))\n"
"async function f(x) {\n"
"\tawait delay(2000);\n"
"\treturn new Promise(r => console.log(`Promise f executed: ${util.inspect(r)} -> ${x}`) || r(x));\n"
"}\n"
"async function g(x) {\n"
"\tawait delay(2000);\n"
"\treturn new Promise((_, r) => console.log(`Promise g executed: ${util.inspect(r)} -> ${x}`) || r(x));\n"
"}\n"
"async function h() {\n"
"\tawait delay(2000);\n"
"\treturn new Promise((resolve) => resolve(34));\n"
"}\n"
"module.exports = { f, g, h };\n";

EXPECT_EQ((int)0, (int)metacall_load_from_memory("node", buffer, sizeof(buffer), NULL));

for (size_t i = 0; i < iteration_size; ++i)
{
void *args[] = {
metacall_value_create_double(10.0)
};

/* Test resolve */
void *future = metacall_await(
"f", args, [](void *result, void *data) -> void * {
EXPECT_NE((void *) NULL, (void *) result);

EXPECT_EQ((enum metacall_value_id) metacall_value_id(result), (enum metacall_value_id) METACALL_DOUBLE);

EXPECT_EQ((double) 10.0, (double) metacall_value_to_double(result));

EXPECT_NE((void *) NULL, (void *) data);

struct async_context * ctx = static_cast<struct async_context *>(data);

EXPECT_EQ((int) 234, (int) ctx->value);

printf("Resolve C Callback\n");

return metacall_value_create_double(15.0); }, [](void *, void *) -> void * {
int this_should_never_be_executed = 0;

EXPECT_EQ((int) 1, (int) this_should_never_be_executed);

printf("Reject C Callback\n");

return NULL; }, static_cast<void *>(&ctx));

EXPECT_NE((void *)NULL, (void *)future);

EXPECT_EQ((enum metacall_value_id)metacall_value_id(future), (enum metacall_value_id)METACALL_FUTURE);

metacall_value_destroy(future);

/* Test reject */
future = metacall_await(
"g", args, [](void *, void *) -> void * {
int this_should_never_be_executed = 0;

EXPECT_EQ((int) 1, (int) this_should_never_be_executed);

printf("Resolve C Callback\n");

return NULL; }, [](void *result, void *data) -> void * {
EXPECT_NE((void *) NULL, (void *) result);

EXPECT_EQ((enum metacall_value_id) metacall_value_id(result), (enum metacall_value_id) METACALL_DOUBLE);

EXPECT_EQ((double) 10.0, (double) metacall_value_to_double(result));

EXPECT_NE((void *) NULL, (void *) data);

struct async_context * ctx = static_cast<struct async_context *>(data);

EXPECT_EQ((int) 234, (int) ctx->value);

printf("Reject C Callback\n");

++success_callbacks;

return metacall_value_create_double(15.0); }, static_cast<void *>(&ctx));

EXPECT_NE((void *)NULL, (void *)future);

EXPECT_EQ((enum metacall_value_id)metacall_value_id(future), (enum metacall_value_id)METACALL_FUTURE);

metacall_value_destroy(future);

metacall_value_destroy(args[0]);

/* Test future */
future = metacall("h");

EXPECT_NE((void *)NULL, (void *)future);

EXPECT_EQ((enum metacall_value_id)metacall_value_id(future), (enum metacall_value_id)METACALL_FUTURE);

void *ret = metacall_await_future(
metacall_value_to_future(future), [](void *result, void *) -> void * {
EXPECT_NE((void *) NULL, (void *) result);

EXPECT_EQ((enum metacall_value_id) metacall_value_id(result), (enum metacall_value_id) METACALL_DOUBLE);

EXPECT_EQ((double) 34.0, (double) metacall_value_to_double(result));

++success_callbacks;

return metacall_value_create_double(155.0); }, [](void *, void *) -> void * {
int this_should_never_be_executed = 0;

EXPECT_EQ((int) 1, (int) this_should_never_be_executed);

return NULL; }, NULL);

metacall_value_destroy(future);

EXPECT_NE((void *)NULL, (void *)ret);

EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_FUTURE);

void *last = metacall_await_future(
metacall_value_to_future(ret), [](void *result, void *) -> void * {
EXPECT_NE((void *) NULL, (void *) result);

EXPECT_EQ((enum metacall_value_id) metacall_value_id(result), (enum metacall_value_id) METACALL_DOUBLE);

EXPECT_EQ((double) 155.0, (double) metacall_value_to_double(result));

++success_callbacks;

return NULL; }, [](void *, void *) -> void * {
int this_should_never_be_executed = 0;

EXPECT_EQ((int) 1, (int) this_should_never_be_executed);

return NULL; }, NULL);

metacall_value_destroy(last);

metacall_value_destroy(ret);
}
}
#endif /* OPTION_BUILD_LOADERS_NODE */

EXPECT_EQ((int)0, (int)metacall_destroy());

/* NodeJS */
#if defined(OPTION_BUILD_LOADERS_NODE)
{
/* Total amount of successful callbacks must be 3 */
EXPECT_EQ((int)success_callbacks, (int)(3 * iteration_size));
}
#endif /* OPTION_BUILD_LOADERS_NODE */
}

0 comments on commit 8302fe1

Please sign in to comment.