简体   繁体   中英

How do I use unittest to catch CapabilityDisabledError exceptions?

I have a Flask project on GAE and I'd like to start adding try/except blocks around database writes in case the datastore has problems, which will definitely fire when there's a real error, but I'd like to mimic that error in a unittest so I can have confidence of what will really happen during an outage.

For example, my User model:

class User(ndb.Model):
    guser = ndb.UserProperty()
    user_handle = ndb.StringProperty()

and in other view/controller code:

def do_something():
    try:
        User(guser=users.get_current_user(), user_handle='barney').put()
    except CapabilityDisabledError:
        flash('Oops, database is down, try again later', 'danger')
    return redirect(url_for('registration_done'))

Here's a gist of my test code: https://gist.github.com/iandouglas/10441406

In a nutshell, GAE allows us to use capabilities to temporarily disable the stubs for memcache, datastore_v3, etc., and in the main test method:

def test_stuff(self):
    # this test ALWAYS passes, making me believe the datastore is temporarily down
    self.assertFalse(capabilities.CapabilitySet('datastore_v3').is_enabled())

    # but this write to the datastore always SUCCEEDS, so the exception never gets
    # thrown, therefore this "assertRaises" always fails
    self.assertRaises(CapabilityDisabledError,
        lambda: User(guser=self.guser, pilot_handle='foo').put())

I read some other post recommending calling the User.put() as a lambda which results in this traceback:

Traceback (most recent call last):
  File "/home/id/src/project/tests/integration/views/test_datastore_offline.py", line 28, in test_stuff
    self.assertRaises(CapabilityDisabledError, lambda: User(
AssertionError: CapabilityDisabledError not raised

If I remove the lambda: portion, I get this traceback instead:

Traceback (most recent call last):
  File "/home/id/src/project/tests/integration/views/test_datastore_offline.py", line 31, in test_stuff
    pilot_handle_lower='foo'
  File "/usr/lib/python2.7/unittest/case.py", line 475, in assertRaises
    callableObj(*args, **kwargs)
TypeError: 'Key' object is not callable

Google's tutorials show you how to turn these capabilities on and off for unit testing, and in other tutorials they show you which exceptions could get thrown if their services are offline or experiencing intermittent issues, but they have no tutorials showing how they might work together in a unit test.

Thanks for any ideas.

The datastore stub does not support returning a CapabilityDisabledError, so enabled the error in the capabilities stub will not affect calls to datastore.

As a separate note, if you are using the High Replication Datastore, you'll never experience the CapabilityDisabledError because it does not have scheduled downtime .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM