code: def test_ConstraintValidation(self) -> None:
      # Can build OptimizationConfig with MultiObjective
      with self.assertRaises(ValueError):
          OptimizationConfig(objective=self.multi_objective)
  
      # Can't constrain on objective metric.
      objective_constraint = OutcomeConstraint(
          metric=self.objective.metric, op=ComparisonOp.GEQ, bound=0
      )
      with self.assertRaises(ValueError):
          OptimizationConfig(
              objective=self.objective,
              outcome_constraints=[objective_constraint],
          )
      # Using an outcome constraint for ScalarizedObjective should also raise
      with self.assertRaisesRegex(
          ValueError, "Cannot constrain on objective metric."
      ):
          OptimizationConfig(
              objective=self.m2_objective,
              outcome_constraints=[objective_constraint],
          )
      # Two outcome_constraints on the same metric with the same op
      # should raise.
      duplicate_constraint = OutcomeConstraint(
          metric=self.outcome_constraint.metric,
          op=self.outcome_constraint.op,
          bound=self.outcome_constraint.bound + 1,
      )
      with self.assertRaises(ValueError):
          OptimizationConfig(
              objective=self.objective,
              outcome_constraints=[
                  self.outcome_constraint,
                  duplicate_constraint,
              ],
          )
  
      # Three outcome_constraints on the same metric should raise.
      opposing_constraint = OutcomeConstraint(
          metric=self.outcome_constraint.metric,
          # pyre-fixme[6]: For 2nd param expected `ComparisonOp` but got `bool`.
          op=not self.outcome_constraint.op,
          bound=self.outcome_constraint.bound,
      )
      with self.assertRaises(ValueError):
          OptimizationConfig(
              objective=self.objective,
              outcome_constraints=self.outcome_constraints
              + [opposing_constraint],
          )
  
      # Two outcome_constraints on the same metric with different ops and
      # flipped bounds (lower < upper) should raise.
      add_bound = (
          1 if self.outcome_constraint.op == ComparisonOp.LEQ else -1
      )
      opposing_constraint = OutcomeConstraint(
          metric=self.outcome_constraint.metric,
          # pyre-fixme[6]: For 2nd param expected `ComparisonOp` but got `bool`.
          op=not self.outcome_constraint.op,
          bound=self.outcome_constraint.bound + add_bound,
      )
      with self.assertRaises(ValueError):
          OptimizationConfig(
              objective=self.objective,
              outcome_constraints=(
                  [self.outcome_constraint, opposing_constraint]
              ),
          )
  
      # Two outcome_constraints on the same metric with different ops and
      # bounds should not raise.
      opposing_constraint = OutcomeConstraint(
          metric=self.outcome_constraint.metric,
          # pyre-fixme[6]: For 2nd param expected `ComparisonOp` but got `bool`.
          op=not self.outcome_constraint.op,
          bound=self.outcome_constraint.bound + 1,
      )
      config = OptimizationConfig(
          objective=self.objective,
          outcome_constraints=(
              [self.outcome_constraint, opposing_constraint]
          ),
      )
      self.assertEqual(
          config.outcome_constraints,
          [self.outcome_constraint, opposing_constraint],
      )
  
imports: from ax.core.metric import Metric
  from ax.core.objective import MultiObjective, Objective, ScalarizedObjective
  from ax.core.optimization_config import _NO_RISK_MEASURE, MultiObjectiveOptimizationConfig, OptimizationConfig
  from ax.core.outcome_constraint import ObjectiveThreshold, OutcomeConstraint, ScalarizedOutcomeConstraint
  from ax.core.risk_measures import RiskMeasure
  from ax.core.types import ComparisonOp
  from ax.exceptions.core import UserInputError
  from ax.utils.common.testutils import TestCase
label_desc: Use image node_id 4 for calling the OptimizationConfigTest obj's underlying member method code with example usage: obj.test_ConstraintValidation() without return types