<commit_before>package spec

import (
	"tritium/src/tritium/packager"
	tp "athena/src/athena/proto"
	. "tritium/src/tritium"
	. "path/filepath"
	"tritium/src/tritium/shark"
	. "fmt"
	l4g "log4go"
	"os"
	"runtime/debug"
)

func All(directory string, options ...string) {

	var mixerPath string
	if len(options) == 1 {
		mixerPath = options[0]
	}

	logger := make(l4g.Logger)
	logger.AddFilter("test", l4g.ERROR, l4g.NewConsoleLogWriter())
	l4g.Global = logger
	eng := shark.NewEngine(logger)

	var pkg *tp.Package

	if len(mixerPath) > 0 {
		// Used when testing in ambrosia
		mixer := tp.OpenMixer(mixerPath)
		pkg = mixer.Package
	} else {
		bigPackage := packager.BuildDefaultPackage()
		pkg = bigPackage.Package
	}

	globalResult := NewResult()
	globalResult.all(directory, pkg, eng, logger)

	logger.AddFilter("stdout", l4g.ERROR, l4g.NewConsoleLogWriter())

	// TODO : Walk over the results here and print errors.

	for _, error := range globalResult.Errors {
		println("\n=========================================", error.Location, "\n")
		if error.Panic {
			Printf(error.Message)
		} else {
			Printf("\n==========\n%v :: %v \n\n Got \n----------\n%v\n\n Expected \n----------\n%v\n", error.Name, error.Message, error.Got, error.Expected)
		}
	}
	println("\n\n")
	println("+++TEST COMPLETE+++\n\n")
}

func (result *Result) all(directory string, pkg *tp.Package, eng Engine, logger l4g.Logger) {
	_, err := Glob(Join(directory, "main.ts"))

	if err == nil {
		newResult := RunSpec(directory, pkg, eng, logger)
		result.Merge(newResult)
	}
	subdirs, _ := Glob(Join(directory, "*"))
	for _, subdir := range subdirs {
		result.all(subdir, pkg, eng, logger)
	}
}

func RunSpec(dir string, pkg *tp.Package, eng Engine, logger l4g.Logger) (result *Result) {
	result = NewResult()
	logWriter := NewTestLogWriter()
	logger["test"] = &l4g.Filter{l4g.WARNING, "test", logWriter}

	defer func() {
		//log.Println("done")  // Println executes normally even in there is a panic
		if x := recover(); x != nil {
			err, ok := x.(os.Error)
			if ok {
				logger.Error(dir + " === " + err.String() + "\n\n" + string(debug.Stack()))
			} else {
				logger.Error(dir + " === " + x.(string) + "\n\n" + string(debug.Stack()))
			}

		}
		for _, rec := range logWriter.Logs {
			//println("HAZ LOGS")
			error := l4g.FormatLogRecord("[%D %T] [%L] (%S) %M", rec)
			result.Error(dir, error)
		}
		print(result.CharStatus())
	}()
	spec, err := LoadSpec(dir, pkg)
	if err != nil {
		result.Error(dir, err.String())
	} else {
		result.Merge(spec.Compare(eng.Run(spec.Script, spec.Input, spec.Vars)))
	}
	return
}
<commit_msg>Return non-zero code if not all tests pass<commit_after>package spec

import (
	"tritium/src/tritium/packager"
	tp "athena/src/athena/proto"
	. "tritium/src/tritium"
	. "path/filepath"
	"tritium/src/tritium/shark"
	. "fmt"
	l4g "log4go"
	"os"
	"runtime/debug"
)

func All(directory string, options ...string) {

	var mixerPath string
	if len(options) == 1 {
		mixerPath = options[0]
	}

	logger := make(l4g.Logger)
	logger.AddFilter("test", l4g.ERROR, l4g.NewConsoleLogWriter())
	l4g.Global = logger
	eng := shark.NewEngine(logger)

	var pkg *tp.Package

	if len(mixerPath) > 0 {
		// Used when testing in ambrosia
		mixer := tp.OpenMixer(mixerPath)
		pkg = mixer.Package
	} else {
		bigPackage := packager.BuildDefaultPackage()
		pkg = bigPackage.Package
	}

	globalResult := NewResult()
	globalResult.all(directory, pkg, eng, logger)

	logger.AddFilter("stdout", l4g.ERROR, l4g.NewConsoleLogWriter())

	// TODO : Walk over the results here and print errors.

	var foundError = false

	for _, error := range globalResult.Errors {
		foundError = true
		println("\n=========================================", error.Location, "\n")
		if error.Panic {
			Printf(error.Message)
		} else {
			Printf("\n==========\n%v :: %v \n\n Got \n----------\n%v\n\n Expected \n----------\n%v\n", error.Name, error.Message, error.Got, error.Expected)
		}
	}
	println("\n\n")
	println("+++TEST COMPLETE+++\n\n")

	if foundError {
		os.Exit(1)
	}
}

func (result *Result) all(directory string, pkg *tp.Package, eng Engine, logger l4g.Logger) {
	_, err := Glob(Join(directory, "main.ts"))

	if err == nil {
		newResult := RunSpec(directory, pkg, eng, logger)
		result.Merge(newResult)
	}
	subdirs, _ := Glob(Join(directory, "*"))
	for _, subdir := range subdirs {
		result.all(subdir, pkg, eng, logger)
	}
}

func RunSpec(dir string, pkg *tp.Package, eng Engine, logger l4g.Logger) (result *Result) {
	result = NewResult()
	logWriter := NewTestLogWriter()
	logger["test"] = &l4g.Filter{l4g.WARNING, "test", logWriter}

	defer func() {
		//log.Println("done")  // Println executes normally even in there is a panic
		if x := recover(); x != nil {
			err, ok := x.(os.Error)
			if ok {
				logger.Error(dir + " === " + err.String() + "\n\n" + string(debug.Stack()))
			} else {
				logger.Error(dir + " === " + x.(string) + "\n\n" + string(debug.Stack()))
			}

		}
		for _, rec := range logWriter.Logs {
			//println("HAZ LOGS")
			error := l4g.FormatLogRecord("[%D %T] [%L] (%S) %M", rec)
			result.Error(dir, error)
		}
		print(result.CharStatus())
	}()
	spec, err := LoadSpec(dir, pkg)
	if err != nil {
		result.Error(dir, err.String())
	} else {
		result.Merge(spec.Compare(eng.Run(spec.Script, spec.Input, spec.Vars)))
	}
	return
}
<|endoftext|>


<commit_before>// Copyright 2011 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 packet

import (
	"bytes"
	"crypto/cipher"
	"crypto/dsa"
	"crypto/openpgp/elgamal"
	error_ "crypto/openpgp/error"
	"crypto/openpgp/s2k"
	"crypto/rsa"
	"crypto/sha1"
	"io"
	"io/ioutil"
	"math/big"
	"strconv"
)

// PrivateKey represents a possibly encrypted private key. See RFC 4880,
// section 5.5.3.
type PrivateKey struct {
	PublicKey
	Encrypted     bool // if true then the private key is unavailable until Decrypt has been called.
	encryptedData []byte
	cipher        CipherFunction
	s2k           func(out, in []byte)
	PrivateKey    interface{} // An *rsa.PrivateKey.
	sha1Checksum  bool
	iv            []byte
}

func NewRSAPrivateKey(currentTimeSecs uint32, priv *rsa.PrivateKey, isSubkey bool) *PrivateKey {
	pk := new(PrivateKey)
	pk.PublicKey = *NewRSAPublicKey(currentTimeSecs, &priv.PublicKey, isSubkey)
	pk.PrivateKey = priv
	return pk
}

func (pk *PrivateKey) parse(r io.Reader) (err error) {
	err = (&pk.PublicKey).parse(r)
	if err != nil {
		return
	}
	var buf [1]byte
	_, err = readFull(r, buf[:])
	if err != nil {
		return
	}

	s2kType := buf[0]

	switch s2kType {
	case 0:
		pk.s2k = nil
		pk.Encrypted = false
	case 254, 255:
		_, err = readFull(r, buf[:])
		if err != nil {
			return
		}
		pk.cipher = CipherFunction(buf[0])
		pk.Encrypted = true
		pk.s2k, err = s2k.Parse(r)
		if err != nil {
			return
		}
		if s2kType == 254 {
			pk.sha1Checksum = true
		}
	default:
		return error_.UnsupportedError("deprecated s2k function in private key")
	}

	if pk.Encrypted {
		blockSize := pk.cipher.blockSize()
		if blockSize == 0 {
			return error_.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
		}
		pk.iv = make([]byte, blockSize)
		_, err = readFull(r, pk.iv)
		if err != nil {
			return
		}
	}

	pk.encryptedData, err = ioutil.ReadAll(r)
	if err != nil {
		return
	}

	if !pk.Encrypted {
		return pk.parsePrivateKey(pk.encryptedData)
	}

	return
}

func mod64kHash(d []byte) uint16 {
	h := uint16(0)
	for i := 0; i < len(d); i += 2 {
		v := uint16(d[i]) << 8
		if i+1 < len(d) {
			v += uint16(d[i+1])
		}
		h += v
	}
	return h
}

func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
	// TODO(agl): support encrypted private keys
	buf := bytes.NewBuffer(nil)
	err = pk.PublicKey.serializeWithoutHeaders(buf)
	if err != nil {
		return
	}
	buf.WriteByte(0 /* no encryption */ )

	privateKeyBuf := bytes.NewBuffer(nil)

	switch priv := pk.PrivateKey.(type) {
	case *rsa.PrivateKey:
		err = serializeRSAPrivateKey(privateKeyBuf, priv)
	default:
		err = error_.InvalidArgumentError("non-RSA private key")
	}
	if err != nil {
		return
	}

	ptype := packetTypePrivateKey
	contents := buf.Bytes()
	privateKeyBytes := privateKeyBuf.Bytes()
	if pk.IsSubkey {
		ptype = packetTypePrivateSubkey
	}
	err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
	if err != nil {
		return
	}
	_, err = w.Write(contents)
	if err != nil {
		return
	}
	_, err = w.Write(privateKeyBytes)
	if err != nil {
		return
	}

	checksum := mod64kHash(privateKeyBytes)
	var checksumBytes [2]byte
	checksumBytes[0] = byte(checksum >> 8)
	checksumBytes[1] = byte(checksum)
	_, err = w.Write(checksumBytes[:])

	return
}

func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
	err := writeBig(w, priv.D)
	if err != nil {
		return err
	}
	err = writeBig(w, priv.Primes[1])
	if err != nil {
		return err
	}
	err = writeBig(w, priv.Primes[0])
	if err != nil {
		return err
	}
	return writeBig(w, priv.Precomputed.Qinv)
}

// Decrypt decrypts an encrypted private key using a passphrase.
func (pk *PrivateKey) Decrypt(passphrase []byte) error {
	if !pk.Encrypted {
		return nil
	}

	key := make([]byte, pk.cipher.KeySize())
	pk.s2k(key, passphrase)
	block := pk.cipher.new(key)
	cfb := cipher.NewCFBDecrypter(block, pk.iv)

	data := pk.encryptedData
	cfb.XORKeyStream(data, data)

	if pk.sha1Checksum {
		if len(data) < sha1.Size {
			return error_.StructuralError("truncated private key data")
		}
		h := sha1.New()
		h.Write(data[:len(data)-sha1.Size])
		sum := h.Sum()
		if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
			return error_.StructuralError("private key checksum failure")
		}
		data = data[:len(data)-sha1.Size]
	} else {
		if len(data) < 2 {
			return error_.StructuralError("truncated private key data")
		}
		var sum uint16
		for i := 0; i < len(data)-2; i++ {
			sum += uint16(data[i])
		}
		if data[len(data)-2] != uint8(sum>>8) ||
			data[len(data)-1] != uint8(sum) {
			return error_.StructuralError("private key checksum failure")
		}
		data = data[:len(data)-2]
	}

	return pk.parsePrivateKey(data)
}

func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
	switch pk.PublicKey.PubKeyAlgo {
	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
		return pk.parseRSAPrivateKey(data)
	case PubKeyAlgoDSA:
		return pk.parseDSAPrivateKey(data)
	case PubKeyAlgoElGamal:
		return pk.parseElGamalPrivateKey(data)
	}
	panic("impossible")
}

func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
	rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
	rsaPriv := new(rsa.PrivateKey)
	rsaPriv.PublicKey = *rsaPub

	buf := bytes.NewBuffer(data)
	d, _, err := readMPI(buf)
	if err != nil {
		return
	}
	p, _, err := readMPI(buf)
	if err != nil {
		return
	}
	q, _, err := readMPI(buf)
	if err != nil {
		return
	}

	rsaPriv.D = new(big.Int).SetBytes(d)
	rsaPriv.Primes = make([]*big.Int, 2)
	rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
	rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
	rsaPriv.Precompute()
	pk.PrivateKey = rsaPriv
	pk.Encrypted = false
	pk.encryptedData = nil

	return nil
}

func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
	dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
	dsaPriv := new(dsa.PrivateKey)
	dsaPriv.PublicKey = *dsaPub

	buf := bytes.NewBuffer(data)
	x, _, err := readMPI(buf)
	if err != nil {
		return
	}

	dsaPriv.X = new(big.Int).SetBytes(x)
	pk.PrivateKey = dsaPriv
	pk.Encrypted = false
	pk.encryptedData = nil

	return nil
}

func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
	pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
	priv := new(elgamal.PrivateKey)
	priv.PublicKey = *pub

	buf := bytes.NewBuffer(data)
	x, _, err := readMPI(buf)
	if err != nil {
		return
	}

	priv.X = new(big.Int).SetBytes(x)
	pk.PrivateKey = priv
	pk.Encrypted = false
	pk.encryptedData = nil

	return nil
}
<commit_msg>crypto/openpgp/packet: fix private key checksum<commit_after>// Copyright 2011 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 packet

