Local unit testing Google Cloud Storage signed URL -


i writing new application using app engine and, docs suggest not use blobstore api, i'm using google cloud storage client (gcs). want able return "signed urls" clients can gcs resources without passing through application. believe signet urls for.

but how test that? can sucessfully test gcs calls client, have no idea how test client's http calls using urlfetch.

below full test case illustrates issue:

import base64 import mimetypes import urllib import urllib2 datetime import datetime, timedelta import time  google.appengine.api import app_identity google.appengine.datastore import datastore_stub_util google.appengine.ext import testbed google.appengine.ext import ndb import unittest  import cloudstorage  # right ? gcs_api_access_endpoint = 'http://localhost:8000/_ah/gcs'   def sign_url(bucket_object, expires_after_seconds=60):     """ cloudstorage signed url download cloudstorage object without login         docs : https://cloud.google.com/storage/docs/access-control?hl=bg#signed-urls         api : https://cloud.google.com/storage/docs/reference-methods?hl=bg#getobject     """     # source: https://github.com/voscausa/appengine-gcs-signed-url/blob/05b8a93e2777679d40af62cc5ffce933216e6a85/sign_url.py     method = 'get'     gcs_filename = urllib.quote(bucket_object)     content_md5, content_type = none, none      # expiration : number of seconds since epoch     expiration_dt = datetime.utcnow() + timedelta(seconds=expires_after_seconds)     expiration = int(time.mktime(expiration_dt.timetuple()))      # generate string sign.     signature_string = '\n'.join([         method,         content_md5 or '',         content_type or '',         str(expiration),         gcs_filename])      signature_bytes = app_identity.sign_blob(signature_string)[1]     google_access_id = app_identity.get_service_account_name()      # set right query parameters. use gae service account id     query_params = {'googleaccessid': google_access_id,                     'expires': str(expiration),                     'signature': base64.b64encode(signature_bytes)}      # return built url.     result = '{endpoint}{resource}?{querystring}'.format(endpoint=gcs_api_access_endpoint,                                                          resource=gcs_filename,                                                          querystring=urllib.urlencode(query_params))     return result   file_data = "this file contents." mime = "text/plain"   class testgcs(unittest.testcase):     def setup(self):         self.testbed = testbed.testbed()         self.testbed.activate()         self.policy = datastore_stub_util.pseudorandomhrconsistencypolicy(probability=0)         self.testbed.init_datastore_v3_stub(consistency_policy=self.policy)         self.testbed.init_app_identity_stub()         self.testbed.init_memcache_stub()         self.testbed.init_urlfetch_stub()         self.testbed.init_blobstore_stub()         ndb.get_context().clear_cache()      def teardown(self):         self.testbed.deactivate()      def test_gcs_works(self):         cloudstorage.open('/mybucket/test.txt', 'w', content_type=mime) f:             f.write(file_data)         cloudstorage.open('/mybucket/test.txt', 'r') f:             data = f.read()         print(data)         self.assertequal(data, file_data)      def test_signurl(self):         url = sign_url('/mybucket/test.txt')         # fixme: not yet working have no idea on how access local gcs during test.         result = urllib2.urlopen(url)         self.assertequal(200, result.code)         self.assertequal(file_data, result.read()) 

you can test gcs , service_accounts in sdk, not have local appengine gcs service when use signed url.

but can test local app service accounts , google cloud services.

service accounts make easy authorize appengine requests other google apis , services.

to use service account in appengine sdk, have add 2 undocumented options when run development server:

  1. --appidentity_email_address=<service_account_email_address>
  2. --appidentity_private_key_path=<pem_key_path>

more info in this request documentation issue

you can create or find service account in developers console permissions section of appengine cloud project.
, can create , download p12 key service account.

use openssl convert p12 key in rsa pem key.

i used this openssl installer windows.

to create pem key file in windows use:

openssl pkcs12 -in <p12_key_path> -nocerts -nodes -passin pass:notasecret | openssl rsa -out <pem_key_path>

now can use cloud app service accounts in development server , use app_identity sign , authorize requests.


Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -