go-vise

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

commit db4c7bc4cb26ba349e8bff534bf0d29809049651
parent a4198d48b46a1e8f4d0917a1de1c3a2972e28a47
Author: lash <dev@holbrook.no>
Date:   Wed, 11 Sep 2024 02:33:06 +0100

Reach 85% coverage on cache tests

Diffstat:
MMakefile | 4++++
Mcache/cache.go | 3+--
Mcache/cache_test.go | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Acache/error.go | 9+++++++++
Mvm/runner.go | 6++++++
5 files changed, 134 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile @@ -29,3 +29,7 @@ intro: doc: make -C doc + +cov: + go test -cover ./... -coverprofile=cover.out + go tool cover -html=cover.out diff --git a/cache/cache.go b/cache/cache.go @@ -58,8 +58,7 @@ func(ca *Cache) Add(key string, value string, sizeLimit uint16) error { if checkFrame > -1 { thisFrame := len(ca.Cache) - 1 if checkFrame == thisFrame { - logg.Debugf("Ignoring load request on frame that has symbol already loaded") - return nil + return ErrDup } return fmt.Errorf("key %v already defined in frame %v, this is frame %v", key, checkFrame, thisFrame) } diff --git a/cache/cache_test.go b/cache/cache_test.go @@ -2,6 +2,7 @@ package cache import ( "testing" + "slices" ) func TestNewCache(t *testing.T) { @@ -15,7 +16,7 @@ func TestNewCache(t *testing.T) { } } -func TestStateCacheUse(t *testing.T) { +func TestCacheUse(t *testing.T) { ca := NewCache() ca = ca.WithCacheSize(10) ca.Push() @@ -31,6 +32,74 @@ func TestStateCacheUse(t *testing.T) { if err == nil { t.Errorf("expected capacity error") } + v := ca.Check("inky") + if v { + t.Fatal("expected true") + } + v = ca.Check("blinky") + if !v { + t.Fatal("expected false") + } +} + +func TestCacheUpdate(t *testing.T) { + ca := NewCache() + ca = ca.WithCacheSize(10) + ca.Add("foo", "bar", 0) + err := ca.Add("foo", "barbarbar", 0) + if err != ErrDup { + t.Error(err) + } + v, err := ca.Get("foo") + if err != nil { + t.Error(err) + } + if v != "bar" { + t.Fatalf("expected 'bar', got '%s'", v) + } + err = ca.Update("foo", "barbarbar") + v, err = ca.Get("foo") + if err != nil { + t.Error(err) + } + if v != "barbarbar" { + t.Fatalf("expected 'barbarbar', got '%s'", v) + } + err = ca.Update("foo", "barbarbarbar") + if err == nil { + t.Fatalf("expect error") + } +} + +func TestCacheLimits(t *testing.T) { + ca := NewCache() + ca = ca.WithCacheSize(8) + err := ca.Add("foo", "bar", 2) + if err == nil { + t.Fatal("expected error") + } + err = ca.Add("foo", "barbarbar", 0) + if err == nil { + t.Fatal("expected error") + } + err = ca.Add("foo", "bar", 0) + if err != nil { + t.Fatal(err) + } + err = ca.Add("baz", "barbar", 0) + if err == nil { + t.Fatal("expected error") + } + ca.Reset() + err = ca.Add("baz", "barbar", 0) + if err == nil { + t.Fatal("expected error") + } + ca.Pop() + err = ca.Add("baz", "barbar", 0) + if err != nil { + t.Fatal(err) + } } func TestStateDownUp(t *testing.T) { @@ -82,12 +151,13 @@ func TestCacheReset(t *testing.T) { if err != nil { t.Error(err) } + ca.Push() err = ca.Add("baz", "xyzzy", 0) if err != nil { t.Error(err) } ca.Reset() - if ca.CacheUseSize != 0 { + if ca.CacheUseSize != 3 { t.Errorf("expected cache use size 0, got %v", ca.CacheUseSize) } } @@ -103,14 +173,55 @@ func TestCacheLoadDup(t *testing.T) { t.Error(err) } err = ca.Push() + if err != nil { + t.Error(err) + } err = ca.Add("foo", "baz", 0) if err == nil { - t.Errorf("expected fail on duplicate load") + t.Errorf("expect duplicate key in different frame") } ca.Pop() err = ca.Add("foo", "baz", 0) + if err != ErrDup { + t.Error(err) + } +} + +func TestCacheLast(t *testing.T) { + ca := NewCache() + v := ca.Last() + if v != "" { + t.Fatal("expected empty") + } + err := ca.Add("foo", "bar", 0) + if err != nil { + t.Error(err) + } + ca.Push() + err = ca.Add("baz", "xyzzy", 0) if err != nil { t.Error(err) } + v = ca.Last() + if v != "xyzzy" { + t.Fatalf("expected 'xyzzy', got: '%s'", v) + } } +func TestCacheKeys(t *testing.T) { + ca := NewCache() + ca.Add("inky", "tinkywinky", 0) + ca.Push() + ca.Add("pinky", "dipsy", 0) + ca.Push() + ca.Push() + ca.Add("blinky", "lala", 0) + ca.Add("clyde", "pu", 0) + ks := ca.Keys(3) + if !slices.Contains(ks, "blinky") { + t.Fatalf("Missing 'blinky'") + } + if !slices.Contains(ks, "clyde") { + t.Fatalf("Missing 'clyde'") + } +} diff --git a/cache/error.go b/cache/error.go @@ -0,0 +1,9 @@ +package cache + +import ( + "fmt" +) + +var ( + ErrDup = fmt.Errorf("duplicate key") +) diff --git a/vm/runner.go b/vm/runner.go @@ -276,6 +276,12 @@ func(vm *Vm) runLoad(ctx context.Context, b []byte) ([]byte, error) { return b, err } err = vm.ca.Add(sym, r, uint16(sz)) + if err != nil { + if err == cache.ErrDup { + logg.DebugCtxf(ctx, "Ignoring load request on frame that has symbol already loaded", "sym", sym) + err = nil + } + } return b, err }