@contextlib.contextmanager
def convert_validation_exceptions():
"""Catches postgresql errors related to invalid arguments, and
re-raises a StorageArgumentException."""
try:
> yield
.tox/py3/lib/python3.7/site-packages/swh/storage/storage.py:76:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <swh.storage.storage.Storage object at 0x7f7a5f962198>
revisions = [Revision(message=b'a simple revision with no parents this time', author=Person(fullname=b'Roberto Dicosmo <roberto@ex...\xa2\x96W\x85*P\xa0\x1bY\x1dF',), id=b'\x88\xcdQ&\xfc\x95\x8e\xd7\x00\x89\xd54\x04A\xa1\xc2G{\xcc ', extra_headers=())]
db = <swh.storage.db.Db object at 0x7f7a5f962dd8>
cur = <cursor object at 0x7f7c425dcce0; closed: -1>
@timed
@process_metrics
@db_transaction()
def revision_add(self, revisions: Iterable[Revision], db=None, cur=None) -> Dict:
revisions = list(revisions)
summary = {"revision:add": 0}
revisions_missing = set(
self.revision_missing(
set(revision.id for revision in revisions), db=db, cur=cur
)
)
if not revisions_missing:
return summary
db.mktemp_revision(cur)
revisions_filtered = [
revision for revision in revisions if revision.id in revisions_missing
]
self.journal_writer.revision_add(revisions_filtered)
revisions_filtered = list(map(converters.revision_to_db, revisions_filtered))
parents_filtered: List[bytes] = []
with convert_validation_exceptions():
db.copy_to(
revisions_filtered,
"tmp_revision",
db.revision_add_cols,
cur,
> lambda rev: parents_filtered.extend(rev["parents"]),
)
.tox/py3/lib/python3.7/site-packages/swh/storage/storage.py:579:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <swh.storage.db.Db object at 0x7f7a5f962dd8>
items = [{'author_email': b'roberto@example.com', 'author_fullname': b'Roberto Dicosmo <roberto@example.com>', 'author_name': ...thor_fullname': b'me <me@soft.heri>', 'author_name': b'me', 'committer_date': '2009-06-09T17:17:23.220000+00:00', ...}]
tblname = 'tmp_revision'
columns = ['id', 'date', 'date_offset', 'date_neg_utc_offset', 'committer_date', 'committer_date_offset', ...]
cur = <cursor object at 0x7f7c425dcce0; closed: -1>
item_cb = <function Storage.revision_add.<locals>.<lambda> at 0x7f7a63006ea0>
default_values = {}
def copy_to(
self, items, tblname, columns, cur=None, item_cb=None, default_values={}
):
"""Copy items' entries to table tblname with columns information.
Args:
items (List[dict]): dictionaries of data to copy over tblname.
tblname (str): destination table's name.
columns ([str]): keys to access data in items and also the
column names in the destination table.
default_values (dict): dictionary of default values to use when
inserting entried int the tblname table.
cur: a db cursor; if not given, a new cursor will be created.
item_cb (fn): optional function to apply to items's entry.
"""
read_file, write_file = os.pipe()
exc_info = None
def writer():
nonlocal exc_info
cursor = self.cursor(cur)
with open(read_file, "r") as f:
try:
cursor.copy_expert(
"COPY %s (%s) FROM STDIN CSV" % (tblname, ", ".join(columns)), f
)
except Exception:
# Tell the main thread about the exception
exc_info = sys.exc_info()
write_thread = threading.Thread(target=writer)
write_thread.start()
try:
with open(write_file, "w") as f:
for d in items:
if item_cb is not None:
item_cb(d)
line = []
for k in columns:
value = d.get(k, default_values.get(k))
try:
line.append(escape(value))
except Exception as e:
logger.error(
"Could not escape value `%r` for column `%s`:"
"Received exception: `%s`",
value,
k,
e,
)
raise e from None
f.write(",".join(line))
f.write("\n")
finally:
# No problem bubbling up exceptions, but we still need to make sure
# we finish copying, even though we're probably going to cancel the
# transaction.
write_thread.join()
if exc_info:
# postgresql returned an error, let's raise it.
> raise exc_info[1].with_traceback(exc_info[2])
.tox/py3/lib/python3.7/site-packages/swh/core/db/__init__.py:213:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def writer():
nonlocal exc_info
cursor = self.cursor(cur)
with open(read_file, "r") as f:
try:
cursor.copy_expert(
> "COPY %s (%s) FROM STDIN CSV" % (tblname, ", ".join(columns)), f
)
E psycopg2.errors.InvalidTextRepresentation: malformed array literal: "()"
E DETAIL: Array value must start with "{" or dimension information.
E CONTEXT: COPY tmp_revision, line 1, column extra_headers: "()"
.tox/py3/lib/python3.7/site-packages/swh/core/db/__init__.py:175: InvalidTextRepresentation
During handling of the above exception, another exception occurred:
self = <swh.storage.tests.test_storage.TestStorage object at 0x7f7a5f9623c8>
swh_storage = <swh.storage.validate.ValidatingProxyStorage object at 0x7f7a5f962240>
def test_revision_log(self, swh_storage):
# given
# data.revision4 -is-child-of-> data.revision3
> swh_storage.revision_add([data.revision3, data.revision4])
.tox/py3/lib/python3.7/site-packages/swh/storage/tests/test_storage.py:1042:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox/py3/lib/python3.7/site-packages/swh/storage/validate.py:104: in revision_add
[dict_converter(Revision, r) for r in revisions]
.tox/py3/lib/python3.7/site-packages/swh/storage/metrics.py:24: in d
return f(*a, **kw)
.tox/py3/lib/python3.7/site-packages/swh/storage/metrics.py:77: in d
r = f(*a, **kw)
.tox/py3/lib/python3.7/site-packages/swh/core/db/common.py:62: in _meth
return meth(self, *args, db=db, cur=cur, **kwargs)
.tox/py3/lib/python3.7/site-packages/swh/storage/storage.py:579: in revision_add
lambda rev: parents_filtered.extend(rev["parents"]),
/usr/lib/python3.7/contextlib.py:130: in __exit__
self.gen.throw(type, value, traceback)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
@contextlib.contextmanager
def convert_validation_exceptions():
"""Catches postgresql errors related to invalid arguments, and
re-raises a StorageArgumentException."""
try:
yield
except tuple(VALIDATION_EXCEPTIONS) as e:
> raise StorageArgumentException(str(e))
E swh.storage.exc.StorageArgumentException: malformed array literal: "()"
E DETAIL: Array value must start with "{" or dimension information.
E CONTEXT: COPY tmp_revision, line 1, column extra_headers: "()"
.tox/py3/lib/python3.7/site-packages/swh/storage/storage.py:78: StorageArgumentException
TEST RESULT
TEST RESULT
- Run At
- Jul 6 2020, 2:26 PM