import (
	"bytes"
	"crypto/cipher"
	"crypto/dsa"
	"crypto/openpgp/elgamal"
	error_ "crypto/openpgp/error"
	"crypto/openpgp/s2k"
	"crypto/rsa"
	"crypto/sha1"
	"io"
	"io/ioutil"
	"math/big"
	"strconv"
)

// PrivateKey represents a possibly encrypted private key. See RFC 4880,
// section 5.5.3.
type PrivateKey struct {
	PublicKey
	Encrypted     bool // if true then the private key is unavailable until Decrypt has been called.
	encryptedData []byte
	cipher        CipherFunction
	s2k           func(out, in []byte)
	PrivateKey    interface{} // An *rsa.PrivateKey.
	sha1Checksum  bool
	iv            []byte
}

func NewRSAPrivateKey(currentTimeSecs uint32, priv *rsa.PrivateKey, isSubkey bool) *PrivateKey {
	pk := new(PrivateKey)
	pk.PublicKey = *NewRSAPublicKey(currentTimeSecs, &priv.PublicKey, isSubkey)
	pk.PrivateKey = priv
	return pk
}

func (pk *PrivateKey) parse(r io.Reader) (err error) {
	err = (&pk.PublicKey).parse(r)
	if err != nil {
		return
	}
	var buf [1]byte
	_, err = readFull(r, buf[:])
	if err != nil {
		return
	}

	s2kType := buf[0]

	switch s2kType {
	case 0:
		pk.s2k = nil
		pk.Encrypted = false
	case 254, 255:
		_, err = readFull(r, buf[:])
		if err != nil {
			return
		}
		pk.cipher = CipherFunction(buf[0])
		pk.Encrypted = true
		pk.s2k, err = s2k.Parse(r)
		if err != nil {
			return
		}
		if s2kType == 254 {
			pk.sha1Checksum = true
		}
	default:
		return error_.UnsupportedError("deprecated s2k function in private key")
	}

	if pk.Encrypted {
		blockSize := pk.cipher.blockSize()
		if blockSize == 0 {
			return error_.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
		}
		pk.iv = make([]byte, blockSize)
		_, err = readFull(r, pk.iv)
		if err != nil {
			return
		}
	}

	pk.encryptedData, err = ioutil.ReadAll(r)
	if err != nil {
		return
	}

	if !pk.Encrypted {
		return pk.parsePrivateKey(pk.encryptedData)
	}

	return
}

func mod64kHash(d []byte) uint16 {
	var h uint16
	for _, b := range d {
		h += uint16(b)
	}
	return h
}

func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
	// TODO(agl): support encrypted private keys
	buf := bytes.NewBuffer(nil)
	err = pk.PublicKey.serializeWithoutHeaders(buf)
	if err != nil {
		return
	}
	buf.WriteByte(0 /* no encryption */ )

	privateKeyBuf := bytes.NewBuffer(nil)

	switch priv := pk.PrivateKey.(type) {
	case *rsa.PrivateKey:
		err = serializeRSAPrivateKey(privateKeyBuf, priv)
	default:
		err = error_.InvalidArgumentError("non-RSA private key")
	}
	if err != nil {
		return
	}

	ptype := packetTypePrivateKey
	contents := buf.Bytes()
	privateKeyBytes := privateKeyBuf.Bytes()
	if pk.IsSubkey {
		ptype = packetTypePrivateSubkey
	}
	err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
	if err != nil {
		return
	}
	_, err = w.Write(contents)
	if err != nil {
		return
	}
	_, err = w.Write(privateKeyBytes)
	if err != nil {
		return
	}

	checksum := mod64kHash(privateKeyBytes)
	var checksumBytes [2]byte
	checksumBytes[0] = byte(checksum >> 8)
	checksumBytes[1] = byte(checksum)
	_, err = w.Write(checksumBytes[:])

	return
}

func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
	err := writeBig(w, priv.D)
	if err != nil {
		return err
	}
	err = writeBig(w, priv.Primes[1])
	if err != nil {
		return err
	}
	err = writeBig(w, priv.Primes[0])
	if err != nil {
		return err
	}
	return writeBig(w, priv.Precomputed.Qinv)
}

// Decrypt decrypts an encrypted private key using a passphrase.
func (pk *PrivateKey) Decrypt(passphrase []byte) error {
	if !pk.Encrypted {
		return nil
	}

	key := make([]byte, pk.cipher.KeySize())
	pk.s2k(key, passphrase)
	block := pk.cipher.new(key)
	cfb := cipher.NewCFBDecrypter(block, pk.iv)

	data := pk.encryptedData
	cfb.XORKeyStream(data, data)

	if pk.sha1Checksum {
		if len(data) < sha1.Size {
			return error_.StructuralError("truncated private key data")
		}
		h := sha1.New()
		h.Write(data[:len(data)-sha1.Size])
		sum := h.Sum()
		if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
			return error_.StructuralError("private key checksum failure")
		}
		data = data[:len(data)-sha1.Size]
	} else {
		if len(data) < 2 {
			return error_.StructuralError("truncated private key data")
		}
		var sum uint16
		for i := 0; i < len(data)-2; i++ {
			sum += uint16(data[i])
		}
		if data[len(data)-2] != uint8(sum>>8) ||
			data[len(data)-1] != uint8(sum) {
			return error_.StructuralError("private key checksum failure")
		}
		data = data[:len(data)-2]
	}

	return pk.parsePrivateKey(data)
}

func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
	switch pk.PublicKey.PubKeyAlgo {
	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
		return pk.parseRSAPrivateKey(data)
	case PubKeyAlgoDSA:
		return pk.parseDSAPrivateKey(data)
	case PubKeyAlgoElGamal:
		return pk.parseElGamalPrivateKey(data)
	}
	panic("impossible")
}

func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
	rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
	rsaPriv := new(rsa.PrivateKey)
	rsaPriv.PublicKey = *rsaPub

	buf := bytes.NewBuffer(data)
	d, _, err := readMPI(buf)
	if err != nil {
		return
	}
	p, _, err := readMPI(buf)
	if err != nil {
		return
	}
	q, _, err := readMPI(buf)
	if err != nil {
		return
	}

	rsaPriv.D = new(big.Int).SetBytes(d)
	rsaPriv.Primes = make([]*big.Int, 2)
	rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
	rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
	rsaPriv.Precompute()
	pk.PrivateKey = rsaPriv
	pk.Encrypted = false
	pk.encryptedData = nil

	return nil
}

func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
	dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
	dsaPriv := new(dsa.PrivateKey)
	dsaPriv.PublicKey = *dsaPub

	buf := bytes.NewBuffer(data)
	x, _, err := readMPI(buf)
	if err != nil {
		return
	}

	dsaPriv.X = new(big.Int).SetBytes(x)
	pk.PrivateKey = dsaPriv
	pk.Encrypted = false
	pk.encryptedData = nil

	return nil
}

func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
	pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
	priv := new(elgamal.PrivateKey)
	priv.PublicKey = *pub

	buf := bytes.NewBuffer(data)
	x, _, err := readMPI(buf)
	if err != nil {
		return
	}

	priv.X = new(big.Int).SetBytes(x)
	pk.PrivateKey = priv
	pk.Encrypted = false
	pk.encryptedData = nil

	return nil
}
<|endoftext|>


<commit_before>// +build darwin

package fuse_test

import (
	"fmt"
	"os"
	"path/filepath"
	"testing"
	"time"

	pfsclient "github.com/pachyderm/pachyderm/src/client/pfs"
	"github.com/pachyderm/pachyderm/src/client/pkg/require"
)

/* This file mirrors `filesystem_seek_test.go`, but changes the expected
 * values to expect errors. Mac doesn't support the seek disallow flag,
 * and so these tests should fail. In the places I changed the expected
 * values, I added a comment with the string 'MAC OS X BEHAVIOR'
 */

func TestSeekRead(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipped because of short mode")
	}

	testFuse(t, func(apiClient pfsclient.APIClient, mountpoint string) {
		repo := "test"
		require.NoError(t, pfsclient.CreateRepo(apiClient, repo))
		commit, err := pfsclient.StartCommit(apiClient, repo, "", "")
		require.NoError(t, err)
		path := filepath.Join(mountpoint, repo, commit.ID, "file")
		file, err := os.Create(path)
		require.NoError(t, err)
		_, err = file.Write([]byte("foobarbaz"))

		require.NoError(t, err)
		require.NoError(t, file.Close())
		require.NoError(t, pfsclient.FinishCommit(apiClient, repo, commit.ID))

		fmt.Printf("==== Finished commit\n")

		file, err = os.Open(path)
		defer file.Close()
		require.NoError(t, err)

		word1 := make([]byte, 3)
		n1, err := file.Read(word1)
		require.NoError(t, err)
		require.Equal(t, 3, n1)
		require.Equal(t, "foo", string(word1))

		fmt.Printf("==== %v - Read word len %v : %v\n", time.Now(), n1, string(word1))

		offset, err := file.Seek(6, 0)
		fmt.Printf("==== %v - err (%v)\n", time.Now(), err)

		fmt.Printf("==== %v - offset (%v)\n", time.Now(), offset)

		// MAC OS X BEHAVIOR - it allows seek
		require.NoError(t, err)
		require.Equal(t, int64(6), offset)

		fmt.Printf("==== Seeked to %v\n", offset)

		/* Leaving in place so the test's intention is clear / for repro'ing manually for mac */

		word2 := make([]byte, 3)
		n2, err := file.Read(word2)
		require.NoError(t, err)
		require.Equal(t, 3, n2)
		require.Equal(t, "baz", string(word2))

		fmt.Printf("==== Read word len %v : %v\n", n2, string(word2))

	})
}

func TestSeekWriteGap(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipped because of short mode")
	}

	testFuse(t, func(apiClient pfsclient.APIClient, mountpoint string) {
		repo := "test"
		require.NoError(t, pfsclient.CreateRepo(apiClient, repo))
		commit, err := pfsclient.StartCommit(apiClient, repo, "", "")
		require.NoError(t, err)
		path := filepath.Join(mountpoint, repo, commit.ID, "file")
		file, err := os.Create(path)
		require.NoError(t, err)
		defer func() {
			// MAC OS X BEHAVIOR - it allows seek, but this is an invalid write
			require.YesError(t, file.Close())
		}()

		_, err = file.Write([]byte("foo"))
		require.NoError(t, err)

		err = file.Sync()
		require.NoError(t, err)

		offset, err := file.Seek(6, 0)

		fmt.Printf("==== %v - err (%v)\n", time.Now(), err)
		fmt.Printf("==== %v - offset (%v)\n", time.Now(), offset)

		// MAC OS X BEHAVIOR - it allows seek
		require.NoError(t, err)
		require.Equal(t, int64(6), offset)

		/* Leaving in place so the test's intention is clear / for repro'ing manually for mac */

		err = file.Sync()
		require.NoError(t, err)

		n1, err := file.Write([]byte("baz"))

		// MAC OS X BEHAVIOR - it allows seek
		require.NoError(t, err)
		require.Equal(t, 3, n1)

		require.NoError(t, pfsclient.FinishCommit(apiClient, repo, commit.ID))
	})
}

func TestSeekWriteBackwards(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipped because of short mode")
	}

	testFuse(t, func(apiClient pfsclient.APIClient, mountpoint string) {
		repo := "test"
		require.NoError(t, pfsclient.CreateRepo(apiClient, repo))
		commit, err := pfsclient.StartCommit(apiClient, repo, "", "")
		require.NoError(t, err)
		path := filepath.Join(mountpoint, repo, commit.ID, "file")
		file, err := os.Create(path)
		require.NoError(t, err)
		defer func() {
			// MAC OS X BEHAVIOR - it allows seek but this is an invalid write
			require.YesError(t, file.Close())
		}()

		_, err = file.Write([]byte("foofoofoo"))
		require.NoError(t, err)

		err = file.Sync()
		require.NoError(t, err)

		offset, err := file.Seek(3, 0)

		fmt.Printf("==== %v - err (%v)\n", time.Now(), err)
		fmt.Printf("==== %v - offset (%v)\n", time.Now(), offset)

		// MAC OS X BEHAVIOR - it allows seek
		require.NoError(t, err)
		require.Equal(t, int64(3), offset)

		/* Leaving in place so the test's intention is clear / for repro'ing manually for mac */

		err = file.Sync()
		require.NoError(t, err)

		n1, err := file.Write([]byte("bar"))

		// MAC OS X BEHAVIOR - it allows seek
		require.NoError(t, err)
		require.Equal(t, 3, n1)

		fmt.Printf("==== %v - write word len %v\n", time.Now(), n1)

		require.NoError(t, pfsclient.FinishCommit(apiClient, repo, commit.ID))
	})
}
<commit_msg>Fix code for fuse tests<commit_after>// +build darwin

package fuse_test

import (
	"fmt"
	"os"
	"path/filepath"
	"testing"
	"time"

	"github.com/pachyderm/pachyderm/src/client"
	"github.com/pachyderm/pachyderm/src/client/pkg/require"
)

/* This file mirrors `filesystem_seek_test.go`, but changes the expected
 * values to expect errors. Mac doesn't support the seek disallow flag,
 * and so these tests should fail. In the places I changed the expected
 * values, I added a comment with the string 'MAC OS X BEHAVIOR'
 */

