docstr: Tests eval every step for 2 steps.
  
  This test's `variable_container` passes the same train step twice to test
  that `is_train_step_the_same_or_behind` is working as expected. If were not
  working, the number of train steps processed will be incorrect (2x higher).
docstr_tok: ["Tests","eval","every","step","for","2","steps",".","This","test","'s","`","variable_container","`","passes","the","same","train","step","twice","to","test","that","`","is_train_step_the_same_or_behind","`","is","working","as","expected",".","If","were","not","working",",","the","number","of","train","steps","processed","will","be","incorrect","(","2x","higher",")","."]
code: def test_eval_job_constant_eval(self):
      """Tests eval every step for 2 steps.
  
      This test's `variable_container` passes the same train step twice to test
      that `is_train_step_the_same_or_behind` is working as expected. If were not
      working, the number of train steps processed will be incorrect (2x higher).
      """
      summary_dir = self.create_tempdir().full_path
      environment = test_envs.CountingEnv(steps_per_episode=4)
      action_tensor_spec = tensor_spec.from_spec(
          environment.action_spec()
      )
      time_step_tensor_spec = tensor_spec.from_spec(
          environment.time_step_spec()
      )
      policy = py_tf_eager_policy.PyTFEagerPolicy(
          random_tf_policy.RandomTFPolicy(
              time_step_tensor_spec, action_tensor_spec
          )
      )
      mock_variable_container = mock.create_autospec(
          reverb_variable_container.ReverbVariableContainer
      )
  
      class VCUpdateIncrementEveryOtherTrainStep(object):
          """Side effect that updates train_step on every other call."""
  
          def __init__(self):
              self.fake_train_step = -1
              self.call_count = 0
  
          def __call__(self, variables):
              if self.call_count % 2:
                  self.fake_train_step += 1
                  variables[
                      reverb_variable_container.TRAIN_STEP_KEY
                  ].assign(self.fake_train_step)
              self.call_count += 1
  
      fake_update = VCUpdateIncrementEveryOtherTrainStep()
      mock_variable_container.update.side_effect = fake_update
  
      with mock.patch.object(
          tf.summary, "scalar", autospec=True
      ) as mock_scalar_summary:
          eval_job.evaluate(
              summary_dir=summary_dir,
              policy=policy,
              environment_name=None,
              suite_load_fn=lambda _: environment,
              variable_container=mock_variable_container,
              eval_interval=1,
              is_running=_NTimesReturnTrue(n=2),
          )
  
          summary_count = self.count_summary_scalar_tags_in_call_list(
              mock_scalar_summary, "Metrics/eval_actor/AverageReturn"
          )
          self.assertEqual(summary_count, 2)
  
file_path: agents/tf_agents/experimental/distributed/examples/eval_job_test.py
imports: from absl.testing.absltest import mock
  import tensorflow.compat.v2
  from tf_agents.environments import test_envs
  from tf_agents.experimental.distributed import reverb_variable_container
  from tf_agents.experimental.distributed.examples import eval_job
  from tf_agents.policies import py_tf_eager_policy
  from tf_agents.policies import random_tf_policy
  from tf_agents.specs import tensor_spec
  from tf_agents.system import system_multiprocessing
  from tf_agents.utils import test_utils
label_desc: Use image node_id 2 for calling the EvalJobTest obj's underlying member method code with example usage: obj.test_eval_job_constant_eval() without return types