code: def test_actor_timestamps(ray_start_regular):
      @ray.remote
      class Foo:
          def get_id(self):
              return ray.get_runtime_context().get_actor_id()
  
          def kill_self(self):
              sys.exit(1)
  
      def graceful_exit():
          actor = Foo.remote()
          actor_id = ray.get(actor.get_id.remote())
  
          state_after_starting = ray._private.state.actors()[actor_id]
          time.sleep(1)
          del actor
          time.sleep(1)
          state_after_ending = ray._private.state.actors()[actor_id]
  
          assert (
              state_after_starting["StartTime"]
              == state_after_ending["StartTime"]
          )
          start_time = state_after_ending["StartTime"]
          end_time = state_after_ending["EndTime"]
          assert (
              end_time > start_time > 0
          ), f"Start: {start_time}, End: {end_time}"
  
      def not_graceful_exit():
          actor = Foo.remote()
          actor_id = ray.get(actor.get_id.remote())
  
          state_after_starting = ray._private.state.actors()[actor_id]
          time.sleep(1)
          actor.kill_self.remote()
          time.sleep(1)
          state_after_ending = ray._private.state.actors()[actor_id]
  
          assert (
              state_after_starting["StartTime"]
              == state_after_ending["StartTime"]
          )
  
          start_time = state_after_ending["StartTime"]
          end_time = state_after_ending["EndTime"]
          assert (
              end_time > start_time > 0
          ), f"Start: {start_time}, End: {end_time}"
  
      def restarted():
          actor = Foo.options(
              max_restarts=1, max_task_retries=-1
          ).remote()
          actor_id = ray.get(actor.get_id.remote())
  
          state_after_starting = ray._private.state.actors()[actor_id]
          time.sleep(1)
          actor.kill_self.remote()
          time.sleep(1)
          actor.kill_self.remote()
          time.sleep(1)
          state_after_ending = ray._private.state.actors()[actor_id]
  
          assert (
              state_after_starting["StartTime"]
              == state_after_ending["StartTime"]
          )
  
          start_time = state_after_ending["StartTime"]
          end_time = state_after_ending["EndTime"]
          assert (
              end_time > start_time > 0
          ), f"Start: {start_time}, End: {end_time}"
  
      graceful_exit()
      not_graceful_exit()
      restarted()
  
imports: import os
  import sys
  import time
  import numpy
  import pytest
  import ray
  import ray._private.gcs_utils
  from ray.util.state import list_actors
  import ray.cluster_utils
  from ray._private.test_utils import SignalActor, convert_actor_state, kill_actor_and_wait_for_failure, make_global_state_accessor, run_string_as_driver, wait_for_condition, wait_for_pid_to_exit
  from ray._private.ray_constants import gcs_actor_scheduling_enabled
  from ray.experimental.internal_kv import _internal_kv_get, _internal_kv_put
label_desc: Use image node_id 31 for calling a global function with example usage: test_actor_timestamps(ray_start_regular) and returns: ray