func TestSeekRead(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipped because of short mode")
	}

	testFuse(t, func(c client.APIClient, mountpoint string) {
		repo := "test"
		require.NoError(t, c.CreateRepo(repo))
		commit, err := c.StartCommit(repo, "", "")
		require.NoError(t, err)
		path := filepath.Join(mountpoint, repo, commit.ID, "file")
		file, err := os.Create(path)
		require.NoError(t, err)
		_, err = file.Write([]byte("foobarbaz"))

		require.NoError(t, err)
		require.NoError(t, file.Close())
		require.NoError(t, c.FinishCommit(repo, commit.ID))

		fmt.Printf("==== Finished commit\n")

		file, err = os.Open(path)
		defer file.Close()
		require.NoError(t, err)

		word1 := make([]byte, 3)
		n1, err := file.Read(word1)
		require.NoError(t, err)
		require.Equal(t, 3, n1)
		require.Equal(t, "foo", string(word1))

		fmt.Printf("==== %v - Read word len %v : %v\n", time.Now(), n1, string(word1))

		offset, err := file.Seek(6, 0)
		fmt.Printf("==== %v - err (%v)\n", time.Now(), err)

		fmt.Printf("==== %v - offset (%v)\n", time.Now(), offset)

		// MAC OS X BEHAVIOR - it allows seek
		require.NoError(t, err)
		require.Equal(t, int64(6), offset)

		fmt.Printf("==== Seeked to %v\n", offset)

		/* Leaving in place so the test's intention is clear / for repro'ing manually for mac */

		word2 := make([]byte, 3)
		n2, err := file.Read(word2)
		require.NoError(t, err)
		require.Equal(t, 3, n2)
		require.Equal(t, "baz", string(word2))

		fmt.Printf("==== Read word len %v : %v\n", n2, string(word2))

	})
}

func TestSeekWriteGap(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipped because of short mode")
	}

	testFuse(t, func(c client.APIClient, mountpoint string) {
		repo := "test"
		require.NoError(t, c.CreateRepo(repo))
		commit, err := c.StartCommit(repo, "", "")
		require.NoError(t, err)
		path := filepath.Join(mountpoint, repo, commit.ID, "file")
		file, err := os.Create(path)
		require.NoError(t, err)
		defer func() {
			// MAC OS X BEHAVIOR - it allows seek, but this is an invalid write
			require.YesError(t, file.Close())
		}()

		_, err = file.Write([]byte("foo"))
		require.NoError(t, err)

		err = file.Sync()
		require.NoError(t, err)

		offset, err := file.Seek(6, 0)

		fmt.Printf("==== %v - err (%v)\n", time.Now(), err)
		fmt.Printf("==== %v - offset (%v)\n", time.Now(), offset)

		// MAC OS X BEHAVIOR - it allows seek
		require.NoError(t, err)
		require.Equal(t, int64(6), offset)

		/* Leaving in place so the test's intention is clear / for repro'ing manually for mac */

		err = file.Sync()
		require.NoError(t, err)

		n1, err := file.Write([]byte("baz"))

		// MAC OS X BEHAVIOR - it allows seek
		require.NoError(t, err)
		require.Equal(t, 3, n1)

		require.NoError(t, c.FinishCommit(repo, commit.ID))
	})
}

func TestSeekWriteBackwards(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipped because of short mode")
	}

	testFuse(t, func(c client.APIClient, mountpoint string) {
		repo := "test"
		require.NoError(t, c.CreateRepo(repo))
		commit, err := c.StartCommit(repo, "", "")
		require.NoError(t, err)
		path := filepath.Join(mountpoint, repo, commit.ID, "file")
		file, err := os.Create(path)
		require.NoError(t, err)
		defer func() {
			// MAC OS X BEHAVIOR - it allows seek but this is an invalid write
			require.YesError(t, file.Close())
		}()

		_, err = file.Write([]byte("foofoofoo"))
		require.NoError(t, err)

		err = file.Sync()
		require.NoError(t, err)

		offset, err := file.Seek(3, 0)

		fmt.Printf("==== %v - err (%v)\n", time.Now(), err)
		fmt.Printf("==== %v - offset (%v)\n", time.Now(), offset)

		// MAC OS X BEHAVIOR - it allows seek
		require.NoError(t, err)
		require.Equal(t, int64(3), offset)

		/* Leaving in place so the test's intention is clear / for repro'ing manually for mac */

		err = file.Sync()
		require.NoError(t, err)

		n1, err := file.Write([]byte("bar"))

		// MAC OS X BEHAVIOR - it allows seek
		require.NoError(t, err)
		require.Equal(t, 3, n1)

		fmt.Printf("==== %v - write word len %v\n", time.Now(), n1)

		require.NoError(t, c.FinishCommit(repo, commit.ID))
	})
}
<|endoftext|>


<commit_before>package logrus_test

import (
	"github.com/sirupsen/logrus"
	slhooks "github.com/sirupsen/logrus/hooks/syslog"
	"log/syslog"
	"os"
)

func Example_hook() {
	var log = logrus.New()
	log.Formatter = new(logrus.TextFormatter)                     // default
	log.Formatter.(*logrus.TextFormatter).DisableTimestamp = true // remove timestamp from test output
	if sl, err := slhooks.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, ""); err != nil {
		log.Hooks.Add(sl)
	}
	log.Out = os.Stdout

	log.WithFields(logrus.Fields{
		"animal": "walrus",
		"size":   10,
	}).Info("A group of walrus emerges from the ocean")

	log.WithFields(logrus.Fields{
		"omg":    true,
		"number": 122,
	}).Warn("The group's number increased tremendously!")

	log.WithFields(logrus.Fields{
		"omg":    true,
		"number": 100,
	}).Error("The ice breaks!")

	// Output:
	// level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
	// level=warning msg="The group's number increased tremendously!" number=122 omg=true
	// level=error msg="The ice breaks!" number=100 omg=true
}
<commit_msg>Fix example build on windows<commit_after>// +build !windows

package logrus_test

import (
	"github.com/sirupsen/logrus"
	slhooks "github.com/sirupsen/logrus/hooks/syslog"
	"log/syslog"
	"os"
)

func Example_hook() {
	var log = logrus.New()
	log.Formatter = new(logrus.TextFormatter)                     // default
	log.Formatter.(*logrus.TextFormatter).DisableTimestamp = true // remove timestamp from test output
	if sl, err := slhooks.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, ""); err != nil {
		log.Hooks.Add(sl)
	}
	log.Out = os.Stdout

	log.WithFields(logrus.Fields{
		"animal": "walrus",
		"size":   10,
	}).Info("A group of walrus emerges from the ocean")

	log.WithFields(logrus.Fields{
		"omg":    true,
		"number": 122,
	}).Warn("The group's number increased tremendously!")

	log.WithFields(logrus.Fields{
		"omg":    true,
		"number": 100,
	}).Error("The ice breaks!")

	// Output:
	// level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
	// level=warning msg="The group's number increased tremendously!" number=122 omg=true
	// level=error msg="The ice breaks!" number=100 omg=true
}
<|endoftext|>


<commit_before>// Copyright 2016 Koichi Shiraishi. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package commands

import (
	"bytes"
	"go/scanner"
	"time"

	"nvim-go/context"
	"nvim-go/nvim"
	"nvim-go/nvim/profile"
	"nvim-go/nvim/quickfix"

	"github.com/garyburd/neovim-go/vim"
	"github.com/garyburd/neovim-go/vim/plugin"
	"github.com/juju/errors"
	"golang.org/x/tools/imports"
)

const pkgFmt = "GoFmt"

var importsOptions = imports.Options{
	AllErrors: true,
	Comments:  true,
	TabIndent: true,
	TabWidth:  8,
}

func init() {
	plugin.HandleCommand("Gofmt", &plugin.CommandOptions{Eval: "expand('%:p:h')"}, Fmt)
}

// Fmt format to the current buffer source uses gofmt behavior.
func Fmt(v *vim.Vim, dir string) error {
	defer profile.Start(time.Now(), pkgFmt)
	ctxt := new(context.Context)
	defer ctxt.Build.SetContext(dir)()

	var (
		b vim.Buffer
		w vim.Window
	)
	p := v.NewPipeline()
	p.CurrentBuffer(&b)
	p.CurrentWindow(&w)
	if err := p.Wait(); err != nil {
		return err
	}

	bufName, err := v.BufferName(b)
	if err != nil {
		return err
	}

	in, err := v.BufferLines(b, 0, -1, true)
	if err != nil {
		return err
	}

	buf, err := imports.Process("", nvim.ToByteSlice(in), &importsOptions)
	if err != nil {
		var loclist []*quickfix.ErrorlistData

		if e, ok := err.(scanner.Error); ok {
			loclist = append(loclist, &quickfix.ErrorlistData{
				FileName: bufName,
				LNum:     e.Pos.Line,
				Col:      e.Pos.Column,
				Text:     e.Msg,
			})
		} else if el, ok := err.(scanner.ErrorList); ok {
			for _, e := range el {
				loclist = append(loclist, &quickfix.ErrorlistData{
					FileName: bufName,
					LNum:     e.Pos.Line,
					Col:      e.Pos.Column,
					Text:     e.Msg,
				})
			}
		}

		if err := quickfix.SetLoclist(v, loclist); err != nil {
			return nvim.Echomsg(v, "Gofmt:", err)
		}

		quickfix.OpenLoclist(v, w, loclist, true)
		return errors.Annotate(err, pkgFmt)
	}

	out := nvim.ToBufferLines(bytes.TrimSuffix(buf, []byte{'\n'}))

	minUpdate(v, b, in, out)
	return v.Command("noautocmd write")
}

func minUpdate(v *vim.Vim, b vim.Buffer, in [][]byte, out [][]byte) error {
	// Find matching head lines.
	n := len(out)
	if len(in) < len(out) {
		n = len(in)
	}
	head := 0
	for ; head < n; head++ {
		if !bytes.Equal(in[head], out[head]) {
			break
		}
	}

	// Nothing to do?
	if head == len(in) && head == len(out) {
		return nil
	}

	// Find matching tail lines.
	n -= head
	tail := 0
	for ; tail < n; tail++ {
		if !bytes.Equal(in[len(in)-tail-1], out[len(out)-tail-1]) {
			break
		}
	}

	// Update the buffer.
	start := head
	end := len(in) - tail
	repl := out[head : len(out)-tail]

	return v.SetBufferLines(b, start, end, true, repl)
}
<commit_msg>cmds/fmt: Add comment for noautocmd write<commit_after>// Copyright 2016 Koichi Shiraishi. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package commands

import (
	"bytes"
	"go/scanner"
	"time"

	"nvim-go/context"
	"nvim-go/nvim"
	"nvim-go/nvim/profile"
	"nvim-go/nvim/quickfix"

	"github.com/garyburd/neovim-go/vim"
	"github.com/garyburd/neovim-go/vim/plugin"
	"github.com/juju/errors"
	"golang.org/x/tools/imports"
)

const pkgFmt = "GoFmt"

var importsOptions = imports.Options{
	AllErrors: true,
	Comments:  true,
	TabIndent: true,
	TabWidth:  8,
}

func init() {
	plugin.HandleCommand("Gofmt", &plugin.CommandOptions{Eval: "expand('%:p:h')"}, Fmt)
}

// Fmt format to the current buffer source uses gofmt behavior.
func Fmt(v *vim.Vim, dir string) error {
	defer profile.Start(time.Now(), pkgFmt)
	ctxt := new(context.Context)
	defer ctxt.Build.SetContext(dir)()

	var (
		b vim.Buffer
		w vim.Window
	)
	p := v.NewPipeline()
	p.CurrentBuffer(&b)
	p.CurrentWindow(&w)
	if err := p.Wait(); err != nil {
		return err
	}

	bufName, err := v.BufferName(b)
	if err != nil {
		return err
	}

	in, err := v.BufferLines(b, 0, -1, true)
	if err != nil {
		return err
	}

	buf, err := imports.Process("", nvim.ToByteSlice(in), &importsOptions)
	if err != nil {
		var loclist []*quickfix.ErrorlistData

		if e, ok := err.(scanner.Error); ok {
			loclist = append(loclist, &quickfix.ErrorlistData{
				FileName: bufName,
				LNum:     e.Pos.Line,
				Col:      e.Pos.Column,
				Text:     e.Msg,
			})
		} else if el, ok := err.(scanner.ErrorList); ok {
			for _, e := range el {
				loclist = append(loclist, &quickfix.ErrorlistData{
					FileName: bufName,
					LNum:     e.Pos.Line,
					Col:      e.Pos.Column,
					Text:     e.Msg,
				})
			}
		}

		if err := quickfix.SetLoclist(v, loclist); err != nil {
			return nvim.Echomsg(v, "Gofmt:", err)
		}

		quickfix.OpenLoclist(v, w, loclist, true)
		return errors.Annotate(err, pkgFmt)
	}

	out := nvim.ToBufferLines(bytes.TrimSuffix(buf, []byte{'\n'}))

	minUpdate(v, b, in, out)

	// TODO(zchee): When executed Fmt(itself) function at autocmd BufWritePre, vim "write"
	// command will starting before the finish of the Fmt function because that function called
	// asynchronously uses goroutine.
	// However, "noautocmd" raises duplicate the filesystem events.
	// In the case of macOS fsevents:
	//  (FSE_STAT_CHANGED -> FSE_CHOWN -> FSE_CONTENT_MODIFIED) x2.
	// It will affect the watchdog system such as inotify-tools, fswatch or fsevents-tools.
	// We need to consider the Alternative of BufWriteCmd or other an effective way.
	return v.Command("noautocmd write")
}

