From 5e54f6b55f00fb6a41e232dd87509aefcd7c1bd2 Mon Sep 17 00:00:00 2001
From: Alexis Poyen <apoyen@mail.apoyen.fr>
Date: Thu, 30 Apr 2020 16:46:46 +0200
Subject: [PATCH] Remove:  useless package

---
 pkg/cache/LICENSE               |  21 --
 pkg/cache/cache.go              | 297 --------------------
 pkg/cache/cache_test.go         | 481 --------------------------------
 pkg/cache/memory/memory.go      | 190 -------------
 pkg/cache/memory/memory_test.go | 299 --------------------
 5 files changed, 1288 deletions(-)
 delete mode 100644 pkg/cache/LICENSE
 delete mode 100644 pkg/cache/cache.go
 delete mode 100644 pkg/cache/cache_test.go
 delete mode 100644 pkg/cache/memory/memory.go
 delete mode 100644 pkg/cache/memory/memory_test.go

diff --git a/pkg/cache/LICENSE b/pkg/cache/LICENSE
deleted file mode 100644
index bbe6990..0000000
--- a/pkg/cache/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2018 Victor Springer
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go
deleted file mode 100644
index 0fc15c6..0000000
--- a/pkg/cache/cache.go
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
-MIT License
-
-Copyright (c) 2018 Victor Springer
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-package cache
-
-import (
-	"bytes"
-	"encoding/gob"
-	"errors"
-	"fmt"
-	"hash/fnv"
-	"io/ioutil"
-	"net/http"
-	"net/http/httptest"
-	"net/url"
-	"sort"
-	"strconv"
-	"strings"
-	"time"
-
-	"github.com/nicolaspernoud/vestibule/pkg/glob"
-)
-
-// Response is the cached response data structure.
-type Response struct {
-	// Value is the cached response value.
-	Value []byte
-
-	// Header is the cached response header.
-	Header http.Header
-
-	// Expiration is the cached response expiration date.
-	Expiration time.Time
-
-	// LastAccess is the last date a cached response was accessed.
-	// Used by LRU and MRU algorithms.
-	LastAccess time.Time
-
-	// Frequency is the count of times a cached response is accessed.
-	// Used for LFU and MFU algorithms.
-	Frequency int
-}
-
-// Client data structure for HTTP cache middleware.
-type Client struct {
-	adapter    Adapter
-	ttl        time.Duration
-	refreshKey string
-	methods    []string
-}
-
-// ClientOption is used to set Client settings.
-type ClientOption func(c *Client) error
-
-// Adapter interface for HTTP cache middleware client.
-type Adapter interface {
-	// Get retrieves the cached response by a given key. It also
-	// returns true or false, whether it exists or not.
-	Get(key uint64) ([]byte, bool)
-
-	// Set caches a response for a given key until an expiration date.
-	Set(key uint64, response []byte, expiration time.Time)
-
-	// Release frees cache for a given key.
-	Release(key uint64)
-}
-
-// Middleware is the HTTP cache middleware handler.
-func (c *Client) Middleware(next http.Handler, patterns []string) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		// Check pattern matching
-		var patternMatched bool
-		for _, p := range patterns {
-			if glob.Glob(p, r.URL.Path) {
-				patternMatched = true
-				break
-			}
-		}
-		if c.cacheableMethod(r.Method) && patternMatched {
-			sortURLParams(r.URL)
-			key := generateKey(r.URL.String())
-			if r.Method == http.MethodPost && r.Body != nil {
-				body, err := ioutil.ReadAll(r.Body)
-				defer r.Body.Close()
-				if err != nil {
-					next.ServeHTTP(w, r)
-					return
-				}
-				reader := ioutil.NopCloser(bytes.NewBuffer(body))
-				key = generateKeyWithBody(r.URL.String(), body)
-				r.Body = reader
-			}
-
-			params := r.URL.Query()
-			if _, ok := params[c.refreshKey]; ok {
-				delete(params, c.refreshKey)
-
-				r.URL.RawQuery = params.Encode()
-				key = generateKey(r.URL.String())
-
-				c.adapter.Release(key)
-			} else {
-				b, ok := c.adapter.Get(key)
-				response := BytesToResponse(b)
-				if ok {
-					if response.Expiration.After(time.Now()) {
-						response.LastAccess = time.Now()
-						response.Frequency++
-						c.adapter.Set(key, response.Bytes(), response.Expiration)
-
-						//w.WriteHeader(http.StatusNotModified)
-						for k, v := range response.Header {
-							w.Header().Set(k, strings.Join(v, ","))
-						}
-						w.Write(response.Value)
-						return
-					}
-
-					c.adapter.Release(key)
-				}
-			}
-
-			rec := httptest.NewRecorder()
-			next.ServeHTTP(rec, r)
-			result := rec.Result()
-
-			statusCode := result.StatusCode
-			value := rec.Body.Bytes()
-			if statusCode < 300 {
-				now := time.Now()
-
-				response := Response{
-					Value:      value,
-					Header:     result.Header,
-					Expiration: now.Add(c.ttl),
-					LastAccess: now,
-					Frequency:  1,
-				}
-				c.adapter.Set(key, response.Bytes(), response.Expiration)
-			}
-			for k, v := range result.Header {
-				w.Header().Set(k, strings.Join(v, ","))
-			}
-			w.WriteHeader(statusCode)
-			w.Write(value)
-			return
-		}
-		next.ServeHTTP(w, r)
-	})
-}
-
-func (c *Client) cacheableMethod(method string) bool {
-	for _, m := range c.methods {
-		if method == m {
-			return true
-		}
-	}
-	return false
-}
-
-// BytesToResponse converts bytes array into Response data structure.
-func BytesToResponse(b []byte) Response {
-	var r Response
-	dec := gob.NewDecoder(bytes.NewReader(b))
-	dec.Decode(&r)
-
-	return r
-}
-
-// Bytes converts Response data structure into bytes array.
-func (r Response) Bytes() []byte {
-	var b bytes.Buffer
-	enc := gob.NewEncoder(&b)
-	enc.Encode(&r)
-
-	return b.Bytes()
-}
-
-func sortURLParams(URL *url.URL) {
-	params := URL.Query()
-	for _, param := range params {
-		sort.Slice(param, func(i, j int) bool {
-			return param[i] < param[j]
-		})
-	}
-	URL.RawQuery = params.Encode()
-}
-
-// KeyAsString can be used by adapters to convert the cache key from uint64 to string.
-func KeyAsString(key uint64) string {
-	return strconv.FormatUint(key, 36)
-}
-
-func generateKey(URL string) uint64 {
-	hash := fnv.New64a()
-	hash.Write([]byte(URL))
-
-	return hash.Sum64()
-}
-
-func generateKeyWithBody(URL string, body []byte) uint64 {
-	hash := fnv.New64a()
-	body = append([]byte(URL), body...)
-	hash.Write(body)
-
-	return hash.Sum64()
-}
-
-// NewClient initializes the cache HTTP middleware client with the given
-// options.
-func NewClient(opts ...ClientOption) (*Client, error) {
-	c := &Client{}
-
-	for _, opt := range opts {
-		if err := opt(c); err != nil {
-			return nil, err
-		}
-	}
-
-	if c.adapter == nil {
-		return nil, errors.New("cache client adapter is not set")
-	}
-	if int64(c.ttl) < 1 {
-		return nil, errors.New("cache client ttl is not set")
-	}
-	if c.methods == nil {
-		c.methods = []string{http.MethodGet}
-	}
-
-	return c, nil
-}
-
-// ClientWithAdapter sets the adapter type for the HTTP cache
-// middleware client.
-func ClientWithAdapter(a Adapter) ClientOption {
-	return func(c *Client) error {
-		c.adapter = a
-		return nil
-	}
-}
-
-// ClientWithTTL sets how long each response is going to be cached.
-func ClientWithTTL(ttl time.Duration) ClientOption {
-	return func(c *Client) error {
-		if int64(ttl) < 1 {
-			return fmt.Errorf("cache client ttl %v is invalid", ttl)
-		}
-
-		c.ttl = ttl
-
-		return nil
-	}
-}
-
-// ClientWithRefreshKey sets the parameter key used to free a request
-// cached response. Optional setting.
-func ClientWithRefreshKey(refreshKey string) ClientOption {
-	return func(c *Client) error {
-		c.refreshKey = refreshKey
-		return nil
-	}
-}
-
-// ClientWithMethods sets the acceptable HTTP methods to be cached.
-// Optional setting. If not set, default is "GET".
-func ClientWithMethods(methods []string) ClientOption {
-	return func(c *Client) error {
-		for _, method := range methods {
-			if method != http.MethodGet && method != http.MethodPost {
-				return fmt.Errorf("invalid method %s", method)
-			}
-		}
-		c.methods = methods
-		return nil
-	}
-}
diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go
deleted file mode 100644
index 8555ab9..0000000
--- a/pkg/cache/cache_test.go
+++ /dev/null
@@ -1,481 +0,0 @@
-package cache
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"net/http"
-	"net/http/httptest"
-	"net/url"
-	"reflect"
-	"sync"
-	"testing"
-	"time"
-)
-
-type adapterMock struct {
-	sync.Mutex
-	store map[uint64][]byte
-}
-
-type errReader int
-
-func (a *adapterMock) Get(key uint64) ([]byte, bool) {
-	a.Lock()
-	defer a.Unlock()
-	if _, ok := a.store[key]; ok {
-		return a.store[key], true
-	}
-	return nil, false
-}
-
-func (a *adapterMock) Set(key uint64, response []byte, expiration time.Time) {
-	a.Lock()
-	defer a.Unlock()
-	a.store[key] = response
-}
-
-func (a *adapterMock) Release(key uint64) {
-	a.Lock()
-	defer a.Unlock()
-	delete(a.store, key)
-}
-
-func (errReader) Read(p []byte) (n int, err error) {
-	return 0, errors.New("readAll error")
-}
-
-func TestMiddleware(t *testing.T) {
-	counter := 0
-	httpTestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		w.Write([]byte(fmt.Sprintf("new value %v", counter)))
-	})
-
-	adapter := &adapterMock{
-		store: map[uint64][]byte{
-			14974843192121052621: Response{
-				Value:      []byte("value 1"),
-				Expiration: time.Now().Add(1 * time.Minute),
-			}.Bytes(),
-			14974839893586167988: Response{
-				Value:      []byte("value 2"),
-				Expiration: time.Now().Add(1 * time.Minute),
-			}.Bytes(),
-			14974840993097796199: Response{
-				Value:      []byte("value 3"),
-				Expiration: time.Now().Add(-1 * time.Minute),
-			}.Bytes(),
-			10956846073361780255: Response{
-				Value:      []byte("value 4"),
-				Expiration: time.Now().Add(-1 * time.Minute),
-			}.Bytes(),
-		},
-	}
-
-	client, _ := NewClient(
-		ClientWithAdapter(adapter),
-		ClientWithTTL(1*time.Minute),
-		ClientWithRefreshKey("rk"),
-		ClientWithMethods([]string{http.MethodGet, http.MethodPost}),
-	)
-
-	handler := client.Middleware(httpTestHandler, []string{"*"})
-
-	tests := []struct {
-		name     string
-		url      string
-		method   string
-		body     []byte
-		wantBody string
-		wantCode int
-	}{
-		{
-			"returns cached response",
-			"http://foo.bar/test-1",
-			"GET",
-			nil,
-			"value 1",
-			200,
-		},
-		{
-			"returns new response",
-			"http://foo.bar/test-2",
-			"PUT",
-			nil,
-			"new value 2",
-			200,
-		},
-		{
-			"returns cached response",
-			"http://foo.bar/test-2",
-			"GET",
-			nil,
-			"value 2",
-			200,
-		},
-		{
-			"returns new response",
-			"http://foo.bar/test-3?zaz=baz&baz=zaz",
-			"GET",
-			nil,
-			"new value 4",
-			200,
-		},
-		{
-			"returns cached response",
-			"http://foo.bar/test-3?baz=zaz&zaz=baz",
-			"GET",
-			nil,
-			"new value 4",
-			200,
-		},
-		{
-			"cache expired",
-			"http://foo.bar/test-3",
-			"GET",
-			nil,
-			"new value 6",
-			200,
-		},
-		{
-			"releases cached response and returns new response",
-			"http://foo.bar/test-2?rk=true",
-			"GET",
-			nil,
-			"new value 7",
-			200,
-		},
-		{
-			"returns new cached response",
-			"http://foo.bar/test-2",
-			"GET",
-			nil,
-			"new value 7",
-			200,
-		},
-		{
-			"returns new cached response",
-			"http://foo.bar/test-2",
-			"POST",
-			[]byte(`{"foo": "bar"}`),
-			"new value 9",
-			200,
-		},
-		{
-			"returns new cached response",
-			"http://foo.bar/test-2",
-			"POST",
-			[]byte(`{"foo": "bar"}`),
-			"new value 9",
-			200,
-		},
-		{
-			"ignores request body",
-			"http://foo.bar/test-2",
-			"GET",
-			[]byte(`{"foo": "bar"}`),
-			"new value 7",
-			200,
-		},
-		{
-			"returns new response",
-			"http://foo.bar/test-2",
-			"POST",
-			[]byte(`{"foo": "bar"}`),
-			"new value 12",
-			200,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			counter++
-			var r *http.Request
-			var err error
-
-			if counter != 12 {
-				reader := bytes.NewReader(tt.body)
-				r, err = http.NewRequest(tt.method, tt.url, reader)
-				if err != nil {
-					t.Error(err)
-					return
-				}
-			} else {
-				r, err = http.NewRequest(tt.method, tt.url, errReader(0))
-				if err != nil {
-					t.Error(err)
-					return
-				}
-			}
-
-			w := httptest.NewRecorder()
-			handler.ServeHTTP(w, r)
-
-			if !reflect.DeepEqual(w.Code, tt.wantCode) {
-				t.Errorf("*Client.Middleware() = %v, want %v", w.Code, tt.wantCode)
-				return
-			}
-			if !reflect.DeepEqual(w.Body.String(), tt.wantBody) {
-				t.Errorf("*Client.Middleware() = %v, want %v", w.Body.String(), tt.wantBody)
-			}
-		})
-	}
-}
-
-func TestBytesToResponse(t *testing.T) {
-	r := Response{
-		Value:      []byte("value 1"),
-		Expiration: time.Time{},
-		Frequency:  0,
-		LastAccess: time.Time{},
-	}
-
-	tests := []struct {
-		name      string
-		b         []byte
-		wantValue string
-	}{
-
-		{
-			"convert bytes array to response",
-			r.Bytes(),
-			"value 1",
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got := BytesToResponse(tt.b)
-			if string(got.Value) != tt.wantValue {
-				t.Errorf("BytesToResponse() Value = %v, want %v", got, tt.wantValue)
-				return
-			}
-		})
-	}
-}
-
-func TestResponseToBytes(t *testing.T) {
-	r := Response{
-		Value:      nil,
-		Expiration: time.Time{},
-		Frequency:  0,
-		LastAccess: time.Time{},
-	}
-
-	tests := []struct {
-		name     string
-		response Response
-	}{
-		{
-			"convert response to bytes array",
-			r,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			b := tt.response.Bytes()
-			if b == nil || len(b) == 0 {
-				t.Error("Bytes() failed to convert")
-				return
-			}
-		})
-	}
-}
-
-func TestSortURLParams(t *testing.T) {
-	u, _ := url.Parse("http://test.com?zaz=bar&foo=zaz&boo=foo&boo=baz")
-	tests := []struct {
-		name string
-		URL  *url.URL
-		want string
-	}{
-		{
-			"returns url with ordered querystring params",
-			u,
-			"http://test.com?boo=baz&boo=foo&foo=zaz&zaz=bar",
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			sortURLParams(tt.URL)
-			got := tt.URL.String()
-			if got != tt.want {
-				t.Errorf("sortURLParams() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestGenerateKeyString(t *testing.T) {
-	urls := []string{
-		"http://localhost:8080/category",
-		"http://localhost:8080/category/morisco",
-		"http://localhost:8080/category/mourisquinho",
-	}
-
-	keys := make(map[string]string, len(urls))
-	for _, u := range urls {
-		rawKey := generateKey(u)
-		key := KeyAsString(rawKey)
-
-		if otherURL, found := keys[key]; found {
-			t.Fatalf("URLs %s and %s share the same key %s", u, otherURL, key)
-		}
-		keys[key] = u
-	}
-}
-
-func TestGenerateKey(t *testing.T) {
-	tests := []struct {
-		name string
-		URL  string
-		want uint64
-	}{
-		{
-			"get url checksum",
-			"http://foo.bar/test-1",
-			14974843192121052621,
-		},
-		{
-			"get url 2 checksum",
-			"http://foo.bar/test-2",
-			14974839893586167988,
-		},
-		{
-			"get url 3 checksum",
-			"http://foo.bar/test-3",
-			14974840993097796199,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := generateKey(tt.URL); got != tt.want {
-				t.Errorf("generateKey() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestGenerateKeyWithBody(t *testing.T) {
-	tests := []struct {
-		name string
-		URL  string
-		body []byte
-		want uint64
-	}{
-		{
-			"get POST checksum",
-			"http://foo.bar/test-1",
-			[]byte(`{"foo": "bar"}`),
-			16224051135567554746,
-		},
-		{
-			"get POST 2 checksum",
-			"http://foo.bar/test-1",
-			[]byte(`{"bar": "foo"}`),
-			3604153880186288164,
-		},
-		{
-			"get POST 3 checksum",
-			"http://foo.bar/test-2",
-			[]byte(`{"foo": "bar"}`),
-			10956846073361780255,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := generateKeyWithBody(tt.URL, tt.body); got != tt.want {
-				t.Errorf("generateKeyWithBody() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestNewClient(t *testing.T) {
-	adapter := &adapterMock{}
-
-	tests := []struct {
-		name    string
-		opts    []ClientOption
-		want    *Client
-		wantErr bool
-	}{
-		{
-			"returns new client",
-			[]ClientOption{
-				ClientWithAdapter(adapter),
-				ClientWithTTL(1 * time.Millisecond),
-				ClientWithMethods([]string{http.MethodGet, http.MethodPost}),
-			},
-			&Client{
-				adapter:    adapter,
-				ttl:        1 * time.Millisecond,
-				refreshKey: "",
-				methods:    []string{http.MethodGet, http.MethodPost},
-			},
-			false,
-		},
-		{
-			"returns new client with refresh key",
-			[]ClientOption{
-				ClientWithAdapter(adapter),
-				ClientWithTTL(1 * time.Millisecond),
-				ClientWithRefreshKey("rk"),
-			},
-			&Client{
-				adapter:    adapter,
-				ttl:        1 * time.Millisecond,
-				refreshKey: "rk",
-				methods:    []string{http.MethodGet},
-			},
-			false,
-		},
-		{
-			"returns error",
-			[]ClientOption{
-				ClientWithAdapter(adapter),
-			},
-			nil,
-			true,
-		},
-		{
-			"returns error",
-			[]ClientOption{
-				ClientWithTTL(1 * time.Millisecond),
-				ClientWithRefreshKey("rk"),
-			},
-			nil,
-			true,
-		},
-		{
-			"returns error",
-			[]ClientOption{
-				ClientWithAdapter(adapter),
-				ClientWithTTL(0),
-				ClientWithRefreshKey("rk"),
-			},
-			nil,
-			true,
-		},
-		{
-			"returns error",
-			[]ClientOption{
-				ClientWithAdapter(adapter),
-				ClientWithTTL(1 * time.Millisecond),
-				ClientWithMethods([]string{http.MethodGet, http.MethodPut}),
-			},
-			nil,
-			true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := NewClient(tt.opts...)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("NewClient() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("NewClient() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
diff --git a/pkg/cache/memory/memory.go b/pkg/cache/memory/memory.go
deleted file mode 100644
index 0d5e823..0000000
--- a/pkg/cache/memory/memory.go
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
-MIT License
-
-Copyright (c) 2018 Victor Springer
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-package memory
-
-import (
-	"errors"
-	"fmt"
-	"sync"
-	"time"
-
-	cache "github.com/nicolaspernoud/vestibule/pkg/cache"
-)
-
-// Algorithm is the string type for caching algorithms labels.
-type Algorithm string
-
-const (
-	// LRU is the constant for Least Recently Used.
-	LRU Algorithm = "LRU"
-
-	// MRU is the constant for Most Recently Used.
-	MRU Algorithm = "MRU"
-
-	// LFU is the constant for Least Frequently Used.
-	LFU Algorithm = "LFU"
-
-	// MFU is the constant for Most Frequently Used.
-	MFU Algorithm = "MFU"
-)
-
-// Adapter is the memory adapter data structure.
-type Adapter struct {
-	mutex     sync.RWMutex
-	capacity  int
-	algorithm Algorithm
-	store     map[uint64][]byte
-}
-
-// AdapterOptions is used to set Adapter settings.
-type AdapterOptions func(a *Adapter) error
-
-// Get implements the cache Adapter interface Get method.
-func (a *Adapter) Get(key uint64) ([]byte, bool) {
-	a.mutex.RLock()
-	response, ok := a.store[key]
-	a.mutex.RUnlock()
-
-	if ok {
-		return response, true
-	}
-
-	return nil, false
-}
-
-// Set implements the cache Adapter interface Set method.
-func (a *Adapter) Set(key uint64, response []byte, expiration time.Time) {
-	a.mutex.RLock()
-	length := len(a.store)
-	a.mutex.RUnlock()
-
-	if length > 0 && length == a.capacity {
-		a.evict()
-	}
-
-	a.mutex.Lock()
-	a.store[key] = response
-	a.mutex.Unlock()
-}
-
-// Release implements the Adapter interface Release method.
-func (a *Adapter) Release(key uint64) {
-	a.mutex.RLock()
-	_, ok := a.store[key]
-	a.mutex.RUnlock()
-
-	if ok {
-		a.mutex.Lock()
-		delete(a.store, key)
-		a.mutex.Unlock()
-	}
-}
-
-func (a *Adapter) evict() {
-	selectedKey := uint64(0)
-	lastAccess := time.Now()
-	frequency := 2147483647
-
-	if a.algorithm == MRU {
-		lastAccess = time.Time{}
-	} else if a.algorithm == MFU {
-		frequency = 0
-	}
-
-	for k, v := range a.store {
-		r := cache.BytesToResponse(v)
-		switch a.algorithm {
-		case LRU:
-			if r.LastAccess.Before(lastAccess) {
-				selectedKey = k
-				lastAccess = r.LastAccess
-			}
-		case MRU:
-			if r.LastAccess.After(lastAccess) ||
-				r.LastAccess.Equal(lastAccess) {
-				selectedKey = k
-				lastAccess = r.LastAccess
-			}
-		case LFU:
-			if r.Frequency < frequency {
-				selectedKey = k
-				frequency = r.Frequency
-			}
-		case MFU:
-			if r.Frequency >= frequency {
-				selectedKey = k
-				frequency = r.Frequency
-			}
-		}
-	}
-
-	a.Release(selectedKey)
-}
-
-// NewAdapter initializes memory adapter.
-func NewAdapter(opts ...AdapterOptions) (cache.Adapter, error) {
-	a := &Adapter{}
-
-	for _, opt := range opts {
-		if err := opt(a); err != nil {
-			return nil, err
-		}
-	}
-
-	if a.capacity <= 1 {
-		return nil, errors.New("memory adapter capacity is not set")
-	}
-
-	if a.algorithm == "" {
-		return nil, errors.New("memory adapter caching algorithm is not set")
-	}
-
-	a.mutex = sync.RWMutex{}
-	a.store = make(map[uint64][]byte, a.capacity)
-
-	return a, nil
-}
-
-// AdapterWithAlgorithm sets the approach used to select a cached
-// response to be evicted when the capacity is reached.
-func AdapterWithAlgorithm(alg Algorithm) AdapterOptions {
-	return func(a *Adapter) error {
-		a.algorithm = alg
-		return nil
-	}
-}
-
-// AdapterWithCapacity sets the maximum number of cached responses.
-func AdapterWithCapacity(cap int) AdapterOptions {
-	return func(a *Adapter) error {
-		if cap <= 1 {
-			return fmt.Errorf("memory adapter requires a capacity greater than %v", cap)
-		}
-
-		a.capacity = cap
-
-		return nil
-	}
-}
diff --git a/pkg/cache/memory/memory_test.go b/pkg/cache/memory/memory_test.go
deleted file mode 100644
index b0f2dbc..0000000
--- a/pkg/cache/memory/memory_test.go
+++ /dev/null
@@ -1,299 +0,0 @@
-package memory
-
-import (
-	"reflect"
-	"sync"
-	"testing"
-	"time"
-
-	cache "github.com/nicolaspernoud/vestibule/pkg/cache"
-)
-
-func TestGet(t *testing.T) {
-	a := &Adapter{
-		sync.RWMutex{},
-		2,
-		LRU,
-		map[uint64][]byte{
-			14974843192121052621: cache.Response{
-				Value:      []byte("value 1"),
-				Expiration: time.Now(),
-				LastAccess: time.Now(),
-				Frequency:  1,
-			}.Bytes(),
-		},
-	}
-
-	tests := []struct {
-		name string
-		key  uint64
-		want []byte
-		ok   bool
-	}{
-		{
-			"returns right response",
-			14974843192121052621,
-			[]byte("value 1"),
-			true,
-		},
-		{
-			"not found",
-			123,
-			nil,
-			false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			b, ok := a.Get(tt.key)
-			if ok != tt.ok {
-				t.Errorf("memory.Get() ok = %v, tt.ok %v", ok, tt.ok)
-				return
-			}
-			got := cache.BytesToResponse(b).Value
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("memory.Get() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestSet(t *testing.T) {
-	a := &Adapter{
-		sync.RWMutex{},
-		2,
-		LRU,
-		make(map[uint64][]byte),
-	}
-
-	tests := []struct {
-		name     string
-		key      uint64
-		response cache.Response
-	}{
-		{
-			"sets a response cache",
-			1,
-			cache.Response{
-				Value:      []byte("value 1"),
-				Expiration: time.Now().Add(1 * time.Minute),
-			},
-		},
-		{
-			"sets a response cache",
-			2,
-			cache.Response{
-				Value:      []byte("value 2"),
-				Expiration: time.Now().Add(1 * time.Minute),
-			},
-		},
-		{
-			"sets a response cache",
-			3,
-			cache.Response{
-				Value:      []byte("value 3"),
-				Expiration: time.Now().Add(1 * time.Minute),
-			},
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			a.Set(tt.key, tt.response.Bytes(), tt.response.Expiration)
-			if cache.BytesToResponse(a.store[tt.key]).Value == nil {
-				t.Errorf(
-					"memory.Set() error = store[%v] response is not %s", tt.key, tt.response.Value,
-				)
-			}
-		})
-	}
-}
-
-func TestRelease(t *testing.T) {
-	a := &Adapter{
-		sync.RWMutex{},
-		2,
-		LRU,
-		map[uint64][]byte{
-			14974843192121052621: cache.Response{
-				Expiration: time.Now().Add(1 * time.Minute),
-				Value:      []byte("value 1"),
-			}.Bytes(),
-			14974839893586167988: cache.Response{
-				Expiration: time.Now(),
-				Value:      []byte("value 2"),
-			}.Bytes(),
-			14974840993097796199: cache.Response{
-				Expiration: time.Now(),
-				Value:      []byte("value 3"),
-			}.Bytes(),
-		},
-	}
-
-	tests := []struct {
-		name        string
-		key         uint64
-		storeLength int
-		wantErr     bool
-	}{
-		{
-			"removes cached response from store",
-			14974843192121052621,
-			2,
-			false,
-		},
-		{
-			"removes cached response from store",
-			14974839893586167988,
-			1,
-			false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			a.Release(tt.key)
-			if len(a.store) > tt.storeLength {
-				t.Errorf("memory.Release() error; store length = %v, want 0", len(a.store))
-			}
-		})
-	}
-}
-
-func TestEvict(t *testing.T) {
-	tests := []struct {
-		name      string
-		algorithm Algorithm
-	}{
-		{
-			"lru removes third cached response",
-			LRU,
-		},
-		{
-			"mru removes first cached response",
-			MRU,
-		},
-		{
-			"lfu removes second cached response",
-			LFU,
-		},
-		{
-			"mfu removes third cached response",
-			MFU,
-		},
-	}
-	count := 0
-	for _, tt := range tests {
-		count++
-
-		a := &Adapter{
-			sync.RWMutex{},
-			2,
-			tt.algorithm,
-			map[uint64][]byte{
-				14974843192121052621: cache.Response{
-					Value:      []byte("value 1"),
-					Expiration: time.Now().Add(1 * time.Minute),
-					LastAccess: time.Now().Add(-1 * time.Minute),
-					Frequency:  2,
-				}.Bytes(),
-				14974839893586167988: cache.Response{
-					Value:      []byte("value 2"),
-					Expiration: time.Now().Add(1 * time.Minute),
-					LastAccess: time.Now().Add(-2 * time.Minute),
-					Frequency:  1,
-				}.Bytes(),
-				14974840993097796199: cache.Response{
-					Value:      []byte("value 3"),
-					Expiration: time.Now().Add(1 * time.Minute),
-					LastAccess: time.Now().Add(-3 * time.Minute),
-					Frequency:  3,
-				}.Bytes(),
-			},
-		}
-		t.Run(tt.name, func(t *testing.T) {
-			a.evict()
-
-			if count == 1 {
-				if _, ok := a.store[14974840993097796199]; ok {
-					t.Errorf("lru is not working properly")
-					return
-				}
-			} else if count == 2 {
-				if _, ok := a.store[14974843192121052621]; ok {
-					t.Errorf("mru is not working properly")
-					return
-				}
-			} else if count == 3 {
-				if _, ok := a.store[14974839893586167988]; ok {
-					t.Errorf("lfu is not working properly")
-					return
-				}
-			} else {
-				if count == 4 {
-					if _, ok := a.store[14974840993097796199]; ok {
-						t.Errorf("mfu is not working properly")
-					}
-				}
-			}
-		})
-	}
-}
-
-func TestNewAdapter(t *testing.T) {
-	tests := []struct {
-		name    string
-		opts    []AdapterOptions
-		want    cache.Adapter
-		wantErr bool
-	}{
-		{
-			"returns new Adapter",
-			[]AdapterOptions{
-				AdapterWithCapacity(4),
-				AdapterWithAlgorithm(LRU),
-			},
-			&Adapter{
-				sync.RWMutex{},
-				4,
-				LRU,
-				make(map[uint64][]byte),
-			},
-			false,
-		},
-		{
-			"returns error",
-			[]AdapterOptions{
-				AdapterWithAlgorithm(LRU),
-			},
-			nil,
-			true,
-		},
-		{
-			"returns error",
-			[]AdapterOptions{
-				AdapterWithCapacity(4),
-			},
-			nil,
-			true,
-		},
-		{
-			"returns error",
-			[]AdapterOptions{
-				AdapterWithCapacity(1),
-			},
-			nil,
-			true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := NewAdapter(tt.opts...)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("NewAdapter() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("NewAdapter() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-- 
GitLab