fix(store): r4 — EnsureDir errors + scoped readiness names + purge event timeout on PR #4
Round 4 follow-up to fc77445.
Code:
- import.go: benchmark directory/subdirectory creation now checked
with contextual errors (was silently failing on EnsureDir)
- import.go: terse loop variables expanded in reviewed loops
- scope.go: nil Namespace() guarded
- scope.go: scoped readiness uses 'store.ScopedStore.*' operation
names across wrappers (matching test updated)
Tests:
- publish_test.go: HOME fallback test clears DIR_HOME (was flaky
due to env leakage)
- store_test.go: purge event wait now uses bounded select with
timeout (was hanging on missing event)
- store_test.go: Exists/GroupExists tests no longer swallow fixture
setup errors
Verification: gofmt clean, golangci-lint v2 0 issues, GOWORK=off
go vet + go test -count=1 ./... pass with explicit cache paths.
Closes residual r4 findings on https://github.com/dAppCore/go-store/pull/4
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
parent
fc77445de0
commit
4aeddacb3f
5 changed files with 102 additions and 81 deletions
|
|
@ -281,7 +281,7 @@ func TestCoverage_ScopedStore_Bad_GroupsClosedStore(t *testing.T) {
|
|||
|
||||
_, err := scopedStore.Groups("")
|
||||
assertError(t, err)
|
||||
assertContainsString(t, err.Error(), "store.Groups")
|
||||
assertContainsString(t, err.Error(), "store.ScopedStore.Groups")
|
||||
}
|
||||
|
||||
func TestCoverage_ScopedStore_Bad_GroupsSeqRowsError(t *testing.T) {
|
||||
|
|
|
|||
76
import.go
76
import.go
|
|
@ -186,14 +186,14 @@ func ImportAll(db *DuckDB, cfg ImportConfig, w io.Writer) error {
|
|||
|
||||
if !cfg.SkipM3 && cfg.Scp != nil {
|
||||
core.Print(w, " Pulling training sets from M3...")
|
||||
for _, td := range trainingDirs {
|
||||
for _, rel := range td.files {
|
||||
local := core.JoinPath(trainingRoot, rel)
|
||||
if result := localFs.EnsureDir(core.PathDir(local)); !result.OK {
|
||||
for _, trainingDir := range trainingDirs {
|
||||
for _, relativePath := range trainingDir.files {
|
||||
localPath := core.JoinPath(trainingRoot, relativePath)
|
||||
if result := localFs.EnsureDir(core.PathDir(localPath)); !result.OK {
|
||||
return core.E("store.ImportAll", "ensure training directory", result.Value.(error))
|
||||
}
|
||||
remote := core.Sprintf("%s:/Volumes/Data/lem/%s", m3Host, rel)
|
||||
_ = cfg.Scp(remote, local) // ignore errors, file might not exist
|
||||
remote := core.Sprintf("%s:/Volumes/Data/lem/%s", m3Host, relativePath)
|
||||
_ = cfg.Scp(remote, localPath) // ignore errors, file might not exist
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -216,23 +216,23 @@ func ImportAll(db *DuckDB, cfg ImportConfig, w io.Writer) error {
|
|||
}
|
||||
|
||||
trainingTotal := 0
|
||||
for _, td := range trainingDirs {
|
||||
for _, rel := range td.files {
|
||||
local := core.JoinPath(trainingRoot, rel)
|
||||
if !isFile(local) {
|
||||
for _, trainingDir := range trainingDirs {
|
||||
for _, relativePath := range trainingDir.files {
|
||||
localPath := core.JoinPath(trainingRoot, relativePath)
|
||||
if !isFile(localPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
split := "train"
|
||||
if core.Contains(rel, "valid") {
|
||||
if core.Contains(relativePath, "valid") {
|
||||
split = "valid"
|
||||
} else if core.Contains(rel, "test") {
|
||||
} else if core.Contains(relativePath, "test") {
|
||||
split = "test"
|
||||
}
|
||||
|
||||
n, err := importTrainingFile(importSession, local, td.name, split)
|
||||
n, err := importTrainingFile(importSession, localPath, trainingDir.name, split)
|
||||
if err != nil {
|
||||
return core.E("store.ImportAll", core.Sprintf("import training file %s", local), err)
|
||||
return core.E("store.ImportAll", core.Sprintf("import training file %s", localPath), err)
|
||||
}
|
||||
trainingTotal += n
|
||||
}
|
||||
|
|
@ -242,22 +242,26 @@ func ImportAll(db *DuckDB, cfg ImportConfig, w io.Writer) error {
|
|||
|
||||
// ── 3. Benchmark results ──
|
||||
benchLocal := core.JoinPath(cfg.DataDir, "benchmarks")
|
||||
localFs.EnsureDir(benchLocal)
|
||||
if result := localFs.EnsureDir(benchLocal); !result.OK {
|
||||
return core.E("store.ImportAll", core.Sprintf("ensure benchmark directory %s", benchLocal), result.Value.(error))
|
||||
}
|
||||
|
||||
if !cfg.SkipM3 {
|
||||
core.Print(w, " Pulling benchmarks from M3...")
|
||||
if cfg.Scp != nil {
|
||||
for _, bname := range []string{"truthfulqa", "gsm8k", "do_not_answer", "toxigen"} {
|
||||
remote := core.Sprintf("%s:/Volumes/Data/lem/benchmarks/%s.jsonl", m3Host, bname)
|
||||
_ = cfg.Scp(remote, core.JoinPath(benchLocal, bname+".jsonl"))
|
||||
for _, benchmarkName := range []string{"truthfulqa", "gsm8k", "do_not_answer", "toxigen"} {
|
||||
remote := core.Sprintf("%s:/Volumes/Data/lem/benchmarks/%s.jsonl", m3Host, benchmarkName)
|
||||
_ = cfg.Scp(remote, core.JoinPath(benchLocal, benchmarkName+".jsonl"))
|
||||
}
|
||||
}
|
||||
if cfg.ScpDir != nil {
|
||||
for _, subdir := range []string{"results", "scale_results", "cross_arch_results", "deepseek-r1-7b"} {
|
||||
localSub := core.JoinPath(benchLocal, subdir)
|
||||
localFs.EnsureDir(localSub)
|
||||
remote := core.Sprintf("%s:/Volumes/Data/lem/benchmarks/%s/", m3Host, subdir)
|
||||
_ = cfg.ScpDir(remote, localSub+"/")
|
||||
for _, benchmarkSubdirectory := range []string{"results", "scale_results", "cross_arch_results", "deepseek-r1-7b"} {
|
||||
localSubdirectory := core.JoinPath(benchLocal, benchmarkSubdirectory)
|
||||
if result := localFs.EnsureDir(localSubdirectory); !result.OK {
|
||||
return core.E("store.ImportAll", core.Sprintf("ensure benchmark subdirectory %s", localSubdirectory), result.Value.(error))
|
||||
}
|
||||
remote := core.Sprintf("%s:/Volumes/Data/lem/benchmarks/%s/", m3Host, benchmarkSubdirectory)
|
||||
_ = cfg.ScpDir(remote, localSubdirectory+"/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -275,31 +279,31 @@ func ImportAll(db *DuckDB, cfg ImportConfig, w io.Writer) error {
|
|||
}
|
||||
|
||||
benchTotal := 0
|
||||
for _, subdir := range []string{"results", "scale_results", "cross_arch_results", "deepseek-r1-7b"} {
|
||||
resultDir := core.JoinPath(benchLocal, subdir)
|
||||
for _, benchmarkSubdirectory := range []string{"results", "scale_results", "cross_arch_results", "deepseek-r1-7b"} {
|
||||
resultDir := core.JoinPath(benchLocal, benchmarkSubdirectory)
|
||||
matches := core.PathGlob(core.JoinPath(resultDir, "*.jsonl"))
|
||||
for _, jf := range matches {
|
||||
n, err := importBenchmarkFile(importSession, jf, subdir)
|
||||
for _, jsonFile := range matches {
|
||||
n, err := importBenchmarkFile(importSession, jsonFile, benchmarkSubdirectory)
|
||||
if err != nil {
|
||||
return core.E("store.ImportAll", core.Sprintf("import benchmark file %s", jf), err)
|
||||
return core.E("store.ImportAll", core.Sprintf("import benchmark file %s", jsonFile), err)
|
||||
}
|
||||
benchTotal += n
|
||||
}
|
||||
}
|
||||
|
||||
// Also import standalone benchmark files.
|
||||
for _, bfile := range []string{"lem_bench", "lem_ethics", "lem_ethics_allen", "instruction_tuned", "abliterated", "base_pt"} {
|
||||
local := core.JoinPath(benchLocal, bfile+".jsonl")
|
||||
if !isFile(local) {
|
||||
for _, benchmarkFile := range []string{"lem_bench", "lem_ethics", "lem_ethics_allen", "instruction_tuned", "abliterated", "base_pt"} {
|
||||
localPath := core.JoinPath(benchLocal, benchmarkFile+".jsonl")
|
||||
if !isFile(localPath) {
|
||||
if !cfg.SkipM3 && cfg.Scp != nil {
|
||||
remote := core.Sprintf("%s:/Volumes/Data/lem/benchmarks/%s.jsonl", m3Host, bfile)
|
||||
_ = cfg.Scp(remote, local)
|
||||
remote := core.Sprintf("%s:/Volumes/Data/lem/benchmarks/%s.jsonl", m3Host, benchmarkFile)
|
||||
_ = cfg.Scp(remote, localPath)
|
||||
}
|
||||
}
|
||||
if isFile(local) {
|
||||
n, err := importBenchmarkFile(importSession, local, "benchmark")
|
||||
if isFile(localPath) {
|
||||
n, err := importBenchmarkFile(importSession, localPath, "benchmark")
|
||||
if err != nil {
|
||||
return core.E("store.ImportAll", core.Sprintf("import benchmark file %s", local), err)
|
||||
return core.E("store.ImportAll", core.Sprintf("import benchmark file %s", localPath), err)
|
||||
}
|
||||
benchTotal += n
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ func TestPublish_Publish_Bad_DatasetCardWithoutParquetSplit(t *testing.T) {
|
|||
func TestPublish_ResolveHFToken_Good_UserHomeFallback(t *testing.T) {
|
||||
homeDirectory := t.TempDir()
|
||||
t.Setenv("HF_TOKEN", "")
|
||||
t.Setenv("DIR_HOME", "")
|
||||
t.Setenv("HOME", homeDirectory)
|
||||
|
||||
tokenDirectory := core.JoinPath(homeDirectory, ".huggingface")
|
||||
|
|
|
|||
47
scope.go
47
scope.go
|
|
@ -157,6 +157,9 @@ func (scopedStore *ScopedStore) ensureReady(operation string) error {
|
|||
// Namespace returns the namespace string.
|
||||
// Usage example: `scopedStore := store.NewScoped(storeInstance, "tenant-a"); namespace := scopedStore.Namespace(); fmt.Println(namespace)`
|
||||
func (scopedStore *ScopedStore) Namespace() string {
|
||||
if scopedStore == nil {
|
||||
return ""
|
||||
}
|
||||
return scopedStore.namespace
|
||||
}
|
||||
|
||||
|
|
@ -178,7 +181,7 @@ func (scopedStore *ScopedStore) Config() ScopedStoreConfig {
|
|||
// Usage example: `exists, err := scopedStore.Exists("colour")`
|
||||
// Usage example: `if exists, _ := scopedStore.Exists("token"); !exists { fmt.Println("session expired") }`
|
||||
func (scopedStore *ScopedStore) Exists(key string) (bool, error) {
|
||||
if err := scopedStore.ensureReady("store.Exists"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.Exists"); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return scopedStore.store.Exists(scopedStore.namespacedGroup(scopedStore.defaultGroup()), key)
|
||||
|
|
@ -187,7 +190,7 @@ func (scopedStore *ScopedStore) Exists(key string) (bool, error) {
|
|||
// Usage example: `exists, err := scopedStore.ExistsIn("config", "colour")`
|
||||
// Usage example: `if exists, _ := scopedStore.ExistsIn("session", "token"); !exists { fmt.Println("session expired") }`
|
||||
func (scopedStore *ScopedStore) ExistsIn(group, key string) (bool, error) {
|
||||
if err := scopedStore.ensureReady("store.Exists"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.ExistsIn"); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return scopedStore.store.Exists(scopedStore.namespacedGroup(group), key)
|
||||
|
|
@ -196,7 +199,7 @@ func (scopedStore *ScopedStore) ExistsIn(group, key string) (bool, error) {
|
|||
// Usage example: `exists, err := scopedStore.GroupExists("config")`
|
||||
// Usage example: `if exists, _ := scopedStore.GroupExists("cache"); !exists { fmt.Println("group is empty") }`
|
||||
func (scopedStore *ScopedStore) GroupExists(group string) (bool, error) {
|
||||
if err := scopedStore.ensureReady("store.GroupExists"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.GroupExists"); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return scopedStore.store.GroupExists(scopedStore.namespacedGroup(group))
|
||||
|
|
@ -204,7 +207,7 @@ func (scopedStore *ScopedStore) GroupExists(group string) (bool, error) {
|
|||
|
||||
// Usage example: `colourValue, err := scopedStore.Get("colour")`
|
||||
func (scopedStore *ScopedStore) Get(key string) (string, error) {
|
||||
if err := scopedStore.ensureReady("store.Get"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.Get"); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return scopedStore.store.Get(scopedStore.namespacedGroup(scopedStore.defaultGroup()), key)
|
||||
|
|
@ -213,7 +216,7 @@ func (scopedStore *ScopedStore) Get(key string) (string, error) {
|
|||
// GetFrom reads a key from an explicit namespaced group.
|
||||
// Usage example: `colourValue, err := scopedStore.GetFrom("config", "colour")`
|
||||
func (scopedStore *ScopedStore) GetFrom(group, key string) (string, error) {
|
||||
if err := scopedStore.ensureReady("store.Get"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.GetFrom"); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return scopedStore.store.Get(scopedStore.namespacedGroup(group), key)
|
||||
|
|
@ -221,7 +224,7 @@ func (scopedStore *ScopedStore) GetFrom(group, key string) (string, error) {
|
|||
|
||||
// Usage example: `if err := scopedStore.Set("colour", "blue"); err != nil { return }`
|
||||
func (scopedStore *ScopedStore) Set(key, value string) error {
|
||||
if err := scopedStore.ensureReady("store.Set"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.Set"); err != nil {
|
||||
return err
|
||||
}
|
||||
defaultGroup := scopedStore.defaultGroup()
|
||||
|
|
@ -234,7 +237,7 @@ func (scopedStore *ScopedStore) Set(key, value string) error {
|
|||
// SetIn writes a key to an explicit namespaced group.
|
||||
// Usage example: `if err := scopedStore.SetIn("config", "colour", "blue"); err != nil { return }`
|
||||
func (scopedStore *ScopedStore) SetIn(group, key, value string) error {
|
||||
if err := scopedStore.ensureReady("store.Set"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.SetIn"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := scopedStore.checkQuota("store.ScopedStore.SetIn", group, key); err != nil {
|
||||
|
|
@ -245,7 +248,7 @@ func (scopedStore *ScopedStore) SetIn(group, key, value string) error {
|
|||
|
||||
// Usage example: `if err := scopedStore.SetWithTTL("sessions", "token", "abc123", time.Hour); err != nil { return }`
|
||||
func (scopedStore *ScopedStore) SetWithTTL(group, key, value string, timeToLive time.Duration) error {
|
||||
if err := scopedStore.ensureReady("store.SetWithTTL"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.SetWithTTL"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := scopedStore.checkQuota("store.ScopedStore.SetWithTTL", group, key); err != nil {
|
||||
|
|
@ -256,7 +259,7 @@ func (scopedStore *ScopedStore) SetWithTTL(group, key, value string, timeToLive
|
|||
|
||||
// Usage example: `if err := scopedStore.Delete("config", "colour"); err != nil { return }`
|
||||
func (scopedStore *ScopedStore) Delete(group, key string) error {
|
||||
if err := scopedStore.ensureReady("store.Delete"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.Delete"); err != nil {
|
||||
return err
|
||||
}
|
||||
return scopedStore.store.Delete(scopedStore.namespacedGroup(group), key)
|
||||
|
|
@ -264,7 +267,7 @@ func (scopedStore *ScopedStore) Delete(group, key string) error {
|
|||
|
||||
// Usage example: `if err := scopedStore.DeleteGroup("cache"); err != nil { return }`
|
||||
func (scopedStore *ScopedStore) DeleteGroup(group string) error {
|
||||
if err := scopedStore.ensureReady("store.DeleteGroup"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.DeleteGroup"); err != nil {
|
||||
return err
|
||||
}
|
||||
return scopedStore.store.DeleteGroup(scopedStore.namespacedGroup(group))
|
||||
|
|
@ -273,7 +276,7 @@ func (scopedStore *ScopedStore) DeleteGroup(group string) error {
|
|||
// Usage example: `if err := scopedStore.DeletePrefix("cache"); err != nil { return }`
|
||||
// Usage example: `if err := scopedStore.DeletePrefix(""); err != nil { return }`
|
||||
func (scopedStore *ScopedStore) DeletePrefix(groupPrefix string) error {
|
||||
if err := scopedStore.ensureReady("store.DeletePrefix"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.DeletePrefix"); err != nil {
|
||||
return err
|
||||
}
|
||||
return scopedStore.store.DeletePrefix(scopedStore.namespacedGroup(groupPrefix))
|
||||
|
|
@ -281,7 +284,7 @@ func (scopedStore *ScopedStore) DeletePrefix(groupPrefix string) error {
|
|||
|
||||
// Usage example: `colourEntries, err := scopedStore.GetAll("config")`
|
||||
func (scopedStore *ScopedStore) GetAll(group string) (map[string]string, error) {
|
||||
if err := scopedStore.ensureReady("store.GetAll"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.GetAll"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return scopedStore.store.GetAll(scopedStore.namespacedGroup(group))
|
||||
|
|
@ -289,7 +292,7 @@ func (scopedStore *ScopedStore) GetAll(group string) (map[string]string, error)
|
|||
|
||||
// Usage example: `page, err := scopedStore.GetPage("config", 0, 25); if err != nil { return }; for _, entry := range page { fmt.Println(entry.Key, entry.Value) }`
|
||||
func (scopedStore *ScopedStore) GetPage(group string, offset, limit int) ([]KeyValue, error) {
|
||||
if err := scopedStore.ensureReady("store.GetPage"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.GetPage"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return scopedStore.store.GetPage(scopedStore.namespacedGroup(group), offset, limit)
|
||||
|
|
@ -297,7 +300,7 @@ func (scopedStore *ScopedStore) GetPage(group string, offset, limit int) ([]KeyV
|
|||
|
||||
// Usage example: `for entry, err := range scopedStore.All("config") { if err != nil { break }; fmt.Println(entry.Key, entry.Value) }`
|
||||
func (scopedStore *ScopedStore) All(group string) iter.Seq2[KeyValue, error] {
|
||||
if err := scopedStore.ensureReady("store.All"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.All"); err != nil {
|
||||
return func(yield func(KeyValue, error) bool) {
|
||||
yield(KeyValue{}, err)
|
||||
}
|
||||
|
|
@ -312,7 +315,7 @@ func (scopedStore *ScopedStore) AllSeq(group string) iter.Seq2[KeyValue, error]
|
|||
|
||||
// Usage example: `keyCount, err := scopedStore.Count("config")`
|
||||
func (scopedStore *ScopedStore) Count(group string) (int, error) {
|
||||
if err := scopedStore.ensureReady("store.Count"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.Count"); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return scopedStore.store.Count(scopedStore.namespacedGroup(group))
|
||||
|
|
@ -321,7 +324,7 @@ func (scopedStore *ScopedStore) Count(group string) (int, error) {
|
|||
// Usage example: `keyCount, err := scopedStore.CountAll("config")`
|
||||
// Usage example: `keyCount, err := scopedStore.CountAll()`
|
||||
func (scopedStore *ScopedStore) CountAll(groupPrefix ...string) (int, error) {
|
||||
if err := scopedStore.ensureReady("store.CountAll"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.CountAll"); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return scopedStore.store.CountAll(scopedStore.namespacedGroup(firstStringOrEmpty(groupPrefix)))
|
||||
|
|
@ -330,7 +333,7 @@ func (scopedStore *ScopedStore) CountAll(groupPrefix ...string) (int, error) {
|
|||
// Usage example: `groupNames, err := scopedStore.Groups("config")`
|
||||
// Usage example: `groupNames, err := scopedStore.Groups()`
|
||||
func (scopedStore *ScopedStore) Groups(groupPrefix ...string) ([]string, error) {
|
||||
if err := scopedStore.ensureReady("store.Groups"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.Groups"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupNames, err := scopedStore.store.Groups(scopedStore.namespacedGroup(firstStringOrEmpty(groupPrefix)))
|
||||
|
|
@ -347,7 +350,7 @@ func (scopedStore *ScopedStore) Groups(groupPrefix ...string) ([]string, error)
|
|||
// Usage example: `for groupName, err := range scopedStore.GroupsSeq() { if err != nil { break }; fmt.Println(groupName) }`
|
||||
func (scopedStore *ScopedStore) GroupsSeq(groupPrefix ...string) iter.Seq2[string, error] {
|
||||
return func(yield func(string, error) bool) {
|
||||
if err := scopedStore.ensureReady("store.GroupsSeq"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.GroupsSeq"); err != nil {
|
||||
yield("", err)
|
||||
return
|
||||
}
|
||||
|
|
@ -368,7 +371,7 @@ func (scopedStore *ScopedStore) GroupsSeq(groupPrefix ...string) iter.Seq2[strin
|
|||
|
||||
// Usage example: `renderedTemplate, err := scopedStore.Render("Hello {{ .name }}", "user")`
|
||||
func (scopedStore *ScopedStore) Render(templateSource, group string) (string, error) {
|
||||
if err := scopedStore.ensureReady("store.Render"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.Render"); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return scopedStore.store.Render(templateSource, scopedStore.namespacedGroup(group))
|
||||
|
|
@ -376,7 +379,7 @@ func (scopedStore *ScopedStore) Render(templateSource, group string) (string, er
|
|||
|
||||
// Usage example: `parts, err := scopedStore.GetSplit("config", "hosts", ","); if err != nil { return }; for part := range parts { fmt.Println(part) }`
|
||||
func (scopedStore *ScopedStore) GetSplit(group, key, separator string) (iter.Seq[string], error) {
|
||||
if err := scopedStore.ensureReady("store.GetSplit"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.GetSplit"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return scopedStore.store.GetSplit(scopedStore.namespacedGroup(group), key, separator)
|
||||
|
|
@ -384,7 +387,7 @@ func (scopedStore *ScopedStore) GetSplit(group, key, separator string) (iter.Seq
|
|||
|
||||
// Usage example: `fields, err := scopedStore.GetFields("config", "flags"); if err != nil { return }; for field := range fields { fmt.Println(field) }`
|
||||
func (scopedStore *ScopedStore) GetFields(group, key string) (iter.Seq[string], error) {
|
||||
if err := scopedStore.ensureReady("store.GetFields"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.GetFields"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return scopedStore.store.GetFields(scopedStore.namespacedGroup(group), key)
|
||||
|
|
@ -392,7 +395,7 @@ func (scopedStore *ScopedStore) GetFields(group, key string) (iter.Seq[string],
|
|||
|
||||
// Usage example: `removedRows, err := scopedStore.PurgeExpired(); if err != nil { return }; fmt.Println(removedRows)`
|
||||
func (scopedStore *ScopedStore) PurgeExpired() (int64, error) {
|
||||
if err := scopedStore.ensureReady("store.PurgeExpired"); err != nil {
|
||||
if err := scopedStore.ensureReady("store.ScopedStore.PurgeExpired"); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -415,10 +415,11 @@ func TestStore_Set_Bad_ClosedStore(t *testing.T) {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestStore_Exists_Good_Present(t *testing.T) {
|
||||
storeInstance, _ := New(":memory:")
|
||||
storeInstance, err := New(":memory:")
|
||||
assertNoError(t, err)
|
||||
defer func() { _ = storeInstance.Close() }()
|
||||
|
||||
_ = storeInstance.Set("config", "colour", "blue")
|
||||
assertNoError(t, storeInstance.Set("config", "colour", "blue"))
|
||||
|
||||
exists, err := storeInstance.Exists("config", "colour")
|
||||
assertNoError(t, err)
|
||||
|
|
@ -426,7 +427,8 @@ func TestStore_Exists_Good_Present(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStore_Exists_Good_Absent(t *testing.T) {
|
||||
storeInstance, _ := New(":memory:")
|
||||
storeInstance, err := New(":memory:")
|
||||
assertNoError(t, err)
|
||||
defer func() { _ = storeInstance.Close() }()
|
||||
|
||||
exists, err := storeInstance.Exists("config", "colour")
|
||||
|
|
@ -435,10 +437,11 @@ func TestStore_Exists_Good_Absent(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStore_Exists_Good_ExpiredKeyReturnsFalse(t *testing.T) {
|
||||
storeInstance, _ := New(":memory:")
|
||||
storeInstance, err := New(":memory:")
|
||||
assertNoError(t, err)
|
||||
defer func() { _ = storeInstance.Close() }()
|
||||
|
||||
_ = storeInstance.SetWithTTL("session", "token", "abc123", 1*time.Millisecond)
|
||||
assertNoError(t, storeInstance.SetWithTTL("session", "token", "abc123", 1*time.Millisecond))
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
|
||||
exists, err := storeInstance.Exists("session", "token")
|
||||
|
|
@ -447,9 +450,10 @@ func TestStore_Exists_Good_ExpiredKeyReturnsFalse(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStore_Exists_Bad_ClosedStore(t *testing.T) {
|
||||
storeInstance, _ := New(":memory:")
|
||||
_ = storeInstance.Close()
|
||||
_, err := storeInstance.Exists("g", "k")
|
||||
storeInstance, err := New(":memory:")
|
||||
assertNoError(t, err)
|
||||
assertNoError(t, storeInstance.Close())
|
||||
_, err = storeInstance.Exists("g", "k")
|
||||
assertError(t, err)
|
||||
}
|
||||
|
||||
|
|
@ -458,10 +462,11 @@ func TestStore_Exists_Bad_ClosedStore(t *testing.T) {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestStore_GroupExists_Good_Present(t *testing.T) {
|
||||
storeInstance, _ := New(":memory:")
|
||||
storeInstance, err := New(":memory:")
|
||||
assertNoError(t, err)
|
||||
defer func() { _ = storeInstance.Close() }()
|
||||
|
||||
_ = storeInstance.Set("config", "colour", "blue")
|
||||
assertNoError(t, storeInstance.Set("config", "colour", "blue"))
|
||||
|
||||
exists, err := storeInstance.GroupExists("config")
|
||||
assertNoError(t, err)
|
||||
|
|
@ -469,7 +474,8 @@ func TestStore_GroupExists_Good_Present(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStore_GroupExists_Good_Absent(t *testing.T) {
|
||||
storeInstance, _ := New(":memory:")
|
||||
storeInstance, err := New(":memory:")
|
||||
assertNoError(t, err)
|
||||
defer func() { _ = storeInstance.Close() }()
|
||||
|
||||
exists, err := storeInstance.GroupExists("config")
|
||||
|
|
@ -478,11 +484,12 @@ func TestStore_GroupExists_Good_Absent(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStore_GroupExists_Good_EmptyAfterDelete(t *testing.T) {
|
||||
storeInstance, _ := New(":memory:")
|
||||
storeInstance, err := New(":memory:")
|
||||
assertNoError(t, err)
|
||||
defer func() { _ = storeInstance.Close() }()
|
||||
|
||||
_ = storeInstance.Set("config", "colour", "blue")
|
||||
_ = storeInstance.DeleteGroup("config")
|
||||
assertNoError(t, storeInstance.Set("config", "colour", "blue"))
|
||||
assertNoError(t, storeInstance.DeleteGroup("config"))
|
||||
|
||||
exists, err := storeInstance.GroupExists("config")
|
||||
assertNoError(t, err)
|
||||
|
|
@ -490,9 +497,10 @@ func TestStore_GroupExists_Good_EmptyAfterDelete(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStore_GroupExists_Bad_ClosedStore(t *testing.T) {
|
||||
storeInstance, _ := New(":memory:")
|
||||
_ = storeInstance.Close()
|
||||
_, err := storeInstance.GroupExists("config")
|
||||
storeInstance, err := New(":memory:")
|
||||
assertNoError(t, err)
|
||||
assertNoError(t, storeInstance.Close())
|
||||
_, err = storeInstance.GroupExists("config")
|
||||
assertError(t, err)
|
||||
}
|
||||
|
||||
|
|
@ -1622,7 +1630,8 @@ func TestStore_PurgeExpired_Good(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStore_PurgeExpired_Good_NotifiesDeletedRows(t *testing.T) {
|
||||
storeInstance, _ := New(":memory:")
|
||||
storeInstance, err := New(":memory:")
|
||||
assertNoError(t, err)
|
||||
defer func() { _ = storeInstance.Close() }()
|
||||
|
||||
assertNoError(t, storeInstance.SetWithTTL("g", "expired", "1", 1*time.Millisecond))
|
||||
|
|
@ -1636,10 +1645,14 @@ func TestStore_PurgeExpired_Good_NotifiesDeletedRows(t *testing.T) {
|
|||
assertNoError(t, err)
|
||||
assertEqual(t, int64(1), removed)
|
||||
|
||||
event := <-events
|
||||
assertEqual(t, EventDelete, event.Type)
|
||||
assertEqual(t, "g", event.Group)
|
||||
assertEqual(t, "expired", event.Key)
|
||||
select {
|
||||
case event := <-events:
|
||||
assertEqual(t, EventDelete, event.Type)
|
||||
assertEqual(t, "g", event.Group)
|
||||
assertEqual(t, "expired", event.Key)
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("timed out waiting for purge delete event")
|
||||
}
|
||||
select {
|
||||
case extraEvent := <-events:
|
||||
t.Fatalf("unexpected extra purge event: %#v", extraEvent)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue