go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

db_test.go (8555B)


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