mirror of
https://gitee.com/openharmony/arkcompiler_runtime_core
synced 2024-11-23 14:50:51 +00:00
!2713 Set up test env for NARK
Merge pull request !2713 from kurnevichstanislav/setup_nark_tests
This commit is contained in:
commit
7edae685ce
@ -498,6 +498,7 @@ add_subdirectory(lookup_by_name)
|
||||
add_subdirectory(ets_test_suite)
|
||||
add_subdirectory(runtime)
|
||||
add_subdirectory(napi)
|
||||
add_subdirectory(nark)
|
||||
if(NOT (PANDA_ENABLE_ADDRESS_SANITIZER OR PANDA_ENABLE_THREAD_SANITIZER))
|
||||
add_subdirectory(micro-benchmarks)
|
||||
endif()
|
||||
|
17
static_core/plugins/ets/tests/nark/CMakeLists.txt
Normal file
17
static_core/plugins/ets/tests/nark/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# 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(cmake/nark_tests.cmake)
|
||||
|
||||
add_subdirectory(nark_gtest)
|
||||
add_subdirectory(tests)
|
69
static_core/plugins/ets/tests/nark/cmake/nark_tests.cmake
Normal file
69
static_core/plugins/ets/tests/nark/cmake/nark_tests.cmake
Normal file
@ -0,0 +1,69 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# 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.
|
||||
|
||||
add_custom_target(nark_tests COMMENT "Common target to run NARK ETS tests")
|
||||
|
||||
# Add gtest-based tests to nark_tests target.
|
||||
#
|
||||
# Example usage:
|
||||
# nark_add_gtest(test_name
|
||||
# CPP_SOURCES
|
||||
# tests/unit1_test.cpp
|
||||
# tests/unit2_test.cpp
|
||||
# ETS_SOURCES
|
||||
# tests/unit1_test.sts
|
||||
# LIBRARIES
|
||||
# lib_target1
|
||||
# lib_target2
|
||||
# )
|
||||
function(nark_add_gtest TARGET)
|
||||
cmake_parse_arguments(
|
||||
ARG # give prefix `ARG` to each argument
|
||||
""
|
||||
""
|
||||
"CPP_SOURCES;ETS_SOURCES;LIBRARIES"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
if(NOT DEFINED ARG_CPP_SOURCES)
|
||||
message(FATAL_ERROR "CPP_SOURCES is not defined")
|
||||
endif()
|
||||
|
||||
if(DEFINED ARG_ETS_SOURCES)
|
||||
set(TARGET_GTEST_PACKAGE ${TARGET}_gtest_package)
|
||||
panda_ets_package_gtest(${TARGET_GTEST_PACKAGE}
|
||||
ETS_SOURCES ${ARG_ETS_SOURCES}
|
||||
)
|
||||
set(NARK_GTEST_ABC_PATH "NARK_GTEST_ABC_PATH=${PANDA_BINARY_ROOT}/abc-gtests/${TARGET_GTEST_PACKAGE}.zip")
|
||||
endif()
|
||||
|
||||
# Add launcher <${TARGET}_gtests> target
|
||||
set(NATIVE_TESTS_DIR "${PANDA_BINARY_ROOT}/tests/native")
|
||||
panda_ets_add_gtest(
|
||||
NAME ${TARGET}
|
||||
NO_CORES
|
||||
CUSTOM_PRERUN_ENVIRONMENT
|
||||
"ARK_ETS_STDLIB_PATH=${PANDA_BINARY_ROOT}/plugins/ets/etsstdlib.abc"
|
||||
"${NARK_GTEST_ABC_PATH}"
|
||||
|
||||
SOURCES ${ARG_CPP_SOURCES}
|
||||
LIBRARIES ${ARG_LIBRARIES} nark_gtest arkruntime
|
||||
SANITIZERS ${PANDA_SANITIZERS_LIST}
|
||||
TSAN_EXTRA_OPTIONS ${ARG_TSAN_EXTRA_OPTIONS}
|
||||
DEPS_TARGETS etsstdlib ${TARGET_GTEST_PACKAGE}
|
||||
TEST_RUN_DIR ${NATIVE_TESTS_DIR}
|
||||
OUTPUT_DIRECTORY ${NATIVE_TESTS_DIR}
|
||||
)
|
||||
|
||||
add_dependencies(nark_tests ${TARGET}_gtests)
|
||||
endfunction(nark_add_gtest)
|
20
static_core/plugins/ets/tests/nark/nark_gtest/CMakeLists.txt
Normal file
20
static_core/plugins/ets/tests/nark/nark_gtest/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# 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.
|
||||
|
||||
panda_add_library(nark_gtest INTERFACE)
|
||||
panda_target_link_libraries(nark_gtest INTERFACE gtest)
|
||||
|
||||
panda_target_include_directories(nark_gtest
|
||||
INTERFACE ${PANDA_ETS_PLUGIN_SOURCE}/tests/nark/nark_gtest/
|
||||
INTERFACE ${PANDA_ROOT}
|
||||
)
|
200
static_core/plugins/ets/tests/nark/nark_gtest/nark_gtest.h
Normal file
200
static_core/plugins/ets/tests/nark/nark_gtest/nark_gtest.h
Normal file
@ -0,0 +1,200 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef PANDA_PLUGINS_ETS_NARK_GTEST_H
|
||||
#define PANDA_PLUGINS_ETS_NARK_GTEST_H
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "libpandabase/macros.h"
|
||||
#include "plugins/ets/runtime/napi/ets_napi.h"
|
||||
|
||||
namespace ark::ets::nark::testing {
|
||||
|
||||
class NarkTest : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
const char *stdlib = std::getenv("ARK_ETS_STDLIB_PATH");
|
||||
ASSERT_NE(stdlib, nullptr);
|
||||
|
||||
std::vector<EtsVMOption> optionsVector {{EtsOptionType::ETS_BOOT_FILE, stdlib}};
|
||||
|
||||
abcPath_ = std::getenv("NARK_GTEST_ABC_PATH");
|
||||
if (abcPath_.empty()) {
|
||||
std::cerr << "NARK_GTEST_ABC_PATH must be set" << std::endl;
|
||||
UNREACHABLE();
|
||||
}
|
||||
optionsVector.push_back({EtsOptionType::ETS_BOOT_FILE, abcPath_.c_str()});
|
||||
|
||||
EtsVMInitArgs vmArgs;
|
||||
vmArgs.version = ETS_NAPI_VERSION_1_0;
|
||||
vmArgs.options = optionsVector.data();
|
||||
vmArgs.nOptions = static_cast<ets_int>(optionsVector.size());
|
||||
|
||||
ASSERT_TRUE(ETS_CreateVM(&vm_, &env_, &vmArgs) == ETS_OK) << "Cannot create ETS VM";
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
ASSERT_TRUE(vm_->DestroyEtsVM() == ETS_OK) << "Cannot destroy ETS VM";
|
||||
}
|
||||
|
||||
/// Call function with name `fnName` from ETSGLOBAL
|
||||
template <typename R, typename... Args>
|
||||
R CallEtsFunction(const std::string &fnName, Args &&...args)
|
||||
{
|
||||
std::optional<R> result;
|
||||
|
||||
CallEtsFunctionImpl(&result, fnName, std::forward<Args>(args)...);
|
||||
|
||||
if constexpr (!std::is_same_v<R, void>) {
|
||||
return result.value();
|
||||
}
|
||||
}
|
||||
|
||||
class NativeFunction {
|
||||
public:
|
||||
template <typename FuncT>
|
||||
NativeFunction(const char *functionName, FuncT nativeFunction)
|
||||
: functionName_(functionName), nativeFunction_(reinterpret_cast<void *>(nativeFunction))
|
||||
{
|
||||
}
|
||||
|
||||
const char *GetName() const
|
||||
{
|
||||
return functionName_;
|
||||
}
|
||||
|
||||
void *GetNativePtr() const
|
||||
{
|
||||
return nativeFunction_;
|
||||
}
|
||||
|
||||
private:
|
||||
const char *functionName_ {nullptr};
|
||||
void *nativeFunction_ {nullptr};
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
R CallEtsNativeMethod(const NativeFunction &fn, Args &&...args)
|
||||
{
|
||||
std::optional<R> result;
|
||||
|
||||
CallEtsNativeMethodImpl(&result, fn, std::forward<Args>(args)...);
|
||||
|
||||
if constexpr (!std::is_same_v<R, void>) {
|
||||
return result.value();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static std::string GetFindClassFailureMsg(const std::string &className)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to find class " << className << ".";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static std::string GetFindMethodFailureMsg(const std::string &className, const std::string &methodName)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to find method `" << methodName << "` in " << className << ".";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template <typename R, typename... Args>
|
||||
void CallEtsFunctionImpl(std::optional<R> *result, const std::string &fnName, Args &&...args)
|
||||
{
|
||||
auto className = "ETSGLOBAL";
|
||||
|
||||
ets_class cls = env_->FindClass(className);
|
||||
ASSERT_NE(cls, nullptr) << GetFindClassFailureMsg(className);
|
||||
|
||||
ets_method fn = env_->GetStaticp_method(cls, fnName.data(), nullptr);
|
||||
ASSERT_NE(fn, nullptr) << GetFindMethodFailureMsg(className, fnName);
|
||||
|
||||
*result = DoCallEtsMethod<R>(cls, fn, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename R, typename... Args>
|
||||
void CallEtsNativeMethodImpl(std::optional<R> *result, const NativeFunction &fn, Args &&...args)
|
||||
{
|
||||
auto functionName = fn.GetName();
|
||||
auto className = "ETSGLOBAL";
|
||||
|
||||
auto cls = env_->FindClass(className);
|
||||
ASSERT_NE(cls, nullptr) << GetFindClassFailureMsg(className);
|
||||
|
||||
auto mtd = env_->GetStaticp_method(cls, functionName, nullptr);
|
||||
ASSERT_NE(mtd, nullptr) << GetFindMethodFailureMsg(className, functionName);
|
||||
|
||||
std::array<EtsNativeMethod, 1> method = {{{functionName, nullptr, fn.GetNativePtr()}}};
|
||||
|
||||
ASSERT_EQ(env_->RegisterNatives(cls, method.data(), method.size()), ETS_OK)
|
||||
<< "Failed to register native function " << functionName << ".";
|
||||
|
||||
*result = DoCallEtsMethod<R>(cls, mtd, std::forward<Args>(args)...);
|
||||
|
||||
ASSERT_EQ(env_->UnregisterNatives(cls), ETS_OK)
|
||||
<< "Failed to unregister native function " << functionName << ".";
|
||||
}
|
||||
|
||||
template <typename R, typename... Args>
|
||||
std::optional<R> DoCallEtsMethod(ets_class cls, ets_method mtd, Args &&...args)
|
||||
{
|
||||
// NOLINTBEGIN(cppcoreguidelines-pro-type-vararg)
|
||||
if constexpr (std::is_same_v<R, ets_boolean>) {
|
||||
return env_->CallStaticBooleanMethod(cls, mtd, std::forward<Args>(args)...);
|
||||
} else if constexpr (std::is_same_v<R, ets_byte>) {
|
||||
return env_->CallStaticByteMethod(cls, mtd, std::forward<Args>(args)...);
|
||||
} else if constexpr (std::is_same_v<R, ets_char>) {
|
||||
return env_->CallStaticCharMethod(cls, mtd, std::forward<Args>(args)...);
|
||||
} else if constexpr (std::is_same_v<R, ets_short>) {
|
||||
return env_->CallStaticShortMethod(cls, mtd, std::forward<Args>(args)...);
|
||||
} else if constexpr (std::is_same_v<R, ets_int>) {
|
||||
return env_->CallStaticIntMethod(cls, mtd, std::forward<Args>(args)...);
|
||||
} else if constexpr (std::is_same_v<R, ets_long>) {
|
||||
return env_->CallStaticLongMethod(cls, mtd, std::forward<Args>(args)...);
|
||||
} else if constexpr (std::is_same_v<R, ets_float>) {
|
||||
return env_->CallStaticFloatMethod(cls, mtd, std::forward<Args>(args)...);
|
||||
} else if constexpr (std::is_same_v<R, ets_double>) {
|
||||
return env_->CallStaticDoubleMethod(cls, mtd, std::forward<Args>(args)...);
|
||||
} else if constexpr (std::is_same_v<R, void>) {
|
||||
env_->CallStaticVoidMethod(cls, mtd, args...);
|
||||
return std::nullopt;
|
||||
} else if constexpr (std::is_same_v<R, ets_object> || std::is_same_v<R, ets_array>) {
|
||||
return static_cast<R>(env_->CallStaticObjectMethod(cls, mtd, std::forward<Args>(args)...));
|
||||
} else {
|
||||
enum { INCORRECT_TEMPLATE_TYPE = false };
|
||||
static_assert(INCORRECT_TEMPLATE_TYPE, "Incorrect template type");
|
||||
}
|
||||
// NOLINTEND(cppcoreguidelines-pro-type-vararg)
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
protected:
|
||||
// NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
|
||||
EtsEnv *env_ {nullptr};
|
||||
|
||||
private:
|
||||
std::string abcPath_;
|
||||
EtsVM *vm_ {nullptr};
|
||||
};
|
||||
|
||||
} // namespace ark::ets::nark::testing
|
||||
|
||||
#endif // PANDA_PLUGINS_ETS_NARK_GTEST_H
|
21
static_core/plugins/ets/tests/nark/tests/CMakeLists.txt
Normal file
21
static_core/plugins/ets/tests/nark/tests/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# 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.
|
||||
|
||||
set(EXCLUDED_TEST_PACKAGES)
|
||||
|
||||
SUBDIRLIST(SUBDIRS ${CMAKE_CURRENT_LIST_DIR} EXCLUDED_TEST_PACKAGES)
|
||||
|
||||
foreach(SUBDIR ${SUBDIRS})
|
||||
get_filename_component(TEST_PACKAGE_NAME ${SUBDIR} NAME)
|
||||
add_subdirectory(${SUBDIR})
|
||||
endforeach()
|
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# 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.
|
||||
|
||||
nark_add_gtest(nark_test_example
|
||||
CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/example.cpp
|
||||
ETS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/example.sts
|
||||
)
|
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* 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 "nark_gtest.h"
|
||||
|
||||
namespace ark::ets::nark::testing {
|
||||
|
||||
class ExampleTest : public NarkTest {};
|
||||
|
||||
// NOLINTBEGIN(readability-magic-numbers)
|
||||
TEST_F(ExampleTest, EtsFunctionCall)
|
||||
{
|
||||
ets_double p1 = 5.0;
|
||||
ets_double p2 = 6.0;
|
||||
|
||||
auto res = CallEtsFunction<ets_double>("exampleFunction", p1, p2);
|
||||
ASSERT_EQ(res, p1 + p2);
|
||||
}
|
||||
|
||||
ets_long NativeFuncExample([[maybe_unused]] EtsEnv *env, [[maybe_unused]] ets_class klass, ets_long param1,
|
||||
ets_long param2)
|
||||
{
|
||||
return param1 * param2;
|
||||
}
|
||||
|
||||
TEST_F(ExampleTest, CallNativeFunction)
|
||||
{
|
||||
NativeFunction fn("nativeExampleFunction", NativeFuncExample);
|
||||
|
||||
ets_long p1 = 12;
|
||||
ets_long p2 = -123;
|
||||
|
||||
// Generic call
|
||||
auto res = CallEtsNativeMethod<ets_long>(fn, p1, p2);
|
||||
ASSERT_EQ(res, p1 * p2);
|
||||
}
|
||||
// NOLINTEND(readability-magic-numbers)
|
||||
|
||||
} // namespace ark::ets::nark::testing
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class Test {
|
||||
constructor(a: double, b: double) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public Summ(): double {
|
||||
return this.a + this.b;
|
||||
}
|
||||
|
||||
private a: double;
|
||||
private b: double;
|
||||
};
|
||||
|
||||
function exampleFunction(a: double, b: double): double {
|
||||
let t = new Test(a, b);
|
||||
let res = t.Summ();
|
||||
return res;
|
||||
}
|
||||
|
||||
native function nativeExampleFunction(a: long, b: long): long;
|
Loading…
Reference in New Issue
Block a user