1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2025-02-21 20:38:57 +00:00

framework: Lock files which could be read/written to concurrently

Add file locking to files that could be read and written to concurrently
by separate wa processes causing race conditions.
This commit is contained in:
Marc Bonnici 2020-01-03 11:16:48 +00:00 committed by setrofim
parent d56f0fbe20
commit 607cff4c54
5 changed files with 65 additions and 50 deletions

View File

@ -31,7 +31,7 @@ import requests
from wa import Parameter, settings, __file__ as _base_filepath
from wa.framework.resource import ResourceGetter, SourcePriority, NO_ONE
from wa.framework.exception import ResourceError
from wa.utils.misc import (ensure_directory_exists as _d,
from wa.utils.misc import (ensure_directory_exists as _d, lock_file,
ensure_file_directory_exists as _f, sha256, urljoin)
from wa.utils.types import boolean, caseless_string
@ -254,6 +254,7 @@ class Http(ResourceGetter):
url = urljoin(self.url, owner_name, asset['path'])
local_path = _f(os.path.join(settings.dependencies_directory, '__remote',
owner_name, asset['path'].replace('/', os.sep)))
with lock_file(local_path, timeout=5 * 60):
if os.path.exists(local_path) and not self.always_fetch:
local_sha = sha256(local_path)
if local_sha == asset['sha256']:

View File

@ -25,6 +25,7 @@ from wa.framework.configuration import settings
from wa.utils import log
from wa.utils.misc import get_object_name
from wa.utils.types import enum, list_or_string, prioritylist, version_tuple
from wa.utils.misc import lock_file
SourcePriority = enum(['package', 'remote', 'lan', 'local',
@ -280,6 +281,7 @@ class ResourceResolver(object):
def apk_version_matches(path, version):
version = list_or_string(version)
with lock_file(path):
info = ApkInfo(path)
for v in version:
if info.version_name == v or info.version_code == v:
@ -290,6 +292,7 @@ def apk_version_matches(path, version):
def apk_version_matches_range(path, min_version=None, max_version=None):
with lock_file(path):
info = ApkInfo(path)
return range_version_matching(info.version_name, min_version, max_version)
@ -333,17 +336,20 @@ def file_name_matches(path, pattern):
def uiauto_test_matches(path, uiauto):
with lock_file(path):
info = ApkInfo(path)
return uiauto == ('com.arm.wa.uiauto' in info.package)
def package_name_matches(path, package):
with lock_file(path):
info = ApkInfo(path)
return info.package == package
def apk_abi_matches(path, supported_abi, exact_abi=False):
supported_abi = list_or_string(supported_abi)
with lock_file(path):
info = ApkInfo(path)
# If no native code present, suitable for all devices.
if not info.native_code:

View File

@ -23,6 +23,7 @@ from devlib.utils.android import AndroidProperties
from wa.framework.configuration.core import settings
from wa.framework.exception import ConfigError
from wa.utils.serializer import read_pod, write_pod, Podable
from wa.utils.misc import lock_file
def cpuinfo_from_pod(pod):
@ -280,12 +281,14 @@ def read_target_info_cache():
os.makedirs(settings.cache_directory)
if not os.path.isfile(settings.target_info_cache_file):
return {}
with lock_file(settings.target_info_cache_file):
return read_pod(settings.target_info_cache_file)
def write_target_info_cache(cache):
if not os.path.exists(settings.cache_directory):
os.makedirs(settings.cache_directory)
with lock_file(settings.target_info_cache_file):
write_pod(cache, settings.target_info_cache_file)

View File

@ -32,6 +32,7 @@ from wa.framework.exception import WorkloadError, ConfigError
from wa.utils.types import ParameterDict, list_or_string, version_tuple
from wa.utils.revent import ReventRecorder
from wa.utils.exec_control import once_per_instance
from wa.utils.misc import lock_file
class Workload(TargetedPlugin):
@ -731,6 +732,7 @@ class PackageHandler(object):
raise WorkloadError(msg)
self.error_msg = None
with lock_file(os.path.join(self.owner.dependencies_directory, self.owner.name)):
if self.prefer_host_package:
self.resolve_package_from_host(context)
if not self.apk_file:
@ -741,6 +743,7 @@ class PackageHandler(object):
self.resolve_package_from_host(context)
if self.apk_file:
with lock_file(self.apk_file):
self.apk_info = ApkInfo(self.apk_file)
else:
if self.error_msg:
@ -898,6 +901,7 @@ class PackageHandler(object):
package_info = self.target.get_package_info(package)
apk_name = self._get_package_name(package_info.apk_path)
host_path = os.path.join(self.owner.dependencies_directory, apk_name)
with lock_file(host_path, timeout=self.install_timeout):
self.target.pull(package_info.apk_path, host_path,
timeout=self.install_timeout)
return host_path

View File

@ -38,7 +38,7 @@ from wa import Instrument, Parameter, very_fast
from wa.framework.exception import ConfigError
from wa.framework.instrument import slow
from wa.utils.diff import diff_sysfs_dirs, diff_interrupt_files
from wa.utils.misc import as_relative
from wa.utils.misc import as_relative, lock_file
from wa.utils.misc import ensure_file_directory_exists as _f
from wa.utils.misc import ensure_directory_exists as _d
from wa.utils.types import list_of_strings
@ -244,6 +244,7 @@ class ApkVersion(Instrument):
def setup(self, context):
if hasattr(context.workload, 'apk_file'):
with lock_file(context.workload.apk_file):
self.apk_info = ApkInfo(context.workload.apk_file)
else:
self.apk_info = None