async def test_delayed_start_give_up(supervisor: SimulatedSupervisor,
                                     addon_stopper: AddonStopper,
                                     config: Config,
                                     interceptor: RequestInterceptor,
                                     time: FakeTime) -> None:
    slug1 = "test_slug_1"
    supervisor.installAddon(slug1, "Test decription")
    config.override(Setting.STOP_ADDONS, ",".join([slug1]))
    addon_stopper.allowRun()
    addon_stopper.must_start = set()
    assert supervisor.addon(slug1)["state"] == "started"
    await addon_stopper.stopAddons("ignore")
    assert supervisor.addon(slug1)["state"] == "stopped"
    assert getSaved(config) == ({slug1}, set())

    # start the addon again, which simluates the supervisor's tendency to report an addon as started right after stopping it.
    supervisor.addon(slug1)["state"] = "started"
    await addon_stopper.check()
    await addon_stopper.startAddons()
    assert getSaved(config) == ({slug1}, set())

    time.advance(seconds=30)
    await addon_stopper.check()
    assert getSaved(config) == ({slug1}, set())

    time.advance(seconds=30)
    await addon_stopper.check()
    assert getSaved(config) == ({slug1}, set())

    # Should clear saved state after this, since it stops checking after 2 minutes.
    time.advance(seconds=100)
    await addon_stopper.check()
    assert getSaved(config) == (set(), set())
Exemplo n.º 2
0
async def test_start_on_boot(ha: HaSource, time,
                             interceptor: RequestInterceptor, config: Config,
                             supervisor: SimulatedSupervisor) -> None:
    boot_slug = "boot_slug"
    supervisor.installAddon(boot_slug,
                            "Start on boot",
                            boot=True,
                            started=False)

    no_boot_slug = "no_boot_slug"
    supervisor.installAddon(no_boot_slug,
                            "Don't start on boot",
                            boot=False,
                            started=False)
    config.override(Setting.STOP_ADDONS, ",".join([boot_slug, no_boot_slug]))
    config.override(Setting.NEW_SNAPSHOT_TIMEOUT_SECONDS, 0.001)

    assert supervisor.addon(boot_slug)["state"] == "stopped"
    assert supervisor.addon(no_boot_slug)["state"] == "stopped"
    async with supervisor._snapshot_inner_lock:
        await ha.create(CreateOptions(time.now(), "Test Name"))
        assert supervisor.addon(boot_slug)["state"] == "stopped"
    assert supervisor.addon(no_boot_slug)["state"] == "stopped"
    await ha._pending_snapshot_task
    assert supervisor.addon(boot_slug)["state"] == "started"
    assert supervisor.addon(no_boot_slug)["state"] == "stopped"
    assert len(await ha.get()) == 1
    assert not interceptor.urlWasCalled(URL_MATCH_START_ADDON)
    assert not interceptor.urlWasCalled(URL_MATCH_STOP_ADDON)
Exemplo n.º 3
0
async def test_cant_reach_refresh_server(drive: DriveSource, server: SimulationServer, config: Config, time):
    config.override(Setting.TOKEN_SERVER_HOSTS, "http://lkasdpoiwehjhcty.com")
    drive.drivebackend.creds._secret = None
    time.advanceDay()
    with pytest.raises(CredRefreshMyError) as error:
        await drive.get()
    assert error.value.data() == {"reason": "Couldn't communicate with lkasdpoiwehjhcty.com"}
async def test_failed_snapshot(time, ha: HaSource,
                               supervisor: SimulatedSupervisor, config: Config,
                               interceptor: RequestInterceptor):
    # create a blocking snapshot
    interceptor.setError(URL_MATCH_SNAPSHOT_FULL, 524)
    config.override(Setting.NEW_SNAPSHOT_TIMEOUT_SECONDS, 0)
    await supervisor.toggleBlockSnapshot()
    snapshot_immediate = await ha.create(CreateOptions(time.now(),
                                                       "Some Name"))
    assert isinstance(snapshot_immediate, PendingSnapshot)
    assert snapshot_immediate.name() == "Some Name"
    assert not ha.check()
    assert not snapshot_immediate.isFailed()
    await supervisor.toggleBlockSnapshot()

    # let the snapshot attempt to complete
    await asyncio.wait({ha._pending_snapshot_task})

    # verify it failed with the expected http error
    assert snapshot_immediate.isFailed()
    assert snapshot_immediate._exception.status == 524

    snapshots = list((await ha.get()).values())
    assert len(snapshots) == 1
    assert snapshots[0] is snapshot_immediate

    # verify we can create a new snapshot immediately
    interceptor.clear()
    await ha.create(CreateOptions(time.now(), "Some Name"))
    assert len(await ha.get()) == 1
