code: def test_custom_experiment(self):
      with ray_start_client_server(ray_init_kwargs={"num_cpus": 3}):
          assert ray.util.client.ray.is_connected()
  
          config = ppo.PPOConfig().environment("CartPole-v1")
          # Special flag signalling `experiment` how many iters to do.
          config = config.to_dict()
          config["train-iterations"] = 2
  
          from ray.rllib.examples.custom_experiment import experiment
  
          # Ray client does not seem to propagate the `fn._resources` property
          # correctly for imported functions. As a workaround, we can wrap the
          # imported function which forces a full transfer.
          def wrapped_experiment(config):
              experiment(config)
  
          tune.Tuner(
              tune.with_resources(
                  wrapped_experiment,
                  ppo.PPO.default_resource_request(config),
              ),
              param_space=config,
          ).fit()
  
file_path: ray/python/ray/rllib/tests/test_ray_client.py
imports: import os
  import sys
  import unittest
  import pytest
  import ray
  from ray import air
  from ray import tune
  import ray.rllib.algorithms.ppo
  from ray.rllib.examples.env.stateless_cartpole import StatelessCartPole
  from ray.util.client.ray_client_helpers import ray_start_client_server
label_desc: Use image node_id 4 for calling the TestRayClient obj's underlying member method code with example usage: obj.test_custom_experiment() without return types