code: def testFilterCustomPropertyEqualResolverFn_E2E(self):
      channel = canned_resolver_functions.filter_custom_property_equal(
          channel_utils.artifact_query(
              artifact_type=test_utils.DummyArtifact
          ),
          key="purity",
          value=2,
      )
      pipeline_node = test_utils.compile_inputs({"x": channel})
  
      mlmd_artifacts = []
      purities = [1, 1, 2]
      for purity in purities:
          mlmd_artifacts.append(
              self.put_artifact(
                  artifact_type="DummyArtifact",
                  custom_properties={"purity": purity},
              )
          )
      self._add_executions_into_mlmd(mlmd_artifacts)
  
      resolved = inputs_utils.resolve_input_artifacts(
          pipeline_node=pipeline_node, metadata_handle=self.mlmd_handle
      )
      self.assertNotEmpty(resolved)
  
      actual_artifacts = [r.mlmd_artifact for r in resolved[0]["x"]]
      expected_artifacts = [mlmd_artifacts[2]]
      self.assertResolvedAndMLMDArtifactListEqual(
          actual_artifacts, expected_artifacts
      )
      self.assertEqual(
          actual_artifacts[0].custom_properties["purity"].int_value, 2
      )
  
imports: from typing import Sequence
  import tensorflow
  from tfx import types
  from tfx.dsl.control_flow import for_each
  from tfx.dsl.input_resolution import canned_resolver_functions
  from tfx.dsl.input_resolution import resolver_op
  from tfx.dsl.input_resolution.ops import test_utils
  from tfx.orchestration import pipeline
  from tfx.orchestration.portable import inputs_utils
  from tfx.orchestration.portable.input_resolution import exceptions
  from tfx.types import channel_utils
  from tfx.types import resolved_channel
  from ml_metadata.proto import metadata_store_pb2
label_desc: Use image node_id 20 for calling the CannedResolverFunctionsTest obj's underlying member method code with example usage: obj.testFilterCustomPropertyEqualResolverFn_E2E() without return types