func minUpdate(v *vim.Vim, b vim.Buffer, in [][]byte, out [][]byte) error {
	// Find matching head lines.
	n := len(out)
	if len(in) < len(out) {
		n = len(in)
	}
	head := 0
	for ; head < n; head++ {
		if !bytes.Equal(in[head], out[head]) {
			break
		}
	}

	// Nothing to do?
	if head == len(in) && head == len(out) {
		return nil
	}

	// Find matching tail lines.
	n -= head
	tail := 0
	for ; tail < n; tail++ {
		if !bytes.Equal(in[len(in)-tail-1], out[len(out)-tail-1]) {
			break
		}
	}

	// Update the buffer.
	start := head
	end := len(in) - tail
	repl := out[head : len(out)-tail]

	return v.SetBufferLines(b, start, end, true, repl)
}
<|endoftext|>


<commit_before>package repository

import (
	"io"
	"math/rand"
	"os"
	"restic/backend"
	"restic/backend/mem"
	"restic/crypto"
	"restic/pack"
	"testing"
)

type randReader struct {
	src  rand.Source
	rand *rand.Rand
}

func newRandReader(src rand.Source) *randReader {
	return &randReader{
		src:  src,
		rand: rand.New(src),
	}
}

// Read generates len(p) random bytes and writes them into p. It
// always returns len(p) and a nil error.
func (r *randReader) Read(p []byte) (n int, err error) {
	for i := 0; i < len(p); i += 7 {
		val := r.src.Int63()
		for j := 0; i+j < len(p) && j < 7; j++ {
			p[i+j] = byte(val)
			val >>= 8
		}
	}
	return len(p), nil
}

func randomID(rd io.Reader) backend.ID {
	id := backend.ID{}
	_, err := io.ReadFull(rd, id[:])
	if err != nil {
		panic(err)
	}
	return id
}

const maxBlobSize = 1 << 20

func saveFile(t testing.TB, be Saver, filename string, n int) {
	f, err := os.Open(filename)
	if err != nil {
		t.Fatal(err)
	}

	data := make([]byte, n)
	m, err := io.ReadFull(f, data)

	if m != n {
		t.Fatalf("read wrong number of bytes from %v: want %v, got %v", filename, m, n)
	}

	if err = f.Close(); err != nil {
		t.Fatal(err)
	}

	h := backend.Handle{Type: backend.Data, Name: backend.Hash(data).String()}

	err = be.Save(h, data)
	if err != nil {
		t.Fatal(err)
	}

	err = os.Remove(filename)
	if err != nil {
		t.Fatal(err)
	}
}

func fillPacks(t testing.TB, rnd *randReader, be Saver, pm *packerManager, buf []byte) (bytes int) {
	for i := 0; i < 100; i++ {
		l := rnd.rand.Intn(1 << 20)
		seed := rnd.rand.Int63()

		packer, err := pm.findPacker(uint(l))
		if err != nil {
			t.Fatal(err)
		}

		rd := rand.New(rand.NewSource(seed))
		id := randomID(rd)
		buf = buf[:l]
		_, err = io.ReadFull(rd, buf)
		if err != nil {
			t.Fatal(err)
		}

		n, err := packer.Add(pack.Data, id, buf)
		if n != l {
			t.Errorf("Add() returned invalid number of bytes: want %v, got %v", n, l)
		}
		bytes += l

		if packer.Size() < minPackSize && pm.countPacker() < maxPackers {
			pm.insertPacker(packer)
			continue
		}

		bytesWritten, err := packer.Finalize()
		if err != nil {
			t.Fatal(err)
		}

		tmpfile := packer.Writer().(*os.File)
		saveFile(t, be, tmpfile.Name(), int(bytesWritten))
	}

	return bytes
}

func flushRemainingPacks(t testing.TB, rnd *randReader, be Saver, pm *packerManager) (bytes int) {
	if pm.countPacker() > 0 {
		for _, packer := range pm.packs {
			n, err := packer.Finalize()
			if err != nil {
				t.Fatal(err)
			}
			bytes += int(n)

			tmpfile := packer.Writer().(*os.File)
			saveFile(t, be, tmpfile.Name(), bytes)
		}
	}

	return bytes
}

type fakeBackend struct{}

func (f *fakeBackend) Save(h backend.Handle, data []byte) error {
	return nil
}

func TestPackerManager(t *testing.T) {
	rnd := newRandReader(rand.NewSource(23))

	be := mem.New()
	pm := newPackerManager(be, crypto.NewRandomKey())

	blobBuf := make([]byte, maxBlobSize)

	bytes := fillPacks(t, rnd, be, pm, blobBuf)
	bytes += flushRemainingPacks(t, rnd, be, pm)

	t.Logf("saved %d bytes", bytes)
}

func BenchmarkPackerManager(t *testing.B) {
	rnd := newRandReader(rand.NewSource(23))

	be := &fakeBackend{}
	pm := newPackerManager(be, crypto.NewRandomKey())
	blobBuf := make([]byte, maxBlobSize)

	t.ResetTimer()

	bytes := 0
	for i := 0; i < t.N; i++ {
		bytes += fillPacks(t, rnd, be, pm, blobBuf)
	}

	bytes += flushRemainingPacks(t, rnd, be, pm)
	t.Logf("saved %d bytes", bytes)
}
<commit_msg>Use newRandReader instead of rand.New()<commit_after>package repository

import (
	"io"
	"math/rand"
	"os"
	"restic/backend"
	"restic/backend/mem"
	"restic/crypto"
	"restic/pack"
	"testing"
)

type randReader struct {
	src  rand.Source
	rand *rand.Rand
}

func newRandReader(src rand.Source) *randReader {
	return &randReader{
		src:  src,
		rand: rand.New(src),
	}
}

// Read generates len(p) random bytes and writes them into p. It
// always returns len(p) and a nil error.
func (r *randReader) Read(p []byte) (n int, err error) {
	for i := 0; i < len(p); i += 7 {
		val := r.src.Int63()
		for j := 0; i+j < len(p) && j < 7; j++ {
			p[i+j] = byte(val)
			val >>= 8
		}
	}
	return len(p), nil
}

func randomID(rd io.Reader) backend.ID {
	id := backend.ID{}
	_, err := io.ReadFull(rd, id[:])
	if err != nil {
		panic(err)
	}
	return id
}

const maxBlobSize = 1 << 20

func saveFile(t testing.TB, be Saver, filename string, n int) {
	f, err := os.Open(filename)
	if err != nil {
		t.Fatal(err)
	}

	data := make([]byte, n)
	m, err := io.ReadFull(f, data)

	if m != n {
		t.Fatalf("read wrong number of bytes from %v: want %v, got %v", filename, m, n)
	}

	if err = f.Close(); err != nil {
		t.Fatal(err)
	}

	h := backend.Handle{Type: backend.Data, Name: backend.Hash(data).String()}

	err = be.Save(h, data)
	if err != nil {
		t.Fatal(err)
	}

	err = os.Remove(filename)
	if err != nil {
		t.Fatal(err)
	}
}

func fillPacks(t testing.TB, rnd *randReader, be Saver, pm *packerManager, buf []byte) (bytes int) {
	for i := 0; i < 100; i++ {
		l := rnd.rand.Intn(1 << 20)
		seed := rnd.rand.Int63()

		packer, err := pm.findPacker(uint(l))
		if err != nil {
			t.Fatal(err)
		}

		rd := newRandReader(rand.NewSource(seed))
		id := randomID(rd)
		buf = buf[:l]
		_, err = io.ReadFull(rd, buf)
		if err != nil {
			t.Fatal(err)
		}

		n, err := packer.Add(pack.Data, id, buf)
		if n != l {
			t.Errorf("Add() returned invalid number of bytes: want %v, got %v", n, l)
		}
		bytes += l

		if packer.Size() < minPackSize && pm.countPacker() < maxPackers {
			pm.insertPacker(packer)
			continue
		}

		bytesWritten, err := packer.Finalize()
		if err != nil {
			t.Fatal(err)
		}

		tmpfile := packer.Writer().(*os.File)
		saveFile(t, be, tmpfile.Name(), int(bytesWritten))
	}

	return bytes
}

func flushRemainingPacks(t testing.TB, rnd *randReader, be Saver, pm *packerManager) (bytes int) {
	if pm.countPacker() > 0 {
		for _, packer := range pm.packs {
			n, err := packer.Finalize()
			if err != nil {
				t.Fatal(err)
			}
			bytes += int(n)

			tmpfile := packer.Writer().(*os.File)
			saveFile(t, be, tmpfile.Name(), bytes)
		}
	}

	return bytes
}

type fakeBackend struct{}

func (f *fakeBackend) Save(h backend.Handle, data []byte) error {
	return nil
}

func TestPackerManager(t *testing.T) {
	rnd := newRandReader(rand.NewSource(23))

	be := mem.New()
	pm := newPackerManager(be, crypto.NewRandomKey())

	blobBuf := make([]byte, maxBlobSize)

	bytes := fillPacks(t, rnd, be, pm, blobBuf)
	bytes += flushRemainingPacks(t, rnd, be, pm)

	t.Logf("saved %d bytes", bytes)
}

func BenchmarkPackerManager(t *testing.B) {
	rnd := newRandReader(rand.NewSource(23))

	be := &fakeBackend{}
	pm := newPackerManager(be, crypto.NewRandomKey())
	blobBuf := make([]byte, maxBlobSize)

	t.ResetTimer()

	bytes := 0
	for i := 0; i < t.N; i++ {
		bytes += fillPacks(t, rnd, be, pm, blobBuf)
	}

	bytes += flushRemainingPacks(t, rnd, be, pm)
	t.Logf("saved %d bytes", bytes)
}
<|endoftext|>


<commit_before>//===- transforms_scalar.go - Bindings for scalaropts ---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines bindings for the scalaropts component.
//
//===----------------------------------------------------------------------===//

package llvm

/*
#include "llvm-c/Transforms/Scalar.h"
*/
import "C"

func (pm PassManager) AddAggressiveDCEPass()           { C.LLVMAddAggressiveDCEPass(pm.C) }
func (pm PassManager) AddCFGSimplificationPass()       { C.LLVMAddCFGSimplificationPass(pm.C) }
func (pm PassManager) AddDeadStoreEliminationPass()    { C.LLVMAddDeadStoreEliminationPass(pm.C) }
func (pm PassManager) AddGVNPass()                     { C.LLVMAddGVNPass(pm.C) }
func (pm PassManager) AddIndVarSimplifyPass()          { C.LLVMAddIndVarSimplifyPass(pm.C) }
func (pm PassManager) AddInstructionCombiningPass()    { C.LLVMAddInstructionCombiningPass(pm.C) }
func (pm PassManager) AddJumpThreadingPass()           { C.LLVMAddJumpThreadingPass(pm.C) }
func (pm PassManager) AddLICMPass()                    { C.LLVMAddLICMPass(pm.C) }
func (pm PassManager) AddLoopDeletionPass()            { C.LLVMAddLoopDeletionPass(pm.C) }
func (pm PassManager) AddLoopRotatePass()              { C.LLVMAddLoopRotatePass(pm.C) }
func (pm PassManager) AddLoopUnrollPass()              { C.LLVMAddLoopUnrollPass(pm.C) }
func (pm PassManager) AddLoopUnswitchPass()            { C.LLVMAddLoopUnswitchPass(pm.C) }
func (pm PassManager) AddMemCpyOptPass()               { C.LLVMAddMemCpyOptPass(pm.C) }
func (pm PassManager) AddPromoteMemoryToRegisterPass() { C.LLVMAddPromoteMemoryToRegisterPass(pm.C) }
func (pm PassManager) AddReassociatePass()             { C.LLVMAddReassociatePass(pm.C) }
func (pm PassManager) AddSCCPPass()                    { C.LLVMAddSCCPPass(pm.C) }
func (pm PassManager) AddScalarReplAggregatesPass()    { C.LLVMAddScalarReplAggregatesPass(pm.C) }
func (pm PassManager) AddScalarReplAggregatesPassWithThreshold(threshold int) {
	C.LLVMAddScalarReplAggregatesPassWithThreshold(pm.C, C.int(threshold))
}
func (pm PassManager) AddSimplifyLibCallsPass()       { C.LLVMAddSimplifyLibCallsPass(pm.C) }
func (pm PassManager) AddTailCallEliminationPass()    { C.LLVMAddTailCallEliminationPass(pm.C) }
func (pm PassManager) AddConstantPropagationPass()    { C.LLVMAddConstantPropagationPass(pm.C) }
func (pm PassManager) AddDemoteMemoryToRegisterPass() { C.LLVMAddDemoteMemoryToRegisterPass(pm.C) }
func (pm PassManager) AddVerifierPass()               { C.LLVMAddVerifierPass(pm.C) }
<commit_msg>Unbreak the build of the go bindings after r328839.<commit_after>//===- transforms_scalar.go - Bindings for scalaropts ---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines bindings for the scalaropts component.
//
//===----------------------------------------------------------------------===//

package llvm

/*
#include "llvm-c/Transforms/Scalar.h"
#include "llvm-c/Transforms/Utils.h"
*/
import "C"

