sql_partitioner 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,268 @@
1
+ require File.expand_path("../spec_helper", File.dirname(__FILE__))
2
+
3
+ shared_examples_for "PartitionCollection" do
4
+ before(:each) do
5
+ @partition_manager = SqlPartitioner::BasePartitionsManager.new(
6
+ :adapter => adapter,
7
+ :current_time => Time.utc(2014,04,18),
8
+ :table_name => 'test_events',
9
+ :logger => SPEC_LOGGER
10
+ )
11
+ end
12
+
13
+ context "with some partitions" do
14
+ before(:each) do
15
+ @partitions = {'until_2014_03_17' => 1395014400, 'until_2014_04_17' => 1397692800}
16
+ @sorted = SqlPartitioner::SQL.sort_partition_data(@partitions)
17
+ @newest_partition_ts = @sorted.last[1]
18
+ @oldest_partition_ts = @sorted.first[1]
19
+ @partition_manager.initialize_partitioning(@partitions)
20
+ @all_partitions = SqlPartitioner::Partition.all(adapter, 'test_events')
21
+ end
22
+
23
+ describe "#current_partition" do
24
+ it "should return nil when timestamp > newest partition.timestamp" do
25
+ @all_partitions.current_partition(@newest_partition_ts + 1).should == nil
26
+ end
27
+ it "should return nil when timestamp == newest partition.timestamp" do
28
+ @all_partitions.current_partition(@newest_partition_ts).should == nil
29
+ end
30
+ it "should return the newest partition when timestamp < newest partition.timestamp" do
31
+ @all_partitions.current_partition(@newest_partition_ts - 1).name.should == @sorted.last[0]
32
+ end
33
+ it "should return the oldest partition when timestamp < oldest partition.timestamp" do
34
+ @all_partitions.current_partition(@oldest_partition_ts - 1).name.should == @sorted.first[0]
35
+ end
36
+ end
37
+
38
+ describe "#older_than_timestamp" do
39
+ it "should return nil when timestamp < oldest partition.timestamp" do
40
+ @all_partitions.older_than_timestamp(@oldest_partition_ts - 1).should == []
41
+ end
42
+ it "should return nil when timestamp == partition.timestamp" do
43
+ @all_partitions.older_than_timestamp(@oldest_partition_ts).should == []
44
+ end
45
+ it "should return the partition when timestamp > newest partition timestamp" do
46
+ @all_partitions.older_than_timestamp(@newest_partition_ts + 1).map{|p| [p.name, p.timestamp]}.should == [
47
+ ['until_2014_03_17', 1395014400],
48
+ ['until_2014_04_17', 1397692800],
49
+ ]
50
+ end
51
+ end
52
+
53
+ describe "#newer_than_timestamp" do
54
+ it "should return nil when timestamp > newest partition.timestamp" do
55
+ @all_partitions.newer_than_timestamp(@newest_partition_ts + 1).should == []
56
+ end
57
+ it "should return the newest partition when timestamp == partition.timestamp" do
58
+ @all_partitions.newer_than_timestamp(@newest_partition_ts).map{|p| [p.name, p.timestamp]}.should == [
59
+ ['until_2014_04_17', 1397692800]
60
+ ]
61
+ end
62
+ it "should return all the partition when timestamp < oldest partition timestamp" do
63
+ @all_partitions.newer_than_timestamp(@oldest_partition_ts - 1).map{|p| [p.name, p.timestamp]}.should == [
64
+ ['until_2014_03_17', 1395014400],
65
+ ['until_2014_04_17', 1397692800],
66
+ ]
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+
73
+ describe "#non_future_partitions" do
74
+ before(:each) do
75
+ @partition_manager = SqlPartitioner::BasePartitionsManager.new(
76
+ :adapter => adapter,
77
+ :current_time => Time.utc(2014,04,18),
78
+ :table_name => 'test_events',
79
+ :logger => SPEC_LOGGER
80
+ )
81
+
82
+ @partitions = {'until_2014_03_17' => 1395014400}
83
+ @partition_manager.initialize_partitioning(@partitions)
84
+ end
85
+
86
+ it "should not return the future partition" do
87
+ SqlPartitioner::Partition.all(adapter, 'test_events').non_future_partitions.map{|p| [p.name, p.timestamp]}.should == [
88
+ ['until_2014_03_17', 1395014400]
89
+ ]
90
+ end
91
+ end
92
+
93
+ describe "#latest_partition" do
94
+ before(:each) do
95
+ @partition_manager = SqlPartitioner::BasePartitionsManager.new(
96
+ :adapter => adapter,
97
+ :current_time => Time.utc(2014,04,18),
98
+ :table_name => 'test_events',
99
+ :logger => SPEC_LOGGER
100
+ )
101
+ end
102
+
103
+ context "with some partitions" do
104
+ before(:each) do
105
+ @partitions = {'until_2014_03_17' => 1395014400, 'until_2014_04_17' => 1397692800}
106
+ @partition_manager.initialize_partitioning(@partitions)
107
+ end
108
+
109
+ it "should return the latest partition" do
110
+ partition = SqlPartitioner::Partition.all(adapter, 'test_events').latest_partition
111
+
112
+ partition.name.should == 'until_2014_04_17'
113
+ partition.timestamp.should == 1397692800
114
+ end
115
+ end
116
+
117
+ context "with no partitions" do
118
+ before(:each) do
119
+ @partition_manager.initialize_partitioning({})
120
+ end
121
+
122
+ it "should not return the future partition" do
123
+ SqlPartitioner::Partition.all(adapter, 'test_events').latest_partition.should == nil
124
+ end
125
+ end
126
+ end
127
+
128
+ describe "#oldest_partition" do
129
+ before(:each) do
130
+ @partition_manager = SqlPartitioner::BasePartitionsManager.new(
131
+ :adapter => adapter,
132
+ :current_time => Time.utc(2014,04,18),
133
+ :table_name => 'test_events',
134
+ :logger => SPEC_LOGGER
135
+ )
136
+ end
137
+
138
+ context "with some partitions" do
139
+ before(:each) do
140
+ @partitions = {'until_2014_03_17' => 1395014400, 'until_2014_04_17' => 1397692800}
141
+ @partition_manager.initialize_partitioning(@partitions)
142
+ end
143
+
144
+ it "should the oldest partition" do
145
+ partition = SqlPartitioner::Partition.all(adapter, 'test_events').oldest_partition
146
+
147
+ partition.name.should == 'until_2014_03_17'
148
+ partition.timestamp.should == 1395014400
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+
155
+ shared_examples_for "Partition" do
156
+ before(:each) do
157
+ @partition_manager = SqlPartitioner::BasePartitionsManager.new(
158
+ :adapter => adapter,
159
+ :current_time => Time.utc(2014,04,18),
160
+ :table_name => 'test_events',
161
+ :logger => SPEC_LOGGER
162
+ )
163
+ end
164
+ describe ".all" do
165
+ context "with no partitions" do
166
+ it "should an empty PartitionCollection" do
167
+ SqlPartitioner::Partition.all(adapter, 'test_events').should == []
168
+ end
169
+ end
170
+ context "with some partitions" do
171
+ before(:each) do
172
+ @partitions = {'until_2014_03_17' => 1395014400}
173
+ @partition_manager.initialize_partitioning(@partitions)
174
+ end
175
+
176
+ it "should return a PartitionCollection containing all the partitions" do
177
+ SqlPartitioner::Partition.all(adapter, 'test_events').map{|p| [p.name, p.timestamp]}.should == [
178
+ ['until_2014_03_17', 1395014400],
179
+ ["future", "MAXVALUE"]
180
+ ]
181
+ end
182
+ end
183
+ end
184
+
185
+ describe "#future_partition?" do
186
+ before(:each) do
187
+ @partitions = {'until_2014_03_17' => 1395014400}
188
+ @partition_manager.initialize_partitioning(@partitions)
189
+ end
190
+
191
+ it "should return true for the future partition" do
192
+ SqlPartitioner::Partition.all(adapter, 'test_events').last.future_partition?.should == true
193
+ end
194
+ it "should return false for non-future partition" do
195
+ SqlPartitioner::Partition.all(adapter, 'test_events').first.future_partition?.should == false
196
+ end
197
+ end
198
+
199
+ describe "#timestamp" do
200
+ before(:each) do
201
+ @partitions = {'until_2014_03_17' => 1395014400}
202
+ @partition_manager.initialize_partitioning(@partitions)
203
+ end
204
+
205
+ it "should return 'MAXVALUE' for the future partition" do
206
+ SqlPartitioner::Partition.all(adapter, 'test_events').last.timestamp.should == SqlPartitioner::Partition::FUTURE_PARTITION_VALUE
207
+ end
208
+ it "should return the timestamp for non-future partition" do
209
+ SqlPartitioner::Partition.all(adapter, 'test_events').first.timestamp.should == @partitions.values.last
210
+ end
211
+ end
212
+
213
+ describe "#to_log" do
214
+ before(:each) do
215
+ @partitions = {'until_2014_03_17' => 1395014400}
216
+ @partition_manager.initialize_partitioning(@partitions)
217
+ end
218
+
219
+ it "should return 'none' for no partitions" do
220
+ SqlPartitioner::Partition.to_log([]).should == 'none'
221
+ end
222
+
223
+ it "should return a pretty log message with partitions" do
224
+ log_msg = "---------------------------------------------------------------------------------------------\n" +
225
+ "ordinal_position name timestamp table_rows data_length index_length \n" +
226
+ "---------------------------------------------------------------------------------------------\n" +
227
+ "1 until_2014_03_17 1395014400 0 16384 0 \n" +
228
+ "2 future MAXVALUE 0 16384 0 \n" +
229
+ "---------------------------------------------------------------------------------------------"
230
+
231
+ SqlPartitioner::Partition.to_log(SqlPartitioner::Partition.all(adapter, 'test_events')).should == log_msg
232
+ end
233
+ end
234
+
235
+ end
236
+
237
+
238
+ describe "PartitionCollection with ARAdapter" do
239
+ it_should_behave_like "PartitionCollection" do
240
+ let(:adapter) do
241
+ SqlPartitioner::ARAdapter.new(ActiveRecord::Base.connection)
242
+ end
243
+ end
244
+ end
245
+
246
+ describe "Partition with ARAdapter" do
247
+ it_should_behave_like "Partition" do
248
+ let(:adapter) do
249
+ SqlPartitioner::ARAdapter.new(ActiveRecord::Base.connection)
250
+ end
251
+ end
252
+ end
253
+
254
+ describe "PartitionCollection with DMAdapter" do
255
+ it_should_behave_like "PartitionCollection" do
256
+ let(:adapter) do
257
+ SqlPartitioner::DMAdapter.new(DataMapper.repository.adapter)
258
+ end
259
+ end
260
+ end
261
+
262
+ describe "Partition with DMAdapter" do
263
+ it_should_behave_like "Partition" do
264
+ let(:adapter) do
265
+ SqlPartitioner::DMAdapter.new(DataMapper.repository.adapter)
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,275 @@
1
+ require File.expand_path("../spec_helper", File.dirname(__FILE__))
2
+
3
+ shared_examples_for "PartitionsManager with an Adapter" do
4
+ describe "#initialize_partitioning_in_intervals" do
5
+ before(:each) do
6
+ @partition_manager = SqlPartitioner::PartitionsManager.new(
7
+ :adapter => adapter,
8
+ :current_time => Time.utc(2014,04,18),
9
+ :table_name => 'test_events',
10
+ :logger => SPEC_LOGGER
11
+ )
12
+ end
13
+ it "should initialize the database table as requested" do
14
+ days_into_future = 50
15
+
16
+ @partition_manager.initialize_partitioning_in_intervals(days_into_future)
17
+
18
+ SqlPartitioner::Partition.all(adapter, 'test_events').map{|p| [p.name, p.timestamp]}.should == [
19
+ ["until_2014_05_18", Time.utc(2014,05,18).to_i],
20
+ ["until_2014_06_18", Time.utc(2014,06,18).to_i],
21
+ ["future", "MAXVALUE"]
22
+ ]
23
+ end
24
+ end
25
+ describe "#append_partition_intervals" do
26
+ before(:each) do
27
+ @partition_manager = SqlPartitioner::PartitionsManager.new(
28
+ :adapter => adapter,
29
+ :current_time => Time.utc(2014,04,18),
30
+ :table_name => 'test_events',
31
+ :logger => SPEC_LOGGER
32
+ )
33
+ end
34
+ context "with an unpartitioned database table" do
35
+ it "should raise a RuntimeError" do
36
+ lambda{
37
+ @partition_manager.append_partition_intervals(:months, 1, days_into_future = 30, dry_run = false)
38
+ }.should raise_error(RuntimeError, /initialized/)
39
+ end
40
+ end
41
+ context "with a partitioned database table" do
42
+ context "and only the future partition exists" do
43
+ before(:each) do
44
+ @partition_manager.initialize_partitioning({})
45
+ end
46
+ it "should raise a RuntimeError" do
47
+ lambda{
48
+ @partition_manager.append_partition_intervals(:months, 1, days_into_future = 30, dry_run = false)
49
+ }.should raise_error(RuntimeError, /initialized/)
50
+ end
51
+ end
52
+ context "and the future partition as well as other partitions exist" do
53
+ context "and all requested partitions already exist" do
54
+ before(:each) do
55
+ @partition_manager.initialize_partitioning({'until_2014_05_18' => Time.utc(2014,05,18).to_i})
56
+ end
57
+ it "should log and do nothing" do
58
+ expect(@partition_manager.append_partition_intervals(:months, 1, days_into_future = 30, dry_run = false)).to eq({})
59
+ end
60
+ end
61
+ context "and not all of the requested partitions exist yet" do
62
+ before(:each) do
63
+ @partition_manager.initialize_partitioning({'until_2014_05_18' => Time.utc(2014,05,18).to_i})
64
+ end
65
+ it "should log and do nothing" do
66
+ expect(@partition_manager.append_partition_intervals(:months, 1, days_into_future = 60, dry_run = false)).to eq({
67
+ 'until_2014_06_18' => Time.utc(2014,06,18).to_i
68
+ })
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ describe "#drop_partitions_older_than_in_days" do
75
+ before(:each) do
76
+ @partition_manager = SqlPartitioner::PartitionsManager.new(
77
+ :adapter => adapter,
78
+ :current_time => Time.utc(2014,04,18),
79
+ :table_name => 'test_events',
80
+ :logger => SPEC_LOGGER
81
+ )
82
+ end
83
+ it "should drop the requested partition" do
84
+ @partition_manager.initialize_partitioning({
85
+ 'until_2014_02_18' => Time.utc(2014,02,18).to_i,
86
+ 'until_2014_03_18' => Time.utc(2014,03,18).to_i,
87
+ 'until_2014_04_18' => Time.utc(2014,04,18).to_i
88
+ })
89
+ @partition_manager.drop_partitions_older_than_in_days(days_from_now = 40)
90
+
91
+ SqlPartitioner::Partition.all(adapter, 'test_events').map{|p| [p.name, p.timestamp]}.should == [
92
+ ["until_2014_03_18", Time.utc(2014,03,18).to_i],
93
+ ["until_2014_04_18", Time.utc(2014,04,18).to_i],
94
+ ["future", "MAXVALUE"]
95
+ ]
96
+ end
97
+ end
98
+
99
+ describe "#drop_partitions_older_than" do
100
+ before(:each) do
101
+ @partition_manager = SqlPartitioner::PartitionsManager.new(
102
+ :adapter => adapter,
103
+ :current_time => Time.utc(2014,04,18),
104
+ :table_name => 'test_events',
105
+ :logger => SPEC_LOGGER
106
+ )
107
+ end
108
+ context "with no partition requested to be dropped" do
109
+ before(:each) do
110
+ @partition_manager.initialize_partitioning({
111
+ 'until_2014_03_18' => Time.utc(2014,03,18).to_i,
112
+ 'until_2014_04_18' => Time.utc(2014,04,18).to_i
113
+ })
114
+ end
115
+ it "should not drop anything" do
116
+ expect(@partition_manager.drop_partitions_older_than(Time.utc(2014,03,18).to_i)).to eq []
117
+ end
118
+ end
119
+ context "with one partition requested to be dropped" do
120
+ before(:each) do
121
+ @partition_manager.initialize_partitioning({
122
+ 'until_2014_03_18' => Time.utc(2014,03,18).to_i,
123
+ 'until_2014_04_18' => Time.utc(2014,04,18).to_i
124
+ })
125
+ end
126
+ it "should drop the requeuest partition to be dropped" do
127
+ expect(@partition_manager.drop_partitions_older_than(Time.utc(2014,04,18).to_i)).to eq [
128
+ 'until_2014_03_18'
129
+ ]
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ describe "PartitionsManager with ARAdapter" do
136
+ it_should_behave_like "PartitionsManager with an Adapter" do
137
+ let(:adapter) do
138
+ SqlPartitioner::ARAdapter.new(ActiveRecord::Base.connection)
139
+ end
140
+ end
141
+ end
142
+
143
+ describe "PartitionsManager with DMAdapter" do
144
+ it_should_behave_like "PartitionsManager with an Adapter" do
145
+ let(:adapter) do
146
+ SqlPartitioner::DMAdapter.new(DataMapper.repository.adapter)
147
+ end
148
+ end
149
+ end
150
+
151
+ describe "PartitionsManager" do
152
+ before(:each) do
153
+ @adapter = Struct.new(:schema_name).new("sql_partitioner_test")
154
+
155
+ @partition_manager = SqlPartitioner::PartitionsManager.new(
156
+ :adapter => @adapter,
157
+ :current_time => Time.utc(2014,01,01),
158
+ :table_name => 'test_events',
159
+ :logger => SPEC_LOGGER
160
+ )
161
+ end
162
+
163
+ describe "#partitions_to_append" do
164
+ it "should return the partitions to create" do
165
+ partition_start_timestamp = Time.utc(2013,12,01).to_i
166
+ partition_size = 2
167
+ days_into_future = 32
168
+
169
+ expect(@partition_manager.partitions_to_append(partition_start_timestamp, :months, partition_size, days_into_future)).to eq({
170
+ "until_2014_02_01"=>Time.utc(2014,02,01).to_i,
171
+ "until_2014_04_01"=>Time.utc(2014,04,01).to_i
172
+ })
173
+ end
174
+ end
175
+
176
+ describe "#partitions_to_append_by_ts_range" do
177
+ context "with end_timestamp == partition_start_timestamp" do
178
+ before(:each) do
179
+ @start_ts = Time.utc(2014,01,01).to_i
180
+ @end_ts = Time.utc(2014,01,01).to_i
181
+ end
182
+ it "should create no partitions" do
183
+ expect(@partition_manager.partitions_to_append_by_ts_range(@start_ts, @end_ts, :months, 1)).to eq({})
184
+ end
185
+ end
186
+ context "with end_timestamp - partition_start_timestamp < partition_size_unit * partition_size" do
187
+ before(:each) do
188
+ @start_ts = Time.utc(2014,01,01).to_i
189
+ @end_ts = Time.utc(2014,01,02).to_i
190
+ end
191
+ it "should create 1 partition" do
192
+ expect(@partition_manager.partitions_to_append_by_ts_range(@start_ts, @end_ts, :months, 1)).to eq({
193
+ "until_2014_02_01"=>Time.utc(2014,02,01).to_i
194
+ }
195
+ )
196
+ end
197
+ end
198
+ context "with end_timestamp - partition_start_timestamp == partition_size_unit * partition_size" do
199
+ before(:each) do
200
+ @start_ts = Time.utc(2014,01,01).to_i
201
+ @end_ts = Time.utc(2014,02,01).to_i
202
+ end
203
+ it "should create 1 partition to cover it" do
204
+ expect(@partition_manager.partitions_to_append_by_ts_range(@start_ts, @end_ts, :months, 1)).to eq({
205
+ "until_2014_02_01"=>Time.utc(2014,02,01).to_i
206
+ }
207
+ )
208
+ end
209
+ end
210
+ context "with end_timestamp - partition_start_timestamp > partition_size_unit * partition_size" do
211
+ before(:each) do
212
+ @start_ts = Time.utc(2014,01,01).to_i
213
+ @end_ts = Time.utc(2014,03,01).to_i
214
+ end
215
+ context "with one months partition size" do
216
+ it "should create two partitions to cover two months in the future from start_ts" do
217
+ expect(@partition_manager.partitions_to_append_by_ts_range(@start_ts, @end_ts, :months, 1)).to eq({
218
+ "until_2014_02_01"=>Time.utc(2014,02,01).to_i,
219
+ "until_2014_03_01"=>Time.utc(2014,03,01).to_i
220
+ }
221
+ )
222
+ end
223
+ end
224
+ context "with two months partition size" do
225
+ it "should create one partition to cover two months in the future from start_ts" do
226
+ expect(@partition_manager.partitions_to_append_by_ts_range(@start_ts, @end_ts, :months, 2)).to eq({
227
+ "until_2014_03_01"=>Time.utc(2014,03,01).to_i
228
+ }
229
+ )
230
+ end
231
+ end
232
+ context "with 20 day partition size" do
233
+ it "should create three partitions to cover two months in the future from start_ts" do
234
+ expect(@partition_manager.partitions_to_append_by_ts_range(@start_ts, @end_ts, :days, 20)).to eq({
235
+ "until_2014_01_21" => Time.utc(2014,01,21).to_i,
236
+ "until_2014_02_10" => Time.utc(2014,02,10).to_i,
237
+ "until_2014_03_02" => Time.utc(2014,03,02).to_i
238
+ }
239
+ )
240
+ end
241
+ end
242
+ end
243
+ context "with end_timestamp < partition_start_timestamp" do
244
+ before(:each) do
245
+ @start_ts = Time.utc(2014,02,01).to_i
246
+ @end_ts = Time.utc(2014,01,01).to_i
247
+ end
248
+ it "should create no partitions" do
249
+ expect(@partition_manager.partitions_to_append_by_ts_range(@start_ts, @end_ts, :months, 1)).to eq({})
250
+ end
251
+ end
252
+ context "with invalid parameters" do
253
+ it "should raise an Argument error with a start_ts < 0" do
254
+ lambda do
255
+ expect(@partition_manager.partitions_to_append_by_ts_range(start_ts = -1, end_ts = 1, :months, 1)).to eq({})
256
+ end.should raise_error(ArgumentError, /should be > 0/)
257
+ end
258
+ it "should raise an Argument error with a end_ts < 0" do
259
+ lambda do
260
+ expect(@partition_manager.partitions_to_append_by_ts_range(start_ts = 1, end_ts = -1, :months, 1)).to eq({})
261
+ end.should raise_error(ArgumentError, /should be > 0/)
262
+ end
263
+ it "should raise an Argument error with an invalid partition_size_unit" do
264
+ lambda do
265
+ expect(@partition_manager.partitions_to_append_by_ts_range(start_ts = 1, end_ts = 1, :potatoes, 1)).to eq({})
266
+ end.should raise_error(ArgumentError, /partition_size_unit must be one of/)
267
+ end
268
+ it "should raise an Argument error with an invalid partition_size" do
269
+ lambda do
270
+ expect(@partition_manager.partitions_to_append_by_ts_range(start_ts = 1, end_ts = 1, :months, -1)).to eq({})
271
+ end.should raise_error(ArgumentError, /should be > 0/)
272
+ end
273
+ end
274
+ end
275
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path("../spec_helper", File.dirname(__FILE__))
2
+
3
+ describe "SqlHelper" do
4
+ before(:each) do
5
+ @table_name = 'my_table'
6
+ end
7
+ describe ".drop_partitions" do
8
+ it "should return nil when no partition_names are passed" do
9
+ SqlPartitioner::SQL.drop_partitions(@table_name, []).should == nil
10
+ end
11
+ end
12
+
13
+ describe ".reorg_partitions" do
14
+ it "should return nil when no partition_names are passed" do
15
+ SqlPartitioner::SQL.reorg_partitions(@table_name, [], "future").should == nil
16
+ end
17
+ end
18
+
19
+ describe ".create_partition" do
20
+ it "should return something" do
21
+ SqlPartitioner::SQL.create_partition(@table_name, "until_2014_03_17", "future").should_not be_empty
22
+ end
23
+ end
24
+
25
+ describe ".sort_partition_data" do
26
+ before(:each) do
27
+ @partition_data = {
28
+ 'until_2014_04_17' => 1397692800,
29
+ SqlPartitioner::BasePartitionsManager::FUTURE_PARTITION_NAME =>
30
+ SqlPartitioner::BasePartitionsManager::FUTURE_PARTITION_VALUE,
31
+ 'until_2014_03_17' => 1395014400,
32
+ }
33
+ end
34
+ it "should sort into an array by timestamp (key) with the 'future' partition at the end" do
35
+ SqlPartitioner::SQL.sort_partition_data(@partition_data).should == [
36
+ ['until_2014_03_17', 1395014400],
37
+ ['until_2014_04_17', 1397692800],
38
+ [SqlPartitioner::BasePartitionsManager::FUTURE_PARTITION_NAME,
39
+ SqlPartitioner::BasePartitionsManager::FUTURE_PARTITION_VALUE],
40
+ ]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,91 @@
1
+ require File.expand_path("../spec_helper", File.dirname(__FILE__))
2
+
3
+ describe "TimeUnitConverter" do
4
+ describe "#initialize" do
5
+ it "should initalize a new TimeUnitConverter with a supported time unit" do
6
+ SqlPartitioner::TimeUnitConverter.new(SqlPartitioner::TimeUnitConverter::SUPPORTED_TIME_UNITS.first)
7
+ end
8
+ it "should raise an ArgumentError with with a unsupported time unit" do
9
+ lambda{ SqlPartitioner::TimeUnitConverter.new(:potatoes) }.should raise_error(ArgumentError)
10
+ end
11
+ end
12
+
13
+ describe "#to_date_time" do
14
+ before(:each) do
15
+ @tuc = SqlPartitioner::TimeUnitConverter.new(:seconds)
16
+ end
17
+ it "should return a DateTime object" do
18
+ timestamp = Time.utc(2014,01,15).to_i
19
+ @tuc.to_date_time(timestamp).to_s.should == "2014-01-15T00:00:00+00:00"
20
+ end
21
+ end
22
+ describe "#from_seconds" do
23
+ it "should return a timestamp in the configured time unit" do
24
+ timestamp_in_secs = Time.utc(2014,01,15).to_i
25
+
26
+ tum = SqlPartitioner::TimeUnitConverter.new(:micro_seconds)
27
+ tum.from_seconds(timestamp_in_secs).should == timestamp_in_secs * 1_000_000
28
+
29
+ tum = SqlPartitioner::TimeUnitConverter.new(:seconds)
30
+ tum.from_seconds(timestamp_in_secs).should == timestamp_in_secs
31
+ end
32
+ end
33
+
34
+ describe "#to_seconds" do
35
+ it "should return a timestamp in the configured time unit" do
36
+ timestamp_in_secs = Time.utc(2014,01,15).to_i
37
+
38
+ tum = SqlPartitioner::TimeUnitConverter.new(:micro_seconds)
39
+ tum.to_seconds(timestamp_in_secs * 1_000_000).should == timestamp_in_secs
40
+
41
+ tum = SqlPartitioner::TimeUnitConverter.new(:seconds)
42
+ tum.to_seconds(timestamp_in_secs).should == timestamp_in_secs
43
+ end
44
+ end
45
+
46
+ describe "#advance_date_time" do
47
+ before(:each) do
48
+ @date_time = DateTime.new(2014,01,31)
49
+ end
50
+ context "using days" do
51
+ before(:each) do
52
+ @calendar_unit = :days
53
+ end
54
+ it "should return the correct DateTime when adding" do
55
+ SqlPartitioner::TimeUnitConverter.advance_date_time(@date_time, @calendar_unit, days = 2).to_s.should == "2014-02-02T00:00:00+00:00"
56
+ end
57
+ it "should return the correct DateTime when subtracting" do
58
+ SqlPartitioner::TimeUnitConverter.advance_date_time(@date_time, @calendar_unit, days = -2).to_s.should == "2014-01-29T00:00:00+00:00"
59
+ end
60
+ end
61
+ context "using months" do
62
+ before(:each) do
63
+ @calendar_unit = :months
64
+ end
65
+ it "should return the correct DateTime when adding" do
66
+ SqlPartitioner::TimeUnitConverter.advance_date_time(@date_time, @calendar_unit, months = 2).to_s.should == "2014-03-31T00:00:00+00:00"
67
+ end
68
+ it "should return the correct DateTime when subtracting" do
69
+ SqlPartitioner::TimeUnitConverter.advance_date_time(@date_time, @calendar_unit, months = -2).to_s.should == "2013-11-30T00:00:00+00:00"
70
+ end
71
+ end
72
+ end
73
+
74
+ describe ".time_units_per_second" do
75
+ it "should return the proper seconds multiplier to get the specified time unit" do
76
+ SqlPartitioner::TimeUnitConverter.time_units_per_second(:micro_seconds).should == 1_000_000
77
+ SqlPartitioner::TimeUnitConverter.time_units_per_second(:seconds).should == 1
78
+ end
79
+ it "all SUPPORTED_TIME_UNITS accounted for" do
80
+ SqlPartitioner::TimeUnitConverter::SUPPORTED_TIME_UNITS.each do |u|
81
+ SqlPartitioner::TimeUnitConverter.time_units_per_second(u).should be_a(Fixnum)
82
+ end
83
+ end
84
+ it "unknown time unit should raise an error" do
85
+ lambda {
86
+ SqlPartitioner::TimeUnitConverter.time_units_per_second(:bogus)
87
+ }.should raise_error(RuntimeError, /unknown time_unit :bogus/)
88
+ end
89
+ end
90
+
91
+ end