commit 6c553e5f99e22bbe1284396a6c268a7036fd6e6e
parent d9bb3fc26ddd7fb8213c1decfea5c36e45cbd5b7
Author: Vetle Haflan <vetle@haflan.dev>
Date: Sat, 11 Apr 2020 11:28:03 +0200
Finish services and events MVP
Will probably be majorly refactored later, but it should be usable
for now
Diffstat:
4 files changed, 116 insertions(+), 26 deletions(-)
diff --git a/database/database.go b/database/database.go
@@ -145,3 +145,11 @@ func BytesToUint64(byteData []byte) uint64 {
func Uint64ToBytes(uint64Data uint64) []byte {
return []byte(strconv.FormatUint(uint64Data, 10))
}
+
+// PrintBucket simply prints the K-V pairs in the bucket
+func PrintBucket(eb *bbolt.Bucket) error {
+ return eb.ForEach(func(k, v []byte) error {
+ fmt.Printf("- %v: %v\n", string(k), string(v))
+ return nil
+ })
+}
diff --git a/events/events.go b/events/events.go
@@ -2,6 +2,7 @@ package events
import (
"errors"
+ "fmt"
"log"
"sermoni/database"
"sermoni/services"
@@ -32,7 +33,7 @@ type Event struct {
// GetAll returns all events in the database
func GetAll() (events []*Event) {
db := database.GetDB()
- db.View(func(tx *bbolt.Tx) error {
+ err := db.View(func(tx *bbolt.Tx) error {
b := tx.Bucket(database.BucketKeyEvents)
if b == nil {
log.Panic("The events bucket does not exist")
@@ -40,7 +41,7 @@ func GetAll() (events []*Event) {
// ForEach doesn't return buckets (nil instead), so only the key is useful
return b.ForEach(func(id, _ []byte) error {
eb := b.Bucket(id)
- event := &Event{}
+ event := new(Event)
if err := event.fromBucket(eb); err != nil {
return err
}
@@ -48,12 +49,24 @@ func GetAll() (events []*Event) {
return nil
})
})
+ if err != nil {
+ fmt.Println(err)
+ }
return
}
-// Delete a service event
-func Delete() {
-
+// Delete event with the given ID.
+// Returns error if no such event can be found
+func Delete(idInt uint64) error {
+ db := database.GetDB()
+ id := database.Uint64ToBytes(idInt)
+ return db.View(func(tx *bbolt.Tx) error {
+ b := tx.Bucket(database.BucketKeyEvents)
+ if b == nil {
+ log.Panic("The events bucket does notexist")
+ }
+ return b.DeleteBucket(id)
+ })
}
// Add a new service event if the token matches any services in the database
@@ -92,11 +105,15 @@ func Add(serviceToken string, event *Event) error {
func (event *Event) toBucket(eb *bbolt.Bucket) error {
var err error
id := database.Uint64ToBytes(event.ID)
- service := database.Uint64ToBytes(event.Service)
+ serviceID := database.Uint64ToBytes(event.Service)
+ timestamp := database.Uint64ToBytes(event.Timestamp)
if err = eb.Put(keyEventID, id); err != nil {
return err
}
- if eb.Put(keyEventService, service); err != nil {
+ if eb.Put(keyEventService, serviceID); err != nil {
+ return err
+ }
+ if eb.Put(keyEventTimestamp, timestamp); err != nil {
return err
}
if eb.Put(keyEventStatus, []byte(event.Status)); err != nil {
@@ -119,7 +136,7 @@ func (event *Event) fromBucket(eb *bbolt.Bucket) error {
err := errors.New("missing field from database")
// Get data from database
- if id := eb.Get(keyEventID); id == nil {
+ if id = eb.Get(keyEventID); id == nil {
return err
}
if service = eb.Get(keyEventService); service == nil {
diff --git a/events/events_test.go b/events/events_test.go
@@ -1,6 +1,7 @@
package events
import (
+ "fmt"
"os"
"sermoni/database"
"sermoni/services"
@@ -9,11 +10,69 @@ import (
const serviceToken = "test-service"
-func TestAddEvent(t *testing.T) {
- Add(serviceToken, &Event{
+func (e1 *Event) equals(e2 *Event) bool {
+ switch {
+ case e1.ID != e2.ID:
+ return false
+ case e1.Service != e2.Service:
+ return false
+ case e1.Status != e2.Status:
+ return false
+ case e1.Title != e2.Title:
+ return false
+ case e1.Details != e2.Details:
+ return false
+ default:
+ return true
+ }
+}
+
+var testEvents = []*Event{
+ {
Timestamp: 1586558825515,
+ Status: "ok",
Title: "Backup completed successfully",
- })
+ },
+ {
+ Timestamp: 1586558838488,
+ Status: "info",
+ Title: "SSH login for user vetle",
+ Details: "User vetle logged in from IP 192.168.10.110",
+ },
+ {
+ Timestamp: 1586558848488,
+ Status: "ok",
+ },
+ {
+ Timestamp: 1586558949488,
+ Status: "error",
+ Title: "Backup failed",
+ Details: "Backup couldn't complete because the disk is full",
+ },
+}
+
+func TestAddEvent(t *testing.T) {
+ for _, event := range testEvents {
+ if err := Add(serviceToken, event); err != nil {
+ fmt.Println(err)
+ t.Fatal("error returned when trying to add event")
+ }
+ }
+
+ // Assumes that bbolt starts sequences on 1
+ for i, event := range testEvents {
+ event.ID = uint64(i) + 1
+ event.Service = 1
+ }
+}
+
+func TestGetAll(t *testing.T) {
+ events := GetAll()
+ for i, event := range events {
+ if !event.equals(testEvents[i]) {
+ t.Fatal("stored event does not match original")
+ }
+ }
}
func TestMain(m *testing.M) {
diff --git a/services/services_test.go b/services/services_test.go
@@ -17,20 +17,19 @@ func intID(id []byte) uint64 {
return idInt
}
-func (s1 *Service) equals (s2 *Service) bool {
- if s1.ID != s2.ID {
+func (s1 *Service) equals(s2 *Service) bool {
+ switch {
+ case s1.ID != s2.ID:
return false
- }
- if s1.Name != s2.Name {
+ case s1.Name != s2.Name:
return false
- }
- if s1.Description != s2.Description {
+ case s1.Description != s2.Description:
return false
- }
- if s1.ExpectationPeriod != s2.ExpectationPeriod {
+ case s1.ExpectationPeriod != s2.ExpectationPeriod:
return false
+ default:
+ return true
}
- return true
}
var (
@@ -40,13 +39,13 @@ var (
)
var testServices = []*Service{
- &Service{
+ {
Name: "tester @ dev-computer",
Description: "This describes the service in more detail",
ExpectationPeriod: 282342,
},
- &Service{Name: "tester2", ExpectationPeriod: 300003},
- &Service{Name: "third @ tester"},
+ {Name: "tester2", ExpectationPeriod: 300003},
+ {Name: "third @ tester"},
}
func TestAddService(t *testing.T) {
@@ -69,16 +68,15 @@ func TestAddService(t *testing.T) {
// Simulate ID generation for testServices after adding them to DB, to avoid
// possible interferrence (shouldn't be a problem, but doesn't hurt to be sure).
- // bbolt should always start ID sequences on 1, so this assumes that the service ID
+ // bbolt should always start ID sequences on 1, so this assumes that the service ID
// equals the testService index + 1
for i, service := range testServices {
service.ID = uint64(i) + 1
}
}
-
func TestDeleteService(t *testing.T) {
- var di uint64 = 1 // Deletion index
+ var di uint64 = 1 // Deletion index
err := Delete(di + 1)
if err != nil {
fmt.Println(err)
@@ -88,6 +86,11 @@ func TestDeleteService(t *testing.T) {
t.Fatal("no error returned when trying to delete non-existing service")
}
+ // Assert that the service token is deleted too
+ if service := GetByToken(token2); service != nil {
+ t.Fatal("the service token was not deleted")
+ }
+
// Delete from testServices too
testServices = append(testServices[:di], testServices[di+1:]...)
}
@@ -122,6 +125,9 @@ func TestGetAll(t *testing.T) {
t.Fatal("stored service doesn't match original")
}
}
+ if services[0].equals(testServices[1]) {
+ t.Fatal("unexpected match between two services")
+ }
}
func TestMain(m *testing.M) {