package app import ( "fmt" "time" . "code.hoteas.com/golang/hotime" . "code.hoteas.com/golang/hotime/common" ) // CacheCtr 缓存测试控制器(数据库无关) var CacheCtr = Ctr{ "all": func(that *Context) { that.Display(0, testCacheAll(that)) }, "compat": func(that *Context) { that.Display(0, testCacheCompatible(that)) }, "batch": func(that *Context) { that.Display(0, Map{"message": "批量缓存测试完成,请查看控制台输出和日志文件"}) }, } func testCacheAll(that *Context) Map { result := Map{"name": "数据库缓存测试", "tests": Slice{}} tests := Slice{} cacheMode := "unknown" if that.Application.HoTimeCache != nil && that.Application.HoTimeCache.Config != nil { dbConfig := that.Application.HoTimeCache.Config.GetMap("db") if dbConfig != nil { cacheMode = dbConfig.GetString("mode") if cacheMode == "" { cacheMode = "new" } } } result["cache_mode"] = cacheMode testPrefix := fmt.Sprintf("cache_test_%d_", time.Now().UnixNano()) // 1. 基础读写测试 test1 := Map{"name": "1. 基础 set/get 测试"} testKey1 := testPrefix + "basic" testValue1 := Map{"name": "测试数据", "count": 123, "active": true} that.Application.Cache(testKey1, testValue1) cached1 := that.Application.Cache(testKey1) if cached1.Data != nil { cachedMap := cached1.ToMap() test1["result"] = cachedMap.GetString("name") == "测试数据" && cachedMap.GetInt("count") == 123 test1["cached_value"] = cachedMap } else { test1["result"] = false test1["error"] = "缓存读取返回 nil" } tests = append(tests, test1) // 2. 删除缓存测试 test2 := Map{"name": "2. delete 删除缓存测试"} testKey2 := testPrefix + "delete" that.Application.Cache(testKey2, "删除测试值") before := that.Application.Cache(testKey2) beforeExists := before.Data != nil that.Application.Cache(testKey2, nil) after := that.Application.Cache(testKey2) afterExists := after.Data != nil test2["result"] = beforeExists && !afterExists test2["before_exists"] = beforeExists test2["after_exists"] = afterExists tests = append(tests, test2) // 3. 过期时间测试 test3 := Map{"name": "3. 过期时间测试(短超时)"} testKey3 := testPrefix + "expire" that.Application.Cache(testKey3, "短期数据", 2) immediate := that.Application.Cache(testKey3) immediateExists := immediate.Data != nil test3["result"] = immediateExists test3["immediate_exists"] = immediateExists test3["note"] = "设置了2秒过期,可等待后再次访问验证过期" tests = append(tests, test3) // 4. 不存在的 key 读取测试 test4 := Map{"name": "4. 不存在的 key 读取测试"} nonExistKey := testPrefix + "non_exist_key_" + fmt.Sprintf("%d", time.Now().UnixNano()) nonExist := that.Application.Cache(nonExistKey) test4["result"] = nonExist.Data == nil test4["value"] = nonExist.Data tests = append(tests, test4) // 5. 重复 set 同一个 key 测试 test5 := Map{"name": "5. 重复 set 同一个 key 测试"} testKey5 := testPrefix + "repeat" that.Application.Cache(testKey5, "第一次值") first := that.Application.Cache(testKey5).ToStr() that.Application.Cache(testKey5, "第二次值") second := that.Application.Cache(testKey5).ToStr() that.Application.Cache(testKey5, Map{"version": 3}) third := that.Application.Cache(testKey5).ToMap() test5["result"] = first == "第一次值" && second == "第二次值" && third.GetInt("version") == 3 test5["first"] = first test5["second"] = second test5["third"] = third tests = append(tests, test5) // 6. 通配删除测试 test6 := Map{"name": "6. 通配删除测试 (key*)"} wildcardPrefix := testPrefix + "wildcard_" that.Application.Cache(wildcardPrefix+"a", "值A") that.Application.Cache(wildcardPrefix+"b", "值B") that.Application.Cache(wildcardPrefix+"c", "值C") aExists := that.Application.Cache(wildcardPrefix+"a").Data != nil bExists := that.Application.Cache(wildcardPrefix+"b").Data != nil cExists := that.Application.Cache(wildcardPrefix+"c").Data != nil allExistBefore := aExists && bExists && cExists that.Application.Cache(wildcardPrefix+"*", nil) aAfter := that.Application.Cache(wildcardPrefix+"a").Data != nil bAfter := that.Application.Cache(wildcardPrefix+"b").Data != nil cAfter := that.Application.Cache(wildcardPrefix+"c").Data != nil allDeletedAfter := !aAfter && !bAfter && !cAfter test6["result"] = allExistBefore && allDeletedAfter test6["before"] = Map{"a": aExists, "b": bExists, "c": cExists} test6["after"] = Map{"a": aAfter, "b": bAfter, "c": cAfter} tests = append(tests, test6) // 7. 不同数据类型测试 test7 := Map{"name": "7. 不同数据类型存储测试"} that.Application.Cache(testPrefix+"type_string", "字符串值") typeString := that.Application.Cache(testPrefix + "type_string").ToStr() that.Application.Cache(testPrefix+"type_int", 12345) typeInt := that.Application.Cache(testPrefix + "type_int").ToInt() that.Application.Cache(testPrefix+"type_float", 3.14159) typeFloat := that.Application.Cache(testPrefix + "type_float").ToFloat64() that.Application.Cache(testPrefix+"type_bool", true) typeBoolData := that.Application.Cache(testPrefix + "type_bool").Data typeBool := typeBoolData == true || typeBoolData == "true" || typeBoolData == 1.0 that.Application.Cache(testPrefix+"type_map", Map{"key": "value", "num": 100}) typeMap := that.Application.Cache(testPrefix + "type_map").ToMap() that.Application.Cache(testPrefix+"type_slice", Slice{1, 2, 3, "four", Map{"five": 5}}) typeSlice := that.Application.Cache(testPrefix + "type_slice").ToSlice() test7["result"] = typeString == "字符串值" && typeInt == 12345 && typeFloat > 3.14 && typeFloat < 3.15 && typeBool == true && typeMap.GetString("key") == "value" && len(typeSlice) == 5 test7["string"] = typeString test7["int"] = typeInt test7["float"] = typeFloat test7["bool"] = typeBool test7["map"] = typeMap test7["slice"] = typeSlice tests = append(tests, test7) // 8. 自定义超时时间测试 test8 := Map{"name": "8. 自定义超时时间参数测试"} testKey8 := testPrefix + "custom_timeout" that.Application.Cache(testKey8, "长期数据", 3600) longTerm := that.Application.Cache(testKey8) test8["result"] = longTerm.Data != nil test8["value"] = longTerm.ToStr() tests = append(tests, test8) // 9. 查询缓存表状态 test9 := Map{"name": "9. 缓存表状态查询"} prefix := that.Db.GetPrefix() newTableName := prefix + "hotime_cache" newCount := that.Db.Count(newTableName) test9["new_table_count"] = newCount test9["new_table_name"] = newTableName test9["result"] = newCount >= 0 tests = append(tests, test9) that.Application.Cache(testPrefix+"*", nil) result["tests"] = tests result["success"] = true result["cleanup"] = "已清理所有测试缓存数据" return result } func testCacheCompatible(that *Context) Map { result := Map{ "test_name": "兼容模式白盒测试", "timestamp": time.Now().Format("2006-01-02 15:04:05"), } prefix := that.Db.GetPrefix() newTableName := prefix + "hotime_cache" legacyTableName := prefix + "cached" tests := Slice{} test1 := Map{"name": "1. 查询当前缓存模式"} cacheConfig := that.Application.Config.GetMap("cache") dbConfig := cacheConfig.GetMap("db") mode := dbConfig.GetString("mode") if mode == "" { mode = "默认(compatible)" } test1["mode"] = mode test1["result"] = true tests = append(tests, test1) // 根据数据库类型使用不同的引号 q := "`" if that.Db.Dialect != nil { q = that.Db.Dialect.QuoteChar() } test2 := Map{"name": "2. 查询老表cached现有数据"} legacyData := that.Db.Query("SELECT * FROM " + q + legacyTableName + q + " LIMIT 5") test2["legacy_table"] = legacyTableName test2["count"] = len(legacyData) test2["data"] = legacyData test2["result"] = true tests = append(tests, test2) test3 := Map{"name": "3. 查询新表hotime_cache现有数据"} newData := that.Db.Query("SELECT * FROM " + q + newTableName + q + " LIMIT 5") test3["new_table"] = newTableName test3["count"] = len(newData) test3["data"] = newData test3["result"] = true tests = append(tests, test3) test4 := Map{"name": "4. 测试兼容模式老表回退读取"} testKey4 := "test_compat_fallback_" + ObjToStr(time.Now().UnixNano()) testValue4 := Map{"admin_id": 999, "admin_name": "测试老数据"} testValueJson4 := ObjToStr(Map{"data": testValue4}) that.Db.Insert(legacyTableName, Map{ "key": testKey4, "value": testValueJson4, "endtime": time.Now().Unix() + 3600, "time": time.Now().UnixNano(), }) test4["test_key"] = testKey4 newExists := that.Db.Get(newTableName, "*", Map{"key": testKey4}) test4["key_in_new_table"] = newExists != nil cacheValue := that.Application.Cache(testKey4) test4["cache_api_result"] = cacheValue.Data test4["result"] = newExists == nil && cacheValue.Data != nil tests = append(tests, test4) test5 := Map{"name": "5. 测试兼容模式写新删老"} testKey5 := "test_compat_write_" + ObjToStr(time.Now().UnixNano()) testValue5 := "兼容模式测试数据" that.Db.Insert(legacyTableName, Map{ "key": testKey5, "value": `{"data":"老表原始数据"}`, "endtime": time.Now().Unix() + 3600, "time": time.Now().UnixNano(), }) legacyBefore := that.Db.Get(legacyTableName, "*", Map{"key": testKey5}) test5["step1_legacy_before"] = legacyBefore != nil that.Application.Cache(testKey5, testValue5) newAfter := that.Db.Get(newTableName, "*", Map{"key": testKey5}) test5["step2_new_after"] = newAfter != nil if newAfter != nil { test5["new_value"] = newAfter.GetString("value") } legacyAfter := that.Db.Get(legacyTableName, "*", Map{"key": testKey5}) test5["step3_legacy_after_deleted"] = legacyAfter == nil test5["result"] = legacyBefore != nil && newAfter != nil && legacyAfter == nil tests = append(tests, test5) test6 := Map{"name": "6. 测试兼容模式删除(删除两表)"} testKey6 := "test_compat_delete_" + ObjToStr(time.Now().UnixNano()) that.Db.Insert(legacyTableName, Map{ "key": testKey6, "value": `{"data":"待删除老数据"}`, "endtime": time.Now().Unix() + 3600, "time": time.Now().UnixNano(), }) that.Db.Insert(newTableName, Map{ "key": testKey6, "value": `"待删除新数据"`, "end_time": time.Now().Add(time.Hour).Format("2006-01-02 15:04:05"), "state": 0, "create_time": time.Now().Format("2006-01-02 15:04:05"), "modify_time": time.Now().Format("2006-01-02 15:04:05"), }) test6["before_legacy"] = that.Db.Get(legacyTableName, "*", Map{"key": testKey6}) != nil test6["before_new"] = that.Db.Get(newTableName, "*", Map{"key": testKey6}) != nil that.Application.Cache(testKey6, nil) test6["after_legacy_deleted"] = that.Db.Get(legacyTableName, "*", Map{"key": testKey6}) == nil test6["after_new_deleted"] = that.Db.Get(newTableName, "*", Map{"key": testKey6}) == nil test6["result"] = test6.GetBool("before_legacy") && test6.GetBool("before_new") && test6.GetBool("after_legacy_deleted") && test6.GetBool("after_new_deleted") tests = append(tests, test6) that.Db.Delete(newTableName, Map{"key[~]": "test_compat_%"}) that.Db.Delete(legacyTableName, Map{"key[~]": "test_compat_%"}) result["tests"] = tests result["success"] = true return result }