code: def test_exit_actor(shutdown_only, tmp_path):
      """
      Verify TypeError is raised when exit_actor is not used
      inside an actor.
      """
      with pytest.raises(
          TypeError,
          match="exit_actor API is called on a non-actor worker",
      ):
          exit_actor()
  
      @ray.remote
      def f():
          exit_actor()
  
      with pytest.raises(
          TypeError,
          match="exit_actor API is called on a non-actor worker",
      ):
          ray.get(f.remote())
  
      """
      Verify the basic case.
      """
  
      @ray.remote
      class Actor:
          def exit(self):
              exit_actor()
  
      @ray.remote
      class AsyncActor:
          async def exit(self):
              exit_actor()
  
      a = Actor.remote()
      ray.get(a.__ray_ready__.remote())
      with pytest.raises(ray.exceptions.RayActorError) as exc_info:
          ray.get(a.exit.remote())
      assert "exit_actor()" in str(exc_info.value)
  
      b = AsyncActor.remote()
      ray.get(b.__ray_ready__.remote())
      with pytest.raises(ray.exceptions.RayActorError) as exc_info:
          ray.get(b.exit.remote())
      assert "exit_actor()" in str(exc_info.value)
  
      """
      Verify atexit handler is called correctly.
      """
      sync_temp_file = tmp_path / "actor.log"
      async_temp_file = tmp_path / "async_actor.log"
      sync_temp_file.touch()
      async_temp_file.touch()
  
      @ray.remote
      class Actor:
          def __init__(self):
              def f():
                  print("atexit handler")
                  with open(sync_temp_file, "w") as f:
                      f.write("Actor\n")
  
              atexit.register(f)
  
          def exit(self):
              exit_actor()
  
      @ray.remote
      class AsyncActor:
          def __init__(self):
              def f():
                  print("atexit handler")
                  with open(async_temp_file, "w") as f:
                      f.write("Async Actor\n")
  
              atexit.register(f)
  
          async def exit(self):
              exit_actor()
  
      a = Actor.remote()
      ray.get(a.__ray_ready__.remote())
      b = AsyncActor.remote()
      ray.get(b.__ray_ready__.remote())
      with pytest.raises(ray.exceptions.RayActorError):
          ray.get(a.exit.remote())
      with pytest.raises(ray.exceptions.RayActorError):
          ray.get(b.exit.remote())
  
      def verify():
          with open(async_temp_file) as f:
              assert f.readlines() == ["Async Actor\n"]
          with open(sync_temp_file) as f:
              assert f.readlines() == ["Actor\n"]
          return True
  
      wait_for_condition(verify)
  
imports: import atexit
  import asyncio
  import collections
  import numpy
  import os
  import pytest
  import signal
  import sys
  import time
  import ray
  from ray.actor import exit_actor
  import ray.cluster_utils
  from ray._private.test_utils import wait_for_condition, wait_for_pid_to_exit, generate_system_config_map, SignalActor
label_desc: Use image node_id 18 for calling a global function with example usage: test_exit_actor(shutdown_only, tmp_path) and returns: True