mirror of
https://github.com/datarhei/core.git
synced 2025-10-01 06:12:26 +08:00
Fix tests
This commit is contained in:
@@ -15,6 +15,7 @@ func TestImport(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
memfs.WriteFileReader("/mime.types", strings.NewReader("foobar"))
|
memfs.WriteFileReader("/mime.types", strings.NewReader("foobar"))
|
||||||
|
memfs.WriteFileReader("/bin/ffmpeg", strings.NewReader("foobar"))
|
||||||
|
|
||||||
configstore, err := store.NewJSON(memfs, "/config.json", nil)
|
configstore, err := store.NewJSON(memfs, "/config.json", nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@@ -228,7 +228,7 @@ func (d *Config) init() {
|
|||||||
d.vars.Register(value.NewStringList(&d.SRT.Log.Topics, []string{}, ","), "srt.log.topics", "CORE_SRT_LOG_TOPICS", nil, "List of topics to log", false, false)
|
d.vars.Register(value.NewStringList(&d.SRT.Log.Topics, []string{}, ","), "srt.log.topics", "CORE_SRT_LOG_TOPICS", nil, "List of topics to log", false, false)
|
||||||
|
|
||||||
// FFmpeg
|
// FFmpeg
|
||||||
d.vars.Register(value.NewExec(&d.FFmpeg.Binary, "ffmpeg"), "ffmpeg.binary", "CORE_FFMPEG_BINARY", nil, "Path to ffmpeg binary", true, false)
|
d.vars.Register(value.NewExec(&d.FFmpeg.Binary, "ffmpeg", d.fs), "ffmpeg.binary", "CORE_FFMPEG_BINARY", nil, "Path to ffmpeg binary", true, false)
|
||||||
d.vars.Register(value.NewInt64(&d.FFmpeg.MaxProcesses, 0), "ffmpeg.max_processes", "CORE_FFMPEG_MAXPROCESSES", nil, "Max. allowed simultaneously running ffmpeg instances, 0 for unlimited", false, false)
|
d.vars.Register(value.NewInt64(&d.FFmpeg.MaxProcesses, 0), "ffmpeg.max_processes", "CORE_FFMPEG_MAXPROCESSES", nil, "Max. allowed simultaneously running ffmpeg instances, 0 for unlimited", false, false)
|
||||||
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Allow, []string{}, " "), "ffmpeg.access.input.allow", "CORE_FFMPEG_ACCESS_INPUT_ALLOW", nil, "List of allowed expression to match against the input addresses", false, false)
|
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Allow, []string{}, " "), "ffmpeg.access.input.allow", "CORE_FFMPEG_ACCESS_INPUT_ALLOW", nil, "List of allowed expression to match against the input addresses", false, false)
|
||||||
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Block, []string{}, " "), "ffmpeg.access.input.block", "CORE_FFMPEG_ACCESS_INPUT_BLOCK", nil, "List of blocked expression to match against the input addresses", false, false)
|
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Block, []string{}, " "), "ffmpeg.access.input.block", "CORE_FFMPEG_ACCESS_INPUT_BLOCK", nil, "List of blocked expression to match against the input addresses", false, false)
|
||||||
|
@@ -57,12 +57,17 @@ func TestConfigCopy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateDefault(t *testing.T) {
|
func TestValidateDefault(t *testing.T) {
|
||||||
fs, _ := fs.NewMemFilesystem(fs.MemConfig{})
|
fs, err := fs.NewMemFilesystem(fs.MemConfig{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
size, fresh, err := fs.WriteFileReader("./mime.types", strings.NewReader("xxxxx"))
|
size, fresh, err := fs.WriteFileReader("./mime.types", strings.NewReader("xxxxx"))
|
||||||
require.Equal(t, int64(5), size)
|
require.Equal(t, int64(5), size)
|
||||||
require.Equal(t, true, fresh)
|
require.Equal(t, true, fresh)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, _, err = fs.WriteFileReader("/bin/ffmpeg", strings.NewReader("xxxxx"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
cfg := New(fs)
|
cfg := New(fs)
|
||||||
|
|
||||||
cfg.Validate(true)
|
cfg.Validate(true)
|
||||||
|
@@ -195,7 +195,7 @@ func (d *Config) init() {
|
|||||||
d.vars.Register(value.NewStringList(&d.SRT.Log.Topics, []string{}, ","), "srt.log.topics", "CORE_SRT_LOG_TOPICS", nil, "List of topics to log", false, false)
|
d.vars.Register(value.NewStringList(&d.SRT.Log.Topics, []string{}, ","), "srt.log.topics", "CORE_SRT_LOG_TOPICS", nil, "List of topics to log", false, false)
|
||||||
|
|
||||||
// FFmpeg
|
// FFmpeg
|
||||||
d.vars.Register(value.NewExec(&d.FFmpeg.Binary, "ffmpeg"), "ffmpeg.binary", "CORE_FFMPEG_BINARY", nil, "Path to ffmpeg binary", true, false)
|
d.vars.Register(value.NewExec(&d.FFmpeg.Binary, "ffmpeg", d.fs), "ffmpeg.binary", "CORE_FFMPEG_BINARY", nil, "Path to ffmpeg binary", true, false)
|
||||||
d.vars.Register(value.NewInt64(&d.FFmpeg.MaxProcesses, 0), "ffmpeg.max_processes", "CORE_FFMPEG_MAXPROCESSES", nil, "Max. allowed simultaneously running ffmpeg instances, 0 for unlimited", false, false)
|
d.vars.Register(value.NewInt64(&d.FFmpeg.MaxProcesses, 0), "ffmpeg.max_processes", "CORE_FFMPEG_MAXPROCESSES", nil, "Max. allowed simultaneously running ffmpeg instances, 0 for unlimited", false, false)
|
||||||
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Allow, []string{}, " "), "ffmpeg.access.input.allow", "CORE_FFMPEG_ACCESS_INPUT_ALLOW", nil, "List of allowed expression to match against the input addresses", false, false)
|
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Allow, []string{}, " "), "ffmpeg.access.input.allow", "CORE_FFMPEG_ACCESS_INPUT_ALLOW", nil, "List of allowed expression to match against the input addresses", false, false)
|
||||||
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Block, []string{}, " "), "ffmpeg.access.input.block", "CORE_FFMPEG_ACCESS_INPUT_BLOCK", nil, "List of blocked expression to match against the input addresses", false, false)
|
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Block, []string{}, " "), "ffmpeg.access.input.block", "CORE_FFMPEG_ACCESS_INPUT_BLOCK", nil, "List of blocked expression to match against the input addresses", false, false)
|
||||||
|
@@ -196,7 +196,7 @@ func (d *Config) init() {
|
|||||||
d.vars.Register(value.NewStringList(&d.SRT.Log.Topics, []string{}, ","), "srt.log.topics", "CORE_SRT_LOG_TOPICS", nil, "List of topics to log", false, false)
|
d.vars.Register(value.NewStringList(&d.SRT.Log.Topics, []string{}, ","), "srt.log.topics", "CORE_SRT_LOG_TOPICS", nil, "List of topics to log", false, false)
|
||||||
|
|
||||||
// FFmpeg
|
// FFmpeg
|
||||||
d.vars.Register(value.NewExec(&d.FFmpeg.Binary, "ffmpeg"), "ffmpeg.binary", "CORE_FFMPEG_BINARY", nil, "Path to ffmpeg binary", true, false)
|
d.vars.Register(value.NewExec(&d.FFmpeg.Binary, "ffmpeg", d.fs), "ffmpeg.binary", "CORE_FFMPEG_BINARY", nil, "Path to ffmpeg binary", true, false)
|
||||||
d.vars.Register(value.NewInt64(&d.FFmpeg.MaxProcesses, 0), "ffmpeg.max_processes", "CORE_FFMPEG_MAXPROCESSES", nil, "Max. allowed simultaneously running ffmpeg instances, 0 for unlimited", false, false)
|
d.vars.Register(value.NewInt64(&d.FFmpeg.MaxProcesses, 0), "ffmpeg.max_processes", "CORE_FFMPEG_MAXPROCESSES", nil, "Max. allowed simultaneously running ffmpeg instances, 0 for unlimited", false, false)
|
||||||
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Allow, []string{}, " "), "ffmpeg.access.input.allow", "CORE_FFMPEG_ACCESS_INPUT_ALLOW", nil, "List of allowed expression to match against the input addresses", false, false)
|
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Allow, []string{}, " "), "ffmpeg.access.input.allow", "CORE_FFMPEG_ACCESS_INPUT_ALLOW", nil, "List of allowed expression to match against the input addresses", false, false)
|
||||||
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Block, []string{}, " "), "ffmpeg.access.input.block", "CORE_FFMPEG_ACCESS_INPUT_BLOCK", nil, "List of blocked expression to match against the input addresses", false, false)
|
d.vars.Register(value.NewStringList(&d.FFmpeg.Access.Input.Block, []string{}, " "), "ffmpeg.access.input.block", "CORE_FFMPEG_ACCESS_INPUT_BLOCK", nil, "List of blocked expression to match against the input addresses", false, false)
|
||||||
|
@@ -2,7 +2,6 @@ package value
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -115,27 +114,35 @@ func (u *Dir) IsEmpty() bool {
|
|||||||
|
|
||||||
// executable
|
// executable
|
||||||
|
|
||||||
type Exec string
|
type Exec struct {
|
||||||
|
p *string
|
||||||
|
fs fs.Filesystem
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewExec(p *string, val string, fs fs.Filesystem) *Exec {
|
||||||
|
v := &Exec{
|
||||||
|
p: p,
|
||||||
|
fs: fs,
|
||||||
|
}
|
||||||
|
|
||||||
func NewExec(p *string, val string) *Exec {
|
|
||||||
*p = val
|
*p = val
|
||||||
|
|
||||||
return (*Exec)(p)
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Exec) Set(val string) error {
|
func (u *Exec) Set(val string) error {
|
||||||
*u = Exec(val)
|
*u.p = val
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Exec) String() string {
|
func (u *Exec) String() string {
|
||||||
return string(*u)
|
return *u.p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Exec) Validate() error {
|
func (u *Exec) Validate() error {
|
||||||
val := string(*u)
|
val := *u.p
|
||||||
|
|
||||||
_, err := exec.LookPath(val)
|
_, err := u.fs.LookPath(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s not found or is not executable", val)
|
return fmt.Errorf("%s not found or is not executable", val)
|
||||||
}
|
}
|
||||||
@@ -144,7 +151,7 @@ func (u *Exec) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *Exec) IsEmpty() bool {
|
func (u *Exec) IsEmpty() bool {
|
||||||
return len(string(*u)) == 0
|
return len(*u.p) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// regular file
|
// regular file
|
||||||
|
@@ -3,9 +3,124 @@ package value
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/datarhei/core/v16/io/fs"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestMustDirValue(t *testing.T) {
|
||||||
|
memfs, err := fs.NewMemFilesystem(fs.MemConfig{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = memfs.Stat("/foobar")
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
var x string
|
||||||
|
|
||||||
|
val := NewMustDir(&x, "./foobar", memfs)
|
||||||
|
|
||||||
|
require.Equal(t, "./foobar", val.String())
|
||||||
|
require.NoError(t, val.Validate())
|
||||||
|
require.Equal(t, false, val.IsEmpty())
|
||||||
|
|
||||||
|
info, err := memfs.Stat("/foobar")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, info.IsDir())
|
||||||
|
|
||||||
|
x = "/bar/foo"
|
||||||
|
|
||||||
|
require.Equal(t, "/bar/foo", val.String())
|
||||||
|
|
||||||
|
_, err = memfs.Stat("/bar/foo")
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
require.NoError(t, val.Validate())
|
||||||
|
|
||||||
|
info, err = memfs.Stat("/bar/foo")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, info.IsDir())
|
||||||
|
|
||||||
|
memfs.WriteFile("/foo/bar", []byte("hello"))
|
||||||
|
|
||||||
|
val.Set("/foo/bar")
|
||||||
|
|
||||||
|
require.Error(t, val.Validate())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDirValue(t *testing.T) {
|
||||||
|
memfs, err := fs.NewMemFilesystem(fs.MemConfig{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var x string
|
||||||
|
|
||||||
|
val := NewDir(&x, "/foobar", memfs)
|
||||||
|
|
||||||
|
require.Equal(t, "/foobar", val.String())
|
||||||
|
require.Error(t, val.Validate())
|
||||||
|
require.Equal(t, false, val.IsEmpty())
|
||||||
|
|
||||||
|
err = memfs.MkdirAll("/foobar", 0755)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NoError(t, val.Validate())
|
||||||
|
|
||||||
|
_, _, err = memfs.WriteFile("/foo/bar", []byte("hello"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
val.Set("/foo/bar")
|
||||||
|
|
||||||
|
require.Error(t, val.Validate())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileValue(t *testing.T) {
|
||||||
|
memfs, err := fs.NewMemFilesystem(fs.MemConfig{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var x string
|
||||||
|
|
||||||
|
val := NewFile(&x, "/foobar", memfs)
|
||||||
|
|
||||||
|
require.Equal(t, "/foobar", val.String())
|
||||||
|
require.Error(t, val.Validate())
|
||||||
|
require.Equal(t, false, val.IsEmpty())
|
||||||
|
|
||||||
|
_, _, err = memfs.WriteFile("/foobar", []byte("hello"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NoError(t, val.Validate())
|
||||||
|
|
||||||
|
err = memfs.MkdirAll("/foo/bar", 0755)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
val.Set("/foo/bar")
|
||||||
|
|
||||||
|
require.Error(t, val.Validate())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExecValue(t *testing.T) {
|
||||||
|
memfs, err := fs.NewMemFilesystem(fs.MemConfig{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var x string
|
||||||
|
|
||||||
|
val := NewExec(&x, "/foobar", memfs)
|
||||||
|
|
||||||
|
require.Equal(t, "/foobar", val.String())
|
||||||
|
require.Error(t, val.Validate())
|
||||||
|
require.Equal(t, false, val.IsEmpty())
|
||||||
|
|
||||||
|
_, _, err = memfs.WriteFile("/foobar", []byte("hello"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NoError(t, val.Validate())
|
||||||
|
|
||||||
|
err = memfs.MkdirAll("/foo/bar", 0755)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
val.Set("/foo/bar")
|
||||||
|
|
||||||
|
require.Error(t, val.Validate())
|
||||||
|
}
|
||||||
|
|
||||||
func TestAbsolutePathValue(t *testing.T) {
|
func TestAbsolutePathValue(t *testing.T) {
|
||||||
var x string
|
var x string
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/datarhei/core/v16/config"
|
"github.com/datarhei/core/v16/config"
|
||||||
@@ -21,6 +22,12 @@ func getDummyConfigRouter(t *testing.T) (*echo.Echo, store.Store) {
|
|||||||
memfs, err := fs.NewMemFilesystem(fs.MemConfig{})
|
memfs, err := fs.NewMemFilesystem(fs.MemConfig{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, _, err = memfs.WriteFileReader("./mime.types", strings.NewReader("xxxxx"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, _, err = memfs.WriteFileReader("/bin/ffmpeg", strings.NewReader("xxxxx"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
config, err := store.NewJSON(memfs, "/config.json", nil)
|
config, err := store.NewJSON(memfs, "/config.json", nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -43,10 +50,13 @@ func TestConfigGet(t *testing.T) {
|
|||||||
func TestConfigSetConflict(t *testing.T) {
|
func TestConfigSetConflict(t *testing.T) {
|
||||||
router, _ := getDummyConfigRouter(t)
|
router, _ := getDummyConfigRouter(t)
|
||||||
|
|
||||||
|
cfg := config.New(nil)
|
||||||
|
cfg.Storage.MimeTypes = "/path/to/mime.types"
|
||||||
|
|
||||||
var data bytes.Buffer
|
var data bytes.Buffer
|
||||||
|
|
||||||
encoder := json.NewEncoder(&data)
|
encoder := json.NewEncoder(&data)
|
||||||
encoder.Encode(config.New(nil))
|
encoder.Encode(cfg)
|
||||||
|
|
||||||
mock.Request(t, http.StatusConflict, router, "PUT", "/", &data)
|
mock.Request(t, http.StatusConflict, router, "PUT", "/", &data)
|
||||||
}
|
}
|
||||||
@@ -63,10 +73,8 @@ func TestConfigSet(t *testing.T) {
|
|||||||
|
|
||||||
// Setting a new v3 config
|
// Setting a new v3 config
|
||||||
cfg := config.New(nil)
|
cfg := config.New(nil)
|
||||||
cfg.FFmpeg.Binary = "true"
|
|
||||||
cfg.DB.Dir = "."
|
cfg.DB.Dir = "."
|
||||||
cfg.Storage.Disk.Dir = "."
|
cfg.Storage.Disk.Dir = "."
|
||||||
cfg.Storage.MimeTypes = ""
|
|
||||||
cfg.Storage.Disk.Cache.Types.Allow = []string{".aaa"}
|
cfg.Storage.Disk.Cache.Types.Allow = []string{".aaa"}
|
||||||
cfg.Storage.Disk.Cache.Types.Block = []string{".zzz"}
|
cfg.Storage.Disk.Cache.Types.Block = []string{".zzz"}
|
||||||
cfg.Host.Name = []string{"foobar.com"}
|
cfg.Host.Name = []string{"foobar.com"}
|
||||||
@@ -84,10 +92,8 @@ func TestConfigSet(t *testing.T) {
|
|||||||
|
|
||||||
// Setting a complete v1 config
|
// Setting a complete v1 config
|
||||||
cfgv1 := v1.New(nil)
|
cfgv1 := v1.New(nil)
|
||||||
cfgv1.FFmpeg.Binary = "true"
|
|
||||||
cfgv1.DB.Dir = "."
|
cfgv1.DB.Dir = "."
|
||||||
cfgv1.Storage.Disk.Dir = "."
|
cfgv1.Storage.Disk.Dir = "."
|
||||||
cfgv1.Storage.MimeTypes = ""
|
|
||||||
cfgv1.Storage.Disk.Cache.Types = []string{".bbb"}
|
cfgv1.Storage.Disk.Cache.Types = []string{".bbb"}
|
||||||
cfgv1.Host.Name = []string{"foobar.com"}
|
cfgv1.Host.Name = []string{"foobar.com"}
|
||||||
|
|
||||||
|
@@ -553,6 +553,51 @@ func (fs *diskFilesystem) List(path, pattern string) []FileInfo {
|
|||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *diskFilesystem) LookPath(file string) (string, error) {
|
||||||
|
if strings.Contains(file, "/") {
|
||||||
|
file = fs.cleanPath(file)
|
||||||
|
err := fs.findExecutable(file)
|
||||||
|
if err == nil {
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
return "", os.ErrNotExist
|
||||||
|
}
|
||||||
|
path := os.Getenv("PATH")
|
||||||
|
for _, dir := range filepath.SplitList(path) {
|
||||||
|
if dir == "" {
|
||||||
|
// Unix shell semantics: path element "" means "."
|
||||||
|
dir = "."
|
||||||
|
}
|
||||||
|
path := filepath.Join(dir, file)
|
||||||
|
path = fs.cleanPath(path)
|
||||||
|
if err := fs.findExecutable(path); err == nil {
|
||||||
|
if !filepath.IsAbs(path) {
|
||||||
|
return path, os.ErrNotExist
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", os.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *diskFilesystem) findExecutable(file string) error {
|
||||||
|
d, err := fs.Stat(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := d.Mode()
|
||||||
|
if m.IsDir() {
|
||||||
|
return fmt.Errorf("is a directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
if m&0111 != 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.ErrPermission
|
||||||
|
}
|
||||||
|
|
||||||
func (fs *diskFilesystem) walk(path string, walkfn func(path string, info os.FileInfo)) {
|
func (fs *diskFilesystem) walk(path string, walkfn func(path string, info os.FileInfo)) {
|
||||||
filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -66,6 +66,12 @@ type ReadFilesystem interface {
|
|||||||
|
|
||||||
// List lists all files that are currently on the filesystem.
|
// List lists all files that are currently on the filesystem.
|
||||||
List(path, pattern string) []FileInfo
|
List(path, pattern string) []FileInfo
|
||||||
|
|
||||||
|
// LookPath searches for an executable named file in the directories named by the PATH environment
|
||||||
|
// variable. If file contains a slash, it is tried directly and the PATH is not consulted. Otherwise,
|
||||||
|
// on success, the result is an absolute path. On non-disk filesystems. Only the mere existence
|
||||||
|
// of that file is verfied.
|
||||||
|
LookPath(file string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type WriteFilesystem interface {
|
type WriteFilesystem interface {
|
||||||
|
33
io/fs/mem.go
33
io/fs/mem.go
@@ -697,6 +697,39 @@ func (fs *memFilesystem) List(path, pattern string) []FileInfo {
|
|||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *memFilesystem) LookPath(file string) (string, error) {
|
||||||
|
if strings.Contains(file, "/") {
|
||||||
|
file = fs.cleanPath(file)
|
||||||
|
info, err := fs.Stat(file)
|
||||||
|
if err == nil {
|
||||||
|
if !info.Mode().IsRegular() {
|
||||||
|
return file, os.ErrNotExist
|
||||||
|
}
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
return "", os.ErrNotExist
|
||||||
|
}
|
||||||
|
path := os.Getenv("PATH")
|
||||||
|
for _, dir := range filepath.SplitList(path) {
|
||||||
|
if dir == "" {
|
||||||
|
// Unix shell semantics: path element "" means "."
|
||||||
|
dir = "."
|
||||||
|
}
|
||||||
|
path := filepath.Join(dir, file)
|
||||||
|
path = fs.cleanPath(path)
|
||||||
|
if info, err := fs.Stat(path); err == nil {
|
||||||
|
if !filepath.IsAbs(path) {
|
||||||
|
return path, os.ErrNotExist
|
||||||
|
}
|
||||||
|
if !info.Mode().IsRegular() {
|
||||||
|
return path, os.ErrNotExist
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", os.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
func (fs *memFilesystem) cleanPath(path string) string {
|
func (fs *memFilesystem) cleanPath(path string) string {
|
||||||
if !filepath.IsAbs(path) {
|
if !filepath.IsAbs(path) {
|
||||||
path = filepath.Join("/", path)
|
path = filepath.Join("/", path)
|
||||||
|
33
io/fs/s3.go
33
io/fs/s3.go
@@ -511,6 +511,39 @@ func (fs *s3Filesystem) List(path, pattern string) []FileInfo {
|
|||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *s3Filesystem) LookPath(file string) (string, error) {
|
||||||
|
if strings.Contains(file, "/") {
|
||||||
|
file = fs.cleanPath(file)
|
||||||
|
info, err := fs.Stat(file)
|
||||||
|
if err == nil {
|
||||||
|
if !info.Mode().IsRegular() {
|
||||||
|
return file, os.ErrNotExist
|
||||||
|
}
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
return "", os.ErrNotExist
|
||||||
|
}
|
||||||
|
path := os.Getenv("PATH")
|
||||||
|
for _, dir := range filepath.SplitList(path) {
|
||||||
|
if dir == "" {
|
||||||
|
// Unix shell semantics: path element "" means "."
|
||||||
|
dir = "."
|
||||||
|
}
|
||||||
|
path := filepath.Join(dir, file)
|
||||||
|
path = fs.cleanPath(path)
|
||||||
|
if info, err := fs.Stat(path); err == nil {
|
||||||
|
if !filepath.IsAbs(path) {
|
||||||
|
return path, os.ErrNotExist
|
||||||
|
}
|
||||||
|
if !info.Mode().IsRegular() {
|
||||||
|
return path, os.ErrNotExist
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", os.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
func (fs *s3Filesystem) isDir(path string) bool {
|
func (fs *s3Filesystem) isDir(path string) bool {
|
||||||
if !strings.HasSuffix(path, "/") {
|
if !strings.HasSuffix(path, "/") {
|
||||||
path = path + "/"
|
path = path + "/"
|
||||||
|
@@ -192,6 +192,7 @@ type process struct {
|
|||||||
onStart func()
|
onStart func()
|
||||||
onExit func()
|
onExit func()
|
||||||
onStateChange func(from, to string)
|
onStateChange func(from, to string)
|
||||||
|
lock sync.Mutex
|
||||||
}
|
}
|
||||||
limits Limiter
|
limits Limiter
|
||||||
}
|
}
|
||||||
@@ -588,6 +589,7 @@ func (p *process) stop(wait bool) error {
|
|||||||
if wait {
|
if wait {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|
||||||
|
p.callbacks.lock.Lock()
|
||||||
if p.callbacks.onExit == nil {
|
if p.callbacks.onExit == nil {
|
||||||
p.callbacks.onExit = func() {
|
p.callbacks.onExit = func() {
|
||||||
wg.Done()
|
wg.Done()
|
||||||
@@ -601,6 +603,7 @@ func (p *process) stop(wait bool) error {
|
|||||||
p.callbacks.onExit = cb
|
p.callbacks.onExit = cb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
p.callbacks.lock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@@ -829,10 +832,12 @@ func (p *process) waiter() {
|
|||||||
// Reset the parser stats
|
// Reset the parser stats
|
||||||
p.parser.ResetStats()
|
p.parser.ResetStats()
|
||||||
|
|
||||||
// Call the onStop callback
|
// Call the onExit callback
|
||||||
|
p.callbacks.lock.Lock()
|
||||||
if p.callbacks.onExit != nil {
|
if p.callbacks.onExit != nil {
|
||||||
go p.callbacks.onExit()
|
go p.callbacks.onExit()
|
||||||
}
|
}
|
||||||
|
p.callbacks.lock.Unlock()
|
||||||
|
|
||||||
p.order.lock.Lock()
|
p.order.lock.Lock()
|
||||||
defer p.order.lock.Unlock()
|
defer p.order.lock.Unlock()
|
||||||
|
Reference in New Issue
Block a user