launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #14505
[Merge] lp:~jtv/maas/make-file-upload into lp:maas
Jeroen T. Vermeulen has proposed merging lp:~jtv/maas/make-file-upload into lp:maas.
Commit message:
Factory method: make_file_upload, to create a file-like object that's just a little bit more file-like than BytesIO.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~jtv/maas/make-file-upload/+merge/135886
This is another bit I just pulled from the larger branch I'm working on, to whittle it down to a convenient reviewing size. This helper turned out to be of use in existing code as well. It creates a BytesIO, but with a "name" attribute, and in the usual factory style, it makes up the name and/or content as desired.
I'm not entirely sure if the name is right. But I toyed with alternatives like "make_fake_file" but found nothing that is quite as distinct from the already present "make_file." Also, its current form holds a concrete and useful promise: that the result is something you can feed to a POST using the Django test client, and which it will then interpret as a file upload.
Jeroen
--
https://code.launchpad.net/~jtv/maas/make-file-upload/+merge/135886
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/maas/make-file-upload into lp:maas.
=== modified file 'src/maasserver/testing/factory.py'
--- src/maasserver/testing/factory.py 2012-11-23 11:13:39 +0000
+++ src/maasserver/testing/factory.py 2012-11-23 12:29:24 +0000
@@ -60,6 +60,30 @@
class Factory(maastesting.factory.Factory):
+ def make_file_upload(self, name=None, content=None):
+ """Create a file-like object for upload in http POST or PUT.
+
+ To upload a file using the Django test client, just include a
+ parameter that maps not to a string, but to a file upload as
+ produced by this method.
+
+ :param name: Name of the file to be uploaded. If omitted, one will
+ be made up.
+ :type name: `unicode`
+ :param content: Contents for the uploaded file. If omitted, some
+ contents will be made up.
+ :type content: `bytes`
+ :return: A file-like object, with the requested `content` and `name`.
+ """
+ if content is None:
+ content = self.getRandomString().encode('ascii')
+ if name is None:
+ name = self.make_name('file')
+ assert isinstance(content, bytes)
+ upload = BytesIO(content)
+ upload.name = name
+ return upload
+
def getRandomEnum(self, enum, but_not=None):
"""Pick a random item from an enumeration class.
@@ -302,12 +326,8 @@
return admin
def make_file_storage(self, filename=None, content=None):
- if filename is None:
- filename = self.getRandomString(100)
- if content is None:
- content = self.getRandomString(1024).encode('ascii')
-
- return FileStorage.objects.save_file(filename, BytesIO(content))
+ fake_file = self.make_file_upload(filename, content)
+ return FileStorage.objects.save_file(fake_file.name, fake_file)
def make_oauth_header(self, **kwargs):
"""Fake an OAuth authorization header.
=== modified file 'src/metadataserver/tests/test_api.py'
--- src/metadataserver/tests/test_api.py 2012-11-14 14:34:06 +0000
+++ src/metadataserver/tests/test_api.py 2012-11-23 12:29:24 +0000
@@ -14,7 +14,6 @@
from collections import namedtuple
import httplib
-from io import BytesIO
import json
from django.conf import settings
@@ -153,9 +152,10 @@
'status': 'OK',
}
params.update(kwargs)
- for name, content in files.items():
- params[name] = BytesIO(content)
- params[name].name = name
+ params.update({
+ name: factory.make_file_upload(name, content)
+ for name, content in files.items()
+ })
url = reverse('metadata-version', args=[version])
return client.post(url, params)