Skip to content

Commit

Permalink
Start adding methods and tests to support multiple devices
Browse files Browse the repository at this point in the history
  • Loading branch information
danesparza committed Aug 23, 2018
1 parent 57d4c9e commit 248b31e
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 29 deletions.
29 changes: 0 additions & 29 deletions api/device.go

This file was deleted.

118 changes: 118 additions & 0 deletions data/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"strings"
"time"

"github.com/rs/xid"

"github.com/boltdb/bolt"
"github.com/spf13/viper"
)
Expand All @@ -28,6 +30,35 @@ type ConfigItem struct {
LastUpdated time.Time `sql:"updated" json:"updated"`
}

// Device represents a device in the system.
type Device struct {
// ID is the unique device identifier
ID string `json:"id"`

// Type is the type of device (amon / hs110 / etc)
Type string `json:"type"`

// Name is the name given to the device by the customer
Name string `json:"name"`

// MinimumMonitorTime is the amount of time required to monitor the device before
// it latches to the 'on' or 'off' state
MinimumMonitorTime time.Duration `json:"minimum_monitor_time"`

// Threshold is the value that must be crossed (after the MinimumMonitorTime time)
// before the device latches to the 'on' or 'off' state
Threshold int `json:"monitor_threshold"`

// IPAddress is the network address for the device
IPAddress string `json:"ipaddress"`

// Running indicates whether the device is currently running (operating) or not
Running bool `json:"running"`

// LastUpdated indicates when this device was last updated in the system
LastUpdated time.Time `sql:"updated" json:"updated"`
}

// InitStore initializes the database
func (store ConfigDB) InitStore() error {
// Open the database:
Expand All @@ -37,6 +68,93 @@ func (store ConfigDB) InitStore() error {
return err
}

// GetAllDevices gets all devices in the system
func (store ConfigDB) GetAllDevices() ([]Device, error) {
// Our return item
retval := []Device{}

// Open the database:
db, err := bolt.Open(store.Database, 0600, nil)
defer db.Close()
if err != nil {
return retval, err
}

// Get all the items:
err = db.View(func(tx *bolt.Tx) error {

b := tx.Bucket([]byte("devices"))
if b == nil {
return nil
}

c := b.Cursor()

for k, v := c.First(); k != nil; k, v = c.Next() {
// Unmarshal data into our config item
device := Device{}
if err := json.Unmarshal(v, &device); err != nil {
return err
}

retval = append(retval, device)
}

return nil
})

// Return our slice:
return retval, err
}

// AddOrUpdateDevice adds a device to the system
func (store ConfigDB) AddOrUpdateDevice(device Device) (Device, error) {

// Our return item:
retval := device

// If there is no config name, throw an error:
if strings.TrimSpace(retval.Name) == "" {
return retval, errors.New("Device name can't be blank")
}

// Open the database:
db, err := bolt.Open(store.Database, 0600, nil)
defer db.Close()
if err != nil {
return retval, err
}

// Update the database:
err = db.Update(func(tx *bolt.Tx) error {
b, err := tx.CreateBucketIfNotExists([]byte("devices"))
if err != nil {
return err
}

// If we don't have an id, generate an id for the configitem.
// This returns an error only if the Tx is closed or not writeable.
// That can't happen in an Update() call so I ignore the error check.
if retval.ID == "" {
retval.ID = xid.New().String()
}

// Set the current datetime:
retval.LastUpdated = time.Now()

// Serialize to JSON format
encoded, err := json.Marshal(retval)
if err != nil {
return err
}

// Store it, with the 'id' as the key:
return b.Put([]byte(retval.ID), encoded)
})

return retval, err
}

// Set inserts or updates the config item
func (store ConfigDB) Set(configItem ConfigItem) (ConfigItem, error) {

Expand Down
23 changes: 23 additions & 0 deletions data/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,3 +464,26 @@ func TestConfig_Remove_ItemDoesntExist_NoErrors(t *testing.T) {
t.Errorf("Set then remove failed: Should have removed a config item without error: %s", err)
}
}

func TestConfig_GetAllDevices_NoItems_Successful(t *testing.T) {
// Arrange
filename := "testing.db"
defer os.Remove(filename)

db := data.ConfigDB{
Database: filename}

// NO ITEMS STORED

// Act
response, err := db.GetAllDevices()

// Assert
if err != nil {
t.Errorf("GetAllDevices failed: Should have returned config items without error: %s", err)
}

if len(response) != 0 {
t.Errorf("GetAllDevices failed: Should have returned no devices but returned %v instead", len(response))
}
}

0 comments on commit 248b31e

Please sign in to comment.