ctop/connector/mock.go

156 lines
2.9 KiB
Go
Raw Normal View History

//go:build !release
// +build !release
package connector
import (
"math/rand"
"strings"
"time"
2017-06-12 16:12:03 +02:00
"github.com/bcicen/ctop/connector/collector"
2017-11-22 15:27:38 +01:00
"github.com/bcicen/ctop/connector/manager"
"github.com/bcicen/ctop/container"
"github.com/jgautheron/codename-generator"
"github.com/nu7hatch/gouuid"
)
2018-01-29 13:47:10 +01:00
func init() { enabled["mock"] = NewMock }
2017-06-08 17:01:08 +02:00
type Mock struct {
containers container.Containers
}
func NewMock() (Connector, error) {
2017-06-08 17:01:08 +02:00
cs := &Mock{}
2017-03-06 03:00:30 +01:00
go cs.Init()
go cs.Loop()
return cs, nil
}
// Create Mock containers
2017-06-08 17:01:08 +02:00
func (cs *Mock) Init() {
rand.Seed(int64(time.Now().Nanosecond()))
for i := 0; i < 4; i++ {
2020-10-26 13:02:31 +01:00
cs.makeContainer(3, true)
}
for i := 0; i < 16; i++ {
2020-10-26 13:02:31 +01:00
cs.makeContainer(1, false)
}
}
func (cs *Mock) Wait() struct{} {
ch := make(chan struct{})
go func() {
time.Sleep(30 * time.Second)
close(ch)
}()
return <-ch
}
2020-10-26 13:02:31 +01:00
var healthStates = []string{"starting", "healthy", "unhealthy"}
func (cs *Mock) makeContainer(aggression int64, health bool) {
2017-06-12 16:12:03 +02:00
collector := collector.NewMock(aggression)
2017-11-20 12:09:36 +01:00
manager := manager.NewMock()
c := container.New(makeID(), collector, manager)
c.SetMeta("name", makeName())
c.SetState(makeState())
2020-10-26 13:02:31 +01:00
if health {
var i int
c.SetMeta("health", healthStates[i])
go func() {
for {
i++
if i >= len(healthStates) {
i = 0
}
c.SetMeta("health", healthStates[i])
time.Sleep(12 * time.Second)
}
}()
}
cs.containers = append(cs.containers, c)
}
2017-06-08 17:01:08 +02:00
func (cs *Mock) Loop() {
iter := 0
for {
2017-03-03 08:57:26 +01:00
// Change state for random container
2017-03-06 03:00:30 +01:00
if iter%5 == 0 && len(cs.containers) > 0 {
2017-03-03 08:57:26 +01:00
randC := cs.containers[rand.Intn(len(cs.containers))]
randC.SetState(makeState())
}
iter++
time.Sleep(3 * time.Second)
}
}
// Get a single container, by ID
2017-06-08 17:01:08 +02:00
func (cs *Mock) Get(id string) (*container.Container, bool) {
for _, c := range cs.containers {
2017-03-03 08:57:26 +01:00
if c.Id == id {
return c, true
}
}
return nil, false
}
// All returns array of all containers, sorted by field
2017-06-08 17:01:08 +02:00
func (cs *Mock) All() container.Containers {
2017-06-12 15:40:52 +02:00
cs.containers.Sort()
2017-03-08 01:26:22 +01:00
cs.containers.Filter()
2017-03-06 03:00:30 +01:00
return cs.containers
}
// Remove containers by ID
2017-06-08 17:01:08 +02:00
func (cs *Mock) delByID(id string) {
for n, c := range cs.containers {
2017-03-03 08:57:26 +01:00
if c.Id == id {
cs.del(n)
return
}
}
}
// Remove one or more containers by index
2017-06-08 17:01:08 +02:00
func (cs *Mock) del(idx ...int) {
for _, i := range idx {
cs.containers = append(cs.containers[:i], cs.containers[i+1:]...)
}
log.Infof("removed %d dead containers", len(idx))
}
func makeID() string {
u, err := uuid.NewV4()
if err != nil {
panic(err)
}
2017-03-03 08:57:26 +01:00
return strings.Replace(u.String(), "-", "", -1)[:12]
}
func makeName() string {
n, err := codename.Get(codename.Sanitized)
nsp := strings.Split(n, "-")
if len(nsp) > 2 {
n = strings.Join(nsp[:2], "-")
}
if err != nil {
panic(err)
}
return strings.Replace(n, "-", "_", -1)
}
func makeState() string {
switch rand.Intn(10) {
case 0, 1, 2:
return "exited"
case 3:
return "paused"
}
return "running"
}