Visitar URL original
Using custom named temporary file. · googleapis/google-cloud-python@85d8371 · GitHub
Skip to content

Commit 85d8371

Browse files
committed
Using custom named temporary file.
This is so that tests can run successfully on Windows. In addition, using generic integer types (from `six`) for `gcloud._helpers._millis_from_datetime` since it returns a `long` on Windows and `int` on Linux. Also monkey patching the GCE ID check in `test_ctor_w_dataset_id_no_environ` since some CI environments will give a "false positive" on that test.
1 parent 7e90a0c commit 85d8371

5 files changed

Lines changed: 126 additions & 60 deletions

File tree

‎gcloud/_testing.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,19 @@ def __enter__(self):
3030
def __exit__(self, exc_type, exc_val, exc_tb):
3131
for key, value in self.to_restore.items():
3232
setattr(self.module, key, value)
33+
34+
35+
class _NamedTemporaryFile(object):
36+
37+
def __init__(self, suffix=''):
38+
import os
39+
import tempfile
40+
filehandle, self.name = tempfile.mkstemp(suffix=suffix)
41+
os.close(filehandle)
42+
43+
def __enter__(self):
44+
return self
45+
46+
def __exit__(self, exc_type, exc_val, exc_tb):
47+
import os
48+
os.remove(self.name)

‎gcloud/datastore/test_client.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,13 @@ def _makeOne(self, dataset_id=DATASET_ID, namespace=None,
190190
http=http)
191191

192192
def test_ctor_w_dataset_id_no_environ(self):
193-
self.assertRaises(EnvironmentError, self._makeOne, None)
193+
from gcloud._testing import _Monkey
194+
from gcloud.datastore import client as _MUT
195+
196+
# Some environments (e.g. AppVeyor CI) run in GCE, so
197+
# this test would fail artificially.
198+
with _Monkey(_MUT, _compute_engine_id=lambda: None):
199+
self.assertRaises(EnvironmentError, self._makeOne, None)
194200

195201
def test_ctor_w_implicit_inputs(self):
196202
from gcloud._testing import _Monkey

‎gcloud/storage/test_blob.py‎

Lines changed: 83 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ def test_download_to_filename(self):
281281
import time
282282
from six.moves.http_client import OK
283283
from six.moves.http_client import PARTIAL_CONTENT
284-
from tempfile import NamedTemporaryFile
284+
from gcloud._testing import _NamedTemporaryFile
285+
285286
BLOB_NAME = 'blob-name'
286287
chunk1_response = {'status': PARTIAL_CONTENT,
287288
'content-range': 'bytes 0-2/6'}
@@ -299,13 +300,14 @@ def test_download_to_filename(self):
299300
blob = self._makeOne(BLOB_NAME, bucket=bucket, properties=properties)
300301
blob._CHUNK_SIZE_MULTIPLE = 1
301302
blob.chunk_size = 3
302-
with NamedTemporaryFile() as f:
303-
blob.download_to_filename(f.name)
304-
f.flush()
305-
with open(f.name, 'rb') as g:
306-
wrote = g.read()
307-
mtime = os.path.getmtime(f.name)
303+
304+
with _NamedTemporaryFile() as temp:
305+
blob.download_to_filename(temp.name)
306+
with open(temp.name, 'rb') as file_obj:
307+
wrote = file_obj.read()
308+
mtime = os.path.getmtime(temp.name)
308309
updatedTime = time.mktime(blob.updated.timetuple())
310+
309311
self.assertEqual(wrote, b'abcdef')
310312
self.assertEqual(mtime, updatedTime)
311313

