code: def test_optimizer_property_validation():
      config = {
          "input_features": [
              category_feature(
                  encoder={"type": "dense", "vocab_size": 2},
                  reduce_input="sum",
              ),
              number_feature(),
          ],
          "output_features": [binary_feature()],
          "combiner": {
              "type": "tabnet",
          },
          TRAINER: {},
      }
      check_schema(config)
  
      # Test that an optimizer's property types are enforced:
      config[TRAINER]["optimizer"] = {"type": "rmsprop"}
      check_schema(config)
  
      config[TRAINER]["optimizer"]["momentum"] = "invalid"
      with pytest.raises(ConfigValidationError):
          check_schema(config)
  
      # Test extra keys are excluded and defaults are loaded appropriately:
      config[TRAINER]["optimizer"]["momentum"] = 10
      config[TRAINER]["optimizer"]["extra_key"] = "invalid"
      check_schema(config)
      assert not hasattr(
          ECDTrainerConfig.Schema().load(config[TRAINER]).optimizer,
          "extra_key",
      )
  
      # Test bad parameter range:
      config[TRAINER]["optimizer"] = {"type": "rmsprop", "eps": -1}
      with pytest.raises(ConfigValidationError):
          check_schema(config)
  
      # Test config validation for tuple types:
      config[TRAINER]["optimizer"] = {
          "type": "adam",
          "betas": (0.1, 0.1),
      }
      check_schema(config)
  
file_path: ludwig/tests/ludwig/config_validation/test_validate_config_trainer.py
imports: import pytest
  from ludwig.config_validation.validation import check_schema
  from ludwig.constants import TRAINER
  from ludwig.error import ConfigValidationError
  from ludwig.schema.optimizers import optimizer_registry
  from ludwig.schema.trainer import ECDTrainerConfig
  from tests.integration_tests.utils import binary_feature, category_feature, number_feature
label_desc: Use image node_id 3 for calling a global function with example usage: test_optimizer_property_validation() without return types