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
import (
"bytes"
"crypto/ed25519"
"encoding/binary"
"encoding/json"
"fmt"
"net"
"net/url"
"sync/atomic"
@ -253,29 +250,3 @@ func (c *Core) SetAdmin(a AddHandler) error {
}
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
import (
"crypto/ed25519"
"crypto/x509"
"encoding/binary"
"database/sql"
"fmt"
"os"
"path/filepath"
@ -26,19 +24,20 @@ func New() (*PeerInfoDBConfig, error) {
filePath := filepath.Join(dir, fileName)
schemas := []string{
`CREATE TABLE IF NOT EXISTS peer_infos (
Id INTEGER NOT NULL PRIMARY KEY,
uri TEXT,
up BOOLEAN,
inbound BOOLEAN,
last_error VARCHAR,
last_error_time TIMESTAMP,
key VARCHAR,
root VARCHAR,
coords VARCHAR,
up INTEGER,
inbound INTEGER,
last_error TEXT NULL,
last_error_time TIMESTAMP NULL,
key BLOB,
root BLOB,
coords BLOB,
port INT,
priority TINYINT,
Rxbytes BIGINT,
Txbytes BIGINT,
uptime BIGINT,
uptime INTEGER,
latency SMALLINT
);`}
dbcfg, err := db.New("sqlite3", &schemas, filePath)
@ -52,132 +51,84 @@ func New() (*PeerInfoDBConfig, error) {
return cfg, nil
}
func (cfg *PeerInfoDBConfig) AddPeer(peer core.PeerInfo) (err error) {
var key, root []byte
if peer.Key != nil {
key, err = x509.MarshalPKIXPublicKey(peer.Key)
func (cfg *PeerInfoDBConfig) Add(model *core.PeerInfoDB) (_ sql.Result, err error) {
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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
result, err := cfg.DbConfig.DB.Exec(query,
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 {
return nil, err
}
LastInsertId, err := result.LastInsertId()
if err != nil {
return nil, err
}
model.Id = int(LastInsertId)
return result, nil
}
func (cfg *PeerInfoDBConfig) Remove(model *core.PeerInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec("DELETE FROM peer_infos WHERE Id = ?",
model.Id)
if err != nil {
return err
}
return nil
}
func (cfg *PeerInfoDBConfig) Get(model *core.PeerInfoDB) (_ *sql.Rows, err error) {
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 {
return nil, err
}
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 {
return err
return rows, err
}
}
if peer.Root != nil {
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)
}
}
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)
model.Coords, err = core.ConvertToUintSlise(model.CoordsBytes)
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) RemovePeer(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
}
_, err = cfg.DbConfig.DB.Exec("DELETE FROM peer_infos WHERE uri = ? AND key = ? AND root = ?",
peer.URI, key, root)
if err != nil {
return err
}
return nil
}
func (cfg *PeerInfoDBConfig) GetPeer(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
}
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)
}
}
func (cfg *PeerInfoDBConfig) Update(model *core.PeerInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec(`UPDATE peer_infos
SET
up = ?,
@ -189,12 +140,15 @@ func (cfg *PeerInfoDBConfig) UpdatePeer(peer core.PeerInfo) (err error) {
priority = ?,
RXBytes = RXBytes + ?,
TXBytes = TXBytes + ?,
uptime = ?,
latency = ?
uptime = uptime + ?,
latency = ?,
uri = ?,
key = ?,
root = ?
WHERE
uri = ? AND key = ? AND root = ?`,
peer.Up, peer.Inbound, peerErr, peer.LastErrorTime, coordsBlob, peer.Port, peer.Priority,
peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency, peer.URI, key, root)
Id = ?`,
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, model.Id)
if err != nil {
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
import (
"bytes"
"crypto/ed25519"
"crypto/rand"
"crypto/x509"
"encoding/binary"
"errors"
"fmt"
"reflect"
"strconv"
@ -20,33 +18,39 @@ import (
)
func TestPeerGetCoords(t *testing.T) {
peer := core.PeerInfo{
peerinfo := core.PeerInfo{
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}
var coordinates = peer.GetCoordinates()
if reflect.DeepEqual(target, coordinates) {
coordinates := core.ConvertToByteSlise(peer.Coords)
if !reflect.DeepEqual(target, coordinates) {
t.Error(fmt.Errorf("Not equal"))
}
}
func TestPeerSetCoords(t *testing.T) {
peer := core.PeerInfo{
Coords: []uint64{1, 2, 3, 4},
peerinfo := core.PeerInfo{}
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 coordinates = peer.SetCoordinates(&target)
if reflect.DeepEqual(target, coordinates) {
var err error
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}
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"))
}
fmt.Print(peer.Coords)
}
func TestAddPeer(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := peerinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
@ -55,12 +59,11 @@ func TestAddPeer(t *testing.T) {
require.NoError(t, err)
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
peer := core.PeerInfo{
peerinfo := core.PeerInfo{
URI: "test.test",
Up: true,
Inbound: true,
LastError: nil,
LastError: errors.New("test"),
LastErrorTime: time.Now(),
Key: pubkey,
Root: rootPubKey,
@ -72,28 +75,19 @@ func TestAddPeer(t *testing.T) {
Uptime: 3600,
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").
WithArgs(
peer.URI,
peer.Up,
peer.Inbound,
nil,
peer.PeerErr,
peer.LastErrorTime,
pKey,
pKeyRoot,
coordsBlob,
peer.KeyBytes,
peer.RootBytes,
peer.CoordsBytes,
peer.Port,
peer.Priority,
peer.RXBytes,
@ -103,7 +97,7 @@ func TestAddPeer(t *testing.T) {
).
WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.AddPeer(peer)
_, err = cfg.Add(peer)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
@ -114,7 +108,6 @@ func TestRemovePeer(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := peerinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
@ -124,11 +117,11 @@ func TestRemovePeer(t *testing.T) {
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
peer := core.PeerInfo{
peerinfo := core.PeerInfo{
URI: "test.test",
Up: true,
Inbound: true,
LastError: nil,
LastError: errors.New("test"),
LastErrorTime: time.Now(),
Key: pubkey,
Root: rootPubKey,
@ -140,16 +133,14 @@ func TestRemovePeer(t *testing.T) {
Uptime: 3600,
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)
mock.ExpectExec("DELETE FROM peer_infos WHERE uri = \\? AND key = \\? AND root = \\?").
WithArgs(peer.URI, pKey, pKeyRoot).
mock.ExpectExec("DELETE FROM peer_infos WHERE Id = \\?").
WithArgs(peer.Id).
WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.RemovePeer(peer)
err = cfg.Remove(peer)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
@ -170,11 +161,11 @@ func TestGetPeer(t *testing.T) {
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
peer := core.PeerInfo{
peerinfo := core.PeerInfo{
URI: "test.test",
Up: true,
Inbound: true,
LastError: nil,
LastError: errors.New("test"),
LastErrorTime: time.Now(),
Key: pubkey,
Root: rootPubKey,
@ -186,20 +177,21 @@ func TestGetPeer(t *testing.T) {
Uptime: 3600,
Latency: 50.0,
}
pKey, err := x509.MarshalPKIXPublicKey(peer.Key)
peer, err := core.NewPeerInfoDB(peerinfo)
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 = ?").
WithArgs(peer.URI, pKey, pKeyRoot).
rows := sqlmock.NewRows([]string{"up", "inbound", "last_error", "last_error_time", "coords",
"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)
err = cfg.GetPeer(&peer)
_, err = cfg.Get(peer)
t.Log(err)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
@ -210,7 +202,6 @@ func TestUpdatePeer(t *testing.T) {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
defer mockDB.Close()
cfg, err := peerinfodb.New()
require.NoError(t, err)
cfg.DbConfig.DB = mockDB
@ -219,12 +210,11 @@ func TestUpdatePeer(t *testing.T) {
require.NoError(t, err)
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
peer := core.PeerInfo{
peerinfo := core.PeerInfo{
URI: "test.test",
Up: true,
Inbound: true,
LastError: nil,
LastError: errors.New("test"),
LastErrorTime: time.Now(),
Key: pubkey,
Root: rootPubKey,
@ -236,17 +226,7 @@ func TestUpdatePeer(t *testing.T) {
Uptime: 3600,
Latency: 50.0,
}
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)
}
}
peer, err := core.NewPeerInfoDB(peerinfo)
require.NoError(t, err)
mock.ExpectExec(`UPDATE peer_infos
SET
@ -259,23 +239,25 @@ func TestUpdatePeer(t *testing.T) {
priority = \?,
RXBytes = RXBytes \+ \?,
TXBytes = TXBytes \+ \?,
uptime = \?,
latency = \?
uptime = uptime \+ \?,
latency = \?,
uri = \?,
key = \?,
root = \?
WHERE
uri = \? AND key = \? AND root = \?`).
Id = \?`).
WithArgs(
peer.Up, peer.Inbound, peer.LastError, peer.LastErrorTime, coordsBlob, peer.Port, peer.Priority,
peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency, peer.URI, pKey, pKeyRoot).
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, peer.Id).
WillReturnResult(sqlmock.NewResult(1, 1))
err = cfg.UpdatePeer(peer)
err = cfg.Update(peer)
require.NoError(t, err)
err = mock.ExpectationsWereMet()
require.NoError(t, err)
}
// One more test here
func TestMain(t *testing.T) {
peerinfodb.Name = fmt.Sprintf(
"%s.%s",
@ -297,7 +279,7 @@ func TestMain(t *testing.T) {
require.NoError(t, err)
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
peer := core.PeerInfo{
peerinfo := core.PeerInfo{
URI: "test.test",
Up: true,
Inbound: true,
@ -313,14 +295,16 @@ func TestMain(t *testing.T) {
Uptime: 3600,
Latency: 50.0,
}
peer, err := core.NewPeerInfoDB(peerinfo)
require.NoError(t, err)
root2PubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)
peer2 := core.PeerInfo{
peerinfo2 := core.PeerInfo{
URI: "new.test",
Up: true,
Inbound: true,
LastError: nil,
LastError: errors.New("test2"),
LastErrorTime: time.Now(),
Key: pubkey,
Root: root2PubKey,
@ -332,9 +316,13 @@ func TestMain(t *testing.T) {
Uptime: 3600,
Latency: 50.0,
}
peer2, err := core.NewPeerInfoDB(peerinfo2)
require.NoError(t, err)
peerdb.AddPeer(peer)
peerdb.AddPeer(peer2)
_, err = peerdb.Add(peer)
require.NoError(t, err)
_, err = peerdb.Add(peer2)
require.NoError(t, err)
count, err := peerdb.Count()
require.NoError(t, err)
condition = func() bool {
@ -342,29 +330,35 @@ func TestMain(t *testing.T) {
}
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()
require.NoError(t, err)
condition = func() bool {
return count == 1
}
require.Condition(t, condition, "Expected count to be 1", count)
peer2.Latency = 10
peer2.RXBytes = 1024
peer2.TXBytes = 1024
peer2.Port = 80
peerdb.UpdatePeer(peer2)
peerdb.GetPeer(&peer2)
err = peerdb.Update(peer2)
require.NoError(t, err)
_, err = peerdb.Get(peer2)
require.NoError(t, err)
condition = func() bool {
return peer2.Latency == 10 &&
peer2.RXBytes == 2048 &&
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")
peerdb.RemovePeer(peer2)
peerdb.Remove(peer2)
count, err = peerdb.Count()
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)
}