github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/plugin/plugin_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package plugin 15 16 import ( 17 "context" 18 "io" 19 "strconv" 20 "testing" 21 22 "github.com/whtcorpsinc/check" 23 "github.com/whtcorpsinc/milevadb/stochastikctx/variable" 24 ) 25 26 func TestT(t *testing.T) { 27 check.TestingT(t) 28 } 29 30 func TestLoadPluginSuccess(t *testing.T) { 31 ctx := context.Background() 32 33 pluginName := "tplugin" 34 pluginVersion := uint16(1) 35 pluginSign := pluginName + "-" + strconv.Itoa(int(pluginVersion)) 36 37 cfg := Config{ 38 Plugins: []string{pluginSign}, 39 PluginDir: "", 40 GlobalSysVar: &variable.SysVars, 41 PluginVarNames: &variable.PluginVarNames, 42 EnvVersion: map[string]uint16{"go": 1112}, 43 } 44 45 // setup load test hook. 46 testHook = &struct{ loadOne loadFn }{loadOne: func(plugin *Plugin, dir string, pluginID ID) (manifest func() *Manifest, err error) { 47 return func() *Manifest { 48 m := &AuditManifest{ 49 Manifest: Manifest{ 50 HoTT: Authentication, 51 Name: pluginName, 52 Version: pluginVersion, 53 SysVars: map[string]*variable.SysVar{pluginName + "_key": {Scope: variable.ScopeGlobal, Name: pluginName + "_key", Value: "v1"}}, 54 OnInit: func(ctx context.Context, manifest *Manifest) error { 55 return nil 56 }, 57 OnShutdown: func(ctx context.Context, manifest *Manifest) error { 58 return nil 59 }, 60 Validate: func(ctx context.Context, manifest *Manifest) error { 61 return nil 62 }, 63 }, 64 OnGeneralEvent: func(ctx context.Context, sctx *variable.StochastikVars, event GeneralEvent, cmd string) { 65 }, 66 } 67 return ExportManifest(m) 68 }, nil 69 }} 70 defer func() { 71 testHook = nil 72 }() 73 74 // trigger load. 75 err := Load(ctx, cfg) 76 if err != nil { 77 t.Errorf("load plugin [%s] fail", pluginSign) 78 } 79 80 err = Init(ctx, cfg) 81 if err != nil { 82 t.Errorf("init plugin [%s] fail", pluginSign) 83 } 84 85 // load all. 86 ps := GetAll() 87 if len(ps) != 1 { 88 t.Errorf("loaded plugins is empty") 89 } 90 91 // find plugin by type and name 92 p := Get(Authentication, "tplugin") 93 if p == nil { 94 t.Errorf("tplugin can not be load") 95 } 96 p = Get(Authentication, "tplugin2") 97 if p != nil { 98 t.Errorf("found miss plugin") 99 } 100 p = getByName("tplugin") 101 if p == nil { 102 t.Errorf("can not find miss plugin") 103 } 104 105 // foreach plugin 106 err = ForeachPlugin(Authentication, func(plugin *Plugin) error { 107 return nil 108 }) 109 if err != nil { 110 t.Errorf("foreach error %v", err) 111 } 112 err = ForeachPlugin(Authentication, func(plugin *Plugin) error { 113 return io.EOF 114 }) 115 if err != io.EOF { 116 t.Errorf("foreach should return EOF error") 117 } 118 119 Shutdown(ctx) 120 } 121 122 func TestLoadPluginSkipError(t *testing.T) { 123 ctx := context.Background() 124 125 pluginName := "tplugin" 126 pluginVersion := uint16(1) 127 pluginSign := pluginName + "-" + strconv.Itoa(int(pluginVersion)) 128 129 cfg := Config{ 130 Plugins: []string{pluginSign, pluginSign, "notExists-2"}, 131 PluginDir: "", 132 PluginVarNames: &variable.PluginVarNames, 133 EnvVersion: map[string]uint16{"go": 1112}, 134 SkipWhenFail: true, 135 } 136 137 // setup load test hook. 138 testHook = &struct{ loadOne loadFn }{loadOne: func(plugin *Plugin, dir string, pluginID ID) (manifest func() *Manifest, err error) { 139 return func() *Manifest { 140 m := &AuditManifest{ 141 Manifest: Manifest{ 142 HoTT: Audit, 143 Name: pluginName, 144 Version: pluginVersion, 145 SysVars: map[string]*variable.SysVar{pluginName + "_key": {Scope: variable.ScopeGlobal, Name: pluginName + "_key", Value: "v1"}}, 146 OnInit: func(ctx context.Context, manifest *Manifest) error { 147 return io.EOF 148 }, 149 OnShutdown: func(ctx context.Context, manifest *Manifest) error { 150 return io.EOF 151 }, 152 Validate: func(ctx context.Context, manifest *Manifest) error { 153 return io.EOF 154 }, 155 }, 156 OnGeneralEvent: func(ctx context.Context, sctx *variable.StochastikVars, event GeneralEvent, cmd string) { 157 }, 158 } 159 return ExportManifest(m) 160 }, nil 161 }} 162 defer func() { 163 testHook = nil 164 }() 165 166 // trigger load. 167 err := Load(ctx, cfg) 168 if err != nil { 169 t.Errorf("load plugin [%s] fail %v", pluginSign, err) 170 } 171 172 err = Init(ctx, cfg) 173 if err != nil { 174 t.Errorf("init plugin [%s] fail", pluginSign) 175 } 176 177 // load all. 178 ps := GetAll() 179 if len(ps) != 1 { 180 t.Errorf("loaded plugins is empty") 181 } 182 183 // find plugin by type and name 184 p := Get(Audit, "tplugin") 185 if p == nil { 186 t.Errorf("tplugin can not be load") 187 } 188 p = Get(Audit, "tplugin2") 189 if p != nil { 190 t.Errorf("found miss plugin") 191 } 192 p = getByName("tplugin") 193 if p == nil { 194 t.Errorf("can not find miss plugin") 195 } 196 p = getByName("not exists") 197 if p != nil { 198 t.Errorf("got not exists plugin") 199 } 200 201 // foreach plugin 202 readyCount := 0 203 err = ForeachPlugin(Authentication, func(plugin *Plugin) error { 204 readyCount++ 205 return nil 206 }) 207 if err != nil { 208 t.Errorf("foreach meet error %v", err) 209 } 210 if readyCount != 0 { 211 t.Errorf("validate fail can be load but no ready") 212 } 213 214 Shutdown(ctx) 215 } 216 217 func TestLoadFail(t *testing.T) { 218 ctx := context.Background() 219 220 pluginName := "tplugin" 221 pluginVersion := uint16(1) 222 pluginSign := pluginName + "-" + strconv.Itoa(int(pluginVersion)) 223 224 cfg := Config{ 225 Plugins: []string{pluginSign, pluginSign, "notExists-2"}, 226 PluginDir: "", 227 PluginVarNames: &variable.PluginVarNames, 228 EnvVersion: map[string]uint16{"go": 1112}, 229 SkipWhenFail: false, 230 } 231 232 // setup load test hook. 233 testHook = &struct{ loadOne loadFn }{loadOne: func(plugin *Plugin, dir string, pluginID ID) (manifest func() *Manifest, err error) { 234 return func() *Manifest { 235 m := &AuditManifest{ 236 Manifest: Manifest{ 237 HoTT: Audit, 238 Name: pluginName, 239 Version: pluginVersion, 240 SysVars: map[string]*variable.SysVar{pluginName + "_key": {Scope: variable.ScopeGlobal, Name: pluginName + "_key", Value: "v1"}}, 241 OnInit: func(ctx context.Context, manifest *Manifest) error { 242 return io.EOF 243 }, 244 OnShutdown: func(ctx context.Context, manifest *Manifest) error { 245 return io.EOF 246 }, 247 Validate: func(ctx context.Context, manifest *Manifest) error { 248 return io.EOF 249 }, 250 }, 251 OnGeneralEvent: func(ctx context.Context, sctx *variable.StochastikVars, event GeneralEvent, cmd string) { 252 }, 253 } 254 return ExportManifest(m) 255 }, nil 256 }} 257 defer func() { 258 testHook = nil 259 }() 260 261 err := Load(ctx, cfg) 262 if err == nil { 263 t.Errorf("load plugin should fail") 264 } 265 } 266 267 func TestPluginsClone(t *testing.T) { 268 ps := &plugins{ 269 plugins: map[HoTT][]Plugin{ 270 Audit: {{}}, 271 }, 272 versions: map[string]uint16{ 273 "whitelist": 1, 274 }, 275 dyingPlugins: []Plugin{{}}, 276 } 277 cps := ps.clone() 278 ps.dyingPlugins = append(ps.dyingPlugins, Plugin{}) 279 ps.versions["w"] = 2 280 as := ps.plugins[Audit] 281 ps.plugins[Audit] = append(as, Plugin{}) 282 283 if len(cps.plugins) != 1 || len(cps.plugins[Audit]) != 1 || len(cps.versions) != 1 || len(cps.dyingPlugins) != 1 { 284 t.Errorf("clone plugins failure") 285 } 286 }