code: def test_placement_group_options_validation(self):
      class Class:
          pass
  
      # Specify placement_group_bundles without num_cpus or placement_group_strategy.
      ReplicaConfig.create(
          Class,
          tuple(),
          dict(),
          placement_group_bundles=[{"CPU": 1.0}],
      )
  
      # Specify placement_group_bundles with integer value.
      ReplicaConfig.create(
          Class,
          tuple(),
          dict(),
          placement_group_bundles=[{"CPU": 1}],
      )
  
      # Specify placement_group_bundles and placement_group_strategy.
      ReplicaConfig.create(
          Class,
          tuple(),
          dict(),
          placement_group_bundles=[{"CPU": 1.0}],
          placement_group_strategy="STRICT_PACK",
      )
  
      # Specify placement_group_bundles and placement_group_strategy and num_cpus.
      ReplicaConfig.create(
          Class,
          tuple(),
          dict(),
          ray_actor_options={"num_cpus": 1},
          placement_group_bundles=[{"CPU": 1.0}],
          placement_group_strategy="STRICT_PACK",
      )
  
      # Invalid: placement_group_strategy without placement_group_bundles.
      with pytest.raises(
          ValueError,
          match="`placement_group_bundles` must also be provided",
      ):
          ReplicaConfig.create(
              Class,
              tuple(),
              dict(),
              placement_group_strategy="PACK",
          )
  
      # Invalid: unsupported placement_group_strategy.
      with pytest.raises(
          ValueError,
          match="Invalid placement group strategy 'FAKE_NEWS'",
      ):
          ReplicaConfig.create(
              Class,
              tuple(),
              dict(),
              placement_group_bundles=[{"CPU": 1.0}],
              placement_group_strategy="FAKE_NEWS",
          )
  
      # Invalid: malformed placement_group_bundles.
      with pytest.raises(
          ValueError,
          match=(
              "`placement_group_bundles` must be a non-empty list "
              "of resource dictionaries."
          ),
      ):
          ReplicaConfig.create(
              Class,
              tuple(),
              dict(),
              placement_group_bundles=[{"CPU": "1.0"}],
          )
  
      # Invalid: replica actor does not fit in the first bundle (CPU).
      with pytest.raises(
          ValueError,
          match=(
              "the resource requirements for the actor must be a "
              "subset of the first bundle."
          ),
      ):
          ReplicaConfig.create(
              Class,
              tuple(),
              dict(),
              ray_actor_options={"num_cpus": 1},
              placement_group_bundles=[{"CPU": 0.1}],
          )
  
      # Invalid: replica actor does not fit in the first bundle (CPU).
      with pytest.raises(
          ValueError,
          match=(
              "the resource requirements for the actor must be a "
              "subset of the first bundle."
          ),
      ):
          ReplicaConfig.create(
              Class,
              tuple(),
              dict(),
              ray_actor_options={"num_gpus": 1},
              placement_group_bundles=[{"CPU": 1.0}],
          )
  
      # Invalid: replica actor does not fit in the first bundle (custom resource).
      with pytest.raises(
          ValueError,
          match=(
              "the resource requirements for the actor must be a "
              "subset of the first bundle."
          ),
      ):
          ReplicaConfig.create(
              Class,
              tuple(),
              dict(),
              ray_actor_options={"resources": {"custom": 1}},
              placement_group_bundles=[{"CPU": 1}],
          )
  
imports: import pytest
  from ray import cloudpickle
  from ray._private.pydantic_compat import ValidationError
  from ray._private.utils import import_attr
  from ray.serve._private.config import DeploymentConfig, ReplicaConfig, _proto_to_dict
  from ray.serve._private.constants import DEFAULT_AUTOSCALING_POLICY, DEFAULT_GRPC_PORT
  from ray.serve._private.utils import DEFAULT
  from ray.serve.autoscaling_policy import default_autoscaling_policy
  from ray.serve.config import AutoscalingConfig, DeploymentMode, HTTPOptions, ProxyLocation, gRPCOptions
  from ray.serve.generated.serve_pb2 import AutoscalingConfig
  from ray.serve.generated.serve_pb2 import DeploymentConfig
  from ray.serve.generated.serve_pb2 import DeploymentLanguage
  from ray.serve.generated.serve_pb2_grpc import add_UserDefinedServiceServicer_to_server
  from ray.serve.schema import DeploymentSchema, HTTPOptionsSchema, ServeApplicationSchema, ServeDeploySchema
label_desc: Use image node_id 4 for calling the TestReplicaConfig obj's underlying member method code with example usage: obj.test_placement_group_options_validation() without return types