Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different etags for Mock storage object between head request and get request #25

Open
brlanier opened this issue Aug 10, 2017 · 0 comments

Comments

@brlanier
Copy link

When using Fog.Mock! in tests I have noticed that a different etag is returned in the response when using a files.head request versus a file.get request. I don't know enough about what is going on, but I think the Mock class for the head request has a bug or I really don't understand what its trying to do.

Using Fog 1.37.0 but can see the code is the same here for the two files I am looking at.

From my test on the same file here is the metadata for the same file using each request

Head:

<Fog::Storage::Rackspace::File
    key="global/teacher/test_program/u1/g1/default/grade_web_resources/test.pdf",
    content_length=19,
    content_type="application/pdf",
    content_disposition=nil,
    etag="\"ba6969cb26232dd85e5b47c8f3a181bb\"",
    last_modified=2017-08-09 21:28:21 UTC,
    access_control_allow_origin=nil,
    origin=nil,
    content_encoding=nil,
    delete_at=nil,
    delete_after=nil

and using get

<Fog::Storage::Rackspace::File
    key="global/teacher/test_program/u1/g1/default/grade_web_resources/test.pdf",
    content_length=19,
    content_type="application/pdf",
    content_disposition=nil,
    etag="f354d658bc16113d80d596a8b61e87bf",
    last_modified=2017-08-09 21:27:53 UTC,
    access_control_allow_origin=nil,
    origin=nil,
    content_encoding=nil,
    delete_at=nil,
    delete_after=nil

The get request has the correct etag based on what we set prior to saving the file.

Part of the method we are using to push the file

    cloud_file = directory.files.create key: cloud_path
    cloud_file.body = File.open local_path
    cloud_file.etag = checksum local_path
    cloud_file.save

In looking at the rackspace/requests/storage/head_object.rb file, specifically the Mock class, I get stuck when looking at how the etag is generated. It looks like it tries to grab the value from each part of the file object that is stored in the hash key, adding that value to a new hash and then later calculating and md5 digest of that new hash turned into a string. This seems weird that you are creating an md5 digest of a value that is a string of all the md5 digests of each part of the file and using that for the etag.
In testing, when inspecting the mock object of the file in question I can see that the @meta entry already contains the correct Etag as set.

...@last_modified=2017-08-10 17:31:12 UTC, @hash="f354d658bc16113d80d596a8b61e87bf", @meta={"Etag"=>"f354d658bc16113d80d596a8b61e87bf"}, @static_manifest=false>

In summary, I can't figure out how to properly test methods that are relying on a head call to test data. We have a method, partly listed above, that creates a cloud file, writes the file body and etag before saving and then does files.head call against the newly uploaded file to verify the file was uploaded with the correct etag and size. That method is failing tests now because the wrong etag is being returned in the head request under Fog.Mock!.

I don't fully understand the process or the best place to make a change, but it seems like the Moc class in get_object is just relying on the .to_headers method to return what is there while head is doing something different.

I would be happy to submit a pull request at some point, but I'm afraid I don't understand enough about the entire process but more specifically why the head_object in the Mock class is creating what seems to be a random etag. If there is no need to have the etag returned with something besides nil, then it seems letting the value that may or may not exist in the @meta value of the object seems the correct way. Not to mention the .to_headers method seems to take care of adding the bytes for each part up.

Sorry for the rambling. Happy to provide more info as needed. Looking for help, clarification or guidance on perhaps the best way or needed way to make the change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant