• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "abc2program_test_utils.h"
17 #include <algorithm>
18 #include <filesystem>
19 #include <fstream>
20 #include <regex>
21 #include <vector>
22 
23 #include "common/abc_file_utils.h"
24 #include "dump_utils.h"
25 
26 namespace panda::abc2program {
27 
28 std::set<std::string> Abc2ProgramTestUtils::helloworld_expected_program_strings_ = {"",
29                                                                                     ".#*#add",
30                                                                                     ".#*#asyncArrowFunc",
31                                                                                     ".#*#asyncGenerateFunc",
32                                                                                     ".#*#foo",
33                                                                                     ".#*#generateFunc",
34                                                                                     ".#*#goo",
35                                                                                     ".#*#hoo",
36                                                                                     ".#~@0=#HelloWorld",
37                                                                                     ".#~@1=#Lit",
38                                                                                     ".#~@2=#NestedLiteralArray",
39                                                                                     "HelloWorld",
40                                                                                     "error",
41                                                                                     "hello",
42                                                                                     "inner catch",
43                                                                                     "masg",
44                                                                                     "max",
45                                                                                     "min",
46                                                                                     "msg",
47                                                                                     "null",
48                                                                                     "num",
49                                                                                     "outter catch",
50                                                                                     "print",
51                                                                                     "prototype",
52                                                                                     "str",
53                                                                                     "string",
54                                                                                     "toString",
55                                                                                     "varA",
56                                                                                     "x"};
57 std::vector<std::string> Abc2ProgramTestUtils::helloworld_expected_record_names_ = {
58     "_ESExpectedPropertyCountAnnotation",
59     "_ESModuleRecord",
60     "_ESSlotNumberAnnotation",
61     "_ESScopeNamesRecord",
62     "_GLOBAL"
63 };
64 std::vector<std::string> Abc2ProgramTestUtils::helloworld_expected_literal_array_keys_ = {
65     "_ESModuleRecord",
66     "_ESScopeNamesRecord",
67     "_GLOBAL",
68     "_GLOBAL",
69     "_GLOBAL",
70     "_GLOBAL",
71     "_GLOBAL"
72 };
73 
74 std::set<size_t> Abc2ProgramTestUtils::helloworld_expected_literals_sizes_ = {2, 6, 8, 10, 21};
75 
76 template <typename T>
ValidateStrings(const T & strings,const T & expected_strings)77 bool Abc2ProgramTestUtils::ValidateStrings(const T &strings, const T &expected_strings)
78 {
79     if (strings.size() != expected_strings.size()) {
80         return false;
81     }
82     for (const std::string &expected_string : expected_strings) {
83         const auto string_iter = std::find(strings.begin(), strings.end(), expected_string);
84         if (string_iter == strings.end()) {
85             return false;
86         }
87     }
88     return true;
89 }
90 
ValidateProgramStrings(const std::set<std::string> & program_strings)91 bool Abc2ProgramTestUtils::ValidateProgramStrings(const std::set<std::string> &program_strings)
92 {
93     return ValidateStrings(program_strings, helloworld_expected_program_strings_);
94 }
95 
ValidateRecordNames(const std::vector<std::string> & record_names)96 bool Abc2ProgramTestUtils::ValidateRecordNames(const std::vector<std::string> &record_names)
97 {
98     return ValidateStrings(record_names, helloworld_expected_record_names_);
99 }
100 
ValidateLiteralArrayKeys(const std::vector<std::string> & literal_array_keys)101 bool Abc2ProgramTestUtils::ValidateLiteralArrayKeys(const std::vector<std::string> &literal_array_keys)
102 {
103     if (literal_array_keys.size() != helloworld_expected_literal_array_keys_.size()) {
104         return false;
105     }
106     for (size_t i = 0; i < literal_array_keys.size(); ++i) {
107         if (literal_array_keys[i].find(helloworld_expected_literal_array_keys_[i]) != 0) {
108             return false;
109         }
110     }
111     return true;
112 }
113 
ValidateLiteralsSizes(const std::set<size_t> & literal_array_sizes)114 bool Abc2ProgramTestUtils::ValidateLiteralsSizes(const std::set<size_t> &literal_array_sizes)
115 {
116     return (literal_array_sizes == helloworld_expected_literals_sizes_);
117 }
118 
ValidateDumpResult(const std::string & result_file_name,const std::string & expected_file_name)119 bool Abc2ProgramTestUtils::ValidateDumpResult(
120     const std::string &result_file_name, const std::string &expected_file_name)
121 {
122     std::ifstream result_file(result_file_name);
123     if (!result_file.is_open()) {
124         return false;
125     }
126     std::ifstream expected_file(expected_file_name);
127     if (!expected_file.is_open()) {
128         return false;
129     }
130     bool is_same = true;
131     std::string result_line;
132     std::string expected_line;
133     // Validate each line of dump results file, including empty lines.
134     while (!result_file.eof() && !expected_file.eof()) {
135         std::getline(result_file, result_line);
136         std::getline(expected_file, expected_line);
137         if (result_line != expected_line && !ValidateLine(result_line, expected_line)) {
138             is_same = false;
139             break;
140         }
141     }
142     bool is_eof = result_file.eof() && expected_file.eof();
143     result_file.close();
144     expected_file.close();
145     return is_same && is_eof;
146 }
147 
ValidateLine(const std::string & result_line,const std::string & expected_line)148 bool Abc2ProgramTestUtils::ValidateLine(const std::string &result_line, const std::string &expected_line)
149 {
150     // Split input strings by white spaces.
151     std::regex white_space("\\s+");
152     std::vector<std::string> result_substrs(
153         std::sregex_token_iterator(result_line.begin(), result_line.end(), white_space, -1),
154         std::sregex_token_iterator());
155     std::vector<std::string> expected_substrs(
156         std::sregex_token_iterator(expected_line.begin(), expected_line.end(), white_space, -1),
157         std::sregex_token_iterator());
158     // Compare all divived sub-strings.
159     if (result_substrs.size() != expected_substrs.size()) {
160         return false;
161     }
162     for (size_t i = 0; i != result_substrs.size(); ++i) {
163         /* It's acceptable if:
164          * 0. the sub-strings are same.
165          * 1. the sub-string is a regular file path, for example, path of the input abc file, which
166          *    could be different on different computers.
167          * 2. the sub-strings are literal array names with offset, offset could be modified when
168          *    abc file version changed.
169          */
170         if (result_substrs[i] != expected_substrs[i] &&
171             !std::filesystem::is_regular_file(std::filesystem::path(result_substrs[i])) &&
172             !ValidateLiteralArrayName(result_substrs[i], expected_substrs[i])) {
173             return false;
174         }
175     }
176     return true;
177 }
178 
ValidateLiteralArrayName(const std::string & result,const std::string & expected)179 bool Abc2ProgramTestUtils::ValidateLiteralArrayName(const std::string &result, const std::string &expected)
180 {
181     // Extract the record name from a literal array name, for example, extract "_GLOBAL" from "_GLOBAL_1466".
182     // The record name of input string 'result' should be same as that of 'expected'.
183     auto res_end_pos = result.rfind(UNDERLINE);
184     auto exp_end_pos = expected.rfind(UNDERLINE);
185     if (res_end_pos == std::string::npos || exp_end_pos == std::string::npos || res_end_pos != exp_end_pos) {
186         return false;
187     }
188     auto res_start_pos = result.rfind(DUMP_CONTENT_COLON, res_end_pos) + 1;
189     auto exp_start_pos = expected.rfind(DUMP_CONTENT_COLON, exp_end_pos) + 1;
190     if (res_start_pos != exp_start_pos) {
191         return false;
192     }
193     auto res_name = result.substr(res_start_pos, res_end_pos - res_start_pos);
194     if (std::find(helloworld_expected_literal_array_keys_.begin(),
195                   helloworld_expected_literal_array_keys_.end(),
196                   res_name) == helloworld_expected_literal_array_keys_.end()) {
197         return false;
198     }
199     auto exp_name = expected.substr(exp_start_pos, exp_end_pos - exp_start_pos);
200     return res_name == exp_name;
201 }
202 
RemoveDumpResultFile(const std::string & file_name)203 void Abc2ProgramTestUtils::RemoveDumpResultFile(const std::string &file_name)
204 {
205     std::filesystem::remove(std::filesystem::path(file_name));
206 }
207 }  // namespace panda::abc2program
208