test bank.cache
cicd / ci (push) Failing after 17s Details

main
Bel LaPointe 2025-05-23 20:32:49 -06:00
parent 6440b07d14
commit e0fa44eef7
4 changed files with 152 additions and 1 deletions

88
src/bank/cache/cache.go vendored Normal file
View File

@ -0,0 +1,88 @@
package cache
import (
"context"
"encoding/json"
"fmt"
"os"
"path"
"time"
"gogs.inhome.blapointe.com/ana-ledger/src/bank"
)
type Client struct {
Client bank.Agg
}
var _ bank.Agg = Client{}
func New(client bank.Agg) Client {
return Client{Client: client}
}
func (c Client) Accounts(ctx context.Context) ([]bank.Account, error) {
if result := []bank.Account{}; fromCache("accounts", &result) == nil {
return result, nil
}
result, err := c.Client.Accounts(ctx)
if err != nil {
return nil, err
}
toCache("accounts", result)
return result, nil
}
func (c Client) Transactions(ctx context.Context, a bank.Account) ([]bank.Transaction, error) {
if result := []bank.Transaction{}; fromCache(path.Join("accounts", a.Account), &result) == nil {
return result, nil
}
result, err := c.Client.Transactions(ctx, a)
if err != nil {
return nil, err
}
toCache(path.Join("accounts", a.Account), result)
return result, nil
}
var (
d = path.Join("/tmp/ana_ledger_bank_cache.d")
)
func toCache(k string, v interface{}) {
b, err := json.Marshal(v)
if err != nil {
return
}
p := path.Join(d, k)
if err := os.WriteFile(p, b, os.ModePerm); err != nil {
os.Remove(p)
}
}
func fromCache(k string, ptr interface{}) error {
p := path.Join(d, k)
if stat, err := os.Stat(p); err != nil {
return err
} else if time.Since(stat.ModTime()) > time.Hour {
return fmt.Errorf("stale")
}
b, err := os.ReadFile(p)
if err != nil {
return err
}
if err := json.Unmarshal(b, ptr); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,51 @@
//go:build integration
package cache_test
import (
"context"
"strconv"
"testing"
"gogs.inhome.blapointe.com/ana-ledger/src/bank/cache"
"gogs.inhome.blapointe.com/ana-ledger/src/bank/teller"
)
func Test(t *testing.T) {
c, err := teller.New()
if err != nil {
t.Fatal(err)
}
client := cache.New(c)
ctx := context.Background()
for i := 0; i < 2; i++ {
i := i
client := client
t.Run(strconv.Itoa(i), func(t *testing.T) {
accounts, err := c.Accounts(ctx)
if err != nil {
t.Fatal(err)
}
for _, account := range accounts {
account := account
t.Run(account.Account, func(t *testing.T) {
transactions, err := c.Transactions(ctx, account)
if err != nil {
t.Fatal(err)
}
for i, tr := range transactions {
t.Logf("[%d] %+v", i, tr)
}
})
break
}
})
client.Client = nil
}
}

View File

@ -3,6 +3,7 @@ package teller
import (
"context"
"crypto/tls"
_ "embed"
"encoding/json"
"net/http"
"time"
@ -16,8 +17,15 @@ type Client struct {
var _ bank.Agg = Client{}
var (
//go:embed certificate.pem
certificate []byte
//go:embed private_key.pem
privateKey []byte
)
func New() (Client, error) {
cert, err := tls.LoadX509KeyPair("./certificate.pem", "./private_key.pem") // TODO
cert, err := tls.X509KeyPair(certificate, privateKey)
return Client{cert: cert}, err
}

View File

@ -1,6 +1,10 @@
package bank
import "context"
type Agg interface {
Accounts(context.Context) ([]Account, error)
Transactions(context.Context, Account) ([]Transaction, error)
}
type Account struct {