@@ -4,6 +4,8 @@ use kvproto::kvrpcpb::Context;
4
4
5
5
use engine:: IterOption ;
6
6
use engine:: { CfName , CF_DEFAULT } ;
7
+ use std:: thread;
8
+ use std:: time;
7
9
use test_raftstore:: * ;
8
10
use tikv:: storage:: kv:: * ;
9
11
use tikv:: storage:: { CFStatistics , Key } ;
@@ -123,6 +125,66 @@ fn test_read_index_on_replica() {
123
125
) ;
124
126
}
125
127
128
+ #[ test]
129
+ fn test_read_on_replica ( ) {
130
+ let count = 3 ;
131
+ let mut cluster = new_server_cluster ( 0 , count) ;
132
+ cluster. run ( ) ;
133
+
134
+ let k1 = b"k1" ;
135
+ let ( k2, v2) = ( b"k2" , b"v2" ) ;
136
+ let ( k3, v3) = ( b"k3" , b"v3" ) ;
137
+ let ( k4, v4) = ( b"k4" , b"v4" ) ;
138
+
139
+ // make sure leader has been elected.
140
+ assert_eq ! ( cluster. must_get( k1) , None ) ;
141
+
142
+ let region = cluster. get_region ( b"" ) ;
143
+ let leader = cluster. leader_of_region ( region. get_id ( ) ) . unwrap ( ) ;
144
+ let leader_storage = cluster. sim . rl ( ) . storages [ & leader. get_id ( ) ] . clone ( ) ;
145
+
146
+ let mut leader_ctx = Context :: new ( ) ;
147
+ leader_ctx. set_region_id ( region. get_id ( ) ) ;
148
+ leader_ctx. set_region_epoch ( region. get_region_epoch ( ) . clone ( ) ) ;
149
+ leader_ctx. set_peer ( leader. clone ( ) ) ;
150
+
151
+ // write some data
152
+ let peers = region. get_peers ( ) ;
153
+ assert_none ( & leader_ctx, & leader_storage, k2) ;
154
+ must_put ( & leader_ctx, & leader_storage, k2, v2) ;
155
+
156
+ // read on follower
157
+ let mut follower_peer = None ;
158
+ let mut follower_id = 0 ;
159
+ for p in peers {
160
+ if p. get_id ( ) != leader. get_id ( ) {
161
+ follower_id = p. get_id ( ) ;
162
+ follower_peer = Some ( p. clone ( ) ) ;
163
+ break ;
164
+ }
165
+ }
166
+
167
+ assert ! ( follower_peer. is_some( ) ) ;
168
+ let mut follower_ctx = Context :: new ( ) ;
169
+ follower_ctx. set_region_id ( region. get_id ( ) ) ;
170
+ follower_ctx. set_region_epoch ( region. get_region_epoch ( ) . clone ( ) ) ;
171
+ follower_ctx. set_peer ( follower_peer. as_ref ( ) . unwrap ( ) . clone ( ) ) ;
172
+ follower_ctx. set_follower_read ( true ) ;
173
+ let follower_storage = cluster. sim . rl ( ) . storages [ & follower_id] . clone ( ) ;
174
+ assert_has ( & follower_ctx, & follower_storage, k2, v2) ;
175
+
176
+ must_put ( & leader_ctx, & leader_storage, k3, v3) ;
177
+ assert_has ( & follower_ctx, & follower_storage, k3, v3) ;
178
+
179
+ cluster. stop_node ( follower_id) ;
180
+ must_put ( & leader_ctx, & leader_storage, k4, v4) ;
181
+ cluster. run_node ( follower_id) . unwrap ( ) ;
182
+ let follower_storage = cluster. sim . rl ( ) . storages [ & follower_id] . clone ( ) ;
183
+ // sleep to ensure the follower has received a heartbeat from the leader
184
+ thread:: sleep ( time:: Duration :: from_millis ( 300 ) ) ;
185
+ assert_has ( & follower_ctx, & follower_storage, k4, v4) ;
186
+ }
187
+
126
188
fn must_put < E : Engine > ( ctx : & Context , engine : & E , key : & [ u8 ] , value : & [ u8 ] ) {
127
189
engine. put ( ctx, Key :: from_raw ( key) , value. to_vec ( ) ) . unwrap ( ) ;
128
190
}
0 commit comments