From e9a4c7519e4e2d9763294461f8628a519a3af308 Mon Sep 17 00:00:00 2001
From: "Antoine R. Dumont (@ardumont)" <antoine.romain.dumont@gmail.com>
Date: Wed, 25 Mar 2020 18:00:03 +0100
Subject: [PATCH] model: Add new OriginVisitUpdate model object + test strategy

(pairing with @vlorentz)

Related to T2310
---
 swh/model/hypothesis_strategies.py | 27 +++++++++++++++++++++------
 swh/model/model.py                 | 17 +++++++++++++++++
 swh/model/tests/test_model.py      | 13 +++++++++++--
 3 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/swh/model/hypothesis_strategies.py b/swh/model/hypothesis_strategies.py
index b6c35933..19c3fd31 100644
--- a/swh/model/hypothesis_strategies.py
+++ b/swh/model/hypothesis_strategies.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2019 The Software Heritage developers
+# Copyright (C) 2019-2020 The Software Heritage developers
 # See the AUTHORS file at the top-level directory of this distribution
 # License: GNU General Public License version 3, or any later version
 # See top-level LICENSE file for more information
@@ -15,8 +15,8 @@ from hypothesis.strategies import (
 from .from_disk import DentryPerms
 from .model import (
     Person, Timestamp, TimestampWithTimezone, Origin, OriginVisit,
-    Snapshot, SnapshotBranch, TargetType, Release, Revision,
-    Directory, DirectoryEntry, Content, SkippedContent
+    OriginVisitUpdate, Snapshot, SnapshotBranch, TargetType, Release,
+    Revision, Directory, DirectoryEntry, Content, SkippedContent
 )
 from .identifiers import snapshot_identifier, identifier_to_bytes
 
@@ -85,7 +85,22 @@ def origin_visits():
         origin=urls(),
         status=sampled_from(['ongoing', 'full', 'partial']),
         type=pgsql_text(),
-        snapshot=optional(sha1_git()))
+        snapshot=optional(sha1_git()),
+    )
+
+
+def metadata_dicts():
+    return dictionaries(pgsql_text(), pgsql_text())
+
+
+def origin_visit_updates():
+    return builds(
+        OriginVisitUpdate,
+        visit=integers(0, 1000),
+        origin=urls(),
+        status=sampled_from(['ongoing', 'full', 'partial']),
+        snapshot=optional(sha1_git()),
+        metadata=one_of(none(), metadata_dicts()))
 
 
 @composite
@@ -104,8 +119,7 @@ def releases(draw):
         author=author)
 
 
-def revision_metadata():
-    return dictionaries(pgsql_text(), pgsql_text())
+revision_metadata = metadata_dicts
 
 
 def revisions():
@@ -238,6 +252,7 @@ def objects():
     return one_of(
         origins().map(lambda x: ('origin', x)),
         origin_visits().map(lambda x: ('origin_visit', x)),
+        origin_visit_updates().map(lambda x: ('origin_visit_update', x)),
         snapshots().map(lambda x: ('snapshot', x)),
         releases().map(lambda x: ('release', x)),
         revisions().map(lambda x: ('revision', x)),
diff --git a/swh/model/model.py b/swh/model/model.py
index 7cfb7e3c..b296b227 100644
--- a/swh/model/model.py
+++ b/swh/model/model.py
@@ -234,6 +234,23 @@ class OriginVisit(BaseModel):
             **d)
 
 
+@attr.s(frozen=True)
+class OriginVisitUpdate(BaseModel):
+    """Represents a visit update of an origin at a given point in time.
+
+    """
+    origin = attr.ib(type=str)
+    visit = attr.ib(type=int)
+
+    date = attr.ib(type=datetime.datetime)
+    status = attr.ib(
+        type=str,
+        validator=attr.validators.in_(['ongoing', 'full', 'partial']))
+    snapshot = attr.ib(type=Optional[Sha1Git])
+    metadata = attr.ib(type=Optional[Dict[str, object]],
+                       default=None)
+
+
 class TargetType(Enum):
     """The type of content pointed to by a snapshot branch. Usually a
     revision or an alias."""
diff --git a/swh/model/tests/test_model.py b/swh/model/tests/test_model.py
index 5e8e1ee2..c5dbc59c 100644
--- a/swh/model/tests/test_model.py
+++ b/swh/model/tests/test_model.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2019 The Software Heritage developers
+# Copyright (C) 2019-2020 The Software Heritage developers
 # See the AUTHORS file at the top-level directory of this distribution
 # License: GNU General Public License version 3, or any later version
 # See top-level LICENSE file for more information
@@ -16,7 +16,9 @@ from swh.model.model import (
     MissingData, Person
 )
 from swh.model.hashutil import hash_to_bytes, MultiHash
-from swh.model.hypothesis_strategies import objects, origins, origin_visits
+from swh.model.hypothesis_strategies import (
+    objects, origins, origin_visits, origin_visit_updates
+)
 from swh.model.identifiers import (
     directory_identifier, revision_identifier, release_identifier,
     snapshot_identifier
@@ -61,6 +63,13 @@ def test_todict_origin_visits(origin_visit):
     assert origin_visit == type(origin_visit).from_dict(obj)
 
 
+@given(origin_visit_updates())
+def test_todict_origin_visit_updates(origin_visit_update):
+    obj = origin_visit_update.to_dict()
+
+    assert origin_visit_update == type(origin_visit_update).from_dict(obj)
+
+
 def test_timestampwithtimezone_from_datetime():
     tz = datetime.timezone(datetime.timedelta(minutes=+60))
     date = datetime.datetime(
-- 
GitLab