diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2640e9ee703646a287d88784f57f0b38fd4e7400
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1676253958656
+
+
+ 1676253958656
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/localCoverage/__init__.py b/localCoverage/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/localCoverage/all_subsystem_config.json b/localCoverage/all_subsystem_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..b4a228566a4544adc115b6bbecf4453300d42b29
--- /dev/null
+++ b/localCoverage/all_subsystem_config.json
@@ -0,0 +1,1238 @@
+{
+ "bundle_framework": {
+ "name": "bundle_framework",
+ "path": [
+ "foundation/bundlemanager/bundle_framework"
+ ]
+ },
+ "bundle_framework_lite": {
+ "name": "bundle_framework_lite",
+ "path": [
+ "foundation/bundlemanager/bundle_framework_lite"
+ ]
+ },
+ "packing_tool": {
+ "name": "packing_tool",
+ "path": [
+ "developtools/packing_tool"
+ ]
+ },
+ "appverify": {
+ "name": "appverify",
+ "path": [
+ "base/security/appverify"
+ ]
+ },
+ "zlib": {
+ "name": "zlib",
+ "path": [
+ "third_party/zlib"
+ ]
+ },
+ "ability_lite": {
+ "name": "ability_lite",
+ "path": [
+ "foundation/ability/ability_lite"
+ ]
+ },
+ "ability_base": {
+ "name": "ability_base",
+ "path": [
+ "foundation/ability/ability_base"
+ ]
+ },
+ "ability_runtime": {
+ "name": "ability_runtime",
+ "path": [
+ "foundation/ability/ability_runtime"
+ ]
+ },
+ "ability_tool": {
+ "name": "ability_tool",
+ "path": [
+ "foundation/ability/ability_runtime/tools"
+ ]
+ },
+ "idl_tool": {
+ "name": "idl_tool",
+ "path": [
+ "foundation/ability/idl_tool"
+ ]
+ },
+ "form_fwk": {
+ "name": "form_fwk",
+ "path": [
+ "foundation/ability/form_fwk"
+ ]
+ },
+ "wms": {
+ "name": "wms",
+ "path": [
+ "foundation/graphic/wms"
+ ]
+ },
+ "ui": {
+ "name": "ui",
+ "path": [
+ "foundation/graphic/ui"
+ ]
+ },
+ "graphic_utils": {
+ "name": "graphic_utils",
+ "path": [
+ "foundation/graphic/utils"
+ ]
+ },
+ "graphic_2d": {
+ "name": "graphic_2d",
+ "path": [
+ "foundation/graphic/graphic_2d"
+ ]
+ },
+ "multimedia_image_framework": {
+ "name": "multimedia_image_framework",
+ "path": [
+ "foundation/multimedia/image_framework"
+ ]
+ },
+ "background_task_mgr": {
+ "name": "background_task_mgr",
+ "path": [
+ "foundation/resourceschedule/background_task_mgr"
+ ]
+ },
+ "work_scheduler": {
+ "name": "work_scheduler",
+ "path": [
+ "foundation/resourceschedule/work_scheduler"
+ ]
+ },
+ "device_usage_statistics": {
+ "name": "device_usage_statistics",
+ "path": [
+ "foundation/resourceschedule/device_usage_statistics"
+ ]
+ },
+ "resource_schedule_service": {
+ "name": "resource_schedule_service",
+ "path": [
+ "foundation/resourceschedule/resource_schedule_service"
+ ]
+ },
+ "schedule_ext": {
+ "name": "schedule_ext",
+ "path": [
+ "foundation/resourceschedule/resource_schedule_service/schedule_ext"
+ ]
+ },
+ "efficiency_manager": {
+ "name": "efficiency_manager",
+ "path": [
+ "foundation/resourceschedule/efficiency_manager"
+ ]
+ },
+ "efficiency_manager_ext": {
+ "name": "efficiency_manager_ext",
+ "path": [
+ "foundation/resourceschedule/efficiency_manager_ext"
+ ]
+ },
+ "preferences": {
+ "name": "preferences",
+ "path": [
+ "foundation/distributeddatamgr/preferences"
+ ]
+ },
+ "relational_store": {
+ "name": "relational_store",
+ "path": [
+ "foundation/distributeddatamgr/relational_store"
+ ]
+ },
+ "data_share": {
+ "name": "data_share",
+ "path": [
+ "foundation/distributeddatamgr/data_share"
+ ]
+ },
+ "kv_store": {
+ "name": "kv_store",
+ "path": [
+ "foundation/distributeddatamgr/kv_store"
+ ]
+ },
+ "datamgr_service": {
+ "name": "datamgr_service",
+ "path": [
+ "foundation/distributeddatamgr/distributeddatamgr"
+ ]
+ },
+ "data_object": {
+ "name": "data_object",
+ "path": [
+ "foundation/distributeddatamgr/data_object"
+ ]
+ },
+ "pasteboard": {
+ "name": "pasteboard",
+ "path": [
+ "foundation/distributeddatamgr/pasteboard"
+ ]
+ },
+ "ipc": {
+ "name": "ipc",
+ "path": [
+ "foundation/communication/ipc"
+ ]
+ },
+ "dsoftbus_standard": {
+ "name": "dsoftbus_standard",
+ "path": [
+ "foundation/communication/dsoftbus"
+ ]
+ },
+ "device_manager": {
+ "name": "device_manager",
+ "path": [
+ "foundation/distributedhardware/device_manager"
+ ]
+ },
+ "distributed_hardware_fwk": {
+ "name": "distributed_hardware_fwk",
+ "path": [
+ "foundation/distributedhardware/distributed_hardware_fwk"
+ ]
+ },
+ "distributed_camera": {
+ "name": "distributed_camera",
+ "path": [
+ "foundation/distributedhardware/distributed_camera"
+ ]
+ },
+ "distributed_audio": {
+ "name": "distributed_audio",
+ "path": [
+ "foundation/distributedhardware/distributed_audio"
+ ]
+ },
+ "distributed_screen": {
+ "name": "distributed_screen",
+ "path": [
+ "foundation/distributedhardware/distributed_screen"
+ ]
+ },
+ "distributed_input": {
+ "name": "distributed_input",
+ "path": [
+ "foundation/distributedhardware/distributed_input"
+ ]
+ },
+ "input": {
+ "name": "input",
+ "path": [
+ "foundation/multimodalinput/input"
+ ]
+ },
+ "multimedia_audio_framework": {
+ "name": "multimedia_audio_framework",
+ "path": [
+ "foundation/multimedia/audio_framework"
+ ]
+ },
+ "audio_manager_lite": {
+ "name": "audio_manager_lite",
+ "path": [
+ "foundation/multimedia/audio_lite"
+ ]
+ },
+ "camera_lite": {
+ "name": "camera_lite",
+ "path": [
+ "foundation/multimedia/camera_lite"
+ ]
+ },
+ "camera_framework": {
+ "name": "camera_framework",
+ "path": [
+ "foundation/multimedia/camera_standard"
+ ]
+ },
+ "media_lite": {
+ "name": "media_lite",
+ "path": [
+ "foundation/multimedia/media_lite"
+ ]
+ },
+ "multimedia_av_session": {
+ "name": "multimedia_av_session",
+ "path": [
+ "foundation/multimedia/av_session"
+ ]
+ },
+ "utils": {
+ "name": "utils",
+ "path": [
+ "foundation/multimedia/utils"
+ ]
+ },
+ "omx_adapter": {
+ "name": "omx_adapter",
+ "path": [
+ "foundation/multimedia/omx_adapter"
+ ]
+ },
+ "multimedia_histreamer": {
+ "name": "multimedia_histreamer",
+ "path": [
+ "foundation/multimedia/histreamer"
+ ]
+ },
+ "multimedia_player_framework": {
+ "name": "multimedia_player_framework",
+ "path": [
+ "foundation/multimedia/player_framework"
+ ]
+ },
+ "neural_network_runtime": {
+ "name": "neural_network_runtime",
+ "path": [
+ "foundation/ai/neural_network_runtime"
+ ]
+ },
+ "ai_engine": {
+ "name": "ai_engine",
+ "path": [
+ "foundation/ai/ai_engine"
+ ]
+ },
+ "decision": {
+ "name": "decision",
+ "path": [
+ "foundation/ai/decision"
+ ]
+ },
+ "mindspore": {
+ "name": "mindspore",
+ "path": [
+ "third_party/mindspore"
+ ]
+ },
+ "core_service": {
+ "name": "core_service",
+ "path": [
+ "base/telephony/core_service"
+ ]
+ },
+ "call_manager": {
+ "name": "call_manager",
+ "path": [
+ "base/telephony/call_manager"
+ ]
+ },
+ "data_storage": {
+ "name": "data_storage",
+ "path": [
+ "base/telephony/data_storage"
+ ]
+ },
+ "sms_mms": {
+ "name": "sms_mms",
+ "path": [
+ "base/telephony/sms_mms"
+ ]
+ },
+ "cellular_call": {
+ "name": "cellular_call",
+ "path": [
+ "base/telephony/cellular_call"
+ ]
+ },
+ "cellular_data": {
+ "name": "cellular_data",
+ "path": [
+ "base/telephony/cellular_data"
+ ]
+ },
+ "state_registry": {
+ "name": "state_registry",
+ "path": [
+ "base/telephony/state_registry"
+ ]
+ },
+ "ril_adapter": {
+ "name": "ril_adapter",
+ "path": [
+ "base/telephony/ril_adapter"
+ ]
+ },
+ "ims_service": {
+ "name": "ims_service",
+ "path": [
+ "vendor/huawei/base/telephony/ims_service"
+ ]
+ },
+ "ril_adapter_ext": {
+ "name": "ril_adapter_ext",
+ "path": [
+ "vendor/huawei/base/telephony/ril_adapter_ext"
+ ]
+ },
+ "certificate_manager": {
+ "name": "certificate_manager",
+ "path": [
+ "base/security/certificate_manager"
+ ]
+ },
+ "crypto_framework": {
+ "name": "crypto_framework",
+ "path": [
+ "base/security/crypto_framework"
+ ]
+ },
+ "dataclassification": {
+ "name": "dataclassification",
+ "path": [
+ "base/security/dataclassification"
+ ]
+ },
+ "device_auth": {
+ "name": "device_auth",
+ "path": [
+ "base/security/device_auth"
+ ]
+ },
+ "device_security_level": {
+ "name": "device_security_level",
+ "path": [
+ "base/security/device_security_level"
+ ]
+ },
+ "device_threat_detection": {
+ "name": "device_threat_detection",
+ "path": [
+ "base/security/device_threat_detection"
+ ]
+ },
+ "hapsigner": {
+ "name": "hapsigner",
+ "path": [
+ "developtools/hapsigner"
+ ]
+ },
+ "huks": {
+ "name": "huks",
+ "path": [
+ "base/security/huks"
+ ]
+ },
+ "appspawn": {
+ "name": "appspawn",
+ "path": [
+ "base/startup/appspawn"
+ ]
+ },
+ "bootstrap_lite": {
+ "name": "bootstrap_lite",
+ "path": [
+ "base/startup/bootstrap_lite"
+ ]
+ },
+ "init": {
+ "name": "init",
+ "path": [
+ "base/startup/init"
+ ]
+ },
+ "notification": {
+ "name": "notification",
+ "path": [
+ "base/notification/common_event_service",
+ "base/notification/distributed_notification_service",
+ "base/notification/eventhandler"
+ ]
+ },
+ "hilog": {
+ "name": "hilog",
+ "path": [
+ "base/hiviewdfx/hilog"
+ ]
+ },
+ "hilog_lite": {
+ "name": "hilog_lite",
+ "path": [
+ "base/hiviewdfx/hilog_lite"
+ ]
+ },
+ "hitrace": {
+ "name": "hitrace",
+ "path": [
+ "base/hiviewdfx/hitrace"
+ ]
+ },
+ "hiview": {
+ "name": "hiview",
+ "path": [
+ "base/hiviewdfx/hiview/adapter",
+ "base/hiviewdfx/hiview/build",
+ "base/hiviewdfx/hiview/base",
+ "base/hiviewdfx/hiview/core",
+ "base/hiviewdfx/hiview/figures",
+ "base/hiviewdfx/hiview/include",
+ "base/hiviewdfx/hiview/service",
+ "base/hiviewdfx/hiview/utility",
+ "base/hiviewdfx/hiview/test",
+ "base/hiviewdfx/hiview/plugins/eventlogger",
+ "base/hiviewdfx/hiview/plugins/eventservice",
+ "base/hiviewdfx/hiview/plugins/faultlogger",
+ "base/hiviewdfx/hiview/plugins/freeze_detector",
+ "base/hiviewdfx/hiview/plugins/hicollie_collector",
+ "base/hiviewdfx/hiview/plugins/usage_event_report",
+ "base/hiviewdfx/hiview/plugins/huawei_proprietary/leak_detectors",
+ "base/hiviewdfx/hiview/plugins/huawei_proprietary/test"
+ ]
+ },
+ "hiview_lite": {
+ "name": "hiview_lite",
+ "path": [
+ "base/hiviewdfx/hiview_lite"
+ ]
+ },
+ "hichecker": {
+ "name": "hichecker",
+ "path": [
+ "base/hiviewdfx/hichecker"
+ ]
+ },
+ "hicollie": {
+ "name": "hicollie",
+ "path": [
+ "base/hiviewdfx/hicollie"
+ ]
+ },
+ "hiappevent": {
+ "name": "hiappevent",
+ "path": [
+ "base/hiviewdfx/hiappevent"
+ ]
+ },
+ "hisysevent": {
+ "name": "hisysevent",
+ "path": [
+ "base/hiviewdfx/hisysevent"
+ ]
+ },
+ "hievent_lite": {
+ "name": "hievent_lite",
+ "path": [
+ "base/hiviewdfx/hievent_lite"
+ ]
+ },
+ "faultloggerd": {
+ "name": "faultloggerd",
+ "path": [
+ "base/hiviewdfx/faultloggerd"
+ ]
+ },
+ "profiler": {
+ "name": "profiler",
+ "path": [
+ "developtools/profiler"
+ ]
+ },
+ "hiperf": {
+ "name": "hiperf",
+ "path": [
+ "developtools/hiperf"
+ ]
+ },
+ "bytrace": {
+ "name": "bytrace",
+ "path": [
+ "developtools/bytrace"
+ ]
+ },
+ "hidumper_lite": {
+ "name": "hidumper_lite",
+ "path": [
+ "base/hiviewdfx/hidumper_lite"
+ ]
+ },
+ "blackbox": {
+ "name": "blackbox",
+ "path": [
+ "base/hiviewdfx/blackbox"
+ ]
+ },
+ "hidumper": {
+ "name": "hidumper",
+ "path": [
+ "base/hiviewdfx/hidumper"
+ ]
+ },
+ "bluetooth": {
+ "name": "bluetooth",
+ "path": [
+ "foundation/communication/bluetooth"
+ ]
+ },
+ "nfc": {
+ "name": "nfc",
+ "path": [
+ "foundation/communication/nfc/nfc_core"
+ ]
+ },
+ "connected_tag": {
+ "name": "connected_tag",
+ "path": [
+ "foundation/communication/nfc/connected_tag"
+ ]
+ },
+ "wifi": {
+ "name": "wifi",
+ "path": [
+ "foundation/communication/wifi/wifi"
+ ]
+ },
+ "dhcp": {
+ "name": "dhcp",
+ "path": [
+ "foundation/communication/wifi/dhcp"
+ ]
+ },
+ "wifi_aware": {
+ "name": "wifi_aware",
+ "path": [
+ "foundation/communication/wifi_aware"
+ ]
+ },
+ "wifi_lite": {
+ "name": "wifi_lite",
+ "path": [
+ "foundation/communication/wifi_lite"
+ ]
+ },
+ "algorithm": {
+ "name": "algorithm",
+ "path": [
+ "base/msdp/algorithm"
+ ]
+ },
+ "geofence": {
+ "name": "geofence",
+ "path": [
+ "base/msdp/geofence"
+ ]
+ },
+ "motion": {
+ "name": "motion",
+ "path": [
+ "base/msdp/motion"
+ ]
+ },
+ "movement": {
+ "name": "movement",
+ "path": [
+ "base/msdp/movement"
+ ]
+ },
+ "spatial_awareness": {
+ "name": "spatial_awareness",
+ "path": [
+ "base/msdp/spatial_awareness"
+ ]
+ },
+ "timeline": {
+ "name": "timeline",
+ "path": [
+ "base/msdp/timeline"
+ ]
+ },
+ "device_status": {
+ "name": "device_status",
+ "path": [
+ "base/msdp/device_status"
+ ]
+ },
+ "os_account": {
+ "name": "os_account",
+ "path": [
+ "base/account/os_account"
+ ]
+ },
+ "i18n": {
+ "name": "i18n",
+ "path": [
+ "base/global/i18n"
+ ]
+ },
+ "i18n_lite": {
+ "name": "i18n_lite",
+ "path": [
+ "base/global/i18n_lite"
+ ]
+ },
+ "system_resources": {
+ "name": "system_resources",
+ "path": [
+ "utils/system_resources"
+ ]
+ },
+ "jsoncpp": {
+ "name": "jsoncpp",
+ "path": [
+ "third_party/jsoncpp"
+ ]
+ },
+ "libxml2": {
+ "name": "libxml2",
+ "path": [
+ "third_party/libxml2"
+ ]
+ },
+ "global_resource_tool": {
+ "name": "global_resource_tool",
+ "path": [
+ "developtools/global_resource_tool"
+ ]
+ },
+ "resource_management": {
+ "name": "resource_management",
+ "path": [
+ "base/global/resource_management"
+ ]
+ },
+ "resource_management_lite": {
+ "name": "resource_management_lite",
+ "path": [
+ "base/global/resource_management_lite"
+ ]
+ },
+ "time_zone": {
+ "name": "time_zone",
+ "path": [
+ "base/global/time_zone"
+ ]
+ },
+ "accessibility": {
+ "name": "accessibility",
+ "path": [
+ "foundation/barrierfree/accessibility"
+ ]
+ },
+ "time_service": {
+ "name": "time_service",
+ "path": [
+ "base/time/time_service"
+ ]
+ },
+ "imf": {
+ "name": "imf",
+ "path": [
+ "base/inputmethod/imf"
+ ]
+ },
+ "theme": {
+ "name": "theme",
+ "path": [
+ "base/theme"
+ ]
+ },
+ "request": {
+ "name": "request",
+ "path": [
+ "base/request"
+ ]
+ },
+ "battery_manager": {
+ "name": "battery_manager",
+ "path": [
+ "base/powermgr/battery_manager"
+ ]
+ },
+ "display_manager": {
+ "name": "display_manager",
+ "path": [
+ "base/powermgr/display_manager"
+ ]
+ },
+ "powermgr_lite": {
+ "name": "powermgr_lite",
+ "path": [
+ "base/powermgr/powermgr_lite"
+ ]
+ },
+ "battery_lite": {
+ "name": "battery_lite",
+ "path": [
+ "base/powermgr/battery_lite"
+ ]
+ },
+ "battery_statistics": {
+ "name": "battery_statistics",
+ "path": [
+ "base/powermgr/battery_statistics"
+ ]
+ },
+ "power_manager": {
+ "name": "power_manager",
+ "path": [
+ "base/powermgr/power_manager"
+ ]
+ },
+ "thermal_manager": {
+ "name": "thermal_manager",
+ "path": [
+ "base/powermgr/thermal_manager"
+ ]
+ },
+ "sensor": {
+ "name": "sensor",
+ "path": [
+ "base/sensors/sensor"
+ ]
+ },
+ "miscdevice": {
+ "name": "miscdevice",
+ "path": [
+ "base/sensors/miscdevice"
+ ]
+ },
+ "sensor_lite": {
+ "name": "sensor_lite",
+ "path": [
+ "base/sensors/sensor_lite"
+ ]
+ },
+ "miscdevice_lite": {
+ "name": "miscdevice_lite",
+ "path": [
+ "base/sensors/miscdevice_lite"
+ ]
+ },
+ "start": {
+ "name": "start",
+ "path": [
+ "base/sensors/start"
+ ]
+ },
+ "user_auth_framework": {
+ "name": "user_auth_framework",
+ "path": [
+ "base/useriam/user_auth_framework"
+ ]
+ },
+ "pin_auth": {
+ "name": "pin_auth",
+ "path": [
+ "base/useriam/pin_auth"
+ ]
+ },
+ "face_auth": {
+ "name": "face_auth",
+ "path": [
+ "base/useriam/face_auth"
+ ]
+ },
+ "fingerprint_auth": {
+ "name": "fingerprint_auth",
+ "path": [
+ "base/useriam/fingerprint_auth"
+ ]
+ },
+ "peripheral": {
+ "name": "peripheral",
+ "path": [
+ "drivers/peripheral/pin_auth",
+ "drivers/peripheral/face_auth",
+ "drivers/peripheral/user_auth",
+ "drivers/peripheral/fingerprint_auth"
+ ]
+ },
+ "location": {
+ "name": "location",
+ "path": [
+ "base/location"
+ ]
+ },
+ "usb_manager": {
+ "name": "usb_manager",
+ "path": [
+ "base/usb/usb_manager"
+ ]
+ },
+ "build": {
+ "name": "build",
+ "path": [
+ "build"
+ ]
+ },
+ "gn": {
+ "name": "gn",
+ "path": [
+ "third_party/gn"
+ ]
+ },
+ "ninja": {
+ "name": "ninja",
+ "path": [
+ "third_party/ninja"
+ ]
+ },
+ "hidl_adapter": {
+ "name": "hidl_adapter",
+ "path": [
+ "drivers/peripheral/adapter/activity_recognition",
+ "drivers/peripheral/adapter/audio",
+ "drivers/peripheral/adapter/camera",
+ "drivers/peripheral/adapter/gralloc",
+ "drivers/peripheral/adapter/hwc",
+ "drivers/peripheral/adapter/input",
+ "drivers/peripheral/adapter/motion",
+ "drivers/peripheral/adapter/sensor",
+ "drivers/peripheral/adapter/thermal"
+ ]
+ },
+ "hdf_core": {
+ "name": "hdf_core",
+ "path": [
+ "drivers/hdf_core/adapter/uhdf2",
+ "drivers/hdf_core/framework/core/common",
+ "drivers/hdf_core/framework/core/host",
+ "drivers/hdf_core/framework/core/manager",
+ "drivers/hdf_core/framework/core/shared",
+ "drivers/hdf_core/framework/support/posix/"
+ ]
+ },
+ "filemanagement_app_file_service": {
+ "name": "filemanagement_app_file_service",
+ "path": [
+ "foundation/filemanagement/app_file_service"
+ ]
+ },
+ "filemanagement_backup": {
+ "name": "filemanagement_backup",
+ "path": [
+ "foundation/filemanagement/backup"
+ ]
+ },
+ "filemanagement_dfs_service": {
+ "name": "filemanagement_dfs_service",
+ "path": [
+ "foundation/filemanagement/dfs_service"
+ ]
+ },
+ "filemanagement_file_api": {
+ "name": "filemanagement_file_api",
+ "path": [
+ "foundation/filemanagement/file_api"
+ ]
+ },
+ "filemanagement_storage_service": {
+ "name": "filemanagement_storage_service",
+ "path": [
+ "foundation/filemanagement/storage_service"
+ ]
+ },
+ "filemanagement_user_file_service": {
+ "name": "filemanagement_user_file_service",
+ "path": [
+ "foundation/filemanagement/user_file_service"
+ ]
+ },
+ "media_library": {
+ "name": "media_library",
+ "path": [
+ "foundation/multimedia/media_library"
+ ]
+ },
+ "netmanager_base": {
+ "name": "netmanager_base",
+ "path": [
+ "foundation/communication/netmanager_base"
+ ]
+ },
+ "netmanager_ext": {
+ "name": "netmanager_ext",
+ "path": [
+ "foundation/communication/netmanager_ext"
+ ]
+ },
+ "netstack": {
+ "name": "netstack",
+ "path": [
+ "foundation/communication/netstack"
+ ]
+ },
+ "webview": {
+ "name": "webview",
+ "path": [
+ "base/web/webview/ohos_adapter",
+ "base/web/webview/ohos_nweb"
+ ]
+ },
+ "tee_client": {
+ "name": "tee_client",
+ "path": [
+ "base/tee/tee_client"
+ ]
+ },
+ "tee_os_framework": {
+ "name": "tee_os_framework",
+ "path": [
+ "base/tee/tee_os_framework"
+ ]
+ },
+ "tee_dev_kit": {
+ "name": "tee_dev_kit",
+ "path": [
+ "base/tee/tee_dev_kit"
+ ]
+ },
+ "tee_tzdriver": {
+ "name": "tee_tzdriver",
+ "path": [
+ "base/tee/tee_tzdriver"
+ ]
+ },
+ "tee_os_kernel": {
+ "name": "tee_os_kernel",
+ "path": [
+ "base/tee/tee_os_kernel"
+ ]
+ },
+ "device_info_manager": {
+ "name": "device_info_manager",
+ "path": [
+ "foundation/deviceprofile"
+ ]
+ },
+ "enterprise_device_management": {
+ "name": "enterprise_device_management",
+ "path": [
+ "base/customization/enterprise_device_management"
+ ]
+ },
+ "config_policy": {
+ "name": "config_policy",
+ "path": [
+ "base/customization/config_policy"
+ ]
+ },
+ "toolchain": {
+ "name": "toolchain",
+ "path": [
+ "arkcompiler/toolchain"
+ ]
+ },
+ "runtime_core": {
+ "name": "runtime_core",
+ "path": [
+ "arkcompiler/runtime_core"
+ ]
+ },
+ "ets_frontend": {
+ "name": "ets_frontend",
+ "path": [
+ "arkcompiler/ets_frontend"
+ ]
+ },
+ "ets_runtime": {
+ "name": "ets_runtime",
+ "path": [
+ "arkcompiler/ets_runtime"
+ ]
+ },
+ "jerryscript": {
+ "name": "jerryscript",
+ "path": [
+ "third_party/jerryscript"
+ ]
+ },
+ "safwk": {
+ "name": "safwk",
+ "path": [
+ "foundation/systemabilitymgr/safwk"
+ ]
+ },
+ "safwk_lite": {
+ "name": "safwk_lite",
+ "path": [
+ "foundation/systemabilitymgr/safwk_lite"
+ ]
+ },
+ "samgr_lite": {
+ "name": "samgr_lite",
+ "path": [
+ "foundation/systemabilitymgr/samgr_lite"
+ ]
+ },
+ "samgr": {
+ "name": "samgr",
+ "path": [
+ "foundation/systemabilitymgr/samgr"
+ ]
+ },
+ "dmsfwk": {
+ "name": "dmsfwk",
+ "path": [
+ "foundation/ability/dmsfwk"
+ ]
+ },
+ "dmsfwk_lite": {
+ "name": "dmsfwk_lite",
+ "path": [
+ "foundation/ability/dmsfwk_lite"
+ ]
+ },
+ "window": {
+ "name": "window",
+ "path": [
+ "foundation/window/window_manager"
+ ]
+ },
+ "utils_lite": {
+ "name": "utils_lite",
+ "path": [
+ "commonlibrary/utils_lite"
+ ]
+ },
+ "c_utils": {
+ "name": "c_utils",
+ "path": [
+ "commonlibrary/c_utils"
+ ]
+ },
+ "ets_utils": {
+ "name": "ets_utils",
+ "path": [
+ "commonlibrary/ets_utils"
+ ]
+ },
+ "selinux": {
+ "name": "selinux",
+ "path": [
+ "base/security/selinux"
+ ]
+ },
+ "access_token": {
+ "name": "access_token",
+ "path": [
+ "base/security/access_token"
+ ]
+ },
+ "permission_lite": {
+ "name": "permission_lite",
+ "path": [
+ "base/security/permission_lite"
+ ]
+ },
+ "dlp_permission_service": {
+ "name": "dlp_permission_service",
+ "path": [
+ "base/security/dlp_permission_service"
+ ]
+ },
+ "dlp_credential_service": {
+ "name": "dlp_credential_service",
+ "path": [
+ "base/security/dlp_credential_service"
+ ]
+ },
+ "memmgr": {
+ "name": "memmgr",
+ "path": [
+ "foundation/resourceschedule/memmgr_plugin"
+ ]
+ },
+ "utils_memory": {
+ "name": "utils_memory",
+ "path": [
+ "utils/memory"
+ ]
+ },
+ "frame_aware_sched": {
+ "name": "frame_aware_sched",
+ "path": [
+ "foundation/resourceschedule/frame_aware_sched"
+ ]
+ },
+ "sys_installer": {
+ "name": "sys_installer",
+ "path": [
+ "base/update/sys_installer"
+ ]
+ },
+ "updater": {
+ "name": "updater",
+ "path": [
+ "base/update/updater"
+ ]
+ },
+ "dupdate_engine": {
+ "name": "dupdate_engine",
+ "path": [
+ "base/update/dupdate_engine"
+ ]
+ },
+ "memory_utils": {
+ "name": "memory_utils",
+ "path": [
+ "commonlibrary/memory_utils"
+ ]
+ },
+ "resourceschedule_ffrt_core": {
+ "name": "resourceschedule_ffrt_core",
+ "path": [
+ "foundation/resourceschedule/ffrt_core"
+ ]
+ },
+ "resourceschedule_ffrt_sched_override": {
+ "name": "resourceschedule_ffrt_sched_override",
+ "path": [
+ "vendor/huawei/foundation/resourceschedule/ffrt_sched_override"
+ ]
+ },
+ "ace_engine": {
+ "name": "ace_engine",
+ "path": [
+ "foundation/arkui/ace_engine/frameworks/base/geometry",
+ "foundation/arkui/ace_engine/frameworks/base/json",
+ "foundation/arkui/ace_engine/frameworks/base/utils",
+ "foundation/arkui/ace_engine/frameworks/bridge/card_frontend",
+ "foundation/arkui/ace_engine/frameworks/bridge/common/manifest",
+ "foundation/arkui/ace_engine/frameworks/bridge/common/media_query",
+ "foundation/arkui/ace_engine/frameworks/bridge/common/plugin_adapter",
+ "foundation/arkui/ace_engine/frameworks/bridge/common/utils",
+ "foundation/arkui/ace_engine/frameworks/bridge/plugin_frontend",
+ "foundation/arkui/ace_engine/interfaces"
+ ]
+ },
+ "ace_engine_core": {
+ "name": "ace_engine_core",
+ "path": [
+ "foundation/arkui/ace_engine/frameworks/core/accessibility",
+ "foundation/arkui/ace_engine/frameworks/core/common",
+ "foundation/arkui/ace_engine/frameworks/core/components_ng",
+ "foundation/arkui/ace_engine/frameworks/core/pipeline_ng"
+ ]
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/localCoverage/codeCoverage/__init__.py b/localCoverage/codeCoverage/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/localCoverage/codeCoverage/codeCoverage_gcov_lcov.py b/localCoverage/codeCoverage/codeCoverage_gcov_lcov.py
new file mode 100644
index 0000000000000000000000000000000000000000..e70b144586c7f3857f4a0ba44ba2b39cb49bf128
--- /dev/null
+++ b/localCoverage/codeCoverage/codeCoverage_gcov_lcov.py
@@ -0,0 +1,288 @@
+#!/usr/bin/env python3
+# coding=utf-8
+
+#
+# Copyright (c) 2023 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+import os
+import json
+import shutil
+import shlex
+import subprocess
+
+
+# 代码根目录
+root_path = os.getcwd()
+CODEPATH = root_path.split("/test/testfwk/developer_test")[0]
+# 子系统json目录
+SYSTEM_JSON = "build/subsystem_config.json"
+# 覆盖率gcda
+COVERAGE_GCDA_RESULTS = "test/localCoverage/codeCoverage/results/coverage/data/cxx"
+# 报告路径
+REPORT_PATH = "test/localCoverage/codeCoverage/results/coverage/reports/cxx"
+# llvm-gcov.sh
+LLVM_GCOV = "test/localCoverage/codeCoverage/llvm-gcov.sh"
+# 编译生成的out路径
+OUTPUT = "out/baltimore"
+# 屏蔽列表
+FILTEROUT_DIRS = ["unittest", "third_party", "test"]
+
+
+def call(cmd_list, is_show_cmd=False, out=None, err=None):
+ return_flag = False
+ try:
+ if is_show_cmd:
+ print("execute command: {}".format(" ".join(cmd_list)))
+ if 0 == subprocess.call(cmd_list, shell=False, stdout=out, stderr=err):
+ return_flag = True
+ except Exception:
+ print("Error : command {} execute faild!".format(cmd_list))
+ return_flag = False
+ return return_flag
+
+
+def execute_command(command, printflag=False):
+ try:
+ cmd_list = shlex.split(command)
+ with open("coverage.log", 'a') as fd:
+ call(cmd_list, printflag, fd, fd)
+ except IOError as err:
+ print("Error: Exception occur in open: %s", err.message)
+
+
+def get_subsystem_config_info():
+ subsystem_info_dic = {}
+ subsystem_config_filepath = os.path.join(CODEPATH, SYSTEM_JSON)
+ if os.path.exists(subsystem_config_filepath):
+ data = None
+ with open(subsystem_config_filepath, 'r') as f:
+ data = json.load(f)
+ if not data:
+ print("subsystem config file error.")
+ for value in data.values():
+ subsystem_name = value.get('name')
+ subsystem_dir = value.get('dir')
+ subsystem_path = value.get('path')
+ subsystem_project = value.get('project')
+ subsystem_rootpath = os.path.join(CODEPATH, subsystem_path)
+ subsystem_info_dic[subsystem_name] = [
+ subsystem_project, subsystem_dir,
+ subsystem_path, subsystem_rootpath
+ ]
+ return subsystem_info_dic
+
+
+def get_subsystem_name_list():
+ subsystem_name_list = []
+ subsystem_info_dic = get_subsystem_config_info()
+ for key in subsystem_info_dic.keys():
+ subsystem_rootpath = subsystem_info_dic[key][3]
+ if os.path.exists(subsystem_rootpath):
+ subsystem_name_list.append(key)
+ return subsystem_name_list
+
+
+def get_subsystem_rootpath(subsystem_name):
+ subsystem_path = ""
+ subsystem_rootpath = ""
+ subsystem_info_dic = get_subsystem_config_info()
+ for key in subsystem_info_dic.keys():
+ if key == subsystem_name:
+ subsystem_path = subsystem_info_dic[key][2]
+ subsystem_rootpath = subsystem_info_dic[key][3]
+ break
+ return subsystem_path, subsystem_rootpath
+
+
+def is_filterout_dir(ignore_prefix, check_path):
+ for dir in FILTEROUT_DIRS:
+ check_list = check_path[len(ignore_prefix):].split("/")
+ if dir in check_list:
+ return True
+ return False
+
+
+def rm_unnecessary_dir(cov_path):
+ topdir = os.path.join(cov_path, "obj")
+ for root, dirs, files in os.walk(topdir):
+ if is_filterout_dir(topdir, root):
+ shutil.rmtree(root)
+
+
+def get_files_from_dir(find_path, postfix=None):
+ names = os.listdir(find_path)
+ file_list = []
+ for fn in names:
+ if not os.path.isfile(os.path.join(find_path, fn)):
+ continue
+ if postfix is not None:
+ if fn.endswith(postfix):
+ file_list.append(fn)
+ else:
+ file_list.append(fn)
+ return file_list
+
+
+def get_gcno_files(cov_path, dir_name):
+ gcda_strip_path = dir_name[len(cov_path) + 1:]
+ gcda_list = get_files_from_dir(dir_name, ".gcda")
+ for file_name in gcda_list:
+ gcno_name = os.path.splitext(file_name)[0] + ".gcno"
+ gcno_path = os.path.join(os.path.join(CODEPATH, OUTPUT),
+ gcda_strip_path, gcno_name)
+ if os.path.exists(gcno_path):
+ if os.path.exists(gcno_path):
+ shutil.copy(gcno_path, dir_name)
+ else:
+ print("%s not exists!", gcno_path)
+
+
+def get_module_gcno_files(cov_path, dir_name):
+ for root, dirs, files in os.walk(dir_name):
+ get_gcno_files(cov_path, root)
+
+
+def gen_subsystem_trace_info(subsystem, data_dir, test_dir):
+ src_dir = os.path.join(CODEPATH, OUTPUT)
+ single_info_path = os.path.join(CODEPATH, REPORT_PATH,
+ "single_test", test_dir)
+ if not os.path.exists(single_info_path):
+ os.makedirs(single_info_path)
+ output_name = os.path.join(CODEPATH, single_info_path,
+ subsystem +"_output.info")
+ if not os.path.exists(src_dir):
+ print("Sours path %s not exist!", src_dir)
+ return
+ cmd = "lcov -c -b {} -d {} --gcov-tool {} -o {} --ignore-errors source,gcov" \
+ .format(src_dir, data_dir, os.path.join(
+ CODEPATH, LLVM_GCOV), output_name)
+ print("single_test**" + cmd)
+ execute_command(cmd)
+
+
+def cut_info(subsystem, test_dir):
+ trace_file = os.path.join(
+ CODEPATH, REPORT_PATH, "single_test",
+ test_dir, subsystem + "_output.info")
+ output_name = os.path.join(
+ CODEPATH, REPORT_PATH, "single_test",
+ test_dir, subsystem + "_strip.info")
+ remove = r"'*/unittest/*' '*/third_party/*' 'sdk/android-arm64/*'"
+ if not os.path.exists(trace_file):
+ print("Error: trace file %s not exisit!", trace_file)
+ return
+ cmd = "lcov --remove {} {} -o {}".format(trace_file, remove, output_name)
+ execute_command(cmd)
+
+
+def gen_info(cov_path, test_dir, subsystem_list):
+ if len(subsystem_list) == 0:
+ return
+ for subsystem in subsystem_list:
+ (subsystem_path, subsystem_rootpath) = get_subsystem_rootpath(subsystem)
+ subsystem_data_abspath = os.path.join(cov_path, "obj", subsystem_path)
+ if not os.path.exists(subsystem_data_abspath):
+ continue
+ get_module_gcno_files(cov_path, subsystem_data_abspath)
+ gen_subsystem_trace_info(subsystem, subsystem_data_abspath, test_dir)
+ cut_info(subsystem, test_dir)
+
+
+def gen_all_test_info(subsystem_list=[]):
+ cov_path = os.path.join(CODEPATH, COVERAGE_GCDA_RESULTS)
+ single_test_dir_list = []
+ for root, dirs, files in os.walk(cov_path):
+ single_test_dir_list = dirs
+ break
+ for index, cur_test_dir in enumerate(single_test_dir_list):
+ cur_test_abs_dir = os.path.join(cov_path, cur_test_dir)
+ rm_unnecessary_dir(cur_test_abs_dir)
+ gen_info(cur_test_abs_dir, cur_test_dir, subsystem_list)
+
+
+def merge_subsystem_info_from_all_test(subsystem):
+ single_test_info_path = os.path.join(CODEPATH, REPORT_PATH, "single_test")
+ subsystem_info_list = []
+ subsystem_info_name = subsystem + "_strip.info"
+ for root, dirs, files in os.walk(single_test_info_path):
+ if subsystem_info_name in files:
+ subsystem_info_path_tmp = os.path.join(
+ single_test_info_path, root, subsystem_info_name)
+ subsystem_info_list.append(subsystem_info_path_tmp)
+ if len(subsystem_info_list) == 0:
+ return
+ info_output_name = os.path.join(
+ CODEPATH, REPORT_PATH, subsystem_info_name)
+ cmd = "lcov -a {} -o {}".format(
+ " -a ".join(subsystem_info_list), info_output_name)
+ execute_command(cmd)
+
+
+def merge_all_test_subsystem_info(subsystem_list):
+ single_test_info_path = os.path.join(
+ CODEPATH, REPORT_PATH, "single_test")
+ if not os.path.exists(single_test_info_path):
+ print("Error: the single test info path %s not exist",
+ single_test_info_path)
+ return
+ for subsystem in subsystem_list:
+ print("Merging all %s info from test data......", subsystem)
+ merge_subsystem_info_from_all_test(subsystem)
+
+
+def merge_info(report_dir):
+ if not os.path.exists(report_dir):
+ print("Error: report dir %s not exist", report_dir)
+ return
+ subsystem_name_list = get_files_from_dir(report_dir, "_strip.info")
+ if len(subsystem_name_list) == 0:
+ print("Error: get subsytem trace files in \report directory failed.")
+ return
+ trace_file_list = []
+ for subsystem in subsystem_name_list:
+ trace_file_name = os.path.join(report_dir, subsystem)
+ trace_file_list.append(trace_file_name)
+ cmd = "lcov -a {} -o {}".format(" -a ".join(trace_file_list),
+ os.path.join(
+ report_dir, "ohos_codeCoverage.info"))
+ execute_command(cmd)
+
+
+def merge_all_subsystem_info():
+ print("Merging all the sysbsystem trace files......")
+ merge_info(os.path.join(CODEPATH, REPORT_PATH))
+
+
+def gen_html(cov_path):
+ tracefile = os.path.join(CODEPATH, REPORT_PATH, "ohos_codeCoverage.info")
+ if not os.path.exists(tracefile):
+ print("Error: the trace file %s not exist", tracefile)
+ return
+ cmd = "genhtml --branch-coverage --demangle-cpp -o {} -p {} --ignore-errors source {}"\
+ .format(os.path.join(CODEPATH, REPORT_PATH, "html"), CODEPATH, tracefile)
+ execute_command(cmd)
+
+
+def gen_final_report(cov_path):
+ print("Generating the html report......")
+ gen_html(cov_path)
+
+
+if __name__ == "__main__":
+ gen_all_test_info(subsystem_list=get_subsystem_name_list())
+ merge_all_test_subsystem_info(subsystem_list=get_subsystem_name_list())
+ merge_all_subsystem_info()
+ gen_final_report(os.path.join(CODEPATH, COVERAGE_GCDA_RESULTS))
diff --git a/localCoverage/codeCoverage/coverage_rc/lcovrc_cov_template b/localCoverage/codeCoverage/coverage_rc/lcovrc_cov_template
new file mode 100644
index 0000000000000000000000000000000000000000..0f99e76a8a1b9acf728a58c019bbffa718fb4570
--- /dev/null
+++ b/localCoverage/codeCoverage/coverage_rc/lcovrc_cov_template
@@ -0,0 +1,175 @@
+#
+# Copyright (c) 2023 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+# /etc/lcovrc - system-wide defaults for LCOV
+#
+# To change settings for a single user, place a customized copy of this file
+# at location ~/.lcovrc
+#
+
+# Specify an external style sheet file (same as -css-file option of genhtml)
+# genhtml_css_file = gcov.css
+
+# Specify coverage rate limits (in %) for classifying file entries
+# HI: hi_limit <= rate <= 100 graph color: green
+# MED: med_limit <= rate < hi_limit graph color: orange
+# LO: 0 <= rate < med_limit graph color: red
+genhtml_hi_limit = 90
+genhtml_med_limit = 75
+
+# Width of line coverage field in source code view
+genhtml_line_field_width = 12
+
+# Width of branch coverage field in source code view
+genhtml_branch_field_width = 16
+
+# Width of overview image (used by --frames option of genhtml)
+genhtml_overview_width = 80
+
+# Resolution of overview navigation: this number specifies the maximum
+# difference in lines between the position a user selected from the overview
+# and the position the source code window is scrolled to (used by --frames
+# option of genhtml)
+genhtml_nav_resolution = 4
+
+# Clicking a line in the overview image should show the source code view at
+# a position a bit further up so that the requested line is not the first
+# line in the window. This number specifies that offset in lines (used by
+# --frames option of genhtml)
+genhtml_nav_offset = 10
+
+# Do not remove unused test descriptions if non-zero (same as
+# --keep-descriptions option of genhtml)
+genhtml_keep_descriptions = 0
+
+# Do not remove prefix from directory names if non-zero (same as --no-prefix
+# option of genhtml)
+genhtml_no_prefix = 0
+
+# Do not create source code view if non-zero (same as --no-source option of
+# genhtml)
+genhtml_no_source = 0
+
+# Replace tabs with number of spaces in source view (same as --num-spaces
+# option of genhtml)
+genhtml_num_spaces = 8
+
+# Highlight lines with converted-only data if non-zero (same as --highlight
+# option of genhtml)
+genhtml_highlight = 0
+
+# Include color legend in HTML output if non-zero (same as --legend option of
+# genhtml)
+genhtml_legend = 0
+
+# Use FILE as HTML prolog for generated pages (same as --html-prolog option of
+# genhtml)
+# genhtml_html_prolog = FILE
+
+# Use FILE as HTML epilog for generated pages (same as --html-epilog option of
+# genhtml)
+# genhtml_html_epilog = FILE
+
+# Use custom filename extension for pages (same as --html-extension option of
+# genhtml)
+# genhtml_html_extension = html
+
+# Compress all generated html files with gzip.
+# genhtml_html_gzip = 1
+
+# Include sorted overview pages (can be disabled by the --no-sort option of
+# genhtml)
+genhtml_sort = 1
+
+# Include function coverage data display (can be disabled by the
+# --no-func-coverage option of genhtml)
+# genhtml_function_coverage = 1
+
+# Include branch coverage data display (can be disabled by the
+# --no-branch-coverage option of genhtml)
+# genhtml_branch_coverage = 1
+
+# Specify the character set of all generated HTML pages
+genhtml_charset=UTF-8
+
+# Allow HTML markup in test case description text if non-zero
+genhtml_desc_html = 0
+
+# Specify the precision for coverage rates
+# genhtml_precision = 1
+
+# Location of the gcov tool (same as --gcov-info option of geninfo)
+# geninfo_gcov_tool = gcov
+
+# Adjust test names to include operating system information if non-zero
+# geninfo_adjust_testname = 0
+
+# Calculate checksum for each source code line if non-zero (same as --checksum
+# option of geninfo if non-zero, same as --no-checksum if zero)
+# geninfo_checksum = 1
+
+# Specify whether to capture coverage data for external source files (can
+# be overridden by the --external and --no-external options of geninfo/lcov)
+# geninfo_external = 1
+
+# Enable libtool compatibility mode if non-zero (same as --compat-libtool option
+# of geninfo if non-zero, same as --no-compat-libtool if zero)
+# geninfo_compat_libtool = 0
+
+# Specify compatiblity modes (same as --compat option of geninfo).
+# geninfo_compat = libtool = on, hammer=auto, split_crc=auto
+
+# Adjust path to source files by removing or changing path components that
+# match the specified pattern (Perl regular expression format)
+# geninfo_adjust_src_path = /tmp/build => /usr/src
+
+# Specify if geninfo should try to automatically determine the base-directory
+# when collecting coverage data.
+geninfo_auto_base = 1
+
+# Directory containing gcov kernel files
+# lcov_gcov_dir = /proc/gcov
+
+# Location of the insmod tool
+lcov_insmod_tool = /sbin/insmod
+
+# Location of the modprobe tool
+lcov_modprobe_tool = /sbin/modprobe
+
+# Location of the rmmod tool
+lcov_rmmod_tool = /sbin/rmmod
+
+# Show full paths during list operation if non-zero (same as --list-full-path
+# option of lcov)
+lcov_list_full_path = 0
+
+# Specify the maximum width for list output. This value is ignored when
+# lcov_list_full_path is non-zero.
+lcov_list_width = 80
+
+# Specify the maximum percentage of file names which may be truncated when
+# choosing a directory prefix in list output. This value is ignored when
+# lcov_list_full_path is non-zero.
+lcov_list_truncate_max = 20
+
+# Specify if function coverage data should be collected and processed.
+lcov_function_coverage = 1
+
+# Specify if branch coverage data should be collected and processed.
+lcov_branch_coverage = 1
+
+# Specify the regular expression of lines to exclude from branch coveragel
+# Default is 'LCOV_EXCL_BR_LINE'.
+lcov_excl_br_line = LCOV_EXCL_BR_LINE
\ No newline at end of file
diff --git a/localCoverage/codeCoverage/llvm-gcov.sh b/localCoverage/codeCoverage/llvm-gcov.sh
new file mode 100644
index 0000000000000000000000000000000000000000..4045480a93649cedd119ba4b5ff25f7b8f80730d
--- /dev/null
+++ b/localCoverage/codeCoverage/llvm-gcov.sh
@@ -0,0 +1,20 @@
+# !/bin/bash
+#
+# Copyright (c) 2023 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This file is autogenerated by c_coverage_mgr.py, do not edit manually .
+
+current_path=$(cd $(dirname $0);pwd)
+root_path=${current_path%%/test/testfwk/developer_test/localCoverage/codeCoverage}
+exec $root_path/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-cov gcov "$@"
diff --git a/localCoverage/codeCoverage/mutilProcess_CodeCoverage.py b/localCoverage/codeCoverage/mutilProcess_CodeCoverage.py
new file mode 100644
index 0000000000000000000000000000000000000000..69a4e3402a8d3e44a202c45cf79a2c85c27379b8
--- /dev/null
+++ b/localCoverage/codeCoverage/mutilProcess_CodeCoverage.py
@@ -0,0 +1,405 @@
+#!/usr/bin/env python3
+# coding=utf-8
+
+#
+# Copyright (c) 2023 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import os
+import json
+import shutil
+import shlex
+import subprocess
+import multiprocessing
+from multiprocessing import Process
+
+
+# 根代码目录
+root_path = os.getcwd()
+CODEPATH = root_path.split("/test/testfwk/developer_test")[0]
+# 子系统json目录
+SYSTEM_JSON = "test/testfwk/developer_test/localCoverage/codeCoverage/subsystem_config.json"
+# 覆盖率gcda
+COVERAGE_GCDA_RESULTS = "test/testfwk/developer_test/localCoverage/codeCoverage/results/coverage/data/cxx"
+# 报告路径
+REPORT_PATH = "test/testfwk/developer_test/localCoverage/codeCoverage/results/coverage/reports/cxx"
+# llvm-gcov.sh
+LLVM_GCOV = "test/testfwk/developer_test/localCoverage/codeCoverage/llvm-gcov.sh"
+# 编译生成的out路径
+OUTPUT = "out/baltimore"
+# 屏蔽列表
+FILTEROUT_DIRS = ["unittest", "third_party", "test"]
+# 测试套划分步长
+STEP_SIZE = 10
+# lcovrc配置文件集合
+LCOVRC_SET = CODEPATH + "/test/testfwk/developer_test/localCoverage/codeCoverage/coverage_rc"
+
+
+def call(cmd_list, is_show_cmd=False, out=None, err=None):
+ return_flag = False
+ try:
+ if is_show_cmd:
+ print("execute command: {}".format(" ".join(cmd_list)))
+ if 0 == subprocess.call(cmd_list, shell=False, stdout=out, stderr=err):
+ return_flag = True
+ except:
+ print("Error : command {} execute faild!".format(cmd_list))
+ return_flag = False
+
+ return return_flag
+
+
+def execute_command(command, printflag=False):
+ try:
+ cmd_list = shlex.split(command)
+ with open("coverage.log", 'a') as fd:
+ call(cmd_list, printflag, fd, fd)
+ except IOError as err:
+ print("Error: Exception occur in open: %s", err.message)
+
+
+def get_subsystem_config_info():
+ filter_subsystem_name_list = [
+ "subsystem_examples",
+ ]
+ subsystem_info_dic = {}
+ subsystem_config_filepath = os.path.join(CODEPATH, SYSTEM_JSON)
+ if os.path.exists(subsystem_config_filepath):
+ data = None
+ with open(subsystem_config_filepath, "r", encoding="utf-8") as f:
+ data = json.load(f)
+ if not data:
+ print("subsystem config file error.")
+ for value in data.values():
+ subsystem_name = value.get("name")
+ if subsystem_name in filter_subsystem_name_list:
+ continue
+ subsystem_dir = value.get('dir')
+ subsystem_path = value.get('path')
+ subsystem_project = value.get('project')
+ subsystem_rootpath = []
+ for path in subsystem_path:
+ subsystem_rootpath.append(os.path.join(CODEPATH, path))
+ subsystem_info_dic[subsystem_name] = [
+ subsystem_project, subsystem_dir,
+ subsystem_path, subsystem_rootpath
+ ]
+ return subsystem_info_dic
+
+
+def get_subsystem_name_list():
+ subsystem_name_list = []
+ subsystem_info_dic = get_subsystem_config_info()
+ for key in subsystem_info_dic.keys():
+ subsystem_rootpath = subsystem_info_dic[key][3]
+ for subsystem_rootpath_item in subsystem_rootpath:
+ if os.path.exists(subsystem_rootpath_item):
+ subsystem_name_list.append(key)
+
+ return subsystem_name_list
+
+
+def get_subsystem_rootpath(subsystem_name):
+ subsystem_path = ""
+ subsystem_rootpath = ""
+ subsystem_info_dic = get_subsystem_config_info()
+ for key in subsystem_info_dic.keys():
+ if key == subsystem_name:
+ subsystem_path = subsystem_info_dic[key][2]
+ subsystem_rootpath = subsystem_info_dic[key][3]
+ break
+
+ return subsystem_path, subsystem_rootpath
+
+
+def is_filterout_dir(ignore_prefix, check_path):
+ for dir in FILTEROUT_DIRS:
+ check_list = check_path[len(ignore_prefix):].split("/")
+ if dir in check_list:
+ return True
+
+ return False
+
+
+def rm_unnecessary_dir(cov_path):
+ topdir = os.path.join(cov_path, "obj")
+ for root, dirs, files in os.walk(topdir):
+ if is_filterout_dir(topdir, root):
+ shutil.rmtree(root)
+
+
+def get_files_from_dir(find_path, postfix=None):
+ names = os.listdir(find_path)
+ file_list = []
+ for fn in names:
+ if not os.path.isfile(os.path.join(find_path, fn)):
+ continue
+ if postfix is not None:
+ if fn.endswith(postfix):
+ file_list.append(fn)
+ else:
+ file_list.append(fn)
+
+ return file_list
+
+
+def get_gcno_files(cov_path, dir_name):
+ gcda_strip_path = dir_name[len(cov_path) + 1:]
+ gcda_list = get_files_from_dir(dir_name, ".gcda")
+ for file_name in gcda_list:
+ gcno_name = os.path.splitext(file_name)[0] + ".gcno"
+ gcno_path = os.path.join(
+ os.path.join(CODEPATH, OUTPUT), gcda_strip_path, gcno_name
+ )
+ if os.path.exists(gcno_path):
+ shutil.copy(gcno_path, dir_name)
+ else:
+ print(f"{gcno_path} not exists!")
+
+
+def get_module_gcno_files(cov_path, dir_name):
+ for root, dirs, files in os.walk(dir_name):
+ get_gcno_files(cov_path, root)
+
+
+def gen_subsystem_trace_info(subsystem, data_dir, test_dir, lcovrc_path):
+ src_dir = os.path.join(CODEPATH, OUTPUT)
+ single_info_path = os.path.join(
+ CODEPATH, REPORT_PATH, "single_test", test_dir
+ )
+ if not os.path.exists(single_info_path):
+ os.makedirs(single_info_path)
+ output_name = os.path.join(
+ CODEPATH, single_info_path, subsystem + "_output.info"
+ )
+ if not os.path.exists(src_dir):
+ print(f"Sours path {src_dir} not exists!")
+ return
+
+ cmd = "lcov -c -b {} -d {} --gcov-tool {} --config-file {} -o {} --ignore-errors" \
+ "source,gcov".format(src_dir, data_dir, os.path.join(
+ CODEPATH, LLVM_GCOV), lcovrc_path, output_name)
+ print("single_test**##father_pid:%s##child_pid:%s cmd:%s config file:%s"%(
+ os.getpid(), os.getppid(), cmd, lcovrc_path
+ ))
+ execute_command(cmd)
+
+
+def cut_info(subsystem, test_dir):
+ trace_file = os.path.join(
+ CODEPATH, REPORT_PATH, "single_test",
+ test_dir, subsystem + "_output.info"
+ )
+ output_name = os.path.join(
+ CODEPATH, REPORT_PATH, "single_test",
+ test_dir, subsystem + "_strip.info"
+ )
+
+ remove = r"'*/third_party/*' 'sdk/android-arm64/*'"
+ if not os.path.exists(trace_file):
+ print(f"Error: trace file {trace_file} not exists!")
+ return
+
+ cmd = "lcov --remove {} {} -o {}".format(trace_file, remove, output_name)
+ execute_command(cmd)
+
+
+def gen_info(cov_path, test_dir, subsystem_list, lcovrc_path):
+ if len(subsystem_list) == 0:
+ print("Error: get subsystem list failed, can not generate trace info")
+ return
+
+ loop = 0
+ for subsystem in list(set(subsystem_list)):
+ subsystem_path, subsystem_rootpath = get_subsystem_rootpath(subsystem)
+ for subsys_path in subsystem_path:
+ subsystem_data_abspath = os.path.join(cov_path, "obj", subsys_path)
+ # check id subsystem data is exists
+ if not os.path.exists(subsystem_data_abspath):
+ continue
+
+ # copy gcno to the gcda same directory
+ get_module_gcno_files(cov_path, subsystem_data_abspath)
+
+ # generate coverage info for each subsystem
+ gen_subsystem_trace_info(
+ subsystem + "#" + subsys_path.replace("/", "_") + "#" + str(loop),
+ subsystem_data_abspath, test_dir, lcovrc_path
+ )
+
+ # remove some type which useless
+ cut_info(subsystem + "#" + subsys_path.replace("/", "_") + "#" + str(loop), test_dir)
+
+ loop += 1
+
+
+def generate_coverage_info(single_test_dir_list, lcovrc_path, subsystem_list=[]):
+ cov_path = os.path.join(CODEPATH, COVERAGE_GCDA_RESULTS)
+ for index, cur_test_dir in enumerate(single_test_dir_list):
+ cur_test_abs_dir = os.path.join(cov_path, cur_test_dir)
+ gen_info(cur_test_abs_dir, cur_test_dir, subsystem_list, lcovrc_path)
+
+
+def gen_all_test_info(subsystem_list=[]):
+ cov_path = os.path.join(CODEPATH, COVERAGE_GCDA_RESULTS)
+ print(os.getpid(), os.getppid())
+ single_test_dir_list = []
+ for root, dirs, files in os.walk(cov_path):
+ single_test_dir_list = dirs
+ break
+
+ return single_test_dir_list
+
+
+def merge_subsystem_info_from_all_test(subsystem):
+ single_test_info_path = os.path.join(
+ CODEPATH, REPORT_PATH, "single_test"
+ )
+ subsystem_info_list = []
+ subsystem_info_name = subsystem + "_strip.info"
+ for root, dirs, files in os.walk(single_test_info_path):
+ for file in files:
+ if file.startswith(subsystem) and file.endswith("_strip.info"):
+ subsystem_info_path_tmp = os.path.join(
+ single_test_info_path, root, file
+ )
+ print("##" + subsystem_info_path_tmp)
+ subsystem_info_list.append(subsystem_info_path_tmp)
+
+ if len(subsystem_info_list) == 0:
+ return
+
+ info_output_name = os.path.join(
+ CODEPATH, REPORT_PATH, subsystem_info_name
+ )
+ cmd = "lcov -a {} -o {}".format(
+ " -a ".join(subsystem_info_list), info_output_name
+ )
+ execute_command(cmd)
+
+
+def merge_all_test_subsystem_info(subsystem_list):
+ single_test_info_path = os.path.join(
+ CODEPATH, REPORT_PATH, "single_test"
+ )
+ if not os.path.exists(single_test_info_path):
+ print(f"Error: the single test info path "
+ f"{single_test_info_path} not exist")
+ return
+
+ for subsystem in subsystem_list:
+ print(f"Merging all {subsystem} info from test data")
+ merge_subsystem_info_from_all_test(subsystem)
+
+
+def merge_info(report_dir):
+ if not os.path.exists(report_dir):
+ print(f"Error: report dir {report_dir} not exists!")
+ return
+
+ subsystem_name_list = get_files_from_dir(report_dir, "_strip.info")
+ if len(subsystem_name_list) == 0:
+ print("Error: get subsystem trace files in report directory failed.")
+ return
+
+ trace_file_list = []
+ for subsystem in subsystem_name_list:
+ trace_file_name = os.path.join(report_dir, subsystem)
+ trace_file_list.append(trace_file_name)
+
+ cmd = "lcov -a {} -o {}".format(
+ " -a ".join(trace_file_list), os.path.join(report_dir, "ohos_codeCoverage.info")
+ )
+ execute_command(cmd)
+
+
+def merge_all_subsystem_info():
+ print("Merging all the subsystem trace files")
+ merge_info(os.path.join(CODEPATH, REPORT_PATH))
+
+
+def gen_html(cov_path):
+ tracefile = os.path.join(CODEPATH, REPORT_PATH, "ohos_codeCoverage.info")
+ if not os.path.exists(tracefile):
+ print(f"Error: the trace file {tracefile} not exists!")
+ return
+
+ cmd = "genhtml --branch-coverage --demangle-cpp -o {} -p {} --ignore-errors " \
+ "source {}".format(os.path.join(CODEPATH, REPORT_PATH, "html"),
+ CODEPATH, tracefile)
+ execute_command(cmd)
+
+
+def gen_final_report(cov_path):
+ print("Generating the html report")
+ gen_html(cov_path)
+
+
+if __name__ == '__main__':
+ caseLst = gen_all_test_info(subsystem_list=get_subsystem_name_list())
+ multiprocessing.set_start_method("fork") # fork spawn forkserver
+ start = end = 0
+ Tag = False
+ process_list = []
+ for i in range(len(caseLst)):
+ lcovrc_path = LCOVRC_SET + "/" + "lcovrc_cov" + str(i)
+ print(lcovrc_path)
+ if os.path.exists(lcovrc_path):
+ print(lcovrc_path + "@" * 20 + "yes")
+ else:
+ raise Exception("mutilProcess have error -rc path not existed. "
+ "please fix add run")
+
+ start = end
+ end += STEP_SIZE
+ if end >= len(caseLst):
+ end = len(caseLst)
+ Tag = True
+
+ p = Process(target=generate_coverage_info,
+ args=(caseLst[start:end], lcovrc_path,
+ get_subsystem_name_list()))
+ p.daemon = True
+ p.start()
+ process_list.append(p)
+ if Tag:
+ break
+
+ for i in process_list:
+ i.join()
+
+ merge_all_test_subsystem_info(subsystem_list=get_subsystem_name_list())
+ merge_all_subsystem_info()
+ gen_final_report(os.path.join(CODEPATH, COVERAGE_GCDA_RESULTS))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/localCoverage/coverage_tools.py b/localCoverage/coverage_tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..f36f735308e61aee8cc68994449dd25eafbf290e
--- /dev/null
+++ b/localCoverage/coverage_tools.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python3
+# coding=utf-8
+
+#
+# Copyright (c) 2023 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+import os
+import sys
+import json
+import shutil
+import subprocess
+from shutil import copyfile
+
+
+def get_subsystem_config(test_part_list):
+ all_system_info_path = os.path.join(
+ developer_path,
+ "developer_test/localCoverage/all_subsystem_config.json"
+ )
+ system_info_path = os.path.join(
+ developer_path,
+ "developer_test/localCoverage/codeCoverage/subsystem_config.json"
+ )
+ if os.path.exists(all_system_info_path):
+ new_json_text = {}
+ for part in test_part_list:
+ with open(all_system_info_path, "r", encoding="utf-8") as system_text:
+ system_text_json = json.load(system_text)
+ if part in system_text_json:
+ new_json_text[part] = system_text_json[part]
+ else:
+ print("part not in all_subsystem_config.json")
+
+ new_json = json.dumps(new_json_text, indent=4)
+ with open(system_info_path, "w") as out_file:
+ out_file.write(new_json)
+ else:
+ print("%s not exists.", all_system_info_path)
+
+
+def copy_coverage():
+ print("[*************** Start TO Get Coverage Report ***************]")
+ coverage_path = os.path.join(
+ developer_path, "developer_test/reports/coverage"
+ )
+ code_path = os.path.join(
+ developer_path,
+ "developer_test/localCoverage/codeCoverage/results/coverage"
+ )
+ if os.path.exists(code_path):
+ shutil.rmtree(code_path)
+ shutil.copytree(coverage_path, code_path)
+
+
+def generate_coverage_rc(developer_path):
+ coverage_rc_path = os.path.join(
+ developer_path,
+ "developer_test/localCoverage/codeCoverage/coverage_rc"
+ )
+ lcovrc_cov_template_path = os.path.join(coverage_rc_path, "lcovrc_cov_template")
+ for num in range(16):
+ tmp_cov_path = os.path.join(coverage_rc_path, f"tmp_cov_{num}")
+ lcovrc_cov_path = os.path.join(coverage_rc_path, f"lcovrc_cov_{num}")
+ if not os.path.exists(tmp_cov_path):
+ os.mkdir(tmp_cov_path)
+ if not os.path.exists(os.path.join(tmp_cov_path, "ex.txt")):
+ with open(os.path.join(tmp_cov_path, "ex.txt"), mode="w") as f:
+ f.write("")
+
+ copyfile(lcovrc_cov_template_path, lcovrc_cov_path)
+ with open(lcovrc_cov_path, mode="a") as f:
+ f.write("\n\n")
+ f.write("# Location for temporary directories\n")
+ f.write(f"lcov_tmp_dir = {tmp_cov_path}")
+
+
+def execute_code_cov_tools():
+ llvm_gcov_path = os.path.join(
+ developer_path,
+ "developer_test/localCoverage/codeCoverage/llvm-gcov.sh"
+ )
+ subprocess.Popen("dos2unix %s" % llvm_gcov_path, shell=True).communicate()
+ tools_path = os.path.join(
+ developer_path,
+ "developer_test/localCoverage/codeCoverage/mutilProcess_CodeCoverage.py"
+ )
+ code_coverage_process = subprocess.Popen("python3 %s" % tools_path, shell=True)
+ code_coverage_process.communicate()
+
+
+def get_subsystem_name(test_part_list):
+ testfwk_json_path = os.path.join(
+ root_path, "out/baltimore/build_configs/infos_for_testfwk.json"
+ )
+ if os.path.exists(testfwk_json_path):
+ with open(testfwk_json_path, "r", encoding="utf-8") as json_text:
+ system_json = json.load(json_text)
+ subsystem_info = system_json.get("phone").get("subsystem_infos")
+ subsystem_list = []
+ for part in test_part_list:
+ for key in subsystem_info.keys():
+ if part in subsystem_info.keys() and key not in subsystem_list:
+ subsystem_list.append(key)
+ subsystem_str = ','.join(list(map(str, subsystem_list)))
+ return subsystem_str
+ else:
+ print("%s not exists.", testfwk_json_path)
+
+
+def execute_interface_cov_tools(subsystem_str):
+ print("[*************** Start TO Get Interface Coverage Report ***************]")
+ innerkits_json_path = os.path.join(
+ developer_path,
+ "developer_test/localCoverage/interfaceCoverage/get_innerkits_json.py"
+ )
+ interface_coverage_process = subprocess.Popen(
+ "python3 %s" % innerkits_json_path, shell=True
+ )
+ interface_coverage_process.communicate()
+
+ interface_path = os.path.join(
+ developer_path,
+ "developer_test/localCoverage/interfaceCoverage/interfaceCoverage_gcov_lcov.py"
+ )
+ subprocess.run("python2 %s %s" % (interface_path, subsystem_str), shell=True)
+
+
+if __name__ == '__main__':
+ testpart_args = sys.argv[1]
+ subsystem_args = sys.argv[2]
+ test_part_list = testpart_args.split("testpart=")[1].split(",")
+ subsystem_args_str = subsystem_args.split("subsystem=")[1]
+
+ current_path = os.getcwd()
+ root_path = current_path.split("/test/testfwk/developer_test")[0]
+ developer_path = current_path.split("/developer_test/src")[0]
+
+ # copy gcda数据到覆盖率工具指定位置
+ copy_coverage()
+ generate_coverage_rc(developer_path)
+
+ # 获取部件位置信息config
+ if len(test_part_list) > 0:
+ get_subsystem_config(test_part_list)
+
+ # 执行代码覆盖率
+ execute_code_cov_tools()
+
+ # 执行接口覆盖率
+ if subsystem_args_str:
+ subsystem_str = subsystem_args_str
+ else:
+ subsystem_str = get_subsystem_name(test_part_list)
+
+ if subsystem_str:
+ execute_interface_cov_tools(subsystem_str)
+ else:
+ print("subsystem or part without!")
+
+
+
diff --git a/localCoverage/interfaceCoverage/__init__.py b/localCoverage/interfaceCoverage/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/localCoverage/interfaceCoverage/get_innerkits_json.py b/localCoverage/interfaceCoverage/get_innerkits_json.py
new file mode 100644
index 0000000000000000000000000000000000000000..94107b6695bb9ff30a7a4d33508c41654d432f8d
--- /dev/null
+++ b/localCoverage/interfaceCoverage/get_innerkits_json.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+# coding=utf-8
+
+#
+# Copyright (c) 2023 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+import os
+import json
+import subprocess
+
+
+def genPartsInfoJSON(folder_list, output_json_path):
+ """
+ 根据部件信息,生成字典至json文件中
+ """
+ if len(folder_list) != 0:
+ data_dict = {}
+ for folder_str in folder_list:
+ data_dict[folder_str] = "innerkits/ohos-arm64/" + folder_str
+ output_json_path = os.path.join(output_json_path, "kits_modules_info.json")
+ json_str = json.dumps(data_dict, indent=2)
+ with open(output_json_path, "w") as json_file:
+ json_file.write(json_str)
+ else:
+ print("Failed to obtain component information")
+
+
+def getPartsJson(path):
+ """
+ #获取out/ohos-arm-release/innerkits/ohos-arm内部接口文件夹名称列表
+ """
+ if os.path.exists(path):
+ folder_list = os.listdir(path)
+ else:
+ print("The folder does not exist")
+ folder_list = []
+ return folder_list
+
+
+if __name__ == "__main__":
+ current_path = os.getcwd()
+ root_path = current_path.split("/test/testfwk/developer_test")[0]
+ part_info_path = os.path.join(
+ root_path, "out/baltimore/innerkits/ohos-arm64"
+ )
+ output_json_path = os.path.join(
+ root_path, "out/baltimore/packages/phone/innerkits/ohos-arm64"
+ )
+ subprocess.Popen("mkdir -p " + output_json_path, shell=True)
+ folder_list = getPartsJson(part_info_path)
+ genPartsInfoJSON(folder_list, output_json_path)
+
diff --git a/localCoverage/interfaceCoverage/interfaceCoverage_gcov_lcov.py b/localCoverage/interfaceCoverage/interfaceCoverage_gcov_lcov.py
new file mode 100644
index 0000000000000000000000000000000000000000..66c77e85d482a9b677b70f0da1d9da7eb93cc446
--- /dev/null
+++ b/localCoverage/interfaceCoverage/interfaceCoverage_gcov_lcov.py
@@ -0,0 +1,461 @@
+#!/usr/bin/env python3
+# coding=utf-8
+
+#
+# Copyright (c) 2023 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+import os
+import sys
+import json
+import shutil
+import subprocess
+import CppHeaderParser
+import get_innerkits_json
+import makeReport
+
+
+root_path = os.getcwd()
+CODEPATH = root_path.split("/test/testfwk/developer_test")[0]
+PATH_INFO_PATH = "out/baltimore/innerkits/ohos-arm64"
+OUTPUT_JSON_PATH = "out/baltimore/packages/phone/innerkits/ohos-arm64"
+KIT_MODULES_INFO = "out/baltimore/packages/phone/innerkits/ohos-arm64/kits_modules_info.json"
+SUB_SYSTEM_INFO_PATH = os.path.join(
+ CODEPATH, "test/testfwk/developer_test/localCoverage/codeCoverage/results/coverage/reports/cxx")
+OUTPUT_REPORT_PATH = os.path.join(
+ CODEPATH, "test/testfwk/developer_test/localCoverage/interfaceCoverage/results/coverage/interface_kits"
+)
+
+
+filter_file_name_list = [
+ "appexecfwk/libjnikit/include/jni.h",
+]
+FILTER_CLASS_ATTRIBUTE_LIST = ["ACE_EXPORT", "OHOS_NWEB_EXPORT"]
+
+
+def create_coverage_result_outpath(filepath):
+ if os.path.exists(filepath):
+ shutil.rmtree(filepath)
+ os.makedirs(filepath)
+
+
+def get_subsystem_part_list(project_rootpath):
+ subsystme_part_dict = {}
+ subsystem_part_config_filepath = os.path.join(
+ project_rootpath, "out/baltimore/build_configs", "infos_for_testfwk.json")
+ print(subsystem_part_config_filepath)
+ if os.path.exists(subsystem_part_config_filepath):
+ try:
+ with open(subsystem_part_config_filepath, 'r') as f:
+ data = json.load(f)
+ except IOError as err_msg:
+ print("Error for open subsystem config file: ", err_msg)
+ if not data:
+ print("subsystem_part config file error.")
+ else:
+ subsystme_part_dict= data.get("phone", "").get("subsystem_infos", "")
+ return subsystme_part_dict
+ else:
+ print("subsystem_part_config_filepath not exists.")
+
+
+def load_json_data():
+ json_file_path = os.path.join(CODEPATH, KIT_MODULES_INFO)
+ json_data_dic = {}
+ if os.path.isfile(json_file_path):
+ try:
+ with open(json_file_path, 'r') as f:
+ json_data_dic = json.load(f)
+ if not json_data_dic:
+ print("Loadind file \"%s\" error" % json_file_path)
+ return {}
+ except(IOError, ValueError) as err_msg:
+ print("Error for load_json_data: \"%s\"" % json_file_path, err_msg)
+ else:
+ print("Info: \"%s\" not exist." % json_file_path)
+ return json_data_dic
+
+
+def get_file_list(find_path, postfix):
+ file_names = os.listdir(find_path)
+ file_list = []
+ if len(file_names) > 0:
+ for fn in file_names:
+ if fn.find(postfix) != -1 and fn[-len(postfix):] == postfix:
+ file_list.append(fn)
+ return file_list
+
+
+def get_file_list_by_postfix(path, postfix, filter_jar=""):
+ file_list = []
+ for dirs in os.walk(path):
+ files = get_file_list(find_path=dirs[0], postfix=postfix)
+ for file_path in files:
+ if "" != file_path and -1 == file_path.find(__file__):
+ pos = file_path.rfind(os.sep)
+ file_name = file_path[pos+1:]
+ file_path = os.path.join(dirs[0], file_path)
+ if filter_jar != "" and file_name == filter_jar:
+ print("Skipped %s" % file_path)
+ continue
+ file_list.append(file_path)
+ return file_list
+
+
+def is_need_to_be_parsed(filepath):
+ for item in filter_file_name_list:
+ if -1 != filepath.find(item):
+ return False
+ return True
+
+
+def get_pubilc_func_list_from_headfile(cxx_header_filepath):
+ pubilc_func_list = []
+ try:
+ cpp_header = CppHeaderParser.CppHeader(cxx_header_filepath)
+ for classname in cpp_header.classes:
+ class_name = classname
+ curr_class = cpp_header.classes[classname]
+ for func in curr_class["methods"]["public"]:
+ func_returntype = func["rtnType"]
+ func_name = func["name"]
+ if class_name in FILTER_CLASS_ATTRIBUTE_LIST:
+ class_name = func_name
+ if func_returntype.find("KVSTORE_API") != -1:
+ func_returntype = func_returntype.replace("KVSTORE_API", "").strip()
+ if func_name.isupper():
+ continue
+ if class_name == func_name:
+ destructor = func["destructor"]
+ if destructor == True:
+ func_name = "~" + func_name
+ func_returntype = ""
+ debug = func["debug"].replace("KVSTORE_API", "")
+ debug = debug.replace(" ", "")
+ debug = debug.strip("{")
+ if debug.endswith("=delete;"):
+ continue
+ if debug.endswith("=default;"):
+ continue
+ if debug.startswith("inline"):
+ continue
+ if debug.startswith("constexpr"):
+ continue
+ if debug.startswith("virtual"):
+ continue
+ template = func["template"]
+ if template != False:
+ continue
+ param_type_list = [t["type"] for t in func["parameters"]]
+ pubilc_func_list.append((cxx_header_filepath, class_name,
+ func_name, param_type_list, func_returntype))
+ for func in cpp_header.functions:
+ func_returntype = func["rtnType"]
+ func_name = func["name"]
+ if func_returntype.find("KVSTORE_API") != -1:
+ func_returntype = func_returntype.replace("KVSTORE_API", "").strip()
+ if func_name.isupper():
+ continue
+ template = func["template"]
+ if template != False:
+ continue
+ debug = func["debug"].replace("KVSTORE_API", "")
+ debug = debug.replace(" ", "")
+ debug = debug.strip("{")
+ if debug.startswith("inline"):
+ continue
+ if debug.startswith("constexpr"):
+ continue
+ param_type_list = [t["type"] for t in func["parameters"]]
+ pubilc_func_list.append(
+ (cxx_header_filepath, "", func_name, param_type_list,
+ func_returntype)
+ )
+ except CppHeaderParser.CppParseError as e:
+ print(e)
+ return pubilc_func_list
+
+
+def get_sdk_interface_func_list(part_name):
+ interface_func_list = []
+ sub_path = load_json_data().get(part_name, "")
+ if sub_path == "":
+ return interface_func_list
+
+ sdk_path = os.path.join(CODEPATH, "out", "baltimore", sub_path)
+ if os.path.exists(sdk_path):
+ file_list = get_file_list_by_postfix(sdk_path, ".h")
+ for file in file_list:
+ try:
+ if is_need_to_be_parsed(file):
+ interface_func_list += get_pubilc_func_list_from_headfile(file)
+ except:
+ print("get interface error ", sdk_path)
+ else:
+ print("Error: %s is not exist." % sdk_path)
+
+ print("interface_func_list:", interface_func_list)
+ return interface_func_list
+
+
+def get_function_info_string(func_string):
+ function_info = ""
+ cxxfilt_filepath = "/usr/bin/c++filt"
+ if os.path.exists(cxxfilt_filepath):
+ command = ["c++filt", func_string]
+ function_info = subprocess.check_output(command, shell=False)
+ else:
+ print("/usr/bin/c++filt is not exist.")
+ return function_info
+
+
+def get_covered_function_list(subsystem_name):
+ covered_function_list = []
+ file_name = subsystem_name + "_strip.info"
+ file_path = os.path.join(SUB_SYSTEM_INFO_PATH, file_name)
+ if os.path.exists(file_path):
+ with open(file_path, "r") as fd:
+ for line in fd:
+ if line.startswith("FNDA:"):
+ sub_line_string = line[len("FNDA:"):].replace("\n", "").strip()
+ temp_list = sub_line_string.split(",")
+ if len(temp_list) == 2 and int(temp_list[0]) != 0:
+ func_info = get_function_info_string(temp_list[1])
+ if "" == func_info:
+ continue
+ func_info = func_info.replace("\n", "")
+ if func_info == temp_list[1] and func_info.startswith("_"):
+ continue
+ covered_function_list.append(func_info)
+ else:
+ pass
+ return covered_function_list
+
+
+def get_para_sub_string(content):
+ start_index = -1
+ ended_index = -1
+ parentheses_list_left = []
+ parentheses_list_right = []
+
+ for index in range(len(content)):
+ char = content[index]
+ if "<" == char:
+ if 0 == len(parentheses_list_left):
+ start_index = index
+ parentheses_list_left.append(char)
+ continue
+ if ">" == char:
+ parentheses_list_right.append(char)
+ if len(parentheses_list_left) == len(parentheses_list_right):
+ ended_index = index
+ break
+ continue
+
+ if -1 == start_index:
+ substring = content
+ else:
+ if -1 != ended_index:
+ substring = content[start_index:ended_index+1]
+ else:
+ substring = content[start_index:]
+
+ return substring
+
+
+def filter_para_sub_string(source):
+ content = source
+ if content != "":
+ while True:
+ pos = content.find("<")
+ if -1 != pos:
+ substring = get_para_sub_string(content[pos:])
+ content = content.replace(substring, "")
+ else:
+ break
+ return content
+
+
+def get_function_para_count(func_info):
+ pos_start = func_info.find("(")
+ pos_end = func_info.rfind(")")
+ content = func_info[pos_start+1: pos_end]
+ if "" == content:
+ return 0
+ content = filter_para_sub_string(content)
+ para_list = content.split(",")
+ return len(para_list)
+
+
+def get_covered_result_data(public_interface_func_list, covered_func_list, subsystem_name):
+ coverage_result_list = []
+ for item in public_interface_func_list:
+ data_list = list(item)
+ file_path = data_list[0]
+ class_name = data_list[1]
+ func_name = data_list[2]
+ para_list = data_list[3]
+ return_val = data_list[4]
+ para_string = ""
+ for index in range(len(para_list)):
+ if para_list[index].strip() == "":
+ continue
+ curr_para = para_list[index]
+ para_string += curr_para
+ if index < len(para_list)-1:
+ para_string += ", "
+ fun_string = return_val + " " + func_name + "(" + para_string.strip().strip(",") + ")"
+ fun_string = fun_string.strip()
+ fun_string = filter_para_sub_string(fun_string)
+
+ find_string = ""
+ if class_name != "":
+ find_string = "::" + class_name + "::" + func_name + "("
+ else:
+ find_string = func_name
+ func_info_list = []
+ for line in covered_func_list:
+ if -1 != line.find(find_string):
+ func_info_list.append(line)
+ curr_list = [class_name, fun_string]
+ if len(func_info_list) == 0:
+ curr_list.append("N")
+ elif len(func_info_list) == 1:
+ curr_list.append("Y")
+ else:
+ interface_para_count = len(para_list)
+ find_flag = False
+ for funcinfo in func_info_list:
+ if find_string == funcinfo:
+ curr_list.append("Y")
+ break
+ para_count = get_function_para_count(funcinfo)
+ if interface_para_count == para_count:
+ curr_list.append("Y")
+ find_flag = True
+ break
+ if not find_flag:
+ curr_list.append("N")
+ coverage_result_list.append(curr_list)
+ return coverage_result_list
+
+
+def get_interface_coverage_result_list(subsystem_name,subsystem_part_dict):
+ part_list = subsystem_part_dict.get(subsystem_name, [])
+ public_interface_func_list = []
+ for part_str in part_list:
+ try:
+ interface_func_list = get_sdk_interface_func_list(part_str)
+ public_interface_func_list.extend(interface_func_list)
+ except:
+ print("####")
+ covered_func_list = get_covered_function_list(subsystem_name)
+ interface_coverage_result_list = get_covered_result_data(
+ public_interface_func_list, covered_func_list, subsystem_name)
+ return interface_coverage_result_list
+
+
+def get_coverage_data(data_list):
+ covered_count = 0
+ total_count = len(data_list)
+ if 0 != total_count:
+ for item in data_list:
+ if "Y" == item[2] or "Recorded" == item[2]:
+ covered_count += 1
+ coverage = str(covered_count * 100 / total_count) + "%"
+ else:
+ coverage = "0%"
+ return covered_count, coverage
+
+
+def get_summary_data(interface_data_list):
+ summary_list = []
+ total_count = 0
+ covered_count = 0
+
+ for item in interface_data_list:
+ subsystem_name = item[0]
+ data_list = item[1]
+ if 0 != len(data_list):
+ count, coverage = get_coverage_data(data_list)
+ summary_list.append([subsystem_name, len(data_list), count, coverage])
+ total_count += len(data_list)
+ covered_count += count
+ if 0 != total_count:
+ total_coverage = str(covered_count * 100 / total_count) + "%"
+ summary_list.append(["Summary", total_count, covered_count, total_coverage])
+ return summary_list
+
+
+def make_summary_file(summary_list, output_path):
+ report_path = os.path.join(output_path, "coverage_summary_file.xml")
+ try:
+ with open(report_path, "w") as fd:
+ fd.write('\n')
+ fd.write('\n')
+ for item in summary_list:
+ fd.write(" \n" % (
+ item[0], str(item[1]), item[3]))
+ fd.write('\n')
+ except(IOError, ValueError) as err_msg:
+ print("Error for make coverage result: ", err_msg)
+
+
+def make_result_file(interface_data_list, summary_list, output_path, title_name):
+ report_path = os.path.join(output_path, "ohos_interfaceCoverage.html")
+ makeReport.create_html_start(report_path)
+ makeReport.create_title(report_path, title_name, summary_list)
+ makeReport.create_summary(report_path, summary_list)
+ for item in interface_data_list:
+ subsystem_name = item[0]
+ data_list = item[1]
+ if 0 == len(data_list):
+ continue
+ count, coverage = get_coverage_data(data_list)
+ makeReport.create_table_test(
+ report_path, subsystem_name, data_list, len(data_list), count)
+ makeReport.create_html_ended(report_path)
+
+
+def make_coverage_result_file(interface_data_list, output_path, title_name):
+ summary_list = get_summary_data(interface_data_list)
+ make_summary_file(summary_list, output_path)
+ make_result_file(interface_data_list, summary_list, output_path, title_name)
+
+
+def make_interface_coverage_result():
+ subsystem_name_list = system_name_list
+ interface_data_list = []
+ subsystem_part_dict = get_subsystem_part_list(CODEPATH)
+ for subsystem_name in subsystem_name_list:
+ coverage_result_list = get_interface_coverage_result_list(
+ subsystem_name,subsystem_part_dict)
+ interface_data_list.append([subsystem_name, coverage_result_list])
+ make_coverage_result_file(interface_data_list, OUTPUT_REPORT_PATH,
+ "Inner Interface")
+
+
+if __name__ == "__main__":
+ system_args = sys.argv[1]
+ system_name_list = system_args.split(",")
+ get_innerkits_json.genPartsInfoJSON(
+ get_innerkits_json.getPartsJson(os.path.join(CODEPATH,PATH_INFO_PATH)),
+ os.path.join(CODEPATH,OUTPUT_JSON_PATH)
+ )
+ if len(system_name_list) > 0:
+ make_interface_coverage_result()
+ else:
+ print("subsystem_name not exists!")
diff --git a/localCoverage/interfaceCoverage/makeReport.py b/localCoverage/interfaceCoverage/makeReport.py
new file mode 100644
index 0000000000000000000000000000000000000000..4b46f1653b34482ed1f070e0a326a4b7748ad200
--- /dev/null
+++ b/localCoverage/interfaceCoverage/makeReport.py
@@ -0,0 +1,243 @@
+#!/usr/bin/env python3
+# coding=utf-8
+
+#
+# Copyright (c) 2023 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+import sys
+import datetime
+reload(sys)
+sys.setdefaultencoding("utf-8")
+
+
+g_html_head = """
+
+
+
+
+ 接口覆盖率邮件模板
+
+
+"""
+g_html_body_start = """
+"""
+
+g_html_body_ended = """
+"""
+g_html_ended = """
+"""
+
+
+def sort_by_field_element(elem):
+ return int(elem[3][:-1]) #@######value是浮点数,如1.0,那么需要先转float再转int
+
+
+def sort_by_field_element_data(elem):
+ return elem[2]
+
+
+def create_html_start(reportpath):
+ try:
+ with open(reportpath, "w") as report:
+ report.write(g_html_head)
+ report.write(g_html_body_start)
+ except(IOError, ValueError) as err_msg:
+ print("Error for create html start: ", err_msg)
+
+
+def create_title(reportpath, title_name, summary_list):
+ currdatetime = datetime.date.today().strftime("%Y-%m-%d")
+ report_title = """
+ %s coverage report (%s)
+ """
+ content = report_title % (title_name, currdatetime)
+ report_title = content + """
+
+
+  |
+
+ Summary Report
+ 接口总数%s, 已覆盖%s, 未覆盖%s
+ |
+
+
+
+ """
+ summary_list.sort(key=sort_by_field_element, reverse=False)
+ subsystems = ""
+ count = 0
+ for item in summary_list:
+ subsystem = item[0]
+ if count < 3:
+ subsystems = subsystems + "、" + subsystem
+ count = count + 1
+ if subsystem == "Summary":
+ nocoverd = item[1] - item[2]
+ report_title = report_title % (item[1], item[2], nocoverd)
+ try:
+ with open(reportpath, "a") as report:
+ report.write(report_title)
+ except(IOError, ValueError) as err_msg:
+ print("Error for create html title: ", err_msg)
+
+
+def create_summary(reportpath, summary_list):
+ table_title = """
+ Summary
+ """
+
+ table_start = """"""
+
+ table_head = """
+
+ SubsystemName |
+ TotalCount |
+ CoveredCount |
+ Coverage |
+
"""
+
+ table_line = """
+
+ %s |
+ %s |
+ %s |
+ %s |
+
+ """
+
+ table_ended = """
+ """
+ try:
+ if len(summary_list) == 0:
+ return
+ with open(reportpath, "a") as report:
+ report.write(table_title)
+ report.write(table_start)
+ report.write(table_head)
+ for item in summary_list:
+ content = table_line % (item[0], str(item[1]), str(item[2]), item[3])
+ report.write(content)
+ report.write(table_ended)
+ except(IOError, ValueError) as err_msg:
+ print("Error for create html summary: ", err_msg)
+
+
+def create_table_test(reportpath, subsystem_name, datalist, total_count, covered_count):
+ table_title = """
+ %s details:
+ """
+ table_start = """"""
+ table_head = """
+
+ SubsystemName |
+ ClassName |
+ InterfaceName |
+ IsCovered |
+
"""
+ table_line = """
+
+ %s |
+ %s |
+ %s |
+ %s |
+
+ """
+ table_summary = """
+
+ TotalCount: %s, CoveredCount:%s, Coverage: %s |
+
+ """
+ table_ended = """
+ """
+ try:
+ with open(reportpath, "a") as report:
+ print("subsystem_name==" + subsystem_name)
+ tabletitle = table_title % (subsystem_name)
+ print("tabletitle==" + tabletitle)
+ tabletitle = "" + tabletitle + "
"
+ report.write(tabletitle)
+ report.write(table_start)
+ report.write(table_head)
+ datalist.sort(key=sort_by_field_element_data, reverse=False)
+
+ for line in datalist:
+ if str(line[2]) == "N":
+ content = table_line % (
+ "" + subsystem_name + "", "" + line[0] + "",
+ "" + line[1] + "",
+ "" + str(line[2]) + "")
+ report.write(content)
+ else:
+ content = table_line % (
+ "" + subsystem_name + "", "" + line[0] + "",
+ "" + line[1] + "",
+ "" + str(line[2]) + "")
+ report.write(content)
+ if 0 != total_count:
+ coverage = str(covered_count * 100 / total_count) + "%"
+ else:
+ coverage = "0%"
+ coverage = table_summary % (total_count, covered_count, coverage)
+ report.write(coverage)
+ report.write(table_ended)
+ except(IOError, ValueError) as err_msg:
+ print("Error for create html table test: ", err_msg)
+
+
+def create_html_ended(reportpath):
+ try:
+ with open(reportpath, "a") as report:
+ report.write(g_html_body_ended)
+ report.write(g_html_ended)
+ except(IOError, ValueError) as err_msg:
+ print("Error for create html end: ", err_msg)
diff --git a/localCoverage/interfaceCoverage/results/coverage/interface_kits/coverage_summary_file.xml b/localCoverage/interfaceCoverage/results/coverage/interface_kits/coverage_summary_file.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fb67817031aa6dee4ca08551f6eba93a9649ed24
--- /dev/null
+++ b/localCoverage/interfaceCoverage/results/coverage/interface_kits/coverage_summary_file.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/localCoverage/interfaceCoverage/results/coverage/interface_kits/ohos_interfaceCoverage.html b/localCoverage/interfaceCoverage/results/coverage/interface_kits/ohos_interfaceCoverage.html
new file mode 100644
index 0000000000000000000000000000000000000000..e506f9b41058743fd5414c45b414c886218e7bd4
--- /dev/null
+++ b/localCoverage/interfaceCoverage/results/coverage/interface_kits/ohos_interfaceCoverage.html
@@ -0,0 +1,1127 @@
+
+
+
+
+
+ 接口覆盖率邮件模板
+
+
+
+
+ Inner Interface coverage report (2022-08-23)
+
+
+
+  |
+
+ Summary Report
+ 接口总数147,已覆盖0,未覆盖147
+ |
+
+
+
+
+ Summary
+
+
+ SubsystemName |
+ TotalCount |
+ CoveredCount |
+ Coverage |
+
+
+ account |
+ 147 |
+ 0 |
+ 0.0% |
+
+
+
+ Summary |
+ 147 |
+ 0 |
+ 0.0% |
+
+
+
+ account details:
+
+
+ SubsystemName |
+ ClassName |
+ InterfaceName |
+ IsCovered |
+
+
+ account |
+ OsAccountSubscribeInfo |
+ OsAccountSubscribeInfo() |
+ N |
+
+
+
+ account |
+ OsAccountSubscribeInfo |
+ OsAccountSubscribeInfo(OS_ACCOUNT_SUBSCRIBE_TYPE &, std::string &) |
+ N |
+
+
+
+ account |
+ OsAccountSubscribeInfo |
+ ~OsAccountSubscribeInfo() |
+ N |
+
+
+
+ account |
+ OsAccountSubscribeInfo |
+ ErrCode GetOsAccountSubscribeType(OS_ACCOUNT_SUBSCRIBE_TYPE &) |
+ N |
+
+
+
+ account |
+ OsAccountSubscribeInfo |
+ ErrCode SetOsAccountSubscribeType(const OS_ACCOUNT_SUBSCRIBE_TYPE &) |
+ N |
+
+
+
+ account |
+ OsAccountSubscribeInfo |
+ ErrCode GetName(std::string &) |
+ N |
+
+
+
+ account |
+ OsAccountSubscribeInfo |
+ ErrCode SetName(const std::string &) |
+ N |
+
+
+
+ account |
+ OsAccountSubscribeInfo |
+ bool Marshalling(Parcel &) |
+ N |
+
+
+
+ account |
+ OsAccountSubscribeInfo |
+ OsAccountSubscribeInfo * Unmarshalling(Parcel &) |
+ N |
+
+
+
+ account |
+ OsAccountSubscriber |
+ OsAccountSubscriber() |
+ N |
+
+
+
+ account |
+ OsAccountSubscriber |
+ OsAccountSubscriber(const OsAccountSubscribeInfo &) |
+ N |
+
+
+
+ account |
+ OsAccountSubscriber |
+ ~OsAccountSubscriber() |
+ N |
+
+
+
+ account |
+ OsAccountSubscriber |
+ ErrCode GetSubscribeInfo(OsAccountSubscribeInfo &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode CreateOsAccount(const std::string &, const OsAccountType &, OsAccountInfo &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode CreateOsAccountForDomain(const OsAccountType &, const DomainAccountInfo &, OsAccountInfo &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode RemoveOsAccount(const int) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode IsOsAccountExists(const int, bool &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode IsOsAccountActived(const int, bool &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode IsOsAccountConstraintEnable(const int, const std::string &, bool &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode IsOsAccountVerified(const int, bool &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetCreatedOsAccountsCount(unsigned int &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetOsAccountLocalIdFromProcess(int &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode IsMainOsAccount(bool &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetOsAccountLocalIdFromUid(const int, int &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetBundleIdFromUid(const int, int &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetOsAccountLocalIdFromDomain(const DomainAccountInfo &, int &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode QueryMaxOsAccountNumber(int &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetOsAccountAllConstraints(const int, std::vector &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode QueryAllCreatedOsAccounts(std::vector &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode QueryCurrentOsAccount(OsAccountInfo &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode QueryOsAccountById(const int, OsAccountInfo &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetOsAccountTypeFromProcess(OsAccountType &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetOsAccountProfilePhoto(const int, std::string &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode IsMultiOsAccountEnable(bool &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode SetOsAccountName(const int, const std::string &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode SetOsAccountConstraints(const int, const std::vector &, const bool) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode SetOsAccountProfilePhoto(const int, const std::string &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetDistributedVirtualDeviceId(std::string &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode ActivateOsAccount(const int) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode StartOsAccount(const int) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode StopOsAccount(const int) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetOsAccountLocalIdBySerialNumber(const int64_t, int &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetSerialNumberByOsAccountLocalId(const int &, int64_t &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode SubscribeOsAccount(const std::shared_ptr &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode UnsubscribeOsAccount(const std::shared_ptr &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ OS_ACCOUNT_SWITCH_MOD GetOsAccountSwitchMod() |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode IsCurrentOsAccountVerified(bool &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode IsOsAccountCompleted(const int, bool &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode SetCurrentOsAccountIsVerified(const bool) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode SetOsAccountIsVerified(const int, const bool) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetCreatedOsAccountNumFromDatabase(const std::string &, int &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetSerialNumberFromDatabase(const std::string &, int64_t &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetMaxAllowCreateIdFromDatabase(const std::string &, int &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetOsAccountFromDatabase(const std::string &, const int, OsAccountInfo &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode GetOsAccountListFromDatabase(const std::string &, std::vector &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode QueryActiveOsAccountIds(std::vector &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode QueryOsAccountConstraintSourceTypes(const int32_t, const std::string, std::vector &) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode SetGlobalOsAccountConstraints(const std::vector &, const bool, const int32_t, const bool) |
+ N |
+
+
+
+ account |
+ OsAccountManager |
+ ErrCode SetSpecificOsAccountConstraints(const std::vector &, const bool, const int32_t, const int32_t, const bool) |
+ N |
+
+
+
+ account |
+ DomainAccountInfo |
+ DomainAccountInfo() |
+ N |
+
+
+
+ account |
+ DomainAccountInfo |
+ DomainAccountInfo(const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ DomainAccountInfo |
+ void Clear() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ OsAccountInfo() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ OsAccountInfo(int, const std::string, OsAccountType, int64_t) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ OsAccountInfo(int, std::string, OsAccountType, std::vector, bool, std::string, int64_t, int64_t, int64_t, bool) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ int GetLocalId() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetLocalId(int) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ std::string GetLocalName() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetLocalName(const std::string) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ OsAccountType GetType() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetType(OsAccountType) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ std::vector GetConstraints() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetConstraints(const std::vector) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ bool GetIsVerified() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetIsVerified(bool) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ std::string GetPhoto() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetPhoto(const std::string) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ int64_t GetCreateTime() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetCreateTime(const int64_t) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ int64_t GetLastLoginTime() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetLastLoginTime(const int64_t) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ Json ToJson() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void FromJson(const Json &) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ bool Marshalling(Parcel &) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ bool ReadFromParcel(Parcel &) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ std::string ToString() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ std::string GetPrimeKey() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ OsAccountInfo * Unmarshalling(Parcel &) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ int64_t GetSerialNumber() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetSerialNumber(const int64_t) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ bool GetIsActived() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetIsActived(const bool) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ bool GetIsCreateCompleted() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetIsCreateCompleted(const bool) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ bool SetDomainInfo(const DomainAccountInfo &) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void GetDomainInfo(DomainAccountInfo &) |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ bool GetToBeRemoved() |
+ N |
+
+
+
+ account |
+ OsAccountInfo |
+ void SetToBeRemoved(bool) |
+ N |
+
+
+
+ account |
+ OhosAccountKits |
+ OhosAccountKits & GetInstance() |
+ N |
+
+
+
+ account |
+ DeviceAccountInfo |
+ DeviceAccountInfo() |
+ N |
+
+
+
+ account |
+ DeviceAccountInfo |
+ DeviceAccountInfo(const std::int32_t, const DeviceAccountType, const std::string &) |
+ N |
+
+
+
+ account |
+ DeviceAccountInfo |
+ DeviceAccountInfo(const std::int32_t, const DeviceAccountType, const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ DeviceAccountInfo |
+ ~DeviceAccountInfo() |
+ N |
+
+
+
+ account |
+ DeviceAccountInfo |
+ bool operator==(const DeviceAccountInfo &) |
+ N |
+
+
+
+ account |
+ DeviceAccountInfo |
+ std::int32_t WriteDataToParcel(MessageParcel &) |
+ N |
+
+
+
+ account |
+ DeviceAccountInfo |
+ void ReadDataFromParcel(MessageParcel &) |
+ N |
+
+
+
+ account |
+ OhosAccountInfo |
+ OhosAccountInfo(const std::string &, const std::string &, std::int32_t) |
+ N |
+
+
+
+ account |
+ OhosAccountInfo |
+ OhosAccountInfo() |
+ N |
+
+
+
+ account |
+ OhosAccountInfo |
+ ~OhosAccountInfo() |
+ N |
+
+
+
+ account |
+ AccountInfo |
+ AccountInfo() |
+ N |
+
+
+
+ account |
+ AccountInfo |
+ AccountInfo(const std::string &, const std::string &, const std::int32_t &) |
+ N |
+
+
+
+ account |
+ AccountInfo |
+ bool operator==(const AccountInfo &) |
+ N |
+
+
+
+ account |
+ AccountInfo |
+ void clear(std::int32_t) |
+ N |
+
+
+
+ account |
+ AccountInfo |
+ ~AccountInfo() |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode AddAccount(const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode AddAccountImplicitly(const std::string &, const std::string &, const AAFwk::Want &, const sptr &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode DeleteAccount(const std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode GetAccountExtraInfo(const std::string &, std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode SetAccountExtraInfo(const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode EnableAppAccess(const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode DisableAppAccess(const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode CheckAppAccountSyncEnable(const std::string &, bool &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode SetAppAccountSyncEnable(const std::string &, const bool &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode GetAssociatedData(const std::string &, const std::string &, std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode SetAssociatedData(const std::string &, const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode GetAccountCredential(const std::string &, const std::string &, std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode SetAccountCredential(const std::string &, const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode Authenticate(const std::string &, const std::string &, const std::string &, const AAFwk::Want &, const sptr &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode GetOAuthToken(const std::string &, const std::string &, const std::string &, std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode SetOAuthToken(const std::string &, const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode DeleteOAuthToken(const std::string &, const std::string &, const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode SetOAuthTokenVisibility(const std::string &, const std::string &, const std::string &, bool) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode CheckOAuthTokenVisibility(const std::string &, const std::string &, const std::string &, bool &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode GetAuthenticatorInfo(const std::string &, AuthenticatorInfo &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode GetAllOAuthTokens(const std::string &, const std::string &, std::vector &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode GetOAuthList(const std::string &, const std::string &, std::set &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode GetAuthenticatorCallback(const std::string &, sptr &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode GetAllAccounts(const std::string &, std::vector &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode GetAllAccessibleAccounts(std::vector &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode CheckAppAccess(const std::string &, const std::string &, bool &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode DeleteAccountCredential(const std::string &, const std::string &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode SelectAccountsByOptions(const SelectAccountsOptions &, const sptr &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode VerifyCredential(const std::string &, const std::string &, const VerifyCredentialOptions &, const sptr &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode CheckAccountLabels(const std::string &, const std::string &, const std::vector &, const sptr &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode SetAuthenticatorProperties(const std::string &, const SetPropertiesOptions &, const sptr &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode SubscribeAppAccount(const std::shared_ptr &) |
+ N |
+
+
+
+ account |
+ AppAccountManager |
+ ErrCode UnsubscribeAppAccount(const std::shared_ptr &) |
+ N |
+
+
+
+ TotalCount: 147, CoveredCount:0, Coverage: 0.0% |
+
+
+
+
+
\ No newline at end of file
diff --git a/localCoverage/interfaceCoverage/results/coverage/interface_kits/test.png b/localCoverage/interfaceCoverage/results/coverage/interface_kits/test.png
new file mode 100644
index 0000000000000000000000000000000000000000..9926563cf3090c93597c170f83e1951d9fabb462
Binary files /dev/null and b/localCoverage/interfaceCoverage/results/coverage/interface_kits/test.png differ
diff --git a/src/core/command/run.py b/src/core/command/run.py
index d47b2b279a3d46cf283d0fa419e6459e8d058856..57baef8a5a689d83a4c87104932253784fe91f47 100644
--- a/src/core/command/run.py
+++ b/src/core/command/run.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# coding=utf-8
-
+import platform
#
# Copyright (c) 2020-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,12 +16,13 @@
# limitations under the License.
#
-import random
-from pydoc import classname
-import time
import os
import sys
+import time
+import random
import datetime
+import subprocess
+from pydoc import classname
import xml.etree.ElementTree as ElementTree
from core.constants import SchedulerType
@@ -179,6 +180,13 @@ class Run(object):
LOG.error("The test file list is empty.")
return
+ if options.coverage and platform.system() != "Windows":
+ print("sys.framework_root_dir", sys.framework_root_dir)
+ coverage_path = os.path.join(sys.framework_root_dir, "reports/coverage")
+ if os.path.exists(coverage_path):
+ coverage_process = subprocess.Popen("rm -rf %s" % coverage_path, shell=True)
+ coverage_process.communicate()
+
if ("distributedtest" in options.testtype and
len(options.testtype) == 1):
from core.command.distribute_utils import get_test_case
@@ -259,6 +267,17 @@ class Run(object):
del self.history_cmd_list[0]
self.history_cmd_list.append(cmd_record)
print("-------------run end: ", self.history_cmd_list)
+ if options.coverage and platform.system() != "Windows":
+ cov_main_file_path = os.path.join(sys.framework_root_dir, "localCoverage/coverage_tools.py")
+ print("cov_main_file_path", cov_main_file_path)
+ testpart = ",".join(list(map(str, options.partname_list)))
+ subsystem = ",".join(list(map(str, options.subsystem)))
+ if os.path.exists(cov_main_file_path):
+ subprocess.run("python3 %s testpart=%s subsystem=%s" % (
+ cov_main_file_path, testpart, subsystem), shell=True)
+ else:
+ print(f"{cov_main_file_path} not exists!")
+
return
##############################################################
diff --git a/src/core/driver/drivers.py b/src/core/driver/drivers.py
index f7a4771c05eefd152a7fbfca22b1e2ab1f78ce99..88cf5b345b5e5f8cd0d9231f266231ab031c5c37 100644
--- a/src/core/driver/drivers.py
+++ b/src/core/driver/drivers.py
@@ -1,1014 +1,1014 @@
-#!/usr/bin/env python3
-# coding=utf-8
-
-#
-# Copyright (c) 2020-2022 Huawei Device Co., Ltd.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import json
-import os
-import re
-import shutil
-import subprocess
-import time
-import platform
-import zipfile
-import stat
-from dataclasses import dataclass
-from json import JSONDecodeError
-
-from xdevice import DeviceTestType
-from xdevice import DeviceLabelType
-from xdevice import CommonParserType
-from xdevice import ExecuteTerminate
-from xdevice import DeviceError
-from xdevice import ShellHandler
-
-from xdevice import IDriver
-from xdevice import platform_logger
-from xdevice import Plugin
-from xdevice import get_plugin
-from ohos.environment.dmlib import process_command_ret
-from core.utils import get_decode
-from core.utils import get_fuzzer_path
-from core.config.resource_manager import ResourceManager
-from core.config.config_manager import FuzzerConfigManager
-
-__all__ = [
- "CppTestDriver",
- "JSUnitTestDriver",
- "disable_keyguard",
- "GTestConst"]
-
-LOG = platform_logger("Drivers")
-DEFAULT_TEST_PATH = "/%s/%s/" % ("data", "test")
-
-TIME_OUT = 900 * 1000
-JS_TIMEOUT = 10
-CYCLE_TIMES = 30
-
-
-##############################################################################
-##############################################################################
-
-
-class DisplayOutputReceiver:
- def __init__(self):
- self.output = ""
- self.unfinished_line = ""
-
- def _process_output(self, output, end_mark="\n"):
- content = output
- if self.unfinished_line:
- content = "".join((self.unfinished_line, content))
- self.unfinished_line = ""
- lines = content.split(end_mark)
- if content.endswith(end_mark):
- return lines[:-1]
- else:
- self.unfinished_line = lines[-1]
- return lines[:-1]
-
- def __read__(self, output):
- self.output = "%s%s" % (self.output, output)
- lines = self._process_output(output)
- for line in lines:
- line = line.strip()
- if line:
- LOG.info(get_decode(line))
-
- def __error__(self, message):
- pass
-
- def __done__(self, result_code="", message=""):
- pass
-
-
-@dataclass
-class GTestConst(object):
- exec_para_filter = "--gtest_filter"
- exec_para_level = "--gtest_testsize"
- exec_acts_para_filter = "--jstest_filter"
- exec_acts_para_level = "--jstest_testsize"
-
-
-def get_device_log_file(report_path, serial=None, log_name="device_log"):
- from xdevice import Variables
- log_path = os.path.join(report_path, Variables.report_vars.log_dir)
- os.makedirs(log_path, exist_ok=True)
-
- serial = serial or time.time_ns()
- device_file_name = "{}_{}.log".format(log_name, serial)
- device_log_file = os.path.join(log_path, device_file_name)
- return device_log_file
-
-
-def get_level_para_string(level_string):
- level_list = list(set(level_string.split(",")))
- level_para_string = ""
- for item in level_list:
- if not item.isdigit():
- continue
- item = item.strip(" ")
- level_para_string = f"{level_para_string}Level{item},"
- level_para_string = level_para_string.strip(",")
- return level_para_string
-
-
-def get_result_savepath(testsuit_path, result_rootpath):
- findkey = os.sep + "tests" + os.sep
- filedir, _ = os.path.split(testsuit_path)
- pos = filedir.find(findkey)
- if -1 != pos:
- subpath = filedir[pos + len(findkey):]
- pos1 = subpath.find(os.sep)
- if -1 != pos1:
- subpath = subpath[pos1 + len(os.sep):]
- result_path = os.path.join(result_rootpath, "result", subpath)
- else:
- result_path = os.path.join(result_rootpath, "result")
- else:
- result_path = os.path.join(result_rootpath, "result")
-
- if not os.path.exists(result_path):
- os.makedirs(result_path)
-
- LOG.info("result_savepath = " + result_path)
- return result_path
-
-
-# all testsuit common Unavailable test result xml
-def _create_empty_result_file(filepath, filename, error_message):
- error_message = str(error_message)
- error_message = error_message.replace("\"", "")
- error_message = error_message.replace("<", "")
- error_message = error_message.replace(">", "")
- error_message = error_message.replace("&", "")
- if filename.endswith(".hap"):
- filename = filename.split(".")[0]
- if not os.path.exists(filepath):
- with open(filepath, "w", encoding='utf-8') as file_desc:
- time_stamp = time.strftime("%Y-%m-%d %H:%M:%S",
- time.localtime())
- file_desc.write('\n')
- file_desc.write(
- '\n' % time_stamp)
- file_desc.write(
- ' \n' %
- (filename, error_message))
- file_desc.write(' \n')
- file_desc.write('\n')
- return
-
-
-def _unlock_screen(device):
- device.execute_shell_command("svc power stayon true")
- time.sleep(1)
-
-
-def _unlock_device(device):
- device.execute_shell_command("input keyevent 82")
- time.sleep(1)
- device.execute_shell_command("wm dismiss-keyguard")
- time.sleep(1)
-
-
-def _lock_screen(device):
- device.execute_shell_command("svc power stayon false")
- time.sleep(1)
-
-
-def disable_keyguard(device):
- _unlock_screen(device)
- _unlock_device(device)
-
-
-def _sleep_according_to_result(result):
- if result:
- time.sleep(1)
-
-
-def _create_fuzz_crash_file(filepath, filename):
- if not os.path.exists(filepath):
- with open(filepath, "w", encoding='utf-8') as file_desc:
- time_stamp = time.strftime("%Y-%m-%d %H:%M:%S",
- time.localtime())
- file_desc.write('\n')
- file_desc.write(
- '\n' % time_stamp)
- file_desc.write(
- ' \n' % filename)
- file_desc.write(
- ' \n' % (filename, filename))
- file_desc.write(
- ' \n')
- file_desc.write(' \n')
- file_desc.write(' \n')
- file_desc.write(' \n')
- file_desc.write('\n')
- return
-
-
-def _create_fuzz_pass_file(filepath, filename):
- if not os.path.exists(filepath):
- with open(filepath, "w", encoding='utf-8') as file_desc:
- time_stamp = time.strftime("%Y-%m-%d %H:%M:%S",
- time.localtime())
- file_desc.write('\n')
- file_desc.write(
- '\n' % time_stamp)
- file_desc.write(
- ' \n' % filename)
- file_desc.write(
- ' \n' % (filename, filename))
- file_desc.write(' \n')
- file_desc.write('\n')
- return
-
-
-def _create_fuzz_result_file(filepath, filename, error_message):
- error_message = str(error_message)
- error_message = error_message.replace("\"", "")
- error_message = error_message.replace("<", "")
- error_message = error_message.replace(">", "")
- error_message = error_message.replace("&", "")
- if "AddressSanitizer" in error_message:
- LOG.error("FUZZ TEST CRASH")
- _create_fuzz_crash_file(filepath, filename)
- elif re.search(r'Done (\b\d+\b) runs in (\b\d+\b) second',
- error_message, re.M) is not None:
- LOG.info("FUZZ TEST PASS")
- _create_fuzz_pass_file(filepath, filename)
- else:
- LOG.error("FUZZ TEST UNAVAILABLE")
- _create_empty_result_file(filepath, filename, error_message)
- return
-
-
-##############################################################################
-##############################################################################
-
-class ResultManager(object):
- def __init__(self, testsuit_path, config):
- self.testsuite_path = testsuit_path
- self.config = config
- self.result_rootpath = self.config.report_path
- self.device = self.config.device
- if testsuit_path.endswith(".hap"):
- self.device_testpath = self.config.test_hap_out_path
- else:
- self.device_testpath = self.config.target_test_path
- self.testsuite_name = os.path.basename(self.testsuite_path)
- self.is_coverage = False
-
- def set_is_coverage(self, is_coverage):
- self.is_coverage = is_coverage
-
- def get_test_results(self, error_message=""):
- # Get test result files
- filepath = self.obtain_test_result_file()
- if "fuzztest" == self.config.testtype[0]:
- LOG.info("create fuzz test report")
- _create_fuzz_result_file(filepath, self.testsuite_name,
- error_message)
- if not self.is_coverage:
- self._obtain_fuzz_corpus()
-
- if not os.path.exists(filepath):
- _create_empty_result_file(filepath, self.testsuite_name,
- error_message)
- if "benchmark" == self.config.testtype[0]:
- self._obtain_benchmark_result()
- # Get coverage data files
- if self.is_coverage:
- self.obtain_coverage_data()
-
- return filepath
-
- def _obtain_fuzz_corpus(self):
- command = f"cd {DEFAULT_TEST_PATH}; tar czf {self.testsuite_name}_corpus.tar.gz corpus;"
- self.config.device.execute_shell_command(command)
- result_save_path = get_result_savepath(self.testsuite_path, self.result_rootpath)
- LOG.info(f"fuzz_dir = {result_save_path}")
- self.device.pull_file(f"{DEFAULT_TEST_PATH}/{self.testsuite_name}_corpus.tar.gz", result_save_path)
-
- def _obtain_benchmark_result(self):
- benchmark_root_dir = os.path.abspath(
- os.path.join(self.result_rootpath, "benchmark"))
- benchmark_dir = os.path.abspath(
- os.path.join(benchmark_root_dir,
- self.get_result_sub_save_path(),
- self.testsuite_name))
-
- if not os.path.exists(benchmark_dir):
- os.makedirs(benchmark_dir)
-
- LOG.info("benchmark_dir = %s" % benchmark_dir)
- self.device.pull_file(os.path.join(self.device_testpath,
- "%s.json" % self.testsuite_name), benchmark_dir)
- if not os.path.exists(os.path.join(benchmark_dir,
- "%s.json" % self.testsuite_name)):
- os.rmdir(benchmark_dir)
- return benchmark_dir
-
- def get_result_sub_save_path(self):
- find_key = os.sep + "benchmark" + os.sep
- file_dir, _ = os.path.split(self.testsuite_path)
- pos = file_dir.find(find_key)
- subpath = ""
- if -1 != pos:
- subpath = file_dir[pos + len(find_key):]
- LOG.info("subpath = " + subpath)
- return subpath
-
- def obtain_test_result_file(self):
- result_save_path = get_result_savepath(self.testsuite_path,
- self.result_rootpath)
- result_file_path = os.path.join(result_save_path,
- "%s.xml" % self.testsuite_name)
-
- result_josn_file_path = os.path.join(result_save_path,
- "%s.json" % self.testsuite_name)
-
- if self.testsuite_path.endswith('.hap'):
- remote_result_file = os.path.join(self.device_testpath,
- "testcase_result.xml")
- remote_json_result_file = os.path.join(self.device_testpath,
- "%s.json" % self.testsuite_name)
- else:
- remote_result_file = os.path.join(self.device_testpath,
- "%s.xml" % self.testsuite_name)
- remote_json_result_file = os.path.join(self.device_testpath,
- "%s.json" % self.testsuite_name)
-
- if self.config.testtype[0] != "fuzztest":
- if self.device.is_file_exist(remote_result_file):
- self.device.pull_file(remote_result_file, result_file_path)
- elif self.device.is_file_exist(remote_json_result_file):
- self.device.pull_file(remote_json_result_file,
- result_josn_file_path)
- result_file_path = result_josn_file_path
- else:
- LOG.info("%s not exist", remote_result_file)
-
- return result_file_path
-
- def make_empty_result_file(self, error_message=""):
- result_savepath = get_result_savepath(self.testsuite_path,
- self.result_rootpath)
- result_filepath = os.path.join(result_savepath, "%s.xml" %
- self.testsuite_name)
- if not os.path.exists(result_filepath):
- _create_empty_result_file(result_filepath,
- self.testsuite_name, error_message)
-
- def is_exist_target_in_device(self, path, target):
- if platform.system() == "Windows":
- command = '\"ls -l %s | grep %s\"' % (path, target)
- else:
- command = "ls -l %s | grep %s" % (path, target)
-
- check_result = False
- stdout_info = self.device.execute_shell_command(command)
- if stdout_info != "" and stdout_info.find(target) != -1:
- check_result = True
- return check_result
-
- def obtain_coverage_data(self):
- cov_root_dir = os.path.abspath(os.path.join(
- self.result_rootpath,
- "..",
- "coverage",
- "data",
- "exec"))
-
- target_name = "obj"
- cxx_cov_path = os.path.abspath(os.path.join(
- self.result_rootpath,
- "..",
- "coverage",
- "data",
- "cxx",
- self.testsuite_name + '_' + self.config.testtype[0]))
-
- if self.is_exist_target_in_device(DEFAULT_TEST_PATH, target_name):
- if not os.path.exists(cxx_cov_path):
- os.makedirs(cxx_cov_path)
- self.config.device.execute_shell_command(
- "cd %s; tar -czf %s.tar.gz %s" % (DEFAULT_TEST_PATH, target_name, target_name))
- src_file_tar = os.path.join(DEFAULT_TEST_PATH, "%s.tar.gz" % target_name)
- self.device.pull_file(src_file_tar, cxx_cov_path, is_create=True, timeout=TIME_OUT)
- tar_path = os.path.join(cxx_cov_path, "%s.tar.gz" % target_name)
- if platform.system() == "Windows":
- process = subprocess.Popen("tar -zxf %s -C %s" % (tar_path, cxx_cov_path), shell=True)
- process.communicate()
- os.remove(tar_path)
- else:
- subprocess.Popen("tar -zxf %s -C %s > /dev/null 2>&1" %
- (tar_path, cxx_cov_path), shell=True)
- subprocess.Popen("rm -rf %s" % tar_path, shell=True)
-
-
-##############################################################################
-##############################################################################
-
-@Plugin(type=Plugin.DRIVER, id=DeviceTestType.cpp_test)
-class CppTestDriver(IDriver):
- """
- CppTest is a Test that runs a native test package on given device.
- """
- # test driver config
- config = None
- result = ""
-
- def __check_environment__(self, device_options):
- if len(device_options) == 1 and device_options[0].label is None:
- return True
- if len(device_options) != 1 or \
- device_options[0].label != DeviceLabelType.phone:
- return False
- return True
-
- def __check_config__(self, config):
- pass
-
- def __result__(self):
- return self.result if os.path.exists(self.result) else ""
-
- def __execute__(self, request):
- try:
- self.config = request.config
- self.config.target_test_path = DEFAULT_TEST_PATH
- self.config.device = request.config.environment.devices[0]
-
- suite_file = request.root.source.source_file
- LOG.debug("Testsuite FilePath: %s" % suite_file)
-
- if not suite_file:
- LOG.error("test source '%s' not exists" %
- request.root.source.source_string)
- return
-
- if not self.config.device:
- result = ResultManager(suite_file, self.config)
- result.set_is_coverage(False)
- result.make_empty_result_file(
- "No test device is found. ")
- return
- self.config.device.set_device_report_path(request.config.report_path)
- self.config.device.device_log_collector.start_hilog_task()
- self._init_gtest()
- self._run_gtest(suite_file)
-
- finally:
- serial = "{}_{}".format(str(request.config.device.__get_serial__()), time.time_ns())
- log_tar_file_name = "{}_{}".format(request.get_module_name(), str(serial).replace(
- ":", "_"))
- self.config.device.device_log_collector.stop_hilog_task(log_tar_file_name)
-
- def _init_gtest(self):
- self.config.device.connector_command("target mount")
- self.config.device.execute_shell_command(
- "rm -rf %s" % self.config.target_test_path)
- self.config.device.execute_shell_command(
- "mkdir -p %s" % self.config.target_test_path)
- self.config.device.execute_shell_command(
- "mount -o rw,remount,rw /")
- if "fuzztest" == self.config.testtype[0]:
- self.config.device.execute_shell_command(
- "mkdir -p %s" % os.path.join(self.config.target_test_path,
- "corpus"))
-
- def _run_gtest(self, suite_file):
- from xdevice import Variables
- filename = os.path.basename(suite_file)
- test_para = self._get_test_para(self.config.testcase,
- self.config.testlevel,
- self.config.testtype,
- self.config.target_test_path,
- suite_file,
- filename)
- is_coverage_test = True if self.config.coverage else False
-
- # push testsuite file
- self.config.device.push_file(suite_file, self.config.target_test_path)
- self._push_corpus_if_exist(suite_file)
-
- # push resource files
- resource_manager = ResourceManager()
- resource_data_dic, resource_dir = \
- resource_manager.get_resource_data_dic(suite_file)
- resource_manager.process_preparer_data(resource_data_dic, resource_dir,
- self.config.device)
- # execute testcase
- if not self.config.coverage:
- command = "cd %s; rm -rf %s.xml; chmod +x *; ./%s %s" % (
- self.config.target_test_path,
- filename,
- filename,
- test_para)
- else:
- coverage_outpath = self.config.coverage_outpath
- strip_num = len(coverage_outpath.strip("/").split("/"))
- if "fuzztest" == self.config.testtype[0]:
- self._push_corpus_cov_if_exist(suite_file)
- command = f"cd {self.config.target_test_path}; tar zxf {filename}_corpus.tar.gz; \
- rm -rf {filename}.xml; chmod +x *; GCOV_PREFIX=.; \
- GCOV_PREFIX_STRIP={strip_num} ./{filename} {test_para}"
- else:
- command = "cd %s; rm -rf %s.xml; chmod +x *; GCOV_PREFIX=. " \
- "GCOV_PREFIX_STRIP=%s ./%s %s" % \
- (self.config.target_test_path,
- filename,
- str(strip_num),
- filename,
- test_para)
-
- result = ResultManager(suite_file, self.config)
- result.set_is_coverage(is_coverage_test)
-
- try:
- # get result
- display_receiver = DisplayOutputReceiver()
- self.config.device.execute_shell_command(
- command,
- receiver=display_receiver,
- timeout=TIME_OUT,
- retry=0)
- return_message = display_receiver.output
- except (ExecuteTerminate, DeviceError) as exception:
- return_message = str(exception.args)
-
- self.result = result.get_test_results(return_message)
- resource_manager.process_cleaner_data(resource_data_dic,
- resource_dir,
- self.config.device)
-
- @staticmethod
- def _alter_init(name):
- lines = list()
- with open(name, "r") as f:
- for line in f:
- line_strip = line.strip()
- if not line_strip:
- continue
- if line_strip[0] != "#" and line_strip[0] != "/" and line_strip[0] != "*":
- lines.append(line_strip)
- with open(name, "w") as f:
- f.writelines(lines)
-
- def _push_corpus_cov_if_exist(self, suite_file):
- cov_file = suite_file + "_corpus.tar.gz"
- LOG.info("corpus_cov file :%s" % str(cov_file))
- self.config.device.push_file(cov_file, os.path.join(self.config.target_test_path))
-
- def _push_corpus_if_exist(self, suite_file):
- if "fuzztest" == self.config.testtype[0]:
- corpus_path = os.path.join(get_fuzzer_path(suite_file), "corpus")
- if not os.path.isdir(corpus_path):
- return
-
- corpus_dirs = []
- corpus_file_list = []
-
- for root, _, files in os.walk(corpus_path):
- if not files:
- continue
-
- corpus_dir = root.split("corpus")[-1]
- if corpus_dir != "":
- corpus_dirs.append(corpus_dir)
-
- for file in files:
- cp_file = os.path.normcase(os.path.join(root, file))
- corpus_file_list.append(cp_file)
- if file == "init":
- self._alter_init(cp_file)
-
- # mkdir corpus files dir
- if corpus_dirs:
- for corpus in corpus_dirs:
- mkdir_corpus_command = f"shell; mkdir -p {corpus}"
- self.config.device.connector_command(mkdir_corpus_command)
-
- # push corpus file
- if corpus_file_list:
- for corpus_file in corpus_file_list:
- self.config.device.push_file(corpus_file,
- os.path.join(self.config.target_test_path, "corpus"))
-
- def _get_test_para(self,
- testcase,
- testlevel,
- testtype,
- target_test_path,
- suite_file,
- filename):
- if "benchmark" == testtype[0]:
- test_para = (" --benchmark_out_format=json"
- " --benchmark_out=%s%s.json") % (
- target_test_path, filename)
- return test_para
-
- if "" != testcase and "" == testlevel:
- test_para = "%s=%s" % (GTestConst.exec_para_filter, testcase)
- elif "" == testcase and "" != testlevel:
- level_para = get_level_para_string(testlevel)
- test_para = "%s=%s" % (GTestConst.exec_para_level, level_para)
- else:
- test_para = ""
-
- if "fuzztest" == testtype[0]:
- cfg_list = FuzzerConfigManager(os.path.join(get_fuzzer_path(
- suite_file), "project.xml")).get_fuzzer_config("fuzztest")
- LOG.info("config list :%s" % str(cfg_list))
- if self.config.coverage:
- test_para += "corpus -runs=0" + \
- " -max_len=" + cfg_list[0] + \
- " -max_total_time=" + cfg_list[1] + \
- " -rss_limit_mb=" + cfg_list[2]
- else:
- test_para += "corpus -max_len=" + cfg_list[0] + \
- " -max_total_time=" + cfg_list[1] + \
- " -rss_limit_mb=" + cfg_list[2]
-
- return test_para
-
-
-##############################################################################
-##############################################################################
-
-@Plugin(type=Plugin.DRIVER, id=DeviceTestType.jsunit_test)
-class JSUnitTestDriver(IDriver):
- """
- JSUnitTestDriver is a Test that runs a native test package on given device.
- """
-
- def __init__(self):
- self.config = None
- self.result = ""
- self.start_time = None
- self.ability_name = ""
- self.package_name = ""
- # log
- self.hilog = None
- self.hilog_proc = None
-
- def __check_environment__(self, device_options):
- pass
-
- def __check_config__(self, config):
- pass
-
- def __result__(self):
- return self.result if os.path.exists(self.result) else ""
-
- def __execute__(self, request):
- try:
- LOG.info("developertest driver")
- self.result = os.path.join(
- request.config.report_path, "result",
- '.'.join((request.get_module_name(), "xml")))
- self.config = request.config
- self.config.target_test_path = DEFAULT_TEST_PATH
- self.config.device = request.config.environment.devices[0]
-
- suite_file = request.root.source.source_file
- if not suite_file:
- LOG.error("test source '%s' not exists" %
- request.root.source.source_string)
- return
-
- if not self.config.device:
- result = ResultManager(suite_file, self.config)
- result.set_is_coverage(False)
- result.make_empty_result_file(
- "No test device is found")
- return
-
- package_name, ability_name = self._get_package_and_ability_name(
- suite_file)
- self.package_name = package_name
- self.ability_name = ability_name
- self.config.test_hap_out_path = \
- "/data/data/%s/files/" % self.package_name
- self.config.device.connector_command("shell hilog -r")
-
- self.hilog = get_device_log_file(
- request.config.report_path,
- request.config.device.__get_serial__() + "_" + request.
- get_module_name(),
- "device_hilog")
-
- hilog_open = os.open(self.hilog, os.O_WRONLY | os.O_CREAT | os.O_APPEND,
- 0o755)
-
- with os.fdopen(hilog_open, "a") as hilog_file_pipe:
- self.config.device.device_log_collector.add_log_address(None, self.hilog)
- _, self.hilog_proc = self.config.device.device_log_collector.\
- start_catch_device_log(hilog_file_pipe=hilog_file_pipe)
- self._init_jsunit_test()
- self._run_jsunit(suite_file, self.hilog)
- hilog_file_pipe.flush()
- self.generate_console_output(self.hilog, request)
- finally:
- self.config.device.device_log_collector.remove_log_address(None, self.hilog)
- self.config.device.device_log_collector.stop_catch_device_log(self.hilog_proc)
-
- def _init_jsunit_test(self):
- self.config.device.connector_command("target mount")
- self.config.device.execute_shell_command(
- "rm -rf %s" % self.config.target_test_path)
- self.config.device.execute_shell_command(
- "mkdir -p %s" % self.config.target_test_path)
- self.config.device.execute_shell_command(
- "mount -o rw,remount,rw /")
-
- def _run_jsunit(self, suite_file, device_log_file):
- filename = os.path.basename(suite_file)
- _, suffix_name = os.path.splitext(filename)
-
- resource_manager = ResourceManager()
- resource_data_dic, resource_dir = resource_manager.get_resource_data_dic(suite_file)
- if suffix_name == ".hap":
- json_file_path = suite_file.replace(".hap", ".json")
- if os.path.exists(json_file_path):
- timeout = self._get_json_shell_timeout(json_file_path)
- else:
- timeout = ResourceManager.get_nodeattrib_data(resource_data_dic)
- else:
- timeout = ResourceManager.get_nodeattrib_data(resource_data_dic)
- resource_manager.process_preparer_data(resource_data_dic, resource_dir, self.config.device)
- main_result = self._install_hap(suite_file)
- result = ResultManager(suite_file, self.config)
- if main_result:
- self._execute_hapfile_jsunittest()
- try:
- status = False
- actiontime = JS_TIMEOUT
- times = CYCLE_TIMES
- if timeout:
- actiontime = timeout
- times = 1
- device_log_file_open = os.open(device_log_file, os.O_RDONLY, stat.S_IWUSR | stat.S_IRUSR)
- with os.fdopen(device_log_file_open, "r", encoding='utf-8') \
- as file_read_pipe:
- for i in range(0, times):
- if status:
- break
- else:
- time.sleep(float(actiontime))
- start_time = int(time.time())
- while True:
- data = file_read_pipe.readline()
- if data.find("JSApp:") != -1 and data.find("[end] run suites end") != -1:
- LOG.info("execute testcase successfully.")
- status = True
- break
- if int(time.time()) - start_time > 5:
- break
- finally:
- _lock_screen(self.config.device)
- self._uninstall_hap(self.package_name)
- else:
- self.result = result.get_test_results("Error: install hap failed")
- LOG.error("Error: install hap failed")
-
- resource_manager.process_cleaner_data(resource_data_dic, resource_dir, self.config.device)
-
- def generate_console_output(self, device_log_file, request):
- result_message = self.read_device_log(device_log_file)
-
- report_name = request.get_module_name()
- parsers = get_plugin(
- Plugin.PARSER, CommonParserType.jsunit)
- if parsers:
- parsers = parsers[:1]
- for listener in request.listeners:
- listener.device_sn = self.config.device.device_sn
- parser_instances = []
-
- for parser in parsers:
- parser_instance = parser.__class__()
- parser_instance.suites_name = report_name
- parser_instance.suite_name = report_name
- parser_instance.listeners = request.listeners
- parser_instances.append(parser_instance)
- handler = ShellHandler(parser_instances)
- process_command_ret(result_message, handler)
-
- def read_device_log(self, device_log_file):
- device_log_file_open = os.open(device_log_file, os.O_RDONLY,
- stat.S_IWUSR | stat.S_IRUSR)
-
- result_message = ""
- with os.fdopen(device_log_file_open, "r", encoding='utf-8') \
- as file_read_pipe:
- while True:
- data = file_read_pipe.readline()
- if not data:
- break
- # only filter JSApp log
- if data.find("JSApp:") != -1:
- result_message += data
- if data.find("[end] run suites end") != -1:
- break
- return result_message
-
- def _execute_hapfile_jsunittest(self):
- _unlock_screen(self.config.device)
- _unlock_device(self.config.device)
-
- try:
- return_message = self.start_hap_execute()
- except (ExecuteTerminate, DeviceError) as exception:
- return_message = str(exception.args)
-
- return return_message
-
- def _install_hap(self, suite_file):
- message = self.config.device.connector_command("install %s" % suite_file)
- message = str(message).rstrip()
- if message == "" or "success" in message:
- return_code = True
- if message != "":
- LOG.info(message)
- else:
- return_code = False
- if message != "":
- LOG.warning(message)
-
- _sleep_according_to_result(return_code)
- return return_code
-
- def start_hap_execute(self):
- try:
- command = "aa start -d 123 -a %s.MainAbility -b %s" \
- % (self.package_name, self.package_name)
- self.start_time = time.time()
- result_value = self.config.device.execute_shell_command(
- command, timeout=TIME_OUT)
-
- if "success" in str(result_value).lower():
- LOG.info("execute %s's testcase success. result value=%s"
- % (self.package_name, result_value))
- else:
- LOG.info("execute %s's testcase failed. result value=%s"
- % (self.package_name, result_value))
-
- _sleep_according_to_result(result_value)
- return_message = result_value
- except (ExecuteTerminate, DeviceError) as exception:
- return_message = exception.args
-
- return return_message
-
- def _uninstall_hap(self, package_name):
- return_message = self.config.device.execute_shell_command(
- "bm uninstall -n %s" % package_name)
- _sleep_according_to_result(return_message)
- return return_message
-
- @staticmethod
- def _get_acts_test_para(testcase,
- testlevel,
- testtype,
- target_test_path,
- suite_file,
- filename):
- if "actstest" == testtype[0]:
- test_para = (" --actstest_out_format=json"
- " --actstest_out=%s%s.json") % (
- target_test_path, filename)
- return test_para
-
- if "" != testcase and "" == testlevel:
- test_para = "%s=%s" % (GTestConst.exec_acts_para_filter, testcase)
- elif "" == testcase and "" != testlevel:
- level_para = get_level_para_string(testlevel)
- test_para = "%s=%s" % (GTestConst.exec_acts_para_level, level_para)
- else:
- test_para = ""
- return test_para
-
- @staticmethod
- def _get_hats_test_para(testcase,
- testlevel,
- testtype,
- target_test_path,
- suite_file,
- filename):
- if "hatstest" == testtype[0]:
- test_hats_para = (" --hatstest_out_format=json"
- " --hatstest_out=%s%s.json") % (
- target_test_path, filename)
- return test_hats_para
-
- if "" != testcase and "" == testlevel:
- test_hats_para = "%s=%s" % (GTestConst.exec_para_filter, testcase)
- elif "" == testcase and "" != testlevel:
- level_para = get_level_para_string(testlevel)
- test_hats_para = "%s=%s" % (GTestConst.exec_para_level, level_para)
- else:
- test_hats_para = ""
- return test_hats_para
-
- @classmethod
- def _get_json_shell_timeout(cls, json_filepath):
- test_timeout = 300
- try:
- with open(json_filepath, 'r') as json_file:
- data_dic = json.load(json_file)
- if not data_dic:
- return test_timeout
- else:
- if "driver" in data_dic.keys():
- driver_dict = data_dic.get("driver")
- if driver_dict and "test-timeout" in driver_dict.keys():
- test_timeout = int(driver_dict["shell-timeout"]) / 1000
- else:
- return
- return test_timeout
- except JSONDecodeError:
- return test_timeout
- finally:
- print(" get json shell timeout finally")
-
- @staticmethod
- def _get_package_and_ability_name(hap_filepath):
- package_name = ""
- ability_name = ""
- if os.path.exists(hap_filepath):
- filename = os.path.basename(hap_filepath)
-
- # unzip the hap file
- hap_bak_path = os.path.abspath(os.path.join(
- os.path.dirname(hap_filepath),
- "%s.bak" % filename))
- zf_desc = zipfile.ZipFile(hap_filepath)
- try:
- zf_desc.extractall(path=hap_bak_path)
- except RuntimeError as error:
- print(error)
- zf_desc.close()
-
- # verify config.json file
- app_profile_path = os.path.join(hap_bak_path, "config.json")
- if not os.path.exists(app_profile_path):
- print("file %s not exist" % app_profile_path)
- return package_name, ability_name
-
- if os.path.isdir(app_profile_path):
- print("%s is a folder, and not a file" % app_profile_path)
- return package_name, ability_name
-
- # get package_name and ability_name value
- load_dict = {}
- with open(app_profile_path, 'r') as load_f:
- load_dict = json.load(load_f)
- profile_list = load_dict.values()
- for profile in profile_list:
- package_name = profile.get("package")
- if not package_name:
- continue
- abilities = profile.get("abilities")
- for abilitie in abilities:
- abilities_name = abilitie.get("name")
- if abilities_name.startswith("."):
- ability_name = package_name + abilities_name[
- abilities_name.find("."):]
- else:
- ability_name = abilities_name
- break
- break
-
- # delete hap_bak_path
- if os.path.exists(hap_bak_path):
- shutil.rmtree(hap_bak_path)
- else:
- print("file %s not exist" % hap_filepath)
- return package_name, ability_name
+#!/usr/bin/env python3
+# coding=utf-8
+
+#
+# Copyright (c) 2020-2022 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import json
+import os
+import re
+import shutil
+import subprocess
+import time
+import platform
+import zipfile
+import stat
+from dataclasses import dataclass
+from json import JSONDecodeError
+
+from xdevice import DeviceTestType
+from xdevice import DeviceLabelType
+from xdevice import CommonParserType
+from xdevice import ExecuteTerminate
+from xdevice import DeviceError
+from xdevice import ShellHandler
+
+from xdevice import IDriver
+from xdevice import platform_logger
+from xdevice import Plugin
+from xdevice import get_plugin
+from ohos.environment.dmlib import process_command_ret
+from core.utils import get_decode
+from core.utils import get_fuzzer_path
+from core.config.resource_manager import ResourceManager
+from core.config.config_manager import FuzzerConfigManager
+
+__all__ = [
+ "CppTestDriver",
+ "JSUnitTestDriver",
+ "disable_keyguard",
+ "GTestConst"]
+
+LOG = platform_logger("Drivers")
+DEFAULT_TEST_PATH = "/%s/%s/" % ("data", "test")
+
+TIME_OUT = 900 * 1000
+JS_TIMEOUT = 10
+CYCLE_TIMES = 30
+
+
+##############################################################################
+##############################################################################
+
+
+class DisplayOutputReceiver:
+ def __init__(self):
+ self.output = ""
+ self.unfinished_line = ""
+
+ def _process_output(self, output, end_mark="\n"):
+ content = output
+ if self.unfinished_line:
+ content = "".join((self.unfinished_line, content))
+ self.unfinished_line = ""
+ lines = content.split(end_mark)
+ if content.endswith(end_mark):
+ return lines[:-1]
+ else:
+ self.unfinished_line = lines[-1]
+ return lines[:-1]
+
+ def __read__(self, output):
+ self.output = "%s%s" % (self.output, output)
+ lines = self._process_output(output)
+ for line in lines:
+ line = line.strip()
+ if line:
+ LOG.info(get_decode(line))
+
+ def __error__(self, message):
+ pass
+
+ def __done__(self, result_code="", message=""):
+ pass
+
+
+@dataclass
+class GTestConst(object):
+ exec_para_filter = "--gtest_filter"
+ exec_para_level = "--gtest_testsize"
+ exec_acts_para_filter = "--jstest_filter"
+ exec_acts_para_level = "--jstest_testsize"
+
+
+def get_device_log_file(report_path, serial=None, log_name="device_log"):
+ from xdevice import Variables
+ log_path = os.path.join(report_path, Variables.report_vars.log_dir)
+ os.makedirs(log_path, exist_ok=True)
+
+ serial = serial or time.time_ns()
+ device_file_name = "{}_{}.log".format(log_name, serial)
+ device_log_file = os.path.join(log_path, device_file_name)
+ return device_log_file
+
+
+def get_level_para_string(level_string):
+ level_list = list(set(level_string.split(",")))
+ level_para_string = ""
+ for item in level_list:
+ if not item.isdigit():
+ continue
+ item = item.strip(" ")
+ level_para_string = f"{level_para_string}Level{item},"
+ level_para_string = level_para_string.strip(",")
+ return level_para_string
+
+
+def get_result_savepath(testsuit_path, result_rootpath):
+ findkey = os.sep + "tests" + os.sep
+ filedir, _ = os.path.split(testsuit_path)
+ pos = filedir.find(findkey)
+ if -1 != pos:
+ subpath = filedir[pos + len(findkey):]
+ pos1 = subpath.find(os.sep)
+ if -1 != pos1:
+ subpath = subpath[pos1 + len(os.sep):]
+ result_path = os.path.join(result_rootpath, "result", subpath)
+ else:
+ result_path = os.path.join(result_rootpath, "result")
+ else:
+ result_path = os.path.join(result_rootpath, "result")
+
+ if not os.path.exists(result_path):
+ os.makedirs(result_path)
+
+ LOG.info("result_savepath = " + result_path)
+ return result_path
+
+
+# all testsuit common Unavailable test result xml
+def _create_empty_result_file(filepath, filename, error_message):
+ error_message = str(error_message)
+ error_message = error_message.replace("\"", "")
+ error_message = error_message.replace("<", "")
+ error_message = error_message.replace(">", "")
+ error_message = error_message.replace("&", "")
+ if filename.endswith(".hap"):
+ filename = filename.split(".")[0]
+ if not os.path.exists(filepath):
+ with open(filepath, "w", encoding='utf-8') as file_desc:
+ time_stamp = time.strftime("%Y-%m-%d %H:%M:%S",
+ time.localtime())
+ file_desc.write('\n')
+ file_desc.write(
+ '\n' % time_stamp)
+ file_desc.write(
+ ' \n' %
+ (filename, error_message))
+ file_desc.write(' \n')
+ file_desc.write('\n')
+ return
+
+
+def _unlock_screen(device):
+ device.execute_shell_command("svc power stayon true")
+ time.sleep(1)
+
+
+def _unlock_device(device):
+ device.execute_shell_command("input keyevent 82")
+ time.sleep(1)
+ device.execute_shell_command("wm dismiss-keyguard")
+ time.sleep(1)
+
+
+def _lock_screen(device):
+ device.execute_shell_command("svc power stayon false")
+ time.sleep(1)
+
+
+def disable_keyguard(device):
+ _unlock_screen(device)
+ _unlock_device(device)
+
+
+def _sleep_according_to_result(result):
+ if result:
+ time.sleep(1)
+
+
+def _create_fuzz_crash_file(filepath, filename):
+ if not os.path.exists(filepath):
+ with open(filepath, "w", encoding='utf-8') as file_desc:
+ time_stamp = time.strftime("%Y-%m-%d %H:%M:%S",
+ time.localtime())
+ file_desc.write('\n')
+ file_desc.write(
+ '\n' % time_stamp)
+ file_desc.write(
+ ' \n' % filename)
+ file_desc.write(
+ ' \n' % (filename, filename))
+ file_desc.write(
+ ' \n')
+ file_desc.write(' \n')
+ file_desc.write(' \n')
+ file_desc.write(' \n')
+ file_desc.write('\n')
+ return
+
+
+def _create_fuzz_pass_file(filepath, filename):
+ if not os.path.exists(filepath):
+ with open(filepath, "w", encoding='utf-8') as file_desc:
+ time_stamp = time.strftime("%Y-%m-%d %H:%M:%S",
+ time.localtime())
+ file_desc.write('\n')
+ file_desc.write(
+ '\n' % time_stamp)
+ file_desc.write(
+ ' \n' % filename)
+ file_desc.write(
+ ' \n' % (filename, filename))
+ file_desc.write(' \n')
+ file_desc.write('\n')
+ return
+
+
+def _create_fuzz_result_file(filepath, filename, error_message):
+ error_message = str(error_message)
+ error_message = error_message.replace("\"", "")
+ error_message = error_message.replace("<", "")
+ error_message = error_message.replace(">", "")
+ error_message = error_message.replace("&", "")
+ if "AddressSanitizer" in error_message:
+ LOG.error("FUZZ TEST CRASH")
+ _create_fuzz_crash_file(filepath, filename)
+ elif re.search(r'Done (\b\d+\b) runs in (\b\d+\b) second',
+ error_message, re.M) is not None:
+ LOG.info("FUZZ TEST PASS")
+ _create_fuzz_pass_file(filepath, filename)
+ else:
+ LOG.error("FUZZ TEST UNAVAILABLE")
+ _create_empty_result_file(filepath, filename, error_message)
+ return
+
+
+##############################################################################
+##############################################################################
+
+class ResultManager(object):
+ def __init__(self, testsuit_path, config):
+ self.testsuite_path = testsuit_path
+ self.config = config
+ self.result_rootpath = self.config.report_path
+ self.device = self.config.device
+ if testsuit_path.endswith(".hap"):
+ self.device_testpath = self.config.test_hap_out_path
+ else:
+ self.device_testpath = self.config.target_test_path
+ self.testsuite_name = os.path.basename(self.testsuite_path)
+ self.is_coverage = False
+
+ def set_is_coverage(self, is_coverage):
+ self.is_coverage = is_coverage
+
+ def get_test_results(self, error_message=""):
+ # Get test result files
+ filepath = self.obtain_test_result_file()
+ if "fuzztest" == self.config.testtype[0]:
+ LOG.info("create fuzz test report")
+ _create_fuzz_result_file(filepath, self.testsuite_name,
+ error_message)
+ if not self.is_coverage:
+ self._obtain_fuzz_corpus()
+
+ if not os.path.exists(filepath):
+ _create_empty_result_file(filepath, self.testsuite_name,
+ error_message)
+ if "benchmark" == self.config.testtype[0]:
+ self._obtain_benchmark_result()
+ # Get coverage data files
+ if self.is_coverage:
+ self.obtain_coverage_data()
+
+ return filepath
+
+ def _obtain_fuzz_corpus(self):
+ command = f"cd {DEFAULT_TEST_PATH}; tar czf {self.testsuite_name}_corpus.tar.gz corpus;"
+ self.config.device.execute_shell_command(command)
+ result_save_path = get_result_savepath(self.testsuite_path, self.result_rootpath)
+ LOG.info(f"fuzz_dir = {result_save_path}")
+ self.device.pull_file(f"{DEFAULT_TEST_PATH}/{self.testsuite_name}_corpus.tar.gz", result_save_path)
+
+ def _obtain_benchmark_result(self):
+ benchmark_root_dir = os.path.abspath(
+ os.path.join(self.result_rootpath, "benchmark"))
+ benchmark_dir = os.path.abspath(
+ os.path.join(benchmark_root_dir,
+ self.get_result_sub_save_path(),
+ self.testsuite_name))
+
+ if not os.path.exists(benchmark_dir):
+ os.makedirs(benchmark_dir)
+
+ LOG.info("benchmark_dir = %s" % benchmark_dir)
+ self.device.pull_file(os.path.join(self.device_testpath,
+ "%s.json" % self.testsuite_name), benchmark_dir)
+ if not os.path.exists(os.path.join(benchmark_dir,
+ "%s.json" % self.testsuite_name)):
+ os.rmdir(benchmark_dir)
+ return benchmark_dir
+
+ def get_result_sub_save_path(self):
+ find_key = os.sep + "benchmark" + os.sep
+ file_dir, _ = os.path.split(self.testsuite_path)
+ pos = file_dir.find(find_key)
+ subpath = ""
+ if -1 != pos:
+ subpath = file_dir[pos + len(find_key):]
+ LOG.info("subpath = " + subpath)
+ return subpath
+
+ def obtain_test_result_file(self):
+ result_save_path = get_result_savepath(self.testsuite_path,
+ self.result_rootpath)
+ result_file_path = os.path.join(result_save_path,
+ "%s.xml" % self.testsuite_name)
+
+ result_josn_file_path = os.path.join(result_save_path,
+ "%s.json" % self.testsuite_name)
+
+ if self.testsuite_path.endswith('.hap'):
+ remote_result_file = os.path.join(self.device_testpath,
+ "testcase_result.xml")
+ remote_json_result_file = os.path.join(self.device_testpath,
+ "%s.json" % self.testsuite_name)
+ else:
+ remote_result_file = os.path.join(self.device_testpath,
+ "%s.xml" % self.testsuite_name)
+ remote_json_result_file = os.path.join(self.device_testpath,
+ "%s.json" % self.testsuite_name)
+
+ if self.config.testtype[0] != "fuzztest":
+ if self.device.is_file_exist(remote_result_file):
+ self.device.pull_file(remote_result_file, result_file_path)
+ elif self.device.is_file_exist(remote_json_result_file):
+ self.device.pull_file(remote_json_result_file,
+ result_josn_file_path)
+ result_file_path = result_josn_file_path
+ else:
+ LOG.info("%s not exist", remote_result_file)
+
+ return result_file_path
+
+ def make_empty_result_file(self, error_message=""):
+ result_savepath = get_result_savepath(self.testsuite_path,
+ self.result_rootpath)
+ result_filepath = os.path.join(result_savepath, "%s.xml" %
+ self.testsuite_name)
+ if not os.path.exists(result_filepath):
+ _create_empty_result_file(result_filepath,
+ self.testsuite_name, error_message)
+
+ def is_exist_target_in_device(self, path, target):
+ if platform.system() == "Windows":
+ command = '\"ls -l %s | grep %s\"' % (path, target)
+ else:
+ command = "ls -l %s | grep %s" % (path, target)
+
+ check_result = False
+ stdout_info = self.device.execute_shell_command(command)
+ if stdout_info != "" and stdout_info.find(target) != -1:
+ check_result = True
+ return check_result
+
+ def obtain_coverage_data(self):
+ cov_root_dir = os.path.abspath(os.path.join(
+ self.result_rootpath,
+ "..",
+ "coverage",
+ "data",
+ "exec"))
+
+ target_name = "obj"
+ cxx_cov_path = os.path.abspath(os.path.join(
+ self.result_rootpath,
+ "..",
+ "coverage",
+ "data",
+ "cxx",
+ self.testsuite_name + '_' + self.config.testtype[0]))
+
+ if self.is_exist_target_in_device(DEFAULT_TEST_PATH, target_name):
+ if not os.path.exists(cxx_cov_path):
+ os.makedirs(cxx_cov_path)
+ self.config.device.execute_shell_command(
+ "cd %s; tar -czf %s.tar.gz %s" % (DEFAULT_TEST_PATH, target_name, target_name))
+ src_file_tar = os.path.join(DEFAULT_TEST_PATH, "%s.tar.gz" % target_name)
+ self.device.pull_file(src_file_tar, cxx_cov_path, is_create=True, timeout=TIME_OUT)
+ tar_path = os.path.join(cxx_cov_path, "%s.tar.gz" % target_name)
+ if platform.system() == "Windows":
+ process = subprocess.Popen("tar -zxf %s -C %s" % (tar_path, cxx_cov_path), shell=True)
+ process.communicate()
+ os.remove(tar_path)
+ else:
+ subprocess.Popen("tar -zxf %s -C %s > /dev/null 2>&1" %
+ (tar_path, cxx_cov_path), shell=True).communicate()
+ subprocess.Popen("rm -rf %s" % tar_path, shell=True).communicate()
+
+
+##############################################################################
+##############################################################################
+
+@Plugin(type=Plugin.DRIVER, id=DeviceTestType.cpp_test)
+class CppTestDriver(IDriver):
+ """
+ CppTest is a Test that runs a native test package on given device.
+ """
+ # test driver config
+ config = None
+ result = ""
+
+ def __check_environment__(self, device_options):
+ if len(device_options) == 1 and device_options[0].label is None:
+ return True
+ if len(device_options) != 1 or \
+ device_options[0].label != DeviceLabelType.phone:
+ return False
+ return True
+
+ def __check_config__(self, config):
+ pass
+
+ def __result__(self):
+ return self.result if os.path.exists(self.result) else ""
+
+ def __execute__(self, request):
+ try:
+ self.config = request.config
+ self.config.target_test_path = DEFAULT_TEST_PATH
+ self.config.device = request.config.environment.devices[0]
+
+ suite_file = request.root.source.source_file
+ LOG.debug("Testsuite FilePath: %s" % suite_file)
+
+ if not suite_file:
+ LOG.error("test source '%s' not exists" %
+ request.root.source.source_string)
+ return
+
+ if not self.config.device:
+ result = ResultManager(suite_file, self.config)
+ result.set_is_coverage(False)
+ result.make_empty_result_file(
+ "No test device is found. ")
+ return
+ self.config.device.set_device_report_path(request.config.report_path)
+ self.config.device.device_log_collector.start_hilog_task()
+ self._init_gtest()
+ self._run_gtest(suite_file)
+
+ finally:
+ serial = "{}_{}".format(str(request.config.device.__get_serial__()), time.time_ns())
+ log_tar_file_name = "{}_{}".format(request.get_module_name(), str(serial).replace(
+ ":", "_"))
+ self.config.device.device_log_collector.stop_hilog_task(log_tar_file_name)
+
+ def _init_gtest(self):
+ self.config.device.connector_command("target mount")
+ self.config.device.execute_shell_command(
+ "rm -rf %s" % self.config.target_test_path)
+ self.config.device.execute_shell_command(
+ "mkdir -p %s" % self.config.target_test_path)
+ self.config.device.execute_shell_command(
+ "mount -o rw,remount,rw /")
+ if "fuzztest" == self.config.testtype[0]:
+ self.config.device.execute_shell_command(
+ "mkdir -p %s" % os.path.join(self.config.target_test_path,
+ "corpus"))
+
+ def _run_gtest(self, suite_file):
+ from xdevice import Variables
+ filename = os.path.basename(suite_file)
+ test_para = self._get_test_para(self.config.testcase,
+ self.config.testlevel,
+ self.config.testtype,
+ self.config.target_test_path,
+ suite_file,
+ filename)
+ is_coverage_test = True if self.config.coverage else False
+
+ # push testsuite file
+ self.config.device.push_file(suite_file, self.config.target_test_path)
+ self._push_corpus_if_exist(suite_file)
+
+ # push resource files
+ resource_manager = ResourceManager()
+ resource_data_dic, resource_dir = \
+ resource_manager.get_resource_data_dic(suite_file)
+ resource_manager.process_preparer_data(resource_data_dic, resource_dir,
+ self.config.device)
+ # execute testcase
+ if not self.config.coverage:
+ command = "cd %s; rm -rf %s.xml; chmod +x *; ./%s %s" % (
+ self.config.target_test_path,
+ filename,
+ filename,
+ test_para)
+ else:
+ coverage_outpath = self.config.coverage_outpath
+ strip_num = len(coverage_outpath.strip("/").split("/"))
+ if "fuzztest" == self.config.testtype[0]:
+ self._push_corpus_cov_if_exist(suite_file)
+ command = f"cd {self.config.target_test_path}; tar zxf {filename}_corpus.tar.gz; \
+ rm -rf {filename}.xml; chmod +x *; GCOV_PREFIX=.; \
+ GCOV_PREFIX_STRIP={strip_num} ./{filename} {test_para}"
+ else:
+ command = "cd %s; rm -rf %s.xml; chmod +x *; GCOV_PREFIX=. " \
+ "GCOV_PREFIX_STRIP=%s ./%s %s" % \
+ (self.config.target_test_path,
+ filename,
+ str(strip_num),
+ filename,
+ test_para)
+
+ result = ResultManager(suite_file, self.config)
+ result.set_is_coverage(is_coverage_test)
+
+ try:
+ # get result
+ display_receiver = DisplayOutputReceiver()
+ self.config.device.execute_shell_command(
+ command,
+ receiver=display_receiver,
+ timeout=TIME_OUT,
+ retry=0)
+ return_message = display_receiver.output
+ except (ExecuteTerminate, DeviceError) as exception:
+ return_message = str(exception.args)
+
+ self.result = result.get_test_results(return_message)
+ resource_manager.process_cleaner_data(resource_data_dic,
+ resource_dir,
+ self.config.device)
+
+ @staticmethod
+ def _alter_init(name):
+ lines = list()
+ with open(name, "r") as f:
+ for line in f:
+ line_strip = line.strip()
+ if not line_strip:
+ continue
+ if line_strip[0] != "#" and line_strip[0] != "/" and line_strip[0] != "*":
+ lines.append(line_strip)
+ with open(name, "w") as f:
+ f.writelines(lines)
+
+ def _push_corpus_cov_if_exist(self, suite_file):
+ cov_file = suite_file + "_corpus.tar.gz"
+ LOG.info("corpus_cov file :%s" % str(cov_file))
+ self.config.device.push_file(cov_file, os.path.join(self.config.target_test_path))
+
+ def _push_corpus_if_exist(self, suite_file):
+ if "fuzztest" == self.config.testtype[0]:
+ corpus_path = os.path.join(get_fuzzer_path(suite_file), "corpus")
+ if not os.path.isdir(corpus_path):
+ return
+
+ corpus_dirs = []
+ corpus_file_list = []
+
+ for root, _, files in os.walk(corpus_path):
+ if not files:
+ continue
+
+ corpus_dir = root.split("corpus")[-1]
+ if corpus_dir != "":
+ corpus_dirs.append(corpus_dir)
+
+ for file in files:
+ cp_file = os.path.normcase(os.path.join(root, file))
+ corpus_file_list.append(cp_file)
+ if file == "init":
+ self._alter_init(cp_file)
+
+ # mkdir corpus files dir
+ if corpus_dirs:
+ for corpus in corpus_dirs:
+ mkdir_corpus_command = f"shell; mkdir -p {corpus}"
+ self.config.device.connector_command(mkdir_corpus_command)
+
+ # push corpus file
+ if corpus_file_list:
+ for corpus_file in corpus_file_list:
+ self.config.device.push_file(corpus_file,
+ os.path.join(self.config.target_test_path, "corpus"))
+
+ def _get_test_para(self,
+ testcase,
+ testlevel,
+ testtype,
+ target_test_path,
+ suite_file,
+ filename):
+ if "benchmark" == testtype[0]:
+ test_para = (" --benchmark_out_format=json"
+ " --benchmark_out=%s%s.json") % (
+ target_test_path, filename)
+ return test_para
+
+ if "" != testcase and "" == testlevel:
+ test_para = "%s=%s" % (GTestConst.exec_para_filter, testcase)
+ elif "" == testcase and "" != testlevel:
+ level_para = get_level_para_string(testlevel)
+ test_para = "%s=%s" % (GTestConst.exec_para_level, level_para)
+ else:
+ test_para = ""
+
+ if "fuzztest" == testtype[0]:
+ cfg_list = FuzzerConfigManager(os.path.join(get_fuzzer_path(
+ suite_file), "project.xml")).get_fuzzer_config("fuzztest")
+ LOG.info("config list :%s" % str(cfg_list))
+ if self.config.coverage:
+ test_para += "corpus -runs=0" + \
+ " -max_len=" + cfg_list[0] + \
+ " -max_total_time=" + cfg_list[1] + \
+ " -rss_limit_mb=" + cfg_list[2]
+ else:
+ test_para += "corpus -max_len=" + cfg_list[0] + \
+ " -max_total_time=" + cfg_list[1] + \
+ " -rss_limit_mb=" + cfg_list[2]
+
+ return test_para
+
+
+##############################################################################
+##############################################################################
+
+@Plugin(type=Plugin.DRIVER, id=DeviceTestType.jsunit_test)
+class JSUnitTestDriver(IDriver):
+ """
+ JSUnitTestDriver is a Test that runs a native test package on given device.
+ """
+
+ def __init__(self):
+ self.config = None
+ self.result = ""
+ self.start_time = None
+ self.ability_name = ""
+ self.package_name = ""
+ # log
+ self.hilog = None
+ self.hilog_proc = None
+
+ def __check_environment__(self, device_options):
+ pass
+
+ def __check_config__(self, config):
+ pass
+
+ def __result__(self):
+ return self.result if os.path.exists(self.result) else ""
+
+ def __execute__(self, request):
+ try:
+ LOG.info("developertest driver")
+ self.result = os.path.join(
+ request.config.report_path, "result",
+ '.'.join((request.get_module_name(), "xml")))
+ self.config = request.config
+ self.config.target_test_path = DEFAULT_TEST_PATH
+ self.config.device = request.config.environment.devices[0]
+
+ suite_file = request.root.source.source_file
+ if not suite_file:
+ LOG.error("test source '%s' not exists" %
+ request.root.source.source_string)
+ return
+
+ if not self.config.device:
+ result = ResultManager(suite_file, self.config)
+ result.set_is_coverage(False)
+ result.make_empty_result_file(
+ "No test device is found")
+ return
+
+ package_name, ability_name = self._get_package_and_ability_name(
+ suite_file)
+ self.package_name = package_name
+ self.ability_name = ability_name
+ self.config.test_hap_out_path = \
+ "/data/data/%s/files/" % self.package_name
+ self.config.device.connector_command("shell hilog -r")
+
+ self.hilog = get_device_log_file(
+ request.config.report_path,
+ request.config.device.__get_serial__() + "_" + request.
+ get_module_name(),
+ "device_hilog")
+
+ hilog_open = os.open(self.hilog, os.O_WRONLY | os.O_CREAT | os.O_APPEND,
+ 0o755)
+
+ with os.fdopen(hilog_open, "a") as hilog_file_pipe:
+ self.config.device.device_log_collector.add_log_address(None, self.hilog)
+ _, self.hilog_proc = self.config.device.device_log_collector.\
+ start_catch_device_log(hilog_file_pipe=hilog_file_pipe)
+ self._init_jsunit_test()
+ self._run_jsunit(suite_file, self.hilog)
+ hilog_file_pipe.flush()
+ self.generate_console_output(self.hilog, request)
+ finally:
+ self.config.device.device_log_collector.remove_log_address(None, self.hilog)
+ self.config.device.device_log_collector.stop_catch_device_log(self.hilog_proc)
+
+ def _init_jsunit_test(self):
+ self.config.device.connector_command("target mount")
+ self.config.device.execute_shell_command(
+ "rm -rf %s" % self.config.target_test_path)
+ self.config.device.execute_shell_command(
+ "mkdir -p %s" % self.config.target_test_path)
+ self.config.device.execute_shell_command(
+ "mount -o rw,remount,rw /")
+
+ def _run_jsunit(self, suite_file, device_log_file):
+ filename = os.path.basename(suite_file)
+ _, suffix_name = os.path.splitext(filename)
+
+ resource_manager = ResourceManager()
+ resource_data_dic, resource_dir = resource_manager.get_resource_data_dic(suite_file)
+ if suffix_name == ".hap":
+ json_file_path = suite_file.replace(".hap", ".json")
+ if os.path.exists(json_file_path):
+ timeout = self._get_json_shell_timeout(json_file_path)
+ else:
+ timeout = ResourceManager.get_nodeattrib_data(resource_data_dic)
+ else:
+ timeout = ResourceManager.get_nodeattrib_data(resource_data_dic)
+ resource_manager.process_preparer_data(resource_data_dic, resource_dir, self.config.device)
+ main_result = self._install_hap(suite_file)
+ result = ResultManager(suite_file, self.config)
+ if main_result:
+ self._execute_hapfile_jsunittest()
+ try:
+ status = False
+ actiontime = JS_TIMEOUT
+ times = CYCLE_TIMES
+ if timeout:
+ actiontime = timeout
+ times = 1
+ device_log_file_open = os.open(device_log_file, os.O_RDONLY, stat.S_IWUSR | stat.S_IRUSR)
+ with os.fdopen(device_log_file_open, "r", encoding='utf-8') \
+ as file_read_pipe:
+ for i in range(0, times):
+ if status:
+ break
+ else:
+ time.sleep(float(actiontime))
+ start_time = int(time.time())
+ while True:
+ data = file_read_pipe.readline()
+ if data.find("JSApp:") != -1 and data.find("[end] run suites end") != -1:
+ LOG.info("execute testcase successfully.")
+ status = True
+ break
+ if int(time.time()) - start_time > 5:
+ break
+ finally:
+ _lock_screen(self.config.device)
+ self._uninstall_hap(self.package_name)
+ else:
+ self.result = result.get_test_results("Error: install hap failed")
+ LOG.error("Error: install hap failed")
+
+ resource_manager.process_cleaner_data(resource_data_dic, resource_dir, self.config.device)
+
+ def generate_console_output(self, device_log_file, request):
+ result_message = self.read_device_log(device_log_file)
+
+ report_name = request.get_module_name()
+ parsers = get_plugin(
+ Plugin.PARSER, CommonParserType.jsunit)
+ if parsers:
+ parsers = parsers[:1]
+ for listener in request.listeners:
+ listener.device_sn = self.config.device.device_sn
+ parser_instances = []
+
+ for parser in parsers:
+ parser_instance = parser.__class__()
+ parser_instance.suites_name = report_name
+ parser_instance.suite_name = report_name
+ parser_instance.listeners = request.listeners
+ parser_instances.append(parser_instance)
+ handler = ShellHandler(parser_instances)
+ process_command_ret(result_message, handler)
+
+ def read_device_log(self, device_log_file):
+ device_log_file_open = os.open(device_log_file, os.O_RDONLY,
+ stat.S_IWUSR | stat.S_IRUSR)
+
+ result_message = ""
+ with os.fdopen(device_log_file_open, "r", encoding='utf-8') \
+ as file_read_pipe:
+ while True:
+ data = file_read_pipe.readline()
+ if not data:
+ break
+ # only filter JSApp log
+ if data.find("JSApp:") != -1:
+ result_message += data
+ if data.find("[end] run suites end") != -1:
+ break
+ return result_message
+
+ def _execute_hapfile_jsunittest(self):
+ _unlock_screen(self.config.device)
+ _unlock_device(self.config.device)
+
+ try:
+ return_message = self.start_hap_execute()
+ except (ExecuteTerminate, DeviceError) as exception:
+ return_message = str(exception.args)
+
+ return return_message
+
+ def _install_hap(self, suite_file):
+ message = self.config.device.connector_command("install %s" % suite_file)
+ message = str(message).rstrip()
+ if message == "" or "success" in message:
+ return_code = True
+ if message != "":
+ LOG.info(message)
+ else:
+ return_code = False
+ if message != "":
+ LOG.warning(message)
+
+ _sleep_according_to_result(return_code)
+ return return_code
+
+ def start_hap_execute(self):
+ try:
+ command = "aa start -d 123 -a %s.MainAbility -b %s" \
+ % (self.package_name, self.package_name)
+ self.start_time = time.time()
+ result_value = self.config.device.execute_shell_command(
+ command, timeout=TIME_OUT)
+
+ if "success" in str(result_value).lower():
+ LOG.info("execute %s's testcase success. result value=%s"
+ % (self.package_name, result_value))
+ else:
+ LOG.info("execute %s's testcase failed. result value=%s"
+ % (self.package_name, result_value))
+
+ _sleep_according_to_result(result_value)
+ return_message = result_value
+ except (ExecuteTerminate, DeviceError) as exception:
+ return_message = exception.args
+
+ return return_message
+
+ def _uninstall_hap(self, package_name):
+ return_message = self.config.device.execute_shell_command(
+ "bm uninstall -n %s" % package_name)
+ _sleep_according_to_result(return_message)
+ return return_message
+
+ @staticmethod
+ def _get_acts_test_para(testcase,
+ testlevel,
+ testtype,
+ target_test_path,
+ suite_file,
+ filename):
+ if "actstest" == testtype[0]:
+ test_para = (" --actstest_out_format=json"
+ " --actstest_out=%s%s.json") % (
+ target_test_path, filename)
+ return test_para
+
+ if "" != testcase and "" == testlevel:
+ test_para = "%s=%s" % (GTestConst.exec_acts_para_filter, testcase)
+ elif "" == testcase and "" != testlevel:
+ level_para = get_level_para_string(testlevel)
+ test_para = "%s=%s" % (GTestConst.exec_acts_para_level, level_para)
+ else:
+ test_para = ""
+ return test_para
+
+ @staticmethod
+ def _get_hats_test_para(testcase,
+ testlevel,
+ testtype,
+ target_test_path,
+ suite_file,
+ filename):
+ if "hatstest" == testtype[0]:
+ test_hats_para = (" --hatstest_out_format=json"
+ " --hatstest_out=%s%s.json") % (
+ target_test_path, filename)
+ return test_hats_para
+
+ if "" != testcase and "" == testlevel:
+ test_hats_para = "%s=%s" % (GTestConst.exec_para_filter, testcase)
+ elif "" == testcase and "" != testlevel:
+ level_para = get_level_para_string(testlevel)
+ test_hats_para = "%s=%s" % (GTestConst.exec_para_level, level_para)
+ else:
+ test_hats_para = ""
+ return test_hats_para
+
+ @classmethod
+ def _get_json_shell_timeout(cls, json_filepath):
+ test_timeout = 300
+ try:
+ with open(json_filepath, 'r') as json_file:
+ data_dic = json.load(json_file)
+ if not data_dic:
+ return test_timeout
+ else:
+ if "driver" in data_dic.keys():
+ driver_dict = data_dic.get("driver")
+ if driver_dict and "test-timeout" in driver_dict.keys():
+ test_timeout = int(driver_dict["shell-timeout"]) / 1000
+ else:
+ return
+ return test_timeout
+ except JSONDecodeError:
+ return test_timeout
+ finally:
+ print(" get json shell timeout finally")
+
+ @staticmethod
+ def _get_package_and_ability_name(hap_filepath):
+ package_name = ""
+ ability_name = ""
+ if os.path.exists(hap_filepath):
+ filename = os.path.basename(hap_filepath)
+
+ # unzip the hap file
+ hap_bak_path = os.path.abspath(os.path.join(
+ os.path.dirname(hap_filepath),
+ "%s.bak" % filename))
+ zf_desc = zipfile.ZipFile(hap_filepath)
+ try:
+ zf_desc.extractall(path=hap_bak_path)
+ except RuntimeError as error:
+ print(error)
+ zf_desc.close()
+
+ # verify config.json file
+ app_profile_path = os.path.join(hap_bak_path, "config.json")
+ if not os.path.exists(app_profile_path):
+ print("file %s not exist" % app_profile_path)
+ return package_name, ability_name
+
+ if os.path.isdir(app_profile_path):
+ print("%s is a folder, and not a file" % app_profile_path)
+ return package_name, ability_name
+
+ # get package_name and ability_name value
+ load_dict = {}
+ with open(app_profile_path, 'r') as load_f:
+ load_dict = json.load(load_f)
+ profile_list = load_dict.values()
+ for profile in profile_list:
+ package_name = profile.get("package")
+ if not package_name:
+ continue
+ abilities = profile.get("abilities")
+ for abilitie in abilities:
+ abilities_name = abilitie.get("name")
+ if abilities_name.startswith("."):
+ ability_name = package_name + abilities_name[
+ abilities_name.find("."):]
+ else:
+ ability_name = abilities_name
+ break
+ break
+
+ # delete hap_bak_path
+ if os.path.exists(hap_bak_path):
+ shutil.rmtree(hap_bak_path)
+ else:
+ print("file %s not exist" % hap_filepath)
+ return package_name, ability_name