code: def test_resources_fingerprints_remain_after_being_cached(
      temp_cache: LocalTrainingCache, train_with_schema: Callable
  ):
      train_schema = GraphSchema(
          {
              "train": SchemaNode(
                  needs={},
                  uses=PersistableTestComponent,
                  fn="train",
                  constructor_name="create",
                  config={"test_value": "4"},
                  is_target=True,
              ),
              "process": SchemaNode(
                  needs={"resource": "train"},
                  uses=PersistableTestComponent,
                  fn="run_inference",
                  constructor_name="load",
                  config={},
                  is_target=True,
              ),
          }
      )
  
      # Train and cache.
      train_with_schema(train_schema, temp_cache)
  
      # We can determine if a cached `Resource` has a static fingerprint by comparing two
      # subsequent cache entries of a child node.
      import sqlalchemy as sa
  
      with temp_cache._sessionmaker.begin() as session:
          # This will get the cache entry for the "process" node.
          query_for_most_recently_used_entry = sa.select(
              temp_cache.CacheEntry
          ).order_by(temp_cache.CacheEntry.last_used.desc())
          entry = (
              session.execute(query_for_most_recently_used_entry)
              .scalars()
              .first()
          )
          # The fingerprint key will incorporate the fingerprint of the `Resource`
          # provided by the "train" node. We save this key to compare after the next run.
          fingerprint_key = entry.fingerprint_key
          # Deleting the entry will force it to be recreated next train.
          delete_query = sa.delete(temp_cache.CacheEntry).where(
              temp_cache.CacheEntry.fingerprint_key == fingerprint_key
          )
          session.execute(delete_query)
  
      # In this second train, the Resource output of "train" will be retrieved from the
      # cache.
      train_with_schema(train_schema, temp_cache)
  
      with temp_cache._sessionmaker.begin() as session:
          # This will get the new cache entry for the "process" node.
          query_for_most_recently_used_entry = sa.select(
              temp_cache.CacheEntry
          ).order_by(temp_cache.CacheEntry.last_used.desc())
          entry = (
              session.execute(query_for_most_recently_used_entry)
              .scalars()
              .first()
          )
          # Assert the fingerprint key of the new entry is the same. This confirms that
          # the Resource from the cache has the same fingerprint.
          assert entry.fingerprint_key == fingerprint_key
  
imports: import logging
  from pathlib import Path
  from typing import Callable, Dict, Optional, Text, Type, Any
  from unittest.mock import Mock
  from _pytest.logging import LogCaptureFixture
  from _pytest.monkeypatch import MonkeyPatch
  from _pytest.tmpdir import TempPathFactory
  import pytest
  from rasa.engine.caching import LocalTrainingCache, TrainingCache
  from rasa.engine.exceptions import GraphComponentException
  from rasa.engine.graph import GraphComponent, GraphSchema, SchemaNode, GraphModelConfiguration, GraphNode, ExecutionContext, GraphNodeHook
  from rasa.engine.runner.dask import DaskGraphRunner
  from rasa.engine.storage.local_model_storage import LocalModelStorage
  from rasa.engine.storage.resource import Resource
  from rasa.engine.storage.storage import ModelStorage
  from rasa.engine.training.graph_trainer import GraphTrainer
  from rasa.shared.core.domain import Domain
  from rasa.shared.data import TrainingType
  from rasa.shared.importers.importer import TrainingDataImporter
  from tests.engine.graph_components_test_classes import AddInputs, AssertComponent, FileReader, PersistableTestComponent, ProvideX, SubtractByX, CacheableComponent
label_desc: Use image node_id 12 for calling a global function with example usage: test_resources_fingerprints_remain_after_being_cached(temp_cache, train_with_schema) without return types