Skip to content

Commit

Permalink
Solved issues with Node tests related to OpenSSL incompatibilities an…
Browse files Browse the repository at this point in the history
…d Rust.
  • Loading branch information
viferga committed Sep 26, 2023
1 parent 1aeaede commit 9be9348
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 49 deletions.
61 changes: 61 additions & 0 deletions source/ports/node_port/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -142,23 +142,84 @@ include(TestEnvironmentVariables)

# Enable cobol test if it is built
if(OPTION_BUILD_LOADERS_COB)
set(COBOL_DEPENDENCY cob_loader)
set(TESTS_ENVIRONMENT_VARIABLES_COB "OPTION_BUILD_LOADERS_COB=1")
endif()

# Enable c test if it is built
if(OPTION_BUILD_LOADERS_C)
set(C_DEPENDENCY c_loader)
set(TESTS_ENVIRONMENT_VARIABLES_C "OPTION_BUILD_LOADERS_C=1")
endif()

# Enable rust test if it is built
if(OPTION_BUILD_LOADERS_RS)
set(RS_DEPENDENCY rs_loader)
set(TESTS_ENVIRONMENT_VARIABLES_RS "OPTION_BUILD_LOADERS_RS=1")
endif()

# Disable OpenSSL related tests if versions are incompatible
set(NodeJS_EXECUTABLE_ONLY ON)

find_package(NodeJS)
find_package(Python COMPONENTS Interpreter)

set(TESTS_ENVIRONMENT_VARIABLES_OPENSSL "OPTION_NODEJS_PYTHON_OPENSSL_MISMATCH=1")

if(NodeJS_FOUND AND Python_Interpreter_FOUND)
execute_process(
COMMAND ${NodeJS_EXECUTABLE} -e "console.log(process.versions.openssl)"
OUTPUT_VARIABLE NODEJS_OPENSSL_VERSION
)
execute_process(
COMMAND ${Python_EXECUTABLE} -c "import ssl; print(ssl.OPENSSL_VERSION.split()[1])"
OUTPUT_VARIABLE PYTHON_OPENSSL_VERSION
)

if(NOT "${NODEJS_OPENSSL_VERSION}" STREQUAL "" AND NOT "${PYTHON_OPENSSL_VERSION}" STREQUAL "")
string(REGEX MATCHALL "-.*$|[0-9]+" NODEJS_OPENSSL_PARTIAL_VERSION_LIST "${NODEJS_OPENSSL_VERSION}")
list(GET NODEJS_OPENSSL_PARTIAL_VERSION_LIST 0 NODEJS_OPENSSL_VERSION_MAJOR)
list(GET NODEJS_OPENSSL_PARTIAL_VERSION_LIST 1 NODEJS_OPENSSL_VERSION_MINOR)
list(GET NODEJS_OPENSSL_PARTIAL_VERSION_LIST 2 NODEJS_OPENSSL_VERSION_PATCH)

string(REGEX MATCHALL "-.*$|[0-9]+" PYTHON_OPENSSL_PARTIAL_VERSION_LIST "${PYTHON_OPENSSL_VERSION}")
list(GET PYTHON_OPENSSL_PARTIAL_VERSION_LIST 0 PYTHON_OPENSSL_VERSION_MAJOR)
list(GET PYTHON_OPENSSL_PARTIAL_VERSION_LIST 1 PYTHON_OPENSSL_VERSION_MINOR)
list(GET PYTHON_OPENSSL_PARTIAL_VERSION_LIST 2 PYTHON_OPENSSL_VERSION_PATCH)

# If major and minor version match, then enable the OpenSSL related tests (https://github.com/metacall/core/issues/31#issuecomment-1736039845)
if(NODEJS_OPENSSL_VERSION_MAJOR VERSION_EQUAL PYTHON_OPENSSL_VERSION_MAJOR
AND NODEJS_OPENSSL_VERSION_MINOR VERSION_EQUAL PYTHON_OPENSSL_VERSION_MINOR)
set(TESTS_ENVIRONMENT_VARIABLES_OPENSSL)
endif()
endif()
endif()

# TODO: When trying multiple versions of OpenSSL in the same project,
# Rust Loader generates a segmentation fault trying to free an unallocated block of memory,
# disable it for now until we can diagnose it
if(OPTION_BUILD_LOADERS_RS AND NOT TESTS_ENVIRONMENT_VARIABLES_OPENSSL)
set(RS_DEPENDENCY)
set(TESTS_ENVIRONMENT_VARIABLES_RS)
endif()