async def test_only_send_duplicates(time, debug_worker: DebugWorker,
                                    config: Config, global_info: GlobalInfo,
                                    server, error_store: ErrorStore):
    config.override(Setting.SEND_ERROR_REPORTS, True)
    config.override(Setting.DRIVE_HOST_NAME, "localhost")
    global_info.failed(Exception("boom1"))
    firstExceptionTime = time.now()
    await debug_worker.doWork()
    report = error_store.last_error
    assert report['report']["error"] == getLogger("test").formatException(
        Exception("boom1"))
    assert report['report']["time"] == firstExceptionTime.isoformat()

    # Same exception shouldn't cause us to send the error report again
    time.advance(days=1)
    global_info.failed(Exception("boom1"))
    await debug_worker.doWork()
    report = error_store.last_error
    assert report['report']["error"] == getLogger("test").formatException(
        Exception("boom1"))
    assert report['report']["time"] == firstExceptionTime.isoformat()

    # Btu a new one will send a new report
    global_info.failed(Exception("boom2"))
    await debug_worker.doWork()
    report = error_store.last_error
    assert report['report']["error"] == getLogger("test").formatException(
        Exception("boom2"))
    assert report['report']["time"] == time.now().isoformat()
Exemplo n.º 6
0
async def test_cred_refresh_upgrade_default_client(drive: DriveSource,
                                                   server: SimulationServer,
                                                   time: FakeTime,
                                                   config: Config):
    return
    # TODO: Enable this when we start removing the default client_secret
    config.override(Setting.DEFAULT_DRIVE_CLIENT_ID,
                    server.getSetting("drive_client_id"))
    creds = server.getCurrentCreds()
    creds_with_secret = server.getCurrentCreds()
    creds_with_secret._secret = server.getSetting("drive_client_secret")
    with open(config.get(Setting.CREDENTIALS_FILE_PATH), "w") as f:
        json.dump(creds_with_secret.serialize(), f)

    # reload the creds
    drive.drivebackend.tryLoadCredentials()

    # Verify the "client secret" was removed
    with open(config.get(Setting.CREDENTIALS_FILE_PATH)) as f:
        saved_creds = json.load(f)
        assert saved_creds == creds.serialize()

    await drive.get()
    old_creds = drive.drivebackend.cred_bearer
    await drive.get()
    assert old_creds == drive.drivebackend.cred_bearer
    time.advanceDay()
    await drive.get()
    assert old_creds != drive.drivebackend.cred_bearer
async def test_update_ignore(reader: ReaderHelper, time: FakeTime,
                             coord: Coordinator, config: Config,
                             supervisor: SimulatedSupervisor, ha: HaSource,
                             drive: DriveSource):
    config.override(Setting.IGNORE_UPGRADE_SNAPSHOTS, True)
    config.override(Setting.DAYS_BETWEEN_SNAPSHOTS, 0)

    # make an ignored_snapshot
    slug = await supervisor.createSnapshot(
        {
            'name': "Ignore_me",
            'folders': ['homeassistant'],
            'addons': []
        },
        date=time.now())

    await coord.sync()
    assert len(await drive.get()) == 0
    assert len(await ha.get()) == 1
    assert len(coord.snapshots()) == 1

    # Disable Drive Upload
    update = {
        "ignore": False,
        "slug": slug,
    }
    await reader.postjson("ignore", json=update)
    await coord.waitForSyncToFinish()
    assert len(coord.snapshots()) == 1
    assert len(await drive.get()) == 1
    assert len(await ha.get()) == 1
Exemplo n.º 8
0
async def test_drive_dns_resolution_error(drive: DriveSource, config: Config,
                                          time):
    config.override(Setting.DRIVE_URL,
                    "http://fsdfsdasdasdf.saasdsdfsdfsd.com:2567")
    with pytest.raises(GoogleCantConnect):
        await drive.get()
    assert time.sleeps == []
