Commit 2d6a4c45 authored by wozz's avatar wozz

update cache and cache tests

parent a69d2e23
......@@ -22,7 +22,7 @@ type cache_load struct {
Resp string
}
type unspent_cache struct {
type cache_exp struct {
Data string
ExpTime time.Time
}
......@@ -40,48 +40,76 @@ func GetCacheKey(i interface{}) (string, bool) {
return "", false
}
func MapCacheRequest(key string, Cache map[interface{}]string) cache_resp {
resp := cache_resp{false, ""}
cached_data, ok := Cache[key]
if ok {
log.Println("Data in Cache:", strings.TrimSpace(cached_data))
resp = cache_resp{true, cached_data}
}
return resp
}
func MapCacheRequestWithExpire(key string, Cache map[interface{}]cache_exp) cache_resp {
resp := cache_resp{false, ""}
cached_data, ok := Cache[key]
if ok {
log.Println("Data in Cache:", strings.TrimSpace(cached_data.Data))
if cached_data.ExpTime.Before(time.Now()) {
log.Println("Data in Cache Expired:", time.Now().Sub(cached_data.ExpTime).Seconds())
} else {
resp = cache_resp{true, cached_data.Data}
}
}
return resp
}
func CacheRequest(scm Stratum_command_msg, TransactionCache map[interface{}]string, UnspentCache map[interface{}]cache_exp, NumBlocks int) cache_resp {
resp := cache_resp{false, ""}
key, keyok := GetCacheKey(scm.Params)
switch scm.Method {
case "blockchain.transaction.get":
if keyok {
resp = MapCacheRequest(key, TransactionCache)
}
case "blockchain.address.listunspent":
if keyok {
resp = MapCacheRequestWithExpire(key, UnspentCache)
}
case "blockchain.numblocks.subscribe":
sr := Stratum_command_resp{
Id: 1,
Result: NumBlocks,
}
msg, err := json.Marshal(sr)
if err != nil {
log.Fatal("json error numblock subscription", err)
}
resp = cache_resp{true, string(msg)}
}
return resp
}
func GetIntFromParams(input interface{}) (int, bool) {
switch p := input.(type) {
case []interface{}:
switch q := p[0].(type) {
case int:
return q, true
}
}
return 0, false
}
func CacheManager(ch *CommHub, exp time.Duration) {
TransactionCache := make(map[interface{}]string)
UnspentCache := make(map[interface{}]unspent_cache)
UnspentCache := make(map[interface{}]cache_exp)
NumBlocks := 0
for {
select {
case cr := <-ch.CacheReq:
resp := cache_resp{false, ""}
scm := cr.stcmd
key, keyok := GetCacheKey(scm.Params)
switch scm.Method {
case "blockchain.transaction.get":
if keyok {
cached_data, ok := TransactionCache[key]
if ok {
log.Println("Data in Cache:", strings.TrimSpace(cached_data))
resp = cache_resp{true, cached_data}
}
}
case "blockchain.address.listunspent":
if keyok {
cached_data, ok := UnspentCache[key]
if ok {
log.Println("Data in Cache:", strings.TrimSpace(cached_data.Data))
if cached_data.ExpTime.Before(time.Now()) {
log.Println("Data in Cache Expired:", time.Now().Sub(cached_data.ExpTime).Seconds())
} else {
resp = cache_resp{true, cached_data.Data}
}
}
}
case "blockchain.numblocks.subscribe":
sr := Stratum_command_resp{
Id: 1,
Result: NumBlocks,
}
msg, err := json.Marshal(sr)
if err != nil {
log.Fatal("json error numblock subscription", err)
}
resp = cache_resp{true, string(msg)}
}
resp := CacheRequest(scm, TransactionCache, UnspentCache, NumBlocks)
cr.retChan <-resp
case cl := <-ch.CacheLoad:
key, keyok := GetCacheKey(cl.StCmdMsg.Params)
......@@ -93,16 +121,13 @@ func CacheManager(ch *CommHub, exp time.Duration) {
case "blockchain.address.listunspent":
if keyok {
exptime := time.Now().Add(exp)
unsp_data := unspent_cache{cl.Resp, exptime}
unsp_data := cache_exp{cl.Resp, exptime}
UnspentCache[key] = unsp_data
}
case "blockchain.numblocks.subscribe":
switch p := cl.StCmdMsg.Params.(type) {
case []interface{}:
switch q := p[0].(type) {
case int:
NumBlocks = q
}
i, ok := GetIntFromParams(cl.StCmdMsg.Params)
if ok {
NumBlocks = i
}
}
}
......
......@@ -73,7 +73,7 @@ func TestLoadCache(t *testing.T) {
done <- cl.Resp
}()
go func() {
time.Sleep(time.Second)
time.Sleep(20 * time.Millisecond)
done <- "timeout"
}()
result := <-done
......@@ -96,7 +96,7 @@ func TestLoadCacheNonCachedMethod(t *testing.T) {
done <- cl.Resp
}()
go func() {
time.Sleep(time.Second)
time.Sleep(20 * time.Millisecond)
done <- "pass"
}()
result := <-done
......@@ -142,3 +142,128 @@ func TestCheckCacheNonCachedMethod(t *testing.T) {
t.Error("Cache value does not match expected result")
}
}
func TestMapCacheRequest(t *testing.T) {
TestCache := make(map[interface{}]string)
TestKey := "testkey1"
TestCache[TestKey] = "value"
resp := MapCacheRequest(TestKey, TestCache)
if !resp.CacheOK {
t.Error("Cache Value Not found when it should be")
}
if resp.CacheVal != "value" {
t.Error("Cache Value Not What it should be")
}
resp = MapCacheRequest("testkey2", TestCache)
if resp.CacheOK {
t.Error("Cache Value Found when it shouldn't be")
}
if resp.CacheVal != "" {
t.Error("Cache Value not blank when it should be")
}
}
func TestMapCacheRequestWithExpire(t *testing.T) {
TestCache := make(map[interface{}]cache_exp)
CurrentTime := time.Now()
TestKey := "testkey1"
CacheValue := cache_exp{
Data: "value",
ExpTime: CurrentTime.Add(-1 * time.Minute),
}
TestCache[TestKey] = CacheValue
resp := MapCacheRequestWithExpire(TestKey, TestCache)
if resp.CacheOK {
t.Error("Cache Value should be expired")
}
if resp.CacheVal != "" {
t.Error("Cache Value should be blank when value is expired")
}
CacheValue = cache_exp{
Data: "value2",
ExpTime: CurrentTime.Add(time.Minute),
}
TestCache[TestKey] = CacheValue
resp = MapCacheRequestWithExpire(TestKey, TestCache)
if !resp.CacheOK {
t.Error("Cache Value should be found")
}
if resp.CacheVal != "value2" {
t.Error("Cache value should be set")
}
resp = MapCacheRequestWithExpire("testkey2", TestCache)
if resp.CacheOK {
t.Error("Cache Value should not be found because key does not exist")
}
if resp.CacheVal != "" {
t.Error("Cache Value should be blank because key does not exist")
}
}
func TestCacheRequest(t *testing.T) {
TestCache1 := make(map[interface{}]string)
TestCache2 := make(map[interface{}]cache_exp)
NumBlocks := 1
scm := Stratum_command_msg{
Id: 1,
Method: "unknown.method",
}
resp := CacheRequest(scm, TestCache1, TestCache2, NumBlocks)
if resp.CacheOK {
t.Error("Cache value found when it should not be")
}
if resp.CacheVal != "" {
t.Error("Cache value not blank when it should be")
}
scm = Stratum_command_msg{
Method: "blockchain.transaction.get",
Params: []interface{}{"key1"},
}
TestCache1["key1"] = "value1"
resp = CacheRequest(scm, TestCache1, TestCache2, NumBlocks)
if !resp.CacheOK {
t.Error("Cache value not found when it should be, value1")
}
if resp.CacheVal != "value1" {
t.Error("Cache Value returned incorrect, should be value1")
}
TestCache2["key1"] = cache_exp{
Data: "value2",
ExpTime: time.Now().Add(time.Minute),
}
scm.Method = "blockchain.address.listunspent"
resp = CacheRequest(scm, TestCache1, TestCache2, NumBlocks)
if !resp.CacheOK {
t.Error("Cache value not found when it should be, value2")
}
if resp.CacheVal != "value2" {
t.Error("Cache value not what it was expected to be, value2")
}
scm.Method = "blockchain.numblocks.subscribe"
resp = CacheRequest(scm, TestCache1, TestCache2, NumBlocks)
if !resp.CacheOK {
t.Error("Cache value for numblocks not found when it should be")
}
if resp.CacheVal != "{\"id\":1,\"result\":1}" {
t.Errorf("Cache value not what it was expected to be: %s", resp.CacheVal)
}
}
func TestGetIntFromParams(t *testing.T) {
input := []interface{}{1}
i, ok := GetIntFromParams(input)
if !ok {
t.Error("Get int from params failed when it shouldn't")
}
if i != 1 {
t.Error("Get int from params returned the wrong value")
}
input2 := 1
i, ok = GetIntFromParams(input2)
if ok {
t.Error("Get int from params did not fail when it should")
}
if i != 0 {
t.Error("Default value for int from params is not 0")
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment