This commit is contained in:
HappyHakunaMatata 2024-09-03 21:32:11 +02:00
parent 215990860b
commit 80ea41600f
13 changed files with 1811 additions and 250 deletions

View file

@ -1,11 +1,8 @@
package core package core
import ( import (
"bytes"
"crypto/ed25519" "crypto/ed25519"
"encoding/binary"
"encoding/json" "encoding/json"
"fmt"
"net" "net"
"net/url" "net/url"
"sync/atomic" "sync/atomic"
@ -253,29 +250,3 @@ func (c *Core) SetAdmin(a AddHandler) error {
} }
return nil return nil
} }
func (peerinfo PeerInfo) GetCoordinates() *[]byte {
var coordsBlob []byte
if peerinfo.Coords != nil {
coordsBlob = make([]byte, len(peerinfo.Coords)*8)
for i, coord := range peerinfo.Coords {
binary.LittleEndian.PutUint64(coordsBlob[i*8:], coord)
}
}
return &coordsBlob
}
func (peerinfo PeerInfo) SetCoordinates(coords *[]byte) error {
if len(*coords)%8 != 0 {
return fmt.Errorf("length of byte slice must be a multiple of 8")
}
numUint64 := len(*coords) / 8
buf := bytes.NewReader(*coords)
for i := 0; i < numUint64; i++ {
err := binary.Read(buf, binary.LittleEndian, &peerinfo.Coords[i])
if err != nil {
return err
}
}
return nil
}

178
src/core/db.go Normal file
View file

@ -0,0 +1,178 @@
package core
import (
"bytes"
"crypto/ed25519"
"crypto/x509"
"database/sql"
"encoding/binary"
"errors"
"fmt"
)
type PeerInfoDB struct {
PeerInfo
Id int
CoordsBytes []byte
KeyBytes []byte
RootBytes []byte
PeerErr sql.NullString
}
type SelfInfoDB struct {
SelfInfo
Id int
KeyBytes []byte
}
type TreeEntryInfoDB struct {
TreeEntryInfo
Id int
KeyBytes []byte
ParentBytes []byte
}
type PathEntryInfoDB struct {
PathEntryInfo
Id int
KeyBytes []byte
PathBytes []byte
}
type SessionInfoDB struct {
SessionInfo
Id int
KeyBytes []byte
}
func NewPeerInfoDB(peerInfo PeerInfo) (_ *PeerInfoDB, err error) {
peer := &PeerInfoDB{
PeerInfo: peerInfo,
}
peer.PeerErr = MarshalError(peer.LastError)
peer.CoordsBytes = ConvertToByteSlise(peer.Coords)
peer.KeyBytes, err = MarshalPKIXPublicKey(&peer.Key)
if err != nil {
return nil, err
}
peer.RootBytes, err = MarshalPKIXPublicKey(&peer.Root)
if err != nil {
return nil, err
}
return peer, nil
}
func NewSelfInfoDB(selfinfo SelfInfo) (_ *SelfInfoDB, err error) {
model := &SelfInfoDB{
SelfInfo: selfinfo,
}
model.KeyBytes, err = MarshalPKIXPublicKey(&model.Key)
if err != nil {
return nil, err
}
return model, nil
}
func NewTreeEntryInfoDB(treeEntyInfo TreeEntryInfo) (_ *TreeEntryInfoDB, err error) {
model := &TreeEntryInfoDB{
TreeEntryInfo: treeEntyInfo,
}
model.KeyBytes, err = MarshalPKIXPublicKey(&model.Key)
if err != nil {
return nil, err
}
model.ParentBytes, err = MarshalPKIXPublicKey(&model.Parent)
if err != nil {
return nil, err
}
return model, nil
}
func NewPathEntryInfoDB(PathEntryInfo PathEntryInfo) (_ *PathEntryInfoDB, err error) {
model := &PathEntryInfoDB{
PathEntryInfo: PathEntryInfo,
}
model.KeyBytes, err = MarshalPKIXPublicKey(&model.Key)
if err != nil {
return nil, err
}
model.PathBytes = ConvertToByteSlise(model.Path)
return model, nil
}
func NewSessionInfoDB(SessionInfo SessionInfo) (_ *SessionInfoDB, err error) {
model := &SessionInfoDB{
SessionInfo: SessionInfo,
}
model.KeyBytes, err = MarshalPKIXPublicKey(&model.Key)
if err != nil {
return nil, err
}
return model, nil
}
func ConvertToByteSlise(uintSlise []uint64) []byte {
var ByteSlise []byte
if uintSlise != nil {
ByteSlise = make([]byte, len(uintSlise)*8)
for i, coord := range uintSlise {
binary.LittleEndian.PutUint64(ByteSlise[i*8:], coord)
}
}
return ByteSlise
}
func ConvertToUintSlise(ByteSlise []byte) (_ []uint64, err error) {
if len(ByteSlise)%8 != 0 {
return nil, fmt.Errorf("length of byte slice must be a multiple of 8")
}
var uintSlise []uint64
length := len(ByteSlise) / 8
uintSlise = make([]uint64, length)
reader := bytes.NewReader(ByteSlise)
for i := 0; i < length; i++ {
err := binary.Read(reader, binary.LittleEndian, &uintSlise[i])
if err != nil {
return nil, err
}
}
return uintSlise, nil
}
func MarshalPKIXPublicKey(PublicKey *ed25519.PublicKey) ([]byte, error) {
pkey, err := x509.MarshalPKIXPublicKey(*PublicKey)
if err != nil {
return nil, err
}
return pkey, nil
}
func ParsePKIXPublicKey(derBytes *[]byte) (PublicKey ed25519.PublicKey, err error) {
key, err := x509.ParsePKIXPublicKey(*derBytes)
if err != nil {
return nil, err
}
return key.(ed25519.PublicKey), nil
}
func ParseError(PeerErr sql.NullString) error {
if PeerErr.Valid {
return errors.New(PeerErr.String)
}
return nil
}
func MarshalError(err error) sql.NullString {
if err != nil {
return sql.NullString{
String: err.Error(),
Valid: true,
}
} else {
return sql.NullString{
String: "",
Valid: false,
}
}
}

View file

@ -0,0 +1,108 @@
package pathentryinfodb
import (
"database/sql"
"fmt"
"os"
"path/filepath"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
"github.com/yggdrasil-network/yggdrasil-go/src/db"
)
type PathEntryInfoDBConfig struct {
DbConfig *db.DbConfig
name string
}
var Name = "PathEntryInfo"
func New() (*PathEntryInfoDBConfig, error) {
dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name)
filePath := filepath.Join(dir, fileName)
schemas := []string{
`CREATE TABLE IF NOT EXISTS path_entry_info (
Id INTEGER NOT NULL PRIMARY KEY,
Key BLOB,
Path BLOB,
Sequence INTEGER
);`}
dbcfg, err := db.New("sqlite3", &schemas, filePath)
if err != nil {
return nil, err
}
cfg := &PathEntryInfoDBConfig{
name: Name,
DbConfig: dbcfg,
}
return cfg, nil
}
func (cfg *PathEntryInfoDBConfig) Add(model *core.PathEntryInfoDB) (_ sql.Result, err error) {
query := "INSERT INTO path_entry_info (Key, Path, Sequence) VALUES (?, ?, ?)"
result, err := cfg.DbConfig.DB.Exec(
query,
model.KeyBytes,
model.PathBytes,
model.Sequence)
if err != nil {
return nil, err
}
lastInsertId, err := result.LastInsertId()
if err != nil {
return nil, err
}
model.Id = int(lastInsertId)
return result, nil
}
func (cfg *PathEntryInfoDBConfig) Remove(model *core.PathEntryInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec("DELETE FROM path_entry_info WHERE Id = ?",
model.Id)
if err != nil {
return err
}
return nil
}
func (cfg *PathEntryInfoDBConfig) Update(model *core.PathEntryInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec(`UPDATE path_entry_info
SET
Sequence = ?,
Key = ?,
Path = ?
WHERE
Id = ?`,
model.Sequence, model.KeyBytes, model.PathBytes, model.Id)
if err != nil {
return err
}
return nil
}
func (cfg *PathEntryInfoDBConfig) Get(model *core.PathEntryInfoDB) (_ *sql.Rows, err error) {
rows, err := cfg.DbConfig.DB.Query("SELECT Sequence, Key, Path FROM path_entry_info WHERE Id = ?",
model.Id,
)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&model.Sequence, &model.KeyBytes, &model.PathBytes)
if err != nil {
return nil, err
}
}
return rows, nil
}
func (cfg *PathEntryInfoDBConfig) Count() (int, error) {
var count int
err := cfg.DbConfig.DB.QueryRow("SELECT COUNT(*) FROM path_entry_info").Scan(&count)
if err != nil {
return 0, err
}
return count, nil
}