async def test_pending_snapshot_replaces_original(
        time, ha: HaSource, config: Config, supervisor: SimulatedSupervisor):
    # now configure a snapshto to start outside of the addon
    config.override(Setting.NEW_SNAPSHOT_TIMEOUT_SECONDS, 100)
    await supervisor.toggleBlockSnapshot()
    with pytest.raises(SnapshotInProgress):
        await ha.create(CreateOptions(time.now(), "Ignored"))
    snapshot_immediate = (await ha.get())['pending']
    await supervisor.toggleBlockSnapshot()
    assert isinstance(snapshot_immediate, PendingSnapshot)
    assert snapshot_immediate.name() == "Pending Snapshot"
    assert ha.check()
    assert ha.pending_snapshot is snapshot_immediate
    assert await ha.get() == {snapshot_immediate.slug(): snapshot_immediate}

    # create a new snapshot behind the scenes, the pending snapshot should get replaced with the new one
    slug = (await ha.harequests.createSnapshot({
        'name': "Suddenly Appears",
        "hardlock": True
    }))['slug']
    results = await ha.get()
    assert len(results) == 1
    assert slug in results
    assert results[slug].name() == "Suddenly Appears"
    assert not results[slug].retained()
async def test_partial_snapshot(ha, time, server, config: Config):
    config.override(Setting.NEW_SNAPSHOT_TIMEOUT_SECONDS, 100)
    for folder in all_folders:
        config.override(Setting.EXCLUDE_FOLDERS, folder)
        snapshot: HASnapshot = await ha.create(
            CreateOptions(time.now(), "Test Name"))

        assert snapshot.snapshotType() == "partial"
        for search in all_folders:
            if search == folder:
                assert search not in snapshot.details()['folders']
            else:
                assert search in snapshot.details()['folders']

    for addon in all_addons:
        config.override(Setting.EXCLUDE_ADDONS, addon['slug'])
        snapshot: HASnapshot = await ha.create(
            CreateOptions(time.now(), "Test Name"))
        assert snapshot.snapshotType() == "partial"
        list_of_addons = []
        for included in snapshot.details()['addons']:
            list_of_addons.append(included['slug'])
        for search in list_of_addons:
            if search == addon:
                assert search not in list_of_addons
            else:
                assert search in list_of_addons

    # excluding addon/folders that don't exist should actually make a full snapshot
    config.override(Setting.EXCLUDE_ADDONS, "none,of.these,are.addons")
    config.override(Setting.EXCLUDE_FOLDERS, "not,folders,either")
    snapshot: HASnapshot = await ha.create(
        CreateOptions(time.now(), "Test Name"))
    assert snapshot.snapshotType() == "full"
async def test_failed_backup(time, ha: HaSource,
                             supervisor: SimulatedSupervisor, config: Config,
                             interceptor: RequestInterceptor):
    # create a blocking backup
    interceptor.setError(URL_MATCH_BACKUP_FULL, 524)
    config.override(Setting.NEW_BACKUP_TIMEOUT_SECONDS, 0)
    await supervisor.toggleBlockBackup()
    backup_immediate = await ha.create(CreateOptions(time.now(), "Some Name"))
    assert isinstance(backup_immediate, PendingBackup)
    assert backup_immediate.name() == "Some Name"
    assert not ha.check()
    assert not backup_immediate.isFailed()
    await supervisor.toggleBlockBackup()

    # let the backup attempt to complete
    await asyncio.wait({ha._pending_backup_task})

    # verify it failed with the expected http error
    assert backup_immediate.isFailed()
    assert backup_immediate._exception.status == 524

    backups = list((await ha.get()).values())
    assert len(backups) == 1
    assert backups[0] is backup_immediate

    # verify we can create a new backup immediately
    interceptor.clear()
    await ha.create(CreateOptions(time.now(), "Some Name"))
    assert len(await ha.get()) == 1
async def test_dont_purge_pending_backup(ha: HaSource, time, config: Config,
                                         supervisor: SimulatedSupervisor,
                                         model: Model, interceptor):
    config.override(Setting.MAX_BACKUPS_IN_HA, 4)
    await ha.create(CreateOptions(time.now(), "Test Name 1"))
    await ha.create(CreateOptions(time.now(), "Test Name 2"))
    await ha.create(CreateOptions(time.now(), "Test Name 3"))
    await ha.create(CreateOptions(time.now(), "Test Name 4"))
    await model.sync(time.now())

    config.override(Setting.NEW_BACKUP_TIMEOUT_SECONDS, 0.1)
    interceptor.setSleep(URL_MATCH_BACKUP_FULL, sleep=2)
    await ha.create(CreateOptions(time.now(), "Test Name"))
    backups = list((await ha.get()).values())
    assert len(backups) == 5
    backup = backups[4]
    assert isinstance(backup, PendingBackup)

    # no backup should get purged yet because the ending backup isn't considered for purging.
    await model.sync(time.now())
    backups = list((await ha.get()).values())
    assert len(backups) == 5

    # Wait for the backup to finish, then verify one gets purged.
    await ha._pending_backup_task
    await model.sync(time.now())
    backups = list((await ha.get()).values())
    assert len(backups) == 4
