code: def test_is_done(self) -> None:
      p = Progress(
          num_epochs_completed=2,
          num_steps_completed=100,
          num_steps_completed_in_epoch=5,
      )
  
      self.assertTrue(_is_done(p, max_epochs=2, max_steps=200))
      self.assertTrue(_is_done(p, max_epochs=2, max_steps=None))
      self.assertTrue(_is_done(p, max_epochs=3, max_steps=100))
      self.assertTrue(_is_done(p, max_epochs=None, max_steps=100))
  
      self.assertFalse(_is_done(p, max_epochs=3, max_steps=200))
      self.assertFalse(_is_done(p, max_epochs=None, max_steps=200))
      self.assertFalse(_is_done(p, max_epochs=3, max_steps=None))
      self.assertFalse(_is_done(p, max_epochs=None, max_steps=None))
  
imports: import unittest
  from typing import cast, Dict, Iterator
  import torch
  from torch import distributed, nn
  from torch.distributed import launcher
  from torch.utils.data import DataLoader
  from torch.utils.data.distributed import DistributedSampler
  from torchtnt.framework._loop_utils import _is_done, _is_epoch_done, _maybe_set_distributed_sampler_epoch, _reset_module_training_mode, _set_module_training_mode, _step_requires_iterator
  from torchtnt.framework._test_utils import generate_random_dataset
  from torchtnt.framework.state import State
  from torchtnt.utils.progress import Progress
  from torchtnt.utils.test_utils import get_pet_launch_config
label_desc: Use image node_id 6 for calling the LoopUtilsTest obj's underlying member method code with example usage: obj.test_is_done() without return types