@@ -347,7 +349,8 @@ def _upload_from_file_simple_test_helper(self, properties=None,
347349
from six.moves.http_client import OK
348350
from six.moves.urllib.parse import parse_qsl
349351
from six.moves.urllib.parse import urlsplit
350-
from tempfile import NamedTemporaryFile
352+
from gcloud._testing import _NamedTemporaryFile
353+
351354
BLOB_NAME = 'blob-name'
352355
DATA = b'ABCDEF'
353356
response = {'status': OK}
@@ -359,11 +362,15 @@ def _upload_from_file_simple_test_helper(self, properties=None,
359362
blob = self._makeOne(BLOB_NAME, bucket=bucket, properties=properties)
360363
blob._CHUNK_SIZE_MULTIPLE = 1
361364
blob.chunk_size = 5
362-
with NamedTemporaryFile() as fh:
363-
fh.write(DATA)
364-
fh.flush()
365-
blob.upload_from_file(fh, rewind=True,
366-
content_type=content_type_arg)
365+
366+
with _NamedTemporaryFile() as temp:
367+
with open(temp.name, 'wb') as file_obj:
368+
file_obj.write(DATA)
369+
370+
with open(temp.name, 'rb') as file_obj:
371+
blob.upload_from_file(file_obj, rewind=True,
372+
content_type=content_type_arg)
373+
367374
rq = connection.http._requested
368375
self.assertEqual(len(rq), 1)
369376
self.assertEqual(rq[0]['method'], 'POST')
@@ -407,10 +414,11 @@ def test_upload_from_file_resumable(self):
407414
from six.moves.http_client import OK
408415
from six.moves.urllib.parse import parse_qsl
409416
from six.moves.urllib.parse import urlsplit
410-
from tempfile import NamedTemporaryFile
411417
from gcloud._testing import _Monkey
418+
from gcloud._testing import _NamedTemporaryFile
412419
from gcloud.streaming import http_wrapper
413420
from gcloud.streaming import transfer
421+
414422
BLOB_NAME = 'blob-name'
415423
UPLOAD_URL = 'http://example.com/upload/name/key'
416424
DATA = b'ABCDEF'
@@ -429,48 +437,70 @@ def test_upload_from_file_resumable(self):
429437
blob = self._makeOne(BLOB_NAME, bucket=bucket)
430438
blob._CHUNK_SIZE_MULTIPLE = 1
431439
blob.chunk_size = 5
440+
432441
# Set the threshhold low enough that we force a resumable uploada.
433442
with _Monkey(transfer, _RESUMABLE_UPLOAD_THRESHOLD=5):
434-
with NamedTemporaryFile() as fh:
435-
fh.write(DATA)
436-
fh.flush()
437-
blob.upload_from_file(fh, rewind=True)
443+
with _NamedTemporaryFile() as temp:
444+
with open(temp.name, 'wb') as file_obj:
445+
file_obj.write(DATA)
446+
with open(temp.name, 'rb') as file_obj:
447+
blob.upload_from_file(file_obj, rewind=True)
448+
438449
rq = connection.http._requested
439450
self.assertEqual(len(rq), 3)
440-
self.assertEqual(rq[0]['method'], 'POST')
441-
uri = rq[0]['uri']
451+
452+
# Requested[0]
453+
headers = dict(
454+
[(x.title(), str(y)) for x, y in rq[0].pop('headers').items()])
455+
self.assertEqual(headers['X-Upload-Content-Length'], '6')
456+
self.assertEqual(headers['X-Upload-Content-Type'],
457+
'application/octet-stream')
458+
459+
uri = rq[0].pop('uri')
442460
scheme, netloc, path, qs, _ = urlsplit(uri)
443461
self.assertEqual(scheme, 'http')
444462
self.assertEqual(netloc, 'example.com')
445463
self.assertEqual(path, '/b/name/o')
446464
self.assertEqual(dict(parse_qsl(qs)),
447465
{'uploadType': 'resumable', 'name': BLOB_NAME})
466+
self.assertEqual(rq[0], {
467+
'method': 'POST',
468+
'body': '',
469+
'connection_type': None,
470+
'redirections': 5,
471+
})
472+
473+
# Requested[1]
448474
headers = dict(
449-
[(x.title(), str(y)) for x, y in rq[0]['headers'].items()])
450-
self.assertEqual(headers['X-Upload-Content-Length'], '6')
451-
self.assertEqual(headers['X-Upload-Content-Type'],
452-
'application/octet-stream')
453-
self.assertEqual(rq[1]['method'], 'PUT')
454-
self.assertEqual(rq[1]['uri'], UPLOAD_URL)
455-
headers = dict(
456-
[(x.title(), str(y)) for x, y in rq[1]['headers'].items()])
457-
self.assertEqual(rq[1]['body'], DATA[:5])
458-
headers = dict(
459-
[(x.title(), str(y)) for x, y in rq[1]['headers'].items()])
475+
[(x.title(), str(y)) for x, y in rq[1].pop('headers').items()])
460476
self.assertEqual(headers['Content-Range'], 'bytes 0-4/6')
461-
self.assertEqual(rq[2]['method'], 'PUT')
462-
self.assertEqual(rq[2]['uri'], UPLOAD_URL)
463-
self.assertEqual(rq[2]['body'], DATA[5:])
477+
self.assertEqual(rq[1], {
478+
'method': 'PUT',
479+
'uri': UPLOAD_URL,
480+
'body': DATA[:5],
481+
'connection_type': None,
482+
'redirections': 5,
483+
})
484+
485+
# Requested[2]
464486
headers = dict(
465-
[(x.title(), str(y)) for x, y in rq[2]['headers'].items()])
487+
[(x.title(), str(y)) for x, y in rq[2].pop('headers').items()])
466488
self.assertEqual(headers['Content-Range'], 'bytes 5-5/6')
489+
self.assertEqual(rq[2], {
490+
'method': 'PUT',
491+
'uri': UPLOAD_URL,
492+
'body': DATA[5:],
493+
'connection_type': None,
494+
'redirections': 5,
495+
})
467496

