133eb0b6dSopenharmony_ci/*
233eb0b6dSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
333eb0b6dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
433eb0b6dSopenharmony_ci * you may not use this file except in compliance with the License.
533eb0b6dSopenharmony_ci * You may obtain a copy of the License at
633eb0b6dSopenharmony_ci *
733eb0b6dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
833eb0b6dSopenharmony_ci *
933eb0b6dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1033eb0b6dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1133eb0b6dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1233eb0b6dSopenharmony_ci * See the License for the specific language governing permissions and
1333eb0b6dSopenharmony_ci * limitations under the License.
1433eb0b6dSopenharmony_ci */
1533eb0b6dSopenharmony_ci
1633eb0b6dSopenharmony_ci#include "test.h"
1733eb0b6dSopenharmony_ci
1833eb0b6dSopenharmony_ci#include "native_engine/impl/ark/ark_native_engine.h"
1933eb0b6dSopenharmony_ci#include "utils/log.h"
2033eb0b6dSopenharmony_ci
2133eb0b6dSopenharmony_ciusing panda::RuntimeOption;
2233eb0b6dSopenharmony_ci
2333eb0b6dSopenharmony_cistruct ThreadArgs {
2433eb0b6dSopenharmony_ci    NativeEngine* engine = nullptr;
2533eb0b6dSopenharmony_ci    bool initialState = false;
2633eb0b6dSopenharmony_ci    bool suspendState = false;
2733eb0b6dSopenharmony_ci    bool resumeState = false;
2833eb0b6dSopenharmony_ci};
2933eb0b6dSopenharmony_ci
3033eb0b6dSopenharmony_cistatic NativeEngine* g_nativeEngine = nullptr;
3133eb0b6dSopenharmony_ci
3233eb0b6dSopenharmony_ciNativeEngineTest::NativeEngineTest()
3333eb0b6dSopenharmony_ci{
3433eb0b6dSopenharmony_ci    engine_ = g_nativeEngine;
3533eb0b6dSopenharmony_ci}
3633eb0b6dSopenharmony_ci
3733eb0b6dSopenharmony_ciNativeEngineTest::~NativeEngineTest()
3833eb0b6dSopenharmony_ci{}
3933eb0b6dSopenharmony_ci
4033eb0b6dSopenharmony_civoid *NativeEngineTest::Run(void *args)
4133eb0b6dSopenharmony_ci{
4233eb0b6dSopenharmony_ci    ThreadArgs* threadArgs = reinterpret_cast<ThreadArgs*>(args);
4333eb0b6dSopenharmony_ci    NativeEngine* engine = threadArgs->engine;
4433eb0b6dSopenharmony_ci    threadArgs->initialState = engine->IsSuspended();
4533eb0b6dSopenharmony_ci    engine->SuspendVM();
4633eb0b6dSopenharmony_ci    threadArgs->suspendState = engine->IsSuspended();
4733eb0b6dSopenharmony_ci    engine->ResumeVM();
4833eb0b6dSopenharmony_ci    sleep(1);
4933eb0b6dSopenharmony_ci    threadArgs->resumeState = engine->IsSuspended();
5033eb0b6dSopenharmony_ci    return nullptr;
5133eb0b6dSopenharmony_ci}
5233eb0b6dSopenharmony_ci
5333eb0b6dSopenharmony_ciint main(int argc, char** argv)
5433eb0b6dSopenharmony_ci{
5533eb0b6dSopenharmony_ci    testing::GTEST_FLAG(output) = "xml:./";
5633eb0b6dSopenharmony_ci    testing::InitGoogleTest(&argc, argv);
5733eb0b6dSopenharmony_ci
5833eb0b6dSopenharmony_ci    // Setup
5933eb0b6dSopenharmony_ci    RuntimeOption option;
6033eb0b6dSopenharmony_ci    option.SetGcType(RuntimeOption::GC_TYPE::GEN_GC);
6133eb0b6dSopenharmony_ci    const int64_t poolSize = 0x1000000;  // 16M
6233eb0b6dSopenharmony_ci    option.SetGcPoolSize(poolSize);
6333eb0b6dSopenharmony_ci    option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
6433eb0b6dSopenharmony_ci    option.SetDebuggerLibraryPath("");
6533eb0b6dSopenharmony_ci    EcmaVM* vm = panda::JSNApi::CreateJSVM(option);
6633eb0b6dSopenharmony_ci    if (vm == nullptr) {
6733eb0b6dSopenharmony_ci        return 0;
6833eb0b6dSopenharmony_ci    }
6933eb0b6dSopenharmony_ci
7033eb0b6dSopenharmony_ci    g_nativeEngine = new ArkNativeEngine(vm, nullptr);
7133eb0b6dSopenharmony_ci
7233eb0b6dSopenharmony_ci    int ret = testing::UnitTest::GetInstance()->Run();
7333eb0b6dSopenharmony_ci
7433eb0b6dSopenharmony_ci    g_nativeEngine->Loop(LOOP_NOWAIT);
7533eb0b6dSopenharmony_ci
7633eb0b6dSopenharmony_ci    delete g_nativeEngine;
7733eb0b6dSopenharmony_ci    g_nativeEngine = nullptr;
7833eb0b6dSopenharmony_ci    panda::JSNApi::DestroyJSVM(vm);
7933eb0b6dSopenharmony_ci    vm = nullptr;
8033eb0b6dSopenharmony_ci
8133eb0b6dSopenharmony_ci    return ret;
8233eb0b6dSopenharmony_ci}
8333eb0b6dSopenharmony_ci
8433eb0b6dSopenharmony_ciHWTEST_F(NativeEngineTest, SuspendVM001, testing::ext::TestSize.Level0)
8533eb0b6dSopenharmony_ci{
8633eb0b6dSopenharmony_ci    pthread_t tids;
8733eb0b6dSopenharmony_ci    struct ThreadArgs *args = new ThreadArgs;
8833eb0b6dSopenharmony_ci    args->engine = engine_;
8933eb0b6dSopenharmony_ci    int res = pthread_create(&tids, NULL, Run, (void*)args);
9033eb0b6dSopenharmony_ci    if (res != 0) {
9133eb0b6dSopenharmony_ci        std::cout << "thread create failed";
9233eb0b6dSopenharmony_ci        return;
9333eb0b6dSopenharmony_ci    }
9433eb0b6dSopenharmony_ci    for (int i = 0; i < 3; ++i) { // 3:Loop 3 times
9533eb0b6dSopenharmony_ci        sleep(1);
9633eb0b6dSopenharmony_ci        engine_->CheckSafepoint();
9733eb0b6dSopenharmony_ci    }
9833eb0b6dSopenharmony_ci    ASSERT_TRUE(!args->initialState);
9933eb0b6dSopenharmony_ci    ASSERT_TRUE(args->suspendState);
10033eb0b6dSopenharmony_ci    ASSERT_TRUE(!args->resumeState);
10133eb0b6dSopenharmony_ci    delete args;
10233eb0b6dSopenharmony_ci    args = nullptr;
10333eb0b6dSopenharmony_ci}
10433eb0b6dSopenharmony_ci
10533eb0b6dSopenharmony_ciHWTEST_F(NativeEngineTest, CreateRuntimeFunc001, testing::ext::TestSize.Level0)
10633eb0b6dSopenharmony_ci{
10733eb0b6dSopenharmony_ci    auto result = engine_->CreateRuntime(true);
10833eb0b6dSopenharmony_ci    ASSERT_TRUE(result);
10933eb0b6dSopenharmony_ci}
11033eb0b6dSopenharmony_ci
11133eb0b6dSopenharmony_ciHWTEST_F(NativeEngineTest, ExecuteTranslateBySourceMapFunc001, testing::ext::TestSize.Level0)
11233eb0b6dSopenharmony_ci{
11333eb0b6dSopenharmony_ci    std::string stack = engine_->ExecuteTranslateBySourceMap("test1/test2/test3/test.ts");
11433eb0b6dSopenharmony_ci    ASSERT_EQ(stack, "test1/test2/test3/test.ts");
11533eb0b6dSopenharmony_ci}
11633eb0b6dSopenharmony_ci
11733eb0b6dSopenharmony_ciHWTEST_F(NativeEngineTest, FinalizersCallbackTest001, testing::ext::TestSize.Level0)
11833eb0b6dSopenharmony_ci{
11933eb0b6dSopenharmony_ci    ASSERT_NE(engine_, nullptr);
12033eb0b6dSopenharmony_ci    napi_env env = (napi_env)engine_;
12133eb0b6dSopenharmony_ci    const EcmaVM *vm = reinterpret_cast<ArkNativeEngine*>(engine_)->GetEcmaVm();
12233eb0b6dSopenharmony_ci
12333eb0b6dSopenharmony_ci    const char *str = "FinalizersCallbackTest001";
12433eb0b6dSopenharmony_ci    size_t size = 2 * ArkNativeEngine::FINALIZERS_PACK_PENDING_NATIVE_BINDING_SIZE_THRESHOLD;
12533eb0b6dSopenharmony_ci    static bool finalizersCallbackDone[2] = {false, false};
12633eb0b6dSopenharmony_ci
12733eb0b6dSopenharmony_ci    for (int i = 0; i < 2; ++i) {
12833eb0b6dSopenharmony_ci        {
12933eb0b6dSopenharmony_ci            panda::LocalScope scope(vm);
13033eb0b6dSopenharmony_ci            napi_value object = nullptr;
13133eb0b6dSopenharmony_ci            napi_create_object(env, &object);
13233eb0b6dSopenharmony_ci            napi_wrap_with_size(env, object, (void*)str, [](napi_env env, void *data, void *hint) {
13333eb0b6dSopenharmony_ci                bool *result = reinterpret_cast<bool*>(hint);
13433eb0b6dSopenharmony_ci                ASSERT_FALSE(*result);
13533eb0b6dSopenharmony_ci                *result = true;
13633eb0b6dSopenharmony_ci            }, reinterpret_cast<void*>(&finalizersCallbackDone[i]), nullptr, size);
13733eb0b6dSopenharmony_ci        }
13833eb0b6dSopenharmony_ci        panda::JSNApi::TriggerGC(vm, panda::ecmascript::GCReason::OTHER, panda::JSNApi::TRIGGER_GC_TYPE::FULL_GC);
13933eb0b6dSopenharmony_ci    }
14033eb0b6dSopenharmony_ci
14133eb0b6dSopenharmony_ci    ASSERT_FALSE(finalizersCallbackDone[0]);
14233eb0b6dSopenharmony_ci    ASSERT_TRUE(finalizersCallbackDone[1]);
14333eb0b6dSopenharmony_ci}