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()
def test_nested_references(historian: mincepy.Historian): car = Car() garage = Garage(car) car_id = historian.save(car) garage_id = historian.save(garage) # Now change the car car.make = 'fiat' car.colour = 'white' historian.save(car) # Try loading while the object is still alive loaded_garage = historian.load(garage_id) assert loaded_garage is garage # Now delete and load del garage del car loaded_garage2 = historian.load(garage_id) # Should be the last version fo the car assert loaded_garage2.car.make == 'fiat' assert len(historian.history(car_id)) == 2 # The following may seem counter intuitive that we only have one history # entry for garage. But above we only saved it once. It's just that when # we load the garage again we get the 'latest' version it's contents i.e. # the newer version of the car assert len(historian.history(garage_id)) == 1
def test_history(historian: mincepy.Historian): rainbow = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'] car = Car() car_id = None for colour in rainbow: car.colour = colour car_id = historian.save(car) car_history = historian.history(car_id) assert len(car_history) == len(rainbow) for i, entry in enumerate(car_history): assert entry[1].colour == rainbow[i] # Test loading directly from snapshot id assert historian.load_snapshot(car_history[2].ref) == car_history[2].obj # Test slicing assert historian.history(car_id, -1)[0].obj.colour == rainbow[-1] # Try changing history old_version = car_history[2].obj old_version.colour = 'black' with pytest.raises(mincepy.ModificationError): historian.save(old_version)
def test_record_times(historian: mincepy.Historian): car = Car('honda', 'red') historian.save(car) time.sleep(0.001) car.colour = 'white' historian.save(car) time.sleep(0.01) car.colour = 'yellow' historian.save(car) history = historian.history(car, as_objects=False) assert len(history) == 3 for idx, record in zip(range(1, 2), history[1:]): assert record.creation_time == history[0].creation_time assert record.snapshot_time > history[0].creation_time assert record.snapshot_time > history[idx - 1].snapshot_time
def test_loading_snapshot(historian: mincepy.Historian): honda = Car('honda', 'white') historian.save(honda) white_honda_sid = historian.get_snapshot_id(honda) honda.colour = 'red' historian.save(honda) del honda with historian.transaction(): white_honda = historian.load_snapshot(white_honda_sid) assert white_honda.colour == 'white' # Make sure that if we load it again we get a different object instance assert white_honda is not historian.load_snapshot(white_honda_sid)
def test_get_latest(historian: mincepy.Historian): # Save the car car = Car() car_id = historian.save(car) # Change it and save getting a snapshot car.make = 'fiat' car.colour = 'white' historian.save(car) fiat_sid = historian.get_snapshot_id(car) assert car_id != fiat_sid # Change it again... car.make = 'honda' car.colour = 'wine red' historian.save(car) honda_sid = historian.get_snapshot_id(car) assert honda_sid != fiat_sid assert honda_sid != car_id # Now delete and reload del car latest = historian.load(car_id) assert latest == historian.load_snapshot(honda_sid)
def test_purge(historian: mincepy.Historian): """Test that snapshots.purge() removes snapshots corresponding to deleted objects""" assert historian.snapshots.purge().deleted_purged == set() car = Car() car_id = car.save() car.colour = 'yellow' car.save() # Insert something else just to check that it doesn't get accidentally purged car2 = Car() car2.save() historian.delete(car) records_count = historian.records.find().count() res = historian.snapshots.purge(dry_run=False) assert records_count == historian.records.find().count() assert res.deleted_purged == { mincepy.SnapshotId(car_id, 0), mincepy.SnapshotId(car_id, 1), mincepy.SnapshotId(car_id, 2) # The deleted record }