func (pm PassManager) AddAggressiveDCEPass()           { C.LLVMAddAggressiveDCEPass(pm.C) }
func (pm PassManager) AddCFGSimplificationPass()       { C.LLVMAddCFGSimplificationPass(pm.C) }
func (pm PassManager) AddDeadStoreEliminationPass()    { C.LLVMAddDeadStoreEliminationPass(pm.C) }
func (pm PassManager) AddGVNPass()                     { C.LLVMAddGVNPass(pm.C) }
func (pm PassManager) AddIndVarSimplifyPass()          { C.LLVMAddIndVarSimplifyPass(pm.C) }
func (pm PassManager) AddInstructionCombiningPass()    { C.LLVMAddInstructionCombiningPass(pm.C) }
func (pm PassManager) AddJumpThreadingPass()           { C.LLVMAddJumpThreadingPass(pm.C) }
func (pm PassManager) AddLICMPass()                    { C.LLVMAddLICMPass(pm.C) }
func (pm PassManager) AddLoopDeletionPass()            { C.LLVMAddLoopDeletionPass(pm.C) }
func (pm PassManager) AddLoopRotatePass()              { C.LLVMAddLoopRotatePass(pm.C) }
func (pm PassManager) AddLoopUnrollPass()              { C.LLVMAddLoopUnrollPass(pm.C) }
func (pm PassManager) AddLoopUnswitchPass()            { C.LLVMAddLoopUnswitchPass(pm.C) }
func (pm PassManager) AddMemCpyOptPass()               { C.LLVMAddMemCpyOptPass(pm.C) }
func (pm PassManager) AddPromoteMemoryToRegisterPass() { C.LLVMAddPromoteMemoryToRegisterPass(pm.C) }
func (pm PassManager) AddReassociatePass()             { C.LLVMAddReassociatePass(pm.C) }
func (pm PassManager) AddSCCPPass()                    { C.LLVMAddSCCPPass(pm.C) }
func (pm PassManager) AddScalarReplAggregatesPass()    { C.LLVMAddScalarReplAggregatesPass(pm.C) }
func (pm PassManager) AddScalarReplAggregatesPassWithThreshold(threshold int) {
	C.LLVMAddScalarReplAggregatesPassWithThreshold(pm.C, C.int(threshold))
}
func (pm PassManager) AddSimplifyLibCallsPass()       { C.LLVMAddSimplifyLibCallsPass(pm.C) }
func (pm PassManager) AddTailCallEliminationPass()    { C.LLVMAddTailCallEliminationPass(pm.C) }
func (pm PassManager) AddConstantPropagationPass()    { C.LLVMAddConstantPropagationPass(pm.C) }
func (pm PassManager) AddDemoteMemoryToRegisterPass() { C.LLVMAddDemoteMemoryToRegisterPass(pm.C) }
func (pm PassManager) AddVerifierPass()               { C.LLVMAddVerifierPass(pm.C) }
<|endoftext|>


<commit_before>package relay

import (
	"context"
	"time"

	discovery "github.com/libp2p/go-libp2p-discovery"
	ma "github.com/multiformats/go-multiaddr"
)

var (
	// this is purposefully long to require some node stability before advertising as a relay
	AdvertiseBootDelay = 15 * time.Minute
)

// Advertise advertises this node as a libp2p relay.
func Advertise(ctx context.Context, advertise discovery.Advertiser) {
	go func() {
		select {
		case <-time.After(AdvertiseBootDelay):
			discovery.Advertise(ctx, advertise, RelayRendezvous)
		case <-ctx.Done():
		}
	}()
}

// Filter filters out all relay addresses.
func Filter(addrs []ma.Multiaddr) []ma.Multiaddr {
	raddrs := make([]ma.Multiaddr, 0, len(addrs))
	for _, addr := range addrs {
		if isRelayAddr(addr) {
			continue
		}
		raddrs = append(raddrs, addr)
	}
	return raddrs
}
<commit_msg>advertise for relay services every 30min<commit_after>package relay

import (
	"context"
	"time"

	discovery "github.com/libp2p/go-libp2p-discovery"
	ma "github.com/multiformats/go-multiaddr"
)

var (
	// this is purposefully long to require some node stability before advertising as a relay
	AdvertiseBootDelay = 15 * time.Minute
	AdvertiseTTL       = 30 * time.Minute
)

// Advertise advertises this node as a libp2p relay.
func Advertise(ctx context.Context, advertise discovery.Advertiser) {
	go func() {
		select {
		case <-time.After(AdvertiseBootDelay):
			discovery.Advertise(ctx, advertise, RelayRendezvous, discovery.TTL(AdvertiseTTL))
		case <-ctx.Done():
		}
	}()
}

// Filter filters out all relay addresses.
func Filter(addrs []ma.Multiaddr) []ma.Multiaddr {
	raddrs := make([]ma.Multiaddr, 0, len(addrs))
	for _, addr := range addrs {
		if isRelayAddr(addr) {
			continue
		}
		raddrs = append(raddrs, addr)
	}
	return raddrs
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
	"github.com/docker/docker/integration-cli/checker"
	"github.com/docker/docker/integration-cli/request"
	"github.com/docker/docker/pkg/stdcopy"
	"github.com/go-check/check"
	"golang.org/x/net/context"
)

func (s *DockerSuite) TestLogsAPIWithStdout(c *check.C) {
	out, _ := dockerCmd(c, "run", "-d", "-t", "busybox", "/bin/sh", "-c", "while true; do echo hello; sleep 1; done")
	id := strings.TrimSpace(out)
	c.Assert(waitRun(id), checker.IsNil)

	type logOut struct {
		out string
		err error
	}

	chLog := make(chan logOut)
	res, body, err := request.Get(fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1&timestamps=1", id))
	c.Assert(err, checker.IsNil)
	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)

	go func() {
		defer body.Close()
		out, err := bufio.NewReader(body).ReadString('\n')
		if err != nil {
			chLog <- logOut{"", err}
			return
		}
		chLog <- logOut{strings.TrimSpace(out), err}
	}()

	select {
	case l := <-chLog:
		c.Assert(l.err, checker.IsNil)
		if !strings.HasSuffix(l.out, "hello") {
			c.Fatalf("expected log output to container 'hello', but it does not")
		}
	case <-time.After(30 * time.Second):
		c.Fatal("timeout waiting for logs to exit")
	}
}

func (s *DockerSuite) TestLogsAPINoStdoutNorStderr(c *check.C) {
	name := "logs_test"
	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
	cli, err := client.NewEnvClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	_, err = cli.ContainerLogs(context.Background(), name, types.ContainerLogsOptions{})
	expected := "Bad parameters: you must choose at least one stream"
	c.Assert(err.Error(), checker.Contains, expected)
}

// Regression test for #12704
func (s *DockerSuite) TestLogsAPIFollowEmptyOutput(c *check.C) {
	name := "logs_test"
	t0 := time.Now()
	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "sleep", "10")

	_, body, err := request.Get(fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1&stderr=1&tail=all", name))
	t1 := time.Now()
	c.Assert(err, checker.IsNil)
	body.Close()
	elapsed := t1.Sub(t0).Seconds()
	if elapsed > 20.0 {
		c.Fatalf("HTTP response was not immediate (elapsed %.1fs)", elapsed)
	}
}

func (s *DockerSuite) TestLogsAPIContainerNotFound(c *check.C) {
	name := "nonExistentContainer"
	resp, _, err := request.Get(fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1&stderr=1&tail=all", name))
	c.Assert(err, checker.IsNil)
	c.Assert(resp.StatusCode, checker.Equals, http.StatusNotFound)
}

func (s *DockerSuite) TestLogsAPIUntilFutureFollow(c *check.C) {
	testRequires(c, DaemonIsLinux)

	name := "logsuntilfuturefollow"
	dockerCmd(c, "run", "-d", "--name", name, "busybox", "/bin/sh", "-c", "while true; do date +%s; sleep 1; done")
	c.Assert(waitRun(name), checker.IsNil)

	untilSecs := 5
	untilDur, err := time.ParseDuration(fmt.Sprintf("%ds", untilSecs))
	c.Assert(err, checker.IsNil)
	until := daemonTime(c).Add(untilDur)

	client, err := request.NewClient()
	if err != nil {
		c.Fatal(err)
	}

	cfg := types.ContainerLogsOptions{Until: until.Format(time.RFC3339Nano), Follow: true, ShowStdout: true, Timestamps: true}
	reader, err := client.ContainerLogs(context.Background(), name, cfg)
	c.Assert(err, checker.IsNil)

	type logOut struct {
		out string
		err error
	}

	chLog := make(chan logOut)

	go func() {
		bufReader := bufio.NewReader(reader)
		defer reader.Close()
		for i := 0; i < untilSecs; i++ {
			out, _, err := bufReader.ReadLine()
			if err != nil {
				if err == io.EOF {
					return
				}
				chLog <- logOut{"", err}
				return
			}

			chLog <- logOut{strings.TrimSpace(string(out)), err}
		}
	}()

	for i := 0; i < untilSecs; i++ {
		select {
		case l := <-chLog:
			c.Assert(l.err, checker.IsNil)
			i, err := strconv.ParseInt(strings.Split(l.out, " ")[1], 10, 64)
			c.Assert(err, checker.IsNil)
			c.Assert(time.Unix(i, 0).UnixNano(), checker.LessOrEqualThan, until.UnixNano())
		case <-time.After(20 * time.Second):
			c.Fatal("timeout waiting for logs to exit")
		}
	}
}

func (s *DockerSuite) TestLogsAPIUntil(c *check.C) {
	name := "logsuntil"
	dockerCmd(c, "run", "--name", name, "busybox", "/bin/sh", "-c", "for i in $(seq 1 3); do echo log$i; sleep 0.5; done")

	client, err := request.NewClient()
	if err != nil {
		c.Fatal(err)
	}

	extractBody := func(c *check.C, cfg types.ContainerLogsOptions) []string {
		reader, err := client.ContainerLogs(context.Background(), name, cfg)
		c.Assert(err, checker.IsNil)

		actualStdout := new(bytes.Buffer)
		actualStderr := ioutil.Discard
		_, err = stdcopy.StdCopy(actualStdout, actualStderr, reader)
		c.Assert(err, checker.IsNil)

		return strings.Split(actualStdout.String(), "\n")
	}

	// Get timestamp of second log line
	allLogs := extractBody(c, types.ContainerLogsOptions{Timestamps: true, ShowStdout: true})
	t, err := time.Parse(time.RFC3339Nano, strings.Split(allLogs[1], " ")[0])
	c.Assert(err, checker.IsNil)
	until := t.Format(time.RFC3339Nano)

	// Get logs until the timestamp of second line, i.e. first two lines
	logs := extractBody(c, types.ContainerLogsOptions{Timestamps: true, ShowStdout: true, Until: until})

	// Ensure log lines after cut-off are excluded
	logsString := strings.Join(logs, "\n")
	c.Assert(logsString, checker.Not(checker.Contains), "log3", check.Commentf("unexpected log message returned, until=%v", until))
}

func (s *DockerSuite) TestLogsAPIUntilDefaultValue(c *check.C) {
	name := "logsuntildefaultval"
	dockerCmd(c, "run", "--name", name, "busybox", "/bin/sh", "-c", "for i in $(seq 1 3); do echo log$i; done")

	client, err := request.NewClient()
	if err != nil {
		c.Fatal(err)
	}

	extractBody := func(c *check.C, cfg types.ContainerLogsOptions) []string {
		reader, err := client.ContainerLogs(context.Background(), name, cfg)
		c.Assert(err, checker.IsNil)

		actualStdout := new(bytes.Buffer)
		actualStderr := ioutil.Discard
		_, err = stdcopy.StdCopy(actualStdout, actualStderr, reader)
		c.Assert(err, checker.IsNil)

		return strings.Split(actualStdout.String(), "\n")
	}

	// Get timestamp of second log line
	allLogs := extractBody(c, types.ContainerLogsOptions{Timestamps: true, ShowStdout: true})

	// Test with default value specified and parameter omitted
	defaultLogs := extractBody(c, types.ContainerLogsOptions{Timestamps: true, ShowStdout: true, Until: "0"})
	c.Assert(defaultLogs, checker.DeepEquals, allLogs)
}
<commit_msg>Remove uneeded sleep in test bash loop<commit_after>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
	"github.com/docker/docker/integration-cli/checker"
	"github.com/docker/docker/integration-cli/request"
	"github.com/docker/docker/pkg/stdcopy"
	"github.com/go-check/check"
	"golang.org/x/net/context"
)

func (s *DockerSuite) TestLogsAPIWithStdout(c *check.C) {
	out, _ := dockerCmd(c, "run", "-d", "-t", "busybox", "/bin/sh", "-c", "while true; do echo hello; sleep 1; done")
	id := strings.TrimSpace(out)
	c.Assert(waitRun(id), checker.IsNil)

	type logOut struct {
		out string
		err error
	}

	chLog := make(chan logOut)
	res, body, err := request.Get(fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1&timestamps=1", id))
	c.Assert(err, checker.IsNil)
	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)

	go func() {
		defer body.Close()
		out, err := bufio.NewReader(body).ReadString('\n')
		if err != nil {
			chLog <- logOut{"", err}
			return
		}
		chLog <- logOut{strings.TrimSpace(out), err}
	}()

	select {
	case l := <-chLog:
		c.Assert(l.err, checker.IsNil)
		if !strings.HasSuffix(l.out, "hello") {
			c.Fatalf("expected log output to container 'hello', but it does not")
		}
	case <-time.After(30 * time.Second):
		c.Fatal("timeout waiting for logs to exit")
	}
}

func (s *DockerSuite) TestLogsAPINoStdoutNorStderr(c *check.C) {
	name := "logs_test"
	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
	cli, err := client.NewEnvClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	_, err = cli.ContainerLogs(context.Background(), name, types.ContainerLogsOptions{})
	expected := "Bad parameters: you must choose at least one stream"
	c.Assert(err.Error(), checker.Contains, expected)
}

// Regression test for #12704
func (s *DockerSuite) TestLogsAPIFollowEmptyOutput(c *check.C) {
	name := "logs_test"
	t0 := time.Now()
	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "sleep", "10")

	_, body, err := request.Get(fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1&stderr=1&tail=all", name))
	t1 := time.Now()
	c.Assert(err, checker.IsNil)
	body.Close()
	elapsed := t1.Sub(t0).Seconds()
	if elapsed > 20.0 {
		c.Fatalf("HTTP response was not immediate (elapsed %.1fs)", elapsed)
	}
}

