1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "test.h"
17
18#include "native_engine/impl/ark/ark_native_engine.h"
19#include "utils/log.h"
20
21using panda::RuntimeOption;
22
23struct ThreadArgs {
24    NativeEngine* engine = nullptr;
25    bool initialState = false;
26    bool suspendState = false;
27    bool resumeState = false;
28};
29
30static NativeEngine* g_nativeEngine = nullptr;
31
32NativeEngineTest::NativeEngineTest()
33{
34    engine_ = g_nativeEngine;
35}
36
37NativeEngineTest::~NativeEngineTest()
38{}
39
40void *NativeEngineTest::Run(void *args)
41{
42    ThreadArgs* threadArgs = reinterpret_cast<ThreadArgs*>(args);
43    NativeEngine* engine = threadArgs->engine;
44    threadArgs->initialState = engine->IsSuspended();
45    engine->SuspendVM();
46    threadArgs->suspendState = engine->IsSuspended();
47    engine->ResumeVM();
48    sleep(1);
49    threadArgs->resumeState = engine->IsSuspended();
50    return nullptr;
51}
52
53int main(int argc, char** argv)
54{
55    testing::GTEST_FLAG(output) = "xml:./";
56    testing::InitGoogleTest(&argc, argv);
57
58    // Setup
59    RuntimeOption option;
60    option.SetGcType(RuntimeOption::GC_TYPE::GEN_GC);
61    const int64_t poolSize = 0x1000000;  // 16M
62    option.SetGcPoolSize(poolSize);
63    option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
64    option.SetDebuggerLibraryPath("");
65    EcmaVM* vm = panda::JSNApi::CreateJSVM(option);
66    if (vm == nullptr) {
67        return 0;
68    }
69
70    g_nativeEngine = new ArkNativeEngine(vm, nullptr);
71
72    int ret = testing::UnitTest::GetInstance()->Run();
73
74    g_nativeEngine->Loop(LOOP_NOWAIT);
75
76    delete g_nativeEngine;
77    g_nativeEngine = nullptr;
78    panda::JSNApi::DestroyJSVM(vm);
79    vm = nullptr;
80
81    return ret;
82}
83
84HWTEST_F(NativeEngineTest, SuspendVM001, testing::ext::TestSize.Level0)
85{
86    pthread_t tids;
87    struct ThreadArgs *args = new ThreadArgs;
88    args->engine = engine_;
89    int res = pthread_create(&tids, NULL, Run, (void*)args);
90    if (res != 0) {
91        std::cout << "thread create failed";
92        return;
93    }
94    for (int i = 0; i < 3; ++i) { // 3:Loop 3 times
95        sleep(1);
96        engine_->CheckSafepoint();
97    }
98    ASSERT_TRUE(!args->initialState);
99    ASSERT_TRUE(args->suspendState);
100    ASSERT_TRUE(!args->resumeState);
101    delete args;
102    args = nullptr;
103}
104
105HWTEST_F(NativeEngineTest, CreateRuntimeFunc001, testing::ext::TestSize.Level0)
106{
107    auto result = engine_->CreateRuntime(true);
108    ASSERT_TRUE(result);
109}
110
111HWTEST_F(NativeEngineTest, ExecuteTranslateBySourceMapFunc001, testing::ext::TestSize.Level0)
112{
113    std::string stack = engine_->ExecuteTranslateBySourceMap("test1/test2/test3/test.ts");
114    ASSERT_EQ(stack, "test1/test2/test3/test.ts");
115}
116
117HWTEST_F(NativeEngineTest, FinalizersCallbackTest001, testing::ext::TestSize.Level0)
118{
119    ASSERT_NE(engine_, nullptr);
120    napi_env env = (napi_env)engine_;
121    const EcmaVM *vm = reinterpret_cast<ArkNativeEngine*>(engine_)->GetEcmaVm();
122
123    const char *str = "FinalizersCallbackTest001";
124    size_t size = 2 * ArkNativeEngine::FINALIZERS_PACK_PENDING_NATIVE_BINDING_SIZE_THRESHOLD;
125    static bool finalizersCallbackDone[2] = {false, false};
126
127    for (int i = 0; i < 2; ++i) {
128        {
129            panda::LocalScope scope(vm);
130            napi_value object = nullptr;
131            napi_create_object(env, &object);
132            napi_wrap_with_size(env, object, (void*)str, [](napi_env env, void *data, void *hint) {
133                bool *result = reinterpret_cast<bool*>(hint);
134                ASSERT_FALSE(*result);
135                *result = true;
136            }, reinterpret_cast<void*>(&finalizersCallbackDone[i]), nullptr, size);
137        }
138        panda::JSNApi::TriggerGC(vm, panda::ecmascript::GCReason::OTHER, panda::JSNApi::TRIGGER_GC_TYPE::FULL_GC);
139    }
140
141    ASSERT_FALSE(finalizersCallbackDone[0]);
142    ASSERT_TRUE(finalizersCallbackDone[1]);
143}