Exemplo n.º 13
0
async def test_update_backups_old_names(updater: HaUpdater, server, backup: Backup, time: FakeTime, supervisor: SimulatedSupervisor, config: Config):
    config.override(Setting.CALL_BACKUP_SNAPSHOT, True)
    await updater.update()
    assert not updater._stale()
    assert updater._state() == "backed_up"
    verifyEntity(supervisor, "binary_sensor.snapshots_stale",
                 "off", {"friendly_name": "Snapshots Stale",
                         "device_class": "problem"})
    date = '1985-12-06T05:00:00+00:00'
    verifyEntity(supervisor, "sensor.snapshot_backup", "backed_up", {
        'friendly_name': 'Snapshot State',
        'last_snapshot': date,
        'snapshots': [{
            'date': date,
            'name': backup.name(),
            'size': backup.sizeString(),
            'state': backup.status(),
            'slug': backup.slug()
        }
        ],
        'snapshots_in_google_drive': 1,
        'snapshots_in_home_assistant': 1,
        'snapshots_in_hassio': 1,
        'size_in_home_assistant': Estimator.asSizeString(backup.size()),
        'size_in_google_drive': Estimator.asSizeString(backup.size())
    })
async def test_failed_snapshot_retry(ha: HaSource, time: FakeTime,
                                     config: Config,
                                     supervisor: SimulatedSupervisor,
                                     interceptor: RequestInterceptor):
    # create a blocking snapshot
    interceptor.setError(URL_MATCH_SNAPSHOT_FULL, 524)
    config.override(Setting.NEW_SNAPSHOT_TIMEOUT_SECONDS, 0)
    await supervisor.toggleBlockSnapshot()
    snapshot_immediate = await ha.create(CreateOptions(time.now(),
                                                       "Some Name"))
    assert isinstance(snapshot_immediate, PendingSnapshot)
    assert snapshot_immediate.name() == "Some Name"
    assert not ha.check()
    assert not snapshot_immediate.isFailed()
    await supervisor.toggleBlockSnapshot()

    # let the snapshot attempt to complete
    await asyncio.wait({ha._pending_snapshot_task})

    # verify it failed with the expected http error
    assert snapshot_immediate.isFailed()
    assert snapshot_immediate._exception.status == 524

    assert ha.check()
    assert not ha.check()
    time.advance(seconds=config.get(Setting.FAILED_SNAPSHOT_TIMEOUT_SECONDS))

    # should trigger a sync after the failed snapshot timeout
    assert ha.check()
    await ha.get()
    assert not ha.check()
async def test_cant_reach_refresh_server(drive: DriveSource, server: SimulationServer, config: Config, time):
    config.override(Setting.REFRESH_URL, "http://lkasdpoiwehjhcty.com")
    drive.drivebackend.creds._secret = None
    time.advanceDay()
    with pytest.raises(CredRefreshMyError) as error:
        await drive.get()
    assert error.value.data() == {"reason": "Unable to connect to https://habackup.io"}
async def test_dont_purge_pending_snapshot(ha: HaSource, time, config: Config,
                                           supervisor: SimulatedSupervisor,
                                           model: Model, interceptor):
    config.override(Setting.MAX_SNAPSHOTS_IN_HASSIO, 4)
    await ha.create(CreateOptions(time.now(), "Test Name 1"))
    await ha.create(CreateOptions(time.now(), "Test Name 2"))
    await ha.create(CreateOptions(time.now(), "Test Name 3"))
    await ha.create(CreateOptions(time.now(), "Test Name 4"))
    await model.sync(time.now())

    config.override(Setting.NEW_SNAPSHOT_TIMEOUT_SECONDS, 0.1)
    interceptor.setSleep(URL_MATCH_SNAPSHOT_FULL, sleep=2)
    await ha.create(CreateOptions(time.now(), "Test Name"))
    snapshots = list((await ha.get()).values())
    assert len(snapshots) == 5
    snapshot = snapshots[4]
    assert isinstance(snapshot, PendingSnapshot)

    # no snapshot should get purged yet because the ending snapshot isn't considered for purging.
    await model.sync(time.now())
    snapshots = list((await ha.get()).values())
    assert len(snapshots) == 5

    # Wait for the snapshot to finish, then verify one gets purged.
    await ha._pending_snapshot_task
    await model.sync(time.now())
    snapshots = list((await ha.get()).values())
    assert len(snapshots) == 4
