11local  fio  =  require (' fio'  )
22local  t  =  require (' luatest'  )
3- local  g_auto  =  t .group (' integration.vshard_storage_disabling.auto'  )
4- local  g_default  =  t .group (' integration.vshard_storage_disabling.default'  )
3+ local  g  =  t .group ()
54
65local  helpers  =  require (' test.helper'  )
76
7+ 
8+ local  function  initialize_functions (srv )
9+     return  srv :exec (function ()
10+         local  confapplier  =  require (' cartridge.confapplier'  )
11+         local  function  get (...)
12+             if  confapplier .get_state () ==  ' OperationError'  then 
13+                 error (' Invalid state'  )
14+             end 
15+             return  box .space .test :get (... )
16+         end 
17+         local  function  put (...)
18+             if  confapplier .get_state () ==  ' OperationError'  then 
19+                 error (' Invalid state'  )
20+             end 
21+             return  box .space .test :put (... )
22+         end 
23+         rawset (_G , ' get'  , get )
24+         rawset (_G , ' put'  , put )
25+     end )
26+ end 
27+ 
828local  function  setup_replica_backoff_interval (srv )
929    srv :exec (function ()
1030        require (' vshard.consts'  ).REPLICA_BACKOFF_INTERVAL  =  0.1 
1131    end )
1232end 
13- local  function  setup_cluster (g , auto_disable )
33+ 
34+ g .before_all  =  function ()
1435    t .skip_if (not  helpers .tarantool_version_ge (' 1.10.1'  ))
1536    g .cluster  =  helpers .Cluster :new ({
1637        datadir  =  fio .tempdir (),
1738        server_command  =  helpers .entrypoint (' srv_basic'  ),
18-         cookie  =  helpers . random_cookie () ,
39+         cookie  =  ' cookie '  ,
1940        use_vshard  =  true ,
2041        replicasets  =  {{
2142            alias  =  ' router'  ,
@@ -33,16 +54,38 @@ local function setup_cluster(g, auto_disable)
3354        }},
3455        env  =  {
3556            TARANTOOL_BUCKET_COUNT  =  300 ,
36-             TARANTOOL_AUTO_DISABLE_VSHARD_STORAGE  =  tostring (auto_disable ),
3757        }
3858    })
3959    g .cluster :start ()
4060    g .router  =  g .cluster :server (' router-1'  )
4161    g .storage_master  =  g .cluster :server (' storage-1'  )
4262    g .storage_replica  =  g .cluster :server (' storage-2'  )
4363
64+     local  test_schema  =  {
65+         engine  =  ' memtx'  ,
66+         is_local  =  false ,
67+         temporary  =  false ,
68+         format  =  {
69+             {name  =  ' bucket_id'  , type  =  ' unsigned'  , is_nullable  =  false },
70+             {name  =  ' record_id'  , type  =  ' unsigned'  , is_nullable  =  false },
71+         },
72+         indexes  =  {{
73+             name  =  ' pk'  , type  =  ' TREE'  , unique  =  true ,
74+             parts  =  {{path  =  ' record_id'  , is_nullable  =  false , type  =  ' unsigned'  }},
75+         },  {
76+             name  =  ' bucket_id'  , type  =  ' TREE'  , unique  =  false ,
77+             parts  =  {{path  =  ' bucket_id'  , is_nullable  =  false , type  =  ' unsigned'  }},
78+         }},
79+         sharding_key  =  {' record_id'  },
80+     }
81+     g .cluster .main_server :call (' cartridge_set_schema'  ,
82+         {require (' yaml'  ).encode ({spaces  =  {test  =  test_schema }})}
83+     )
84+ 
4485    g .cluster :wait_until_healthy ()
4586
87+     initialize_functions (g .storage_master )
88+     initialize_functions (g .storage_replica )
4689    --  Just to speedup tests
4790    setup_replica_backoff_interval (g .router )
4891
@@ -56,6 +99,17 @@ local function setup_cluster(g, auto_disable)
5699    end )
57100end 
58101
102+ g .after_all  =  function ()
103+     g .cluster :stop ()
104+     fio .rmtree (g .cluster .datadir )
105+ end 
106+ 
107+ g .after_each  =  function ()
108+     g .storage_master :exec (function ()
109+         box .space .test :truncate ()
110+     end )
111+ end 
112+ 
59113local  function  inject_operation_error (srv )
60114    helpers .run_remotely (srv , function ()
61115        local  myrole  =  package.loaded [' mymodule'  ]
@@ -73,127 +127,161 @@ local function dismiss_operation_error(srv)
73127    end )
74128end 
75129
130+ local  function  get_state (srv )
131+     return  srv :eval (' return require("cartridge.confapplier").get_state()'  )
132+ end 
133+ 
134+ local  function  get (srv , i )
135+     return  srv :eval (
136+         ' return require("vshard").router.callro(...)'  ,
137+         {i , ' get'  , {i }}
138+     )
139+ end 
140+ 
141+ local  function  put (srv , i )
142+     return  srv :eval (' return require("vshard").router.callrw(...)'  ,
143+         {i , ' put'  , {{i , i , string.format (' i%04d'  , i )}}}
144+     )
145+ end 
146+ 
76147local  function  apply_config (srv )
77-     return  srv :exec (function ()
78-         return  require (" cartridge"  ).config_patch_clusterwide ({uuid  =  require (" uuid"  ).str ()})
79-     end )
148+     return  srv :eval (' return require("cartridge").config_patch_clusterwide({uuid = require("uuid").str()})'  )
80149end 
81150
82- for  _ , case  in  pairs ({{g_auto , true }, {g_default , false }}) do 
83-     local  g , auto_disable  =  case [1 ], case [2 ]
84- 
85-     local  function  set_failover (mode )
86-         local  response  =  g .cluster .main_server :graphql ({
87-             query  =  [[ 
88-                 mutation($mode: String) { 
89-                     cluster { 
90-                         failover_params( 
91-                             mode: $mode 
92-                         ) { 
93-                             mode 
94-                         } 
95-                     } 
96-                 } 
97-             ]]  ,
98-             variables  =  { mode  =  mode  },
99-             raise  =  false ,
100-         })
101-         if  response .errors  then 
102-             error (response .errors [1 ].message , 2 )
103-         end 
151+ function  g .test_vshard_storage_disable ()
152+     --  Read/write data from/to healthy cluster
153+     t .assert_equals (put (g .router , 1 ), {1 , 1 , ' i0001'  })
154+     t .assert_equals (get (g .router , 1 ), {1 , 1 , ' i0001'  })
155+ 
156+     --  Break master instance
157+     inject_operation_error (g .storage_master )
158+     apply_config (g .router )
159+     t .assert_equals (get_state (g .storage_master ), ' OperationError'  )
160+     t .assert_equals (get_state (g .storage_replica ), ' RolesConfigured'  )
161+ 
162+     for  _  =  1 , 1000  do 
163+         t .assert_equals (get (g .router , 1 ), {1 , 1 , ' i0001'  })
104164    end 
105165
106-     g .before_all  =  function ()
107-         setup_cluster (g , auto_disable )
166+     local  data , err  =  put (g .router , 2 )
167+     t .assert_equals (data , box .NULL )
168+     t .assert_equals (err .message , ' Storage is disabled: storage is disabled explicitly'  )
169+ 
170+     --  Fix master state
171+     dismiss_operation_error (g .storage_master )
172+     apply_config (g .router )
173+     t .assert_not_equals (get_state (g .storage_master ), ' OperationError'  )
174+     t .assert_not_equals (get_state (g .storage_replica ), ' OperationError'  )
175+ 
176+     t .assert_equals (put (g .router , 2 ), {2 , 2 , ' i0002'  })
177+     for  _  =  1 , 1000  do 
178+         t .assert_equals (get (g .router , 2 ), {2 , 2 , ' i0002'  })
108179    end 
109180
110-     g .after_all  =  function ()
111-         g .cluster :stop ()
112-         fio .rmtree (g .cluster .datadir )
181+     --  Break replica instance
182+     inject_operation_error (g .storage_replica )
183+     apply_config (g .router )
184+     t .assert_not_equals (get_state (g .storage_master ), ' OperationError'  )
185+     t .assert_equals (get_state (g .storage_replica ), ' OperationError'  )
186+ 
187+     t .assert_equals (put (g .router , 3 ), {3 , 3 , ' i0003'  })
188+     for  _  =  1 , 1000  do 
189+         t .assert_equals (get (g .router , 3 ), {3 , 3 , ' i0003'  })
113190    end 
114191
115-     g .before_test (' test_disabled_on_failover'  , function ()
116-         set_failover (' eventual'  )
117-     end )
192+     --  Fix replica state
193+     dismiss_operation_error (g .storage_replica )
194+     apply_config (g .router )
195+     t .assert_not_equals (get_state (g .storage_master ), ' OperationError'  )
196+     t .assert_not_equals (get_state (g .storage_replica ), ' OperationError'  )
118197
119-     function  g .test_disabled_on_failover ()
120-         --  Break replica instance
121-         inject_operation_error (g .storage_replica )
198+     t .assert_equals (put (g .router , 4 ), {4 , 4 , ' i0004'  })
199+     for  _  =  1 , 1000  do 
200+         t .assert_equals (get (g .router , 4 ), {4 , 4 , ' i0004'  })
201+     end 
202+ end 
122203
123-         g .storage_master :stop ()
204+ local  function  set_failover (mode )
205+     local  response  =  g .cluster .main_server :graphql ({
206+         query  =  [[ 
207+             mutation($mode: String) { 
208+                 cluster { 
209+                     failover_params( 
210+                         mode: $mode 
211+                     ) { 
212+                         mode 
213+                     } 
214+                 } 
215+             } 
216+         ]]  ,
217+         variables  =  { mode  =  mode  },
218+         raise  =  false ,
219+     })
220+     if  response .errors  then 
221+         error (response .errors [1 ].message , 2 )
222+     end 
223+ end 
124224
125-         helpers .retrying ({timeout  =  30 }, function ()
126-             g .storage_replica :exec (function ()
127-                 assert (box .info .ro  ==  false )
128-             end )
129-         end )
225+ function  g .test_vshard_storage_disable_on_failover ()
226+     set_failover (' eventual'  )
227+ 
228+     --  Read/write data from/to healthy cluster
229+     t .assert_equals (put (g .router , 1 ), {1 , 1 , ' i0001'  })
230+     t .assert_equals (get (g .router , 1 ), {1 , 1 , ' i0001'  })
231+ 
232+     --  Break replica instance
233+     inject_operation_error (g .storage_replica )
234+ 
235+     g .storage_master :stop ()
130236
131-          local   res   =   g . storage_replica : exec ( function ()
132-              local   cartridge   =   require ( ' cartridge '  )
133-             return   cartridge . service_get ( ' myrole ' ). was_vshard_enabled_on_apply ( )
237+     helpers . retrying ({ timeout   =   30 },  function ()
238+         g . storage_replica : exec ( function ( )
239+             assert ( box . info . ro   ==   false )
134240        end )
135-         if  auto_disable  then 
136-             for  _ , v  in  ipairs (res ) do 
137-                 t .assert_not (v )
138-             end 
139-         else 
140-             local  res  =  g .storage_replica :exec (function ()
141-                 local  vshard  =  rawget (_G , ' vshard'  )
142-                 return  vshard .storage .internal .is_enabled 
143-             end )
144-             t .assert_not (res )
145-         end 
146-     end 
241+     end )
147242
148-     g .after_test (' test_disabled_on_failover'  , function  ()
149-         g .storage_master :start ()
150-         g .cluster :wait_until_healthy ()
151-         dismiss_operation_error (g .storage_replica )
152-         set_failover (' disabled'  )
243+     helpers .retrying ({}, function ()
244+         local  data , err  =  put (g .router , 2 )
245+         t .assert_equals (data , box .NULL )
246+         t .assert_equals (err .message , ' Storage is disabled: storage is disabled explicitly'  )
153247    end )
154248
155-     function   g . test_disabled_on_apply_config ()
156-          inject_operation_error ( g . storage_replica )
157-          apply_config (g .router )
249+     g . storage_master : start ()
250+     g . cluster : wait_until_healthy ( )
251+     initialize_functions (g .storage_master )
158252
159-         local  res  =  g .storage_replica :exec (function ()
160-             local  cartridge  =  require (' cartridge'  )
161-             return  cartridge .service_get (' myrole'  ).was_vshard_enabled_on_apply ()
162-         end )
163-         if  auto_disable  then 
164-             for  _ , v  in  ipairs (res ) do 
165-                 t .assert_not (v )
166-             end 
167-         else 
168-             local  res  =  g .storage_replica :exec (function ()
169-                 local  vshard  =  rawget (_G , ' vshard'  )
170-                 return  vshard .storage .internal .is_enabled 
171-             end )
172-             t .assert_not (res )
173-         end 
253+     --  Fix replica state
254+     dismiss_operation_error (g .storage_replica )
255+ 
256+     g .cluster :wait_until_healthy ()
257+     t .assert_not_equals (get_state (g .storage_master ), ' OperationError'  )
258+     t .assert_not_equals (get_state (g .storage_replica ), ' OperationError'  )
259+ 
260+     t .assert_equals (put (g .router , 2 ), {2 , 2 , ' i0002'  })
261+     for  _  =  1 , 1000  do 
262+         t .assert_equals (get (g .router , 2 ), {2 , 2 , ' i0002'  })
174263    end 
175264
176-     g .after_test (' test_disabled_on_apply_config'  , function  ()
177-         dismiss_operation_error (g .storage_replica )
178-         apply_config (g .router )
179-     end )
265+     set_failover (' disabled'  )
180266end 
181267
182- g_default .test_disabled_on_first_apply  =  function  ()
183-     local  res  =  g_default .storage_master :exec (function ()
268+ g .test_disabled_on_first_apply  =  function  ()
269+     local  res  =  g .storage_master :exec (function ()
184270        local  cartridge  =  require (' cartridge'  )
185271        return  cartridge .service_get (' myrole'  ).was_vshard_enabled_on_apply ()
186272    end )
187273
274+     --  last applied config
275+     apply_config (g .router )
276+ 
188277    t .assert_not (res [1 ])
189-     for  i  =  2 , # res  do 
190-         t .assert (res [i ])
191-     end 
278+     t .assert (res [# res ], ' enabled on last apply'  )
192279
193-     local   res  =  g_default .storage_replica :exec (function ()
280+     res  =  g .storage_replica :exec (function ()
194281        local  cartridge  =  require (' cartridge'  )
195282        return  cartridge .service_get (' myrole'  ).was_vshard_enabled_on_apply ()
196283    end )
197284
198285    t .assert_not (res [1 ])
286+     t .assert (res [# res ], ' enabled on last apply'  )
199287end 
0 commit comments