Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

chore: add golden file tests for resources top #301

Merged
merged 3 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/cmd/envs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ func assertEnv(t *testing.T, name string, envs []coder.Environment) *coder.Envir

var seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))

//nolint:unparam
func randString(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyz"
b := make([]byte, length)
Expand Down
35 changes: 20 additions & 15 deletions internal/cmd/resourcemanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,29 +99,34 @@ func runResourceTop(options *resourceTopOptions) func(cmd *cobra.Command, args [
if err != nil {
return xerrors.Errorf("get workspace providers: %w", err)
}

var groups []groupable
var labeler envLabeler
data := entities{
providers: providers.Kubernetes,
users: users,
orgs: orgs,
envs: envs,
images: images,
}
switch options.group {
case "user":
groups, labeler = aggregateByUser(data, *options)
case "org":
groups, labeler = aggregateByOrg(data, *options)
case "provider":
groups, labeler = aggregateByProvider(data, *options)
default:
return xerrors.Errorf("unknown --group %q", options.group)
}
return presentEntites(cmd.OutOrStdout(), data, *options)
}
}

return printResourceTop(cmd.OutOrStdout(), groups, labeler, options.showEmptyGroups, options.sortBy)
func presentEntites(w io.Writer, data entities, options resourceTopOptions) error {
var (
groups []groupable
labeler envLabeler
)
switch options.group {
case "user":
groups, labeler = aggregateByUser(data, options)
case "org":
groups, labeler = aggregateByOrg(data, options)
case "provider":
groups, labeler = aggregateByProvider(data, options)
default:
return xerrors.Errorf("unknown --group %q", options.group)
}

return printResourceTop(w, groups, labeler, options.showEmptyGroups, options.sortBy)
}

type entities struct {
Expand Down Expand Up @@ -241,7 +246,7 @@ func (o orgGrouping) environments() []coder.Environment {

func (o orgGrouping) header() string {
plural := "s"
if len(o.org.Members) < 2 {
if len(o.org.Members) == 1 {
plural = ""
}
return fmt.Sprintf("%s\t(%v member%s)", truncate(o.org.Name, 20, "..."), len(o.org.Members), plural)
Expand Down
184 changes: 184 additions & 0 deletions internal/cmd/resourcemanager_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package cmd

import (
"bytes"
"flag"
"fmt"
"io/ioutil"
"testing"

"cdr.dev/slog/sloggers/slogtest/assert"

"cdr.dev/coder-cli/coder-sdk"
)

var write = flag.Bool("write", false, "write to the golden files")

func Test_resourceManager(t *testing.T) {
// TODO: cleanup
verbose = true

const goldenFile = "resourcemanager_test.golden"
var buff bytes.Buffer
data := mockResourceTopEntities()
tests := []struct {
header string
data entities
options resourceTopOptions
}{
{
header: "By User",
data: data,
options: resourceTopOptions{
group: "user",
sortBy: "cpu",
},
},
{
header: "By Org",
data: data,
options: resourceTopOptions{
group: "org",
sortBy: "cpu",
},
},
{
header: "By Provider",
data: data,
options: resourceTopOptions{
group: "provider",
sortBy: "cpu",
},
},
{
header: "Sort By Memory",
data: data,
options: resourceTopOptions{
group: "user",
sortBy: "memory",
},
},
}

for _, tcase := range tests {
buff.WriteString(fmt.Sprintf("=== TEST: %s\n", tcase.header))
err := presentEntites(&buff, tcase.data, tcase.options)
assert.Success(t, "present entities", err)
}

assertGolden(t, goldenFile, buff.Bytes())
}

func assertGolden(t *testing.T, path string, output []byte) {
if *write {
err := ioutil.WriteFile(path, output, 0777)
assert.Success(t, "write file", err)
return
}
goldenContent, err := ioutil.ReadFile(path)
assert.Success(t, "read golden file", err)
assert.Equal(t, "golden content matches", string(goldenContent), string(output))
}

func mockResourceTopEntities() entities {
orgIDs := [...]string{randString(10), randString(10), randString(10)}
imageIDs := [...]string{randString(10), randString(10), randString(10)}
providerIDs := [...]string{randString(10), randString(10), randString(10)}
userIDs := [...]string{randString(10), randString(10), randString(10)}
envIDs := [...]string{randString(10), randString(10), randString(10), randString(10)}

return entities{
providers: []coder.KubernetesProvider{
{
ID: providerIDs[0],
Name: "mars",
},
{
ID: providerIDs[1],
Name: "underground",
},
},
users: []coder.User{
{
ID: userIDs[0],
Name: "Random",
Email: "random@coder.com",
},
{
ID: userIDs[1],
Name: "Second Random",
Email: "second-random@coder.com",
},
},
orgs: []coder.Organization{
{
ID: orgIDs[0],
Name: "SpecialOrg",

//! these should probably be fixed, but for now they are just for the count
Members: []coder.OrganizationUser{{}, {}},
},
{
ID: orgIDs[1],
Name: "NotSoSpecialOrg",

//! these should probably be fixed, but for now they are just for the count
Members: []coder.OrganizationUser{{}, {}},
},
},
envs: []coder.Environment{
{
ID: envIDs[0],
ResourcePoolID: providerIDs[0],
ImageID: imageIDs[0],
OrganizationID: orgIDs[0],
UserID: userIDs[0],
Name: "dev-env",
ImageTag: "20.04",
CPUCores: 12.2,
MemoryGB: 64.4,
LatestStat: coder.EnvironmentStat{
ContainerStatus: coder.EnvironmentOn,
},
},
{
ID: envIDs[1],
ResourcePoolID: providerIDs[1],
ImageID: imageIDs[1],
OrganizationID: orgIDs[1],
UserID: userIDs[1],
Name: "another-env",
ImageTag: "10.2",
CPUCores: 4,
MemoryGB: 16,
LatestStat: coder.EnvironmentStat{
ContainerStatus: coder.EnvironmentOn,
},
},
{
ID: envIDs[2],
ResourcePoolID: providerIDs[1],
ImageID: imageIDs[1],
OrganizationID: orgIDs[1],
UserID: userIDs[1],
Name: "yet-another-env",
ImageTag: "10.2",
CPUCores: 100,
MemoryGB: 2,
LatestStat: coder.EnvironmentStat{
ContainerStatus: coder.EnvironmentOn,
},
},
},
images: map[string]*coder.Image{
imageIDs[0]: {
Repository: "ubuntu",
OrganizationID: orgIDs[0],
},
imageIDs[1]: {
Repository: "archlinux",
OrganizationID: orgIDs[0],
},
},
}
}
32 changes: 32 additions & 0 deletions internal/cmd/resourcemanager_test.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
=== TEST: By User
Second Random (second-random@coder.com) [cpu: 104.0] [mem: 18.0 GB]
yet-another-env [cpu: 100.0] [mem: 2.0 GB] [img: archlinux:10.2] [provider: underground] [org: NotSoSpecialOrg]
another-env [cpu: 4.0] [mem: 16.0 GB] [img: archlinux:10.2] [provider: underground] [org: NotSoSpecialOrg]

Random (random@coder.com) [cpu: 12.2] [mem: 64.4 GB]
dev-env [cpu: 12.2] [mem: 64.4 GB] [img: ubuntu:20.04] [provider: mars] [org: SpecialOrg]

=== TEST: By Org
NotSoSpecialOrg (2 members) [cpu: 104.0] [mem: 18.0 GB]
yet-another-env [cpu: 100.0] [mem: 2.0 GB] [img: archlinux:10.2] [user: second-random@coder.com] [provider: underground]
another-env [cpu: 4.0] [mem: 16.0 GB] [img: archlinux:10.2] [user: second-random@coder.com] [provider: underground]

SpecialOrg (2 members) [cpu: 12.2] [mem: 64.4 GB]
dev-env [cpu: 12.2] [mem: 64.4 GB] [img: ubuntu:20.04] [user: random@coder.com] [provider: mars]

=== TEST: By Provider
underground [cpu: 104.0] [mem: 18.0 GB]
yet-another-env [cpu: 100.0] [mem: 2.0 GB] [img: archlinux:10.2] [user: second-random@coder.com]
another-env [cpu: 4.0] [mem: 16.0 GB] [img: archlinux:10.2] [user: second-random@coder.com]

mars [cpu: 12.2] [mem: 64.4 GB]
dev-env [cpu: 12.2] [mem: 64.4 GB] [img: ubuntu:20.04] [user: random@coder.com]

=== TEST: Sort By Memory
Random (random@coder.com) [cpu: 12.2] [mem: 64.4 GB]
dev-env [cpu: 12.2] [mem: 64.4 GB] [img: ubuntu:20.04] [provider: mars] [org: SpecialOrg]

Second Random (second-random@coder.com) [cpu: 104.0] [mem: 18.0 GB]
another-env [cpu: 4.0] [mem: 16.0 GB] [img: archlinux:10.2] [provider: underground] [org: NotSoSpecialOrg]
yet-another-env [cpu: 100.0] [mem: 2.0 GB] [img: archlinux:10.2] [provider: underground] [org: NotSoSpecialOrg]