Exemplo n.º 17
0
async def test_purge_before_upload(source: HelperTestSource,
                                   dest: HelperTestSource, time: FakeTime,
                                   model: Model, data_cache: DataCache,
                                   simple_config: Config):
    source.setMax(2)
    dest.setMax(2)
    older = source.insert("older",
                          time.now() - timedelta(days=7),
                          slug="older")
    oldest = source.insert("oldest",
                           time.now() - timedelta(days=14),
                           slug="oldest")
    await model.sync(time.now() - timedelta(days=7))

    source.allow_create = False
    dest.allow_save = False

    dest.reset()
    source.reset()

    # trying to sync now should do nothing.
    with pytest.raises(IntentionalFailure):
        await model.sync(time.now())
    source.assertThat(current=2)
    dest.assertThat(current=2)

    simple_config.override(Setting.DELETE_BEFORE_NEW_BACKUP, True)
    # Trying to sync should delete the backup before syncing and then fail to create a new one.
    with pytest.raises(IntentionalFailure):
        await model.sync(time.now())
    source.assertThat(deleted=1, current=1)
    assert oldest.slug() not in (await source.get()).keys()
    dest.assertThat(current=2)

    # Trying to do it again should do nothing (eg not delete another backup)
    with pytest.raises(IntentionalFailure):
        await model.sync(time.now())
    source.assertThat(deleted=1, current=1)
    dest.assertThat(current=2)

    # let the new source backup get created, which then deletes the destination but fails to save
    source.allow_create = True
    with pytest.raises(IntentionalFailure):
        await model.sync(time.now())
    source.assertThat(deleted=1, current=2, created=1)
    dest.assertThat(current=1, deleted=1)
    assert oldest.slug() not in (await dest.get()).keys()

    # now let the new backup get saved.
    dest.allow_save = True
    await model.sync(time.now())
    source.assertThat(deleted=1, current=2, created=1)
    dest.assertThat(current=2, deleted=1, saved=1)

    assert oldest.slug() not in (await source.get()).keys()
    assert older.slug() in (await source.get()).keys()
    assert oldest.slug() not in (await dest.get()).keys()
    assert older.slug() in (await dest.get()).keys()
async def test_dont_send_error_report(time, debug_worker: DebugWorker,
                                      config: Config, global_info: GlobalInfo,
                                      server: SimulationServer,
                                      error_store: ErrorStore):
    config.override(Setting.SEND_ERROR_REPORTS, False)
    config.override(Setting.DRIVE_HOST_NAME, "localhost")
    global_info.failed(Exception())
    await debug_worker.doWork()
    assert error_store.last_error is None
async def test_bad_host(debug_worker: DebugWorker, config: Config):
    skipForWindows()
    config.override(Setting.DRIVE_HOST_NAME, "dasdfdfgvxcvvsoejbr.com")
    await debug_worker.doWork()
    assert debug_worker.dns_info == {
        'dasdfdfgvxcvvsoejbr.com': {
            'dasdfdfgvxcvvsoejbr.com': "Name or service not known"
        }
    }
async def test_folder_invalid_when_specified(time, drive: DriveSource, config: Config, server):
    await drive.get()

    config.override(Setting.SPECIFY_SNAPSHOT_FOLDER, "true")
    await drive.drivebackend.update(await drive.getFolderId(), {"trashed": True})

    time.advanceDay()

    with pytest.raises(BackupFolderInaccessible):
        await drive.get()
async def test_supervisor_host(ha: HaSource, supervisor: SimulatedSupervisor,
                               interceptor: RequestInterceptor, config: Config,
                               server_url):
    assert ha.harequests.getSupervisorURL() == server_url

    config.override(Setting.SUPERVISOR_URL, "")
    assert ha.harequests.getSupervisorURL() == URL("http://hassio")

    os.environ['SUPERVISOR_TOKEN'] = "test"
    assert ha.harequests.getSupervisorURL() == URL("http://supervisor")