468497
def test_upload_from_file_w_slash_in_name(self):
469498
from six.moves.http_client import OK
470499
from six.moves.urllib.parse import parse_qsl
471500
from six.moves.urllib.parse import urlsplit
472-
from tempfile import NamedTemporaryFile
501+
from gcloud._testing import _NamedTemporaryFile
473502
from gcloud.streaming import http_wrapper
503+
474504
BLOB_NAME = 'parent/child'
475505
UPLOAD_URL = 'http://example.com/upload/name/parent%2Fchild'
476506
DATA = b'ABCDEF'
@@ -488,11 +518,14 @@ def test_upload_from_file_w_slash_in_name(self):
488518
blob = self._makeOne(BLOB_NAME, bucket=bucket)
489519
blob._CHUNK_SIZE_MULTIPLE = 1
490520
blob.chunk_size = 5
491-
with NamedTemporaryFile() as fh:
492-
fh.write(DATA)
493-
fh.flush()
494-
blob.upload_from_file(fh, rewind=True)
495-
self.assertEqual(fh.tell(), len(DATA))
521+
522+
with _NamedTemporaryFile() as temp:
523+
with open(temp.name, 'wb') as file_obj:
524+
file_obj.write(DATA)
525+
with open(temp.name, 'rb') as file_obj:
526+
blob.upload_from_file(file_obj, rewind=True)
527+
self.assertEqual(file_obj.tell(), len(DATA))
528+
496529
rq = connection.http._requested
497530
self.assertEqual(len(rq), 1)
498531
self.assertEqual(rq[0]['redirections'], 5)
@@ -517,8 +550,9 @@ def _upload_from_filename_test_helper(self, properties=None,
517550
from six.moves.http_client import OK
518551
from six.moves.urllib.parse import parse_qsl
519552
from six.moves.urllib.parse import urlsplit
520-
from tempfile import NamedTemporaryFile
553+
from gcloud._testing import _NamedTemporaryFile
521554
from gcloud.streaming import http_wrapper
555+
522556
BLOB_NAME = 'blob-name'
523557
UPLOAD_URL = 'http://example.com/upload/name/key'
524558
DATA = b'ABCDEF'
@@ -537,10 +571,13 @@ def _upload_from_filename_test_helper(self, properties=None,
537571
properties=properties)
538572
blob._CHUNK_SIZE_MULTIPLE = 1
539573
blob.chunk_size = 5
540-
with NamedTemporaryFile(suffix='.jpeg') as fh:
541-
fh.write(DATA)
542-
fh.flush()
543-
blob.upload_from_filename(fh.name, content_type=content_type_arg)
574+
575+
with _NamedTemporaryFile(suffix='.jpeg') as temp:
576+
with open(temp.name, 'wb') as file_obj:
577+
file_obj.write(DATA)
578+
blob.upload_from_filename(temp.name,
579+
content_type=content_type_arg)
580+
544581
rq = connection.http._requested
545582
self.assertEqual(len(rq), 1)
546583
self.assertEqual(rq[0]['method'], 'POST')

‎gcloud/test__helpers.py‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,18 +293,20 @@ def test_w_none(self):
293293

294294
def test_w_utc_datetime(self):
295295
import datetime
296+
import six
296297
from gcloud._helpers import UTC
297298
from gcloud._helpers import _microseconds_from_datetime
298299

299300
NOW = datetime.datetime.utcnow().replace(tzinfo=UTC)
300301
NOW_MICROS = _microseconds_from_datetime(NOW)
301302
MILLIS = NOW_MICROS // 1000
302303
result = self._callFUT(NOW)
303-
self.assertTrue(isinstance(result, int))
304+
self.assertTrue(isinstance(result, six.integer_types))
304305
self.assertEqual(result, MILLIS)
305306

306307
def test_w_non_utc_datetime(self):
307308
import datetime
309+
import six
308310
from gcloud._helpers import _UTC
309311
from gcloud._helpers import _microseconds_from_datetime
310312

@@ -317,11 +319,12 @@ class CET(_UTC):
317319
NOW_MICROS = _microseconds_from_datetime(NOW)
318320
MILLIS = NOW_MICROS // 1000
319321
result = self._callFUT(NOW)
320-
self.assertTrue(isinstance(result, int))
322+
self.assertTrue(isinstance(result, six.integer_types))
321323
self.assertEqual(result, MILLIS)
322324

323325
def test_w_naive_datetime(self):
324326
import datetime
327+
import six
325328
from gcloud._helpers import UTC
326329
from gcloud._helpers import _microseconds_from_datetime
327330

@@ -330,7 +333,7 @@ def test_w_naive_datetime(self):
330333
UTC_NOW_MICROS = _microseconds_from_datetime(UTC_NOW)
331334
MILLIS = UTC_NOW_MICROS // 1000
332335
result = self._callFUT(NOW)
333-
self.assertTrue(isinstance(result, int))
336+
self.assertTrue(isinstance(result, six.integer_types))
334337
self.assertEqual(result, MILLIS)
335338

336339

‎gcloud/test_credentials.py‎

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,19 @@ def _callFUT(self, client_email, private_key_path, scope=None):
8888
scope=scope)
8989