func (s *DockerSuite) TestLogsAPIContainerNotFound(c *check.C) {
	name := "nonExistentContainer"
	resp, _, err := request.Get(fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1&stderr=1&tail=all", name))
	c.Assert(err, checker.IsNil)
	c.Assert(resp.StatusCode, checker.Equals, http.StatusNotFound)
}

func (s *DockerSuite) TestLogsAPIUntilFutureFollow(c *check.C) {
	testRequires(c, DaemonIsLinux)

	name := "logsuntilfuturefollow"
	dockerCmd(c, "run", "-d", "--name", name, "busybox", "/bin/sh", "-c", "while true; do date +%s; sleep 1; done")
	c.Assert(waitRun(name), checker.IsNil)

	untilSecs := 5
	untilDur, err := time.ParseDuration(fmt.Sprintf("%ds", untilSecs))
	c.Assert(err, checker.IsNil)
	until := daemonTime(c).Add(untilDur)

	client, err := request.NewClient()
	if err != nil {
		c.Fatal(err)
	}

	cfg := types.ContainerLogsOptions{Until: until.Format(time.RFC3339Nano), Follow: true, ShowStdout: true, Timestamps: true}
	reader, err := client.ContainerLogs(context.Background(), name, cfg)
	c.Assert(err, checker.IsNil)

	type logOut struct {
		out string
		err error
	}

	chLog := make(chan logOut)

	go func() {
		bufReader := bufio.NewReader(reader)
		defer reader.Close()
		for i := 0; i < untilSecs; i++ {
			out, _, err := bufReader.ReadLine()
			if err != nil {
				if err == io.EOF {
					return
				}
				chLog <- logOut{"", err}
				return
			}

			chLog <- logOut{strings.TrimSpace(string(out)), err}
		}
	}()

	for i := 0; i < untilSecs; i++ {
		select {
		case l := <-chLog:
			c.Assert(l.err, checker.IsNil)
			i, err := strconv.ParseInt(strings.Split(l.out, " ")[1], 10, 64)
			c.Assert(err, checker.IsNil)
			c.Assert(time.Unix(i, 0).UnixNano(), checker.LessOrEqualThan, until.UnixNano())
		case <-time.After(20 * time.Second):
			c.Fatal("timeout waiting for logs to exit")
		}
	}
}

func (s *DockerSuite) TestLogsAPIUntil(c *check.C) {
	name := "logsuntil"
	dockerCmd(c, "run", "--name", name, "busybox", "/bin/sh", "-c", "for i in $(seq 1 3); do echo log$i; done")

	client, err := request.NewClient()
	if err != nil {
		c.Fatal(err)
	}

	extractBody := func(c *check.C, cfg types.ContainerLogsOptions) []string {
		reader, err := client.ContainerLogs(context.Background(), name, cfg)
		c.Assert(err, checker.IsNil)

		actualStdout := new(bytes.Buffer)
		actualStderr := ioutil.Discard
		_, err = stdcopy.StdCopy(actualStdout, actualStderr, reader)
		c.Assert(err, checker.IsNil)

		return strings.Split(actualStdout.String(), "\n")
	}

	// Get timestamp of second log line
	allLogs := extractBody(c, types.ContainerLogsOptions{Timestamps: true, ShowStdout: true})
	t, err := time.Parse(time.RFC3339Nano, strings.Split(allLogs[1], " ")[0])
	c.Assert(err, checker.IsNil)
	until := t.Format(time.RFC3339Nano)

	// Get logs until the timestamp of second line, i.e. first two lines
	logs := extractBody(c, types.ContainerLogsOptions{Timestamps: true, ShowStdout: true, Until: until})

	// Ensure log lines after cut-off are excluded
	logsString := strings.Join(logs, "\n")
	c.Assert(logsString, checker.Not(checker.Contains), "log3", check.Commentf("unexpected log message returned, until=%v", until))
}

func (s *DockerSuite) TestLogsAPIUntilDefaultValue(c *check.C) {
	name := "logsuntildefaultval"
	dockerCmd(c, "run", "--name", name, "busybox", "/bin/sh", "-c", "for i in $(seq 1 3); do echo log$i; done")

	client, err := request.NewClient()
	if err != nil {
		c.Fatal(err)
	}

	extractBody := func(c *check.C, cfg types.ContainerLogsOptions) []string {
		reader, err := client.ContainerLogs(context.Background(), name, cfg)
		c.Assert(err, checker.IsNil)

		actualStdout := new(bytes.Buffer)
		actualStderr := ioutil.Discard
		_, err = stdcopy.StdCopy(actualStdout, actualStderr, reader)
		c.Assert(err, checker.IsNil)

		return strings.Split(actualStdout.String(), "\n")
	}

	// Get timestamp of second log line
	allLogs := extractBody(c, types.ContainerLogsOptions{Timestamps: true, ShowStdout: true})

	// Test with default value specified and parameter omitted
	defaultLogs := extractBody(c, types.ContainerLogsOptions{Timestamps: true, ShowStdout: true, Until: "0"})
	c.Assert(defaultLogs, checker.DeepEquals, allLogs)
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package schema

import (
	"errors"
	"sync"
	"time"

	"github.com/GoogleCloudPlatform/heapster/sinks/cache"
)

var lock sync.RWMutex

func NewCluster() Cluster {
	return newRealCluster()
}

func newRealCluster() *realCluster {
	cinfo := ClusterInfo{
		InfoType:   newInfoType(nil, nil),
		Namespaces: make(map[string]*NamespaceInfo),
		Nodes:      make(map[string]*NodeInfo),
	}
	cluster := &realCluster{
		timestamp:   time.Time{},
		ClusterInfo: cinfo,
	}
	return cluster
}

func (rc *realCluster) GetAllClusterData() (*ClusterInfo, time.Time, error) {
	// Returns the entire ClusterInfo object
	lock.RLock()
	defer lock.RUnlock()
	return &rc.ClusterInfo, rc.timestamp, nil
}

func (rc *realCluster) GetAllNodeData(hostname string) (*NodeInfo, time.Time, error) {
	// Returns the corresponding NodeInfo object
	lock.RLock()
	defer lock.RUnlock()

	var res *NodeInfo
	var stamp time.Time
	var err error

	if val, ok := rc.Nodes[hostname]; ok {
		res = val
		stamp = rc.timestamp
		err = nil
	} else {
		res = nil
		err = errors.New("Unable to find node with hostname: " + hostname)
	}
	return res, stamp, err
}

func (rc *realCluster) GetAllPodData(namespace string, pod_name string) (*PodInfo, time.Time, error) {
	// Returns the corresponding NodeInfo object
	lock.RLock()
	defer lock.RUnlock()

	var res *PodInfo
	var stamp time.Time
	var err error

	if len(rc.Namespaces) == 0 {
		err = errors.New("Unable to find pod: no namespaces registered")
	} else {
		if ns, ok := rc.Namespaces[namespace]; ok {
			if val, ok := ns.Pods[pod_name]; ok {
				res = val
				stamp = rc.timestamp
				err = nil
			} else {
				err = errors.New("Unable to find pod with name: " + pod_name)
			}
		} else {
			err = errors.New("Unable to find namespace with name: " + namespace)
		}
	}
	return res, stamp, err
}

func (rc *realCluster) Update(c *cache.Cache) error {
	return nil
}
<commit_msg>updated error handling to match error-case-first style<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package schema

import (
	"fmt"
	"sync"
	"time"

	"github.com/GoogleCloudPlatform/heapster/sinks/cache"
)

var lock sync.RWMutex

func NewCluster() Cluster {
	return newRealCluster()
}

func newRealCluster() *realCluster {
	cinfo := ClusterInfo{
		InfoType:   newInfoType(nil, nil),
		Namespaces: make(map[string]*NamespaceInfo),
		Nodes:      make(map[string]*NodeInfo),
	}
	cluster := &realCluster{
		timestamp:   time.Time{},
		ClusterInfo: cinfo,
	}
	return cluster
}

func (rc *realCluster) GetAllClusterData() (*ClusterInfo, time.Time, error) {
	// Returns the entire ClusterInfo object
	lock.RLock()
	defer lock.RUnlock()
	return &rc.ClusterInfo, rc.timestamp, nil
}

func (rc *realCluster) GetAllNodeData(hostname string) (*NodeInfo, time.Time, error) {
	// Returns the corresponding NodeInfo object
	var zeroTime time.Time

	lock.RLock()
	defer lock.RUnlock()

	res, ok := rc.Nodes[hostname]
	if !ok {
		return nil, zeroTime, fmt.Errorf("Unable to find node with hostname: %s", hostname)
	}

	return res, rc.timestamp, nil
}

func (rc *realCluster) GetAllPodData(namespace string, pod_name string) (*PodInfo, time.Time, error) {
	// Returns the corresponding NodeInfo object
	var zeroTime time.Time

	lock.RLock()
	defer lock.RUnlock()

	if len(rc.Namespaces) == 0 {
		return nil, zeroTime, fmt.Errorf("Unable to find pod: no namespaces in cluster")
	}

	ns, ok := rc.Namespaces[namespace]
	if !ok {
		return nil, zeroTime, fmt.Errorf("Unable to find namespace with name: %s", namespace)
	}

	pod, ok := ns.Pods[pod_name]
	if !ok {
		return nil, zeroTime, fmt.Errorf("Unable to find pod with name: %s", pod_name)
	}

	return pod, rc.timestamp, nil
}

func (rc *realCluster) Update(c *cache.Cache) error {
	return nil
}
<|endoftext|>


<commit_before>package omxplayer

import (
	"fmt"
	"github.com/guelfey/go.dbus"
)

const (
	ifaceProps     = "org.freedesktop.DBus.Properties"
	ifaceOmxRoot   = ifaceMpris
	ifaceOmxPlayer = ifaceOmxRoot + ".Player"

	cmdQuit                 = ifaceOmxRoot + ".Quit"
	propCanQuit             = ifaceProps + ".CanQuit"
	propFullscreen          = ifaceProps + ".Fullscreen"
	propCanSetFullscreen    = ifaceProps + ".CanSetFullscreen"
	propCanRaise            = ifaceProps + ".CanRaise"
	propHasTrackList        = ifaceProps + ".HasTrackList"
	propIdentity            = ifaceProps + ".Identity"
	propSupportedUriSchemes = ifaceProps + ".SupportedUriSchemes"
	propSupportedMimeTypes  = ifaceProps + ".SupportedMimeTypes"
	propCanGoNext           = ifaceProps + ".CanGoNext"
	propCanGoPrevious       = ifaceProps + ".CanGoPrevious"
	propCanSeek             = ifaceProps + ".CanSeek"
	propCanControl          = ifaceProps + ".CanControl"
	propCanPlay             = ifaceProps + ".CanPlay"
	propCanPause            = ifaceProps + ".CanPause"
	cmdNext                 = ifaceOmxPlayer + ".Next"
	cmdPrevious             = ifaceOmxPlayer + ".Previous"
	cmdPause                = ifaceOmxPlayer + ".Pause"
	cmdPlayPause            = ifaceOmxPlayer + ".PlayPause"
	cmdStop                 = ifaceOmxPlayer + ".Stop"
	cmdSeek                 = ifaceOmxPlayer + ".Seek"
	cmdSetPosition          = ifaceOmxPlayer + ".SetPosition"
	propPlaybackStatus      = ifaceProps + ".PlaybackStatus"
	cmdVolume               = ifaceProps + ".Volume"
	cmdMute                 = ifaceProps + ".Mute"
	cmdUnmute               = ifaceProps + ".Unmute"
	propPosition            = ifaceProps + ".Position"
	propAspect              = ifaceProps + ".Aspect"
	propVideoStreamCount    = ifaceProps + ".VideoStreamCount"
	propResWidth            = ifaceProps + ".ResWidth"
	propResHeight           = ifaceProps + ".ResHeight"
	propDuration            = ifaceProps + ".Duration"
	propMinimumRate         = ifaceProps + ".MinimumRate"
	propMaximumRate         = ifaceProps + ".MaximumRate"
	cmdListSubtitles        = ifaceOmxPlayer + ".ListSubtitles"
	cmdHideVideo            = ifaceOmxPlayer + ".HideVideo"
	cmdUnHideVideo          = ifaceOmxPlayer + ".UnHideVideo"
	cmdListAudio            = ifaceOmxPlayer + ".ListAudio"
	cmdListVideo            = ifaceOmxPlayer + ".ListVideo"
	cmdSelectSubtitle       = ifaceOmxPlayer + ".SelectSubtitle"
	cmdSelectAudio          = ifaceOmxPlayer + ".SelectAudio"
	cmdShowSubtitles        = ifaceOmxPlayer + ".ShowSubtitles"
	cmdHideSubtitles        = ifaceOmxPlayer + ".HideSubtitles"
	cmdAction               = ifaceOmxPlayer + ".Action"
)

type Player struct {
	bus *dbus.Object
}

func (p *Player) Quit() error {
	return dbusCall(p.bus, cmdQuit)
}

func (p *Player) CanQuit() (bool, error) {
	return dbusGetBool(p.bus, propCanQuit)
}

func (p *Player) Fullscreen() (bool, error) {
	return dbusGetBool(p.bus, propFullscreen)
}

func (p *Player) CanSetFullscreen() (bool, error) {
	return dbusGetBool(p.bus, propCanSetFullscreen)
}

func (p *Player) CanRaise() (bool, error) {
	return dbusGetBool(p.bus, propCanRaise)
}

func (p *Player) HasTrackList() (bool, error) {
	return dbusGetBool(p.bus, propHasTrackList)
}

func (p *Player) Identity() (string, error) {
	return dbusGetString(p.bus, propIdentity)
}

func (p *Player) SupportedUriSchemes() ([]string, error) {
	return dbusGetStringArray(p.bus, propSupportedUriSchemes)
}

func (p *Player) SupportedMimeTypes() ([]string, error) {
	return dbusGetStringArray(p.bus, propSupportedMimeTypes)
}

func (p *Player) CanGoNext() (bool, error) {
	return dbusGetBool(p.bus, propCanGoNext)
}

func (p *Player) CanGoPrevious() (bool, error) {
	return dbusGetBool(p.bus, propCanGoPrevious)
}

func (p *Player) CanSeek() (bool, error) {
	return dbusGetBool(p.bus, cmdSeek)
}

func (p *Player) CanControl() (bool, error) {
	return dbusGetBool(p.bus, propCanControl)
}

func (p *Player) CanPlay() (bool, error) {
	return dbusGetBool(p.bus, propCanPlay)
}

func (p *Player) CanPause() (bool, error) {
	return dbusGetBool(p.bus, propCanPause)
}

func (p *Player) Next() error {
	return dbusCall(p.bus, cmdNext)
}

func (p *Player) Previous() error {
	return dbusCall(p.bus, cmdPrevious)
}

func (p *Player) Pause() error {
	return dbusCall(p.bus, cmdPause)
}

func (p *Player) PlayPause() error {
	return dbusCall(p.bus, cmdPlayPause)
}

func (p *Player) Stop() error {
	return dbusCall(p.bus, cmdStop)
}

func (p *Player) Seek(amount int64) (int64, error) {
	return 0, fmt.Errorf("omxplayer: not implemented yet")
}

func (p *Player) SetPosition(path string, position int64) (int64, error) {
	return 0, fmt.Errorf("omxplayer: not implemented yet")
}

func (p *Player) PlaybackStatus() (string, error) {
	return dbusGetString(p.bus, propPlaybackStatus)
}

func (p *Player) Volume(volume ...float64) (float64, error) {
	return 0, fmt.Errorf("omxplayer: not implemented yet")
}

func (p *Player) Mute() error {
	return dbusCall(p.bus, cmdMute)
}

func (p *Player) Unmute() error {
	return dbusCall(p.bus, cmdUnmute)
}

func (p *Player) Position() (int64, error) {
	return dbusGetInt64(p.bus, propPosition)
}

func (p *Player) Aspect() (float64, error) {
	return dbusGetFloat64(p.bus, propAspect)
}

func (p *Player) VideoStreamCount() (int64, error) {
	return dbusGetInt64(p.bus, propVideoStreamCount)
}

func (p *Player) ResWidth() (int64, error) {
	return dbusGetInt64(p.bus, propResWidth)
}

func (p *Player) ResHeight() (int64, error) {
	return dbusGetInt64(p.bus, propResHeight)
}

func (p *Player) Duration() (int64, error) {
	return dbusGetInt64(p.bus, propDuration)
}

func (p *Player) MinimumRate() (float64, error) {
	return dbusGetFloat64(p.bus, propMinimumRate)
}

func (p *Player) MaximumRate() (float64, error) {
	return dbusGetFloat64(p.bus, propMaximumRate)
}

func (p *Player) ListSubtitles() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListSubtitles)
}

