[TASK] extract enable to all databases + increase testing in database

(#78)
This commit is contained in:
Geno 2017-12-31 05:26:17 +01:00 committed by Martin Geno
parent 3422a29254
commit 69079b7d64
No known key found for this signature in database
GPG Key ID: F0D39A37E925E941
16 changed files with 431 additions and 44 deletions

26
data/nodeinfo_test.go Normal file
View File

@ -0,0 +1,26 @@
package data
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestNodeinfoBatAddresses(t *testing.T) {
assert := assert.New(t)
batIface := &BatInterface{
Interfaces: struct {
Wireless []string `json:"wireless,omitempty"`
Other []string `json:"other,omitempty"`
Tunnel []string `json:"tunnel,omitempty"`
}{
Wireless: nil,
Other: []string{"aa:aa:aa:aa:aa", "aa:aa:aa:aa:ab"},
Tunnel: []string{},
},
}
addr := batIface.Addresses()
assert.NotNil(addr)
assert.Equal([]string{"aa:aa:aa:aa:aa", "aa:aa:aa:aa:ab"}, addr)
}

View File

@ -1,6 +1,7 @@
package all package all
import ( import (
"log"
"time" "time"
"github.com/FreifunkBremen/yanic/database" "github.com/FreifunkBremen/yanic/database"
@ -12,12 +13,23 @@ type Connection struct {
list []database.Connection list []database.Connection
} }
func Connect(configuration interface{}) (database.Connection, error) { func Connect(allConnection map[string]interface{}) (database.Connection, error) {
var list []database.Connection var list []database.Connection
allConnection := configuration.(map[string][]interface{})
for dbType, conn := range database.Adapters { for dbType, conn := range database.Adapters {
dbConfigs := allConnection[dbType] configForType := allConnection[dbType]
if configForType == nil {
log.Printf("the output type '%s' has no configuration\n", dbType)
continue
}
dbConfigs, ok := configForType.([]map[string]interface{})
if !ok {
log.Panicf("the output type '%s' has the wrong format\n", dbType)
}
for _, config := range dbConfigs { for _, config := range dbConfigs {
if c, ok := config["enable"].(bool); ok && !c {
continue
}
connected, err := conn(config) connected, err := conn(config)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -1 +1,156 @@
package all package all
import (
"errors"
"sync"
"testing"
"time"
"github.com/FreifunkBremen/yanic/database"
"github.com/FreifunkBremen/yanic/runtime"
"github.com/stretchr/testify/assert"
)
type testConn struct {
database.Connection
countNode int
countLink int
countGlobals int
countPrune int
countClose int
sync.Mutex
}
func (c *testConn) InsertNode(node *runtime.Node) {
c.Lock()
c.countNode++
c.Unlock()
}
func (c *testConn) GetNode() int {
c.Lock()
defer c.Unlock()
return c.countNode
}
func (c *testConn) InsertLink(link *runtime.Link, time time.Time) {
c.Lock()
c.countLink++
c.Unlock()
}
func (c *testConn) GetLink() int {
c.Lock()
defer c.Unlock()
return c.countLink
}
func (c *testConn) InsertGlobals(stats *runtime.GlobalStats, time time.Time, site string) {
c.Lock()
c.countGlobals++
c.Unlock()
}
func (c *testConn) GetGlobal() int {
c.Lock()
defer c.Unlock()
return c.countGlobals
}
func (c *testConn) PruneNodes(time.Duration) {
c.Lock()
c.countPrune++
c.Unlock()
}
func (c *testConn) GetPrune() int {
c.Lock()
defer c.Unlock()
return c.countPrune
}
func (c *testConn) Close() {
c.Lock()
c.countClose++
c.Unlock()
}
func (c *testConn) GetClose() int {
c.Lock()
defer c.Unlock()
return c.countClose
}
func TestStart(t *testing.T) {
assert := assert.New(t)
globalConn := &testConn{}
database.RegisterAdapter("a", func(config map[string]interface{}) (database.Connection, error) {
return globalConn, nil
})
database.RegisterAdapter("b", func(config map[string]interface{}) (database.Connection, error) {
return globalConn, nil
})
database.RegisterAdapter("c", func(config map[string]interface{}) (database.Connection, error) {
return globalConn, nil
})
database.RegisterAdapter("d", func(config map[string]interface{}) (database.Connection, error) {
return nil, nil
})
database.RegisterAdapter("e", func(config map[string]interface{}) (database.Connection, error) {
return nil, errors.New("blub")
})
allConn, err := Connect(map[string]interface{}{
"a": []map[string]interface{}{
map[string]interface{}{
"enable": false,
"path": "a1",
},
map[string]interface{}{
"path": "a2",
},
map[string]interface{}{
"enable": true,
"path": "a3",
},
},
"b": nil,
"c": []map[string]interface{}{
map[string]interface{}{
"path": "c1",
},
},
// fetch continue command in Connect
"d": []map[string]interface{}{
map[string]interface{}{
"path": "d0",
},
},
})
assert.NoError(err)
assert.Equal(0, globalConn.GetNode())
allConn.InsertNode(nil)
assert.Equal(3, globalConn.GetNode())
assert.Equal(0, globalConn.GetLink())
allConn.InsertLink(nil, time.Now())
assert.Equal(3, globalConn.GetLink())
assert.Equal(0, globalConn.GetGlobal())
allConn.InsertGlobals(nil, time.Now(), runtime.GLOBAL_SITE)
assert.Equal(3, globalConn.GetGlobal())
assert.Equal(0, globalConn.GetPrune())
allConn.PruneNodes(time.Second)
assert.Equal(3, globalConn.GetPrune())
assert.Equal(0, globalConn.GetClose())
allConn.Close()
assert.Equal(3, globalConn.GetClose())
_, err = Connect(map[string]interface{}{
"e": []map[string]interface{}{
map[string]interface{}{},
},
})
assert.Error(err)
// wrong format -> the only panic in Register
assert.Panics(func() {
Connect(map[string]interface{}{
"e": true,
})
})
}

View File

@ -25,7 +25,7 @@ type Connection interface {
} }
// Connect function with config to get DB connection interface // Connect function with config to get DB connection interface
type Connect func(config interface{}) (Connection, error) type Connect func(config map[string]interface{}) (Connection, error)
// Adapters is the list of registered database adapters // Adapters is the list of registered database adapters
var Adapters = map[string]Connect{} var Adapters = map[string]Connect{}

View File

@ -6,11 +6,11 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestNow(t *testing.T) { func TestRegister(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
assert.Len(Adapters, 0) assert.Len(Adapters, 0)
RegisterAdapter("blub", func(config interface{}) (Connection, error) { RegisterAdapter("blub", func(config map[string]interface{}) (Connection, error) {
return nil, nil return nil, nil
}) })

View File

@ -33,18 +33,10 @@ func (c Config) Prefix() string {
return c["prefix"].(string) return c["prefix"].(string)
} }
func (c Config) Enable() bool { func Connect(configuration map[string]interface{}) (database.Connection, error) {
return c["enable"].(bool)
}
func Connect(configuration interface{}) (database.Connection, error) {
var config Config var config Config
config = configuration.(map[string]interface{}) config = configuration
if !config.Enable() {
return nil, nil
}
con := &Connection{ con := &Connection{
client: graphigo.Client{ client: graphigo.Client{

View File

@ -32,9 +32,6 @@ type Connection struct {
type Config map[string]interface{} type Config map[string]interface{}
func (c Config) Enable() bool {
return c["enable"].(bool)
}
func (c Config) Address() string { func (c Config) Address() string {
return c["address"].(string) return c["address"].(string)
} }
@ -57,12 +54,10 @@ func (c Config) Tags() map[string]interface{} {
func init() { func init() {
database.RegisterAdapter("influxdb", Connect) database.RegisterAdapter("influxdb", Connect)
} }
func Connect(configuration interface{}) (database.Connection, error) { func Connect(configuration map[string]interface{}) (database.Connection, error) {
var config Config var config Config
config = configuration.(map[string]interface{}) config = configuration
if !config.Enable() {
return nil, nil
}
// Make client // Make client
c, err := client.NewHTTPClient(client.HTTPConfig{ c, err := client.NewHTTPClient(client.HTTPConfig{
Addr: config.Address(), Addr: config.Address(),

View File

@ -10,6 +10,27 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestConnect(t *testing.T) {
assert := assert.New(t)
conn, err := Connect(map[string]interface{}{
"address": "",
"username": "",
"password": "",
})
assert.Nil(conn)
assert.Error(err)
conn, err = Connect(map[string]interface{}{
"address": "http://localhost",
"database": "",
"username": "",
"password": "",
})
assert.NotNil(conn)
assert.NoError(err)
}
func TestAddPoint(t *testing.T) { func TestAddPoint(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)

View File

@ -1,8 +1,11 @@
package influxdb package influxdb
import ( import (
"sync"
"testing" "testing"
"time"
"github.com/influxdata/influxdb/client/v2"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/FreifunkBremen/yanic/data" "github.com/FreifunkBremen/yanic/data"
@ -20,9 +23,68 @@ func TestGlobalStats(t *testing.T) {
fields := GlobalStatsFields(stats[runtime.GLOBAL_SITE]) fields := GlobalStatsFields(stats[runtime.GLOBAL_SITE])
assert.EqualValues(3, fields["nodes"]) assert.EqualValues(3, fields["nodes"])
// check TEST_SITE fields
fields = GlobalStatsFields(stats[TEST_SITE]) fields = GlobalStatsFields(stats[TEST_SITE])
assert.EqualValues(2, fields["nodes"]) assert.EqualValues(1, fields["nodes"])
conn := &Connection{
points: make(chan *client.Point),
}
global := 0
globalSite := 0
model := 0
modelSite := 0
firmware := 0
firmwareSite := 0
autoupdater := 0
autoupdaterSite := 0
wg := sync.WaitGroup{}
wg.Add(9)
go func() {
for p := range conn.points {
switch p.Name() {
case MeasurementGlobal:
global++
break
case "global_site":
globalSite++
break
case CounterMeasurementModel:
model++
break
case "model_site":
modelSite++
break
case CounterMeasurementFirmware:
firmware++
break
case "firmware_site":
firmwareSite++
break
case CounterMeasurementAutoupdater:
autoupdater++
break
case "autoupdater_site":
autoupdaterSite++
break
default:
assert.Equal("invalid p.Name found", p.Name())
}
wg.Done()
}
}()
for site, stat := range stats {
conn.InsertGlobals(stat, time.Now(), site)
}
wg.Wait()
assert.Equal(1, global)
assert.Equal(1, globalSite)
assert.Equal(2, model)
assert.Equal(1, modelSite)
assert.Equal(1, firmware)
assert.Equal(0, firmwareSite)
assert.Equal(2, autoupdater)
assert.Equal(1, autoupdaterSite)
} }
func createTestNodes() *runtime.Nodes { func createTestNodes() *runtime.Nodes {
@ -40,9 +102,7 @@ func createTestNodes() *runtime.Nodes {
Hardware: data.Hardware{ Hardware: data.Hardware{
Model: "TP-Link 841", Model: "TP-Link 841",
}, },
System: data.System{ System: data.System{},
SiteCode: TEST_SITE,
},
}, },
} }
nodeData.Nodeinfo.Software.Firmware.Release = "2016.1.6+entenhausen1" nodeData.Nodeinfo.Software.Firmware.Release = "2016.1.6+entenhausen1"

View File

@ -82,7 +82,9 @@ func TestToInflux(t *testing.T) {
}, },
}, },
}, },
LLDP: map[string]data.LLDPNeighbours{}, LLDP: map[string]data.LLDPNeighbours{
"b-interface": data.LLDPNeighbours{},
},
}, },
} }

69
database/internal_test.go Normal file
View File

@ -0,0 +1,69 @@
package database
import (
"sync"
"testing"
"time"
"github.com/FreifunkBremen/yanic/runtime"
"github.com/stretchr/testify/assert"
)
type testConn struct {
Connection
countClose int
countPrune int
sync.Mutex
}
func (c *testConn) Close() {
c.Lock()
c.countClose++
c.Unlock()
}
func (c *testConn) GetClose() int {
c.Lock()
defer c.Unlock()
return c.countClose
}
func (c *testConn) PruneNodes(time.Duration) {
c.Lock()
c.countPrune++
c.Unlock()
}
func (c *testConn) GetPruneNodes() int {
c.Lock()
defer c.Unlock()
return c.countPrune
}
func TestStart(t *testing.T) {
assert := assert.New(t)
conn := &testConn{}
config := &runtime.Config{
Database: struct {
DeleteInterval runtime.Duration `toml:"delete_interval"`
DeleteAfter runtime.Duration `toml:"delete_after"`
Connection map[string]interface{}
}{
DeleteInterval: runtime.Duration{Duration: time.Millisecond * 10},
},
}
assert.Nil(quit)
Start(conn, config)
assert.NotNil(quit)
assert.Equal(0, conn.GetPruneNodes())
time.Sleep(time.Millisecond * 12)
assert.Equal(1, conn.GetPruneNodes())
assert.Equal(0, conn.GetClose())
Close(conn)
assert.NotNil(quit)
assert.Equal(1, conn.GetClose())
time.Sleep(time.Millisecond * 12) // to reach timer.Stop() line
}

View File

@ -23,9 +23,6 @@ type Connection struct {
type Config map[string]interface{} type Config map[string]interface{}
func (c Config) Enable() bool {
return c["enable"].(bool)
}
func (c Config) Path() string { func (c Config) Path() string {
return c["path"].(string) return c["path"].(string)
} }
@ -34,12 +31,9 @@ func init() {
database.RegisterAdapter("logging", Connect) database.RegisterAdapter("logging", Connect)
} }
func Connect(configuration interface{}) (database.Connection, error) { func Connect(configuration map[string]interface{}) (database.Connection, error) {
var config Config var config Config
config = configuration.(map[string]interface{}) config = configuration
if !config.Enable() {
return nil, nil
}
file, err := os.OpenFile(config.Path(), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) file, err := os.OpenFile(config.Path(), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
if err != nil { if err != nil {

View File

@ -1 +1,60 @@
package logging package logging
import (
"io/ioutil"
"os"
"testing"
"time"
"github.com/FreifunkBremen/yanic/data"
"github.com/FreifunkBremen/yanic/runtime"
"github.com/stretchr/testify/assert"
)
func TestStart(t *testing.T) {
assert := assert.New(t)
conn, err := Connect(map[string]interface{}{
"path": "/dev/notexists/file",
})
assert.Nil(conn)
assert.Error(err)
path := "/tmp/testlogfile"
conn, err = Connect(map[string]interface{}{
"path": path,
})
dat, _ := ioutil.ReadFile(path)
assert.NotContains(string(dat), "InsertNode")
conn.InsertNode(&runtime.Node{
Statistics: &data.Statistics{},
})
dat, _ = ioutil.ReadFile(path)
assert.Contains(string(dat), "InsertNode")
assert.NotContains(string(dat), "InsertLink")
conn.InsertLink(&runtime.Link{}, time.Now())
dat, _ = ioutil.ReadFile(path)
assert.Contains(string(dat), "InsertLink")
assert.NotContains(string(dat), "InsertGlobals")
conn.InsertGlobals(&runtime.GlobalStats{}, time.Now(), runtime.GLOBAL_SITE)
dat, _ = ioutil.ReadFile(path)
assert.Contains(string(dat), "InsertGlobals")
assert.NotContains(string(dat), "PruneNodes")
conn.PruneNodes(time.Second)
dat, _ = ioutil.ReadFile(path)
assert.Contains(string(dat), "PruneNodes")
assert.NotContains(string(dat), "Close")
conn.Close()
dat, _ = ioutil.ReadFile(path)
assert.Contains(string(dat), "Close")
os.Remove(path)
}

View File

@ -172,12 +172,14 @@ func TestTransform(t *testing.T) {
assert.Equal("node:b:mac:wifi", link.TargetMAC) assert.Equal("node:b:mac:wifi", link.TargetMAC)
assert.Equal(float32(0.6), link.SourceTQ) assert.Equal(float32(0.6), link.SourceTQ)
assert.Equal(float32(0.8), link.TargetTQ) assert.Equal(float32(0.8), link.TargetTQ)
default: case "node:b:mac:lan":
assert.Equal("other", link.Type) assert.Equal("other", link.Type)
assert.Equal("node:c:mac:lan", link.TargetMAC) assert.Equal("node:c:mac:lan", link.TargetMAC)
assert.Equal(float32(0.8), link.SourceTQ) assert.Equal(float32(0.8), link.SourceTQ)
assert.Equal(float32(0.4), link.TargetTQ) assert.Equal(float32(0.4), link.TargetTQ)
break break
default:
assert.False(true, "invalid link.SourceMAC found")
} }
} }
} }

View File

@ -37,7 +37,7 @@ type Config struct {
Database struct { Database struct {
DeleteInterval Duration `toml:"delete_interval"` // Delete stats of nodes every n minutes DeleteInterval Duration `toml:"delete_interval"` // Delete stats of nodes every n minutes
DeleteAfter Duration `toml:"delete_after"` // Delete stats of nodes till now-deletetill n minutes DeleteAfter Duration `toml:"delete_after"` // Delete stats of nodes till now-deletetill n minutes
Connection map[string][]interface{} Connection map[string]interface{}
} }
} }

View File

@ -31,15 +31,15 @@ func TestReadConfig(t *testing.T) {
assert.Equal("/var/www/html/meshviewer/data/nodes.json", meshviewer["nodes_path"]) assert.Equal("/var/www/html/meshviewer/data/nodes.json", meshviewer["nodes_path"])
var influxdb map[string]interface{} var influxdb map[string]interface{}
dbs := config.Database.Connection["influxdb"] dbs := config.Database.Connection["influxdb"].([]map[string]interface{})
assert.Len(dbs, 1, "more influxdb are given") assert.Len(dbs, 1, "more influxdb are given")
influxdb = dbs[0].(map[string]interface{}) influxdb = dbs[0]
assert.Equal(influxdb["database"], "ffhb") assert.Equal(influxdb["database"], "ffhb")
var graphitedb map[string]interface{} var graphitedb map[string]interface{}
dbs = config.Database.Connection["graphite"] dbs = config.Database.Connection["graphite"].([]map[string]interface{})
assert.Len(dbs, 1, "more graphitedb are given") assert.Len(dbs, 1, "more graphitedb are given")
graphitedb = dbs[0].(map[string]interface{}) graphitedb = dbs[0]
assert.Equal(graphitedb["address"], "localhost:2003") assert.Equal(graphitedb["address"], "localhost:2003")
_, err = ReadConfigFile("testdata/config_failed.toml") _, err = ReadConfigFile("testdata/config_failed.toml")