• 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_ = {"_ESModuleRecord",
58                                                                                     "_ESSlotNumberAnnotation",
59                                                                                     "_ESScopeNamesRecord",
60                                                                                     "_GLOBAL"};
61 std::vector<std::string> Abc2ProgramTestUtils::helloworld_expected_literal_array_keys_ = {"_ESModuleRecord",
62                                                                                           "_ESScopeNamesRecord",
63                                                                                           "_GLOBAL",
64                                                                                           "_GLOBAL",
65                                                                                           "_GLOBAL",
66                                                                                           "_GLOBAL",
67                                                                                           "_GLOBAL"};
68 
69 std::set<size_t> Abc2ProgramTestUtils::helloworld_expected_literals_sizes_ = {2, 6, 8, 10, 21};
70 
71 template <typename T>
ValidateStrings(const T & strings,const T & expected_strings)72 bool Abc2ProgramTestUtils::ValidateStrings(const T &strings, const T &expected_strings)
73 {
74     if (strings.size() != expected_strings.size()) {
75         return false;
76     }
77     for (const std::string &expected_string : expected_strings) {
78         const auto string_iter = std::find(strings.begin(), strings.end(), expected_string);
79         if (string_iter == strings.end()) {
80             return false;
81         }
82     }
83     return true;
84 }
85 
ValidateProgramStrings(const std::set<std::string> & program_strings)86 bool Abc2ProgramTestUtils::ValidateProgramStrings(const std::set<std::string> &program_strings)
87 {
88     return ValidateStrings(program_strings, helloworld_expected_program_strings_);
89 }
90 
ValidateRecordNames(const std::vector<std::string> & record_names)91 bool Abc2ProgramTestUtils::ValidateRecordNames(const std::vector<std::string> &record_names)
92 {
93     return ValidateStrings(record_names, helloworld_expected_record_names_);
94 }
95 
ValidateLiteralArrayKeys(const std::vector<std::string> & literal_array_keys)96 bool Abc2ProgramTestUtils::ValidateLiteralArrayKeys(const std::vector<std::string> &literal_array_keys)
97 {
98     if (literal_array_keys.size() != helloworld_expected_literal_array_keys_.size()) {
99         return false;
100     }
101     for (size_t i = 0; i < literal_array_keys.size(); ++i) {
102         if (literal_array_keys[i].find(helloworld_expected_literal_array_keys_[i]) != 0) {
103             return false;
104         }
105     }
106     return true;
107 }
108 
ValidateLiteralsSizes(const std::set<size_t> & literal_array_sizes)109 bool Abc2ProgramTestUtils::ValidateLiteralsSizes(const std::set<size_t> &literal_array_sizes)
110 {
111     return (literal_array_sizes == helloworld_expected_literals_sizes_);
112 }
113 
ValidateDumpResult(const std::string & result_file_name,const std::string & expected_file_name)114 bool Abc2ProgramTestUtils::ValidateDumpResult(
115     const std::string &result_file_name, const std::string &expected_file_name)
116 {
117     std::ifstream result_file(result_file_name);
118     if (!result_file.is_open()) {
119         return false;
120     }
121     std::ifstream expected_file(expected_file_name);
122     if (!expected_file.is_open()) {
123         return false;
124     }
125     bool is_same = true;
126     std::string result_line;
127     std::string expected_line;
128     // Validate each line of dump results file, including empty lines.
129     while (!result_file.eof() && !expected_file.eof()) {
130         std::getline(result_file, result_line);
131         std::getline(expected_file, expected_line);
132         if (result_line != expected_line && !ValidateLine(result_line, expected_line)) {
133             is_same = false;
134             break;
135         }
136     }
137     bool is_eof = result_file.eof() && expected_file.eof();
138     result_file.close();
139     expected_file.close();
140     return is_same && is_eof;
141 }
142 
ValidateLine(const std::string & result_line,const std::string & expected_line)143 bool Abc2ProgramTestUtils::ValidateLine(const std::string &result_line, const std::string &expected_line)
144 {
145     // Split input strings by white spaces.
146     std::regex white_space("\\s+");
147     std::vector<std::string> result_substrs(
148         std::sregex_token_iterator(result_line.begin(), result_line.end(), white_space, -1),
149         std::sregex_token_iterator());
150     std::vector<std::string> expected_substrs(
151         std::sregex_token_iterator(expected_line.begin(), expected_line.end(), white_space, -1),
152         std::sregex_token_iterator());
153     // Compare all divived sub-strings.
154     if (result_substrs.size() != expected_substrs.size()) {
155         return false;
156     }
157     for (size_t i = 0; i != result_substrs.size(); ++i) {
158         /* It's acceptable if:
159          * 0. the sub-strings are same.
160          * 1. the sub-string is a regular file path, for example, path of the input abc file, which
161          *    could be different on different computers.
162          * 2. the sub-strings are literal array names with offset, offset could be modified when
163          *    abc file version changed.
164          */
165         if (result_substrs[i] != expected_substrs[i] &&
166             !std::filesystem::is_regular_file(std::filesystem::path(result_substrs[i])) &&
167             !ValidateLiteralArrayName(result_substrs[i], expected_substrs[i])) {
168             return false;
169         }
170     }
171     return true;
172 }
173 
ValidateLiteralArrayName(const std::string & result,const std::string & expected)174 bool Abc2ProgramTestUtils::ValidateLiteralArrayName(const std::string &result, const std::string &expected)
175 {
176     // Extract the record name from a literal array name, for example, extract "_GLOBAL" from "_GLOBAL_1466".
177     // The record name of input string 'result' should be same as that of 'expected'.
178     auto res_end_pos = result.rfind(UNDERLINE);
179     auto exp_end_pos = expected.rfind(UNDERLINE);
180     if (res_end_pos == std::string::npos || exp_end_pos == std::string::npos || res_end_pos != exp_end_pos) {
181         return false;
182     }
183     auto res_start_pos = result.rfind(DUMP_CONTENT_COLON, res_end_pos) + 1;
184     auto exp_start_pos = expected.rfind(DUMP_CONTENT_COLON, exp_end_pos) + 1;
185     if (res_start_pos != exp_start_pos) {
186         return false;
187     }
188     auto res_name = result.substr(res_start_pos, res_end_pos - res_start_pos);
189     if (std::find(helloworld_expected_literal_array_keys_.begin(),
190                   helloworld_expected_literal_array_keys_.end(),
191                   res_name) == helloworld_expected_literal_array_keys_.end()) {
192         return false;
193     }
194     auto exp_name = expected.substr(exp_start_pos, exp_end_pos - exp_start_pos);
195     return res_name == exp_name;
196 }
197 
RemoveDumpResultFile(const std::string & file_name)198 void Abc2ProgramTestUtils::RemoveDumpResultFile(const std::string &file_name)
199 {
200     std::filesystem::remove(std::filesystem::path(file_name));
201 }
202 }  // namespace panda::abc2program
203