improve docs and tests
This commit is contained in:
parent
5fd5733261
commit
d5533157a3
|
@ -1,8 +1,9 @@
|
||||||
// Package that provides the functionality to open, close and use a database
|
// Package database provides the functionality to open, close and use a database
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
|
// load gorm defaults dialects
|
||||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
_ "github.com/jinzhu/gorm/dialects/postgres"
|
_ "github.com/jinzhu/gorm/dialects/postgres"
|
||||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||||
|
@ -10,10 +11,10 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Database connection for writing purposes
|
// Write Database connection for writing purposes
|
||||||
var Write *gorm.DB
|
var Write *gorm.DB
|
||||||
|
|
||||||
// Database connection for reading purposes
|
// Read Database connection for reading purposes
|
||||||
var Read *gorm.DB
|
var Read *gorm.DB
|
||||||
|
|
||||||
// Configuration files
|
// Configuration files
|
||||||
|
@ -22,7 +23,7 @@ var (
|
||||||
runtime []interface{}
|
runtime []interface{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Configuration of the database connection
|
// Config of the database connection
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// type of the database, currently supports sqlite and postgres
|
// type of the database, currently supports sqlite and postgres
|
||||||
Type string
|
Type string
|
||||||
|
@ -34,7 +35,7 @@ type Config struct {
|
||||||
Logging bool
|
Logging bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to open a database and set the given configuration
|
// Open database and set the given configuration
|
||||||
func Open(c Config) (err error) {
|
func Open(c Config) (err error) {
|
||||||
writeLog := log.WithField("db", "write")
|
writeLog := log.WithField("db", "write")
|
||||||
config = &c
|
config = &c
|
||||||
|
@ -65,7 +66,7 @@ func Open(c Config) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to safely close the database
|
// Close connnection to database safely
|
||||||
func Close() {
|
func Close() {
|
||||||
Write.Close()
|
Write.Close()
|
||||||
if len(config.ReadConnection) > 0 {
|
if len(config.ReadConnection) > 0 {
|
||||||
|
@ -73,7 +74,7 @@ func Close() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to add a model to the runtime
|
// AddModel to the runtime
|
||||||
func AddModel(m interface{}) {
|
func AddModel(m interface{}) {
|
||||||
runtime = append(runtime, m)
|
runtime = append(runtime, m)
|
||||||
}
|
}
|
||||||
|
|
22
file/main.go
22
file/main.go
|
@ -8,18 +8,14 @@ import (
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadConfigFile reads a config model from path of a yml file
|
// ReadTOML reads a config model from path of a yml file
|
||||||
func ReadTOML(path string, data interface{}) error {
|
func ReadTOML(path string, data interface{}) error {
|
||||||
file, err := ioutil.ReadFile(path)
|
file, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := toml.Unmarshal(file, data); err != nil {
|
return toml.Unmarshal(file, data)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadJSON reads a config model from path of a yml file
|
// ReadJSON reads a config model from path of a yml file
|
||||||
|
@ -29,11 +25,7 @@ func ReadJSON(path string, data interface{}) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.NewDecoder(file).Decode(data); err != nil {
|
return json.NewDecoder(file).Decode(data)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveJSON to path
|
// SaveJSON to path
|
||||||
|
@ -45,13 +37,11 @@ func SaveJSON(outputFile string, data interface{}) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.NewEncoder(file).Encode(data); err != nil {
|
err = json.NewEncoder(file).Encode(data)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
file.Close()
|
file.Close()
|
||||||
if err := os.Rename(tmpFile, outputFile); err != nil {
|
return os.Rename(tmpFile, outputFile)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestReadTOML(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
a := struct {
|
||||||
|
Text string `toml:"text"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
err := ReadTOML("testfiles/donoexists", &a)
|
||||||
|
assert.Error(err, "could find file ^^")
|
||||||
|
|
||||||
|
err = ReadTOML("testfiles/trash.txt", &a)
|
||||||
|
assert.Error(err, "could marshel file ^^")
|
||||||
|
|
||||||
|
err = ReadTOML("testfiles/ok.toml", &a)
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal("hallo", a.Text)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadJSON(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
a := struct {
|
||||||
|
Text string `toml:"text"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
err := ReadJSON("testfiles/donoexists", &a)
|
||||||
|
assert.Error(err, "could find file ^^")
|
||||||
|
|
||||||
|
err = ReadJSON("testfiles/trash.txt", &a)
|
||||||
|
assert.Error(err, "could marshel file ^^")
|
||||||
|
|
||||||
|
err = ReadJSON("testfiles/ok.json", &a)
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal("hallo", a.Text)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSaveJSON(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tmpfile, _ := ioutil.TempFile("/tmp", "lib-json-testfile.json")
|
||||||
|
err := SaveJSON(tmpfile.Name(), 3)
|
||||||
|
assert.NoError(err, "could not save temp")
|
||||||
|
|
||||||
|
err = SaveJSON(tmpfile.Name(), tmpfile.Name)
|
||||||
|
assert.Error(err, "could not save func")
|
||||||
|
|
||||||
|
err = SaveJSON("/dev/null", 4)
|
||||||
|
assert.Error(err, "could not save to /dev/null")
|
||||||
|
|
||||||
|
var testvalue int
|
||||||
|
err = ReadJSON(tmpfile.Name(), &testvalue)
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal(3, testvalue)
|
||||||
|
os.Remove(tmpfile.Name())
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"text": "hallo"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
text = "hallo"
|
|
@ -0,0 +1 @@
|
||||||
|
wrong format example
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"dev.sum7.eu/genofire/golang-lib/worker"
|
"dev.sum7.eu/genofire/golang-lib/worker"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewSaveJSONWorker Starts a worker, which save periodly data to json file
|
||||||
func NewSaveJSONWorker(repeat time.Duration, path string, data interface{}) *worker.Worker {
|
func NewSaveJSONWorker(repeat time.Duration, path string, data interface{}) *worker.Worker {
|
||||||
saveWorker := worker.NewWorker(repeat, func() {
|
saveWorker := worker.NewWorker(repeat, func() {
|
||||||
SaveJSON(path, data)
|
SaveJSON(path, data)
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSaveJSONWorker(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tmpfile, _ := ioutil.TempFile("/tmp", "lib-json-workertest.json")
|
||||||
|
|
||||||
|
worker := NewSaveJSONWorker(100*time.Millisecond, tmpfile.Name(), 12)
|
||||||
|
assert.NotNil(worker)
|
||||||
|
|
||||||
|
time.Sleep(300 * time.Millisecond)
|
||||||
|
|
||||||
|
var testvalue int
|
||||||
|
err := ReadJSON(tmpfile.Name(), &testvalue)
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal(12, testvalue)
|
||||||
|
os.Remove(tmpfile.Name())
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Package that provides the logic of the webserver
|
// Package http provides the logic of the webserver
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -8,7 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Function to read data from a http request via json format (input)
|
// Read data from a http request via json format (input)
|
||||||
func Read(r *http.Request, to interface{}) (err error) {
|
func Read(r *http.Request, to interface{}) (err error) {
|
||||||
if !strings.Contains(r.Header.Get("Content-Type"), "application/json") {
|
if !strings.Contains(r.Header.Get("Content-Type"), "application/json") {
|
||||||
err = errors.New("no json request received")
|
err = errors.New("no json request received")
|
||||||
|
@ -18,7 +18,7 @@ func Read(r *http.Request, to interface{}) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to write data as json to a http response (output)
|
// Write data as json to a http response (output)
|
||||||
func Write(w http.ResponseWriter, data interface{}) {
|
func Write(w http.ResponseWriter, data interface{}) {
|
||||||
js, err := json.Marshal(data)
|
js, err := json.Marshal(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package http
|
||||||
|
|
||||||
import "net/http"
|
import "net/http"
|
||||||
|
|
||||||
|
// GetRemoteIP of http Request
|
||||||
func GetRemoteIP(r *http.Request) string {
|
func GetRemoteIP(r *http.Request) string {
|
||||||
ip := r.Header.Get("X-Forwarded-For")
|
ip := r.Header.Get("X-Forwarded-For")
|
||||||
if len(ip) <= 1 {
|
if len(ip) <= 1 {
|
||||||
|
|
|
@ -7,8 +7,9 @@ import (
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
const channelBufSize = 100
|
const channelBufSize = 1000
|
||||||
|
|
||||||
|
// Client of Websocket Server Connection
|
||||||
type Client struct {
|
type Client struct {
|
||||||
id uuid.UUID
|
id uuid.UUID
|
||||||
server *Server
|
server *Server
|
||||||
|
@ -18,12 +19,6 @@ type Client struct {
|
||||||
readQuit chan bool
|
readQuit chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTestClient(out chan *Message) *Client {
|
|
||||||
return &Client{
|
|
||||||
out: out,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewClient(s *Server, ws *websocket.Conn) *Client {
|
func NewClient(s *Server, ws *websocket.Conn) *Client {
|
||||||
|
|
||||||
if ws == nil {
|
if ws == nil {
|
||||||
|
|
|
@ -66,7 +66,6 @@ func (s *Server) DelClient(c *Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) SendAll(msg *Message) {
|
func (s *Server) SendAll(msg *Message) {
|
||||||
s.clientsMutex.Lock()
|
s.clientsMutex.Lock()
|
||||||
defer s.clientsMutex.Unlock()
|
defer s.clientsMutex.Unlock()
|
||||||
|
|
|
@ -3,10 +3,10 @@ package websocket
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,14 +39,14 @@ func TestServerSendAll(t *testing.T) {
|
||||||
srv := NewServer(nil, nil)
|
srv := NewServer(nil, nil)
|
||||||
assert.NotNil(srv)
|
assert.NotNil(srv)
|
||||||
|
|
||||||
out1 := make(chan *Message)
|
out1 := make(chan *Message, 2)
|
||||||
c1 := &Client{
|
c1 := &Client{
|
||||||
id: uuid.New(),
|
id: uuid.New(),
|
||||||
out: out1,
|
out: out1,
|
||||||
server: srv,
|
server: srv,
|
||||||
}
|
}
|
||||||
|
|
||||||
out2 := make(chan *Message)
|
out2 := make(chan *Message, 2)
|
||||||
c2 := &Client{
|
c2 := &Client{
|
||||||
id: uuid.New(),
|
id: uuid.New(),
|
||||||
out: out2,
|
out: out2,
|
||||||
|
@ -55,22 +55,21 @@ func TestServerSendAll(t *testing.T) {
|
||||||
srv.AddClient(c1)
|
srv.AddClient(c1)
|
||||||
srv.AddClient(c2)
|
srv.AddClient(c2)
|
||||||
|
|
||||||
go func() {
|
wg := sync.WaitGroup{}
|
||||||
|
|
||||||
msg := <-out1
|
client := func(out chan *Message) {
|
||||||
|
msg := <-out
|
||||||
assert.Equal("hi", msg.Subject)
|
assert.Equal("hi", msg.Subject)
|
||||||
|
wg.Done()
|
||||||
}()
|
}
|
||||||
go func() {
|
wg.Add(2)
|
||||||
|
go client(out1)
|
||||||
msg := <-out2
|
go client(out2)
|
||||||
assert.Equal("hi", msg.Subject)
|
|
||||||
|
|
||||||
}()
|
|
||||||
|
|
||||||
srv.SendAll(&Message{
|
srv.SendAll(&Message{
|
||||||
Subject: "hi",
|
Subject: "hi",
|
||||||
})
|
})
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
srv.DelClient(c2)
|
srv.DelClient(c2)
|
||||||
srv.DelClient(c1)
|
srv.DelClient(c1)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Package with a lib for cronjobs to run in background
|
// Package worker a lib for cronjobs to run in background
|
||||||
package worker
|
package worker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -6,7 +6,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Struct which handles the job
|
// Worker Struct which handles the job
|
||||||
type Worker struct {
|
type Worker struct {
|
||||||
every time.Duration
|
every time.Duration
|
||||||
run func()
|
run func()
|
||||||
|
@ -14,7 +14,7 @@ type Worker struct {
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to create a new Worker with a timestamp, run, every and it's function
|
// NewWorker create a Worker with a timestamp, run, every and it's function
|
||||||
func NewWorker(every time.Duration, f func()) (w *Worker) {
|
func NewWorker(every time.Duration, f func()) (w *Worker) {
|
||||||
w = &Worker{
|
w = &Worker{
|
||||||
every: every,
|
every: every,
|
||||||
|
@ -24,8 +24,7 @@ func NewWorker(every time.Duration, f func()) (w *Worker) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to start the Worker
|
// Start the Worker
|
||||||
// (please us it as a go routine with go w.Start())
|
|
||||||
func (w *Worker) Start() {
|
func (w *Worker) Start() {
|
||||||
w.wg.Add(1)
|
w.wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -43,7 +42,7 @@ func (w *Worker) Start() {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to stop the Worker
|
// Close stops the Worker
|
||||||
func (w *Worker) Close() {
|
func (w *Worker) Close() {
|
||||||
close(w.quit)
|
close(w.quit)
|
||||||
w.wg.Wait()
|
w.wg.Wait()
|
||||||
|
|
Loading…
Reference in New Issue