docstr: Simple test of a SOBOL + GPEI GenerationStrategy composed of GenerationNodes
code: def test_gs_with_generation_nodes(self) -> None:
      "Simple test of a SOBOL + GPEI GenerationStrategy composed of GenerationNodes"
      sobol_criterion = [
          MaxTrials(
              threshold=5,
              transition_to="GPEI_node",
              block_gen_if_met=True,
              only_in_statuses=None,
              not_in_statuses=[
                  TrialStatus.FAILED,
                  TrialStatus.ABANDONED,
              ],
          )
      ]
      gpei_criterion = [
          MaxTrials(
              threshold=2,
              transition_to=None,
              block_gen_if_met=True,
              only_in_statuses=None,
              not_in_statuses=[
                  TrialStatus.FAILED,
                  TrialStatus.ABANDONED,
              ],
          )
      ]
      sobol_model_spec = ModelSpec(
          model_enum=Models.SOBOL,
          model_kwargs=self.step_model_kwargs,
          model_gen_kwargs={},
      )
      gpei_model_spec = ModelSpec(
          model_enum=Models.GPEI,
          model_kwargs=self.step_model_kwargs,
          model_gen_kwargs={},
      )
      sobol_node = GenerationNode(
          node_name="sobol_node",
          transition_criteria=sobol_criterion,
          model_specs=[sobol_model_spec],
          gen_unlimited_trials=False,
      )
      gpei_node = GenerationNode(
          node_name="GPEI_node",
          transition_criteria=gpei_criterion,
          model_specs=[gpei_model_spec],
          gen_unlimited_trials=False,
      )
  
      sobol_GPEI_GS_nodes = GenerationStrategy(
          name="Sobol+GPEI_Nodes",
          nodes=[sobol_node, gpei_node],
      )
      exp = get_branin_experiment()
      self.assertEqual(sobol_GPEI_GS_nodes.name, "Sobol+GPEI_Nodes")
  
      for i in range(7):
          g = sobol_GPEI_GS_nodes.gen(exp)
          exp.new_trial(generator_run=g).run()
          self.assertEqual(
              len(sobol_GPEI_GS_nodes._generator_runs), i + 1
          )
          if i > 4:
              self.mock_torch_model_bridge.assert_called()
          else:
              self.assertEqual(g._model_key, "Sobol")
              mkw = g._model_kwargs
              self.assertIsNotNone(mkw)
              if i > 0:
                  # Generated points are randomized, so checking that they're there.
                  self.assertIsNotNone(mkw.get("generated_points"))
              else:
                  # This is the first GR, there should be no generated points yet.
                  self.assertIsNone(mkw.get("generated_points"))
              # Remove the randomized generated points to compare the rest.
              mkw = mkw.copy()
              del mkw["generated_points"]
              self.assertEqual(
                  mkw,
                  {
                      "seed": None,
                      "deduplicate": True,
                      "init_position": i,
                      "scramble": True,
                      "fallback_to_sample_polytope": False,
                  },
              )
              self.assertEqual(
                  g._bridge_kwargs,
                  {
                      "optimization_config": None,
                      "status_quo_features": None,
                      "status_quo_name": None,
                      "transform_configs": None,
                      "transforms": Cont_X_trans,
                      "fit_out_of_design": False,
                      "fit_abandoned": False,
                      "fit_tracking_metrics": True,
                      "fit_on_init": True,
                  },
              )
              ms = g._model_state_after_gen
              self.assertIsNotNone(ms)
              # Generated points are randomized, so just checking that they are there.
              self.assertIn("generated_points", ms)
              # Remove the randomized generated points to compare the rest.
              ms = ms.copy()
              del ms["generated_points"]
              self.assertEqual(ms, {"init_position": i + 1})
  
imports: import logging
  from typing import cast, List
  from unittest import mock
  from unittest.mock import MagicMock, patch
  from ax.core.arm import Arm
  from ax.core.base_trial import TrialStatus
  from ax.core.experiment import Experiment
  from ax.core.generator_run import GeneratorRun
  from ax.core.observation import ObservationFeatures
  from ax.core.parameter import ChoiceParameter, FixedParameter, Parameter, ParameterType
  from ax.core.search_space import SearchSpace
  from ax.core.utils import get_pending_observation_features_based_on_trial_status
  from ax.exceptions.core import DataRequiredError, UnsupportedError, UserInputError
  from ax.exceptions.generation_strategy import GenerationStrategyCompleted, GenerationStrategyMisconfiguredException, GenerationStrategyRepeatedPoints, MaxParallelismReachedException
  from ax.modelbridge.discrete import DiscreteModelBridge
  from ax.modelbridge.factory import get_sobol
  from ax.modelbridge.generation_node import GenerationNode
  from ax.modelbridge.generation_strategy import GenerationStep, GenerationStrategy
  from ax.modelbridge.model_spec import ModelSpec
  from ax.modelbridge.random import RandomModelBridge
  from ax.modelbridge.registry import Cont_X_trans, MODEL_KEY_TO_MODEL_SETUP, Models
  from ax.modelbridge.torch import TorchModelBridge
  from ax.modelbridge.transition_criterion import MaxGenerationParallelism, MaxTrials, MinTrials
  from ax.models.random.sobol import SobolGenerator
  from ax.utils.common.equality import same_elements
  from ax.utils.common.mock import mock_patch_method_original
  from ax.utils.common.testutils import TestCase
  from ax.utils.common.typeutils import not_none
  from ax.utils.testing.core_stubs import get_branin_data, get_branin_experiment, get_choice_parameter, get_data, get_experiment_with_multi_objective, get_hierarchical_search_space_experiment
label_desc: Use image node_id 29 for calling the TestGenerationStrategy obj's underlying member method code with example usage: obj.test_gs_with_generation_nodes() without return types