code: def test_BotorchMOOModel_with_qehvi_and_outcome_constraints(
      self,
      dtype: torch.dtype = torch.float,
      cuda: bool = False,
      use_noisy: bool = False,
      use_log: bool = True,
  ) -> None:
      if use_log:
          acqf_constructor = (
              botorch_moo_defaults.get_qLogNEHVI
              if use_noisy
              else botorch_moo_defaults.get_qLogEHVI
          )
      else:
          acqf_constructor = (
              botorch_moo_defaults.get_NEHVI
              if use_noisy
              else botorch_moo_defaults.get_EHVI
          )
  
      tkwargs: Dict[str, Any] = {
          "device": torch.device("cuda")
          if cuda
          else torch.device("cpu"),
          "dtype": dtype,
      }
      (
          Xs1,
          Ys1,
          Yvars1,
          bounds,
          tfs,
          feature_names,
          metric_names,
      ) = _get_torch_test_data(
          dtype=dtype, cuda=cuda, constant_noise=True
      )
      Xs2, Ys2, Yvars2, _, _, _, _ = _get_torch_test_data(
          dtype=dtype, cuda=cuda, constant_noise=True
      )
      Xs3, Ys3, Yvars3, _, _, _, _ = _get_torch_test_data(
          dtype=dtype, cuda=cuda, constant_noise=True
      )
      training_data = [
          SupervisedDataset(
              X=Xs1[0],
              Y=Ys1[0],
              Yvar=Yvars1[0],
              feature_names=feature_names,
              outcome_names=metric_names,
          ),
          SupervisedDataset(
              X=Xs2[0],
              Y=Ys2[0],
              Yvar=Yvars2[0],
              feature_names=feature_names,
              outcome_names=metric_names,
          ),
          SupervisedDataset(
              X=Xs3[0],
              Y=Ys3[0],
              Yvar=Yvars3[0],
              feature_names=feature_names,
              outcome_names=metric_names,
          ),
      ]
  
      n = 3
      objective_weights = torch.tensor([1.0, 1.0, 0.0], **tkwargs)
      obj_t = torch.tensor([1.0, 1.0, 1.0], **tkwargs)
      # pyre-fixme[6]: For 1st param expected `(Model, Tensor, Optional[Tuple[Tenso...
      model = MultiObjectiveBotorchModel(
          acqf_constructor=acqf_constructor
      )
  
      search_space_digest = SearchSpaceDigest(
          feature_names=feature_names,
          bounds=bounds,
          task_features=tfs,
      )
      with mock.patch(FIT_MODEL_MO_PATH) as _mock_fit_model:
          model.fit(
              datasets=training_data,
              metric_names=metric_names,
              search_space_digest=search_space_digest,
          )
          _mock_fit_model.assert_called_once()
  
      # test wrong number of objective thresholds
      torch_opt_config = TorchOptConfig(
          objective_weights=objective_weights,
          objective_thresholds=torch.tensor([1.0, 1.0], **tkwargs),
      )
      with self.assertRaises(AxError):
          model.gen(
              n,
              search_space_digest=search_space_digest,
              torch_opt_config=torch_opt_config,
          )
      # test that objective thresholds and weights are properly subsetted
      obj_t = torch.tensor([1.0, 1.0, 1.0], **tkwargs)
      torch_opt_config = dataclasses.replace(
          torch_opt_config,
          objective_thresholds=obj_t,
      )
      with mock.patch.object(
          model,
          "acqf_constructor",
          wraps=acqf_constructor,  # botorch_moo_defaults.get_qLogNEHVI,
      ) as mock_get_nehvi:
          model.gen(
              n,
              search_space_digest=search_space_digest,
              torch_opt_config=torch_opt_config,
          )
          mock_get_nehvi.assert_called_once()
          _, ckwargs = mock_get_nehvi.call_args
          self.assertEqual(ckwargs["model"].num_outputs, 2)
          self.assertTrue(
              torch.equal(
                  ckwargs["objective_weights"], objective_weights[:-1]
              )
          )
          self.assertTrue(
              torch.equal(ckwargs["objective_thresholds"], obj_t[:-1])
          )
          self.assertIsNone(ckwargs["outcome_constraints"])
          # the second datapoint is out of bounds
          self.assertTrue(
              torch.equal(ckwargs["X_observed"], Xs1[0][:1])
          )
          self.assertIsNone(ckwargs["X_pending"])
      # test that outcome constraints are passed properly
      oc = (
          torch.tensor([[0.0, 0.0, 1.0]], **tkwargs),
          torch.tensor([[10.0]], **tkwargs),
      )
      torch_opt_config = dataclasses.replace(
          torch_opt_config,
          outcome_constraints=oc,
      )
      with mock.patch.object(
          model,
          "acqf_constructor",
          wraps=acqf_constructor,  # botorch_moo_defaults.get_qLogNEHVI,
      ) as mock_get_nehvi:
          model.gen(
              n,
              search_space_digest=search_space_digest,
              torch_opt_config=torch_opt_config,
          )
          mock_get_nehvi.assert_called_once()
          _, ckwargs = mock_get_nehvi.call_args
          self.assertEqual(ckwargs["model"].num_outputs, 3)
          self.assertTrue(
              torch.equal(
                  ckwargs["objective_weights"], objective_weights
              )
          )
          self.assertTrue(
              torch.equal(ckwargs["objective_thresholds"], obj_t)
          )
          self.assertTrue(
              torch.equal(ckwargs["outcome_constraints"][0], oc[0])
          )
          self.assertTrue(
              torch.equal(ckwargs["outcome_constraints"][1], oc[1])
          )
          # the second datapoint is out of bounds
          self.assertTrue(
              torch.equal(ckwargs["X_observed"], Xs1[0][:1])
          )
          self.assertIsNone(ckwargs["X_pending"])
  
imports: import dataclasses
  from contextlib import ExitStack
  from typing import Any, Dict
  from unittest import mock
  import ax.models.torch.botorch_moo_defaults
  import botorch.utils.multi_objective.hypervolume
  import numpy
  import torch
  from ax.core.search_space import SearchSpaceDigest
  from ax.exceptions.core import AxError
  from ax.models.torch.botorch_defaults import get_qLogNEI
  from ax.models.torch.botorch_moo import MultiObjectiveBotorchModel
  from ax.models.torch.botorch_moo_defaults import get_EHVI, get_NEHVI, get_qLogEHVI, get_qLogNEHVI, infer_objective_thresholds
  from ax.models.torch.utils import HYPERSPHERE
  from ax.models.torch_base import TorchOptConfig
  from ax.utils.common.testutils import TestCase
  from ax.utils.testing.mock import fast_botorch_optimize
  from botorch.acquisition.multi_objective import logei, monte_carlo
  from botorch.models import ModelListGP
  from botorch.models.transforms.input import Warp
  from botorch.optim.optimize import optimize_acqf_list
  from botorch.sampling.normal import IIDNormalSampler
  from botorch.utils.datasets import SupervisedDataset
  from botorch.utils.multi_objective.hypervolume import infer_reference_point
  from botorch.utils.multi_objective.scalarization import get_chebyshev_scalarization
  from botorch.utils.testing import MockModel, MockPosterior
label_desc: Use image node_id 10 for calling the BotorchMOOModelTest obj's underlying member method code with example usage: obj.test_BotorchMOOModel_with_qehvi_and_outcome_constraints(dtype, cuda, use_noisy, use_log) without return types