openubmc-bingo 0.6.45__py3-none-any.whl → 0.6.99__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bmcgo/__init__.py +1 -1
- bmcgo/bmcgo.py +9 -3
- bmcgo/bmcgo_config.py +16 -0
- bmcgo/cli/cli.py +72 -21
- bmcgo/codegen/__init__.py +1 -1
- bmcgo/codegen/lua/codegen.py +2 -2
- bmcgo/codegen/lua/script/check_intfs.py +1 -0
- bmcgo/codegen/lua/script/dto/options.py +1 -0
- bmcgo/codegen/lua/script/gen_db_json.py +4 -3
- bmcgo/codegen/lua/script/gen_rpc_msg_json.py +78 -11
- bmcgo/codegen/lua/script/model_consistency_check.py +1 -1
- bmcgo/codegen/lua/script/render_utils/db_lua.py +5 -6
- bmcgo/codegen/lua/script/render_utils/model_lua.py +5 -1
- bmcgo/codegen/lua/script/template.py +5 -0
- bmcgo/codegen/lua/script/utils.py +50 -8
- bmcgo/codegen/lua/templates/apps/Makefile +2 -2
- bmcgo/codegen/lua/templates/apps/client.lua.mako +1 -1
- bmcgo/codegen/lua/templates/apps/model.lua.mako +4 -3
- bmcgo/codegen/lua/templates/apps/service.lua.mako +1 -1
- bmcgo/codegen/lua/templates/apps/utils/mdb_intf.lua.mako +4 -0
- bmcgo/codegen/lua/templates/new_app_v2/CMakeLists.txt.mako +26 -0
- bmcgo/codegen/lua/templates/new_app_v2/conanfile.py.mako +9 -0
- bmcgo/codegen/lua/v1/script/render_utils/db_lua.py +5 -6
- bmcgo/codegen/lua/v1/script/render_utils/model_lua.py +13 -1
- bmcgo/codegen/lua/v1/templates/apps/client.lua.mako +1 -1
- bmcgo/codegen/lua/v1/templates/apps/local_db.lua.mako +0 -4
- bmcgo/codegen/lua/v1/templates/apps/message.lua.mako +3 -0
- bmcgo/codegen/lua/v1/templates/apps/model.lua.mako +3 -0
- bmcgo/codegen/lua/v1/templates/apps/utils/mdb_intf.lua.mako +6 -4
- bmcgo/component/analysis/analysis.py +9 -4
- bmcgo/component/analysis/dep-rules.json +20 -8
- bmcgo/component/analysis/dep_node.py +2 -0
- bmcgo/component/analysis/intf_validation.py +8 -7
- bmcgo/component/analysis/sr_validation.py +5 -4
- bmcgo/component/busctl_log_parse/busctl_log_parser.py +809 -0
- bmcgo/component/busctl_log_parse/mock_data_save.py +170 -0
- bmcgo/component/busctl_log_parse/test_data_save.py +49 -0
- bmcgo/component/component_helper.py +29 -0
- bmcgo/component/coverage/incremental_cov.py +5 -0
- bmcgo/component/fixture/__init__.py +29 -0
- bmcgo/component/fixture/auto_case_generator.py +490 -0
- bmcgo/component/fixture/busctl_type_converter.py +1081 -0
- bmcgo/component/fixture/common_config.py +15 -0
- bmcgo/component/fixture/dbus_gateway.py +669 -0
- bmcgo/component/fixture/dbus_library.py +250 -0
- bmcgo/component/fixture/dbus_mock_utils.py +514 -0
- bmcgo/component/fixture/dbus_response_handler.py +138 -0
- bmcgo/component/fixture/dbus_signature.py +110 -0
- bmcgo/component/template_v2/conanbase.py.mako +1 -5
- bmcgo/component/test.py +69 -10
- bmcgo/error_analyzer/__init__.py +0 -0
- bmcgo/error_analyzer/case_matcher.py +114 -0
- bmcgo/error_analyzer/log_parser.py +128 -0
- bmcgo/error_analyzer/unified_error_analyzer.py +359 -0
- bmcgo/error_cases/cases.yml +59 -0
- bmcgo/error_cases/cases_template_valid.json +71 -0
- bmcgo/error_cases/conanfile.py +58 -0
- bmcgo/frame.py +0 -4
- bmcgo/functional/analysis.py +18 -12
- bmcgo/functional/bmc_studio_action.py +21 -10
- bmcgo/functional/check.py +86 -42
- bmcgo/functional/conan_index_build.py +1 -1
- bmcgo/functional/config.py +22 -18
- bmcgo/functional/csr_build.py +63 -34
- bmcgo/functional/deploy.py +4 -3
- bmcgo/functional/diff.py +51 -34
- bmcgo/functional/full_component.py +16 -5
- bmcgo/functional/hpm_signer.py +484 -0
- bmcgo/functional/new.py +8 -2
- bmcgo/functional/schema_valid.py +111 -15
- bmcgo/functional/upgrade.py +6 -6
- bmcgo/misc.py +1 -0
- bmcgo/tasks/task_build_conan.py +27 -6
- bmcgo/tasks/task_build_rootfs_img.py +120 -83
- bmcgo/tasks/task_buildgppbin.py +30 -13
- bmcgo/tasks/task_buildhpm_ext4.py +5 -3
- bmcgo/tasks/task_download_buildtools.py +20 -11
- bmcgo/tasks/task_download_dependency.py +29 -20
- bmcgo/tasks/task_hpm_envir_prepare.py +32 -53
- bmcgo/tasks/task_packet_to_supporte.py +12 -4
- bmcgo/tasks/task_prepare.py +1 -1
- bmcgo/tasks/task_sign_and_pack_hpm.py +15 -7
- bmcgo/utils/component_version_check.py +4 -4
- bmcgo/utils/config.py +3 -0
- bmcgo/utils/fetch_component_code.py +148 -17
- bmcgo/utils/install_manager.py +2 -2
- bmcgo/utils/installations/base_installer.py +10 -27
- bmcgo/utils/installations/install_plans/studio.yml +3 -0
- bmcgo/utils/mapping_config_patch.py +5 -4
- bmcgo/utils/tools.py +49 -7
- {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/METADATA +1 -1
- {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/RECORD +95 -74
- bmcgo/tasks/download_buildtools_hm.py +0 -124
- {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/WHEEL +0 -0
- {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/entry_points.txt +0 -0
- {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding: utf-8
|
|
3
|
+
# Copyright (c) 2024 Huawei Technologies Co., Ltd.
|
|
4
|
+
# openUBMC is licensed under Mulan PSL v2.
|
|
5
|
+
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
6
|
+
# You may obtain a copy of Mulan PSL v2 at:
|
|
7
|
+
# http://license.coscl.org.cn/MulanPSL2
|
|
8
|
+
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
9
|
+
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
10
|
+
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
11
|
+
# See the Mulan PSL v2 for more details.
|
|
12
|
+
import asyncio
|
|
13
|
+
import logging
|
|
14
|
+
import os
|
|
15
|
+
from dbus_next.aio import MessageBus
|
|
16
|
+
from dbus_next import Message, MessageType
|
|
17
|
+
from dbus_next.errors import DBusError
|
|
18
|
+
from bmcgo.component.fixture.dbus_signature import DBusSignature
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class DBusLibrary:
|
|
24
|
+
def __init__(self):
|
|
25
|
+
"""初始化DBus连接"""
|
|
26
|
+
self.bus = None
|
|
27
|
+
self._loop = None
|
|
28
|
+
self._connect()
|
|
29
|
+
|
|
30
|
+
def __del__(self):
|
|
31
|
+
"""析构函数,确保连接被关闭"""
|
|
32
|
+
self.close()
|
|
33
|
+
|
|
34
|
+
def list_names(self):
|
|
35
|
+
"""获取所有已注册的 D-Bus 服务名"""
|
|
36
|
+
try:
|
|
37
|
+
async def _list_names():
|
|
38
|
+
# 直接使用 Message API 调用 ListNames 方法
|
|
39
|
+
list_names_msg = Message(
|
|
40
|
+
message_type=MessageType.METHOD_CALL,
|
|
41
|
+
destination='org.freedesktop.DBus',
|
|
42
|
+
path='/org/freedesktop/DBus',
|
|
43
|
+
interface='org.freedesktop.DBus',
|
|
44
|
+
member='ListNames',
|
|
45
|
+
signature='',
|
|
46
|
+
body=[]
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
reply = await self.bus.call(list_names_msg)
|
|
50
|
+
if reply.message_type == MessageType.ERROR:
|
|
51
|
+
error_name = reply.error_name or 'UnknownError'
|
|
52
|
+
error_msg = reply.body[0] if reply.body else 'Unknown error'
|
|
53
|
+
raise DBusError(error_name, error_msg)
|
|
54
|
+
# ListNames 返回一个字符串数组
|
|
55
|
+
return reply.body[0] if reply.body else []
|
|
56
|
+
names = self._loop.run_until_complete(_list_names())
|
|
57
|
+
return names
|
|
58
|
+
except Exception as e:
|
|
59
|
+
logger.warning(f"获取 D-Bus 服务列表失败: {e}")
|
|
60
|
+
return []
|
|
61
|
+
|
|
62
|
+
def service_ok(self, service_name, timeout=5):
|
|
63
|
+
"""检查 D-Bus 服务是否已注册"""
|
|
64
|
+
try:
|
|
65
|
+
async def _check_service():
|
|
66
|
+
introspection = await self.bus.introspect('org.freedesktop.DBus', '/org/freedesktop/DBus')
|
|
67
|
+
proxy = self.bus.get_proxy_object('org.freedesktop.DBus', '/org/freedesktop/DBus', introspection)
|
|
68
|
+
dbus_interface = proxy.get_interface('org.freedesktop.DBus')
|
|
69
|
+
has_owner = await dbus_interface.call_name_has_owner(service_name)
|
|
70
|
+
return has_owner
|
|
71
|
+
has_owner = self._loop.run_until_complete(_check_service())
|
|
72
|
+
if not has_owner:
|
|
73
|
+
raise AssertionError(f"Service '{service_name}' is not registered")
|
|
74
|
+
return has_owner
|
|
75
|
+
except Exception as e:
|
|
76
|
+
raise AssertionError(f"DBUS check failed: {e}") from e
|
|
77
|
+
|
|
78
|
+
def get_interfaces(self, service_name, object_path):
|
|
79
|
+
"""获取指定服务指定对象的接口"""
|
|
80
|
+
try:
|
|
81
|
+
async def _get_introspection():
|
|
82
|
+
introspection = await self.bus.introspect(service_name, object_path)
|
|
83
|
+
proxy = self.bus.get_proxy_object(service_name, object_path, introspection)
|
|
84
|
+
introspectable = proxy.get_interface('org.freedesktop.DBus.Introspectable')
|
|
85
|
+
xml_data = await introspectable.call_introspect()
|
|
86
|
+
return xml_data
|
|
87
|
+
xml_data = self._loop.run_until_complete(_get_introspection())
|
|
88
|
+
return xml_data
|
|
89
|
+
except Exception as e:
|
|
90
|
+
raise AssertionError(f"获取接口失败: {e}") from e
|
|
91
|
+
|
|
92
|
+
def call_dbus_method(self, service_name, object_path, interface_name, method_name, *args):
|
|
93
|
+
"""调用指定服务指定对象指定接口指定方法(直接调用,不需要 introspect)"""
|
|
94
|
+
try:
|
|
95
|
+
async def _call_method():
|
|
96
|
+
# 转换参数
|
|
97
|
+
converted_args = []
|
|
98
|
+
signature_parts = []
|
|
99
|
+
for arg in args:
|
|
100
|
+
logger.info(f"Arg {arg}, type: {type(arg)}")
|
|
101
|
+
if isinstance(arg, dict):
|
|
102
|
+
# 字典类型,dbus-next直接支持Python字典
|
|
103
|
+
logger.debug("trans arg to dict")
|
|
104
|
+
converted_args.append(arg)
|
|
105
|
+
signature_parts.append(DBusSignature.get_dbus_signature(arg))
|
|
106
|
+
elif isinstance(arg, str) and arg.isdigit():
|
|
107
|
+
# 字符串数字转为整数
|
|
108
|
+
logger.debug("trans arg to int")
|
|
109
|
+
intarg = int(arg)
|
|
110
|
+
converted_args.append(intarg)
|
|
111
|
+
signature_parts.append(DBusSignature.get_dbus_signature(intarg))
|
|
112
|
+
else:
|
|
113
|
+
converted_args.append(arg)
|
|
114
|
+
signature_parts.append(DBusSignature.get_dbus_signature(arg))
|
|
115
|
+
# 生成方法签名
|
|
116
|
+
signature = ''.join(signature_parts)
|
|
117
|
+
logger.info(f"转换后的参数: {converted_args}, 签名: {signature}")
|
|
118
|
+
# 直接使用 Message API 调用方法,不需要 introspect
|
|
119
|
+
call_msg = Message(
|
|
120
|
+
message_type=MessageType.METHOD_CALL,
|
|
121
|
+
destination=service_name,
|
|
122
|
+
path=object_path,
|
|
123
|
+
interface=interface_name,
|
|
124
|
+
member=method_name,
|
|
125
|
+
signature=signature,
|
|
126
|
+
body=converted_args
|
|
127
|
+
)
|
|
128
|
+
# 发送消息并等待回复
|
|
129
|
+
reply = await self.bus.call(call_msg)
|
|
130
|
+
# 检查是否有错误
|
|
131
|
+
if reply.message_type == MessageType.ERROR:
|
|
132
|
+
error_name = reply.error_name or 'UnknownError'
|
|
133
|
+
error_msg = reply.body[0] if reply.body else 'Unknown error'
|
|
134
|
+
raise DBusError(error_name, error_msg)
|
|
135
|
+
# 返回结果
|
|
136
|
+
# 如果只有一个返回值,直接返回;如果有多个,返回元组
|
|
137
|
+
if len(reply.body) == 0:
|
|
138
|
+
return None
|
|
139
|
+
elif len(reply.body) == 1:
|
|
140
|
+
return reply.body[0]
|
|
141
|
+
else:
|
|
142
|
+
return tuple(reply.body)
|
|
143
|
+
result = self._loop.run_until_complete(_call_method())
|
|
144
|
+
return result
|
|
145
|
+
except DBusError as e:
|
|
146
|
+
raise AssertionError(f"DBus Error: {e}") from e
|
|
147
|
+
except Exception as e:
|
|
148
|
+
raise AssertionError(f"Error: {e}") from e
|
|
149
|
+
|
|
150
|
+
def send_signal(self, object_path, interface_name, signal_name, *args):
|
|
151
|
+
"""发送D-Bus信号(自动生成签名)
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
object_path: 对象路径,例如 '/org/example/Object'
|
|
155
|
+
interface_name: 接口名称,例如 'org.example.Interface'
|
|
156
|
+
signal_name: 信号名称,例如 'SignalName'
|
|
157
|
+
*args: 信号的参数
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
None
|
|
161
|
+
"""
|
|
162
|
+
signature = ''
|
|
163
|
+
if args:
|
|
164
|
+
signature = ''.join([DBusSignature.get_dbus_signature(arg) for arg in args])
|
|
165
|
+
return self.send_signal_with_signature(object_path, interface_name, signal_name, signature, *args)
|
|
166
|
+
|
|
167
|
+
def send_signal_with_signature(self, object_path, interface_name, signal_name, signature, *args):
|
|
168
|
+
"""发送D-Bus信号(使用指定的签名)
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
object_path: 对象路径,例如 '/org/example/Object'
|
|
172
|
+
interface_name: 接口名称,例如 'org.example.Interface'
|
|
173
|
+
signal_name: 信号名称,例如 'SignalName'
|
|
174
|
+
signature: D-Bus签名字符串,例如 'sa{sv}as' 表示 (string, dict, array of string)
|
|
175
|
+
*args: 信号的参数,必须与签名匹配
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
None
|
|
179
|
+
|
|
180
|
+
Example:
|
|
181
|
+
# 发送一个包含字符串、字典和字符串数组的信号
|
|
182
|
+
dbus_lib.send_signal_with_signature(
|
|
183
|
+
'/org/example/Object',
|
|
184
|
+
'org.example.Interface',
|
|
185
|
+
'PropertiesChanged',
|
|
186
|
+
'sa{sv}as', # 签名:string, dict, array of string
|
|
187
|
+
'interface_name',
|
|
188
|
+
{'key': Variant('s', 'value')},
|
|
189
|
+
['item1', 'item2']
|
|
190
|
+
)
|
|
191
|
+
"""
|
|
192
|
+
try:
|
|
193
|
+
async def _send_signal():
|
|
194
|
+
# 创建信号消息,使用指定的签名
|
|
195
|
+
signal = Message(
|
|
196
|
+
destination='harbor.bmc.kepler.network_adapter',
|
|
197
|
+
message_type=MessageType.SIGNAL,
|
|
198
|
+
path=object_path,
|
|
199
|
+
interface=interface_name,
|
|
200
|
+
member=signal_name,
|
|
201
|
+
signature=signature,
|
|
202
|
+
body=list(args)
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
# 发送信号
|
|
206
|
+
await self.bus.send(signal)
|
|
207
|
+
logger.info(f"✅ 信号已发送: {interface_name}.{signal_name} 到 {object_path}, 参数: {args}, 签名: {signature}")
|
|
208
|
+
|
|
209
|
+
self._loop.run_until_complete(_send_signal())
|
|
210
|
+
|
|
211
|
+
except Exception as e:
|
|
212
|
+
raise AssertionError(f"发送信号失败: {e}") from e
|
|
213
|
+
|
|
214
|
+
def close(self):
|
|
215
|
+
"""关闭DBus连接"""
|
|
216
|
+
try:
|
|
217
|
+
if self.bus:
|
|
218
|
+
async def _disconnect():
|
|
219
|
+
self.bus.disconnect()
|
|
220
|
+
|
|
221
|
+
if self._loop and not self._loop.is_closed():
|
|
222
|
+
self._loop.run_until_complete(_disconnect())
|
|
223
|
+
logger.info("DBus连接已关闭")
|
|
224
|
+
except Exception as e:
|
|
225
|
+
logger.warning(f"关闭DBus连接时出错: {e}")
|
|
226
|
+
|
|
227
|
+
def _connect(self):
|
|
228
|
+
"""连接到DBus总线"""
|
|
229
|
+
try:
|
|
230
|
+
# 设置环境变量
|
|
231
|
+
dbus_session_bus_address = os.environ['DBUS_SESSION_BUS_ADDRESS']
|
|
232
|
+
if not dbus_session_bus_address:
|
|
233
|
+
raise AssertionError("DBus总线地址未设置")
|
|
234
|
+
logger.info(f"DBus总线地址: {dbus_session_bus_address}")
|
|
235
|
+
# 创建新的事件循环(如果当前线程没有)
|
|
236
|
+
try:
|
|
237
|
+
self._loop = asyncio.get_event_loop()
|
|
238
|
+
except RuntimeError:
|
|
239
|
+
self._loop = asyncio.new_event_loop()
|
|
240
|
+
asyncio.set_event_loop(self._loop)
|
|
241
|
+
# 同步方式连接(使用run_until_complete)
|
|
242
|
+
if self._loop.is_running():
|
|
243
|
+
# 如果循环已经在运行,使用异步方式
|
|
244
|
+
raise RuntimeError("Event loop is already running. Use async methods instead.")
|
|
245
|
+
else:
|
|
246
|
+
self.bus = self._loop.run_until_complete(MessageBus().connect())
|
|
247
|
+
logger.info(f"成功连接到DBus总线: {dbus_session_bus_address}")
|
|
248
|
+
except Exception as e:
|
|
249
|
+
raise AssertionError(f"DBus连接失败: {e}") from e
|
|
250
|
+
|