test bank.cache
cicd / ci (push) Failing after 17s
Details
cicd / ci (push) Failing after 17s
Details
parent
6440b07d14
commit
e0fa44eef7
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue