From dc5864329eb2a717d708ed8c47282a3205f2a391 Mon Sep 17 00:00:00 2001 From: Raggaer Date: Wed, 1 Aug 2018 16:15:00 +0200 Subject: [PATCH] Add cache module with tests --- app/controllers/controller.go | 1 + app/lua/cache.go | 58 ++++++++++++++++++++++++++++++++++ test/cache_test.go | 55 ++++++++++++++++++++++++++++++++ test/controllers/cache/get.lua | 3 ++ test/controllers/cache/set.lua | 2 ++ test/router/router.lua | 6 ++++ test/suite.go | 3 ++ 7 files changed, 128 insertions(+) create mode 100644 app/lua/cache.go create mode 100644 test/cache_test.go create mode 100644 test/controllers/cache/get.lua create mode 100644 test/controllers/cache/set.lua diff --git a/app/controllers/controller.go b/app/controllers/controller.go index 3f963a8..d719aa4 100644 --- a/app/controllers/controller.go +++ b/app/controllers/controller.go @@ -77,6 +77,7 @@ func (h *Handler) MainRoute(ctx *fasthttp.RequestCtx) { lua.NewConfigModule(h.Config.Custom), lua.NewTemplateModule(h.Tpl, ctx), lua.NewURLModule(), + lua.NewCacheModule(h.Cache), }) defer state.Close() diff --git a/app/lua/cache.go b/app/lua/cache.go new file mode 100644 index 0000000..c9a7187 --- /dev/null +++ b/app/lua/cache.go @@ -0,0 +1,58 @@ +package lua + +import ( + "time" + + "github.com/patrickmn/go-cache" + glua "github.com/tul/gopher-lua" +) + +// CacheModule provices access to the memory cache object +type CacheModule struct { + Cache *cache.Cache +} + +// NewCacheModule returns a new cache module +func NewCacheModule(c *cache.Cache) *Module { + module := &CacheModule{ + Cache: c, + } + return &Module{ + Name: "cache", + Data: module, + Funcs: map[string]glua.LGFunction{ + "get": module.Get, + "set": module.Set, + }, + } +} + +// Get retrieves a cache value +func (c *CacheModule) Get(state *glua.LState) int { + key := state.ToString(1) + v, ok := c.Cache.Get(key) + if !ok { + state.Push(glua.LNil) + return 1 + } + state.Push(GoValueToLua(v)) + return 1 +} + +// Set sets a cache value +func (c *CacheModule) Set(state *glua.LState) int { + key := state.ToString(1) + val := LuaValueToGo(state.Get(2)) + dur := state.Get(3) + if dur.Type() == glua.LTString { + d, err := time.ParseDuration(state.ToString(3)) + if err != nil { + state.RaiseError("Unable to parse cache duration - %v", err) + return 0 + } + c.Cache.Set(key, val, d) + return 0 + } + c.Cache.Set(key, val, time.Minute*5) + return 0 +} diff --git a/test/cache_test.go b/test/cache_test.go new file mode 100644 index 0000000..e106ee6 --- /dev/null +++ b/test/cache_test.go @@ -0,0 +1,55 @@ +package test + +import ( + "fmt" + "io/ioutil" + "net/http" + "testing" +) + +// TestCacheSet test the cache module set function + +func TestCacheSet(t *testing.T) { + port := make(chan int, 1) + defer createTestServer(port, t).Close() + addr := <-port + resp, err := http.Get(fmt.Sprintf("http://localhost:%d/cache/set", addr)) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + t.Fatalf("Wrong cache.set status code. Expected '200' but got '%d'", resp.StatusCode) + } +} + +// TestCacheGet test the cache module get function +func TestCacheGet(t *testing.T) { + port := make(chan int, 1) + defer createTestServer(port, t).Close() + + // First set a cache value + addr := <-port + resps, err := http.Get(fmt.Sprintf("http://localhost:%d/cache/set", addr)) + if err != nil { + t.Fatal(err) + } + defer resps.Body.Close() + if resps.StatusCode != 200 { + t.Fatalf("Wrong cache.set status code. Expected '200' but got '%d'", resps.StatusCode) + } + + // Get a cache value + respg, err := http.Get(fmt.Sprintf("http://localhost:%d/cache/get", addr)) + if err != nil { + t.Fatal(err) + } + defer respg.Body.Close() + bodyContent, err := ioutil.ReadAll(respg.Body) + if err != nil { + t.Fatal(err) + } + if string(bodyContent) != "Testing cache.set function" { + t.Fatalf("Wrong cache.get value. Expected 'Testing cache.set function' but got '%s'", string(bodyContent)) + } +} diff --git a/test/controllers/cache/get.lua b/test/controllers/cache/get.lua new file mode 100644 index 0000000..a0cb657 --- /dev/null +++ b/test/controllers/cache/get.lua @@ -0,0 +1,3 @@ +local cache = require('cache') +local req = require('http') +req.write(cache.get("bison-test")) \ No newline at end of file diff --git a/test/controllers/cache/set.lua b/test/controllers/cache/set.lua new file mode 100644 index 0000000..75a4498 --- /dev/null +++ b/test/controllers/cache/set.lua @@ -0,0 +1,2 @@ +local cache = require('cache') +cache.set("bison-test", "Testing cache.set function", "5m") \ No newline at end of file diff --git a/test/router/router.lua b/test/router/router.lua index a6b2f58..5109922 100644 --- a/test/router/router.lua +++ b/test/router/router.lua @@ -43,6 +43,12 @@ local router = { }, ['/url/path_unescape'] = { get = 'url/path_unescape.lua' + }, + ['/cache/set'] = { + get = 'cache/set.lua' + }, + ['/cache/get'] = { + get = 'cache/get.lua' } } diff --git a/test/suite.go b/test/suite.go index f95b14e..069dd25 100644 --- a/test/suite.go +++ b/test/suite.go @@ -7,8 +7,10 @@ import ( "net/http" "path/filepath" "testing" + "time" "github.com/buaazp/fasthttprouter" + "github.com/patrickmn/go-cache" "github.com/raggaer/bison/app/config" "github.com/raggaer/bison/app/controllers" "github.com/raggaer/bison/app/lua" @@ -54,6 +56,7 @@ func createTestServer(p chan<- int, t *testing.T) io.Closer { Routes: routes, Files: files, Tpl: tpl, + Cache: cache.New(time.Minute*5, time.Minute*10), } for _, rx := range routes {