mbed-os/tools/python/mbed_os_tools/test/mbed_greentea_dlm.py

170 lines
6.1 KiB
Python

# Copyright (c) 2018, Arm Limited and affiliates.
# SPDX-License-Identifier: Apache-2.0
#
# 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 uuid
import lockfile
from os.path import expanduser
HOME_DIR = expanduser("~")
GREENTEA_HOME_DIR = ".mbed-greentea"
GREENTEA_GLOBAL_LOCK = "glock.lock"
GREENTEA_KETTLE = "kettle.json" # active Greentea instances
GREENTEA_KETTLE_PATH = os.path.join(HOME_DIR, GREENTEA_HOME_DIR, GREENTEA_KETTLE)
def greentea_home_dir_init():
""" Initialize data in home directory for locking features
"""
if not os.path.isdir(os.path.join(HOME_DIR, GREENTEA_HOME_DIR)):
os.mkdir(os.path.join(HOME_DIR, GREENTEA_HOME_DIR))
def greentea_get_app_sem():
""" Obtain locking mechanism info
"""
greentea_home_dir_init()
gt_instance_uuid = str(uuid.uuid4()) # String version
gt_file_sem_name = os.path.join(HOME_DIR, GREENTEA_HOME_DIR, gt_instance_uuid)
gt_file_sem = lockfile.LockFile(gt_file_sem_name)
return gt_file_sem, gt_file_sem_name, gt_instance_uuid
def greentea_get_target_lock(target_id):
greentea_home_dir_init()
file_path = os.path.join(HOME_DIR, GREENTEA_HOME_DIR, target_id)
lock = lockfile.LockFile(file_path)
return lock
def greentea_get_global_lock():
greentea_home_dir_init()
file_path = os.path.join(HOME_DIR, GREENTEA_HOME_DIR, GREENTEA_GLOBAL_LOCK)
lock = lockfile.LockFile(file_path)
return lock
def greentea_update_kettle(greentea_uuid):
from time import gmtime, strftime
with greentea_get_global_lock():
current_brew = get_json_data_from_file(GREENTEA_KETTLE_PATH)
if not current_brew:
current_brew = {}
current_brew[greentea_uuid] = {
"start_time" : strftime("%Y-%m-%d %H:%M:%S", gmtime()),
"cwd" : os.getcwd(),
"locks" : []
}
with open(GREENTEA_KETTLE_PATH, 'w') as kettle_file:
json.dump(current_brew, kettle_file, indent=4)
def greentea_clean_kettle(greentea_uuid):
""" Clean info in local file system config file
"""
with greentea_get_global_lock():
current_brew = get_json_data_from_file(GREENTEA_KETTLE_PATH)
if not current_brew:
current_brew = {}
current_brew.pop(greentea_uuid, None)
with open(GREENTEA_KETTLE_PATH, 'w') as kettle_file:
json.dump(current_brew, kettle_file, indent=4)
def greentea_acquire_target_id(target_id, gt_instance_uuid):
""" Acquire lock on target_id for given greentea UUID
"""
with greentea_get_global_lock():
current_brew = get_json_data_from_file(GREENTEA_KETTLE_PATH)
if current_brew:
current_brew[gt_instance_uuid]['locks'].append(target_id)
with open(GREENTEA_KETTLE_PATH, 'w') as kettle_file:
json.dump(current_brew, kettle_file, indent=4)
def greentea_acquire_target_id_from_list(possible_target_ids, gt_instance_uuid):
""" Acquire lock on target_id from list of possible target_ids for given greentea UUID
"""
target_id = None
already_locked_target_ids = []
with greentea_get_global_lock():
current_brew = get_json_data_from_file(GREENTEA_KETTLE_PATH)
# Get all already locked target_id
for cb in current_brew:
locks_list = current_brew[cb]['locks']
already_locked_target_ids.extend(locks_list)
# Remove from possible_target_ids elements from already_locked_target_ids
available_target_ids = [item for item in possible_target_ids if item not in already_locked_target_ids]
if available_target_ids:
target_id = available_target_ids[0]
current_brew[gt_instance_uuid]['locks'].append(target_id)
with open(GREENTEA_KETTLE_PATH, 'w') as kettle_file:
json.dump(current_brew, kettle_file, indent=4)
return target_id
def greentea_release_target_id(target_id, gt_instance_uuid):
""" Release target_id for given greentea UUID
"""
with greentea_get_global_lock():
current_brew = get_json_data_from_file(GREENTEA_KETTLE_PATH)
if current_brew:
current_brew[gt_instance_uuid]['locks'].remove(target_id)
with open(GREENTEA_KETTLE_PATH, 'w') as kettle_file:
json.dump(current_brew, kettle_file, indent=4)
def get_json_data_from_file(json_spec_filename):
""" Loads from file JSON formatted string to data structure
"""
result = None
try:
with open(json_spec_filename, 'r') as data_file:
try:
result = json.load(data_file)
except ValueError:
result = None
except IOError:
result = None
return result
def greentea_kettle_info():
""" generates human friendly info about current kettle state
@details
{
"475a46d0-41fe-41dc-b5e6-5197a2fcbb28": {
"locks": [],
"start_time": "2015-10-23 09:29:54",
"cwd": "c:\\Work\\mbed-drivers"
}
}
"""
from prettytable import PrettyTable
with greentea_get_global_lock():
current_brew = get_json_data_from_file(GREENTEA_KETTLE_PATH)
cols = ['greentea_uuid', 'start_time', 'cwd', 'locks']
pt = PrettyTable(cols)
for col in cols:
pt.align[col] = "l"
pt.padding_width = 1 # One space between column edges and contents (default)
row = []
for greentea_uuid in current_brew:
kettle = current_brew[greentea_uuid]
row.append(greentea_uuid)
row.append(kettle['start_time'])
row.append(kettle['cwd'])
row.append('\n'.join(kettle['locks']))
pt.add_row(row)
row = []
return pt.get_string()