async def test_disabled_at_install(coord: Coordinator, dest, time):
    """
    Verifies that at install time, if some snapshots are already present the
    addon doesn't try to sync over and over when drive is disabled.  This was
    a problem at one point.
    """
    dest.setEnabled(True)
    await coord.sync()
    assert len(coord.snapshots()) == 1

    dest.setEnabled(False)
    time.advance(days=5)
    assert coord.check()
    await coord.sync()
    assert not coord.check()
async def test_alternate_timezone(coord: Coordinator, time: FakeTime, model: Model, dest, source, simple_config: Config):
    time.setTimeZone("Europe/Stockholm")
    simple_config.override(Setting.BACKUP_TIME_OF_DAY, "12:00")
    simple_config.override(Setting.DAYS_BETWEEN_BACKUPS, 1)

    source.setMax(10)
    source.insert("Fri", time.toUtc(time.local(2020, 3, 16, 18, 5)))
    time.setNow(time.local(2020, 3, 16, 18, 6))
    model.reinitialize()
    coord.reset()
    await coord.sync()
    assert not coord.check()
    assert coord.nextBackupTime() == time.local(2020, 3, 17, 12)

    time.setNow(time.local(2020, 3, 17, 11, 59))
    await coord.sync()
    assert not coord.check()
    time.setNow(time.local(2020, 3, 17, 12))
    assert coord.check()
async def test_backoff(coord: Coordinator, model, source: HelperTestSource,
                       dest: HelperTestSource, snapshot, time: FakeTime,
                       simple_config: Config):
    assert coord.check()
    simple_config.override(Setting.DAYS_BETWEEN_SNAPSHOTS, 1)
    simple_config.override(Setting.MAX_SYNC_INTERVAL_SECONDS, 60 * 60 * 6)

    assert coord.nextSyncAttempt() == time.now() + timedelta(hours=6)
    assert not coord.check()
    error = Exception("BOOM")
    old_sync = model.sync
    model.sync = lambda s: doRaise(error)
    await coord.sync()

    # first backoff should be 0 seconds
    assert coord.nextSyncAttempt() == time.now()
    assert coord.check()

    # backoff maxes out at 1 hr = 3600 seconds
    for seconds in [
            10, 20, 40, 80, 160, 320, 640, 1280, 2560, 3600, 3600, 3600
    ]:
        await coord.sync()
        assert coord.nextSyncAttempt() == time.now() + timedelta(
            seconds=seconds)
        assert not coord.check()
        assert not coord.check()
        assert not coord.check()

    # a good sync resets it back to 6 hours from now
    model.sync = old_sync
    await coord.sync()
    assert coord.nextSyncAttempt() == time.now() + timedelta(hours=6)
    assert not coord.check()

    # if the next snapshot is less that 6 hours from the last one, that that shoudl be when we sync
    simple_config.override(Setting.DAYS_BETWEEN_SNAPSHOTS, 1.0 / 24.0)
    assert coord.nextSyncAttempt() == time.now() + timedelta(hours=1)
    assert not coord.check()

    time.advance(hours=2)
    assert coord.nextSyncAttempt() == time.now() - timedelta(hours=1)
    assert coord.check()