Skip to content

Commit f2b0f27

Browse files
Merge pull request #253 from ARMmbed/update-platform-db
Update platform database when it's out of date
2 parents 4f044d7 + d7c627f commit f2b0f27

File tree

2 files changed

+58
-37
lines changed

2 files changed

+58
-37
lines changed

mbed_lstools/platform_database.py

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717

1818
"""Functions that manage a platform database"""
1919

20+
import datetime
2021
import json
2122
import re
2223
from collections import OrderedDict
2324
from copy import copy
2425
from io import open
2526
from os import makedirs
26-
from os.path import join, dirname
27+
from os.path import join, dirname, getmtime
2728
from appdirs import user_data_dir
2829
from fasteners import InterProcessLock
2930

@@ -32,6 +33,7 @@
3233
except NameError:
3334
unicode = str
3435

36+
3537
import logging
3638
logger = logging.getLogger("mbedls.platform_database")
3739
del logging
@@ -251,6 +253,40 @@
251253
u'RIOT': u'RIOT',
252254
}
253255

256+
257+
def _get_modified_time(path):
258+
try:
259+
mtime = getmtime(path)
260+
except OSError:
261+
mtime = 0
262+
return datetime.date.fromtimestamp(mtime)
263+
264+
265+
def _older_than_me(path):
266+
return _get_modified_time(path) < _get_modified_time(__file__)
267+
268+
269+
def _overwrite_or_open(db):
270+
try:
271+
if db is LOCAL_PLATFORM_DATABASE and _older_than_me(db):
272+
raise ValueError("Platform Database is out of date")
273+
with open(db, encoding="utf-8") as db_in:
274+
return json.load(db_in)
275+
except (IOError, ValueError) as exc:
276+
if db is LOCAL_PLATFORM_DATABASE:
277+
logger.warning(
278+
"Error loading database %s: %s; Recreating", db, str(exc))
279+
try:
280+
makedirs(dirname(db))
281+
except OSError:
282+
pass
283+
with open(db, "w", encoding="utf-8") as out:
284+
out.write(unicode(json.dumps(DEFAULT_PLATFORM_DB)))
285+
return copy(DEFAULT_PLATFORM_DB)
286+
else:
287+
return {}
288+
289+
254290
class PlatformDatabase(object):
255291
"""Represents a union of multiple platform database files.
256292
Handles inter-process synchronization of database files.
@@ -266,42 +302,15 @@ def __init__(self, database_files, primary_database=None):
266302
self._dbs = OrderedDict()
267303
self._keys = set()
268304
for db in database_files:
269-
try:
270-
with open(db, encoding="utf-8") as db_json_file:
271-
new_db = json.load(db_json_file)
272-
duplicates = set(self._keys).intersection(set(new_db.keys()))
273-
if duplicates:
274-
logger.warning(
275-
"Duplicate platform ids found: %s,"
276-
" ignoring the definitions from %s",
277-
" ".join(duplicates), db)
278-
self._dbs[db] = new_db
279-
self._keys = self._keys.union(new_db.keys())
280-
except IOError as exc:
281-
if db is LOCAL_PLATFORM_DATABASE:
282-
logger.warning(
283-
"Could not open local platform database at %s; "
284-
"Recereating", db)
285-
try:
286-
makedirs(dirname(db))
287-
except OSError:
288-
pass
289-
with open(db, "w", encoding="utf-8") as out:
290-
out.write(unicode(json.dumps(DEFAULT_PLATFORM_DB)))
291-
new_db = copy(DEFAULT_PLATFORM_DB)
292-
self._dbs[db] = new_db
293-
self._keys = self._keys.union(new_db.keys())
294-
else:
295-
if db is not self._prim_db:
296-
logger.error(
297-
"Could not open platform database %s: %s; skipping",
298-
db, str(exc))
299-
self._dbs[db] = {}
300-
except ValueError as exc:
301-
logger.error(
302-
"Could not parse platform database %s because %s; "
303-
"skipping", db, str(exc))
304-
self._dbs[db] = {}
305+
new_db = _overwrite_or_open(db)
306+
duplicates = set(self._keys).intersection(set(new_db.keys()))
307+
if duplicates:
308+
logger.warning(
309+
"Duplicate platform ids found: %s,"
310+
" ignoring the definitions from %s",
311+
" ".join(duplicates), db)
312+
self._dbs[db] = new_db
313+
self._keys = self._keys.union(new_db.keys())
305314

306315
def items(self):
307316
for db in self._dbs.values():

test/platform_database.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@ def test_broken_database(self):
7979
self.pdb.add("1234", "MYTARGET")
8080
self.assertEqual(self.pdb.get("1234"), "MYTARGET")
8181

82+
def test_old_database(self):
83+
"""Verify that the platform database correctly updates's its database
84+
"""
85+
with patch("mbed_lstools.platform_database.open") as _open,\
86+
patch("mbed_lstools.platform_database.getmtime") as _getmtime:
87+
stringio = MagicMock()
88+
_open.return_value = stringio
89+
_getmtime.side_effect = (0, 1000000)
90+
self.pdb = PlatformDatabase([LOCAL_PLATFORM_DATABASE])
91+
stringio.__enter__.return_value.write.assert_called_with(
92+
unicode(json.dumps(DEFAULT_PLATFORM_DB)))
93+
8294
def test_bogus_database(self):
8395
"""Basic empty database test
8496
"""

0 commit comments

Comments
 (0)