Beispiel #1
0
def test_obj_ref_max_depth(historian: mincepy.Historian):
    """Test object references max depth"""
    # Set up the chain: three -> two -> one -> zero
    zero = mincepy.ObjRef()
    one = mincepy.ObjRef(zero)
    two = mincepy.ObjRef(one)
    three = mincepy.ObjRef(two)
    zero_id, one_id, two_id, three_id = historian.save(zero, one, two, three)

    # No max depth
    graph = historian.archive.get_obj_ref_graph(two_id)
    assert len(graph.nodes) == 3
    assert len(graph.edges) == 2
    assert (one_id, zero_id) in graph.edges
    assert (two_id, one_id) in graph.edges

    graph = historian.archive.get_obj_ref_graph(three_id, max_dist=3)
    assert len(graph.nodes) == 4
    assert len(graph.edges) == 3
    assert (one_id, zero_id) in graph.edges
    assert (two_id, one_id) in graph.edges
    assert (three_id, two_id) in graph.edges

    graph = historian.archive.get_obj_ref_graph(two_id, max_dist=1)
    assert len(graph.edges) == 1
    assert (two_id, one_id) in graph.edges

    graph = historian.archive.get_obj_ref_graph(two_id, max_dist=0)
    assert len(graph.nodes) == 1
    assert len(graph.edges) == 0
Beispiel #2
0
def test_get_obj_graph_current(historian: mincepy.Historian):
    """Test that when changing a reference the reference graph is returned correctly"""
    car = Car()
    garage = Garage(mincepy.ObjRef(car))
    gid = garage.save()

    garage_graph = historian.archive.get_obj_ref_graph(gid)
    assert len(garage_graph.edges) == 1
    assert (gid, car.obj_id) in garage_graph.edges

    # Now, modify the garage
    car2 = Car()
    garage.car = mincepy.ObjRef(car2)
    garage.save()

    # Check that the reference graph is correct
    garage_graph = historian.archive.get_obj_ref_graph(gid)
    assert len(garage_graph.edges) == 1
    assert (gid, car2.obj_id) in garage_graph.edges

    # Finally, set the reference to None
    garage.car = mincepy.ObjRef()
    garage.save()

    # Check that the reference graph is correct
    garage_graph = historian.archive.get_obj_ref_graph(gid)
    assert len(garage_graph.edges) == 0
    assert len(garage_graph.nodes) == 1
Beispiel #3
0
def test_get_obj_referencing_simple(historian: mincepy.Historian):
    car = Car()
    garage = Garage(mincepy.ObjRef(car))
    gid = garage.save()

    car_graph = historian.archive.get_obj_ref_graph(car.obj_id,
                                                    direction=mincepy.INCOMING)
    assert len(car_graph.edges) == 1
    assert len(car_graph.nodes) == 2
    assert (gid, car.obj_id) in car_graph.edges

    # Now, create a new garage
    garage2 = Garage(mincepy.ObjRef(car))
    g2id = garage2.save()

    # Check that the reference graph is correct
    car_graph = historian.archive.get_obj_ref_graph(car.obj_id,
                                                    direction=mincepy.INCOMING)
    assert len(car_graph.nodes) == 3
    assert len(car_graph.edges) == 2
    assert (gid, car.obj_id) in car_graph.edges
    assert (g2id, car.obj_id) in car_graph.edges

    # Finally, set the references to None
    garage.car = mincepy.ObjRef()
    garage.save()
    garage2.car = mincepy.ObjRef()
    garage2.save()

    # Check that the reference graph is correct
    car_graph = historian.archive.get_obj_ref_graph(gid)
    assert len(car_graph.edges) == 0
    assert len(car_graph.nodes) == 1
Beispiel #4
0
def test_null_ref(historian: mincepy.Historian):
    null = mincepy.ObjRef()
    null2 = mincepy.ObjRef()

    assert null == null2

    nid1, _nid2 = historian.save(null, null2)
    del null
    loaded = historian.load(nid1)
    assert loaded == null2
