@@ -121,6 +121,163 @@ def test_regions(self):
121121 with self .assertRaises (NotImplementedError ):
122122 table .regions ()
123123
124+ def test_counter_get (self ):
125+ klass = self ._getTargetClass ()
126+ counter_value = 1337
127+
128+ class TableWithInc (klass ):
129+
130+ incremented = []
131+ value = counter_value
132+
133+ def counter_inc (self , row , column , value = 1 ):
134+ self .incremented .append ((row , column , value ))
135+ self .value += value
136+ return self .value
137+
138+ name = 'table-name'
139+ connection = None
140+ table = TableWithInc (name , connection )
141+
142+ row = 'row-key'
143+ column = 'fam:col1'
144+ self .assertEqual (TableWithInc .incremented , [])
145+ result = table .counter_get (row , column )
146+ self .assertEqual (result , counter_value )
147+ self .assertEqual (TableWithInc .incremented , [(row , column , 0 )])
148+
149+ def test_counter_dec (self ):
150+ klass = self ._getTargetClass ()
151+ counter_value = 42
152+
153+ class TableWithInc (klass ):
154+
155+ incremented = []
156+ value = counter_value
157+
158+ def counter_inc (self , row , column , value = 1 ):
159+ self .incremented .append ((row , column , value ))
160+ self .value += value
161+ return self .value
162+
163+ name = 'table-name'
164+ connection = None
165+ table = TableWithInc (name , connection )
166+
167+ row = 'row-key'
168+ column = 'fam:col1'
169+ dec_value = 987
170+ self .assertEqual (TableWithInc .incremented , [])
171+ result = table .counter_dec (row , column , value = dec_value )
172+ self .assertEqual (result , counter_value - dec_value )
173+ self .assertEqual (TableWithInc .incremented , [(row , column , - dec_value )])
174+
175+ def _counter_inc_helper (self , row , column , value , commit_result ):
176+ import six
177+
178+ name = 'table-name'
179+ connection = None
180+ table = self ._makeOne (name , connection )
181+ # Mock the return values.
182+ table ._low_level_table = _MockLowLevelTable ()
183+ table ._low_level_table .row_values [row ] = _MockLowLevelRow (
184+ row , commit_result = commit_result )
185+
186+ result = table .counter_inc (row , column , value = value )
187+
188+ incremented_value = value + _MockLowLevelRow .COUNTER_DEFAULT
189+ self .assertEqual (result , incremented_value )
190+
191+ # Check the row values returned.
192+ row_obj = table ._low_level_table .row_values [row ]
193+ if isinstance (column , six .binary_type ):
194+ column = column .decode ('utf-8' )
195+ self .assertEqual (row_obj .counts ,
196+ {tuple (column .split (':' )): incremented_value })
197+
198+ def test_counter_inc (self ):
199+ import struct
200+
201+ row = 'row-key'
202+ col_fam = u'fam'
203+ col_qual = u'col1'
204+ column = col_fam + u':' + col_qual
205+ value = 42
206+ packed_value = struct .pack ('>q' , value )
207+ fake_timestamp = None
208+ commit_result = {
209+ col_fam : {
210+ col_qual : [(packed_value , fake_timestamp )],
211+ }
212+ }
213+ self ._counter_inc_helper (row , column , value , commit_result )
214+
215+ def test_counter_inc_column_bytes (self ):
216+ import struct
217+
218+ row = 'row-key'
219+ col_fam = b'fam'
220+ col_qual = b'col1'
221+ column = col_fam + b':' + col_qual
222+ value = 42
223+ packed_value = struct .pack ('>q' , value )
224+ fake_timestamp = None
225+ commit_result = {
226+ col_fam .decode ('utf-8' ): {
227+ col_qual .decode ('utf-8' ): [(packed_value , fake_timestamp )],
228+ }
229+ }
230+ self ._counter_inc_helper (row , column , value , commit_result )
231+
232+ def test_counter_inc_bad_result (self ):
233+ row = 'row-key'
234+ col_fam = 'fam'
235+ col_qual = 'col1'
236+ column = col_fam + ':' + col_qual
237+ value = 42
238+ commit_result = None
239+ with self .assertRaises (TypeError ):
240+ self ._counter_inc_helper (row , column , value , commit_result )
241+
242+ def test_counter_inc_result_key_error (self ):
243+ row = 'row-key'
244+ col_fam = 'fam'
245+ col_qual = 'col1'
246+ column = col_fam + ':' + col_qual
247+ value = 42
248+ commit_result = {}
249+ with self .assertRaises (KeyError ):
250+ self ._counter_inc_helper (row , column , value , commit_result )
251+
252+ def test_counter_inc_result_nested_key_error (self ):
253+ row = 'row-key'
254+ col_fam = 'fam'
255+ col_qual = 'col1'
256+ column = col_fam + ':' + col_qual
257+ value = 42
258+ commit_result = {col_fam : {}}
259+ with self .assertRaises (KeyError ):
260+ self ._counter_inc_helper (row , column , value , commit_result )
261+
262+ def test_counter_inc_result_non_unique_cell (self ):
263+ row = 'row-key'
264+ col_fam = 'fam'
265+ col_qual = 'col1'
266+ column = col_fam + ':' + col_qual
267+ value = 42
268+ fake_timestamp = None
269+ packed_value = None
270+ commit_result = {
271+ col_fam : {
272+ col_qual : [
273+ (packed_value , fake_timestamp ),
274+ (packed_value , fake_timestamp ),
275+ ],
276+ }
277+ }
278+ with self .assertRaises (ValueError ):
279+ self ._counter_inc_helper (row , column , value , commit_result )
280+
124281
125282class Test__gc_rule_to_dict (unittest2 .TestCase ):
126283
@@ -231,7 +388,29 @@ def __init__(self, *args, **kwargs):
231388 self .kwargs = kwargs
232389 self .list_column_families_calls = 0
233390 self .column_families = {}
391+ self .row_values = {}
234392
235393 def list_column_families (self ):
236394 self .list_column_families_calls += 1
237395 return self .column_families
396+
397+ def row (self , row_key ):
398+ return self .row_values [row_key ]
399+
400+
401+ class _MockLowLevelRow (object ):
402+
403+ COUNTER_DEFAULT = 0
404+
405+ def __init__ (self , row_key , commit_result = None ):
406+ self .row_key = row_key
407+ self .counts = {}
408+ self .commit_result = commit_result
409+
410+ def increment_cell_value (self , column_family_id , column , int_value ):
411+ count = self .counts .setdefault ((column_family_id , column ),
412+ self .COUNTER_DEFAULT )
413+ self .counts [(column_family_id , column )] = count + int_value
414+
415+ def commit_modifications (self ):
416+ return self .commit_result
0 commit comments