View file

@ -1,9 +1,7 @@
package peerinfodb package peerinfodb
import ( import (
"crypto/ed25519" "database/sql"
"crypto/x509"
"encoding/binary"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -26,19 +24,20 @@ func New() (*PeerInfoDBConfig, error) {
filePath := filepath.Join(dir, fileName) filePath := filepath.Join(dir, fileName)
schemas := []string{ schemas := []string{
`CREATE TABLE IF NOT EXISTS peer_infos ( `CREATE TABLE IF NOT EXISTS peer_infos (
Id INTEGER NOT NULL PRIMARY KEY,
uri TEXT, uri TEXT,
up BOOLEAN, up INTEGER,
inbound BOOLEAN, inbound INTEGER,
last_error VARCHAR, last_error TEXT NULL,
last_error_time TIMESTAMP, last_error_time TIMESTAMP NULL,
key VARCHAR, key BLOB,
root VARCHAR, root BLOB,
coords VARCHAR, coords BLOB,
port INT, port INT,
priority TINYINT, priority TINYINT,
Rxbytes BIGINT, Rxbytes BIGINT,
Txbytes BIGINT, Txbytes BIGINT,
uptime BIGINT, uptime INTEGER,
latency SMALLINT latency SMALLINT
);`} );`}
dbcfg, err := db.New("sqlite3", &schemas, filePath) dbcfg, err := db.New("sqlite3", &schemas, filePath)
@ -52,132 +51,84 @@ func New() (*PeerInfoDBConfig, error) {
return cfg, nil return cfg, nil
} }
func (cfg *PeerInfoDBConfig) AddPeer(peer core.PeerInfo) (err error) { func (cfg *PeerInfoDBConfig) Add(model *core.PeerInfoDB) (_ sql.Result, err error) {
var key, root []byte query := "INSERT OR REPLACE INTO peer_infos (uri, up, inbound, last_error, last_error_time, key, root, coords, port, priority, Rxbytes, Txbytes, uptime, latency) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
if peer.Key != nil { result, err := cfg.DbConfig.DB.Exec(query,
key, err = x509.MarshalPKIXPublicKey(peer.Key) model.URI,
model.Up,
model.Inbound,
model.PeerErr,
model.LastErrorTime,
model.KeyBytes,
model.RootBytes,
model.CoordsBytes,
model.Port,
model.Priority,
model.RXBytes,
model.TXBytes,
model.Uptime,
model.Latency)
if err != nil { if err != nil {
return err return nil, err
} }
} LastInsertId, err := result.LastInsertId()
if peer.Root != nil {
root, err = x509.MarshalPKIXPublicKey(peer.Root)
if err != nil { if err != nil {
return err return nil, err
} }
} model.Id = int(LastInsertId)
var peerErr interface{} return result, nil
if peer.LastError != nil { }
peerErr = peer.LastError.Error()
} else { func (cfg *PeerInfoDBConfig) Remove(model *core.PeerInfoDB) (err error) {
peerErr = nil _, err = cfg.DbConfig.DB.Exec("DELETE FROM peer_infos WHERE Id = ?",
} model.Id)
var coordsBlob []byte
if peer.Coords != nil {
coordsBlob = make([]byte, len(peer.Coords)*8)
for i, coord := range peer.Coords {
binary.LittleEndian.PutUint64(coordsBlob[i*8:], coord)
}
}
if !cfg.DbConfig.DBIsOpened() {
return nil
}
_, err = cfg.DbConfig.DB.Exec(`
INSERT OR REPLACE INTO peer_infos
(
uri,
up,
inbound,
last_error,
last_error_time,
key,
root,
coords,
port,
priority,
Rxbytes,
Txbytes,
uptime,
latency
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
peer.URI, peer.Up, peer.Inbound, peerErr, peer.LastErrorTime, key, root, coordsBlob, peer.Port, peer.Priority, peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
func (cfg *PeerInfoDBConfig) RemovePeer(peer core.PeerInfo) (err error) { func (cfg *PeerInfoDBConfig) Get(model *core.PeerInfoDB) (_ *sql.Rows, err error) {
key, err := x509.MarshalPKIXPublicKey(peer.Key) rows, err := cfg.DbConfig.DB.Query(`
SELECT
up, inbound, last_error, last_error_time, coords, port,
priority, Rxbytes, Txbytes, uptime, latency, uri, key, root
FROM
peer_infos
WHERE Id = ?`,
model.Id)
if err != nil { if err != nil {
return err return nil, err
} }
root, err := x509.MarshalPKIXPublicKey(peer.Root) defer rows.Close()
for rows.Next() {
err = rows.Scan(&model.Up, &model.Inbound, &model.PeerErr, &model.LastErrorTime, &model.CoordsBytes,
&model.Port, &model.Priority, &model.RXBytes, &model.TXBytes, &model.Uptime, &model.Latency,
&model.URI, &model.KeyBytes, &model.RootBytes)
if err != nil { if err != nil {
return err return rows, err
} }
_, err = cfg.DbConfig.DB.Exec("DELETE FROM peer_infos WHERE uri = ? AND key = ? AND root = ?", }
peer.URI, key, root)
model.Coords, err = core.ConvertToUintSlise(model.CoordsBytes)
if err != nil { if err != nil {
return err return nil, err
} }
return nil publickey, err := core.ParsePKIXPublicKey(&model.KeyBytes)
if err != nil {
return nil, err
}
model.Key = publickey
publicRoot, err := core.ParsePKIXPublicKey(&model.RootBytes)
if err != nil {
return nil, err
}
model.Root = publicRoot
model.LastError = core.ParseError(model.PeerErr)
return rows, nil
} }
func (cfg *PeerInfoDBConfig) GetPeer(peer *core.PeerInfo) (err error) { func (cfg *PeerInfoDBConfig) Update(model *core.PeerInfoDB) (err error) {
key, err := x509.MarshalPKIXPublicKey(peer.Key)
if err != nil {
return err
}
root, err := x509.MarshalPKIXPublicKey(peer.Root)
if err != nil {
return err
}
row := cfg.DbConfig.DB.QueryRow("SELECT * FROM peer_infos WHERE uri = ? AND key = ? AND root = ?",
peer.URI, key, root)
var coord []byte
var peerErr interface{}
err = row.Scan(&peer.URI, &peer.Up, &peer.Inbound, &peerErr, &peer.LastErrorTime, &key, &root, &coord, &peer.Port, &peer.Priority, &peer.RXBytes, &peer.TXBytes, &peer.Uptime, &peer.Latency)
if err != nil {
return err
}
parsedKey, err := x509.ParsePKCS8PrivateKey(key)
if err != nil {
return err
}
ParsedRoot, err := x509.ParsePKCS8PrivateKey(root)
if err != nil {
return err
}
peer.Key = parsedKey.(ed25519.PublicKey)
peer.Root = ParsedRoot.(ed25519.PublicKey)
return nil
}
func (cfg *PeerInfoDBConfig) UpdatePeer(peer core.PeerInfo) (err error) {
key, err := x509.MarshalPKIXPublicKey(peer.Key)
if err != nil {
return err
}
root, err := x509.MarshalPKIXPublicKey(peer.Root)
if err != nil {
return err
}
var peerErr interface{}
if peer.LastError != nil {
peerErr = peer.LastError.Error()
} else {
peerErr = nil
}
var coordsBlob []byte
if peer.Coords != nil {
coordsBlob = make([]byte, len(peer.Coords)*8)
for i, coord := range peer.Coords {
binary.LittleEndian.PutUint64(coordsBlob[i*8:], coord)
}
}
_, err = cfg.DbConfig.DB.Exec(`UPDATE peer_infos _, err = cfg.DbConfig.DB.Exec(`UPDATE peer_infos
SET SET
up = ?, up = ?,
@ -189,12 +140,15 @@ func (cfg *PeerInfoDBConfig) UpdatePeer(peer core.PeerInfo) (err error) {
priority = ?, priority = ?,
RXBytes = RXBytes + ?, RXBytes = RXBytes + ?,
TXBytes = TXBytes + ?, TXBytes = TXBytes + ?,
uptime = ?, uptime = uptime + ?,
latency = ? latency = ?,
uri = ?,
key = ?,
root = ?
WHERE WHERE
uri = ? AND key = ? AND root = ?`, Id = ?`,
peer.Up, peer.Inbound, peerErr, peer.LastErrorTime, coordsBlob, peer.Port, peer.Priority, model.Up, model.Inbound, model.PeerErr, model.LastErrorTime, model.CoordsBytes, model.Port, model.Priority,
peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency, peer.URI, key, root) model.RXBytes, model.TXBytes, model.Uptime, model.Latency, model.URI, model.KeyBytes, model.RootBytes, model.Id)
if err != nil { if err != nil {
return err return err
} }

View file

@ -0,0 +1,103 @@
package selfinfodb
import (
"database/sql"
"fmt"
"os"
"path/filepath"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
"github.com/yggdrasil-network/yggdrasil-go/src/db"
)
type SelfInfoDBConfig struct {
DbConfig *db.DbConfig
name string
}
var Name = "SelfInfo"
func New() (*SelfInfoDBConfig, error) {
dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name)
filePath := filepath.Join(dir, fileName)
schemas := []string{
`CREATE TABLE IF NOT EXISTS self_info (
Id INTEGER NOT NULL PRIMARY KEY,
Key BLOB,
RoutingEntries INTEGER
);`}
dbcfg, err := db.New("sqlite3", &schemas, filePath)
if err != nil {
return nil, err
}
cfg := &SelfInfoDBConfig{
name: Name,
DbConfig: dbcfg,
}
return cfg, nil
}
func (cfg *SelfInfoDBConfig) Add(model *core.SelfInfoDB) (_ sql.Result, err error) {
query := "INSERT OR REPLACE INTO self_info (Key, RoutingEntries) VALUES (?, ?)"
result, err := cfg.DbConfig.DB.Exec(query,
model.KeyBytes,
model.RoutingEntries)
if err != nil {
return nil, err
}
lastInsertId, err := result.LastInsertId()
if err != nil {
return nil, err
}
model.Id = int(lastInsertId)
return result, nil
}
func (cfg *SelfInfoDBConfig) Update(model *core.SelfInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec(`UPDATE self_info
SET
RoutingEntries = ?,
Key = ?
WHERE
Id = ?`,
model.RoutingEntries, model.KeyBytes, model.Id)
if err != nil {
return err
}
return nil
}
func (cfg *SelfInfoDBConfig) Remove(model *core.SelfInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec("DELETE FROM self_info WHERE Id = ?",
model.Id)
if err != nil {
return err
}
return nil
}
func (cfg *SelfInfoDBConfig) Get(model *core.SelfInfoDB) (_ *sql.Rows, err error) {
rows, err := cfg.DbConfig.DB.Query("SELECT RoutingEntries, Key FROM self_info WHERE Id = ?",
model.Id)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&model.RoutingEntries, &model.KeyBytes)
if err != nil {
return rows, err
}
}
return rows, nil
}
func (cfg *SelfInfoDBConfig) Count() (int, error) {
var count int
err := cfg.DbConfig.DB.QueryRow("SELECT COUNT(*) FROM self_info").Scan(&count)
if err != nil {
return 0, err
}
return count, nil
}

View file

@ -0,0 +1,111 @@
package sessioninfodb
import (
"database/sql"
"fmt"
"os"
"path/filepath"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
"github.com/yggdrasil-network/yggdrasil-go/src/db"
)
type SessionInfoDBConfig struct {
DbConfig *db.DbConfig
name string
}
var Name = "SessionInfo"
func New() (*SessionInfoDBConfig, error) {
dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name)
filePath := filepath.Join(dir, fileName)
schemas := []string{
`CREATE TABLE IF NOT EXISTS session_info (
Id INTEGER NOT NULL PRIMARY KEY,
Key BLOB,
RXBytes INTEGER,
TXBytes INTEGER,
Duration INTEGER
);`}
dbcfg, err := db.New("sqlite3", &schemas, filePath)
if err != nil {
return nil, err
}
cfg := &SessionInfoDBConfig{
name: Name,
DbConfig: dbcfg,
}
return cfg, nil
}
func (cfg *SessionInfoDBConfig) Add(model *core.SessionInfoDB) (_ sql.Result, err error) {
query := "INSERT INTO session_info (Key, RXBytes, TXBytes, Duration) VALUES (?, ?, ?, ?)"
result, err := cfg.DbConfig.DB.Exec(query,
model.KeyBytes,
model.RXBytes,
model.TXBytes,
model.Uptime,
)
if err != nil {
return nil, err
}
lastInsertId, err := result.LastInsertId()
if err != nil {
return nil, err
}
model.Id = int(lastInsertId)
return result, nil
}
func (cfg *SessionInfoDBConfig) Remove(model *core.SessionInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec("DELETE FROM session_info WHERE Id = ?",
model.Id)
if err != nil {
return err
}
return nil
}
func (cfg *SessionInfoDBConfig) Update(model *core.SessionInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec(`UPDATE session_info
SET
RXBytes = RXBytes + ?,
TXBytes = TXBytes + ?,
Duration = Duration + ?,
Key = ?
WHERE
Id = ?`,
model.RXBytes, model.TXBytes, model.Uptime, model.KeyBytes, model.Id)
if err != nil {
return err
}
return nil
}
func (cfg *SessionInfoDBConfig) Get(model *core.SessionInfoDB) (_ *sql.Rows, err error) {
rows, err := cfg.DbConfig.DB.Query("SELECT RXBytes, TXBytes, Duration, Key FROM session_info WHERE Id = ?",
model.Id,
)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&model.RXBytes, &model.TXBytes, &model.Uptime, &model.KeyBytes)
if err != nil {
return nil, err
}
}
return rows, nil
}
func (cfg *SessionInfoDBConfig) Count() (int, error) {
var count int
err := cfg.DbConfig.DB.QueryRow("SELECT COUNT(*) FROM session_info").Scan(&count)
if err != nil {
return 0, err
}
return count, nil
}

View file

@ -0,0 +1,108 @@
package treeentryinfodb
import (
"database/sql"
"fmt"
"os"
"path/filepath"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
"github.com/yggdrasil-network/yggdrasil-go/src/db"
)
type TreeEntryInfoDBConfig struct {
DbConfig *db.DbConfig
name string
}
var Name = "TreeEntryInfo"
func New() (*TreeEntryInfoDBConfig, error) {
dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name)
filePath := filepath.Join(dir, fileName)
schemas := []string{
`CREATE TABLE IF NOT EXISTS tree_entry_info (
Id INTEGER NOT NULL PRIMARY KEY,
Key BLOB,
Parent BLOB,
Sequence INTEGER
);`}
dbcfg, err := db.New("sqlite3", &schemas, filePath)
if err != nil {
return nil, err
}
cfg := &TreeEntryInfoDBConfig{
name: Name,
DbConfig: dbcfg,
}
return cfg, nil
}
func (cfg *TreeEntryInfoDBConfig) Add(model *core.TreeEntryInfoDB) (_ sql.Result, err error) {
query := "INSERT INTO tree_entry_info (Key, Parent, Sequence) VALUES (?, ?, ?)"
result, err := cfg.DbConfig.DB.Exec(query,
model.KeyBytes,
model.ParentBytes,
model.Sequence,
)
if err != nil {
return nil, err
}
lastInsertId, err := result.LastInsertId()
if err != nil {
return nil, err
}
model.Id = int(lastInsertId)
return result, nil
}
func (cfg *TreeEntryInfoDBConfig) Remove(model *core.TreeEntryInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec("DELETE FROM tree_entry_info WHERE Id = ?",
model.Id)
if err != nil {
return err
}
return nil
}
func (cfg *TreeEntryInfoDBConfig) Update(model *core.TreeEntryInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec(`UPDATE tree_entry_info
SET
Sequence = ?,
Key = ?,
Parent = ?
WHERE
Id = ?`,
model.Sequence, model.KeyBytes, model.ParentBytes, model.Id)
if err != nil {
return err
}
return nil
}
func (cfg *TreeEntryInfoDBConfig) Get(model *core.TreeEntryInfoDB) (_ *sql.Rows, err error) {
rows, err := cfg.DbConfig.DB.Query("SELECT Sequence, Key, Parent FROM tree_entry_info WHERE Id = ?",
model.Id,
)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&model.Sequence, &model.KeyBytes, &model.ParentBytes)
if err != nil {
return nil, err
}
}
return rows, nil
}
func (cfg *TreeEntryInfoDBConfig) Count() (int, error) {
var count int
err := cfg.DbConfig.DB.QueryRow("SELECT COUNT(*) FROM tree_entry_info").Scan(&count)
if err != nil {
return 0, err
}
return count, nil
}

Binary file not shown.

View file

@ -1,11 +1,9 @@
package db_test package db_test
import ( import (
"bytes"
"crypto/ed25519" "crypto/ed25519"
"crypto/rand" "crypto/rand"
"crypto/x509" "errors"
"encoding/binary"
"fmt" "fmt"
"reflect" "reflect"
"strconv" "strconv"
@ -20,33 +18,39 @@ import (
) )
func TestPeerGetCoords(t *testing.T) { func TestPeerGetCoords(t *testing.T) {
peer := core.PeerInfo{ peerinfo := core.PeerInfo{
Coords: []uint64{1, 2, 3, 4}, Coords: []uint64{1, 2, 3, 4},
} }
peer := core.PeerInfoDB{
PeerInfo: peerinfo,
}
target := []byte{1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0} target := []byte{1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0}
var coordinates = peer.GetCoordinates() coordinates := core.ConvertToByteSlise(peer.Coords)
if reflect.DeepEqual(target, coordinates) { if !reflect.DeepEqual(target, coordinates) {
t.Error(fmt.Errorf("Not equal")) t.Error(fmt.Errorf("Not equal"))
} }
} }
func TestPeerSetCoords(t *testing.T) { func TestPeerSetCoords(t *testing.T) {
peer := core.PeerInfo{ peerinfo := core.PeerInfo{}
Coords: []uint64{1, 2, 3, 4}, peer := core.PeerInfoDB{
PeerInfo: peerinfo,
} }
target := []byte{4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0} var err error
var coordinates = peer.SetCoordinates(&target) peer.CoordsBytes = []byte{4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}
if reflect.DeepEqual(target, coordinates) { peer.Coords, err = core.ConvertToUintSlise(peer.CoordsBytes)
require.NoError(t, err)
coords := []uint64{4, 3, 2, 1}
if !reflect.DeepEqual(coords, peer.Coords) {
t.Error(fmt.Errorf("Not equal")) t.Error(fmt.Errorf("Not equal"))
} }
fmt.Print(peer.Coords)
} }
func TestAddPeer(t *testing.T) { func TestAddPeer(t *testing.T) {
mockDB, mock, err := sqlmock.New() mockDB, mock, err := sqlmock.New()
require.NoError(t, err) require.NoError(t, err)
defer mockDB.Close() defer mockDB.Close()
cfg, err := peerinfodb.New() cfg, err := peerinfodb.New()
require.NoError(t, err) require.NoError(t, err)
cfg.DbConfig.DB = mockDB cfg.DbConfig.DB = mockDB
@ -55,12 +59,11 @@ func TestAddPeer(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader) rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err) require.NoError(t, err)
peerinfo := core.PeerInfo{
peer := core.PeerInfo{
URI: "test.test", URI: "test.test",
Up: true, Up: true,
Inbound: true, Inbound: true,
LastError: nil, LastError: errors.New("test"),
LastErrorTime: time.Now(), LastErrorTime: time.Now(),
Key: pubkey, Key: pubkey,
Root: rootPubKey, Root: rootPubKey,
@ -72,28 +75,19 @@ func TestAddPeer(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer, err := core.NewPeerInfoDB(peerinfo)
require.NoError(t, err)
pKey, err := x509.MarshalPKIXPublicKey(peer.Key)
require.NoError(t, err)
pKeyRoot, err := x509.MarshalPKIXPublicKey(peer.Root)
require.NoError(t, err)
var coordsBlob []byte
if peer.Coords != nil {
coordsBlob = make([]byte, len(peer.Coords)*8)
for i, coord := range peer.Coords {
binary.LittleEndian.PutUint64(coordsBlob[i*8:], coord)
}
}
mock.ExpectExec("INSERT OR REPLACE INTO peer_infos"). mock.ExpectExec("INSERT OR REPLACE INTO peer_infos").
WithArgs( WithArgs(
peer.URI, peer.URI,
peer.Up, peer.Up,
peer.Inbound, peer.Inbound,
nil, peer.PeerErr,
peer.LastErrorTime, peer.LastErrorTime,
pKey, peer.KeyBytes,
pKeyRoot, peer.RootBytes,
coordsBlob, peer.CoordsBytes,
peer.Port, peer.Port,
peer.Priority, peer.Priority,
peer.RXBytes, peer.RXBytes,
@ -103,7 +97,7 @@ func TestAddPeer(t *testing.T) {
). ).
WillReturnResult(sqlmock.NewResult(1, 1)) WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.AddPeer(peer) _, err = cfg.Add(peer)
require.NoError(t, err) require.NoError(t, err)
err = mock.ExpectationsWereMet() err = mock.ExpectationsWereMet()
@ -114,7 +108,6 @@ func TestRemovePeer(t *testing.T) {
mockDB, mock, err := sqlmock.New() mockDB, mock, err := sqlmock.New()
require.NoError(t, err) require.NoError(t, err)
defer mockDB.Close() defer mockDB.Close()
cfg, err := peerinfodb.New() cfg, err := peerinfodb.New()
require.NoError(t, err) require.NoError(t, err)
cfg.DbConfig.DB = mockDB cfg.DbConfig.DB = mockDB
@ -124,11 +117,11 @@ func TestRemovePeer(t *testing.T) {
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader) rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err) require.NoError(t, err)
peer := core.PeerInfo{ peerinfo := core.PeerInfo{
URI: "test.test", URI: "test.test",
Up: true, Up: true,
Inbound: true, Inbound: true,
LastError: nil, LastError: errors.New("test"),
LastErrorTime: time.Now(), LastErrorTime: time.Now(),
Key: pubkey, Key: pubkey,
Root: rootPubKey, Root: rootPubKey,
@ -140,16 +133,14 @@ func TestRemovePeer(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer, err := core.NewPeerInfoDB(peerinfo)
require.NoError(t, err)
pKey, err := x509.MarshalPKIXPublicKey(peer.Key) mock.ExpectExec("DELETE FROM peer_infos WHERE Id = \\?").
require.NoError(t, err) WithArgs(peer.Id).
pKeyRoot, err := x509.MarshalPKIXPublicKey(peer.Root)
require.NoError(t, err)
mock.ExpectExec("DELETE FROM peer_infos WHERE uri = \\? AND key = \\? AND root = \\?").
WithArgs(peer.URI, pKey, pKeyRoot).
WillReturnResult(sqlmock.NewResult(1, 1)) WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.RemovePeer(peer) err = cfg.Remove(peer)
require.NoError(t, err) require.NoError(t, err)
err = mock.ExpectationsWereMet() err = mock.ExpectationsWereMet()
@ -170,11 +161,11 @@ func TestGetPeer(t *testing.T) {
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader) rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err) require.NoError(t, err)
peer := core.PeerInfo{ peerinfo := core.PeerInfo{
URI: "test.test", URI: "test.test",
Up: true, Up: true,
Inbound: true, Inbound: true,
LastError: nil, LastError: errors.New("test"),
LastErrorTime: time.Now(), LastErrorTime: time.Now(),
Key: pubkey, Key: pubkey,
Root: rootPubKey, Root: rootPubKey,
@ -186,20 +177,21 @@ func TestGetPeer(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer, err := core.NewPeerInfoDB(peerinfo)
pKey, err := x509.MarshalPKIXPublicKey(peer.Key)
require.NoError(t, err) require.NoError(t, err)
pKeyRoot, err := x509.MarshalPKIXPublicKey(peer.Root)
require.NoError(t, err)
var coords []byte
rows := sqlmock.NewRows([]string{"uri", "up", "Inbound", "LastError", "LastErrorTime", "Key", "Root", "Coords", "Port", "Priority", "Rxbytes", "Txbytes", "Uptime", "Latency"}).
AddRow(peer.URI, peer.Up, peer.Inbound, peer.LastError, peer.LastErrorTime, peer.Key, peer.Root, coords, peer.Port, peer.Priority, peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency)
mock.ExpectQuery("SELECT * FROM peer_infos WHERE uri = ? AND key = ? AND root = ?"). rows := sqlmock.NewRows([]string{"up", "inbound", "last_error", "last_error_time", "coords",
WithArgs(peer.URI, pKey, pKeyRoot). "port", "priority", "Rxbytes", "Txbytes", "uptime", "latency", "uri", "key", "root"}).
AddRow(peer.Up, peer.Inbound, peer.PeerErr, peer.LastErrorTime, peer.CoordsBytes,
peer.Port, peer.Priority, peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency,
peer.URI, peer.KeyBytes, peer.RootBytes)
mock.ExpectQuery("SELECT (.+) FROM peer_infos WHERE Id = \\?").
WithArgs(peer.Id).
WillReturnRows(rows) WillReturnRows(rows)
err = cfg.GetPeer(&peer) _, err = cfg.Get(peer)
t.Log(err)
require.NoError(t, err) require.NoError(t, err)
err = mock.ExpectationsWereMet() err = mock.ExpectationsWereMet()
@ -210,7 +202,6 @@ func TestUpdatePeer(t *testing.T) {
mockDB, mock, err := sqlmock.New() mockDB, mock, err := sqlmock.New()
require.NoError(t, err) require.NoError(t, err)
defer mockDB.Close() defer mockDB.Close()
cfg, err := peerinfodb.New() cfg, err := peerinfodb.New()
require.NoError(t, err) require.NoError(t, err)
cfg.DbConfig.DB = mockDB cfg.DbConfig.DB = mockDB
@ -219,12 +210,11 @@ func TestUpdatePeer(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader) rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err) require.NoError(t, err)
peerinfo := core.PeerInfo{
peer := core.PeerInfo{
URI: "test.test", URI: "test.test",
Up: true, Up: true,
Inbound: true, Inbound: true,
LastError: nil, LastError: errors.New("test"),
LastErrorTime: time.Now(), LastErrorTime: time.Now(),
Key: pubkey, Key: pubkey,
Root: rootPubKey, Root: rootPubKey,
@ -236,17 +226,7 @@ func TestUpdatePeer(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer, err := core.NewPeerInfoDB(peerinfo)
pKey, err := x509.MarshalPKIXPublicKey(peer.Key)
require.NoError(t, err)
pKeyRoot, err := x509.MarshalPKIXPublicKey(peer.Root)
var coordsBlob []byte
if peer.Coords != nil {
coordsBlob = make([]byte, len(peer.Coords)*8)
for i, coord := range peer.Coords {
binary.LittleEndian.PutUint64(coordsBlob[i*8:], coord)
}
}
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec(`UPDATE peer_infos mock.ExpectExec(`UPDATE peer_infos
SET SET
@ -259,23 +239,25 @@ func TestUpdatePeer(t *testing.T) {
priority = \?, priority = \?,
RXBytes = RXBytes \+ \?, RXBytes = RXBytes \+ \?,
TXBytes = TXBytes \+ \?, TXBytes = TXBytes \+ \?,
uptime = \?, uptime = uptime \+ \?,
latency = \? latency = \?,
uri = \?,
key = \?,
root = \?
WHERE WHERE
uri = \? AND key = \? AND root = \?`). Id = \?`).
WithArgs( WithArgs(
peer.Up, peer.Inbound, peer.LastError, peer.LastErrorTime, coordsBlob, peer.Port, peer.Priority, peer.Up, peer.Inbound, peer.PeerErr, peer.LastErrorTime, peer.CoordsBytes, peer.Port, peer.Priority,
peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency, peer.URI, pKey, pKeyRoot). peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency, peer.URI, peer.KeyBytes, peer.RootBytes, peer.Id).
WillReturnResult(sqlmock.NewResult(1, 1)) WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.UpdatePeer(peer) err = cfg.Update(peer)
require.NoError(t, err) require.NoError(t, err)
err = mock.ExpectationsWereMet() err = mock.ExpectationsWereMet()
require.NoError(t, err) require.NoError(t, err)
} }
// One more test here
func TestMain(t *testing.T) { func TestMain(t *testing.T) {
peerinfodb.Name = fmt.Sprintf( peerinfodb.Name = fmt.Sprintf(
"%s.%s", "%s.%s",
@ -297,7 +279,7 @@ func TestMain(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader) rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err) require.NoError(t, err)
peer := core.PeerInfo{ peerinfo := core.PeerInfo{
URI: "test.test", URI: "test.test",
Up: true, Up: true,
Inbound: true, Inbound: true,
@ -313,14 +295,16 @@ func TestMain(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer, err := core.NewPeerInfoDB(peerinfo)
require.NoError(t, err)
root2PubKey, _, err := ed25519.GenerateKey(rand.Reader) root2PubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err) require.NoError(t, err)
peer2 := core.PeerInfo{ peerinfo2 := core.PeerInfo{
URI: "new.test", URI: "new.test",
Up: true, Up: true,
Inbound: true, Inbound: true,
LastError: nil, LastError: errors.New("test2"),
LastErrorTime: time.Now(), LastErrorTime: time.Now(),
Key: pubkey, Key: pubkey,
Root: root2PubKey, Root: root2PubKey,
@ -332,9 +316,13 @@ func TestMain(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer2, err := core.NewPeerInfoDB(peerinfo2)
require.NoError(t, err)
peerdb.AddPeer(peer) _, err = peerdb.Add(peer)
peerdb.AddPeer(peer2) require.NoError(t, err)
_, err = peerdb.Add(peer2)
require.NoError(t, err)
count, err := peerdb.Count() count, err := peerdb.Count()
require.NoError(t, err) require.NoError(t, err)
condition = func() bool { condition = func() bool {
@ -342,29 +330,35 @@ func TestMain(t *testing.T) {
} }
require.Condition(t, condition, "Expected count to be 2", count) require.Condition(t, condition, "Expected count to be 2", count)
peerdb.RemovePeer(peer) err = peerdb.Remove(peer)
require.NoError(t, err)
count, err = peerdb.Count() count, err = peerdb.Count()
require.NoError(t, err) require.NoError(t, err)
condition = func() bool { condition = func() bool {
return count == 1 return count == 1
} }
require.Condition(t, condition, "Expected count to be 1", count) require.Condition(t, condition, "Expected count to be 1", count)
peer2.Latency = 10 peer2.Latency = 10
peer2.RXBytes = 1024 peer2.RXBytes = 1024
peer2.TXBytes = 1024 peer2.TXBytes = 1024
peer2.Port = 80 peer2.Port = 80
peerdb.UpdatePeer(peer2) err = peerdb.Update(peer2)
peerdb.GetPeer(&peer2) require.NoError(t, err)
_, err = peerdb.Get(peer2)
require.NoError(t, err)
condition = func() bool { condition = func() bool {
return peer2.Latency == 10 && return peer2.Latency == 10 &&
peer2.RXBytes == 2048 && peer2.RXBytes == 2048 &&
peer2.TXBytes == 3072 && peer2.TXBytes == 3072 &&
peer2.Port == 80 && peer2.URI == "new.test" && bytes.Equal(peer.Key, pubkey) peer2.Port == 80 && peer2.URI == "new.test" && peer2.Key.Equal(pubkey)
} }
require.Condition(t, condition, "Inner exception") require.Condition(t, condition, "Inner exception")
peerdb.RemovePeer(peer2) peerdb.Remove(peer2)
count, err = peerdb.Count() count, err = peerdb.Count()
require.NoError(t, err) require.NoError(t, err)

View file

@ -0,0 +1,258 @@
package db_test
import (
"crypto/ed25519"
"crypto/rand"
"fmt"
"strconv"
"testing"
"time"
"github.com/DATA-DOG/go-sqlmock"
"github.com/stretchr/testify/require"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
pathentryinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/PathEntryInfoDB"
)
func TestSelectPathEntryInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := pathentryinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.PathEntryInfo{
Key: pubkey,
Path: []uint64{0, 0, 0},
Sequence: 100,
}
model, err := core.NewPathEntryInfoDB(entry)
require.NoError(t, err)
rows := sqlmock.NewRows([]string{"Sequence", "Key", "Path"}).
AddRow(100, model.KeyBytes, model.PathBytes)
mock.ExpectQuery("SELECT (.+) FROM path_entry_info WHERE Id = \\?").
WithArgs(model.Id).
WillReturnRows(rows)
_, err = cfg.Get(model)
t.Log(err)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestInsertPathEntryInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := pathentryinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.PathEntryInfo{
Key: pubkey,
Path: []uint64{0, 0, 0},
Sequence: 100,
}
model, err := core.NewPathEntryInfoDB(entry)
require.NoError(t, err)
mock.ExpectExec("INSERT INTO path_entry_info").
WithArgs(
model.KeyBytes,
model.PathBytes,
model.Sequence,
).
WillReturnResult(sqlmock.NewResult(1, 1))
_, err = cfg.Add(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestDeletePathEntryInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := pathentryinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.PathEntryInfo{
Key: pubkey,
Path: []uint64{0, 0, 0},
Sequence: 100,
}
model, err := core.NewPathEntryInfoDB(entry)
require.NoError(t, err)
mock.ExpectExec("DELETE FROM path_entry_info WHERE Id = \\?").
WithArgs(
model.Id,
).WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.Remove(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestUpdatePathEntryInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := pathentryinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.PathEntryInfo{
Key: pubkey,
Path: []uint64{0, 0, 0},
Sequence: 100,
}
model, err := core.NewPathEntryInfoDB(entry)
require.NoError(t, err)
mock.ExpectExec(`
UPDATE path_entry_info
SET
Sequence = \?,
Key = \?,
Path = \?
WHERE
Id = \?`).
WithArgs(
model.Sequence,
model.KeyBytes,
model.PathBytes,
model.Id,
).WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.Update(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestMainPathEntryInfo(t *testing.T) {
pathentryinfodb.Name = fmt.Sprintf(
"%s.%s",
pathentryinfodb.Name,
strconv.Itoa(int(time.Now().Unix())),
)
pathentryinfodb, err := pathentryinfodb.New()
require.NoError(t, err)
pathentryinfodb.DbConfig.OpenDb()
isOpened := pathentryinfodb.DbConfig.DBIsOpened()
condition := func() bool {
return isOpened
}
require.Condition(t, condition, "Expected db is opened", isOpened)
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
secondPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.PathEntryInfo{
Key: pubkey,
Path: []uint64{0, 0, 0},
Sequence: 100,
}
model, err := core.NewPathEntryInfoDB(entry)
require.NoError(t, err)
secondEntry := core.PathEntryInfo{
Key: secondPubKey,
Path: []uint64{0, 0, 0},
Sequence: 100,
}
secondModel, err := core.NewPathEntryInfoDB(secondEntry)
require.NoError(t, err)
_, err = pathentryinfodb.Add(model)
require.NoError(t, err)
_, err = pathentryinfodb.Add(secondModel)
require.NoError(t, err)
count, err := pathentryinfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 2
}
require.Condition(t, condition, "Expected count to be 2", count)
err = pathentryinfodb.Remove(secondModel)
require.NoError(t, err)
count, err = pathentryinfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 1
}
require.Condition(t, condition, "Expected count to be 1", count)
model.Sequence = 10
err = pathentryinfodb.Update(model)
require.NoError(t, err)
_, err = pathentryinfodb.Get(model)
require.NoError(t, err)
err = pathentryinfodb.Update(secondModel)
require.NoError(t, err)
condition = func() bool {
return model.Sequence == 10
}
require.Condition(t, condition, "Inner exception")
pathentryinfodb.Remove(model)
count, err = pathentryinfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 0
}
require.Condition(t, condition, "Expected count to be 0", count)
err = pathentryinfodb.DbConfig.CloseDb()
isOpened = pathentryinfodb.DbConfig.DBIsOpened()
require.NoError(t, err)
condition = func() bool {
return !isOpened
}
require.Condition(t, condition, "Expected db is not opened", isOpened)
err = pathentryinfodb.DbConfig.DeleteDb()
require.NoError(t, err)
isExist := pathentryinfodb.DbConfig.DBIsExist()
condition = func() bool {
return !isExist
}
require.Condition(t, condition, "Expected db is not exist", isExist)
}

View file

@ -0,0 +1,246 @@
package db_test
import (
"crypto/ed25519"
"crypto/rand"
"fmt"
"strconv"
"testing"
"time"
"github.com/DATA-DOG/go-sqlmock"
"github.com/stretchr/testify/require"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
selfinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/SelfInfoDB"
)
func TestSelectSelfInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := selfinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
selfinfo := core.SelfInfo{
Key: pubkey,
}
model, err := core.NewSelfInfoDB(selfinfo)
require.NoError(t, err)
rows := sqlmock.NewRows([]string{"RoutingEntries", "Key"}).
AddRow(100, model.KeyBytes)
mock.ExpectQuery("SELECT (.+) FROM self_info WHERE Id = \\?").
WithArgs(model.Id).
WillReturnRows(rows)
_, err = cfg.Get(model)
t.Log(err)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestInsertSelfInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := selfinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
selfinfo := core.SelfInfo{
Key: pubkey,
}
model, err := core.NewSelfInfoDB(selfinfo)
require.NoError(t, err)
mock.ExpectExec("INSERT OR REPLACE INTO self_info").
WithArgs(
model.KeyBytes,
model.RoutingEntries,
).
WillReturnResult(sqlmock.NewResult(1, 1))
_, err = cfg.Add(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestDeleteSelfInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := selfinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
selfinfo := core.SelfInfo{
Key: pubkey,
}
model, err := core.NewSelfInfoDB(selfinfo)
require.NoError(t, err)
mock.ExpectExec("DELETE FROM self_info WHERE Id = \\?").
WithArgs(
model.Id,
).WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.Remove(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestUpdateSelfInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := selfinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
selfinfo := core.SelfInfo{
Key: pubkey,
RoutingEntries: 100,
}
model, err := core.NewSelfInfoDB(selfinfo)
require.NoError(t, err)
mock.ExpectExec(`
UPDATE self_info
SET
RoutingEntries = \?,
Key = \?
WHERE
Id = \?`).
WithArgs(
model.RoutingEntries,
model.KeyBytes,
model.Id,
).WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.Update(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestMainSelfInfo(t *testing.T) {
selfinfodb.Name = fmt.Sprintf(
"%s.%s",
selfinfodb.Name,
strconv.Itoa(int(time.Now().Unix())),
)
selfinfodb, err := selfinfodb.New()
require.NoError(t, err)
selfinfodb.DbConfig.OpenDb()
isOpened := selfinfodb.DbConfig.DBIsOpened()
condition := func() bool {
return isOpened
}
require.Condition(t, condition, "Expected db is opened", isOpened)
firstKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
secondKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
firstSelfinfo := core.SelfInfo{
Key: firstKey,
RoutingEntries: 100,
}
firstModel, err := core.NewSelfInfoDB(firstSelfinfo)
require.NoError(t, err)
secondSelfinfo := core.SelfInfo{
Key: secondKey,
RoutingEntries: 200,
}
secondModel, err := core.NewSelfInfoDB(secondSelfinfo)
require.NoError(t, err)
_, err = selfinfodb.Add(firstModel)
require.NoError(t, err)
_, err = selfinfodb.Add(secondModel)
require.NoError(t, err)
count, err := selfinfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 2
}
require.Condition(t, condition, "Expected count to be 2", count)
err = selfinfodb.Remove(secondModel)
require.NoError(t, err)
count, err = selfinfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 1
}
require.Condition(t, condition, "Expected count to be 1", count)
firstModel.RoutingEntries = 10
err = selfinfodb.Update(firstModel)
require.NoError(t, err)
_, err = selfinfodb.Get(firstModel)
require.NoError(t, err)
err = selfinfodb.Update(secondModel)
require.NoError(t, err)
condition = func() bool {
return firstModel.RoutingEntries == 10
}
require.Condition(t, condition, "Inner exception")
selfinfodb.Remove(firstModel)
count, err = selfinfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 0
}
require.Condition(t, condition, "Expected count to be 0", count)
err = selfinfodb.DbConfig.CloseDb()
isOpened = selfinfodb.DbConfig.DBIsOpened()
require.NoError(t, err)
condition = func() bool {
return !isOpened
}
require.Condition(t, condition, "Expected db is not opened", isOpened)
err = selfinfodb.DbConfig.DeleteDb()
require.NoError(t, err)
isExist := selfinfodb.DbConfig.DBIsExist()
condition = func() bool {
return !isExist
}
require.Condition(t, condition, "Expected db is not exist", isExist)
}

View file

@ -0,0 +1,271 @@
package db_test
import (
"crypto/ed25519"
"crypto/rand"
"fmt"
"strconv"
"testing"
"time"
"github.com/DATA-DOG/go-sqlmock"
"github.com/stretchr/testify/require"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
sessioninfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/SessionInfoDB"
)
func TestSelectSessionInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := sessioninfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.SessionInfo{
Key: pubkey,
RXBytes: 10,
TXBytes: 10,
Uptime: time.Hour,
}
model, err := core.NewSessionInfoDB(entry)
require.NoError(t, err)
rows := sqlmock.NewRows([]string{"RXBytes", "TXBytes", "Duration", "Key"}).
AddRow(100, 200, 100, model.KeyBytes)
mock.ExpectQuery("SELECT (.+) FROM session_info WHERE Id = \\?").
WithArgs(model.Id).
WillReturnRows(rows)
_, err = cfg.Get(model)
t.Log(err)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestInsertSessionInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := sessioninfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.SessionInfo{
Key: pubkey,
RXBytes: 10,
TXBytes: 10,
Uptime: time.Hour,
}
model, err := core.NewSessionInfoDB(entry)
require.NoError(t, err)
mock.ExpectExec("INSERT INTO session_info").
WithArgs(
model.KeyBytes,
model.RXBytes,
model.TXBytes,
model.Uptime,
).
WillReturnResult(sqlmock.NewResult(1, 1))
_, err = cfg.Add(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestDeleteSessionInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := sessioninfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.SessionInfo{
Key: pubkey,
RXBytes: 10,
TXBytes: 10,
Uptime: time.Hour,
}
model, err := core.NewSessionInfoDB(entry)
require.NoError(t, err)
mock.ExpectExec("DELETE FROM session_info WHERE Id = \\?").
WithArgs(
model.Id,
).WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.Remove(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestUpdateSessionInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := sessioninfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.SessionInfo{
Key: pubkey,
RXBytes: 10,
TXBytes: 10,
Uptime: time.Hour,
}
model, err := core.NewSessionInfoDB(entry)
require.NoError(t, err)
mock.ExpectExec(`
UPDATE session_info
SET
RXBytes = RXBytes \+ \?,
TXBytes = TXBytes \+ \?,
Duration = Duration \+ \?,
Key = \?
WHERE
Id = \?`).
WithArgs(
model.RXBytes,
model.TXBytes,
model.Uptime,
model.KeyBytes,
model.Id,
).WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.Update(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestMainSessionInfo(t *testing.T) {
sessioninfodb.Name = fmt.Sprintf(
"%s.%s",
sessioninfodb.Name,
strconv.Itoa(int(time.Now().Unix())),
)
sessioninfodb, err := sessioninfodb.New()
require.NoError(t, err)
sessioninfodb.DbConfig.OpenDb()
isOpened := sessioninfodb.DbConfig.DBIsOpened()
condition := func() bool {
return isOpened
}
require.Condition(t, condition, "Expected db is opened", isOpened)
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
secondPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.SessionInfo{
Key: pubkey,
RXBytes: 10,
TXBytes: 10,
Uptime: time.Hour,
}
model, err := core.NewSessionInfoDB(entry)
require.NoError(t, err)
secondEntry := core.SessionInfo{
Key: secondPubKey,
RXBytes: 10,
TXBytes: 10,
Uptime: time.Hour,
}
secondModel, err := core.NewSessionInfoDB(secondEntry)
require.NoError(t, err)
_, err = sessioninfodb.Add(model)
require.NoError(t, err)
_, err = sessioninfodb.Add(secondModel)
require.NoError(t, err)
count, err := sessioninfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 2
}
require.Condition(t, condition, "Expected count to be 2", count)
err = sessioninfodb.Remove(secondModel)
require.NoError(t, err)
count, err = sessioninfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 1
}
require.Condition(t, condition, "Expected count to be 1", count)
model.TXBytes = 100
model.RXBytes = 150
model.Uptime = 100
err = sessioninfodb.Update(model)
require.NoError(t, err)
_, err = sessioninfodb.Get(model)
require.NoError(t, err)
err = sessioninfodb.Update(secondModel)
require.NoError(t, err)
condition = func() bool {
return model.RXBytes == 160 &&
model.TXBytes == 110 && model.Uptime == 3600000000100
}
require.Condition(t, condition, "Inner exception")
sessioninfodb.Remove(model)
count, err = sessioninfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 0
}
require.Condition(t, condition, "Expected count to be 0", count)
err = sessioninfodb.DbConfig.CloseDb()
isOpened = sessioninfodb.DbConfig.DBIsOpened()
require.NoError(t, err)
condition = func() bool {
return !isOpened
}
require.Condition(t, condition, "Expected db is not opened", isOpened)
err = sessioninfodb.DbConfig.DeleteDb()
require.NoError(t, err)
isExist := sessioninfodb.DbConfig.DBIsExist()
condition = func() bool {
return !isExist
}
require.Condition(t, condition, "Expected db is not exist", isExist)
}

View file

@ -0,0 +1,259 @@
package db_test
import (
"crypto/ed25519"
"crypto/rand"
"fmt"
"strconv"
"testing"
"time"
"github.com/DATA-DOG/go-sqlmock"
"github.com/stretchr/testify/require"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
treeentryinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/TreeEntryInfoDB"
)
func TestSelectTreeEntryInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := treeentryinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.TreeEntryInfo{
Key: pubkey,
Parent: pubkey,
Sequence: 10,
}
model, err := core.NewTreeEntryInfoDB(entry)
require.NoError(t, err)
rows := sqlmock.NewRows([]string{"Sequence", "Key", "Parent"}).
AddRow(100, model.KeyBytes, model.ParentBytes)
mock.ExpectQuery("SELECT (.+) FROM tree_entry_info WHERE Id = \\?").
WithArgs(model.Id).
WillReturnRows(rows)
_, err = cfg.Get(model)
t.Log(err)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestInsertTreeEntryInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := treeentryinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.TreeEntryInfo{
Key: pubkey,
Parent: pubkey,
Sequence: 10,
}
model, err := core.NewTreeEntryInfoDB(entry)
require.NoError(t, err)
mock.ExpectExec("INSERT INTO tree_entry_info").
WithArgs(
model.KeyBytes,
model.ParentBytes,
model.Sequence,
).
WillReturnResult(sqlmock.NewResult(1, 1))
_, err = cfg.Add(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestDeleteTreeEntryInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := treeentryinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.TreeEntryInfo{
Key: pubkey,
Parent: pubkey,
Sequence: 10,
}
model, err := core.NewTreeEntryInfoDB(entry)
require.NoError(t, err)
mock.ExpectExec("DELETE FROM tree_entry_info WHERE Id = \\?").
WithArgs(
model.Id,
).WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.Remove(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestUpdateTreeEntryInfo(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := treeentryinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.TreeEntryInfo{
Key: pubkey,
Parent: pubkey,
Sequence: 10,
}
model, err := core.NewTreeEntryInfoDB(entry)
require.NoError(t, err)
mock.ExpectExec(`
UPDATE tree_entry_info
SET
Sequence = \?,
Key = \?,
Parent = \?
WHERE
Id = \?`).
WithArgs(
model.Sequence,
model.KeyBytes,
model.ParentBytes,
model.Id,
).WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.Update(model)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
func TestMainTreeEntryInfo(t *testing.T) {
treeentryinfodb.Name = fmt.Sprintf(
"%s.%s",
treeentryinfodb.Name,
strconv.Itoa(int(time.Now().Unix())),
)
treeentryinfodb, err := treeentryinfodb.New()
require.NoError(t, err)
treeentryinfodb.DbConfig.OpenDb()
isOpened := treeentryinfodb.DbConfig.DBIsOpened()
condition := func() bool {
return isOpened
}
require.Condition(t, condition, "Expected db is opened", isOpened)
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
secondPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
entry := core.TreeEntryInfo{
Key: pubkey,
Parent: pubkey,
Sequence: 10,
}
model, err := core.NewTreeEntryInfoDB(entry)
require.NoError(t, err)
secondEntry := core.TreeEntryInfo{
Key: secondPubKey,
Parent: secondPubKey,
Sequence: 20,
}
secondModel, err := core.NewTreeEntryInfoDB(secondEntry)
require.NoError(t, err)
_, err = treeentryinfodb.Add(model)
require.NoError(t, err)
_, err = treeentryinfodb.Add(secondModel)
require.NoError(t, err)
count, err := treeentryinfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 2
}
require.Condition(t, condition, "Expected count to be 2", count)
err = treeentryinfodb.Remove(secondModel)
require.NoError(t, err)
count, err = treeentryinfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 1
}
require.Condition(t, condition, "Expected count to be 1", count)
model.Sequence = 100
err = treeentryinfodb.Update(model)
require.NoError(t, err)
_, err = treeentryinfodb.Get(model)
require.NoError(t, err)
err = treeentryinfodb.Update(secondModel)
require.NoError(t, err)
condition = func() bool {
return model.Sequence == 100
}
require.Condition(t, condition, "Inner exception")
treeentryinfodb.Remove(model)
count, err = treeentryinfodb.Count()
require.NoError(t, err)
condition = func() bool {
return count == 0
}
require.Condition(t, condition, "Expected count to be 0", count)
err = treeentryinfodb.DbConfig.CloseDb()
isOpened = treeentryinfodb.DbConfig.DBIsOpened()
require.NoError(t, err)
condition = func() bool {
return !isOpened
}
require.Condition(t, condition, "Expected db is not opened", isOpened)
err = treeentryinfodb.DbConfig.DeleteDb()
require.NoError(t, err)
isExist := treeentryinfodb.DbConfig.DBIsExist()
condition = func() bool {
return !isExist
}
require.Condition(t, condition, "Expected db is not exist", isExist)
}