Beispiel #5
0
def test_obj_ref_snapshot(historian: mincepy.Historian):
    """Check that a historic snapshot still works with references"""
    ns = Namespace()
    car = testing.Car('honda', 'white')
    ns.car = mincepy.ObjRef(car)
    historian.save(ns)
    honda_ns_sid = historian.get_snapshot_id(ns)

    car.make = 'fiat'
    historian.save(ns)
    fiat_ns_sid = historian.get_snapshot_id(ns)
    del ns

    assert fiat_ns_sid.version == honda_ns_sid.version + 1

    loaded = historian.load(honda_ns_sid)
    assert loaded.car().make == 'honda'

    loaded2 = historian.load(fiat_ns_sid)
    assert loaded2.car().make == 'fiat'
    assert loaded2.car() is not car

    # Load the 'live' namespace
    loaded3 = historian.load(honda_ns_sid.obj_id)
    assert loaded3.car() is car
Beispiel #6
0
def test_purge(historian: mincepy.Historian):
    car = Car()
    garage = testing.Garage(mincepy.ObjRef(car))
    car_id, _ = historian.save(car, garage)

    # Now update the car
    car.colour = 'blue'
    car.save()

    records_count = historian.records.find().count()

    # This should not perge anything as v0 of the car has a reference from the garage, while
    # v1 is the current, live, version
    res = historian.purge(dry_run=False)
    assert not res.deleted_purged
    assert not res.unreferenced_purged
    assert records_count == historian.records.find().count()

    # Now mutate the car, save and purge again
    car.colour = 'white'
    car.save()

    # This time, version 1 is unreferenced by anything and so can be safely deleted
    res = historian.purge(dry_run=False)
    assert not res.deleted_purged
    assert res.unreferenced_purged == {mincepy.SnapshotId(car_id, 1)}
    assert records_count == historian.records.find().count()
Beispiel #7
0
def test_obj_ref_simple(historian: mincepy.Historian):
    a = testing.Cycle()
    a.ref = mincepy.ObjRef(a)
    aid = historian.save(a)
    del a

    loaded = historian.load(aid)
    assert loaded.ref() is loaded
Beispiel #8
0
def test_get_snapshot_graph_simple(historian: mincepy.Historian):
    car = Car()
    garage = Garage(mincepy.ObjRef(car))
    garage.save()
    garage_sid = historian.get_snapshot_id(garage)

    garage_graph = historian.archive.get_snapshot_ref_graph(garage_sid)
    assert len(garage_graph.edges) == 1
    assert (garage_sid, historian.get_snapshot_id(car)) in garage_graph.edges
Beispiel #9
0
def test_get_object_graph(historian: mincepy.Historian):
    """Try getting the reference graph for live objects"""
    car = Car()
    garage = Garage(mincepy.ObjRef(car))
    gid = garage.save()

    garage_graph = historian.archive.get_obj_ref_graph(gid)
    assert len(garage_graph.edges) == 1
    assert (gid, car.obj_id) in garage_graph.edges
Beispiel #10
0
def test_saving_creator_that_owns_child(historian: mincepy.Historian):
    class TestProc(mincepy.Process):
        ATTRS = ('child', )

        def __init__(self):
            super().__init__('test_proc')
            self.child = None

    test_proc = TestProc()
    with test_proc.running():
        test_proc.child = mincepy.ObjRef(testing.Car())
        historian.save(test_proc)
Beispiel #11
0
def test_delete_referenced(historian: mincepy.Historian):
    car = testing.Car()
    garage = testing.Garage(mincepy.ObjRef(car))
    garage.save()

    # Should be prevented from deleting the car as it is referenced by the garage
    try:
        historian.delete(car)
    except mincepy.ReferenceError as exc:
        assert exc.references == {car.obj_id}
    else:
        assert False, 'Reference error should have been raised'

    historian.delete(garage)
    # Now safe to delete car
    historian.delete(car)

    car = testing.Car()
    garage = testing.Garage(mincepy.ObjRef(car))
    garage.save()

    # Now, check that deleting both together works
    historian.delete(car, garage)