async def test_dns_info(debug_worker: DebugWorker, config: Config):
    skipForWindows()
    config.override(Setting.SEND_ERROR_REPORTS, True)
    config.override(Setting.DRIVE_HOST_NAME, "localhost")
    await debug_worker.doWork()
    assert debug_worker.dns_info == {
        'localhost': {
            '127.0.0.1': 'alive',
            'localhost': 'alive'
        }
    }
async def test_empty_name_server(resolver: Resolver, config: Config):
    assert resolver._alt_dns.nameservers == ["8.8.8.8", "8.8.4.4"]
    assert resolver._resolver is resolver._original_dns
    config.override(Setting.ALTERNATE_DNS_SERVERS, "")
    resolver.updateConfig()
    assert resolver._resolver is resolver._alt_dns

    # make sure the value is cached
    prev = resolver._alt_dns
    resolver.updateConfig()
    assert resolver._alt_dns is prev
Exemplo n.º 24
0
async def test_ignored_backups(updater: HaUpdater, time: FakeTime, server: SimulationServer, backup: Backup, supervisor: SimulatedSupervisor, coord: Coordinator, config: Config):
    config.override(Setting.IGNORE_OTHER_BACKUPS, True)
    time.advance(hours=1)
    await supervisor.createBackup({'name': "test_backup"}, date=time.now())
    await coord.sync()
    await updater.update()
    state = supervisor.getAttributes("sensor.backup_state")
    assert state["backups_in_google_drive"] == 1
    assert state["backups_in_home_assistant"] == 1
    assert len(state["backups"]) == 1
    assert state['last_backup'] == backup.date().isoformat()
async def test_ignored_snapshots(updater: HaUpdater, time: Time,
                                 server: SimulationServer, snapshot,
                                 supervisor: SimulatedSupervisor,
                                 coord: Coordinator, config: Config):
    config.override(Setting.IGNORE_OTHER_SNAPSHOTS, True)
    await supervisor.createSnapshot({'name': "test_snapshot"}, date=time.now())
    await coord.sync()
    await updater.update()
    state = supervisor.getAttributes("sensor.snapshot_backup")
    assert state["snapshots_in_google_drive"] == 1
    assert state["snapshots_in_home_assistant"] == 1
    assert len(state["snapshots"]) == 2
async def test_pending_snapshot_nowait(ha: HaSource, time,
                                       supervisor: SimulatedSupervisor,
                                       interceptor: RequestInterceptor,
                                       config: Config):
    interceptor.setSleep(URL_MATCH_SNAPSHOT_FULL, sleep=5)
    config.override(Setting.NEW_SNAPSHOT_TIMEOUT_SECONDS, 0.1)
    snapshot_immediate: PendingSnapshot = await ha.create(
        CreateOptions(time.now(), "Test Name"))
    assert isinstance(snapshot_immediate, PendingSnapshot)
    snapshot_pending: HASnapshot = (await ha.get())['pending']

    assert isinstance(snapshot_immediate, PendingSnapshot)
    assert isinstance(snapshot_pending, PendingSnapshot)
    assert snapshot_immediate is snapshot_pending
    assert snapshot_immediate.name() == "Test Name"
    assert snapshot_immediate.slug() == "pending"
    assert not snapshot_immediate.uploadable()
    assert snapshot_immediate.snapshotType() == "Full"
    assert snapshot_immediate.source() == SOURCE_HA
    assert snapshot_immediate.date() == time.now()
    assert not snapshot_immediate.protected()

    # Might be a little flaky but...whatever
    await asyncio.wait({ha._pending_snapshot_task})

    snapshots = await ha.get()
    assert 'pending' not in snapshots
    assert isinstance(next(iter(snapshots.values())), HASnapshot)

    return
    # ignroe events for now
    assert supervisor.getEvents() == [(EVENT_SNAPSHOT_START, {
        'snapshot_name':
        snapshot_immediate.name(),
        'snapshot_time':
        str(snapshot_immediate.date())
    })]
    ha.snapshot_thread.join()
    assert supervisor.getEvents() == [(EVENT_SNAPSHOT_START, {
        'snapshot_name':
        snapshot_immediate.name(),
        'snapshot_time':
        str(snapshot_immediate.date())
    }),
                                      (EVENT_SNAPSHOT_END, {
                                          'completed':
                                          True,
                                          'snapshot_name':
                                          snapshot_immediate.name(),
                                          'snapshot_time':
                                          str(snapshot_immediate.date())
                                      })]
