code: def test_on_episode_created(self):
      # 1000 steps sampled (2.5 episodes on each sub-environment) before training
      # starts.
      config = (
          dqn.DQNConfig()
          .environment(
              RandomEnv,
              env_config={
                  "max_episode_len": 200,
                  "p_terminated": 0.0,
              },
          )
          .rollouts(num_envs_per_worker=2, num_rollout_workers=1)
          .callbacks(OnEpisodeCreatedCallback)
      )
  
      # Test with and without Connectors.
      for connector in [True, False]:
          config.rollouts(enable_connectors=connector)
          algo = config.build()
          algo.train()
          # Two sub-environments share 1000 steps in the first training iteration
          # (min_sample_timesteps_per_iteration = 1000).
          # -> 1000 / 2 [sub-envs] = 500 [per sub-env]
          # -> 1 episode = 200 timesteps
          # -> 2.5 episodes per sub-env
          # -> 3 episodes created [per sub-env] = 6 episodes total
          self.assertEqual(
              6,
              algo.workers.foreach_worker(
                  lambda w: w.callbacks._reset_counter,
                  local_worker=False,
              )[0],
          )
          algo.stop()
  
imports: from collections import Counter
  import unittest
  import ray
  from ray.rllib.algorithms.callbacks import DefaultCallbacks, make_multi_callbacks
  import ray.rllib.algorithms.dqn
  from ray.rllib.algorithms.ppo import PPOConfig
  from ray.rllib.evaluation.episode import Episode
  from ray.rllib.examples.env.random_env import RandomEnv
  from ray.rllib.utils.test_utils import framework_iterator
label_desc: Use image node_id 6 for calling the TestCallbacks obj's underlying member method code with example usage: obj.test_on_episode_created() without return types