SAML Unit Tests, Go Driver & Removed vendor dependency (#3532)
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
d2df385f41
Коммит
540ebbd74d
7
Makefile
7
Makefile
@@ -181,14 +181,19 @@ ifeq ($(BUILD_ENTERPRISE_READY),true)
|
|||||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -covermode=count -c ./enterprise/ldap && ./ldap.test -test.v -test.timeout=120s -test.coverprofile=cldap.out || exit 1
|
$(GO) test $(GOFLAGS) -run=$(TESTS) -covermode=count -c ./enterprise/ldap && ./ldap.test -test.v -test.timeout=120s -test.coverprofile=cldap.out || exit 1
|
||||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -covermode=count -c ./enterprise/compliance && ./compliance.test -test.v -test.timeout=120s -test.coverprofile=ccompliance.out || exit 1
|
$(GO) test $(GOFLAGS) -run=$(TESTS) -covermode=count -c ./enterprise/compliance && ./compliance.test -test.v -test.timeout=120s -test.coverprofile=ccompliance.out || exit 1
|
||||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -covermode=count -c ./enterprise/emoji && ./emoji.test -test.v -test.timeout=120s -test.coverprofile=cemoji.out || exit 1
|
$(GO) test $(GOFLAGS) -run=$(TESTS) -covermode=count -c ./enterprise/emoji && ./emoji.test -test.v -test.timeout=120s -test.coverprofile=cemoji.out || exit 1
|
||||||
|
$(GO) test $(GOFLAGS) -run=$(TESTS) -covermode=count -c ./enterprise/saml && ./saml.test -test.v -test.timeout=60s -test.coverprofile=csaml.out || exit 1
|
||||||
|
|
||||||
tail -n +2 cldap.out >> ecover.out
|
tail -n +2 cldap.out >> ecover.out
|
||||||
tail -n +2 ccompliance.out >> ecover.out
|
tail -n +2 ccompliance.out >> ecover.out
|
||||||
tail -n +2 cemoji.out >> ecover.out
|
tail -n +2 cemoji.out >> ecover.out
|
||||||
rm -f cldap.out ccompliance.out cemoji.out
|
tail -n +2 csaml.out >> ecover.out
|
||||||
|
rm -f cldap.out ccompliance.out cemoji.out csaml.out
|
||||||
rm -r ldap.test
|
rm -r ldap.test
|
||||||
rm -r compliance.test
|
rm -r compliance.test
|
||||||
rm -r emoji.test
|
rm -r emoji.test
|
||||||
|
rm -r saml.test
|
||||||
|
rm -f config/*.crt
|
||||||
|
rm -f config/*.key
|
||||||
endif
|
endif
|
||||||
|
|
||||||
internal-test-web-client: start-docker prepare-enterprise
|
internal-test-web-client: start-docker prepare-enterprise
|
||||||
|
|||||||
2
glide.lock
сгенерированный
2
glide.lock
сгенерированный
@@ -42,8 +42,6 @@ imports:
|
|||||||
version: 9c19ed558d5df4da88e2ade9c8940d742aef0e7e
|
version: 9c19ed558d5df4da88e2ade9c8940d742aef0e7e
|
||||||
- name: github.com/gorilla/websocket
|
- name: github.com/gorilla/websocket
|
||||||
version: 1f512fc3f05332ba7117626cdfb4e07474e58e60
|
version: 1f512fc3f05332ba7117626cdfb4e07474e58e60
|
||||||
- name: github.com/kardianos/osext
|
|
||||||
version: 29ae4ffbc9a6fe9fb2bc5029050ce6996ea1d3bc
|
|
||||||
- name: github.com/lib/pq
|
- name: github.com/lib/pq
|
||||||
version: ee1442bda7bd1b6a84e913bdb421cb1874ec629d
|
version: ee1442bda7bd1b6a84e913bdb421cb1874ec629d
|
||||||
subpackages:
|
subpackages:
|
||||||
|
|||||||
@@ -39,4 +39,3 @@ import:
|
|||||||
- package: gopkg.in/throttled/throttled.v1
|
- package: gopkg.in/throttled/throttled.v1
|
||||||
subpackages:
|
subpackages:
|
||||||
- store
|
- store
|
||||||
- package: github.com/kardianos/osext
|
|
||||||
|
|||||||
@@ -1649,3 +1649,36 @@ func (c *Client) DeleteEmoji(id string) (bool, *AppError) {
|
|||||||
func (c *Client) GetCustomEmojiImageUrl(id string) string {
|
func (c *Client) GetCustomEmojiImageUrl(id string) string {
|
||||||
return c.GetEmojiRoute() + "/" + id
|
return c.GetEmojiRoute() + "/" + id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uploads a x509 base64 Certificate or Private Key file to be used with SAML.
|
||||||
|
// data byte array is required and needs to be a Multi-Part with 'certificate' as the field name
|
||||||
|
// contentType is also required. Returns nil if succesful, otherwise returns an AppError
|
||||||
|
func (c *Client) UploadCertificateFile(data []byte, contentType string) *AppError {
|
||||||
|
url := c.ApiUrl + "/admin/add_certificate"
|
||||||
|
rq, _ := http.NewRequest("POST", url, bytes.NewReader(data))
|
||||||
|
rq.Header.Set("Content-Type", contentType)
|
||||||
|
|
||||||
|
if len(c.AuthToken) > 0 {
|
||||||
|
rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rp, err := c.HttpClient.Do(rq); err != nil {
|
||||||
|
return NewLocAppError(url, "model.client.connecting.app_error", nil, err.Error())
|
||||||
|
} else if rp.StatusCode >= 300 {
|
||||||
|
return AppErrorFromJson(rp.Body)
|
||||||
|
} else {
|
||||||
|
defer closeBody(rp)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes a x509 base64 Certificate or Private Key file used with SAML.
|
||||||
|
// filename is required. Returns nil if succesful, otherwise returns an AppError
|
||||||
|
func (c *Client) RemoveCertificateFile(filename string) *AppError {
|
||||||
|
if r, err := c.DoApiPost("/admin/remove_certificate", MapToJson(map[string]string{"filename": filename})); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
defer closeBody(r)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
27
vendor/github.com/kardianos/osext/LICENSE
сгенерированный
поставляемый
27
vendor/github.com/kardianos/osext/LICENSE
сгенерированный
поставляемый
@@ -1,27 +0,0 @@
|
|||||||
Copyright (c) 2012 The Go Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
16
vendor/github.com/kardianos/osext/README.md
сгенерированный
поставляемый
16
vendor/github.com/kardianos/osext/README.md
сгенерированный
поставляемый
@@ -1,16 +0,0 @@
|
|||||||
### Extensions to the "os" package.
|
|
||||||
|
|
||||||
## Find the current Executable and ExecutableFolder.
|
|
||||||
|
|
||||||
There is sometimes utility in finding the current executable file
|
|
||||||
that is running. This can be used for upgrading the current executable
|
|
||||||
or finding resources located relative to the executable file. Both
|
|
||||||
working directory and the os.Args[0] value are arbitrary and cannot
|
|
||||||
be relied on; os.Args[0] can be "faked".
|
|
||||||
|
|
||||||
Multi-platform and supports:
|
|
||||||
* Linux
|
|
||||||
* OS X
|
|
||||||
* Windows
|
|
||||||
* Plan 9
|
|
||||||
* BSDs.
|
|
||||||
33
vendor/github.com/kardianos/osext/osext.go
сгенерированный
поставляемый
33
vendor/github.com/kardianos/osext/osext.go
сгенерированный
поставляемый
@@ -1,33 +0,0 @@
|
|||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Extensions to the standard "os" package.
|
|
||||||
package osext // import "github.com/kardianos/osext"
|
|
||||||
|
|
||||||
import "path/filepath"
|
|
||||||
|
|
||||||
var cx, ce = executableClean()
|
|
||||||
|
|
||||||
func executableClean() (string, error) {
|
|
||||||
p, err := executable()
|
|
||||||
return filepath.Clean(p), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Executable returns an absolute path that can be used to
|
|
||||||
// re-invoke the current program.
|
|
||||||
// It may not be valid after the current program exits.
|
|
||||||
func Executable() (string, error) {
|
|
||||||
return cx, ce
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns same path as Executable, returns just the folder
|
|
||||||
// path. Excludes the executable name and any trailing slash.
|
|
||||||
func ExecutableFolder() (string, error) {
|
|
||||||
p, err := Executable()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return filepath.Dir(p), nil
|
|
||||||
}
|
|
||||||
20
vendor/github.com/kardianos/osext/osext_plan9.go
сгенерированный
поставляемый
20
vendor/github.com/kardianos/osext/osext_plan9.go
сгенерированный
поставляемый
@@ -1,20 +0,0 @@
|
|||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package osext
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func executable() (string, error) {
|
|
||||||
f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
return syscall.Fd2path(int(f.Fd()))
|
|
||||||
}
|
|
||||||
36
vendor/github.com/kardianos/osext/osext_procfs.go
сгенерированный
поставляемый
36
vendor/github.com/kardianos/osext/osext_procfs.go
сгенерированный
поставляемый
@@ -1,36 +0,0 @@
|
|||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build linux netbsd solaris dragonfly
|
|
||||||
|
|
||||||
package osext
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func executable() (string, error) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "linux":
|
|
||||||
const deletedTag = " (deleted)"
|
|
||||||
execpath, err := os.Readlink("/proc/self/exe")
|
|
||||||
if err != nil {
|
|
||||||
return execpath, err
|
|
||||||
}
|
|
||||||
execpath = strings.TrimSuffix(execpath, deletedTag)
|
|
||||||
execpath = strings.TrimPrefix(execpath, deletedTag)
|
|
||||||
return execpath, nil
|
|
||||||
case "netbsd":
|
|
||||||
return os.Readlink("/proc/curproc/exe")
|
|
||||||
case "dragonfly":
|
|
||||||
return os.Readlink("/proc/curproc/file")
|
|
||||||
case "solaris":
|
|
||||||
return os.Readlink(fmt.Sprintf("/proc/%d/path/a.out", os.Getpid()))
|
|
||||||
}
|
|
||||||
return "", errors.New("ExecPath not implemented for " + runtime.GOOS)
|
|
||||||
}
|
|
||||||
126
vendor/github.com/kardianos/osext/osext_sysctl.go
сгенерированный
поставляемый
126
vendor/github.com/kardianos/osext/osext_sysctl.go
сгенерированный
поставляемый
@@ -1,126 +0,0 @@
|
|||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin freebsd openbsd
|
|
||||||
|
|
||||||
package osext
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var initCwd, initCwdErr = os.Getwd()
|
|
||||||
|
|
||||||
func executable() (string, error) {
|
|
||||||
var mib [4]int32
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "freebsd":
|
|
||||||
mib = [4]int32{1 /* CTL_KERN */, 14 /* KERN_PROC */, 12 /* KERN_PROC_PATHNAME */, -1}
|
|
||||||
case "darwin":
|
|
||||||
mib = [4]int32{1 /* CTL_KERN */, 38 /* KERN_PROCARGS */, int32(os.Getpid()), -1}
|
|
||||||
case "openbsd":
|
|
||||||
mib = [4]int32{1 /* CTL_KERN */, 55 /* KERN_PROC_ARGS */, int32(os.Getpid()), 1 /* KERN_PROC_ARGV */}
|
|
||||||
}
|
|
||||||
|
|
||||||
n := uintptr(0)
|
|
||||||
// Get length.
|
|
||||||
_, _, errNum := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
|
|
||||||
if errNum != 0 {
|
|
||||||
return "", errNum
|
|
||||||
}
|
|
||||||
if n == 0 { // This shouldn't happen.
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
buf := make([]byte, n)
|
|
||||||
_, _, errNum = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0)
|
|
||||||
if errNum != 0 {
|
|
||||||
return "", errNum
|
|
||||||
}
|
|
||||||
if n == 0 { // This shouldn't happen.
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var execPath string
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "openbsd":
|
|
||||||
// buf now contains **argv, with pointers to each of the C-style
|
|
||||||
// NULL terminated arguments.
|
|
||||||
var args []string
|
|
||||||
argv := uintptr(unsafe.Pointer(&buf[0]))
|
|
||||||
Loop:
|
|
||||||
for {
|
|
||||||
argp := *(**[1 << 20]byte)(unsafe.Pointer(argv))
|
|
||||||
if argp == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
for i := 0; uintptr(i) < n; i++ {
|
|
||||||
// we don't want the full arguments list
|
|
||||||
if string(argp[i]) == " " {
|
|
||||||
break Loop
|
|
||||||
}
|
|
||||||
if argp[i] != 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
args = append(args, string(argp[:i]))
|
|
||||||
n -= uintptr(i)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if n < unsafe.Sizeof(argv) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
argv += unsafe.Sizeof(argv)
|
|
||||||
n -= unsafe.Sizeof(argv)
|
|
||||||
}
|
|
||||||
execPath = args[0]
|
|
||||||
// There is no canonical way to get an executable path on
|
|
||||||
// OpenBSD, so check PATH in case we are called directly
|
|
||||||
if execPath[0] != '/' && execPath[0] != '.' {
|
|
||||||
execIsInPath, err := exec.LookPath(execPath)
|
|
||||||
if err == nil {
|
|
||||||
execPath = execIsInPath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
for i, v := range buf {
|
|
||||||
if v == 0 {
|
|
||||||
buf = buf[:i]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
execPath = string(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
// execPath will not be empty due to above checks.
|
|
||||||
// Try to get the absolute path if the execPath is not rooted.
|
|
||||||
if execPath[0] != '/' {
|
|
||||||
execPath, err = getAbs(execPath)
|
|
||||||
if err != nil {
|
|
||||||
return execPath, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// For darwin KERN_PROCARGS may return the path to a symlink rather than the
|
|
||||||
// actual executable.
|
|
||||||
if runtime.GOOS == "darwin" {
|
|
||||||
if execPath, err = filepath.EvalSymlinks(execPath); err != nil {
|
|
||||||
return execPath, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return execPath, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getAbs(execPath string) (string, error) {
|
|
||||||
if initCwdErr != nil {
|
|
||||||
return execPath, initCwdErr
|
|
||||||
}
|
|
||||||
// The execPath may begin with a "../" or a "./" so clean it first.
|
|
||||||
// Join the two paths, trailing and starting slashes undetermined, so use
|
|
||||||
// the generic Join function.
|
|
||||||
return filepath.Join(initCwd, filepath.Clean(execPath)), nil
|
|
||||||
}
|
|
||||||
203
vendor/github.com/kardianos/osext/osext_test.go
сгенерированный
поставляемый
203
vendor/github.com/kardianos/osext/osext_test.go
сгенерированный
поставляемый
@@ -1,203 +0,0 @@
|
|||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin linux freebsd netbsd windows openbsd
|
|
||||||
|
|
||||||
package osext
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
executableEnvVar = "OSTEST_OUTPUT_EXECUTABLE"
|
|
||||||
|
|
||||||
executableEnvValueMatch = "match"
|
|
||||||
executableEnvValueDelete = "delete"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPrintExecutable(t *testing.T) {
|
|
||||||
ef, err := Executable()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Executable failed: %v", err)
|
|
||||||
}
|
|
||||||
t.Log("Executable:", ef)
|
|
||||||
}
|
|
||||||
func TestPrintExecutableFolder(t *testing.T) {
|
|
||||||
ef, err := ExecutableFolder()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ExecutableFolder failed: %v", err)
|
|
||||||
}
|
|
||||||
t.Log("Executable Folder:", ef)
|
|
||||||
}
|
|
||||||
func TestExecutableFolder(t *testing.T) {
|
|
||||||
ef, err := ExecutableFolder()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ExecutableFolder failed: %v", err)
|
|
||||||
}
|
|
||||||
if ef[len(ef)-1] == filepath.Separator {
|
|
||||||
t.Fatal("ExecutableFolder ends with a trailing slash.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func TestExecutableMatch(t *testing.T) {
|
|
||||||
ep, err := Executable()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Executable failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// fullpath to be of the form "dir/prog".
|
|
||||||
dir := filepath.Dir(filepath.Dir(ep))
|
|
||||||
fullpath, err := filepath.Rel(dir, ep)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("filepath.Rel: %v", err)
|
|
||||||
}
|
|
||||||
// Make child start with a relative program path.
|
|
||||||
// Alter argv[0] for child to verify getting real path without argv[0].
|
|
||||||
cmd := &exec.Cmd{
|
|
||||||
Dir: dir,
|
|
||||||
Path: fullpath,
|
|
||||||
Env: []string{fmt.Sprintf("%s=%s", executableEnvVar, executableEnvValueMatch)},
|
|
||||||
}
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("exec(self) failed: %v", err)
|
|
||||||
}
|
|
||||||
outs := string(out)
|
|
||||||
if !filepath.IsAbs(outs) {
|
|
||||||
t.Fatalf("Child returned %q, want an absolute path", out)
|
|
||||||
}
|
|
||||||
if !sameFile(outs, ep) {
|
|
||||||
t.Fatalf("Child returned %q, not the same file as %q", out, ep)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExecutableDelete(t *testing.T) {
|
|
||||||
if runtime.GOOS != "linux" {
|
|
||||||
t.Skip()
|
|
||||||
}
|
|
||||||
fpath, err := Executable()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Executable failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r, w := io.Pipe()
|
|
||||||
stderrBuff := &bytes.Buffer{}
|
|
||||||
stdoutBuff := &bytes.Buffer{}
|
|
||||||
cmd := &exec.Cmd{
|
|
||||||
Path: fpath,
|
|
||||||
Env: []string{fmt.Sprintf("%s=%s", executableEnvVar, executableEnvValueDelete)},
|
|
||||||
Stdin: r,
|
|
||||||
Stderr: stderrBuff,
|
|
||||||
Stdout: stdoutBuff,
|
|
||||||
}
|
|
||||||
err = cmd.Start()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("exec(self) start failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tempPath := fpath + "_copy"
|
|
||||||
_ = os.Remove(tempPath)
|
|
||||||
|
|
||||||
err = copyFile(tempPath, fpath)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("copy file failed: %v", err)
|
|
||||||
}
|
|
||||||
err = os.Remove(fpath)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("remove running test file failed: %v", err)
|
|
||||||
}
|
|
||||||
err = os.Rename(tempPath, fpath)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("rename copy to previous name failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Write([]byte{0})
|
|
||||||
w.Close()
|
|
||||||
|
|
||||||
err = cmd.Wait()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("exec wait failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
childPath := stderrBuff.String()
|
|
||||||
if !filepath.IsAbs(childPath) {
|
|
||||||
t.Fatalf("Child returned %q, want an absolute path", childPath)
|
|
||||||
}
|
|
||||||
if !sameFile(childPath, fpath) {
|
|
||||||
t.Fatalf("Child returned %q, not the same file as %q", childPath, fpath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sameFile(fn1, fn2 string) bool {
|
|
||||||
fi1, err := os.Stat(fn1)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
fi2, err := os.Stat(fn2)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return os.SameFile(fi1, fi2)
|
|
||||||
}
|
|
||||||
func copyFile(dest, src string) error {
|
|
||||||
df, err := os.Create(dest)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer df.Close()
|
|
||||||
|
|
||||||
sf, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer sf.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(df, sf)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
|
||||||
env := os.Getenv(executableEnvVar)
|
|
||||||
switch env {
|
|
||||||
case "":
|
|
||||||
os.Exit(m.Run())
|
|
||||||
case executableEnvValueMatch:
|
|
||||||
// First chdir to another path.
|
|
||||||
dir := "/"
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
dir = filepath.VolumeName(".")
|
|
||||||
}
|
|
||||||
os.Chdir(dir)
|
|
||||||
if ep, err := Executable(); err != nil {
|
|
||||||
fmt.Fprint(os.Stderr, "ERROR: ", err)
|
|
||||||
} else {
|
|
||||||
fmt.Fprint(os.Stderr, ep)
|
|
||||||
}
|
|
||||||
case executableEnvValueDelete:
|
|
||||||
bb := make([]byte, 1)
|
|
||||||
var err error
|
|
||||||
n, err := os.Stdin.Read(bb)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprint(os.Stderr, "ERROR: ", err)
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
|
||||||
if n != 1 {
|
|
||||||
fmt.Fprint(os.Stderr, "ERROR: n != 1, n == ", n)
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
|
||||||
if ep, err := Executable(); err != nil {
|
|
||||||
fmt.Fprint(os.Stderr, "ERROR: ", err)
|
|
||||||
} else {
|
|
||||||
fmt.Fprint(os.Stderr, ep)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
34
vendor/github.com/kardianos/osext/osext_windows.go
сгенерированный
поставляемый
34
vendor/github.com/kardianos/osext/osext_windows.go
сгенерированный
поставляемый
@@ -1,34 +0,0 @@
|
|||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package osext
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unicode/utf16"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
kernel = syscall.MustLoadDLL("kernel32.dll")
|
|
||||||
getModuleFileNameProc = kernel.MustFindProc("GetModuleFileNameW")
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetModuleFileName() with hModule = NULL
|
|
||||||
func executable() (exePath string, err error) {
|
|
||||||
return getModuleFileName()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getModuleFileName() (string, error) {
|
|
||||||
var n uint32
|
|
||||||
b := make([]uint16, syscall.MAX_PATH)
|
|
||||||
size := uint32(len(b))
|
|
||||||
|
|
||||||
r0, _, e1 := getModuleFileNameProc.Call(0, uintptr(unsafe.Pointer(&b[0])), uintptr(size))
|
|
||||||
n = uint32(r0)
|
|
||||||
if n == 0 {
|
|
||||||
return "", e1
|
|
||||||
}
|
|
||||||
return string(utf16.Decode(b[0:n])), nil
|
|
||||||
}
|
|
||||||
Ссылка в новой задаче
Block a user