# Add dependencies and optional dependencies
add_dependencies(${target}
node_loader
mock_loader
py_loader
rb_loader
ts_loader
${COBOL_DEPENDENCY}
${C_DEPENDENCY}
${RS_DEPENDENCY}
)

test_environment_variables(${target}
""
${TESTS_ENVIRONMENT_VARIABLES}
${TESTS_ENVIRONMENT_VARIABLES_COB}
${TESTS_ENVIRONMENT_VARIABLES_C}
${TESTS_ENVIRONMENT_VARIABLES_RS}
${TESTS_ENVIRONMENT_VARIABLES_OPENSSL}
)
76 changes: 39 additions & 37 deletions source/ports/node_port/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,43 +202,45 @@ describe('metacall', () => {
assert.notStrictEqual(py_encode_basestring_ascii, undefined);
assert.strictEqual(py_encode_basestring_ascii('asd'), '"asd"');
});
it('require (py submodule dependency)', () => {
// Require the 'core' submodule from 'rsa' Python package
const { encrypt_int } = require('py:rsa.core');

// In NodeJS, the numbers are of type 'Number', this gets converted to TYPE_DOUBLE,
// but this function requires values of type 'int' in Python, which is TYPE_LONG.
// So basically in python3-rsa at version 4.0-4, this function has assertions
// for requiring type int as parameters, but the parameters are not annotated with types
// so the casting is impossible to be done, thus it throws an exception. In newer versions
// this has been solved and they added type hints, so it does not throw.
//
// Old version:
// def encrypt_int(message, ekey, n):
// """Encrypts a message using encryption key 'ekey', working modulo n"""
//
// assert_int(message, 'message')
// assert_int(ekey, 'ekey')
// assert_int(n, 'n')
// ...
//
// New version:
// def encrypt_int(message: int, ekey: int, n: int) -> int:
// """Encrypts a message using encryption key 'ekey', working modulo n"""
//
// assert_int(message, 'message')
// assert_int(ekey, 'ekey')
// assert_int(n, 'n')
// ...
//
// Without the type annotations metacall has no way to convert from NodeJS Number to Python int.
// So both paths of try and catch are valid for this tests, there is not a bug in MetaCall.
try {
assert.strictEqual(encrypt_int(3, 2, 5), 4);
} catch (e) {
assert.strictEqual(e.message, 'message should be an integer, not <class \'float\'>')
}
});
if (!process.env['OPTION_NODEJS_PYTHON_OPENSSL_MISMATCH']) {
it('require (py submodule dependency)', () => {
// Require the 'core' submodule from 'rsa' Python package
const { encrypt_int } = require('py:rsa.core');

// In NodeJS, the numbers are of type 'Number', this gets converted to TYPE_DOUBLE,
// but this function requires values of type 'int' in Python, which is TYPE_LONG.
// So basically in python3-rsa at version 4.0-4, this function has assertions
// for requiring type int as parameters, but the parameters are not annotated with types
// so the casting is impossible to be done, thus it throws an exception. In newer versions
// this has been solved and they added type hints, so it does not throw.
//
// Old version:
// def encrypt_int(message, ekey, n):
// """Encrypts a message using encryption key 'ekey', working modulo n"""
//
// assert_int(message, 'message')
// assert_int(ekey, 'ekey')
// assert_int(n, 'n')
// ...
//
// New version:
// def encrypt_int(message: int, ekey: int, n: int) -> int:
// """Encrypts a message using encryption key 'ekey', working modulo n"""
//
// assert_int(message, 'message')
// assert_int(ekey, 'ekey')
// assert_int(n, 'n')
// ...
//
// Without the type annotations metacall has no way to convert from NodeJS Number to Python int.
// So both paths of try and catch are valid for this tests, there is not a bug in MetaCall.
try {
assert.strictEqual(encrypt_int(3, 2, 5), 4);
} catch (e) {
assert.strictEqual(e.message, 'message should be an integer, not <class \'float\'>')
}
});
}
it('require (rb)', () => {
const cache = require('./cache.rb');
assert.notStrictEqual(cache, undefined);
Expand Down
76 changes: 64 additions & 12 deletions source/tests/metacall_node_port_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,43 +149,95 @@ add_test(NAME ${target}
)

#
# Define dependencies
# Define test labels
#

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

include(TestEnvironmentVariables)

# Enable cobol test if it is built
if(OPTION_BUILD_LOADERS_COB)
set(COBOL_DEPENDENCY cob_loader)
set(TESTS_ENVIRONMENT_VARIABLES_COB "OPTION_BUILD_LOADERS_COB=1")
endif()

# Enable c test if it is built
if(OPTION_BUILD_LOADERS_C)
set(C_DEPENDENCY c_loader)
set(TESTS_ENVIRONMENT_VARIABLES_C "OPTION_BUILD_LOADERS_C=1")
endif()

# Enable rust test if it is built
if(OPTION_BUILD_LOADERS_RS)
set(RS_DEPENDENCY rs_loader)
set(TESTS_ENVIRONMENT_VARIABLES_RS "OPTION_BUILD_LOADERS_RS=1")
endif()

# Disable OpenSSL related tests if versions are incompatible
set(NodeJS_EXECUTABLE_ONLY ON)

find_package(NodeJS)
find_package(Python COMPONENTS Interpreter)

set(TESTS_ENVIRONMENT_VARIABLES_OPENSSL "OPTION_NODEJS_PYTHON_OPENSSL_MISMATCH=1")

if(NodeJS_FOUND AND Python_Interpreter_FOUND)
execute_process(
COMMAND ${NodeJS_EXECUTABLE} -e "console.log(process.versions.openssl)"
OUTPUT_VARIABLE NODEJS_OPENSSL_VERSION
)
execute_process(
COMMAND ${Python_EXECUTABLE} -c "import ssl; print(ssl.OPENSSL_VERSION.split()[1])"
OUTPUT_VARIABLE PYTHON_OPENSSL_VERSION
)

if(NOT "${NODEJS_OPENSSL_VERSION}" STREQUAL "" AND NOT "${PYTHON_OPENSSL_VERSION}" STREQUAL "")
string(REGEX MATCHALL "-.*$|[0-9]+" NODEJS_OPENSSL_PARTIAL_VERSION_LIST "${NODEJS_OPENSSL_VERSION}")
list(GET NODEJS_OPENSSL_PARTIAL_VERSION_LIST 0 NODEJS_OPENSSL_VERSION_MAJOR)
list(GET NODEJS_OPENSSL_PARTIAL_VERSION_LIST 1 NODEJS_OPENSSL_VERSION_MINOR)
list(GET NODEJS_OPENSSL_PARTIAL_VERSION_LIST 2 NODEJS_OPENSSL_VERSION_PATCH)

string(REGEX MATCHALL "-.*$|[0-9]+" PYTHON_OPENSSL_PARTIAL_VERSION_LIST "${PYTHON_OPENSSL_VERSION}")
list(GET PYTHON_OPENSSL_PARTIAL_VERSION_LIST 0 PYTHON_OPENSSL_VERSION_MAJOR)
list(GET PYTHON_OPENSSL_PARTIAL_VERSION_LIST 1 PYTHON_OPENSSL_VERSION_MINOR)
list(GET PYTHON_OPENSSL_PARTIAL_VERSION_LIST 2 PYTHON_OPENSSL_VERSION_PATCH)

# If major and minor version match, then enable the OpenSSL related tests (https://github.com/metacall/core/issues/31#issuecomment-1736039845)
if(NODEJS_OPENSSL_VERSION_MAJOR VERSION_EQUAL PYTHON_OPENSSL_VERSION_MAJOR
AND NODEJS_OPENSSL_VERSION_MINOR VERSION_EQUAL PYTHON_OPENSSL_VERSION_MINOR)
set(TESTS_ENVIRONMENT_VARIABLES_OPENSSL)
endif()
endif()
endif()

# TODO: When trying multiple versions of OpenSSL in the same project,
# Rust Loader generates a segmentation fault trying to free an unallocated block of memory,
# disable it for now until we can diagnose it
if(OPTION_BUILD_LOADERS_RS AND NOT TESTS_ENVIRONMENT_VARIABLES_OPENSSL)
set(RS_DEPENDENCY)
set(TESTS_ENVIRONMENT_VARIABLES_RS)
endif()

# Add dependencies and optional dependencies
add_dependencies(${target}
node_port
node_loader
mock_loader
py_loader
rb_loader
ts_loader
${COBOL_DEPENDENCY}
${C_DEPENDENCY}
${RS_DEPENDENCY}
)

#
# Define test properties
#

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

include(TestEnvironmentVariables)

test_environment_variables(${target}
""
${TESTS_ENVIRONMENT_VARIABLES}
${TESTS_ENVIRONMENT_VARIABLES_COB}
${TESTS_ENVIRONMENT_VARIABLES_C}
${TESTS_ENVIRONMENT_VARIABLES_RS}
${TESTS_ENVIRONMENT_VARIABLES_OPENSSL}
)

0 comments on commit 9be9348

Please sign in to comment.