@@ -39,6 +39,101 @@ def test_hit(self):
39
39
40
40
self .assertEquals (self .successResultOf (cache .get ("foo" )), 123 )
41
41
42
+ def test_hit_deferred (self ):
43
+ cache = DeferredCache ("test" )
44
+ origin_d = defer .Deferred ()
45
+ set_d = cache .set ("k1" , origin_d )
46
+
47
+ # get should return an incomplete deferred
48
+ get_d = cache .get ("k1" )
49
+ self .assertFalse (get_d .called )
50
+
51
+ # add a callback that will make sure that the set_d gets called before the get_d
52
+ def check1 (r ):
53
+ self .assertTrue (set_d .called )
54
+ return r
55
+
56
+ # TODO: Actually ObservableDeferred *doesn't* run its tests in order on py3.8.
57
+ # maybe we should fix that?
58
+ # get_d.addCallback(check1)
59
+
60
+ # now fire off all the deferreds
61
+ origin_d .callback (99 )
62
+ self .assertEqual (self .successResultOf (origin_d ), 99 )
63
+ self .assertEqual (self .successResultOf (set_d ), 99 )
64
+ self .assertEqual (self .successResultOf (get_d ), 99 )
65
+
66
+ def test_callbacks (self ):
67
+ """Invalidation callbacks are called at the right time"""
68
+ cache = DeferredCache ("test" )
69
+ callbacks = set ()
70
+
71
+ # start with an entry, with a callback
72
+ cache .prefill ("k1" , 10 , callback = lambda : callbacks .add ("prefill" ))
73
+
74
+ # now replace that entry with a pending result
75
+ origin_d = defer .Deferred ()
76
+ set_d = cache .set ("k1" , origin_d , callback = lambda : callbacks .add ("set" ))
77
+
78
+ # ... and also make a get request
79
+ get_d = cache .get ("k1" , callback = lambda : callbacks .add ("get" ))
80
+
81
+ # we don't expect the invalidation callback for the original value to have
82
+ # been called yet, even though get() will now return a different result.
83
+ # I'm not sure if that is by design or not.
84
+ self .assertEqual (callbacks , set ())
85
+
86
+ # now fire off all the deferreds
87
+ origin_d .callback (20 )
88
+ self .assertEqual (self .successResultOf (set_d ), 20 )
89
+ self .assertEqual (self .successResultOf (get_d ), 20 )
90
+
91
+ # now the original invalidation callback should have been called, but none of
92
+ # the others
93
+ self .assertEqual (callbacks , {"prefill" })
94
+ callbacks .clear ()
95
+
96
+ # another update should invalidate both the previous results
97
+ cache .prefill ("k1" , 30 )
98
+ self .assertEqual (callbacks , {"set" , "get" })
99
+
100
+ def test_set_fail (self ):
101
+ cache = DeferredCache ("test" )
102
+ callbacks = set ()
103
+
104
+ # start with an entry, with a callback
105
+ cache .prefill ("k1" , 10 , callback = lambda : callbacks .add ("prefill" ))
106
+
107
+ # now replace that entry with a pending result
108
+ origin_d = defer .Deferred ()
109
+ set_d = cache .set ("k1" , origin_d , callback = lambda : callbacks .add ("set" ))
110
+
111
+ # ... and also make a get request
112
+ get_d = cache .get ("k1" , callback = lambda : callbacks .add ("get" ))
113
+
114
+ # none of the callbacks should have been called yet
115
+ self .assertEqual (callbacks , set ())
116
+
117
+ # oh noes! fails!
118
+ e = Exception ("oops" )
119
+ origin_d .errback (e )
120
+ self .assertIs (self .failureResultOf (set_d , Exception ).value , e )
121
+ self .assertIs (self .failureResultOf (get_d , Exception ).value , e )
122
+
123
+ # the callbacks for the failed requests should have been called.
124
+ # I'm not sure if this is deliberate or not.
125
+ self .assertEqual (callbacks , {"get" , "set" })
126
+ callbacks .clear ()
127
+
128
+ # the old value should still be returned now?
129
+ get_d2 = cache .get ("k1" , callback = lambda : callbacks .add ("get2" ))
130
+ self .assertEqual (self .successResultOf (get_d2 ), 10 )
131
+
132
+ # replacing the value now should run the callbacks for those requests
133
+ # which got the original result
134
+ cache .prefill ("k1" , 30 )
135
+ self .assertEqual (callbacks , {"prefill" , "get2" })
136
+
42
137
def test_get_immediate (self ):
43
138
cache = DeferredCache ("test" )
44
139
d1 = defer .Deferred ()
0 commit comments