-
Notifications
You must be signed in to change notification settings - Fork 167
/
bitcask_timeshift.erl
92 lines (80 loc) · 2.98 KB
/
bitcask_timeshift.erl
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
%% -------------------------------------------------------------------
%%
%% bitcask: Eric Brewer-inspired key/value store
%%
%% Copyright (c) 2012 Basho Technologies, Inc. All Rights Reserved.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
%% except in compliance with the License. You may obtain
%% a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing,
%% software distributed under the License is distributed on an
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%% KIND, either express or implied. See the License for the
%% specific language governing permissions and limitations
%% under the License.
%%
%% -------------------------------------------------------------------
-module(bitcask_timeshift).
-include_lib("eunit/include/eunit.hrl").
-include("bitcask.hrl").
-compile(export_all).
current_tstamp() ->
case erlang:get(meck_tstamp) of
undefined ->
erlang:error(uninitialized_meck_tstamp);
Value ->
Value
end.
next_tstamp() ->
Ts = case erlang:get(meck_tstamp) of
undefined ->
1;
Tstamp ->
Tstamp + erlang:get(meck_tstamp_step)
end,
erlang:put(meck_tstamp, Ts),
Ts.
set_tstamp(Tstamp) ->
erlang:put(meck_tstamp, Tstamp).
set_tstamp_step(Step) ->
erlang:put(meck_tstamp_step, Step).
timeshift_test() ->
{timeout, 60, fun() -> timeshift_test2() end}.
timeshift_test2() ->
try
Dirname = "/tmp/bc.timeshift",
meck:new(bitcask_time, [passthrough]),
meck:expect(bitcask_time, tstamp, fun next_tstamp/0),
set_tstamp(100),
set_tstamp_step(-1),
?cmd("rm -rf " ++ Dirname),
Bref = bitcask:open(Dirname, [read_write]),
ok = bitcask:put(Bref, <<"k1">>, <<"v1">>),
%% Back when the NIF's internal puts depended on timestamps, this
%% second put would fail because we've meck'ed time to go backward.
%% Nowadays, this put should succeed.
ok = bitcask:put(Bref, <<"k1">>, <<"v2">>),
bitcask:close(Bref),
%% For each of the data files, validate that it has a valid hint file
Validate = fun(Fname) ->
{ok, S} = bitcask_fileops:open_file(Fname),
try
?assert(bitcask_fileops:has_valid_hintfile(S))
after
bitcask_fileops:close(S)
end
end,
[Validate(Fname) || {_Ts, Fname} <-
bitcask_fileops:data_file_tstamps(Dirname)],
%% In our post-wall-clock timestamp world, verify that we read the newer value.
Bref2 = bitcask:open(Dirname, [read_write]),
{ok, <<"v2">>} = bitcask:get(Bref2, <<"k1">>),
bitcask:close(Bref2)
after
meck:unload()
end.