code: def testResolveExecProperties(self):
      # Create input dir.
      self._input_base_path = os.path.join(self._test_dir, "input_base")
      fileio.makedirs(self._input_base_path)
  
      # Create exec proterties.
      self._exec_properties = {
          standard_component_specs.INPUT_BASE_KEY: self._input_base_path,
          standard_component_specs.INPUT_CONFIG_KEY: proto_utils.proto_to_json(
              example_gen_pb2.Input(
                  splits=[
                      example_gen_pb2.Input.Split(
                          name="s1",
                          pattern="span{SPAN:2}/version{VERSION:2}/split1/*",
                      ),
                      example_gen_pb2.Input.Split(
                          name="s2",
                          pattern="span{SPAN:2}/version{VERSION:2}/split2/*",
                      ),
                  ]
              )
          ),
          standard_component_specs.RANGE_CONFIG_KEY: None,
      }
  
      # Test align of span number.
      span1_v1_split1 = os.path.join(
          self._input_base_path, "span01", "version01", "split1", "data"
      )
      io_utils.write_string_file(span1_v1_split1, "testing11")
      span1_v1_split2 = os.path.join(
          self._input_base_path, "span01", "version01", "split2", "data"
      )
      io_utils.write_string_file(span1_v1_split2, "testing12")
      span2_v1_split1 = os.path.join(
          self._input_base_path, "span02", "version01", "split1", "data"
      )
      io_utils.write_string_file(span2_v1_split1, "testing21")
  
      # Check that error raised when span does not match.
      with self.assertRaisesRegex(
          ValueError, "Latest span should be the same for each split"
      ):
          self._file_based_driver.resolve_exec_properties(
              self._exec_properties, None, None
          )
  
      span2_v1_split2 = os.path.join(
          self._input_base_path, "span02", "version01", "split2", "data"
      )
      io_utils.write_string_file(span2_v1_split2, "testing22")
      span2_v2_split1 = os.path.join(
          self._input_base_path, "span02", "version02", "split1", "data"
      )
      io_utils.write_string_file(span2_v2_split1, "testing21")
  
      # Check that error raised when span matches, but version does not match.
      with self.assertRaisesRegex(
          ValueError, "Latest version should be the same for each split"
      ):
          self._file_based_driver.resolve_exec_properties(
              self._exec_properties, None, None
          )
  
      span2_v2_split2 = os.path.join(
          self._input_base_path, "span02", "version02", "split2", "data"
      )
      io_utils.write_string_file(span2_v2_split2, "testing22")
  
      # Test if latest span and version selected when span and version aligns
      # for each split.
      self._file_based_driver.resolve_exec_properties(
          self._exec_properties, None, None
      )
      self.assertEqual(
          self._exec_properties[utils.SPAN_PROPERTY_NAME], 2
      )
      self.assertEqual(
          self._exec_properties[utils.VERSION_PROPERTY_NAME], 2
      )
      self.assertRegex(
          self._exec_properties[utils.FINGERPRINT_PROPERTY_NAME],
          r"split:s1,num_files:1,total_bytes:9,xor_checksum:.*,sum_checksum:.*\nsplit:s2,num_files:1,total_bytes:9,xor_checksum:.*,sum_checksum:.*",
      )
      updated_input_config = example_gen_pb2.Input()
      proto_utils.json_to_proto(
          self._exec_properties[
              standard_component_specs.INPUT_CONFIG_KEY
          ],
          updated_input_config,
      )
  
      # Check if latest span is selected.
      self.assertProtoEquals(
          """
          splits {
            name: "s1"
            pattern: "span02/version02/split1/*"
          }
          splits {
            name: "s2"
            pattern: "span02/version02/split2/*"
          }""",
          updated_input_config,
      )
  
      # Test driver behavior using RangeConfig with static range.
      self._exec_properties[
          standard_component_specs.INPUT_CONFIG_KEY
      ] = proto_utils.proto_to_json(
          example_gen_pb2.Input(
              splits=[
                  example_gen_pb2.Input.Split(
                      name="s1",
                      pattern="span{SPAN:2}/version{VERSION:2}/split1/*",
                  ),
                  example_gen_pb2.Input.Split(
                      name="s2",
                      pattern="span{SPAN:2}/version{VERSION:2}/split2/*",
                  ),
              ]
          )
      )
  
      self._exec_properties[
          standard_component_specs.RANGE_CONFIG_KEY
      ] = proto_utils.proto_to_json(
          range_config_pb2.RangeConfig(
              static_range=range_config_pb2.StaticRange(
                  start_span_number=1, end_span_number=2
              )
          )
      )
      with self.assertRaisesRegex(
          ValueError, "For ExampleGen, start and end span numbers"
      ):
          self._file_based_driver.resolve_exec_properties(
              self._exec_properties, None, None
          )
  
      self._exec_properties[
          standard_component_specs.RANGE_CONFIG_KEY
      ] = proto_utils.proto_to_json(
          range_config_pb2.RangeConfig(
              static_range=range_config_pb2.StaticRange(
                  start_span_number=1, end_span_number=1
              )
          )
      )
      self._file_based_driver.resolve_exec_properties(
          self._exec_properties, None, None
      )
      self.assertEqual(
          self._exec_properties[utils.SPAN_PROPERTY_NAME], 1
      )
      self.assertEqual(
          self._exec_properties[utils.VERSION_PROPERTY_NAME], 1
      )
      self.assertRegex(
          self._exec_properties[utils.FINGERPRINT_PROPERTY_NAME],
          r"split:s1,num_files:1,total_bytes:9,xor_checksum:.*,sum_checksum:.*\nsplit:s2,num_files:1,total_bytes:9,xor_checksum:.*,sum_checksum:.*",
      )
      updated_input_config = example_gen_pb2.Input()
      proto_utils.json_to_proto(
          self._exec_properties[
              standard_component_specs.INPUT_CONFIG_KEY
          ],
          updated_input_config,
      )
      # Check if correct span inside static range is selected.
      self.assertProtoEquals(
          """
          splits {
            name: "s1"
            pattern: "span01/version01/split1/*"
          }
          splits {
            name: "s2"
            pattern: "span01/version01/split2/*"
          }""",
          updated_input_config,
      )
  
imports: import os
  import tensorflow
  from tfx.components.example_gen import driver
  from tfx.components.example_gen import utils
  from tfx.dsl.components.base import base_driver
  from tfx.dsl.io import fileio
  from tfx.orchestration import data_types
  from tfx.orchestration.portable import data_types
  from tfx.proto import example_gen_pb2
  from tfx.proto import range_config_pb2
  from tfx.types import artifact
  from tfx.types import artifact_utils
  from tfx.types import channel_utils
  from tfx.types import standard_artifacts
  from tfx.types import standard_component_specs
  from tfx.utils import io_utils
  from tfx.utils import proto_utils
label_desc: Use image node_id 2 for calling the DriverTest obj's underlying member method code with example usage: obj.testResolveExecProperties() without return types