forked from PerceptumNL/KhanLatest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
backup_model_test.py
142 lines (110 loc) · 4.78 KB
/
backup_model_test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import datetime
import time
from third_party.agar.test import BaseTest
from google.appengine.ext import db
import backup_model
from testutil import testsize
class BackupModelTest(BaseTest):
"""Tests for verifying the auto-timestamping of BackupModel.
Since this relies on a feature deep in GAE's implementation, it's hard
to mock out the timestamping, so these tests rely on time.sleep() and
just compares relative times for sanity.
"""
def tearDown(self):
super(BackupModelTest, self).tearDown()
@testsize.medium()
def test_backup_auto_updates_timestamp(self):
class Monkey(backup_model.BackupModel):
pass
george = Monkey()
key = george.put()
retrieved = Monkey.get(key)
first_timestamp = retrieved.backup_timestamp
self.assertTrue(first_timestamp is not None)
# Simulate some time ellapsed.
time.sleep(1)
# Another put() should update the timestamp again.
george.put()
retrieved = Monkey.get(key)
second_timestamp = retrieved.backup_timestamp
self.assertTrue(second_timestamp is not None)
self.assertTrue(second_timestamp > first_timestamp)
def test_backup_adds_timestamps_to_existing_models(self):
# This is just a normal model for now.
class ExistingModel(db.Model):
pass
instance = ExistingModel()
key = instance.put()
retrieved = ExistingModel.get(key)
# We don't expect to have a timestamp, since it's a normal Model.
self.assertFalse(hasattr(retrieved, 'backup_timestamp'))
# Pretend the code got updated to have this model inherit BackupModel
class ExistingModel(backup_model.BackupModel):
pass
# Retrieving an existing entity and calling put() should add
# a timestamp to existing entities.
retrieved = ExistingModel.get(key)
self.assertTrue(isinstance(retrieved, backup_model.BackupModel))
key = retrieved.put()
retrieved = ExistingModel.get(key)
self.assertTrue(retrieved.backup_timestamp is not None)
def test_backup_timestamp_auto_populates(self):
"""
This is a test to document the behaviour of an auto_now field auto
populating in App Engine.
WARNING: since auto_now fields auto-populate, you cannot rely on
reading a property of an instance to determine the backup_timestamp.
"""
class Monkey(backup_model.BackupModel):
pass
monkey = Monkey()
# Even before this entity is saved to the datastore, GAE will auto
# populate any date properties with auto_now=True, meaning we can't
# distinguish whether or not we manually set that property or not!
# This means models that claimed to have been backed up, might not have
# actually been backed up!
first_timestamp = monkey.backup_timestamp
self.assertTrue(first_timestamp is not None)
@testsize.medium()
def test_backup_timestamp_cant_be_written_to(self):
"""
This is a test to document the behaviour of an auto_now field not
actually being able to be set in App Engine.
"""
class Monkey(backup_model.BackupModel):
name = db.StringProperty()
fixed_timestamp = datetime.datetime.now()
monkey = Monkey()
monkey.backup_timestamp = fixed_timestamp
key = monkey.put()
time.sleep(1)
# Retrieve it again and modify some stuff.
monkey = Monkey.get(key)
monkey.name = "george"
monkey.put()
monkey = Monkey.get(key)
retrieved_timestamp = monkey.backup_timestamp
self.assertNotEquals(fixed_timestamp, retrieved_timestamp)
@testsize.medium()
def test_can_filter_by_backup_timestamp(self):
# This is the real test of BackupModel - can we actually query and
# filter by the backup_timestamp so that we can do the backup!
class Monkey(backup_model.BackupModel):
name = db.StringProperty()
a = Monkey(key_name="a")
b = Monkey(key_name="b")
c = Monkey(key_name="c")
d = Monkey(key_name="d")
db.put([a, b, c, d])
# Pretend we do a backup and now we have info on all 4 monkeys
last_backup_time = datetime.datetime.now()
time.sleep(1)
# Pretend to update one of the monkeys
d = Monkey.get_by_key_name("d")
d.name = "george"
d.put()
monkeys_to_backup = (Monkey.all().
filter("backup_timestamp >", last_backup_time).
fetch(100))
self.assertEquals(1, len(monkeys_to_backup))
self.assertEquals(d.key(), monkeys_to_backup[0].key())