345ab87b5c
With this change users can use the uplink cli in scripts (ie. bash) more easily, since the output can be switched to an easier processable json format. It keeps the default of tabbed output. Change-Id: I37e2c55f75c2250c3119fd8df8b66a766ff9096b
468 lines
16 KiB
Go
468 lines
16 KiB
Go
// Copyright (C) 2021 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package main
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"storj.io/storj/cmd/uplink/ultest"
|
|
)
|
|
|
|
func TestLsErrors(t *testing.T) {
|
|
state := ultest.Setup(commands)
|
|
|
|
// empty bucket name is a parse error
|
|
state.Fail(t, "ls", "sj:///user")
|
|
}
|
|
|
|
func TestLsRemote(t *testing.T) {
|
|
state := ultest.Setup(commands,
|
|
ultest.WithFile("sj://user/deep/aaa/bbb/1"),
|
|
ultest.WithFile("sj://user/deep/aaa/bbb/2"),
|
|
ultest.WithFile("sj://user/deep/aaa/bbb/3"),
|
|
ultest.WithFile("sj://user/foobar"),
|
|
ultest.WithFile("sj://user/foobar/"),
|
|
ultest.WithFile("sj://user/foobar/1"),
|
|
ultest.WithFile("sj://user/foobar/2"),
|
|
ultest.WithFile("sj://user/foobar/3"),
|
|
ultest.WithFile("sj://user/foobaz/1"),
|
|
|
|
ultest.WithPendingFile("sj://user/invisible"),
|
|
)
|
|
|
|
t.Run("Recursive", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user", "--recursive", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:01 0 deep/aaa/bbb/1
|
|
OBJ 1970-01-01 00:00:02 0 deep/aaa/bbb/2
|
|
OBJ 1970-01-01 00:00:03 0 deep/aaa/bbb/3
|
|
OBJ 1970-01-01 00:00:04 0 foobar
|
|
OBJ 1970-01-01 00:00:05 0 foobar/
|
|
OBJ 1970-01-01 00:00:06 0 foobar/1
|
|
OBJ 1970-01-01 00:00:07 0 foobar/2
|
|
OBJ 1970-01-01 00:00:08 0 foobar/3
|
|
OBJ 1970-01-01 00:00:09 0 foobaz/1
|
|
`)
|
|
})
|
|
|
|
t.Run("Basic", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/fo", "--utc").RequireStdout(t, ``)
|
|
})
|
|
|
|
t.Run("ExactPrefix", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/foobar", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:04 0 foobar
|
|
PRE foobar/
|
|
`)
|
|
})
|
|
|
|
t.Run("ExactPrefixWithSlash", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/foobar/", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:05 0
|
|
OBJ 1970-01-01 00:00:06 0 1
|
|
OBJ 1970-01-01 00:00:07 0 2
|
|
OBJ 1970-01-01 00:00:08 0 3
|
|
`)
|
|
})
|
|
|
|
t.Run("MultipleLayers", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/deep/").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
PRE aaa/
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/deep/aaa/").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
PRE bbb/
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/deep/aaa/bbb/", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:01 0 1
|
|
OBJ 1970-01-01 00:00:02 0 2
|
|
OBJ 1970-01-01 00:00:03 0 3
|
|
`)
|
|
})
|
|
}
|
|
|
|
func TestLsJSON(t *testing.T) {
|
|
state := ultest.Setup(commands,
|
|
ultest.WithFile("sj://user/deep/aaa/bbb/1"),
|
|
ultest.WithFile("sj://user/deep/aaa/bbb/2"),
|
|
ultest.WithFile("sj://user/deep/aaa/bbb/3"),
|
|
ultest.WithFile("sj://user/foobar"),
|
|
ultest.WithFile("sj://user/foobar/"),
|
|
ultest.WithFile("sj://user/foobar/1"),
|
|
ultest.WithFile("sj://user/foobar/2"),
|
|
ultest.WithFile("sj://user/foobar/3"),
|
|
ultest.WithFile("sj://user/foobaz/1"),
|
|
|
|
ultest.WithPendingFile("sj://user/invisible"),
|
|
)
|
|
|
|
t.Run("Recursive", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user", "--recursive", "--utc", "--output", "json").RequireStdout(t, `
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:01","size":0,"key":"deep/aaa/bbb/1"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:02","size":0,"key":"deep/aaa/bbb/2"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:03","size":0,"key":"deep/aaa/bbb/3"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:04","size":0,"key":"foobar"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:05","size":0,"key":"foobar/"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:06","size":0,"key":"foobar/1"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:07","size":0,"key":"foobar/2"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:08","size":0,"key":"foobar/3"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:09","size":0,"key":"foobaz/1"}
|
|
`)
|
|
})
|
|
|
|
t.Run("Basic", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/fo", "--utc", "--output", "json").RequireStdout(t, ``)
|
|
})
|
|
|
|
t.Run("ExactPrefix", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/foobar", "--utc", "--output", "json").RequireStdout(t, `
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:04","size":0,"key":"foobar"}
|
|
{"kind":"PRE","key":"foobar/"}
|
|
`)
|
|
})
|
|
|
|
t.Run("ShortFlag", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/foobar", "--utc", "-o", "json").RequireStdout(t, `
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:04","size":0,"key":"foobar"}
|
|
{"kind":"PRE","key":"foobar/"}
|
|
`)
|
|
})
|
|
|
|
t.Run("ExactPrefixWithSlash", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/foobar/", "--utc", "--output", "json").RequireStdout(t, `
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:05","size":0,"key":""}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:06","size":0,"key":"1"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:07","size":0,"key":"2"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:08","size":0,"key":"3"}
|
|
`)
|
|
})
|
|
|
|
t.Run("MultipleLayers", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/deep/", "--output", "json").RequireStdout(t, `
|
|
{"kind":"PRE","key":"aaa/"}
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/deep/aaa/", "--output", "json").RequireStdout(t, `
|
|
{"kind":"PRE","key":"bbb/"}
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/deep/aaa/bbb/", "--utc", "--output", "json").RequireStdout(t, `
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:01","size":0,"key":"1"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:02","size":0,"key":"2"}
|
|
{"kind":"OBJ","created":"1970-01-01 00:00:03","size":0,"key":"3"}
|
|
`)
|
|
})
|
|
}
|
|
|
|
func TestLsPending(t *testing.T) {
|
|
state := ultest.Setup(commands,
|
|
ultest.WithPendingFile("sj://user/deep/aaa/bbb/1"),
|
|
ultest.WithPendingFile("sj://user/deep/aaa/bbb/2"),
|
|
ultest.WithPendingFile("sj://user/deep/aaa/bbb/3"),
|
|
ultest.WithPendingFile("sj://user/foobar"),
|
|
ultest.WithPendingFile("sj://user/foobar/"),
|
|
ultest.WithPendingFile("sj://user/foobar/1"),
|
|
ultest.WithPendingFile("sj://user/foobar/2"),
|
|
ultest.WithPendingFile("sj://user/foobar/3"),
|
|
ultest.WithPendingFile("sj://user/foobaz/1"),
|
|
|
|
ultest.WithFile("sj://user/invisible"),
|
|
)
|
|
|
|
t.Run("Recursive", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user", "--recursive", "--pending", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:01 0 deep/aaa/bbb/1
|
|
OBJ 1970-01-01 00:00:02 0 deep/aaa/bbb/2
|
|
OBJ 1970-01-01 00:00:03 0 deep/aaa/bbb/3
|
|
OBJ 1970-01-01 00:00:04 0 foobar
|
|
OBJ 1970-01-01 00:00:05 0 foobar/
|
|
OBJ 1970-01-01 00:00:06 0 foobar/1
|
|
OBJ 1970-01-01 00:00:07 0 foobar/2
|
|
OBJ 1970-01-01 00:00:08 0 foobar/3
|
|
OBJ 1970-01-01 00:00:09 0 foobaz/1
|
|
`)
|
|
})
|
|
|
|
t.Run("Basic", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/fo", "--pending", "--utc").RequireStdout(t, ``)
|
|
})
|
|
|
|
t.Run("ExactPrefix", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/foobar", "--pending", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:04 0 foobar
|
|
PRE foobar/
|
|
`)
|
|
})
|
|
|
|
t.Run("ExactPrefixWithSlash", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/foobar/", "--pending", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:05 0
|
|
OBJ 1970-01-01 00:00:06 0 1
|
|
OBJ 1970-01-01 00:00:07 0 2
|
|
OBJ 1970-01-01 00:00:08 0 3
|
|
`)
|
|
})
|
|
|
|
t.Run("MultipleLayers", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/deep/", "--pending").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
PRE aaa/
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/deep/aaa/", "--pending").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
PRE bbb/
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/deep/aaa/bbb/", "--pending", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:01 0 1
|
|
OBJ 1970-01-01 00:00:02 0 2
|
|
OBJ 1970-01-01 00:00:03 0 3
|
|
`)
|
|
})
|
|
}
|
|
|
|
func TestLsDifficult(t *testing.T) {
|
|
state := ultest.Setup(commands,
|
|
ultest.WithFile("sj://user//"),
|
|
ultest.WithFile("sj://user///"),
|
|
ultest.WithFile("sj://user////"),
|
|
|
|
ultest.WithFile("sj://user//starts-slash"),
|
|
|
|
ultest.WithFile("sj://user/ends-slash"),
|
|
ultest.WithFile("sj://user/ends-slash/"),
|
|
ultest.WithFile("sj://user/ends-slash//"),
|
|
|
|
ultest.WithFile("sj://user/mid-slash"),
|
|
ultest.WithFile("sj://user/mid-slash//2"),
|
|
ultest.WithFile("sj://user/mid-slash/1"),
|
|
)
|
|
|
|
t.Run("Recursive", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user", "--recursive", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:01 0 /
|
|
OBJ 1970-01-01 00:00:02 0 //
|
|
OBJ 1970-01-01 00:00:03 0 ///
|
|
OBJ 1970-01-01 00:00:04 0 /starts-slash
|
|
OBJ 1970-01-01 00:00:05 0 ends-slash
|
|
OBJ 1970-01-01 00:00:06 0 ends-slash/
|
|
OBJ 1970-01-01 00:00:07 0 ends-slash//
|
|
OBJ 1970-01-01 00:00:08 0 mid-slash
|
|
OBJ 1970-01-01 00:00:09 0 mid-slash//2
|
|
OBJ 1970-01-01 00:00:10 0 mid-slash/1
|
|
`)
|
|
})
|
|
|
|
t.Run("Basic", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
PRE /
|
|
OBJ 1970-01-01 00:00:05 0 ends-slash
|
|
PRE ends-slash/
|
|
OBJ 1970-01-01 00:00:08 0 mid-slash
|
|
PRE mid-slash/
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
PRE /
|
|
OBJ 1970-01-01 00:00:05 0 ends-slash
|
|
PRE ends-slash/
|
|
OBJ 1970-01-01 00:00:08 0 mid-slash
|
|
PRE mid-slash/
|
|
`)
|
|
})
|
|
|
|
t.Run("OnlySlash", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user//", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:01 0
|
|
PRE /
|
|
OBJ 1970-01-01 00:00:04 0 starts-slash
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user///", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:02 0
|
|
PRE /
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user////", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:03 0
|
|
`)
|
|
})
|
|
|
|
t.Run("EndsSlash", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/ends-slash", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:05 0 ends-slash
|
|
PRE ends-slash/
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/ends-slash/", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:06 0
|
|
PRE /
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/ends-slash//", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:07 0
|
|
`)
|
|
})
|
|
|
|
t.Run("MidSlash", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "sj://user/mid-slash", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:08 0 mid-slash
|
|
PRE mid-slash/
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/mid-slash/", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
PRE /
|
|
OBJ 1970-01-01 00:00:10 0 1
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "sj://user/mid-slash//", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:09 0 2
|
|
`)
|
|
})
|
|
}
|
|
|
|
func TestLsLocal(t *testing.T) {
|
|
state := ultest.Setup(commands,
|
|
ultest.WithFile("/user/deep/aaa/bbb/1"),
|
|
ultest.WithFile("/user/deep/aaa/bbb/2"),
|
|
ultest.WithFile("/user/deep/aaa/bbb/3"),
|
|
ultest.WithFile("/user/foobar/1"),
|
|
ultest.WithFile("/user/foobar/2"),
|
|
ultest.WithFile("/user/foobar/3"),
|
|
ultest.WithFile("/user/foobaz/1"),
|
|
)
|
|
|
|
t.Run("Recursive", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "/user", "--recursive", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:01 0 /user/deep/aaa/bbb/1
|
|
OBJ 1970-01-01 00:00:02 0 /user/deep/aaa/bbb/2
|
|
OBJ 1970-01-01 00:00:03 0 /user/deep/aaa/bbb/3
|
|
OBJ 1970-01-01 00:00:04 0 /user/foobar/1
|
|
OBJ 1970-01-01 00:00:05 0 /user/foobar/2
|
|
OBJ 1970-01-01 00:00:06 0 /user/foobar/3
|
|
OBJ 1970-01-01 00:00:07 0 /user/foobaz/1
|
|
`)
|
|
})
|
|
|
|
t.Run("Basic", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "/user/fo", "--utc").RequireStdout(t, ``)
|
|
})
|
|
|
|
t.Run("ExactPrefix", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "/user/foobar", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:04 0 1
|
|
OBJ 1970-01-01 00:00:05 0 2
|
|
OBJ 1970-01-01 00:00:06 0 3
|
|
`)
|
|
})
|
|
|
|
t.Run("ExactPrefixWithSlash", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "/user/foobar/", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:04 0 1
|
|
OBJ 1970-01-01 00:00:05 0 2
|
|
OBJ 1970-01-01 00:00:06 0 3
|
|
`)
|
|
})
|
|
|
|
t.Run("MultipleLayers", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "/user/deep/").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
PRE aaa/
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "/user/deep/aaa/").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
PRE bbb/
|
|
`)
|
|
|
|
state.Succeed(t, "ls", "/user/deep/aaa/bbb/", "--utc").RequireStdout(t, `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:01 0 1
|
|
OBJ 1970-01-01 00:00:02 0 2
|
|
OBJ 1970-01-01 00:00:03 0 3
|
|
`)
|
|
})
|
|
}
|
|
|
|
func TestLsRelative(t *testing.T) {
|
|
state := ultest.Setup(commands,
|
|
ultest.WithFile("deep/aaa/bbb/1"),
|
|
ultest.WithFile("deep/aaa/bbb/2"),
|
|
ultest.WithFile("deep/aaa/bbb/3"),
|
|
ultest.WithFile("foobar/1"),
|
|
ultest.WithFile("foobar/2"),
|
|
ultest.WithFile("foobar/3"),
|
|
ultest.WithFile("foobaz/1"),
|
|
)
|
|
|
|
basic := `
|
|
KIND CREATED SIZE KEY
|
|
PRE deep/
|
|
PRE foobar/
|
|
PRE foobaz/
|
|
`
|
|
|
|
t.Run("Basic", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "", "--utc").RequireStdout(t, basic)
|
|
})
|
|
|
|
t.Run("BasicDot", func(t *testing.T) {
|
|
state.Succeed(t, "ls", ".", "--utc").RequireStdout(t, basic)
|
|
})
|
|
|
|
t.Run("BasicDotSlash", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "./", "--utc").RequireStdout(t, basic)
|
|
})
|
|
|
|
recursive := `
|
|
KIND CREATED SIZE KEY
|
|
OBJ 1970-01-01 00:00:01 0 deep/aaa/bbb/1
|
|
OBJ 1970-01-01 00:00:02 0 deep/aaa/bbb/2
|
|
OBJ 1970-01-01 00:00:03 0 deep/aaa/bbb/3
|
|
OBJ 1970-01-01 00:00:04 0 foobar/1
|
|
OBJ 1970-01-01 00:00:05 0 foobar/2
|
|
OBJ 1970-01-01 00:00:06 0 foobar/3
|
|
OBJ 1970-01-01 00:00:07 0 foobaz/1
|
|
`
|
|
|
|
t.Run("Recursive", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "", "--recursive", "--utc").RequireStdout(t, recursive)
|
|
})
|
|
|
|
t.Run("RecursiveDot", func(t *testing.T) {
|
|
state.Succeed(t, "ls", ".", "--recursive", "--utc").RequireStdout(t, recursive)
|
|
})
|
|
|
|
t.Run("RecursiveDotSlash", func(t *testing.T) {
|
|
state.Succeed(t, "ls", "./", "--recursive", "--utc").RequireStdout(t, recursive)
|
|
})
|
|
|
|
}
|