9090
def test_it(self):
91-
from tempfile import NamedTemporaryFile
9291
from gcloud import credentials as MUT
9392
from gcloud._testing import _Monkey
93+
from gcloud._testing import _NamedTemporaryFile
94+
9495
CLIENT_EMAIL = 'phred@example.com'
9596
PRIVATE_KEY = b'SEEkR1t'
9697
client = _Client()
9798
with _Monkey(MUT, client=client):
98-
with NamedTemporaryFile() as file_obj:
99-
file_obj.write(PRIVATE_KEY)
100-
file_obj.flush()
101-
found = self._callFUT(CLIENT_EMAIL, file_obj.name)
99+
with _NamedTemporaryFile() as temp:
100+
with open(temp.name, 'wb') as file_obj:
101+
file_obj.write(PRIVATE_KEY)
102+
found = self._callFUT(CLIENT_EMAIL, temp.name)
103+
102104
self.assertTrue(found is client._signed)
103105
expected_called_with = {
104106
'service_account_name': CLIENT_EMAIL,
@@ -108,18 +110,20 @@ def test_it(self):
108110
self.assertEqual(client._called_with, expected_called_with)
109111

110112
def test_it_with_scope(self):
111-
from tempfile import NamedTemporaryFile
112113
from gcloud import credentials as MUT
113114
from gcloud._testing import _Monkey
115+
from gcloud._testing import _NamedTemporaryFile
116+
114117
CLIENT_EMAIL = 'phred@example.com'
115118
PRIVATE_KEY = b'SEEkR1t'
116119
SCOPE = 'SCOPE'
117120
client = _Client()
118121
with _Monkey(MUT, client=client):
119-
with NamedTemporaryFile() as file_obj:
120-
file_obj.write(PRIVATE_KEY)
121-
file_obj.flush()
122-
found = self._callFUT(CLIENT_EMAIL, file_obj.name, SCOPE)
122+
with _NamedTemporaryFile() as temp:
123+
with open(temp.name, 'wb') as file_obj:
124+
file_obj.write(PRIVATE_KEY)
125+
found = self._callFUT(CLIENT_EMAIL, temp.name, SCOPE)
126+
123127
self.assertTrue(found is client._signed)
124128
expected_called_with = {
125129
'service_account_name': CLIENT_EMAIL,

0 commit comments

Comments
 (0)