1#!/usr/bin/env python3
2# coding=utf-8
3
4#
5# Copyright (c) 2021 Huawei Device Co., Ltd.
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#     http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19import os
20import sys
21import re
22import time
23import platform
24import stat
25
26FLAGS = os.O_WRONLY | os.O_CREAT | os.O_EXCL
27MODES = stat.S_IWUSR | stat.S_IRUSR
28
29# insert src path for loading xdevice modules
30
31sys.framework_src_dir = os.path.abspath(os.path.dirname(
32    os.path.dirname(__file__)))
33sys.path.insert(1, sys.framework_src_dir)
34sys.framework_root_dir = os.path.abspath(os.path.dirname(
35    os.path.dirname(os.path.dirname(os.path.dirname(
36        os.path.dirname(__file__))))))
37sys.xdevice_dir = os.path.abspath(os.path.join(
38    sys.framework_root_dir,
39    "src"))
40sys.path.insert(2, sys.xdevice_dir)
41sys.xdevice_dir = os.path.abspath(os.path.join(
42    sys.framework_root_dir,
43    "..",
44    "xdevice",
45    "src"))
46sys.path.insert(3, sys.xdevice_dir)
47sys.adapter_dir = os.path.abspath(os.path.join(
48    sys.framework_root_dir,
49    "adapter",
50    "aw",
51    "python"))
52sys.path.insert(4, sys.adapter_dir)
53
54
55from distributed.common.common import create_empty_result_file
56from distributed.common.common import get_resource_dir
57from distributed.common.drivers import CppTestDriver
58
59
60DEVICE_INFO_TEMPLATE = "agentlist:%s\nagentport:%s,\ndevicesuuid:%s"
61
62
63##############################################################################
64##############################################################################
65
66
67def get_current_driver(device, target_name, hdc_tools):
68    driver = None
69    _, suffix_name = os.path.splitext(target_name)
70    if suffix_name == "":
71        driver = CppTestDriver(device, hdc_tools)
72    elif suffix_name == ".bin":
73        driver = CppTestDriver(device, hdc_tools)
74    return driver
75
76
77##############################################################################
78##############################################################################
79
80
81class Distribute:
82    def __init__(self, suite_dir, major, agent_list, hdc_tools):
83        self.suite_dir = suite_dir
84        self.major = major
85        self.agent_list = agent_list
86        self.hdc_tools = hdc_tools
87
88    @staticmethod
89    def pull_result(device, source_path, result_save_path):
90        _, file_name = os.path.split(source_path)
91        device.pull_file(source_path, result_save_path)
92        if not os.path.exists(os.path.join(result_save_path, file_name)):
93            create_empty_result_file(result_save_path, file_name)
94
95    @staticmethod
96    def _check_thread(device, thread_name):
97        check_command = "ps -A | grep %s" % thread_name
98        checksum = 0
99        while checksum < 10:
100            checksum += 1
101            print("check thread:%s %s times" % (thread_name, checksum))
102            output = device.shell_with_output(check_command)
103            if output == "":
104                time.sleep(0.1)
105            else:
106                print("thread info: %s" % output)
107                break
108        return True if checksum < 100 else False
109
110    @staticmethod
111    def _query_device_ip(device):
112        output = device.shell_with_output("getprop ro.hardware")
113        if output == "":
114            return ""
115
116        isemulator = re.findall(r"ranchu", output)
117        output = device.shell_with_output("ifconfig")
118        if output == "":
119            return ""
120
121        if len(isemulator) != 0:
122            ipaddress = re.findall(r"\b10\.0\.2\.[0-9]{1,3}\b", output)
123        else:
124            ip_template = r"\b1[0-9]{1,2}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\b"
125            ipaddress = re.findall(ip_template, output)
126
127        if len(ipaddress) == 0:
128            return ""
129
130        return ipaddress[0]
131
132    @staticmethod
133    def _query_device_hdc_ip(device):
134        output = device.shell_with_output("param get ohos.boot.hardware")
135        if output == "":
136            return ""
137
138        isemulator = re.findall('readonly', str(output))
139        output = device.shell_with_output("ifconfig waln0")
140        if output == "":
141            return ""
142
143        if 0 != len(isemulator):
144            ipaddress = re.findall(r"\b10\.0\.2\.[0-9]{1,3}\b", output)
145        else:
146            ip_template = r"\b1[0-9]{1,2}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\b"
147            ipaddress = re.findall(ip_template, output)
148        if len(ipaddress) == 0:
149            return ""
150        return ipaddress[0]
151
152    @staticmethod
153    def _query_device_uuid(device):
154        """
155        1. Run the dumpsys DdmpDeviceMonitorService command to query the value
156           of dev_nodeid.
157        2. The dump information reported by the soft bus. Local device info,
158           should be placed first.
159        Note: The dump information may not comply with the JSON format.
160        """
161        dumpsys_command = "dumpsys DdmpDeviceMonitorService"
162        device_info = device.shell_with_output(dumpsys_command)
163        if device_info == "":
164            return ""
165
166        begin = device_info.find("dev_nodeid")
167        if begin == -1:
168            return ""
169
170        end = device_info.find(",", begin)
171        if end == -1:
172            return ""
173
174        dev_nodeid_info = device_info[begin:end].replace('"', "")
175        return dev_nodeid_info.split(":")[1]
176
177    @staticmethod
178    def _query_device_major_uuid(device):
179        device_sn = device.device_sn
180        command = "hdc -t %s shell hidumper -s 4700 -a 'buscenter -l local_device_info'" % device_sn
181        device_info = device.execute_command_with_output(command)
182
183        if device_info == "":
184            return ""
185        dev_nodeid_info = re.findall(r"Uuid = (.*?\r\n)", device_info)
186        if dev_nodeid_info:
187            return str(dev_nodeid_info[0])
188        else:
189            return ""
190
191    @staticmethod
192    def _query_device_agent_uuid(device):
193        device_sn = device.device_sn
194        command = "hdc -t %s shell hidumper -s 4700 -a 'buscenter -l remote_device_info'" % device_sn
195        device_info = device.execute_command_with_output(command)
196
197        if device_info == "":
198            return ""
199        dev_nodeid_info = re.findall(r"Uuid = (.*?\r\n)", device_info)
200        if dev_nodeid_info:
201            return str(dev_nodeid_info[0])
202        else:
203            return ""
204
205    @staticmethod
206    def _write_device_config(device_info, file_path):
207        file_dir, file_name = os.path.split(file_path)
208        final_file = os.path.join(file_dir, file_name.split('.')[0] + ".desc")
209        if os.path.exists(final_file):
210            os.remove(final_file)
211        if os.path.exists(file_path):
212            os.remove(file_path)
213        with os.fdopen(os.open(file_path, FLAGS, MODES), 'w') as file_desc:
214            file_desc.write(device_info)
215        os.rename(file_path, final_file)
216
217    def exec_agent(self, device, target_name, result_path, options):
218        driver = get_current_driver(device, target_name, self.hdc_tools)
219        if driver is None:
220            print("Error: driver is None.")
221            return False
222
223        resource_dir = get_resource_dir(self.suite_dir, device.name)
224
225        self._make_agent_desc_file(device)
226        device.push_file(os.path.join(self.suite_dir, "agent.desc"),
227                         device.test_path)
228        device.push_file(os.path.join(resource_dir, target_name),
229                         device.test_path)
230
231        suite_path = os.path.join(self.suite_dir, target_name)
232        driver.execute(suite_path, result_path, options, background=True)
233        return self._check_thread(device, target_name)
234
235    def exec_major(self, device, target_name, result_path, options):
236        driver = get_current_driver(device, target_name, self.hdc_tools)
237        if driver is None:
238            print("Error: driver is None.")
239            return False
240
241        resource_dir = get_resource_dir(self.suite_dir, device.name)
242        self._make_major_desc_file()
243        device.push_file(os.path.join(self.suite_dir, "major.desc"),
244                         device.test_path)
245        device.push_file(os.path.join(resource_dir, target_name),
246                         device.test_path)
247
248        suite_path = os.path.join(self.suite_dir, target_name)
249        return driver.execute(suite_path, result_path, options, background=False)
250
251    def _make_agent_desc_file(self, device):
252        agent_ip_list = ""
253        device_uuid_list = ""
254
255        if self.hdc_tools != "hdc":
256            if self._query_device_uuid(self.major) != '':
257                device_uuid_list = "{}{},".format(
258                    device_uuid_list, self._query_device_uuid(self.major))
259
260            if self._query_device_ip(device) != "":
261                agent_ip_list = "{}{},".format(
262                    agent_ip_list, self._query_device_ip(device))
263
264            for agent in self.agent_list:
265                if self._query_device_uuid(agent):
266                    device_uuid_list = "{}{},".format(
267                        device_uuid_list, self._query_device_uuid(agent))
268
269            config_info = DEVICE_INFO_TEMPLATE % (agent_ip_list, "8888",
270                                                  device_uuid_list)
271
272            config_agent_file = os.path.join(self.suite_dir, "agent.desc")
273            self._write_device_config(config_info, config_agent_file)
274        else:
275            if self._query_device_agent_uuid(self.major):
276                device_uuid_list = "{}{},".format(
277                    device_uuid_list, self._query_device_agent_uuid(self.major))
278
279            if self._query_device_hdc_ip(device):
280                agent_ip_list = "{}{},".format(
281                    agent_ip_list, self._query_device_hdc_ip(device))
282
283            for agent in self.agent_list:
284                if self._query_device_agent_uuid(agent):
285                    device_uuid_list = "{}{},".format(
286                        device_uuid_list, self._query_device_agent_uuid(agent))
287
288            config_info = DEVICE_INFO_TEMPLATE % (agent_ip_list, "8888",
289                                                  device_uuid_list)
290
291            config_agent_file = os.path.join(self.suite_dir, "agent.desc")
292            self._write_device_config(config_info, config_agent_file)
293
294    def _make_major_desc_file(self):
295        agent_ip_list = ""
296        device_uuid_list = ""
297
298        if self.hdc_tools != "hdc":
299            if self._query_device_uuid(self.major) != "NoneTyple":
300                device_uuid_list = "{}{},".format(
301                    device_uuid_list, self._query_device_uuid(self.major))
302
303            for agent in self.agent_list:
304                if self._query_device_ip(agent) != "" and self._query_device_uuid(agent) != "":
305                    agent_ip_list = "{}{},".format(agent_ip_list, self._query_device_ip(agent))
306                    device_uuid_list = "{}{},".format(
307                        device_uuid_list, self._query_device_uuid(agent))
308
309            config_info = DEVICE_INFO_TEMPLATE % (agent_ip_list, "8888",
310                                                  device_uuid_list)
311
312            config_major_file = os.path.join(self.suite_dir, "major.desc")
313            self._write_device_config(config_info, config_major_file)
314        else:
315            if self._query_device_major_uuid(self.major):
316                device_uuid_list = "{}{},".format(
317                    device_uuid_list, self._query_device_major_uuid(self.major))
318
319            for agent in self.agent_list:
320                if self._query_device_major_uuid(agent):
321                    agent_ip_list = "{}{},".format(agent_ip_list, self._query_device_hdc_ip(agent))
322                    device_uuid_list = "{}{},".format(
323                        device_uuid_list, self._query_device_major_uuid(agent))
324            config_info = DEVICE_INFO_TEMPLATE % (agent_ip_list, "8888",
325                                                  device_uuid_list)
326
327            config_major_file = os.path.join(self.suite_dir, "major.desc")
328            self._write_device_config(config_info, config_major_file)
329##############################################################################
330##############################################################################
331
332