Improve device allocation (#333)

* Improve device allocation

* Improve

* Tweak MAC code

* Add `golangci-lint` to tools

* Debugging

* Revert "Debugging"

This reverts commit 90c0b054256e9a741193854dc6b5984f6e749a9a.

* Use `golang-set`

* Remove `sync.Mutex`

* Cleanup
This commit is contained in:
Joshua Spence
2023-03-03 14:05:09 +11:00
committed by GitHub
parent cecd408e57
commit 284c42aaae
4 changed files with 58 additions and 52 deletions

3
go.mod
View File

@@ -8,6 +8,7 @@ go 1.19
require (
github.com/apparentlymart/go-cidr v1.1.0
github.com/deckarep/golang-set/v2 v2.1.0
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/terraform-plugin-docs v0.13.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.25.0
@@ -58,7 +59,7 @@ require (
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/russross/blackfriday v1.6.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.5.0 // indirect

8
go.sum
View File

@@ -33,6 +33,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI=
github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@@ -174,7 +176,6 @@ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
github.com/paultyng/go-unifi v1.32.0 h1:k3zHkL57JEmzghRgvvRuDTSkw9CtD10zdxCB9OUweYI=
github.com/paultyng/go-unifi v1.32.0/go.mod h1:i8D+gyo5NinnDlQ5ZGdqSvRqRyHuV4zA2CLZnHb0axE=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -182,8 +183,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
@@ -317,7 +318,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -6,27 +6,24 @@ import (
"regexp"
"sync"
"testing"
"time"
mapset "github.com/deckarep/golang-set/v2"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/paultyng/go-unifi/unifi"
)
var (
deviceLock sync.Mutex
devicesAvailable []string
devicesInitialized bool = false
deviceInit sync.Once
devicePool mapset.Set[*unifi.Device] = mapset.NewSet[*unifi.Device]()
)
func allocateDevice(t *testing.T) (string, func()) {
deviceLock.Lock()
defer deviceLock.Unlock()
ctx := context.Background()
if !devicesInitialized {
devicesAvailable = []string{}
devicesInitialized = true
devices, err := testClient.ListDevice(context.Background(), "default")
deviceInit.Do(func() {
devices, err := testClient.ListDevice(ctx, "default")
if err != nil {
t.Fatalf("Error listing devices: %s", err)
}
@@ -41,25 +38,37 @@ func allocateDevice(t *testing.T) (string, func()) {
continue
}
devicesAvailable = append(devicesAvailable, device.MAC)
d := device
if ok := devicePool.Add(&d); !ok {
t.Fatal("Failed to add device to pool")
}
}
})
var device *unifi.Device
err := resource.RetryContext(ctx, 1*time.Minute, func() *resource.RetryError {
var ok bool
device, ok = devicePool.Pop()
if device == nil || !ok {
return resource.RetryableError(fmt.Errorf("Unable to allocate test device"))
}
return nil
})
if err != nil {
t.Fatal(err)
}
unallocate := func() {
if ok := devicePool.Add(device); !ok {
t.Fatal("Failed to add device to pool")
}
}
if len(devicesAvailable) == 0 {
t.Fatal("Unable to allocate test device")
}
var device string
device, devicesAvailable = devicesAvailable[0], devicesAvailable[1:]
unallocate := func() {
deviceLock.Lock()
defer deviceLock.Unlock()
devicesAvailable = append(devicesAvailable, device)
}
return device, unallocate
return device.MAC, unallocate
}
func preCheckDeviceExists(t *testing.T, site, mac string) {

View File

@@ -10,6 +10,7 @@ import (
"testing"
"github.com/apparentlymart/go-cidr/cidr"
mapset "github.com/deckarep/golang-set/v2"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/paultyng/go-unifi/unifi"
@@ -20,35 +21,30 @@ func userImportStep(name string) resource.TestStep {
}
var (
testMacLock sync.Mutex
testMacsAvailable []*net.HardwareAddr
macInit sync.Once
macPool mapset.Set[*net.HardwareAddr] = mapset.NewSet[*net.HardwareAddr]()
)
// for test MAC addresses, see https://tools.ietf.org/html/rfc7042#section-2.1.2
func init() {
testMacsAvailable = make([]*net.HardwareAddr, 256)
for i := 0; i < 256; i++ {
testMacsAvailable[i] = &net.HardwareAddr{0x00, 0x00, 0x5e, 0x00, 0x53, byte(i)}
}
}
func allocateTestMac(t *testing.T) (string, func()) {
testMacLock.Lock()
defer testMacLock.Unlock()
macInit.Do(func() {
// for test MAC addresses, see https://tools.ietf.org/html/rfc7042#section-2.1.
for i := 0; i < 256; i++ {
mac := net.HardwareAddr{0x00, 0x00, 0x5e, 0x00, 0x53, byte(i)}
if ok := macPool.Add(&mac); !ok {
t.Fatal("Failed to add MAC to pool")
}
}
})
if len(testMacsAvailable) == 0 {
mac, ok := macPool.Pop()
if mac == nil || !ok {
t.Fatal("Unable to allocate test MAC")
}
var mac *net.HardwareAddr
mac, testMacsAvailable = testMacsAvailable[0], testMacsAvailable[1:]
unallocate := func() {
testMacLock.Lock()
defer testMacLock.Unlock()
testMacsAvailable = append(testMacsAvailable, mac) //nolint:makezero
if ok := macPool.Add(mac); !ok {
t.Fatal("Failed to add MAC to pool")
}
}
return mac.String(), unallocate