class_docstr: TestCallback
code: def test_callback(self) -> None:
      train_log = self._init_log()
      eval_log = self._init_log()
      callback = TestCallback.CustomCallback()
  
      # simulate the train loop.
      train_epoch_nums = 3
      train_batch_nums = 5
      callback.on_train_begin(train_log)
      for train_epoch in range(train_epoch_nums):
          callback.on_epoch_begin(train_epoch, train_log)
          for _ in range(train_batch_nums):
              mock_batch = (None, None)
              callback.on_train_batch_begin(mock_batch, train_log)
              callback.on_train_batch_end(mock_batch, train_log)
          callback.on_epoch_end(train_epoch, train_log)
      callback.on_train_end(train_log)
  
      def _assert_train_attrs(attr, gt):
          self.assertEqual(train_log[attr], gt)
  
      _assert_train_attrs("on_batch_begin", 0)
      _assert_train_attrs("on_batch_end", 0)
      _assert_train_attrs("on_epoch_begin", train_epoch_nums)
      _assert_train_attrs("on_epoch_end", train_epoch_nums)
      _assert_train_attrs(
          "on_train_batch_begin", train_epoch_nums * train_batch_nums
      )
      _assert_train_attrs(
          "on_train_batch_end", train_epoch_nums * train_batch_nums
      )
      _assert_train_attrs("on_train_begin", 1)
      _assert_train_attrs("on_train_end", 1)
  
      # simulate the eval loop.
      eval_epoch_nums = 5
      eval_batch_nums = 10
      eval_log = self._init_log()
      callback.on_eval_begin(eval_log)
      for eval_epoch in range(eval_epoch_nums):
          callback.on_epoch_begin(eval_epoch, eval_log)
          for _ in range(eval_batch_nums):
              mock_batch = (None, None)
              callback.on_eval_batch_begin(mock_batch, eval_log)
              callback.on_eval_batch_end(mock_batch, eval_log)
          callback.on_epoch_end(eval_epoch, eval_log)
      callback.on_eval_end(eval_log)
  
      def _assert_eval_attrs(attr, gt):
          self.assertEqual(eval_log[attr], gt)
  
      _assert_eval_attrs("on_batch_begin", 0)
      _assert_eval_attrs("on_batch_end", 0)
      _assert_eval_attrs("on_epoch_begin", eval_epoch_nums)
      _assert_eval_attrs("on_epoch_end", eval_epoch_nums)
      _assert_eval_attrs(
          "on_eval_batch_begin", eval_epoch_nums * eval_batch_nums
      )
      _assert_eval_attrs(
          "on_eval_batch_end", eval_epoch_nums * eval_batch_nums
      )
      _assert_eval_attrs("on_eval_begin", 1)
      _assert_eval_attrs("on_eval_end", 1)
  
file_path: towhee/tests/unittests/trainer/test_callback.py
imports: import unittest
  from typing import Dict, Tuple
  from tqdm import tqdm
  from towhee.trainer.callback import TrainerControl, Callback, CallbackList, EarlyStoppingCallback, ModelCheckpointCallback, TensorBoardCallBack, PrintCallBack, ProgressBarCallBack
label_desc: Use image node_id 2 for calling the TestCallback obj's underlying member method code with example usage: obj.test_callback() without return types