mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 23:40:23 +00:00
TUN-813: Clean up cloudflared dependencies
This commit is contained in:
426
vendor/github.com/equinox-io/equinox/internal/go-update/apply_test.go
generated
vendored
426
vendor/github.com/equinox-io/equinox/internal/go-update/apply_test.go
generated
vendored
@@ -1,426 +0,0 @@
|
||||
package update
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/equinox-io/equinox/internal/go-update/internal/binarydist"
|
||||
)
|
||||
|
||||
var (
|
||||
oldFile = []byte{0xDE, 0xAD, 0xBE, 0xEF}
|
||||
newFile = []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}
|
||||
newFileChecksum = sha256.Sum256(newFile)
|
||||
)
|
||||
|
||||
func cleanup(path string) {
|
||||
os.Remove(path)
|
||||
os.Remove(fmt.Sprintf(".%s.new", path))
|
||||
}
|
||||
|
||||
// we write with a separate name for each test so that we can run them in parallel
|
||||
func writeOldFile(path string, t *testing.T) {
|
||||
if err := ioutil.WriteFile(path, oldFile, 0777); err != nil {
|
||||
t.Fatalf("Failed to write file for testing preparation: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func validateUpdate(path string, err error, t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to update: %v", err)
|
||||
}
|
||||
|
||||
buf, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file post-update: %v", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(buf, newFile) {
|
||||
t.Fatalf("File was not updated! Bytes read: %v, Bytes expected: %v", buf, newFile)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplySimple(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestApplySimple"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
err := Apply(bytes.NewReader(newFile), Options{
|
||||
TargetPath: fName,
|
||||
})
|
||||
validateUpdate(fName, err, t)
|
||||
}
|
||||
|
||||
func TestApplyOldSavePath(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestApplyOldSavePath"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
oldfName := "OldSavePath"
|
||||
|
||||
err := Apply(bytes.NewReader(newFile), Options{
|
||||
TargetPath: fName,
|
||||
OldSavePath: oldfName,
|
||||
})
|
||||
validateUpdate(fName, err, t)
|
||||
|
||||
if _, err := os.Stat(oldfName); os.IsNotExist(err) {
|
||||
t.Fatalf("Failed to find the old file: %v", err)
|
||||
}
|
||||
|
||||
cleanup(oldfName)
|
||||
}
|
||||
|
||||
func TestVerifyChecksum(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestVerifyChecksum"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
err := Apply(bytes.NewReader(newFile), Options{
|
||||
TargetPath: fName,
|
||||
Checksum: newFileChecksum[:],
|
||||
})
|
||||
validateUpdate(fName, err, t)
|
||||
}
|
||||
|
||||
func TestVerifyChecksumNegative(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestVerifyChecksumNegative"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
badChecksum := []byte{0x0A, 0x0B, 0x0C, 0xFF}
|
||||
err := Apply(bytes.NewReader(newFile), Options{
|
||||
TargetPath: fName,
|
||||
Checksum: badChecksum,
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatalf("Failed to detect bad checksum!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyPatch(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestApplyPatch"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
patch := new(bytes.Buffer)
|
||||
err := binarydist.Diff(bytes.NewReader(oldFile), bytes.NewReader(newFile), patch)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create patch: %v", err)
|
||||
}
|
||||
|
||||
err = Apply(patch, Options{
|
||||
TargetPath: fName,
|
||||
Patcher: NewBSDiffPatcher(),
|
||||
})
|
||||
validateUpdate(fName, err, t)
|
||||
}
|
||||
|
||||
func TestCorruptPatch(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestCorruptPatch"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
badPatch := []byte{0x44, 0x38, 0x86, 0x3c, 0x4f, 0x8d, 0x26, 0x54, 0xb, 0x11, 0xce, 0xfe, 0xc1, 0xc0, 0xf8, 0x31, 0x38, 0xa0, 0x12, 0x1a, 0xa2, 0x57, 0x2a, 0xe1, 0x3a, 0x48, 0x62, 0x40, 0x2b, 0x81, 0x12, 0xb1, 0x21, 0xa5, 0x16, 0xed, 0x73, 0xd6, 0x54, 0x84, 0x29, 0xa6, 0xd6, 0xb2, 0x1b, 0xfb, 0xe6, 0xbe, 0x7b, 0x70}
|
||||
err := Apply(bytes.NewReader(badPatch), Options{
|
||||
TargetPath: fName,
|
||||
Patcher: NewBSDiffPatcher(),
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatalf("Failed to detect corrupt patch!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyChecksumPatchNegative(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestVerifyChecksumPatchNegative"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
patch := new(bytes.Buffer)
|
||||
anotherFile := []byte{0x77, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}
|
||||
err := binarydist.Diff(bytes.NewReader(oldFile), bytes.NewReader(anotherFile), patch)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create patch: %v", err)
|
||||
}
|
||||
|
||||
err = Apply(patch, Options{
|
||||
TargetPath: fName,
|
||||
Checksum: newFileChecksum[:],
|
||||
Patcher: NewBSDiffPatcher(),
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatalf("Failed to detect patch to wrong file!")
|
||||
}
|
||||
}
|
||||
|
||||
const ecdsaPublicKey = `
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEL8ThbSyEucsCxnd4dCZR2hIy5nea54ko
|
||||
O+jUUfIjkvwhCWzASm0lpCVdVpXKZXIe+NZ+44RQRv3+OqJkCCGzUgJkPNI3lxdG
|
||||
9zu8rbrnxISV06VQ8No7Ei9wiTpqmTBB
|
||||
-----END PUBLIC KEY-----
|
||||
`
|
||||
|
||||
const ecdsaPrivateKey = `
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDBttCB/1NOY4T+WrG4FSV49Ayn3gK1DNzfGaJ01JUXeiNFCWQM2pqpU
|
||||
om8ATPP/dkegBwYFK4EEACKhZANiAAQvxOFtLIS5ywLGd3h0JlHaEjLmd5rniSg7
|
||||
6NRR8iOS/CEJbMBKbSWkJV1Wlcplch741n7jhFBG/f46omQIIbNSAmQ80jeXF0b3
|
||||
O7ytuufEhJXTpVDw2jsSL3CJOmqZMEE=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`
|
||||
|
||||
const rsaPublicKey = `
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxSWmu7trWKAwDFjiCN2D
|
||||
Tk2jj2sgcr/CMlI4cSSiIOHrXCFxP1I8i9PvQkd4hasXQrLbT5WXKrRGv1HKUKab
|
||||
b9ead+kD0kxk7i2bFYvKX43oq66IW0mOLTQBO7I9UyT4L7svcMD+HUQ2BqHoaQe4
|
||||
y20C59dPr9Dpcz8DZkdLsBV6YKF6Ieb3iGk8oRLMWNaUqPa8f1BGgxAkvPHcqDjT
|
||||
x4xRnjgTRRRlZvRtALHMUkIChgxDOhoEzKpGiqnX7HtMJfrhV6h0PAXNA4h9Kjv5
|
||||
5fhJ08Rz7mmZmtH5JxTK5XTquo59sihSajR4bSjZbbkQ1uLkeFlY3eli3xdQ7Nrf
|
||||
fQIDAQAB
|
||||
-----END PUBLIC KEY-----`
|
||||
|
||||
const rsaPrivateKey = `
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAxSWmu7trWKAwDFjiCN2DTk2jj2sgcr/CMlI4cSSiIOHrXCFx
|
||||
P1I8i9PvQkd4hasXQrLbT5WXKrRGv1HKUKabb9ead+kD0kxk7i2bFYvKX43oq66I
|
||||
W0mOLTQBO7I9UyT4L7svcMD+HUQ2BqHoaQe4y20C59dPr9Dpcz8DZkdLsBV6YKF6
|
||||
Ieb3iGk8oRLMWNaUqPa8f1BGgxAkvPHcqDjTx4xRnjgTRRRlZvRtALHMUkIChgxD
|
||||
OhoEzKpGiqnX7HtMJfrhV6h0PAXNA4h9Kjv55fhJ08Rz7mmZmtH5JxTK5XTquo59
|
||||
sihSajR4bSjZbbkQ1uLkeFlY3eli3xdQ7NrffQIDAQABAoIBAAkN+6RvrTR61voa
|
||||
Mvd5RQiZpEN4Bht/Fyo8gH8h0Zh1B9xJZOwlmMZLS5fdtHlfLEhR8qSrGDBL61vq
|
||||
I8KkhEsUufF78EL+YzxVN+Q7cWYGHIOWFokqza7hzpSxUQO6lPOMQ1eIZaNueJTB
|
||||
Zu07/47ISPPg/bXzgGVcpYlTCPTjUwKjtfyMqvX9AD7fIyYRm6zfE7EHj1J2sBFt
|
||||
Yz1OGELg6HfJwXfpnPfBvftD0hWGzJ78Bp71fPJe6n5gnqmSqRvrcXNWFnH/yqkN
|
||||
d6vPIxD6Z3LjvyZpkA7JillLva2L/zcIFhg4HZvQnWd8/PpDnUDonu36hcj4SC5j
|
||||
W4aVPLkCgYEA4XzNKWxqYcajzFGZeSxlRHupSAl2MT7Cc5085MmE7dd31wK2T8O4
|
||||
n7N4bkm/rjTbX85NsfWdKtWb6mpp8W3VlLP0rp4a/12OicVOkg4pv9LZDmY0sRlE
|
||||
YuDJk1FeCZ50UrwTZI3rZ9IhZHhkgVA6uWAs7tYndONkxNHG0pjqs4sCgYEA39MZ
|
||||
JwMqo3qsPntpgP940cCLflEsjS9hYNO3+Sv8Dq3P0HLVhBYajJnotf8VuU0fsQZG
|
||||
grmtVn1yThFbMq7X1oY4F0XBA+paSiU18c4YyUnwax2u4sw9U/Q9tmQUZad5+ueT
|
||||
qriMBwGv+ewO+nQxqvAsMUmemrVzrfwA5Oct+hcCgYAfiyXoNZJsOy2O15twqBVC
|
||||
j0oPGcO+/9iT89sg5lACNbI+EdMPNYIOVTzzsL1v0VUfAe08h++Enn1BPcG0VHkc
|
||||
ZFBGXTfJoXzfKQrkw7ZzbzuOGB4m6DH44xlP0oIlNlVvfX/5ASF9VJf3RiBJNsAA
|
||||
TsP6ZVr/rw/ZuL7nlxy+IQKBgDhL/HOXlE3yOQiuOec8WsNHTs7C1BXe6PtVxVxi
|
||||
988pYK/pclL6zEq5G5NLSceF4obAMVQIJ9UtUGbabrncyGUo9UrFPLsjYvprSZo8
|
||||
YHegpVwL50UcYgCP2kXZ/ldjPIcjYDz8lhvdDMor2cidGTEJn9P11HLNWP9V91Ob
|
||||
4jCZAoGAPNRSC5cC8iP/9j+s2/kdkfWJiNaolPYAUrmrkL6H39PYYZM5tnhaIYJV
|
||||
Oh9AgABamU0eb3p3vXTISClVgV7ifq1HyZ7BSUhMfaY2Jk/s3sUHCWFxPZe9sgEG
|
||||
KinIY/373KIkIV/5g4h2v1w330IWcfptxKcY/Er3DJr38f695GE=
|
||||
-----END RSA PRIVATE KEY-----`
|
||||
|
||||
func signec(privatePEM string, source []byte, t *testing.T) []byte {
|
||||
parseFn := func(p []byte) (crypto.Signer, error) { return x509.ParseECPrivateKey(p) }
|
||||
return sign(parseFn, privatePEM, source, t)
|
||||
}
|
||||
|
||||
func signrsa(privatePEM string, source []byte, t *testing.T) []byte {
|
||||
parseFn := func(p []byte) (crypto.Signer, error) { return x509.ParsePKCS1PrivateKey(p) }
|
||||
return sign(parseFn, privatePEM, source, t)
|
||||
}
|
||||
|
||||
func sign(parsePrivKey func([]byte) (crypto.Signer, error), privatePEM string, source []byte, t *testing.T) []byte {
|
||||
block, _ := pem.Decode([]byte(privatePEM))
|
||||
if block == nil {
|
||||
t.Fatalf("Failed to parse private key PEM")
|
||||
}
|
||||
|
||||
priv, err := parsePrivKey(block.Bytes)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse private key DER: %v", err)
|
||||
}
|
||||
|
||||
checksum := sha256.Sum256(source)
|
||||
sig, err := priv.Sign(rand.Reader, checksum[:], crypto.SHA256)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to sign: %v", sig)
|
||||
}
|
||||
|
||||
return sig
|
||||
}
|
||||
|
||||
func TestVerifyECSignature(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestVerifySignature"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
opts := Options{TargetPath: fName}
|
||||
err := opts.SetPublicKeyPEM([]byte(ecdsaPublicKey))
|
||||
if err != nil {
|
||||
t.Fatalf("Could not parse public key: %v", err)
|
||||
}
|
||||
|
||||
opts.Signature = signec(ecdsaPrivateKey, newFile, t)
|
||||
err = Apply(bytes.NewReader(newFile), opts)
|
||||
validateUpdate(fName, err, t)
|
||||
}
|
||||
|
||||
func TestVerifyRSASignature(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestVerifySignature"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
opts := Options{
|
||||
TargetPath: fName,
|
||||
Verifier: NewRSAVerifier(),
|
||||
}
|
||||
err := opts.SetPublicKeyPEM([]byte(rsaPublicKey))
|
||||
if err != nil {
|
||||
t.Fatalf("Could not parse public key: %v", err)
|
||||
}
|
||||
|
||||
opts.Signature = signrsa(rsaPrivateKey, newFile, t)
|
||||
err = Apply(bytes.NewReader(newFile), opts)
|
||||
validateUpdate(fName, err, t)
|
||||
}
|
||||
|
||||
func TestVerifyFailBadSignature(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestVerifyFailBadSignature"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
opts := Options{
|
||||
TargetPath: fName,
|
||||
Signature: []byte{0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA},
|
||||
}
|
||||
err := opts.SetPublicKeyPEM([]byte(ecdsaPublicKey))
|
||||
if err != nil {
|
||||
t.Fatalf("Could not parse public key: %v", err)
|
||||
}
|
||||
|
||||
err = Apply(bytes.NewReader(newFile), opts)
|
||||
if err == nil {
|
||||
t.Fatalf("Did not fail with bad signature")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyFailNoSignature(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestVerifySignatureWithPEM"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
opts := Options{TargetPath: fName}
|
||||
err := opts.SetPublicKeyPEM([]byte(ecdsaPublicKey))
|
||||
if err != nil {
|
||||
t.Fatalf("Could not parse public key: %v", err)
|
||||
}
|
||||
|
||||
err = Apply(bytes.NewReader(newFile), opts)
|
||||
if err == nil {
|
||||
t.Fatalf("Did not fail with empty signature")
|
||||
}
|
||||
}
|
||||
|
||||
const wrongKey = `
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDBzqYp6N2s8YWYifBjS03/fFfmGeIPcxQEi+bbFeekIYt8NIKIkhD+r
|
||||
hpaIwSmot+qgBwYFK4EEACKhZANiAAR0EC8Usbkc4k30frfEB2ECmsIghu9DJSqE
|
||||
RbH7jfq2ULNv8tN/clRjxf2YXgp+iP3SQF1R1EYERKpWr8I57pgfIZtoZXjwpbQC
|
||||
VBbP/Ff+05HOqwPC7rJMy1VAJLKg7Cw=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`
|
||||
|
||||
func TestVerifyFailWrongSignature(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestVerifyFailWrongSignature"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
opts := Options{TargetPath: fName}
|
||||
err := opts.SetPublicKeyPEM([]byte(ecdsaPublicKey))
|
||||
if err != nil {
|
||||
t.Fatalf("Could not parse public key: %v", err)
|
||||
}
|
||||
|
||||
opts.Signature = signec(wrongKey, newFile, t)
|
||||
err = Apply(bytes.NewReader(newFile), opts)
|
||||
if err == nil {
|
||||
t.Fatalf("Verified an update that was signed by an untrusted key!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignatureButNoPublicKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestSignatureButNoPublicKey"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
err := Apply(bytes.NewReader(newFile), Options{
|
||||
TargetPath: fName,
|
||||
Signature: signec(ecdsaPrivateKey, newFile, t),
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatalf("Allowed an update with a signautre verification when no public key was specified!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicKeyButNoSignature(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fName := "TestPublicKeyButNoSignature"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
opts := Options{TargetPath: fName}
|
||||
if err := opts.SetPublicKeyPEM([]byte(ecdsaPublicKey)); err != nil {
|
||||
t.Fatalf("Could not parse public key: %v", err)
|
||||
}
|
||||
err := Apply(bytes.NewReader(newFile), opts)
|
||||
if err == nil {
|
||||
t.Fatalf("Allowed an update with no signautre when a public key was specified!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteError(t *testing.T) {
|
||||
t.Parallel()
|
||||
fName := "TestWriteError"
|
||||
defer cleanup(fName)
|
||||
writeOldFile(fName, t)
|
||||
|
||||
openFile = func(name string, flags int, perm os.FileMode) (*os.File, error) {
|
||||
f, err := os.OpenFile(name, flags, perm)
|
||||
|
||||
// simulate Write() error by closing the file prematurely
|
||||
f.Close()
|
||||
|
||||
return f, err
|
||||
}
|
||||
|
||||
err := Apply(bytes.NewReader(newFile), Options{TargetPath: fName})
|
||||
if err == nil {
|
||||
t.Fatalf("Allowed an update to an empty file")
|
||||
}
|
||||
}
|
@@ -1,93 +0,0 @@
|
||||
package binarydist
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
func mustOpen(path string) *os.File {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func mustReadAll(r io.Reader) []byte {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func fileCmp(a, b *os.File) int64 {
|
||||
sa, err := a.Seek(0, 2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
sb, err := b.Seek(0, 2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if sa != sb {
|
||||
return sa
|
||||
}
|
||||
|
||||
_, err = a.Seek(0, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = b.Seek(0, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pa, err := ioutil.ReadAll(a)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pb, err := ioutil.ReadAll(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := range pa {
|
||||
if pa[i] != pb[i] {
|
||||
return int64(i)
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func mustWriteRandFile(path string, size int) *os.File {
|
||||
p := make([]byte, size)
|
||||
_, err := rand.Read(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = f.Write(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = f.Seek(0, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
67
vendor/github.com/equinox-io/equinox/internal/go-update/internal/binarydist/diff_test.go
generated
vendored
67
vendor/github.com/equinox-io/equinox/internal/go-update/internal/binarydist/diff_test.go
generated
vendored
@@ -1,67 +0,0 @@
|
||||
package binarydist
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var diffT = []struct {
|
||||
old *os.File
|
||||
new *os.File
|
||||
}{
|
||||
{
|
||||
old: mustWriteRandFile("test.old", 1e3),
|
||||
new: mustWriteRandFile("test.new", 1e3),
|
||||
},
|
||||
{
|
||||
old: mustOpen("testdata/sample.old"),
|
||||
new: mustOpen("testdata/sample.new"),
|
||||
},
|
||||
}
|
||||
|
||||
func TestDiff(t *testing.T) {
|
||||
for _, s := range diffT {
|
||||
got, err := ioutil.TempFile("/tmp", "bspatch.")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
os.Remove(got.Name())
|
||||
|
||||
exp, err := ioutil.TempFile("/tmp", "bspatch.")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("bsdiff", s.old.Name(), s.new.Name(), exp.Name())
|
||||
cmd.Stdout = os.Stdout
|
||||
err = cmd.Run()
|
||||
os.Remove(exp.Name())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = Diff(s.old, s.new, got)
|
||||
if err != nil {
|
||||
t.Fatal("err", err)
|
||||
}
|
||||
|
||||
_, err = got.Seek(0, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
gotBuf := mustReadAll(got)
|
||||
expBuf := mustReadAll(exp)
|
||||
|
||||
if !bytes.Equal(gotBuf, expBuf) {
|
||||
t.Fail()
|
||||
t.Logf("diff %s %s", s.old.Name(), s.new.Name())
|
||||
t.Logf("%s: len(got) = %d", got.Name(), len(gotBuf))
|
||||
t.Logf("%s: len(exp) = %d", exp.Name(), len(expBuf))
|
||||
i := matchlen(gotBuf, expBuf)
|
||||
t.Logf("produced different output at pos %d; %d != %d", i, gotBuf[i], expBuf[i])
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,62 +0,0 @@
|
||||
package binarydist
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPatch(t *testing.T) {
|
||||
mustWriteRandFile("test.old", 1e3)
|
||||
mustWriteRandFile("test.new", 1e3)
|
||||
|
||||
got, err := ioutil.TempFile("/tmp", "bspatch.")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
os.Remove(got.Name())
|
||||
|
||||
err = exec.Command("bsdiff", "test.old", "test.new", "test.patch").Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = Patch(mustOpen("test.old"), got, mustOpen("test.patch"))
|
||||
if err != nil {
|
||||
t.Fatal("err", err)
|
||||
}
|
||||
|
||||
ref, err := got.Seek(0, 2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
t.Logf("got %d bytes", ref)
|
||||
if n := fileCmp(got, mustOpen("test.new")); n > -1 {
|
||||
t.Fatalf("produced different output at pos %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPatchHk(t *testing.T) {
|
||||
got, err := ioutil.TempFile("/tmp", "bspatch.")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
os.Remove(got.Name())
|
||||
|
||||
err = Patch(mustOpen("testdata/sample.old"), got, mustOpen("testdata/sample.patch"))
|
||||
if err != nil {
|
||||
t.Fatal("err", err)
|
||||
}
|
||||
|
||||
ref, err := got.Seek(0, 2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
t.Logf("got %d bytes", ref)
|
||||
if n := fileCmp(got, mustOpen("testdata/sample.new")); n > -1 {
|
||||
t.Fatalf("produced different output at pos %d", n)
|
||||
}
|
||||
}
|
33
vendor/github.com/equinox-io/equinox/internal/go-update/internal/binarydist/sort_test.go
generated
vendored
33
vendor/github.com/equinox-io/equinox/internal/go-update/internal/binarydist/sort_test.go
generated
vendored
@@ -1,33 +0,0 @@
|
||||
package binarydist
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var sortT = [][]byte{
|
||||
mustRandBytes(1000),
|
||||
mustReadAll(mustOpen("test.old")),
|
||||
[]byte("abcdefabcdef"),
|
||||
}
|
||||
|
||||
func TestQsufsort(t *testing.T) {
|
||||
for _, s := range sortT {
|
||||
I := qsufsort(s)
|
||||
for i := 1; i < len(I); i++ {
|
||||
if bytes.Compare(s[I[i-1]:], s[I[i]:]) > 0 {
|
||||
t.Fatalf("unsorted at %d", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mustRandBytes(n int) []byte {
|
||||
b := make([]byte, n)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
203
vendor/github.com/equinox-io/equinox/internal/go-update/internal/osext/osext_test.go
generated
vendored
203
vendor/github.com/equinox-io/equinox/internal/go-update/internal/osext/osext_test.go
generated
vendored
@@ -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
|
||||
|
||||
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)
|
||||
}
|
203
vendor/github.com/equinox-io/equinox/internal/osext/osext_test.go
generated
vendored
203
vendor/github.com/equinox-io/equinox/internal/osext/osext_test.go
generated
vendored
@@ -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
|
||||
|
||||
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)
|
||||
}
|
183
vendor/github.com/equinox-io/equinox/sdk_test.go
generated
vendored
183
vendor/github.com/equinox-io/equinox/sdk_test.go
generated
vendored
@@ -1,183 +0,0 @@
|
||||
package equinox
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/equinox-io/equinox/proto"
|
||||
)
|
||||
|
||||
const fakeAppID = "fake_app_id"
|
||||
|
||||
var (
|
||||
fakeBinary = []byte{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}
|
||||
newFakeBinary = []byte{0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2}
|
||||
ts *httptest.Server
|
||||
key *ecdsa.PrivateKey
|
||||
sha string
|
||||
newSHA string
|
||||
signature string
|
||||
)
|
||||
|
||||
func init() {
|
||||
shaBytes := sha256.Sum256(fakeBinary)
|
||||
sha = hex.EncodeToString(shaBytes[:])
|
||||
newSHABytes := sha256.Sum256(newFakeBinary)
|
||||
newSHA = hex.EncodeToString(newSHABytes[:])
|
||||
|
||||
var err error
|
||||
key, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to generate ecdsa key: %v", err))
|
||||
}
|
||||
sig, err := key.Sign(rand.Reader, newSHABytes[:], nil)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to sign new binary: %v", err))
|
||||
}
|
||||
signature = hex.EncodeToString(sig)
|
||||
}
|
||||
|
||||
func TestNotAvailable(t *testing.T) {
|
||||
opts := setup(t, "TestNotAvailable", proto.Response{
|
||||
Available: false,
|
||||
})
|
||||
defer cleanup(opts)
|
||||
|
||||
_, err := Check(fakeAppID, opts)
|
||||
if err != NotAvailableErr {
|
||||
t.Fatalf("Expected not available error, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEndToEnd(t *testing.T) {
|
||||
opts := setup(t, "TestEndtoEnd", proto.Response{
|
||||
Available: true,
|
||||
Release: proto.Release{
|
||||
Version: "0.1.2.3",
|
||||
Title: "Release Title",
|
||||
Description: "Release Description",
|
||||
CreateDate: time.Now(),
|
||||
},
|
||||
Checksum: newSHA,
|
||||
Signature: signature,
|
||||
})
|
||||
defer cleanup(opts)
|
||||
|
||||
resp, err := Check(fakeAppID, opts)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed check: %v", err)
|
||||
}
|
||||
err = resp.Apply()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed apply: %v", err)
|
||||
}
|
||||
|
||||
buf, err := ioutil.ReadFile(opts.TargetPath)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
if !bytes.Equal(buf, newFakeBinary) {
|
||||
t.Fatalf("Binary did not update to new expected value. Got %v, expected %v", buf, newFakeBinary)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidPatch(t *testing.T) {
|
||||
opts := setup(t, "TestInavlidPatch", proto.Response{
|
||||
Available: true,
|
||||
Release: proto.Release{
|
||||
Version: "0.1.2.3",
|
||||
Title: "Release Title",
|
||||
Description: "Release Description",
|
||||
CreateDate: time.Now(),
|
||||
},
|
||||
DownloadURL: "bad-request",
|
||||
Checksum: newSHA,
|
||||
Signature: signature,
|
||||
Patch: proto.PatchBSDiff,
|
||||
})
|
||||
defer cleanup(opts)
|
||||
|
||||
resp, err := Check(fakeAppID, opts)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed check: %v", err)
|
||||
}
|
||||
err = resp.Apply()
|
||||
if err == nil {
|
||||
t.Fatalf("Apply succeeded")
|
||||
}
|
||||
if err.Error() != "error downloading patch: bad-request" {
|
||||
t.Fatalf("Expected a different error message: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func setup(t *testing.T, name string, resp proto.Response) Options {
|
||||
checkUserAgent := func(req *http.Request) {
|
||||
if req.Header.Get("User-Agent") != userAgent {
|
||||
t.Errorf("Expected user agent to be %s, not %s", userAgent, req.Header.Get("User-Agent"))
|
||||
}
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/check", func(w http.ResponseWriter, r *http.Request) {
|
||||
checkUserAgent(r)
|
||||
var req proto.Request
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to decode proto request: %v", err)
|
||||
}
|
||||
if resp.Available {
|
||||
if req.AppID != fakeAppID {
|
||||
t.Fatalf("Unexpected app ID. Got %v, expected %v", err)
|
||||
}
|
||||
if req.CurrentSHA256 != sha {
|
||||
t.Fatalf("Unexpected request SHA: %v", sha)
|
||||
}
|
||||
}
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
})
|
||||
|
||||
// Keying off the download URL may not be the best idea...
|
||||
if resp.DownloadURL == "bad-request" {
|
||||
mux.HandleFunc("/bin", func(w http.ResponseWriter, r *http.Request) {
|
||||
checkUserAgent(r)
|
||||
http.Error(w, "bad-request", http.StatusBadRequest)
|
||||
})
|
||||
} else {
|
||||
mux.HandleFunc("/bin", func(w http.ResponseWriter, r *http.Request) {
|
||||
checkUserAgent(r)
|
||||
w.Write(newFakeBinary)
|
||||
})
|
||||
}
|
||||
|
||||
ts = httptest.NewServer(mux)
|
||||
resp.DownloadURL = ts.URL + "/bin"
|
||||
|
||||
var opts Options
|
||||
opts.CheckURL = ts.URL + "/check"
|
||||
opts.PublicKey = key.Public()
|
||||
|
||||
if name != "" {
|
||||
opts.TargetPath = name
|
||||
ioutil.WriteFile(name, fakeBinary, 0644)
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func cleanup(opts Options) {
|
||||
if opts.TargetPath != "" {
|
||||
os.Remove(opts.TargetPath)
|
||||
}
|
||||
ts.Close()
|
||||
}
|
Reference in New Issue
Block a user