func (p *Player) HideVideo() error {
	return dbusCall(p.bus, cmdHideVideo)
}

func (p *Player) UnHideVideo() error {
	return dbusCall(p.bus, cmdUnHideVideo)
}

func (p *Player) ListAudio() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListAudio)
}

func (p *Player) ListVideo() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListVideo)
}

func (p *Player) SelectSubtitle(index int32) (bool, error) {
	return false, fmt.Errorf("omxplayer: not implemented yet")
}

func (p *Player) SelectAudio(index int32) (bool, error) {
	return false, fmt.Errorf("omxplayer: not implemented yet")
}

func (p *Player) ShowSubtitles() error {
	return dbusCall(p.bus, cmdShowSubtitles)
}

func (p *Player) HideSubtitles() error {
	return dbusCall(p.bus, cmdHideSubtitles)
}

func (p *Player) Action(action int32) error {
	return fmt.Errorf("omxplayer: not implemented yet")
}
<commit_msg>Implement D-Bus methods with parameters.<commit_after>package omxplayer

import (
	log "github.com/Sirupsen/logrus"
	"github.com/guelfey/go.dbus"
)

const (
	ifaceProps     = "org.freedesktop.DBus.Properties"
	ifaceOmxRoot   = ifaceMpris
	ifaceOmxPlayer = ifaceOmxRoot + ".Player"

	cmdQuit                 = ifaceOmxRoot + ".Quit"
	propCanQuit             = ifaceProps + ".CanQuit"
	propFullscreen          = ifaceProps + ".Fullscreen"
	propCanSetFullscreen    = ifaceProps + ".CanSetFullscreen"
	propCanRaise            = ifaceProps + ".CanRaise"
	propHasTrackList        = ifaceProps + ".HasTrackList"
	propIdentity            = ifaceProps + ".Identity"
	propSupportedUriSchemes = ifaceProps + ".SupportedUriSchemes"
	propSupportedMimeTypes  = ifaceProps + ".SupportedMimeTypes"
	propCanGoNext           = ifaceProps + ".CanGoNext"
	propCanGoPrevious       = ifaceProps + ".CanGoPrevious"
	propCanSeek             = ifaceProps + ".CanSeek"
	propCanControl          = ifaceProps + ".CanControl"
	propCanPlay             = ifaceProps + ".CanPlay"
	propCanPause            = ifaceProps + ".CanPause"
	cmdNext                 = ifaceOmxPlayer + ".Next"
	cmdPrevious             = ifaceOmxPlayer + ".Previous"
	cmdPause                = ifaceOmxPlayer + ".Pause"
	cmdPlayPause            = ifaceOmxPlayer + ".PlayPause"
	cmdStop                 = ifaceOmxPlayer + ".Stop"
	cmdSeek                 = ifaceOmxPlayer + ".Seek"
	cmdSetPosition          = ifaceOmxPlayer + ".SetPosition"
	propPlaybackStatus      = ifaceProps + ".PlaybackStatus"
	cmdVolume               = ifaceProps + ".Volume"
	cmdMute                 = ifaceProps + ".Mute"
	cmdUnmute               = ifaceProps + ".Unmute"
	propPosition            = ifaceProps + ".Position"
	propAspect              = ifaceProps + ".Aspect"
	propVideoStreamCount    = ifaceProps + ".VideoStreamCount"
	propResWidth            = ifaceProps + ".ResWidth"
	propResHeight           = ifaceProps + ".ResHeight"
	propDuration            = ifaceProps + ".Duration"
	propMinimumRate         = ifaceProps + ".MinimumRate"
	propMaximumRate         = ifaceProps + ".MaximumRate"
	cmdListSubtitles        = ifaceOmxPlayer + ".ListSubtitles"
	cmdHideVideo            = ifaceOmxPlayer + ".HideVideo"
	cmdUnHideVideo          = ifaceOmxPlayer + ".UnHideVideo"
	cmdListAudio            = ifaceOmxPlayer + ".ListAudio"
	cmdListVideo            = ifaceOmxPlayer + ".ListVideo"
	cmdSelectSubtitle       = ifaceOmxPlayer + ".SelectSubtitle"
	cmdSelectAudio          = ifaceOmxPlayer + ".SelectAudio"
	cmdShowSubtitles        = ifaceOmxPlayer + ".ShowSubtitles"
	cmdHideSubtitles        = ifaceOmxPlayer + ".HideSubtitles"
	cmdAction               = ifaceOmxPlayer + ".Action"
)

type Player struct {
	bus *dbus.Object
}

func (p *Player) Quit() error {
	return dbusCall(p.bus, cmdQuit)
}

func (p *Player) CanQuit() (bool, error) {
	return dbusGetBool(p.bus, propCanQuit)
}

func (p *Player) Fullscreen() (bool, error) {
	return dbusGetBool(p.bus, propFullscreen)
}

func (p *Player) CanSetFullscreen() (bool, error) {
	return dbusGetBool(p.bus, propCanSetFullscreen)
}

func (p *Player) CanRaise() (bool, error) {
	return dbusGetBool(p.bus, propCanRaise)
}

func (p *Player) HasTrackList() (bool, error) {
	return dbusGetBool(p.bus, propHasTrackList)
}

func (p *Player) Identity() (string, error) {
	return dbusGetString(p.bus, propIdentity)
}

func (p *Player) SupportedUriSchemes() ([]string, error) {
	return dbusGetStringArray(p.bus, propSupportedUriSchemes)
}

func (p *Player) SupportedMimeTypes() ([]string, error) {
	return dbusGetStringArray(p.bus, propSupportedMimeTypes)
}

func (p *Player) CanGoNext() (bool, error) {
	return dbusGetBool(p.bus, propCanGoNext)
}

func (p *Player) CanGoPrevious() (bool, error) {
	return dbusGetBool(p.bus, propCanGoPrevious)
}

func (p *Player) CanSeek() (bool, error) {
	return dbusGetBool(p.bus, cmdSeek)
}

func (p *Player) CanControl() (bool, error) {
	return dbusGetBool(p.bus, propCanControl)
}

func (p *Player) CanPlay() (bool, error) {
	return dbusGetBool(p.bus, propCanPlay)
}

func (p *Player) CanPause() (bool, error) {
	return dbusGetBool(p.bus, propCanPause)
}

func (p *Player) Next() error {
	return dbusCall(p.bus, cmdNext)
}

func (p *Player) Previous() error {
	return dbusCall(p.bus, cmdPrevious)
}

func (p *Player) Pause() error {
	return dbusCall(p.bus, cmdPause)
}

func (p *Player) PlayPause() error {
	return dbusCall(p.bus, cmdPlayPause)
}

func (p *Player) Stop() error {
	return dbusCall(p.bus, cmdStop)
}

func (p *Player) Seek(amount int64) (int64, error) {
	log.WithFields(log.Fields{
		"path":        cmdSeek,
		"paramAmount": amount,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSeek, 0, amount)
	if call.Err != nil {
		return 0, call.Err
	}
	return call.Body[0].(int64), nil
}

func (p *Player) SetPosition(path string, position int64) (int64, error) {
	log.WithFields(log.Fields{
		"path":          cmdSetPosition,
		"paramPath":     path,
		"paramPosition": position,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSetPosition, 0, path, position)
	if call.Err != nil {
		return 0, call.Err
	}
	return call.Body[0].(int64), nil
}

func (p *Player) PlaybackStatus() (string, error) {
	return dbusGetString(p.bus, propPlaybackStatus)
}

func (p *Player) Volume(volume ...float64) (float64, error) {
	log.WithFields(log.Fields{
		"path":        cmdVolume,
		"paramVolume": volume,
	}).Debug("omxplayer: dbus call")
	if len(volume) == 0 {
		return dbusGetFloat64(p.bus, cmdVolume)
	}
	call := p.bus.Call(cmdVolume, 0, volume[0])
	if call.Err != nil {
		return 0, call.Err
	}
	return call.Body[0].(float64), nil
}

func (p *Player) Mute() error {
	return dbusCall(p.bus, cmdMute)
}

func (p *Player) Unmute() error {
	return dbusCall(p.bus, cmdUnmute)
}

func (p *Player) Position() (int64, error) {
	return dbusGetInt64(p.bus, propPosition)
}

func (p *Player) Aspect() (float64, error) {
	return dbusGetFloat64(p.bus, propAspect)
}

func (p *Player) VideoStreamCount() (int64, error) {
	return dbusGetInt64(p.bus, propVideoStreamCount)
}

func (p *Player) ResWidth() (int64, error) {
	return dbusGetInt64(p.bus, propResWidth)
}

func (p *Player) ResHeight() (int64, error) {
	return dbusGetInt64(p.bus, propResHeight)
}

func (p *Player) Duration() (int64, error) {
	return dbusGetInt64(p.bus, propDuration)
}

func (p *Player) MinimumRate() (float64, error) {
	return dbusGetFloat64(p.bus, propMinimumRate)
}

func (p *Player) MaximumRate() (float64, error) {
	return dbusGetFloat64(p.bus, propMaximumRate)
}

func (p *Player) ListSubtitles() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListSubtitles)
}

func (p *Player) HideVideo() error {
	return dbusCall(p.bus, cmdHideVideo)
}

func (p *Player) UnHideVideo() error {
	return dbusCall(p.bus, cmdUnHideVideo)
}

func (p *Player) ListAudio() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListAudio)
}

func (p *Player) ListVideo() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListVideo)
}

func (p *Player) SelectSubtitle(index int32) (bool, error) {
	log.WithFields(log.Fields{
		"path":       cmdSelectSubtitle,
		"paramIndex": index,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSelectSubtitle, 0, index)
	if call.Err != nil {
		return false, call.Err
	}
	return call.Body[0].(bool), nil
}

func (p *Player) SelectAudio(index int32) (bool, error) {
	log.WithFields(log.Fields{
		"path":       cmdSelectAudio,
		"paramIndex": index,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSelectAudio, 0, index)
	if call.Err != nil {
		return false, call.Err
	}
	return call.Body[0].(bool), nil
}

func (p *Player) ShowSubtitles() error {
	return dbusCall(p.bus, cmdShowSubtitles)
}

func (p *Player) HideSubtitles() error {
	return dbusCall(p.bus, cmdHideSubtitles)
}

func (p *Player) Action(action int32) error {
	log.WithFields(log.Fields{
		"path":        cmdAction,
		"paramAction": action,
	}).Debug("omxplayer: dbus call")
	return p.bus.Call(cmdAction, 0, action).Err
}
<|endoftext|>


<commit_before>package vlc

// #cgo LDFLAGS: -lvlc
// #include <vlc/vlc.h>
// #include <stdlib.h>
import "C"
import (
	"errors"
	"unsafe"
)

// Player is a media player used to play a single media file.
// For playing media lists (playlists) use ListPlayer instead.
type Player struct {
	player *C.libvlc_media_player_t
}

// NewPlayer creates an instance of a single-media player.
func NewPlayer() (*Player, error) {
	if instance == nil {
		return nil, errors.New("Module must be initialized first")
	}

	if player := C.libvlc_media_player_new(instance); player != nil {
		return &Player{player: player}, nil
	}

	return nil, getError()
}

// Release destroys the media player instance.
func (p *Player) Release() error {
	if p.player == nil {
		return nil
	}

	C.libvlc_media_player_release(p.player)
	p.player = nil

	return getError()
}

// Play plays the current media.
func (p *Player) Play() error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}
	if p.IsPlaying() {
		return nil
	}

	if C.libvlc_media_player_play(p.player) < 0 {
		return getError()
	}

	return nil
}

