.
âââ command
â  âââ command.go
â  âââ command_test.go
âââ go.mod
âââ go.sum
哪里
go.mod
module github.com/kurtpeek/monkeypatching
go 1.12
require (
bou.ke/monkey v1.0.2
github.com/google/go-cmp v0.3.1 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/stretchr/testify v1.4.0
gotest.tools v2.2.0+incompatible
)
command.go
阅读
package command
import "os/exec"
// RunCommand runs a command
func RunCommand() ([]byte, error) {
return exec.Command("profiles", "list", "-all").Output()
}
和
command_test.go
package command
import (
"os/exec"
"reflect"
"testing"
"bou.ke/monkey"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRunCommand(t *testing.T) {
var cmd *exec.Cmd
patchGuard := monkey.PatchInstanceMethod(reflect.TypeOf(cmd), "Output", func(_ *exec.Cmd) ([]byte, error) {
return []byte("foobar"), nil
})
defer patchGuard.Unpatch()
output, err := RunCommand()
require.NoError(t, err)
assert.Equal(t, []byte("foobar"), output)
}
这个测试通过了。
func TestFindIdentity(t *testing.T) {
certPEM, err := ioutil.ReadFile("testdata/6dc9bf91-37c6-4882-bfaf-301f118f7fac.pem")
require.NoError(t, err)
var cmd *exec.Cmd
patchGuard := monkey.PatchInstanceMethod(reflect.TypeOf(cmd), "Output", func(_ *exec.Cmd) ([]byte, error) {
output, err := ioutil.ReadFile("testdata/find_identity_match.txt")
require.NoError(t, err)
return output, nil
})
defer patchGuard.Unpatch()
found, err := FindIdentity(certPEM)
assert.True(t, found)
}
哪里
FindIdentity()
阅读
// FindIdentity checks whether there is an identity (certificate + private key) for the given certificate in the system keychain
func FindIdentity(certPEM []byte) (bool, error) {
ctx, cancel := context.WithTimeout(context.TODO(), time.Second*5)
defer cancel()
fingerprint, err := GetFingerprint(certPEM)
if err != nil {
return false, fmt.Errorf("get cert fingerprint: %v", err)
}
output, err := exec.CommandContext(ctx, cmdSecurity, "find-identity", systemKeychain).Output()
if err != nil {
return false, fmt.Errorf("find identity: %v", err)
}
return strings.Contains(string(output), fingerprint), nil
}
// GetFingerprint generates a SHA-1 fingerprint of a certificate, which is how it can be identified from the `security` command
func GetFingerprint(certPEM []byte) (string, error) {
block, _ := pem.Decode(certPEM)
if block == nil {
return "", errors.New("failed to decode cert PEM")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return "", fmt.Errorf("parse certificate: %v", err)
}
fingerprint := fmt.Sprintf("%x", sha1.Sum(cert.Raw))
fingerprint = strings.Replace(fingerprint, " ", "", -1)
return strings.ToUpper(fingerprint), nil
}
Command
Running tool: /usr/local/opt/go@1.12/bin/go test -timeout 30s github.com/fleetsmith/agent/agent/auth/defaultauth -run ^(TestFindIdentity)$
--- FAIL: TestFindIdentity (0.00s)
panic: permission denied [recovered]
panic: permission denied
goroutine 25 [running]:
testing.tRunner.func1(0xc000494100)
/usr/local/Cellar/go@1.12/1.12.12/libexec/src/testing/testing.go:830 +0x392
panic(0x48fede0, 0xc000554730)
/usr/local/Cellar/go@1.12/1.12.12/libexec/src/runtime/panic.go:522 +0x1b5
bou.ke/monkey.mprotectCrossPage(0x41c20e0, 0xc, 0x7)
/Users/kurt/go/pkg/mod/bou.ke/monkey@v1.0.2/replace_unix.go:15 +0xe6
bou.ke/monkey.copyToLocation(0x41c20e0, 0xc0000ebd2c, 0xc, 0xc)
/Users/kurt/go/pkg/mod/bou.ke/monkey@v1.0.2/replace_unix.go:26 +0x6d
bou.ke/monkey.replaceFunction(0x41c20e0, 0xc0001a2510, 0x13, 0x41c20e0, 0x48c3b00)
/Users/kurt/go/pkg/mod/bou.ke/monkey@v1.0.2/replace.go:29 +0xe6
bou.ke/monkey.patchValue(0x48c3b60, 0xc0000bc078, 0x13, 0x48c3b60, 0xc0001a2510, 0x13)
/Users/kurt/go/pkg/mod/bou.ke/monkey@v1.0.2/monkey.go:87 +0x22f
bou.ke/monkey.PatchInstanceMethod(0x4b359a0, 0x4996280, 0x49d0699, 0x6, 0x48c3b60, 0xc0001a2510, 0x0)
/Users/kurt/go/pkg/mod/bou.ke/monkey@v1.0.2/monkey.go:62 +0x160
github.com/fleetsmith/agent/agent/auth/defaultauth.TestFindIdentity(0xc000494100)
/Users/kurt/go/src/github.com/fleetsmith/agent/agent/auth/defaultauth/keychain_test.go:46 +0x146
testing.tRunner(0xc000494100, 0x4a30260)
/usr/local/Cellar/go@1.12/1.12.12/libexec/src/testing/testing.go:865 +0xc0
created by testing.(*T).Run
/usr/local/Cellar/go@1.12/1.12.12/libexec/src/testing/testing.go:916 +0x35a
FAIL github.com/fleetsmith/agent/agent/auth/defaultauth 0.390s
Error: Tests failed.
具体来说,我得到了一个
permission denied
monkey.PatchInstanceMethod
在这一行:
patchGuard := monkey.PatchInstanceMethod(reflect.TypeOf(cmd), "Output", func(_ *exec.Cmd) ([]byte, error) {
})