db_test.go (8018B)
1 package engine 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "os" 8 "strings" 9 "testing" 10 11 "git.defalsify.org/vise.git/cache" 12 memdb "git.defalsify.org/vise.git/db/mem" 13 "git.defalsify.org/vise.git/persist" 14 "git.defalsify.org/vise.git/resource" 15 "git.defalsify.org/vise.git/state" 16 "git.defalsify.org/vise.git/vm" 17 ) 18 19 func getNull() io.WriteCloser { 20 nul, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0700) 21 if err != nil { 22 panic(err) 23 } 24 return nul 25 } 26 27 func codeGet(ctx context.Context, s string) ([]byte, error) { 28 var b []byte 29 var err error 30 switch s { 31 case "root": 32 b = vm.NewLine(nil, vm.HALT, nil, nil, nil) 33 b = vm.NewLine(b, vm.LOAD, []string{"foo"}, []byte{0x0}, nil) 34 case "tinkywinky": 35 b = vm.NewLine(nil, vm.MOVE, []string{"dipsy"}, nil, nil) 36 b = vm.NewLine(b, vm.LOAD, []string{"foo"}, []byte{0x0}, nil) 37 case "dipsy": 38 b = vm.NewLine(nil, vm.HALT, nil, nil, nil) 39 b = vm.NewLine(b, vm.LOAD, []string{"foo"}, []byte{0x0}, nil) 40 default: 41 err = fmt.Errorf("unknown code symbol '%s'", s) 42 } 43 return b, err 44 } 45 46 func flagSet(ctx context.Context, nodeSym string, input []byte) (resource.Result, error) { 47 return resource.Result{ 48 Content: "xyzzy", 49 FlagSet: []uint32{state.FLAG_USERSTART}, 50 }, nil 51 } 52 53 func TestDbEngineMinimal(t *testing.T) { 54 ctx := context.Background() 55 cfg := Config{} 56 rs := resource.NewMenuResource() 57 en := NewEngine(cfg, rs) 58 //cont, err := en.Init(ctx) 59 cont, err := en.Exec(ctx, []byte{}) 60 if err != nil { 61 t.Fatal(err) 62 } 63 if cont { 64 t.Fatalf("expected not continue") 65 } 66 err = en.Finish(ctx) 67 if err != nil { 68 t.Fatal(err) 69 } 70 } 71 72 func TestDbEngineNoResource(t *testing.T) { 73 cfg := Config{} 74 defer func() { 75 if r := recover(); r == nil { 76 t.Fatal("did not panic") 77 } 78 }() 79 NewEngine(cfg, nil) 80 } 81 82 func TestDbEngineStateNil(t *testing.T) { 83 cfg := Config{} 84 rs := resource.NewMenuResource() 85 defer func() { 86 if r := recover(); r == nil { 87 t.Fatal("did not panic") 88 } 89 }() 90 NewEngine(cfg, rs).WithState(nil) 91 } 92 93 func TestDbEngineCacheNil(t *testing.T) { 94 cfg := Config{} 95 rs := resource.NewMenuResource() 96 defer func() { 97 if r := recover(); r == nil { 98 t.Fatal("did not panic") 99 } 100 }() 101 NewEngine(cfg, rs).WithMemory(nil) 102 } 103 104 func TestDbEnginePersisterNil(t *testing.T) { 105 cfg := Config{} 106 rs := resource.NewMenuResource() 107 defer func() { 108 if r := recover(); r == nil { 109 t.Fatal("did not panic") 110 } 111 }() 112 NewEngine(cfg, rs).WithPersister(nil) 113 } 114 115 func TestDbEngineFirstNil(t *testing.T) { 116 cfg := Config{} 117 rs := resource.NewMenuResource() 118 defer func() { 119 if r := recover(); r == nil { 120 t.Fatal("did not panic") 121 } 122 }() 123 NewEngine(cfg, rs).WithFirst(nil) 124 } 125 126 func TestDbEngineStateDup(t *testing.T) { 127 cfg := Config{} 128 rs := resource.NewMenuResource() 129 st := state.NewState(0) 130 en := NewEngine(cfg, rs).WithState(st) 131 defer func() { 132 if r := recover(); r == nil { 133 t.Fatal("did not panic") 134 } 135 }() 136 en.WithState(st) 137 } 138 139 func TestDbEngineCacheDup(t *testing.T) { 140 cfg := Config{} 141 rs := resource.NewMenuResource() 142 ca := cache.NewCache() 143 en := NewEngine(cfg, rs).WithMemory(ca) 144 defer func() { 145 if r := recover(); r == nil { 146 t.Fatal("did not panic") 147 } 148 }() 149 en.WithMemory(ca) 150 } 151 152 func TestDbEnginePersisterDup(t *testing.T) { 153 ctx := context.Background() 154 cfg := Config{} 155 rs := resource.NewMenuResource() 156 store := memdb.NewMemDb() 157 store.Connect(ctx, "") 158 pe := persist.NewPersister(store) 159 en := NewEngine(cfg, rs).WithPersister(pe) 160 defer func() { 161 if r := recover(); r == nil { 162 t.Fatal("did not panic") 163 } 164 }() 165 en.WithPersister(pe) 166 } 167 168 func TestDbEngineFirstDup(t *testing.T) { 169 cfg := Config{} 170 rs := resource.NewMenuResource() 171 en := NewEngine(cfg, rs).WithFirst(flagSet) 172 defer func() { 173 if r := recover(); r == nil { 174 t.Fatal("did not panic") 175 } 176 }() 177 en.WithFirst(flagSet) 178 } 179 180 func TestDbEngineRoot(t *testing.T) { 181 nul := getNull() 182 defer nul.Close() 183 ctx := context.Background() 184 cfg := Config{} 185 rs := resource.NewMenuResource() 186 rs.WithCodeGetter(codeGet) 187 en := NewEngine(cfg, rs) 188 //cont, err := en.Init(ctx) 189 cont, err := en.Exec(ctx, []byte{}) 190 if err != nil { 191 t.Fatal(err) 192 } 193 if !cont { 194 t.Fatalf("expected continue") 195 } 196 197 cont, err = en.Exec(ctx, []byte{0x30}) 198 if err == nil { 199 t.Fatalf("expected loadfail") 200 } 201 202 cont, err = en.Exec(ctx, []byte{0x30}) 203 if err == nil { 204 t.Fatalf("expected nocode") 205 } 206 err = en.Finish(ctx) 207 if err != nil { 208 t.Fatal(err) 209 } 210 } 211 212 func TestDbEnginePersist(t *testing.T) { 213 nul := getNull() 214 defer nul.Close() 215 ctx := context.Background() 216 cfg := Config{ 217 FlagCount: 1, 218 SessionId: "bar", 219 } 220 store := memdb.NewMemDb() 221 store.Connect(ctx, "") 222 pe := persist.NewPersister(store) 223 rs := resource.NewMenuResource() 224 rs.WithCodeGetter(codeGet) 225 rs.AddLocalFunc("foo", flagSet) 226 en := NewEngine(cfg, rs) 227 en = en.WithPersister(pe) 228 //cont, err := en.Init(ctx) 229 cont, err := en.Exec(ctx, []byte{}) 230 if err != nil { 231 t.Fatal(err) 232 } 233 if !cont { 234 t.Fatalf("expected continue") 235 } 236 237 cont, err = en.Exec(ctx, []byte{0x30}) 238 if err != nil { 239 t.Fatal(err) 240 } 241 242 _, err = en.Flush(ctx, nul) 243 if err != nil { 244 t.Fatal(err) 245 } 246 err = en.Finish(ctx) 247 if err != nil { 248 t.Fatal(err) 249 } 250 251 en = NewEngine(cfg, rs) 252 pe = persist.NewPersister(store) 253 en = NewEngine(cfg, rs) 254 en = en.WithPersister(pe) 255 cont, err = en.Exec(ctx, []byte{}) 256 if err != nil { 257 t.Fatal(err) 258 } 259 stn := pe.GetState() 260 if !stn.MatchFlag(state.FLAG_USERSTART, true) { 261 t.Fatalf("expected userstart set, have state %v", stn) 262 } 263 } 264 265 func TestDbConfigString(t *testing.T) { 266 cfg := Config{ 267 Root: "tinkywinky", 268 } 269 s := cfg.String() 270 if !strings.Contains(s, "tinky") { 271 t.Fatalf("expected contains 'tinky', got: '%s'", s) 272 } 273 } 274 275 func TestDbEnsure(t *testing.T) { 276 var err error 277 var cfg Config 278 ctx := context.Background() 279 rs := resource.NewMenuResource() 280 store := memdb.NewMemDb() 281 store.Connect(ctx, "") 282 pe := persist.NewPersister(store) 283 en := NewEngine(cfg, rs).WithPersister(pe) 284 //_, err = en.Init(ctx) 285 _, err = en.Exec(ctx, []byte{}) 286 if err != nil { 287 t.Fatal(err) 288 } 289 if pe.GetState() == nil { 290 t.Fatal("expected persister state") 291 } 292 if pe.GetMemory() == nil { 293 t.Fatal("expected persister memory") 294 } 295 } 296 297 func TestDbKeepPersisterContent(t *testing.T) { 298 var err error 299 var cfg Config 300 ctx := context.Background() 301 rs := resource.NewMenuResource() 302 st := state.NewState(0) 303 ca := cache.NewCache() 304 store := memdb.NewMemDb() 305 store.Connect(ctx, "") 306 pe := persist.NewPersister(store) 307 pe = pe.WithContent(st, ca) 308 en := NewEngine(cfg, rs).WithPersister(pe) 309 //_, err = en.Init(ctx) 310 _, err = en.Exec(ctx, []byte{}) 311 if err != nil { 312 t.Fatal(err) 313 } 314 pest := pe.GetState() 315 if pest != st { 316 t.Fatalf("expected persisted state %p same as engine %p", pest, st) 317 } 318 peca := pe.GetMemory() 319 if peca != ca { 320 t.Fatalf("expected persisted cache %p same as engine %p", peca, st) 321 } 322 } 323 324 func TestDbKeepState(t *testing.T) { 325 var err error 326 var cfg Config 327 ctx := context.Background() 328 rs := resource.NewMenuResource() 329 st := state.NewState(0) 330 ca := cache.NewCache() 331 store := memdb.NewMemDb() 332 store.Connect(ctx, "") 333 pe := persist.NewPersister(store) 334 en := NewEngine(cfg, rs) 335 en = en.WithState(st) 336 en = en.WithMemory(ca) 337 en = en.WithPersister(pe) 338 //_, err = en.Init(ctx) 339 _, err = en.Exec(ctx, []byte{}) 340 if err != nil { 341 t.Fatal(err) 342 } 343 pest := pe.GetState() 344 if pest != st { 345 t.Fatalf("expected persisted state %p same as engine preset %p", pest, st) 346 } 347 peca := pe.GetMemory() 348 if peca != ca { 349 t.Fatalf("expected persisted cache %p same as engine preset %p", peca, st) 350 } 351 } 352 353 func TestDbFirst(t *testing.T) { 354 var err error 355 var cfg Config 356 ctx := context.Background() 357 rs := resource.NewMenuResource() 358 st := state.NewState(1) 359 store := memdb.NewMemDb() 360 store.Connect(ctx, "") 361 362 v := st.GetFlag(state.FLAG_USERSTART) 363 if v { 364 t.Fatal("expected flag unset") 365 } 366 en := NewEngine(cfg, rs) 367 en = en.WithState(st) 368 en = en.WithFirst(flagSet) 369 //_, err = en.Init(ctx) 370 _, err = en.Exec(ctx, []byte{}) 371 if err != nil { 372 t.Fatal(err) 373 } 374 v = st.GetFlag(state.FLAG_USERSTART) 375 if !v { 376 t.Fatal("expected flag set") 377 } 378 }