resources: Add resource sorting and clean tests
Resource sorting is needed for comparing resource groups.
This commit is contained in:
@@ -115,11 +115,13 @@ type ResData struct {
|
||||
// The Base interface is everything that is common to all resources.
|
||||
// Everything here only needs to be implemented once, in the BaseRes.
|
||||
type Base interface {
|
||||
fmt.Stringer // String() string
|
||||
|
||||
GetName() string // can't be named "Name()" because of struct field
|
||||
SetName(string)
|
||||
SetKind(string)
|
||||
GetKind() string
|
||||
String() string
|
||||
|
||||
Meta() *MetaParams
|
||||
Events() chan *event.Event
|
||||
Data() *ResData
|
||||
|
||||
@@ -18,9 +18,6 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/gob"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -67,83 +64,6 @@ func TestCompare2(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMiscEncodeDecode1(t *testing.T) {
|
||||
var err error
|
||||
//gob.Register( &NoopRes{} ) // happens in noop.go : init()
|
||||
//gob.Register( &FileRes{} ) // happens in file.go : init()
|
||||
// ...
|
||||
|
||||
// encode
|
||||
var input interface{} = &FileRes{}
|
||||
b1 := bytes.Buffer{}
|
||||
e := gob.NewEncoder(&b1)
|
||||
err = e.Encode(&input) // pass with &
|
||||
if err != nil {
|
||||
t.Errorf("Gob failed to Encode: %v", err)
|
||||
}
|
||||
str := base64.StdEncoding.EncodeToString(b1.Bytes())
|
||||
|
||||
// decode
|
||||
var output interface{}
|
||||
bb, err := base64.StdEncoding.DecodeString(str)
|
||||
if err != nil {
|
||||
t.Errorf("Base64 failed to Decode: %v", err)
|
||||
}
|
||||
b2 := bytes.NewBuffer(bb)
|
||||
d := gob.NewDecoder(b2)
|
||||
err = d.Decode(&output) // pass with &
|
||||
if err != nil {
|
||||
t.Errorf("Gob failed to Decode: %v", err)
|
||||
}
|
||||
|
||||
res1, ok := input.(Res)
|
||||
if !ok {
|
||||
t.Errorf("Input %v is not a Res", res1)
|
||||
return
|
||||
}
|
||||
res2, ok := output.(Res)
|
||||
if !ok {
|
||||
t.Errorf("Output %v is not a Res", res2)
|
||||
return
|
||||
}
|
||||
if !res1.Compare(res2) {
|
||||
t.Error("The input and output Res values do not match!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMiscEncodeDecode2(t *testing.T) {
|
||||
var err error
|
||||
|
||||
// encode
|
||||
input, _ := NewResource("file")
|
||||
|
||||
b64, err := ResToB64(input)
|
||||
if err != nil {
|
||||
t.Errorf("Can't encode: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
output, err := B64ToRes(b64)
|
||||
if err != nil {
|
||||
t.Errorf("Can't decode: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
res1, ok := input.(Res)
|
||||
if !ok {
|
||||
t.Errorf("Input %v is not a Res", res1)
|
||||
return
|
||||
}
|
||||
res2, ok := output.(Res)
|
||||
if !ok {
|
||||
t.Errorf("Output %v is not a Res", res2)
|
||||
return
|
||||
}
|
||||
if !res1.Compare(res2) {
|
||||
t.Error("The input and output Res values do not match!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIFF(t *testing.T) {
|
||||
uid := &BaseUID{Name: "/tmp/unit-test"}
|
||||
same := &BaseUID{Name: "/tmp/unit-test"}
|
||||
|
||||
@@ -22,10 +22,30 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
errwrap "github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ResourceSlice is a linear list of resources. It can be sorted.
|
||||
type ResourceSlice []Res
|
||||
|
||||
func (rs ResourceSlice) Len() int { return len(rs) }
|
||||
func (rs ResourceSlice) Swap(i, j int) { rs[i], rs[j] = rs[j], rs[i] }
|
||||
func (rs ResourceSlice) Less(i, j int) bool { return rs[i].String() < rs[j].String() }
|
||||
|
||||
// Sort the list of resources and return a copy without modifying the input.
|
||||
func Sort(rs []Res) []Res {
|
||||
resources := []Res{}
|
||||
for _, r := range rs { // copy
|
||||
resources = append(resources, r)
|
||||
}
|
||||
sort.Sort(ResourceSlice(resources))
|
||||
return resources
|
||||
// sort.Sort(ResourceSlice(rs)) // this is wrong, it would modify input!
|
||||
//return rs
|
||||
}
|
||||
|
||||
// ResToB64 encodes a resource to a base64 encoded string (after serialization).
|
||||
func ResToB64(res Res) (string, error) {
|
||||
b := bytes.Buffer{}
|
||||
|
||||
154
resources/util_test.go
Normal file
154
resources/util_test.go
Normal file
@@ -0,0 +1,154 @@
|
||||
// Mgmt
|
||||
// Copyright (C) 2013-2017+ James Shubin and the project contributors
|
||||
// Written by James Shubin <james@shubin.ca> and the project contributors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package resources
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/gob"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSort0(t *testing.T) {
|
||||
rs := []Res{}
|
||||
s := Sort(rs)
|
||||
|
||||
if !reflect.DeepEqual(s, []Res{}) {
|
||||
t.Errorf("sort failed!")
|
||||
if s == nil {
|
||||
t.Logf("output is nil!")
|
||||
} else {
|
||||
str := "Got:"
|
||||
for _, r := range s {
|
||||
str += " " + r.String()
|
||||
}
|
||||
t.Errorf(str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSort1(t *testing.T) {
|
||||
r1, _ := NewResource("noop")
|
||||
r1.SetName("noop1")
|
||||
r2, _ := NewResource("noop")
|
||||
r2.SetName("noop2")
|
||||
r3, _ := NewResource("noop")
|
||||
r3.SetName("noop3")
|
||||
r4, _ := NewResource("noop")
|
||||
r4.SetName("noop4")
|
||||
r5, _ := NewResource("noop")
|
||||
r5.SetName("noop5")
|
||||
r6, _ := NewResource("noop")
|
||||
r6.SetName("noop6")
|
||||
|
||||
rs := []Res{r3, r2, r6, r1, r5, r4}
|
||||
s := Sort(rs)
|
||||
|
||||
if !reflect.DeepEqual(s, []Res{r1, r2, r3, r4, r5, r6}) {
|
||||
t.Errorf("sort failed!")
|
||||
str := "Got:"
|
||||
for _, r := range s {
|
||||
str += " " + r.String()
|
||||
}
|
||||
t.Errorf(str)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(rs, []Res{r3, r2, r6, r1, r5, r4}) {
|
||||
t.Errorf("sort modified input!")
|
||||
str := "Got:"
|
||||
for _, r := range rs {
|
||||
str += " " + r.String()
|
||||
}
|
||||
t.Errorf(str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMiscEncodeDecode1(t *testing.T) {
|
||||
var err error
|
||||
|
||||
// encode
|
||||
var input interface{} = &FileRes{}
|
||||
b1 := bytes.Buffer{}
|
||||
e := gob.NewEncoder(&b1)
|
||||
err = e.Encode(&input) // pass with &
|
||||
if err != nil {
|
||||
t.Errorf("Gob failed to Encode: %v", err)
|
||||
}
|
||||
str := base64.StdEncoding.EncodeToString(b1.Bytes())
|
||||
|
||||
// decode
|
||||
var output interface{}
|
||||
bb, err := base64.StdEncoding.DecodeString(str)
|
||||
if err != nil {
|
||||
t.Errorf("Base64 failed to Decode: %v", err)
|
||||
}
|
||||
b2 := bytes.NewBuffer(bb)
|
||||
d := gob.NewDecoder(b2)
|
||||
err = d.Decode(&output) // pass with &
|
||||
if err != nil {
|
||||
t.Errorf("Gob failed to Decode: %v", err)
|
||||
}
|
||||
|
||||
res1, ok := input.(Res)
|
||||
if !ok {
|
||||
t.Errorf("Input %v is not a Res", res1)
|
||||
return
|
||||
}
|
||||
res2, ok := output.(Res)
|
||||
if !ok {
|
||||
t.Errorf("Output %v is not a Res", res2)
|
||||
return
|
||||
}
|
||||
if !res1.Compare(res2) {
|
||||
t.Error("The input and output Res values do not match!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMiscEncodeDecode2(t *testing.T) {
|
||||
var err error
|
||||
|
||||
// encode
|
||||
input, _ := NewResource("file")
|
||||
|
||||
b64, err := ResToB64(input)
|
||||
if err != nil {
|
||||
t.Errorf("Can't encode: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
output, err := B64ToRes(b64)
|
||||
if err != nil {
|
||||
t.Errorf("Can't decode: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
res1, ok := input.(Res)
|
||||
if !ok {
|
||||
t.Errorf("Input %v is not a Res", res1)
|
||||
return
|
||||
}
|
||||
res2, ok := output.(Res)
|
||||
if !ok {
|
||||
t.Errorf("Output %v is not a Res", res2)
|
||||
return
|
||||
}
|
||||
if !res1.Compare(res2) {
|
||||
t.Error("The input and output Res values do not match!")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user