parent
7c5ba99cc1
commit
66c22f1c6f
2
Makefile
2
Makefile
|
|
@ -5,7 +5,7 @@ PACKAGE := github.com/derailed/$(NAME)
|
|||
GIT_REV ?= $(shell git rev-parse --short HEAD)
|
||||
SOURCE_DATE_EPOCH ?= $(shell date +%s)
|
||||
DATE ?= $(shell date -u -d @${SOURCE_DATE_EPOCH} +"%Y-%m-%dT%H:%M:%SZ")
|
||||
VERSION ?= v0.25.20
|
||||
VERSION ?= v0.25.21
|
||||
IMG_NAME := derailed/k9s
|
||||
IMAGE := ${IMG_NAME}:${VERSION}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s.png" align="center" width="800" height="auto"/>
|
||||
|
||||
# Release v0.25.21
|
||||
|
||||
## Notes
|
||||
|
||||
Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better are as ever very much noted and appreciated! Also big thanks to all that have allocated their own time to help others on both slack and this repo!!
|
||||
|
||||
If you feel K9s is helping your Kubernetes journey, please consider joining our [sponsorship program](https://github.com/sponsors/derailed) and/or make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)
|
||||
|
||||
On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM)
|
||||
|
||||
---
|
||||
|
||||
## Maintenance Release
|
||||
|
||||
---
|
||||
|
||||
## Resolved Issues
|
||||
|
||||
* [Issue #1634](https://github.com/derailed/k9s/issues/1634) Namespace view all has the age field in strange format
|
||||
* [Issue #1633](https://github.com/derailed/k9s/issues/1633) Nodes sort by age has wrong order
|
||||
|
||||
## Resolved PR
|
||||
|
||||
* [PR #1632](https://github.com/derailed/k9s/pull/1632) Fix delete dialog dropdown styling
|
||||
* [PR #1629](https://github.com/derailed/k9s/pull/1629) Fix reference to base image in dockerfile
|
||||
* [PR #1627](https://github.com/derailed/k9s/pull/1627) Fix TestToAge
|
||||
* [PR #1624](https://github.com/derailed/k9s/pull/1624) Change makefile version
|
||||
|
||||
---
|
||||
|
||||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2021 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
4
go.mod
4
go.mod
|
|
@ -59,7 +59,7 @@ require (
|
|||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
|
||||
github.com/containerd/containerd v1.6.3 // indirect
|
||||
github.com/containerd/containerd v1.6.6 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/cli v20.10.11+incompatible // indirect
|
||||
|
|
@ -147,7 +147,7 @@ require (
|
|||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
|
|
|||
9
go.sum
9
go.sum
|
|
@ -83,7 +83,7 @@ github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFP
|
|||
github.com/Masterminds/squirrel v1.5.2 h1:UiOEi2ZX4RCSkpiNDQN5kro/XIBpSRk9iTqdIRPzUXE=
|
||||
github.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
|
||||
github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY=
|
||||
github.com/Microsoft/hcsshim v0.9.3 h1:k371PzBuRrz2b+ebGuI2nVgVhgsVX60jMfSw80NECxo=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
|
|
@ -156,8 +156,8 @@ github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h
|
|||
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
||||
github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4=
|
||||
github.com/containerd/containerd v1.6.3 h1:JfgUEIAH07xDWk6kqz0P3ArZt+KJ9YeihSC9uyFtSKg=
|
||||
github.com/containerd/containerd v1.6.3/go.mod h1:gCVGrYRYFm2E8GmuUIbj/NGD7DLZQLzSJQazjVKDOig=
|
||||
github.com/containerd/containerd v1.6.6 h1:xJNPhbrmz8xAMDNoVjHy9YHtWwEQNS+CDkcIRh7t8Y0=
|
||||
github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
|
|
@ -999,8 +999,9 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
|
|
|
|||
|
|
@ -23,15 +23,16 @@ var (
|
|||
// Helm represents a helm chart.
|
||||
type Helm struct {
|
||||
NonResource
|
||||
cfg *action.Configuration
|
||||
ns string
|
||||
}
|
||||
|
||||
// List returns a collection of resources.
|
||||
func (c *Helm) List(ctx context.Context, ns string) ([]runtime.Object, error) {
|
||||
cfg, err := c.EnsureHelmConfig(ns)
|
||||
func (h *Helm) List(ctx context.Context, ns string) ([]runtime.Object, error) {
|
||||
cfg, err := h.EnsureHelmConfig(ns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rr, err := action.NewList(cfg).Run()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -46,9 +47,9 @@ func (c *Helm) List(ctx context.Context, ns string) ([]runtime.Object, error) {
|
|||
}
|
||||
|
||||
// Get returns a resource.
|
||||
func (c *Helm) Get(_ context.Context, path string) (runtime.Object, error) {
|
||||
func (h *Helm) Get(_ context.Context, path string) (runtime.Object, error) {
|
||||
ns, n := client.Namespaced(path)
|
||||
cfg, err := c.EnsureHelmConfig(ns)
|
||||
cfg, err := h.EnsureHelmConfig(ns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -61,9 +62,9 @@ func (c *Helm) Get(_ context.Context, path string) (runtime.Object, error) {
|
|||
}
|
||||
|
||||
// GetValues returns values for a release
|
||||
func (c *Helm) GetValues(path string, allValues bool) ([]byte, error) {
|
||||
func (h *Helm) GetValues(path string, allValues bool) ([]byte, error) {
|
||||
ns, n := client.Namespaced(path)
|
||||
cfg, err := c.EnsureHelmConfig(ns)
|
||||
cfg, err := h.EnsureHelmConfig(ns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -78,9 +79,9 @@ func (c *Helm) GetValues(path string, allValues bool) ([]byte, error) {
|
|||
}
|
||||
|
||||
// Describe returns the chart notes.
|
||||
func (c *Helm) Describe(path string) (string, error) {
|
||||
func (h *Helm) Describe(path string) (string, error) {
|
||||
ns, n := client.Namespaced(path)
|
||||
cfg, err := c.EnsureHelmConfig(ns)
|
||||
cfg, err := h.EnsureHelmConfig(ns)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -93,9 +94,9 @@ func (c *Helm) Describe(path string) (string, error) {
|
|||
}
|
||||
|
||||
// ToYAML returns the chart manifest.
|
||||
func (c *Helm) ToYAML(path string, showManaged bool) (string, error) {
|
||||
func (h *Helm) ToYAML(path string, showManaged bool) (string, error) {
|
||||
ns, n := client.Namespaced(path)
|
||||
cfg, err := c.EnsureHelmConfig(ns)
|
||||
cfg, err := h.EnsureHelmConfig(ns)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -108,9 +109,9 @@ func (c *Helm) ToYAML(path string, showManaged bool) (string, error) {
|
|||
}
|
||||
|
||||
// Delete uninstall a Helm.
|
||||
func (c *Helm) Delete(path string, _ *metav1.DeletionPropagation, force bool) error {
|
||||
func (h *Helm) Delete(path string, _ *metav1.DeletionPropagation, force bool) error {
|
||||
ns, n := client.Namespaced(path)
|
||||
cfg, err := c.EnsureHelmConfig(ns)
|
||||
cfg, err := h.EnsureHelmConfig(ns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -128,12 +129,15 @@ func (c *Helm) Delete(path string, _ *metav1.DeletionPropagation, force bool) er
|
|||
}
|
||||
|
||||
// EnsureHelmConfig return a new configuration.
|
||||
func (c *Helm) EnsureHelmConfig(ns string) (*action.Configuration, error) {
|
||||
cfg := new(action.Configuration)
|
||||
if err := cfg.Init(c.Client().Config().Flags(), ns, os.Getenv("HELM_DRIVER"), helmLogger); err != nil {
|
||||
func (h *Helm) EnsureHelmConfig(ns string) (*action.Configuration, error) {
|
||||
if h.cfg != nil && h.ns == ns {
|
||||
return h.cfg, nil
|
||||
}
|
||||
h.cfg = new(action.Configuration)
|
||||
if err := h.cfg.Init(h.Client().Config().Flags(), ns, os.Getenv("HELM_DRIVER"), helmLogger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cfg, nil
|
||||
return h.cfg, nil
|
||||
}
|
||||
|
||||
func helmLogger(s string, args ...interface{}) {
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ func (h Header) IsMetricsCol(col int) bool {
|
|||
if col < 0 || col >= len(h) {
|
||||
return false
|
||||
}
|
||||
|
||||
return h[col].MX
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,10 +96,6 @@ func TestToAge(t *testing.T) {
|
|||
t: time.Time{},
|
||||
e: UnknownValue,
|
||||
},
|
||||
"good": {
|
||||
t: testTime().Add(-10 * time.Second),
|
||||
e: "3y197d",
|
||||
},
|
||||
}
|
||||
|
||||
for k := range uu {
|
||||
|
|
|
|||
|
|
@ -177,14 +177,18 @@ func (s RowSorter) Swap(i, j int) {
|
|||
func (s RowSorter) Less(i, j int) bool {
|
||||
v1, v2 := s.Rows[i].Fields[s.Index], s.Rows[j].Fields[s.Index]
|
||||
id1, id2 := s.Rows[i].ID, s.Rows[j].ID
|
||||
return Less(s.Asc, s.IsNumber, s.IsDuration, id1, id2, v1, v2)
|
||||
less := Less(s.IsNumber, s.IsDuration, id1, id2, v1, v2)
|
||||
if s.Asc {
|
||||
return less
|
||||
}
|
||||
return !less
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Helpers...
|
||||
|
||||
// Less return true if c1 < c2.
|
||||
func Less(asc, isNumber, isDuration bool, id1, id2, v1, v2 string) bool {
|
||||
func Less(isNumber, isDuration bool, id1, id2, v1, v2 string) bool {
|
||||
var less bool
|
||||
switch {
|
||||
case isNumber:
|
||||
|
|
@ -196,12 +200,9 @@ func Less(asc, isNumber, isDuration bool, id1, id2, v1, v2 string) bool {
|
|||
default:
|
||||
less = sortorder.NaturalLess(v1, v2)
|
||||
}
|
||||
|
||||
if v1 == v2 {
|
||||
return sortorder.NaturalLess(id1, id2)
|
||||
}
|
||||
if asc {
|
||||
return less
|
||||
}
|
||||
return !less
|
||||
|
||||
return less
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,7 +239,12 @@ func (r RowEventSorter) Swap(i, j int) {
|
|||
func (r RowEventSorter) Less(i, j int) bool {
|
||||
f1, f2 := r.Events[i].Row.Fields, r.Events[j].Row.Fields
|
||||
id1, id2 := r.Events[i].Row.ID, r.Events[j].Row.ID
|
||||
return Less(r.Asc, r.IsNumber, r.IsDuration, id1, id2, f1[r.Index], f2[r.Index])
|
||||
less := Less(r.IsNumber, r.IsDuration, id1, id2, f1[r.Index], f2[r.Index])
|
||||
if r.Asc {
|
||||
return less
|
||||
}
|
||||
|
||||
return !less
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -317,6 +317,18 @@ func TestRowsSortDuration(t *testing.T) {
|
|||
asc bool
|
||||
e render.Rows
|
||||
}{
|
||||
"years": {
|
||||
rows: render.Rows{
|
||||
{Fields: []string{testTime().Add(-365 * 24 * time.Hour).String(), "blee"}},
|
||||
{Fields: []string{testTime().String(), "duh"}},
|
||||
},
|
||||
col: 0,
|
||||
asc: true,
|
||||
e: render.Rows{
|
||||
{Fields: []string{testTime().String(), "duh"}},
|
||||
{Fields: []string{testTime().Add(-365 * 24 * time.Hour).String(), "blee"}},
|
||||
},
|
||||
},
|
||||
"durationAsc": {
|
||||
rows: render.Rows{
|
||||
{Fields: []string{testTime().Add(10 * time.Second).String(), "duh"}},
|
||||
|
|
@ -392,3 +404,36 @@ func TestRowsSortMetrics(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLess(t *testing.T) {
|
||||
uu := map[string]struct {
|
||||
isNumber, isDuration bool
|
||||
id1, id2 string
|
||||
v1, v2 string
|
||||
e bool
|
||||
}{
|
||||
"years": {
|
||||
isNumber: false,
|
||||
isDuration: true,
|
||||
id1: "id1",
|
||||
id2: "id2",
|
||||
v1: "2y263d",
|
||||
v2: "1y179d",
|
||||
},
|
||||
"hours": {
|
||||
isNumber: false,
|
||||
isDuration: true,
|
||||
id1: "id1",
|
||||
id2: "id2",
|
||||
v1: "2y263d",
|
||||
v2: "19h",
|
||||
},
|
||||
}
|
||||
|
||||
for k := range uu {
|
||||
u := uu[k]
|
||||
t.Run(k, func(t *testing.T) {
|
||||
assert.Equal(t, u.e, render.Less(u.isNumber, u.isDuration, u.id1, u.id2, u.v1, u.v2))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ func (t *Table) doUpdate(data render.TableData) {
|
|||
custData.Namespace,
|
||||
colIndex,
|
||||
custData.Header.IsTimeCol(colIndex),
|
||||
data.Header.IsMetricsCol(colIndex),
|
||||
custData.Header.IsMetricsCol(colIndex),
|
||||
t.sortCol.asc,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ func clearScreen() {
|
|||
const (
|
||||
k9sShell = "k9s-shell"
|
||||
k9sShellRetryCount = 10
|
||||
k9sShellRetryDelay = 1 * time.Second
|
||||
k9sShellRetryDelay = 10 * time.Second
|
||||
)
|
||||
|
||||
func ssh(a *App, node string) error {
|
||||
|
|
|
|||
|
|
@ -108,10 +108,8 @@ func TestLogViewSave(t *testing.T) {
|
|||
|
||||
dir := filepath.Join(app.Config.K9s.GetScreenDumpDir(), app.Config.K9s.CurrentCluster)
|
||||
c1, _ := os.ReadDir(dir)
|
||||
fmt.Println("C1", c1)
|
||||
v.SaveCmd(nil)
|
||||
c2, _ := os.ReadDir(dir)
|
||||
fmt.Println("C2", c2)
|
||||
assert.Equal(t, len(c2), len(c1)+1)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
package view
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/derailed/k9s/internal/client"
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/render"
|
||||
|
|
@ -85,7 +83,7 @@ func (n *Namespace) decorate(data render.TableData) render.TableData {
|
|||
Kind: render.EventUnchanged,
|
||||
Row: render.Row{
|
||||
ID: client.NamespaceAll,
|
||||
Fields: render.Fields{client.NamespaceAll, "Active", "", "", time.Now().String()},
|
||||
Fields: render.Fields{client.NamespaceAll, "Active", "", "", ""},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -70,20 +70,49 @@ func TestTableViewFilter(t *testing.T) {
|
|||
v.CmdBuff().SetActive(true)
|
||||
v.CmdBuff().SetText("blee", "")
|
||||
|
||||
assert.Equal(t, 3, v.GetRowCount())
|
||||
assert.Equal(t, 5, v.GetRowCount())
|
||||
}
|
||||
|
||||
func TestTableViewSort(t *testing.T) {
|
||||
v := NewTable(client.NewGVR("test"))
|
||||
v.Init(makeContext())
|
||||
v.SetModel(&mockTableModel{})
|
||||
v.SortColCmd("NAME", true)(nil)
|
||||
assert.Equal(t, 3, v.GetRowCount())
|
||||
assert.Equal(t, "blee", v.GetCell(1, 0).Text)
|
||||
|
||||
v.SortInvertCmd(nil)
|
||||
assert.Equal(t, 3, v.GetRowCount())
|
||||
assert.Equal(t, "fred", v.GetCell(1, 0).Text)
|
||||
uu := map[string]struct {
|
||||
sortCol string
|
||||
sorted []string
|
||||
reversed []string
|
||||
}{
|
||||
"by_name": {
|
||||
sortCol: "NAME",
|
||||
sorted: []string{"r0", "r1", "r2", "r3"},
|
||||
reversed: []string{"r3", "r2", "r1", "r0"},
|
||||
},
|
||||
"by_age": {
|
||||
sortCol: "AGE",
|
||||
sorted: []string{"r0", "r1", "r2", "r3"},
|
||||
reversed: []string{"r3", "r2", "r1", "r0"},
|
||||
},
|
||||
"by_fred": {
|
||||
sortCol: "FRED",
|
||||
sorted: []string{"r3", "r2", "r0", "r1"},
|
||||
reversed: []string{"r1", "r0", "r2", "r3"},
|
||||
},
|
||||
}
|
||||
|
||||
for k := range uu {
|
||||
u := uu[k]
|
||||
v.SortColCmd(u.sortCol, true)(nil)
|
||||
assert.Equal(t, len(u.sorted)+1, v.GetRowCount())
|
||||
for i, s := range u.sorted {
|
||||
assert.Equal(t, s, v.GetCell(i+1, 0).Text)
|
||||
}
|
||||
v.SortInvertCmd(nil)
|
||||
assert.Equal(t, len(u.reversed)+1, v.GetRowCount())
|
||||
for i, s := range u.reversed {
|
||||
assert.Equal(t, s, v.GetCell(i+1, 0).Text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -128,27 +157,35 @@ func (t *mockTableModel) SetRefreshRate(time.Duration) {}
|
|||
|
||||
func makeTableData() render.TableData {
|
||||
t := render.NewTableData()
|
||||
|
||||
t.Header = render.Header{
|
||||
render.HeaderColumn{Name: "NAMESPACE"},
|
||||
render.HeaderColumn{Name: "NAME", Align: tview.AlignRight},
|
||||
render.HeaderColumn{Name: "FRED"},
|
||||
render.HeaderColumn{Name: "AGE", Time: true, Decorator: render.AgeDecorator},
|
||||
render.HeaderColumn{Name: "AGE", Time: true},
|
||||
}
|
||||
t.RowEvents = render.RowEvents{
|
||||
render.RowEvent{
|
||||
Row: render.Row{
|
||||
Fields: render.Fields{"ns1", "blee", "10", "3m"},
|
||||
Fields: render.Fields{"ns1", "r3", "10", "3y125d"},
|
||||
},
|
||||
},
|
||||
render.RowEvent{
|
||||
Row: render.Row{
|
||||
Fields: render.Fields{"ns1", "fred", "15", "1m"},
|
||||
Fields: render.Fields{"ns1", "r2", "15", "2y12d"},
|
||||
},
|
||||
Deltas: render.DeltaRow{"", "", "20", ""},
|
||||
},
|
||||
render.RowEvent{
|
||||
Row: render.Row{
|
||||
Fields: render.Fields{"ns1", "r1", "20", "19h"},
|
||||
},
|
||||
},
|
||||
render.RowEvent{
|
||||
Row: render.Row{
|
||||
Fields: render.Fields{"ns1", "r0", "15", "10s"},
|
||||
},
|
||||
},
|
||||
}
|
||||
t.Namespace = ""
|
||||
|
||||
return *t
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue