code: def test_logger_after_fit_predict_test_calls(tmpdir):
      """Make sure logger outputs are finalized after fit, prediction, and test calls."""
  
      class BufferLogger(Logger):
          def __init__(self):
              super().__init__()
              self.buffer = {}
              self.logs = {}
  
          def log_metrics(
              self,
              metrics: Dict[str, float],
              step: Optional[int] = None,
          ) -> None:
              self.buffer.update(metrics)
  
          def finalize(self, status: str) -> None:
              self.logs.update(self.buffer)
              self.buffer = {}
  
          @property
          def experiment(self) -> Any:
              return None
  
          @property
          def version(self) -> Union[int, str]:
              return 1
  
          @property
          def name(self) -> str:
              return "BufferLogger"
  
          def log_hyperparams(self, *args, **kwargs) -> None:
              return None
  
      class LoggerCallsObserver(Callback):
          def on_fit_end(
              self,
              trainer: "pl.Trainer",
              pl_module: "pl.LightningModule",
          ) -> None:
              trainer.logger.log_metrics({"fit": 1})
  
          def on_validation_end(
              self,
              trainer: "pl.Trainer",
              pl_module: "pl.LightningModule",
          ) -> None:
              trainer.logger.log_metrics({"validate": 1})
  
          def on_predict_end(
              self,
              trainer: "pl.Trainer",
              pl_module: "pl.LightningModule",
          ) -> None:
              trainer.logger.log_metrics({"predict": 1})
  
          def on_test_end(
              self,
              trainer: "pl.Trainer",
              pl_module: "pl.LightningModule",
          ) -> None:
              trainer.logger.log_metrics({"test": 1})
  
      model = BoringModel()
      trainer = Trainer(
          default_root_dir=tmpdir,
          limit_train_batches=1,
          limit_val_batches=1,
          max_epochs=1,
          logger=BufferLogger(),
          callbacks=[LoggerCallsObserver()],
      )
  
      assert not trainer.logger.logs
      trainer.fit(model)
      assert trainer.logger.logs == {"fit": 1, "validate": 1}
      trainer.test(model)
      assert trainer.logger.logs == {"fit": 1, "validate": 1, "test": 1}
      trainer.predict(model)
      assert trainer.logger.logs == {
          "fit": 1,
          "validate": 1,
          "test": 1,
          "predict": 1,
      }
  
imports: import os
  from typing import Any, Dict, Optional, Union
  from unittest.mock import Mock
  import lightning.pytorch
  from lightning.pytorch import Callback, Trainer
  from lightning.pytorch.demos.boring_classes import BoringModel
  from lightning.pytorch.loggers.logger import Logger
  from tests_pytorch.helpers.runif import RunIf
label_desc: Use image node_id 4 for calling a global function with example usage: test_logger_after_fit_predict_test_calls(tmpdir) and returns: None, int, str, None