Beispiel #12
0
def test_obj_sid_complex(historian: mincepy.Historian):
    honda = testing.Car('honda')
    nested1 = Namespace()
    nested2 = Namespace()
    parent = Namespace()

    # Both the nested refer to the same car
    nested1.car = mincepy.ObjRef(honda)
    nested2.car = mincepy.ObjRef(honda)

    # Now put them in their containers
    parent.ns1 = mincepy.ObjRef(nested1)
    parent.ns2 = mincepy.ObjRef(nested2)

    parent_id = historian.save(parent)
    del parent

    loaded = historian.load(parent_id)
    assert loaded.ns1() is nested1
    assert loaded.ns2() is nested2
    assert loaded.ns1().car() is loaded.ns2().car()

    fiat = testing.Car('fiat')
    loaded.ns2().car = mincepy.ObjRef(fiat)
    historian.save(loaded)
    parent_sid = historian.get_snapshot_id(loaded)
    del loaded

    loaded2 = historian.load_snapshot(mincepy.records.SnapshotId(parent_id, 0))
    assert loaded2.ns1().car().make == 'honda'
    assert loaded2.ns2().car().make == 'honda'
    del loaded2

    loaded3 = historian.load_snapshot(parent_sid)
    assert loaded3.ns1().car().make == 'honda'
    assert loaded3.ns2().car().make == 'fiat'
Beispiel #13
0
def test_get_snapshot_graph_twice(historian: mincepy.Historian):
    """Check for a bug that arise when asking for references twice"""
    car = Car()
    garage = Garage(mincepy.ObjRef(car))
    garage.save()
    garage_sid = historian.get_snapshot_id(garage)

    def make_checks(graph):
        assert len(graph.edges) == 1
        assert (garage_sid, historian.get_snapshot_id(car)) in graph.edges

    ref_graphs = historian.archive.get_snapshot_ref_graph(garage_sid)
    make_checks(ref_graphs)

    # Check again
    ref_graphs = historian.archive.get_snapshot_ref_graph(garage_sid)
    make_checks(ref_graphs)
Beispiel #14
0
def test_ref_load_save_load(historian: mincepy.Historian):
    """This is here to catch a bug that manifested when a reference was saved, loaded and then
    re-saved without being dereferenced in-between.  This would result in the second saved state
    being that of a null reference.  This can only be tested if the reference is stored by value
    as otherwise the historian will not re-save a reference that has not been mutated."""
    ref_list = mincepy.List((mincepy.ObjRef(testing.Car()), ))
    assert isinstance(ref_list[0](), testing.Car)

    list_id = ref_list.save()  # pylint: disable=no-member
    del ref_list

    loaded = historian.load(list_id)
    # Re-save
    loaded.save()
    del loaded

    # Re-load
    reloaded = historian.load(list_id)
    # Should still be our car but because of a bug this was a None reference
    assert isinstance(reloaded[0](), testing.Car)
Beispiel #15
0
 def upgrade(cls, saved_state, loader: 'mincepy.Loader') -> dict:
     # Replace the value stored version with a reference
     saved_state['ref'] = mincepy.ObjRef(saved_state['ref'])
     return saved_state
Beispiel #16
0
 def upgrade(cls, saved_state, loader: 'mincepy.Loader'):
     # Create a reference to the live car object
     saved_state['ref'] = mincepy.ObjRef(car)
     return saved_state
Beispiel #17
0
 def ref(self, value):
     self._ref = mincepy.ObjRef(value)
Beispiel #18
0
 def __init__(self, ref=None):
     super().__init__()
     self._ref = mincepy.ObjRef(ref)