• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3#
4# Copyright (c) 2024 Huawei Device Co., Ltd.
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17import multiprocessing.pool
18import os
19import sys
20from distutils.dir_util import copy_tree
21import random
22from typing import Tuple, Dict, Final, List
23import logging
24
25import stress_test
26import stress_common
27from stress_test import StressTest, Test, Result
28
29from stress_common import SCRIPT_DIR, TMP_DIR, collect_from
30
31TEST_ETS_SOURCES_ROOT = os.path.join(SCRIPT_DIR, '..', '..', '..',
32                                     'static_core', 'plugins', "ets", "tests",
33                                     'ets_func_tests')
34STDLIB_ETS_SOURCES_ROOT = os.path.join(SCRIPT_DIR, '..', '..', '..',
35                                       'static_core', 'plugins', "ets",
36                                       "stdlib")
37
38
39def get_stdlib_path(build_dir: str) -> str:
40    return os.path.join(
41        build_dir,
42        'gen/arkcompiler/runtime_core/static_core/plugins/ets/etsstdlib.abc')
43
44
45def get_verifier_path(build_dir: str) -> str:
46    return os.path.abspath(
47        os.path.join(build_dir, f'arkcompiler/runtime_core/verifier'))
48
49
50def get_config_path(build_dir: str) -> str:
51    return f'{build_dir}/arkcompiler/ets_frontend/arktsconfig.json'
52
53
54def stress_single(test: Test, out_dir) -> Result:
55    stress_abc = test.abc + '.stress.abc'
56    result = stress_common.run_abckit(out_dir, test.source, test.abc,
57                                      stress_abc)
58
59    if result.returncode == 0:
60        return Result(test.source, 0)
61    return Result(test.source, result.returncode, result.stdout, result.stderr)
62
63
64class StsStressTest(StressTest):
65
66    def __init__(self, args):
67        super().__init__()
68        self.ets_dir = os.path.join(TMP_DIR, 'abckit_test_ets')
69        self.stdlib_dir = os.path.join(TMP_DIR, 'abckit_stdlib')
70
71        self.cp = self.get_compiler_path(args.build_dir)
72        self.vp = get_verifier_path(args.build_dir)
73        self.sp = get_stdlib_path(args.build_dir)
74        self.config = get_config_path(args.build_dir)
75        self.build_dir = args.build_dir
76
77        rc_lib_path: Final[str] = f'{args.build_dir}/arkcompiler/runtime_core'
78
79        self.cenv: Dict[str, str] = {'LD_LIBRARY_PATH': rc_lib_path}
80        self.venv: Dict[str, str] = {
81            'LD_LIBRARY_PATH':
82            f'{rc_lib_path}:{args.build_dir}/thirdparty/icu/'
83        }
84
85    def get_fail_list_path(self) -> str:
86        return os.path.join(SCRIPT_DIR, 'fail_list_sts.json')
87
88    def run_single(self, test: Test) -> Result:
89        stress_result: Result = stress_single(test, self.build_dir)
90        verify_result_one: Result = self.verify_single(test)
91
92        r2p = Test(test.source, test.abc + ".stress.abc")
93        verify_result_two: Result = self.verify_single(r2p)
94
95        if stress_result.result != 0:
96            error = stress_common.parse_stdout(stress_result.result,
97                                               stress_result.stdout)
98            return Result(test.source, error)
99        # Stress test passed
100
101        if verify_result_two.result == 0:
102            return Result(test.source, "0")
103
104        if verify_result_one.result != verify_result_two.result:
105            msg = f'Verifier result changed. Was {verify_result_one.result}, now {verify_result_two.result}'
106            return Result(test.source, msg)
107
108        return Result(test.source, "0")
109
110    def prepare(self) -> None:
111        self.download_ets()
112        self.download_stdlib()
113
114    def download_ets(self) -> None:
115        logger = stress_common.create_logger()
116        abs_path = os.path.abspath(TEST_ETS_SOURCES_ROOT)
117        logger.debug('Ets test download from %s', abs_path)
118        if not os.path.exists(abs_path):
119            logger.debug('Not exists %s', abs_path)
120            return
121        copy_tree(abs_path, self.ets_dir)
122
123    def download_stdlib(self) -> None:
124        logger = stress_common.create_logger()
125
126        abs_path = os.path.abspath(STDLIB_ETS_SOURCES_ROOT)
127        logger.debug('Stdlib download from %s', abs_path)
128        if not os.path.exists(abs_path):
129            logger.debug('Not exists %s', abs_path)
130            return
131        copy_tree(abs_path, self.stdlib_dir)
132
133    def get_compiler_path(self, build_dir) -> str:
134        return os.path.abspath(
135            os.path.join(build_dir, 'arkcompiler/ets_frontend/es2panda'))
136
137    def compile_single(self, src: str) -> Tuple[str, str, int]:
138        logger = stress_common.create_logger()
139        abc_path = src + '.abc'
140        cmd = [
141            self.cp, '--ets-module', '--arktsconfig', self.config,
142            f'--output={abc_path}', src
143        ]
144        result = stress_common.stress_exec(cmd,
145                                           allow_error=True,
146                                           print_command=True,
147                                           env=self.cenv)
148        if result.returncode == 0 and not os.path.exists(abc_path):
149            logger.debug(
150                'WARNING: for %s es2abc has %s return code, but has no output',
151                src, result.returncode)
152        return src, abc_path, result.returncode
153
154    def verify_single(self, test: Test) -> Result:
155        boot_panda_files = f'--boot-panda-files={self.sp}'
156        cmd = [self.vp, boot_panda_files, '--load-runtimes=ets', test.abc]
157        result = stress_common.stress_exec(cmd,
158                                           allow_error=True,
159                                           print_command=True,
160                                           env=self.venv)
161        return Result(test.source, result.returncode)
162
163    def collect(self) -> List[str]:
164        logger = stress_common.create_logger()
165        tests: List[str] = []
166        tests.extend(
167            collect_from(
168                self.ets_dir, lambda name: name.endswith('.sts') and not name.
169                startswith('.')))
170        tests.extend(
171            collect_from(
172                self.stdlib_dir, lambda name: name.endswith('.sts') and
173                not name.startswith('.')))
174
175        random.shuffle(tests)
176        logger.debug('Total tests: %s', len(tests))
177        return tests
178