$file->original: Where does it come from? I am attempting to write a patch for the Redirect module that automatically creates a redirect from the old file path to the new one, whenever a file is updated.

I added a hook to redirect.module:

function redirect_file_update($file){
      /**
     * Creates a new redirect from old file to new one when the new one has a different URI.
     */

  if (empty($file-&gt;original)) {
    $file-&gt;original = entity_load_unchanged('file', $file-&gt;fid);
  }
  if ($file-&gt;uri !== $file-&gt;original-&gt;uri) {
    $redirect = new stdClass();
    redirect_object_prepare(
        $redirect,
        array(
        'source' =&gt; file_create_url($file-&gt;original-&gt;uri),
        'source_options' =&gt; array(),
        'redirect' =&gt; file_create_url($file-&gt;uri),
        'redirect_options' =&gt; array(),
        )
    );
    module_invoke(
      'redirect',
      'object_prepare',
      $redirect,
      array(
        'source' =&gt; file_create_url($file-&gt;original-&gt;uri),
        'source_options' =&gt; array(),
        'redirect' =&gt; file_create_url($file-&gt;uri),
        'redirect_options' =&gt; array(),
      )
    );
    module_invoke('redirect', 'save', $redirect);
  }
}


and I verified with a dpm() that $file->original exists as expected when I'm working with files in the GUI. 

But when I run tests it doesn't work. According to hook_file_update() docs, it should be called whenever file_save() is called, but it appears that the code inside my redirect_file_update() is never being called, entity_load_unchanged() is returning the exact same object as plain old $file, and my $file objects don't have an 'original' property as far as the test knows, even after saving. Here's the testing code:

function setUp(array $modules = array()) {
  parent::setUp($modules);

  $this-&gt;admin_user = $this-&gt;drupalCreateUser(array('administer redirects', 'access site reports', 'access content', 'create article content', 'edit any article content', 'create url aliases'));
  $this-&gt;drupalLogin($this-&gt;admin_user);
}
  // Test whether replacement of a file redirects the old file URI to the new one.
  function testFileReplacementRedirects () {
  // Create a few test files and save them.
  $files = $this-&gt;drupalGetTestFiles('image');
  foreach ($files as $file) {
    file_save($file);
  }
  // Get a list of all the files we just created.
  $fileQuery = new EntityFieldQuery();
  $files_list = $fileQuery-&gt;entityCondition('entity_type', 'file')
    -&gt;propertyOrderBy('fid')
    -&gt;execute();
  // Pick out two files to use for our test.
  $test_file_one = file_load($files_list['file'][1]-&gt;fid);
  $test_file_two = file_load($files_list['file'][2]-&gt;fid);

  // Move file one to file two's URI
  $old_url = file_create_url($test_file_one-&gt;uri);
  $new_url = file_create_url($test_file_two-&gt;uri);
  $test_file_one = file_move($test_file_one, $dest = $test_file_two-&gt;uri, $replace = FILE_EXISTS_REPLACE);
  // Load the old module's URI and see if it redirects to the new one.
  $this-&gt;drupalGet($old_url);
  $this_page = $this-&gt;drupalGetHeaders(TRUE);
  $this-&gt;assertEqual($this_page[0]['location'], $new_url, 'Redirected from ' . $old_url . ' to ' . $new_url . '.');
  $this-&gt;assertEqual($this_page[0][':status'], 'HTTP/1.1 301 Moved Permanently', 'Status: ' . $this_page[0][':status']);
}


What is going wrong?
$file-&gt;original is set from file_save() to make it available to hook_file_presave(), hook_entity_presave(), hook_file_insert(), hook_entity_insert(), hook_file_update(), and hook_entity_update(). It is then removed from file_save() before the function returns the file object to the caller.

// Load the stored entity, if any.
if (!empty($file-&gt;fid) &amp;&amp; !isset($file-&gt;original)) {
  $file-&gt;original = entity_load_unchanged('file', $file-&gt;fid);
}


Clearly, if the file was not previously saved, $file-&gt;original doesn't get set.