// IsPlaying returns a boolean value specifying if the player is currently
// playing.
func (p *Player) IsPlaying() bool {
	if p.player == nil {
		return false
	}

	return C.libvlc_media_player_is_playing(p.player) != 0
}

// Stop cancels the currently playing media, if there is one.
func (p *Player) Stop() error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}
	if !p.IsPlaying() {
		return nil
	}

	C.libvlc_media_player_stop(p.player)
	return getError()
}

// SetPause sets the pause state of the media player.
// Pass in true to pause the current media, or false to resume it.
func (p *Player) SetPause(pause bool) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_media_player_set_pause(p.player, C.int(boolToInt(pause)))
	return getError()
}

// TogglePause pauses/resumes the player.
// Calling this method has no effect if there is no media.
func (p *Player) TogglePause() error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_media_player_pause(p.player)
	return getError()
}

// SetFullScreen sets the fullscreen state of the media player.
// Pass in true to enable fullscreen, or false to disable it.
func (p *Player) SetFullScreen(fullscreen bool) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_set_fullscreen(p.player, C.int(boolToInt(fullscreen)))
	return getError()
}

// ToggleFullScreen toggles the fullscreen status of the player,
// on non-embedded video outputs.
func (p *Player) ToggleFullScreen() error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_toggle_fullscreen(p.player)
	return getError()
}

// IsFullScreen gets the fullscreen status of the current player.
func (p *Player) IsFullScreen() (bool, error) {
	if p.player == nil {
		return false, errors.New("A player must be initialized first")
	}

	return (C.libvlc_get_fullscreen(p.player) != C.int(0)), getError()
}

// Volume returns the volume of the player.
func (p *Player) Volume() (int, error) {
	if p.player == nil {
		return 0, errors.New("A player must be initialized first")
	}

	return int(C.libvlc_audio_get_volume(p.player)), getError()
}

// SetVolume sets the volume of the player.
func (p *Player) SetVolume(volume int) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_audio_set_volume(p.player, C.int(volume))
	return getError()
}

// Media returns the current media of the player, if one exists.
func (p *Player) Media() (*Media, error) {
	if p.player == nil {
		return nil, errors.New("A player must be initialized first")
	}

	media := C.libvlc_media_player_get_media(p.player)
	if media == nil {
		return nil, nil
	}

	// This call will not release the media. Instead, it will decrement
	// the reference count increased by libvlc_media_player_get_media.
	C.libvlc_media_release(media)

	return &Media{media}, nil
}

// SetMedia sets the provided media as the current media of the player.
func (p *Player) SetMedia(m *Media) error {
	return p.setMedia(m)
}

// LoadMediaFromPath loads the media from the specified path and adds it as the
// current media of the player.
func (p *Player) LoadMediaFromPath(path string) (*Media, error) {
	return p.loadMedia(path, true)
}

// LoadMediaFromURL loads the media from the specified URL and adds it as the
// current media of the player.
func (p *Player) LoadMediaFromURL(url string) (*Media, error) {
	return p.loadMedia(url, false)
}

// SetAudioOutput selects an audio output module.
// Any change will take be effect only after playback is stopped and restarted.
// Audio output cannot be changed while playing.
func (p *Player) SetAudioOutput(output string) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	cOutput := C.CString(output)
	defer C.free(unsafe.Pointer(cOutput))

	if C.libvlc_audio_output_set(p.player, cOutput) != 0 {
		return getError()
	}

	return nil
}

// MediaLength returns media length in milliseconds.
func (p *Player) MediaLength() (int, error) {
	if p.player == nil {
		return 0, errors.New("A player must be initialized first")
	}

	return int(C.libvlc_media_player_get_length(p.player)), getError()
}

// MediaState returns the state of the current media.
func (p *Player) MediaState() (MediaState, error) {
	if p.player == nil {
		return 0, errors.New("A player must be initialized first")
	}

	state := int(C.libvlc_media_player_get_state(p.player))
	return MediaState(state), getError()
}

// MediaPosition returns media position as a
// float percentage between 0.0 and 1.0.
func (p *Player) MediaPosition() (float32, error) {
	if p.player == nil {
		return 0, errors.New("A player must be initialized first")
	}

	return float32(C.libvlc_media_player_get_position(p.player)), getError()
}

// SetMediaPosition sets media position as percentage between 0.0 and 1.0.
// Some formats and protocols do not support this.
func (p *Player) SetMediaPosition(pos float32) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_media_player_set_position(p.player, C.float(pos))
	return getError()
}

// MediaTime returns media time in milliseconds.
func (p *Player) MediaTime() (int, error) {
	if p.player == nil {
		return 0, errors.New("A player must be initialized first")
	}

	return int(C.libvlc_media_player_get_time(p.player)), getError()
}

// SetMediaTime sets the media time in milliseconds.
// Some formats and protocals do not support this.
func (p *Player) SetMediaTime(t int) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_media_player_set_time(p.player, C.libvlc_time_t(int64(t)))
	return getError()
}

// WillPlay returns true if the current media is not in a
// finished or error state.
func (p *Player) WillPlay() bool {
	if p.player == nil {
		return false
	}

	return C.libvlc_media_player_will_play(p.player) != 0
}

func (p *Player) loadMedia(path string, local bool) (*Media, error) {
	m, err := newMedia(path, local)
	if err != nil {
		return nil, err
	}

	if err = p.setMedia(m); err != nil {
		m.Release()
		return nil, err
	}

	return m, nil
}

func (p *Player) setMedia(m *Media) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}
	if m.media == nil {
		return errors.New("The media must be initialized first")
	}

	C.libvlc_media_player_set_media(p.player, m.media)
	return getError()
}

func (p *Player) setXWindow(XID uint32) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}
	C.libvlc_media_player_set_xwindow(p.player, C.uint(XID))
	return getError()
}
<commit_msg>export the new function<commit_after>package vlc

// #cgo LDFLAGS: -lvlc
// #include <vlc/vlc.h>
// #include <stdlib.h>
import "C"
import (
	"errors"
	"unsafe"
)

// Player is a media player used to play a single media file.
// For playing media lists (playlists) use ListPlayer instead.
type Player struct {
	player *C.libvlc_media_player_t
}

// NewPlayer creates an instance of a single-media player.
func NewPlayer() (*Player, error) {
	if instance == nil {
		return nil, errors.New("Module must be initialized first")
	}

	if player := C.libvlc_media_player_new(instance); player != nil {
		return &Player{player: player}, nil
	}

	return nil, getError()
}

// Release destroys the media player instance.
func (p *Player) Release() error {
	if p.player == nil {
		return nil
	}

	C.libvlc_media_player_release(p.player)
	p.player = nil

	return getError()
}

// Play plays the current media.
func (p *Player) Play() error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}
	if p.IsPlaying() {
		return nil
	}

	if C.libvlc_media_player_play(p.player) < 0 {
		return getError()
	}

	return nil
}

// IsPlaying returns a boolean value specifying if the player is currently
// playing.
func (p *Player) IsPlaying() bool {
	if p.player == nil {
		return false
	}

	return C.libvlc_media_player_is_playing(p.player) != 0
}

// Stop cancels the currently playing media, if there is one.
func (p *Player) Stop() error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}
	if !p.IsPlaying() {
		return nil
	}

	C.libvlc_media_player_stop(p.player)
	return getError()
}

// SetPause sets the pause state of the media player.
// Pass in true to pause the current media, or false to resume it.
func (p *Player) SetPause(pause bool) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_media_player_set_pause(p.player, C.int(boolToInt(pause)))
	return getError()
}

// TogglePause pauses/resumes the player.
// Calling this method has no effect if there is no media.
func (p *Player) TogglePause() error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_media_player_pause(p.player)
	return getError()
}

// SetFullScreen sets the fullscreen state of the media player.
// Pass in true to enable fullscreen, or false to disable it.
func (p *Player) SetFullScreen(fullscreen bool) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_set_fullscreen(p.player, C.int(boolToInt(fullscreen)))
	return getError()
}

// ToggleFullScreen toggles the fullscreen status of the player,
// on non-embedded video outputs.
func (p *Player) ToggleFullScreen() error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_toggle_fullscreen(p.player)
	return getError()
}

// IsFullScreen gets the fullscreen status of the current player.
func (p *Player) IsFullScreen() (bool, error) {
	if p.player == nil {
		return false, errors.New("A player must be initialized first")
	}

	return (C.libvlc_get_fullscreen(p.player) != C.int(0)), getError()
}

// Volume returns the volume of the player.
func (p *Player) Volume() (int, error) {
	if p.player == nil {
		return 0, errors.New("A player must be initialized first")
	}

	return int(C.libvlc_audio_get_volume(p.player)), getError()
}

// SetVolume sets the volume of the player.
func (p *Player) SetVolume(volume int) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_audio_set_volume(p.player, C.int(volume))
	return getError()
}

// Media returns the current media of the player, if one exists.
func (p *Player) Media() (*Media, error) {
	if p.player == nil {
		return nil, errors.New("A player must be initialized first")
	}

	media := C.libvlc_media_player_get_media(p.player)
	if media == nil {
		return nil, nil
	}

	// This call will not release the media. Instead, it will decrement
	// the reference count increased by libvlc_media_player_get_media.
	C.libvlc_media_release(media)

	return &Media{media}, nil
}

// SetMedia sets the provided media as the current media of the player.
func (p *Player) SetMedia(m *Media) error {
	return p.setMedia(m)
}

// LoadMediaFromPath loads the media from the specified path and adds it as the
// current media of the player.
func (p *Player) LoadMediaFromPath(path string) (*Media, error) {
	return p.loadMedia(path, true)
}

// LoadMediaFromURL loads the media from the specified URL and adds it as the
// current media of the player.
func (p *Player) LoadMediaFromURL(url string) (*Media, error) {
	return p.loadMedia(url, false)
}

// SetAudioOutput selects an audio output module.
// Any change will take be effect only after playback is stopped and restarted.
// Audio output cannot be changed while playing.
func (p *Player) SetAudioOutput(output string) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	cOutput := C.CString(output)
	defer C.free(unsafe.Pointer(cOutput))

	if C.libvlc_audio_output_set(p.player, cOutput) != 0 {
		return getError()
	}

	return nil
}

// MediaLength returns media length in milliseconds.
func (p *Player) MediaLength() (int, error) {
	if p.player == nil {
		return 0, errors.New("A player must be initialized first")
	}

	return int(C.libvlc_media_player_get_length(p.player)), getError()
}

// MediaState returns the state of the current media.
func (p *Player) MediaState() (MediaState, error) {
	if p.player == nil {
		return 0, errors.New("A player must be initialized first")
	}

	state := int(C.libvlc_media_player_get_state(p.player))
	return MediaState(state), getError()
}

// MediaPosition returns media position as a
// float percentage between 0.0 and 1.0.
func (p *Player) MediaPosition() (float32, error) {
	if p.player == nil {
		return 0, errors.New("A player must be initialized first")
	}

	return float32(C.libvlc_media_player_get_position(p.player)), getError()
}

// SetMediaPosition sets media position as percentage between 0.0 and 1.0.
// Some formats and protocols do not support this.
func (p *Player) SetMediaPosition(pos float32) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_media_player_set_position(p.player, C.float(pos))
	return getError()
}

// MediaTime returns media time in milliseconds.
func (p *Player) MediaTime() (int, error) {
	if p.player == nil {
		return 0, errors.New("A player must be initialized first")
	}

	return int(C.libvlc_media_player_get_time(p.player)), getError()
}

// SetMediaTime sets the media time in milliseconds.
// Some formats and protocals do not support this.
func (p *Player) SetMediaTime(t int) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}

	C.libvlc_media_player_set_time(p.player, C.libvlc_time_t(int64(t)))
	return getError()
}

// WillPlay returns true if the current media is not in a
// finished or error state.
func (p *Player) WillPlay() bool {
	if p.player == nil {
		return false
	}

	return C.libvlc_media_player_will_play(p.player) != 0
}

func (p *Player) loadMedia(path string, local bool) (*Media, error) {
	m, err := newMedia(path, local)
	if err != nil {
		return nil, err
	}

	if err = p.setMedia(m); err != nil {
		m.Release()
		return nil, err
	}

	return m, nil
}

func (p *Player) setMedia(m *Media) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}
	if m.media == nil {
		return errors.New("The media must be initialized first")
	}

	C.libvlc_media_player_set_media(p.player, m.media)
	return getError()
}

// SetXWindow sets the X window to play on
func (p *Player) SetXWindow(XID uint32) error {
	if p.player == nil {
		return errors.New("A player must be initialized first")
	}
	C.libvlc_media_player_set_xwindow(p.player, C.uint(XID))
	return getError()
}
<|endoftext|>