def test_fit_ckpt_path_epoch_restored(monkeypatch, tmp_path, tmpdir_server, url_ckpt):
    """Verify resuming from checkpoint runs the right number of epochs."""
    # set $TORCH_HOME, which determines torch hub's cache path, to tmp_path
    monkeypatch.setenv("TORCH_HOME", tmp_path)

    class TestModel(BoringModel):
        # Model that tracks epochs and batches seen
        num_epochs_end_seen = 0
        num_batches_seen = 0
        num_on_load_checkpoint_called = 0

        def on_train_epoch_end(self):
            self.num_epochs_end_seen += 1

        def on_train_batch_start(self, *_):
            self.num_batches_seen += 1

        def on_load_checkpoint(self, _):
            self.num_on_load_checkpoint_called += 1

    model = TestModel()
    max_epochs = 2
    trainer = Trainer(
        max_epochs=max_epochs,
        limit_train_batches=0.65,
        limit_val_batches=1,
        callbacks=ModelCheckpoint(dirpath=tmp_path, save_top_k=-1),
        default_root_dir=tmp_path,
        val_check_interval=1.0,
        enable_progress_bar=False,
        logger=False,
        enable_model_summary=False,
    )
    trainer.fit(model)

    assert model.num_epochs_end_seen == max_epochs
    assert model.num_batches_seen == trainer.num_training_batches * max_epochs == trainer.global_step
    assert model.num_on_load_checkpoint_called == 0

    checkpoints = set(Path(trainer.checkpoint_callback.dirpath).glob("*.ckpt"))
    if url_ckpt:
        # transform local paths into url checkpoints
        ip, port = tmpdir_server
        checkpoints = [f"http://{ip}:{port}/" + ckpt.name for ckpt in checkpoints]

    assert len(checkpoints) == max_epochs
    for ckpt in checkpoints:
        model = TestModel()
        state = pl_load(ckpt)
        # Resume training
        trainer = Trainer(default_root_dir=tmp_path, max_epochs=2, enable_progress_bar=False)
        trainer.fit(model, ckpt_path=ckpt)
        assert state["global_step"] + model.num_batches_seen == trainer.global_step
        assert model.num_on_load_checkpoint_called == 1
Verify resuming from checkpoint runs the right number of epochs.
tests/tests_pytorch/trainer/test_trainer.py