• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstdio>
17 #include <fstream>
18 #include <fcntl.h>
19 
20 #include "ecmascript/dfx/hprof/heap_profiler_interface.h"
21 #include "ecmascript/dfx/hprof/heap_profiler.h"
22 #include "ecmascript/dfx/hprof/heap_snapshot_json_serializer.h"
23 #include "ecmascript/dfx/hprof/heap_snapshot.h"
24 #include "ecmascript/ecma_string.h"
25 #include "ecmascript/global_env.h"
26 
27 #include "ecmascript/js_tagged_value.h"
28 #include "ecmascript/js_thread.h"
29 #include "ecmascript/mem/heap.h"
30 #include "ecmascript/tests/test_helper.h"
31 #include "ecmascript/dfx/hprof/file_stream.h"
32 
33 using namespace panda::ecmascript;
34 
35 namespace panda::ecmascript {
36 class TestProgress : public Progress {
37 public:
38     TestProgress() = default;
39     ~TestProgress() = default;
40 
ReportProgress(int32_t done,int32_t total)41     void ReportProgress([[maybe_unused]] int32_t done, [[maybe_unused]] int32_t total) override {}
42 };
43 
44 class TestStream : public Stream {
45 public:
46     TestStream() = default;
47     ~TestStream() = default;
48 
EndOfStream()49     void EndOfStream() override {}
GetSize()50     int GetSize() override
51     {
52         static const int HEAP_PROFILER_CHUNK_SIZE = 100_KB;
53         return HEAP_PROFILER_CHUNK_SIZE;
54     }
WriteChunk(char * data,int32_t size)55     bool WriteChunk([[maybe_unused]] char *data, [[maybe_unused]] int32_t size) override
56     {
57         return true;
58     }
Good()59     bool Good() override
60     {
61         return testStream_.good();
62     }
63 
UpdateHeapStats(HeapStat * updateData,int32_t count)64     void UpdateHeapStats([[maybe_unused]] HeapStat* updateData, [[maybe_unused]] int32_t count) override
65     {
66     }
67 
UpdateLastSeenObjectId(int32_t lastSeenObjectId,int64_t timeStampUs)68     void UpdateLastSeenObjectId([[maybe_unused]] int32_t lastSeenObjectId, [[maybe_unused]]int64_t timeStampUs) override
69     {
70     }
71 
Clear()72     void Clear()
73     {
74         testStream_.clear(std::ios::badbit);
75     }
76 
77 private:
78     std::fstream testStream_;
79 };
80 }
81 
82 namespace panda::test {
83 class HeapTrackerTest : public testing::Test {
84 public:
SetUpTestCase()85     static void SetUpTestCase()
86     {
87         GTEST_LOG_(INFO) << "SetUpTestCase";
88     }
89 
TearDownTestCase()90     static void TearDownTestCase()
91     {
92         GTEST_LOG_(INFO) << "TearDownCase";
93     }
94 
SetUp()95     void SetUp() override
96     {
97         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
98         instance->SetEnableForceGC(false);
99     }
100 
TearDown()101     void TearDown() override
102     {
103         TestHelper::DestroyEcmaVMWithScope(instance, scope);
104     }
105 
106     EcmaVM *instance {nullptr};
107     EcmaHandleScope *scope {nullptr};
108     JSThread *thread {nullptr};
109 };
110 
HWTEST_F_L0(HeapTrackerTest,GenDumpFileName_001)111 HWTEST_F_L0(HeapTrackerTest, GenDumpFileName_001)
112 {
113     [[maybe_unused]] EcmaHandleScope handleScope(thread);
114     HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(instance);
115 
116     sleep(1);
117     int count = 100;
118     while (count-- > 0) {
119         instance->GetFactory()->NewJSAsyncFuncObject();
120     }
121     sleep(1);
122     count = 100;
123     while (count-- > 0) {
124         instance->GetFactory()->NewJSSymbol();
125     }
126     sleep(1);
127     count = 100;
128     while (count-- > 0) {
129         JSHandle<JSTaggedValue> undefined = instance->GetJSThread()->GlobalConstants()->GetHandledUndefined();
130         JSHandle<EcmaString> string = instance->GetFactory()->NewFromASCII("Hello World");
131         instance->GetFactory()->NewJSString(JSHandle<JSTaggedValue>(string), undefined);
132     }
133 
134     TestStream stream;
135     stream.Clear();
136     EXPECT_TRUE(!stream.Good());
137     TestProgress testProgress;
138     heapProfile->DumpHeapSnapshot(DumpFormat::JSON, &stream, &testProgress, true, true, false);
139     HeapProfilerInterface::Destroy(instance);
140 }
141 
HWTEST_F_L0(HeapTrackerTest,GenDumpFileName_002)142 HWTEST_F_L0(HeapTrackerTest, GenDumpFileName_002)
143 {
144     [[maybe_unused]] EcmaHandleScope handleScope(thread);
145     HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(instance);
146 
147     sleep(1);
148     int count = 100;
149     while (count-- > 0) {
150         instance->GetFactory()->NewJSAsyncFuncObject();
151     }
152     sleep(1);
153     count = 100;
154     while (count-- > 0) {
155         instance->GetFactory()->NewJSSymbol();
156     }
157     sleep(1);
158     count = 100;
159     while (count-- > 0) {
160         JSHandle<JSTaggedValue> undefined = instance->GetJSThread()->GlobalConstants()->GetHandledUndefined();
161         JSHandle<EcmaString> string = instance->GetFactory()->NewFromASCII("Hello World");
162         instance->GetFactory()->NewJSString(JSHandle<JSTaggedValue>(string), undefined);
163     }
164 
165     TestStream stream;
166     stream.Clear();
167     EXPECT_TRUE(!stream.Good());
168     TestProgress testProgress;
169     heapProfile->DumpHeapSnapshot(DumpFormat::BINARY, &stream, &testProgress, true, true, false);
170     HeapProfilerInterface::Destroy(instance);
171 }
172 
HWTEST_F_L0(HeapTrackerTest,GenDumpFileName_003)173 HWTEST_F_L0(HeapTrackerTest, GenDumpFileName_003)
174 {
175     [[maybe_unused]] EcmaHandleScope handleScope(thread);
176     HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(instance);
177 
178     sleep(1);
179     int count = 100;
180     while (count-- > 0) {
181         instance->GetFactory()->NewJSAsyncFuncObject();
182     }
183     sleep(1);
184     count = 100;
185     while (count-- > 0) {
186         instance->GetFactory()->NewJSSymbol();
187     }
188     sleep(1);
189     count = 100;
190     while (count-- > 0) {
191         JSHandle<JSTaggedValue> undefined = instance->GetJSThread()->GlobalConstants()->GetHandledUndefined();
192         JSHandle<EcmaString> string = instance->GetFactory()->NewFromASCII("Hello World");
193         instance->GetFactory()->NewJSString(JSHandle<JSTaggedValue>(string), undefined);
194     }
195 
196     TestStream stream;
197     stream.Clear();
198     EXPECT_TRUE(!stream.Good());
199     TestProgress testProgress;
200     heapProfile->DumpHeapSnapshot(DumpFormat::OTHER, &stream, &testProgress, true, true, false);
201     HeapProfilerInterface::Destroy(instance);
202 }
203 
HWTEST_F_L0(HeapTrackerTest,GenDumpFileName_004)204 HWTEST_F_L0(HeapTrackerTest, GenDumpFileName_004)
205 {
206     [[maybe_unused]] EcmaHandleScope handleScope(thread);
207     HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(instance);
208 
209     sleep(1);
210     int count = 100;
211     while (count-- > 0) {
212         instance->GetFactory()->NewJSAsyncFuncObject();
213     }
214     sleep(1);
215     count = 100;
216     while (count-- > 0) {
217         instance->GetFactory()->NewJSSymbol();
218     }
219     sleep(1);
220     count = 100;
221     while (count-- > 0) {
222         JSHandle<JSTaggedValue> undefined = instance->GetJSThread()->GlobalConstants()->GetHandledUndefined();
223         JSHandle<EcmaString> string = instance->GetFactory()->NewFromASCII("Hello World");
224         instance->GetFactory()->NewJSString(JSHandle<JSTaggedValue>(string), undefined);
225     }
226 
227     TestStream stream;
228     stream.Clear();
229     EXPECT_TRUE(!stream.Good());
230     TestProgress testProgress;
231     DumpFormat dumFormat = static_cast<DumpFormat>(5);
232     heapProfile->DumpHeapSnapshot(dumFormat, &stream, &testProgress, true, true, false);
233     HeapProfilerInterface::Destroy(instance);
234 }
235 
HWTEST_F_L0(HeapTrackerTest,FileDescriptorStreamEndOfStream)236 HWTEST_F_L0(HeapTrackerTest, FileDescriptorStreamEndOfStream)
237 {
238     int fd = 3;
239     FileDescriptorStream fileStream(fd);
240     EXPECT_TRUE(fileStream.Good());
241     fileStream.EndOfStream();
242 }
243 } // namespace panda::test