async def test_confirm_multiple_deletes(reader, ui_server, server,
                                        config: Config, time: FakeTime,
                                        ha: HaSource):
    # reconfigure to only store 1 snapshot
    server._options.update({
        "max_snapshots_in_hassio": 1,
        "max_snapshots_in_google_drive": 1
    })
    config.override(Setting.MAX_SNAPSHOTS_IN_HASSIO, 1)
    config.override(Setting.MAX_SNAPSHOTS_IN_GOOGLE_DRIVE, 1)

    # create three snapshots
    await ha.create(CreateOptions(time.now(), "Name1"))
    await ha.create(CreateOptions(time.now(), "Name2"))
    await ha.create(CreateOptions(time.now(), "Name3"))

    # verify we have 3 snapshots an the multiple delete error
    status = await reader.getjson("sync")
    assert len(status['snapshots']) == 3
    assert status["last_error"]["error_type"] == ERROR_MULTIPLE_DELETES
    assert status["last_error"]["data"] == {
        SOURCE_GOOGLE_DRIVE: 0,
        SOURCE_HA: 2
    }

    # request that multiple deletes be allowed
    assert await reader.getjson("confirmdelete?always=false") == {
        'message': 'Snapshots deleted this one time'
    }
    assert config.get(Setting.CONFIRM_MULTIPLE_DELETES)

    # backup, verify the deletes go through
    status = await reader.getjson("sync")
    assert status["last_error"] is None
    assert len(status["snapshots"]) == 1

    # create another snapshot, verify we delete the one
    await ha.create(CreateOptions(time.now(), "Name1"))
    status = await reader.getjson("sync")
    assert len(status['snapshots']) == 1
    assert status["last_error"] is None

    # create two mroe snapshots, verify we see the error again
    await ha.create(CreateOptions(time.now(), "Name1"))
    await ha.create(CreateOptions(time.now(), "Name2"))
    status = await reader.getjson("sync")
    assert len(status['snapshots']) == 3
    assert status["last_error"]["error_type"] == ERROR_MULTIPLE_DELETES
    assert status["last_error"]["data"] == {
        SOURCE_GOOGLE_DRIVE: 0,
        SOURCE_HA: 2
    }
Exemplo n.º 28
0
async def test_expose_extra_server_option(reader, ui_server: UiServer, config: Config):
    with pytest.raises(aiohttp.client_exceptions.ClientConnectionError):
        await reader.getjson("sync", ingress=False)
    config.override(Setting.EXPOSE_EXTRA_SERVER, True)
    await ui_server.run()
    await reader.getjson("sync", ingress=False)
    await ui_server.run()
    await reader.getjson("sync", ingress=False)
    config.override(Setting.EXPOSE_EXTRA_SERVER, False)
    await ui_server.run()
    with pytest.raises(aiohttp.client_exceptions.ClientConnectionError):
        await reader.getjson("sync", ingress=False)
    await reader.getjson("sync")
Exemplo n.º 29
0
async def test_download_timeout(time, drive: DriveSource, config: Config, interceptor: RequestInterceptor, backup_helper):
    config.override(Setting.DOWNLOAD_TIMEOUT_SECONDS, 0.1)
    from_backup, data = await backup_helper.createFile()
    backup = await drive.save(from_backup, data)

    # Verify the uploaded bytes are identical
    from_backup.addSource(backup)
    interceptor.setSleep(URL_MATCH_FILE, sleep=100)
    download = await drive.read(from_backup)
    data.position(0)

    with pytest.raises(GoogleTimeoutError):
        await compareStreams(data, download)
async def test_download_timeout(time, drive: DriveSource, config: Config, server: SimulationServer, snapshot_helper):
    config.override(Setting.DOWNLOAD_TIMEOUT_SECONDS, 1)
    from_snapshot, data = await snapshot_helper.createFile()
    snapshot = await drive.save(from_snapshot, data)

    # Verify the uploaded bytes are identical
    from_snapshot.addSource(snapshot)
    server.drive_sleep = 100
    download = await drive.read(from_snapshot)
    data.position(0)
    
    with pytest.raises(GoogleTimeoutError):
        await compareStreams(data, download)