code: def test_cache_checksum(csv_filename, tmp_path):
      # setup for training
      input_features = [category_feature(encoder={"vocab_size": 5})]
      output_features = [
          category_feature(decoder={"vocab_size": 2}, top_k=2)
      ]
  
      source_dataset = os.path.join(tmp_path, csv_filename)
      source_dataset = generate_data(
          input_features, output_features, source_dataset
      )
  
      config = {
          INPUT_FEATURES: input_features,
          OUTPUT_FEATURES: output_features,
          DEFAULTS: {
              CATEGORY: {PREPROCESSING: {"fill_value": "<UNKNOWN>"}}
          },
          TRAINER: {EPOCHS: 2, BATCH_SIZE: 128},
      }
  
      backend = LocalTestBackend()
      cache_fname = replace_file_extension(
          source_dataset, TRAINING_PREPROC_FILE_NAME
      )
  
      # conduct initial training
      output_directory = os.path.join(tmp_path, "results")
      model = LudwigModel(config, backend=backend)
      model.train(
          dataset=source_dataset, output_directory=output_directory
      )
      first_training_timestamp = os.path.getmtime(cache_fname)
  
      # conduct second training, should not force recreating hdf5
      model = LudwigModel(config, backend=backend)
      model.train(
          dataset=source_dataset, output_directory=output_directory
      )
      current_training_timestamp = os.path.getmtime(cache_fname)
  
      # time stamps should be the same
      assert first_training_timestamp == current_training_timestamp
  
      # force recreating cache file by changing checksum by updating defaults
      prior_training_timestamp = current_training_timestamp
      config[DEFAULTS][CATEGORY][PREPROCESSING][
          "fill_value"
      ] = "<EMPTY>"
      model = LudwigModel(config, backend=backend)
      model.train(
          dataset=source_dataset, output_directory=output_directory
      )
      current_training_timestamp = os.path.getmtime(cache_fname)
  
      # timestamp should differ
      assert prior_training_timestamp < current_training_timestamp
  
      # force recreating cache by updating modification time of source dataset
      prior_training_timestamp = current_training_timestamp
      os.utime(source_dataset)
      model = LudwigModel(config, backend=backend)
      model.train(
          dataset=source_dataset, output_directory=output_directory
      )
      current_training_timestamp = os.path.getmtime(cache_fname)
  
      # timestamps should be different
      assert prior_training_timestamp < current_training_timestamp
  
      # force change in feature preprocessing
      prior_training_timestamp = current_training_timestamp
      input_features = config[INPUT_FEATURES].copy()
      input_features[0][PREPROCESSING] = {"lowercase": True}
      config[INPUT_FEATURES] = input_features
      model = LudwigModel(config, backend=backend)
      model.train(
          dataset=source_dataset, output_directory=output_directory
      )
      current_training_timestamp = os.path.getmtime(cache_fname)
  
      # timestamps should be different
      assert prior_training_timestamp < current_training_timestamp
  
      # force change in features names (and properties)
      prior_training_timestamp = current_training_timestamp
      input_features = [
          category_feature(encoder={"vocab_size": 5}),
          category_feature(),
      ]
      source_dataset = generate_data(
          input_features, output_features, source_dataset
      )
      config[INPUT_FEATURES] = input_features
      model = LudwigModel(config, backend=backend)
      model.train(
          dataset=source_dataset, output_directory=output_directory
      )
      current_training_timestamp = os.path.getmtime(cache_fname)
  
      # timestamps should be different
      assert prior_training_timestamp < current_training_timestamp
  
      # force change in Ludwig version
      prior_training_timestamp = current_training_timestamp
      global_vars.LUDWIG_VERSION = "new_version"
      model = LudwigModel(config, backend=backend)
      model.train(
          dataset=source_dataset, output_directory=output_directory
      )
      current_training_timestamp = os.path.getmtime(cache_fname)
  
      # timestamps should be different
      assert prior_training_timestamp < current_training_timestamp
  
imports: import json
  import logging
  import os.path
  import re
  import numpy
  import pandas
  import pytest
  import torch
  from ludwig import globals
  from ludwig.api import LudwigModel
  from ludwig.backend import LOCAL_BACKEND
  from ludwig.constants import BATCH_SIZE, CATEGORY, DEFAULTS, EPOCHS, INPUT_FEATURES, OUTPUT_FEATURES, PREPROCESSING, TRAINER, TRAINING
  from ludwig.contribs.mlflow import MlflowCallback
  from ludwig.experiment import experiment_cli
  from ludwig.features.number_feature import numeric_transformation_registry
  from ludwig.globals import DESCRIPTION_FILE_NAME, TRAINING_PREPROC_FILE_NAME
  from ludwig.schema.optimizers import optimizer_registry
  from ludwig.utils.data_utils import load_json, replace_file_extension
  from ludwig.utils.misc_utils import get_from_registry
  from ludwig.utils.package_utils import LazyLoader
  from tests.integration_tests import synthetic_test_data
  from tests.integration_tests.utils import category_feature, generate_data, LocalTestBackend
label_desc: Use image node_id 7 for calling a global function with example usage: test_cache_checksum(csv_filename, tmp_path) without return types