<commit_before>// Package fluentd provides the log driver for forwarding server logs
// to fluentd endpoints.
package fluentd

import (
	"fmt"
	"math"
	"net"
	"net/url"
	"strconv"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/daemon/logger"
	"github.com/docker/docker/daemon/logger/loggerutils"
	"github.com/docker/docker/pkg/urlutil"
	"github.com/docker/go-units"
	"github.com/fluent/fluent-logger-golang/fluent"
	"github.com/pkg/errors"
)

type fluentd struct {
	tag           string
	containerID   string
	containerName string
	writer        *fluent.Fluent
	extra         map[string]string
}

type location struct {
	protocol string
	host     string
	port     int
	path     string
}

const (
	name = "fluentd"

	defaultProtocol    = "tcp"
	defaultHost        = "127.0.0.1"
	defaultPort        = 24224
	defaultBufferLimit = 1024 * 1024

	// logger tries to reconnect 2**32 - 1 times
	// failed (and panic) after 204 years [ 1.5 ** (2**32 - 1) - 1 seconds]
	defaultRetryWait  = 1000
	defaultMaxRetries = math.MaxInt32

	addressKey      = "fluentd-address"
	bufferLimitKey  = "fluentd-buffer-limit"
	retryWaitKey    = "fluentd-retry-wait"
	maxRetriesKey   = "fluentd-max-retries"
	asyncConnectKey = "fluentd-async-connect"
)

func init() {
	if err := logger.RegisterLogDriver(name, New); err != nil {
		logrus.Fatal(err)
	}
	if err := logger.RegisterLogOptValidator(name, ValidateLogOpt); err != nil {
		logrus.Fatal(err)
	}
}

// New creates a fluentd logger using the configuration passed in on
// the context. The supported context configuration variable is
// fluentd-address.
func New(info logger.Info) (logger.Logger, error) {
	loc, err := parseAddress(info.Config[addressKey])
	if err != nil {
		return nil, err
	}

	tag, err := loggerutils.ParseLogTag(info, loggerutils.DefaultTemplate)
	if err != nil {
		return nil, err
	}

	extra, err := info.ExtraAttributes(nil)
	if err != nil {
		return nil, err
	}

	bufferLimit := defaultBufferLimit
	if info.Config[bufferLimitKey] != "" {
		bl64, err := units.RAMInBytes(info.Config[bufferLimitKey])
		if err != nil {
			return nil, err
		}
		bufferLimit = int(bl64)
	}

	retryWait := defaultRetryWait
	if info.Config[retryWaitKey] != "" {
		rwd, err := time.ParseDuration(info.Config[retryWaitKey])
		if err != nil {
			return nil, err
		}
		retryWait = int(rwd.Seconds() * 1000)
	}

	maxRetries := defaultMaxRetries
	if info.Config[maxRetriesKey] != "" {
		mr64, err := strconv.ParseUint(info.Config[maxRetriesKey], 10, strconv.IntSize)
		if err != nil {
			return nil, err
		}
		maxRetries = int(mr64)
	}

	asyncConnect := false
	if info.Config[asyncConnectKey] != "" {
		if asyncConnect, err = strconv.ParseBool(info.Config[asyncConnectKey]); err != nil {
			return nil, err
		}
	}

	fluentConfig := fluent.Config{
		FluentPort:       loc.port,
		FluentHost:       loc.host,
		FluentNetwork:    loc.protocol,
		FluentSocketPath: loc.path,
		BufferLimit:      bufferLimit,
		RetryWait:        retryWait,
		MaxRetry:         maxRetries,
		AsyncConnect:     asyncConnect,
	}

	logrus.WithField("container", info.ContainerID).WithField("config", fluentConfig).
		Debug("logging driver fluentd configured")

	log, err := fluent.New(fluentConfig)
	if err != nil {
		return nil, err
	}
	return &fluentd{
		tag:           tag,
		containerID:   info.ContainerID,
		containerName: info.ContainerName,
		writer:        log,
		extra:         extra,
	}, nil
}

func (f *fluentd) Log(msg *logger.Message) error {
	data := map[string]string{
		"container_id":   f.containerID,
		"container_name": f.containerName,
		"source":         msg.Source,
		"log":            string(msg.Line),
	}
	for k, v := range f.extra {
		data[k] = v
	}

	ts := msg.Timestamp
	logger.PutMessage(msg)
	// fluent-logger-golang buffers logs from failures and disconnections,
	// and these are transferred again automatically.
	return f.writer.PostWithTime(f.tag, ts, data)
}

func (f *fluentd) Close() error {
	return f.writer.Close()
}

func (f *fluentd) Name() string {
	return name
}

// ValidateLogOpt looks for fluentd specific log option fluentd-address.
func ValidateLogOpt(cfg map[string]string) error {
	for key := range cfg {
		switch key {
		case "env":
		case "env-regex":
		case "labels":
		case "tag":
		case addressKey:
		case bufferLimitKey:
		case retryWaitKey:
		case maxRetriesKey:
		case asyncConnectKey:
			// Accepted
		default:
			return fmt.Errorf("unknown log opt '%s' for fluentd log driver", key)
		}
	}

	_, err := parseAddress(cfg["fluentd-address"])
	return err
}

func parseAddress(address string) (*location, error) {
	if address == "" {
		return &location{
			protocol: defaultProtocol,
			host:     defaultHost,
			port:     defaultPort,
			path:     "",
		}, nil
	}

	protocol := defaultProtocol
	givenAddress := address
	if urlutil.IsTransportURL(address) {
		url, err := url.Parse(address)
		if err != nil {
			return nil, errors.Wrapf(err, "invalid fluentd-address %s", givenAddress)
		}
		// unix and unixgram socket
		if url.Scheme == "unix" || url.Scheme == "unixgram" {
			return &location{
				protocol: url.Scheme,
				host:     "",
				port:     0,
				path:     url.Path,
			}, nil
		}
		// tcp|udp
		protocol = url.Scheme
		address = url.Host
	}

	host, port, err := net.SplitHostPort(address)
	if err != nil {
		if !strings.Contains(err.Error(), "missing port in address") {
			return nil, errors.Wrapf(err, "invalid fluentd-address %s", givenAddress)
		}
		return &location{
			protocol: protocol,
			host:     host,
			port:     defaultPort,
			path:     "",
		}, nil
	}

	portnum, err := strconv.Atoi(port)
	if err != nil {
		return nil, errors.Wrapf(err, "invalid fluentd-address %s", givenAddress)
	}
	return &location{
		protocol: protocol,
		host:     host,
		port:     portnum,
		path:     "",
	}, nil
}
<commit_msg>Replaces fluentd-address string by constant<commit_after>// Package fluentd provides the log driver for forwarding server logs
// to fluentd endpoints.
package fluentd

import (
	"fmt"
	"math"
	"net"
	"net/url"
	"strconv"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/daemon/logger"
	"github.com/docker/docker/daemon/logger/loggerutils"
	"github.com/docker/docker/pkg/urlutil"
	"github.com/docker/go-units"
	"github.com/fluent/fluent-logger-golang/fluent"
	"github.com/pkg/errors"
)

type fluentd struct {
	tag           string
	containerID   string
	containerName string
	writer        *fluent.Fluent
	extra         map[string]string
}

type location struct {
	protocol string
	host     string
	port     int
	path     string
}

const (
	name = "fluentd"

	defaultProtocol    = "tcp"
	defaultHost        = "127.0.0.1"
	defaultPort        = 24224
	defaultBufferLimit = 1024 * 1024

	// logger tries to reconnect 2**32 - 1 times
	// failed (and panic) after 204 years [ 1.5 ** (2**32 - 1) - 1 seconds]
	defaultRetryWait  = 1000
	defaultMaxRetries = math.MaxInt32

	addressKey      = "fluentd-address"
	bufferLimitKey  = "fluentd-buffer-limit"
	retryWaitKey    = "fluentd-retry-wait"
	maxRetriesKey   = "fluentd-max-retries"
	asyncConnectKey = "fluentd-async-connect"
)

func init() {
	if err := logger.RegisterLogDriver(name, New); err != nil {
		logrus.Fatal(err)
	}
	if err := logger.RegisterLogOptValidator(name, ValidateLogOpt); err != nil {
		logrus.Fatal(err)
	}
}

// New creates a fluentd logger using the configuration passed in on
// the context. The supported context configuration variable is
// fluentd-address.
func New(info logger.Info) (logger.Logger, error) {
	loc, err := parseAddress(info.Config[addressKey])
	if err != nil {
		return nil, err
	}

	tag, err := loggerutils.ParseLogTag(info, loggerutils.DefaultTemplate)
	if err != nil {
		return nil, err
	}

	extra, err := info.ExtraAttributes(nil)
	if err != nil {
		return nil, err
	}

	bufferLimit := defaultBufferLimit
	if info.Config[bufferLimitKey] != "" {
		bl64, err := units.RAMInBytes(info.Config[bufferLimitKey])
		if err != nil {
			return nil, err
		}
		bufferLimit = int(bl64)
	}

	retryWait := defaultRetryWait
	if info.Config[retryWaitKey] != "" {
		rwd, err := time.ParseDuration(info.Config[retryWaitKey])
		if err != nil {
			return nil, err
		}
		retryWait = int(rwd.Seconds() * 1000)
	}

	maxRetries := defaultMaxRetries
	if info.Config[maxRetriesKey] != "" {
		mr64, err := strconv.ParseUint(info.Config[maxRetriesKey], 10, strconv.IntSize)
		if err != nil {
			return nil, err
		}
		maxRetries = int(mr64)
	}

	asyncConnect := false
	if info.Config[asyncConnectKey] != "" {
		if asyncConnect, err = strconv.ParseBool(info.Config[asyncConnectKey]); err != nil {
			return nil, err
		}
	}

	fluentConfig := fluent.Config{
		FluentPort:       loc.port,
		FluentHost:       loc.host,
		FluentNetwork:    loc.protocol,
		FluentSocketPath: loc.path,
		BufferLimit:      bufferLimit,
		RetryWait:        retryWait,
		MaxRetry:         maxRetries,
		AsyncConnect:     asyncConnect,
	}

	logrus.WithField("container", info.ContainerID).WithField("config", fluentConfig).
		Debug("logging driver fluentd configured")

	log, err := fluent.New(fluentConfig)
	if err != nil {
		return nil, err
	}
	return &fluentd{
		tag:           tag,
		containerID:   info.ContainerID,
		containerName: info.ContainerName,
		writer:        log,
		extra:         extra,
	}, nil
}

func (f *fluentd) Log(msg *logger.Message) error {
	data := map[string]string{
		"container_id":   f.containerID,
		"container_name": f.containerName,
		"source":         msg.Source,
		"log":            string(msg.Line),
	}
	for k, v := range f.extra {
		data[k] = v
	}

	ts := msg.Timestamp
	logger.PutMessage(msg)
	// fluent-logger-golang buffers logs from failures and disconnections,
	// and these are transferred again automatically.
	return f.writer.PostWithTime(f.tag, ts, data)
}

func (f *fluentd) Close() error {
	return f.writer.Close()
}

func (f *fluentd) Name() string {
	return name
}

// ValidateLogOpt looks for fluentd specific log option fluentd-address.
func ValidateLogOpt(cfg map[string]string) error {
	for key := range cfg {
		switch key {
		case "env":
		case "env-regex":
		case "labels":
		case "tag":
		case addressKey:
		case bufferLimitKey:
		case retryWaitKey:
		case maxRetriesKey:
		case asyncConnectKey:
			// Accepted
		default:
			return fmt.Errorf("unknown log opt '%s' for fluentd log driver", key)
		}
	}

	_, err := parseAddress(cfg[addressKey])
	return err
}

func parseAddress(address string) (*location, error) {
	if address == "" {
		return &location{
			protocol: defaultProtocol,
			host:     defaultHost,
			port:     defaultPort,
			path:     "",
		}, nil
	}

	protocol := defaultProtocol
	givenAddress := address
	if urlutil.IsTransportURL(address) {
		url, err := url.Parse(address)
		if err != nil {
			return nil, errors.Wrapf(err, "invalid fluentd-address %s", givenAddress)
		}
		// unix and unixgram socket
		if url.Scheme == "unix" || url.Scheme == "unixgram" {
			return &location{
				protocol: url.Scheme,
				host:     "",
				port:     0,
				path:     url.Path,
			}, nil
		}
		// tcp|udp
		protocol = url.Scheme
		address = url.Host
	}

	host, port, err := net.SplitHostPort(address)
	if err != nil {
		if !strings.Contains(err.Error(), "missing port in address") {
			return nil, errors.Wrapf(err, "invalid fluentd-address %s", givenAddress)
		}
		return &location{
			protocol: protocol,
			host:     host,
			port:     defaultPort,
			path:     "",
		}, nil
	}

	portnum, err := strconv.Atoi(port)
	if err != nil {
		return nil, errors.Wrapf(err, "invalid fluentd-address %s", givenAddress)
	}
	return &location{
		protocol: protocol,
		host:     host,
		port:     portnum,
		path:     "",
	}, nil
}
<|endoftext|>


<commit_before>package twse

import (
	"fmt"
	"reflect"
	"testing"
	"time"

	"github.com/toomore/gogrs/utils"
)

func assertType(t *testing.T, t1 interface{}, t2 interface{}) {
	if reflect.TypeOf(t1) != reflect.TypeOf(t2) {
		t.Errorf("Diff type t1(%s), t2(%s)", reflect.TypeOf(t1), reflect.TypeOf(t2))
	}
}

func TestURL(t *testing.T) {
	var d = NewTWSE("2618", time.Now())
	assertType(t, d, &Data{})
}

func ExampleData() {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))
	fmt.Println(d)

	stockData, _ := d.Get()
	fmt.Println(stockData)
}

func TestData_Get(*testing.T) {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))
	fmt.Println(d)

	stockData, _ := d.Get()
	d.Get() // Test Cache.
	fmt.Println(stockData)
}

var twse = NewTWSE("2329", time.Date(2015, 03, 20, 0, 0, 0, 0, time.Local))
var otc = NewOTC("8446", time.Date(2015, 03, 20, 0, 0, 0, 0, time.Local))

func TestGetList(*testing.T) {
	for _, stock := range []*Data{twse, otc} {

		fmt.Println(stock)
		fmt.Println(stock.URL())
		stock.Get()
		fmt.Println(stock.RawData)
		fmt.Println(stock.MA(6))
		fmt.Println(stock.MAV(6))
		fmt.Println(stock.GetPriceList())
		fmt.Println(utils.ThanPastFloat64(stock.GetPriceList(), 3, true))
		fmt.Println(utils.ThanPastFloat64(stock.GetPriceList(), 3, false))
		fmt.Println(stock.GetVolumeList())
		fmt.Println(utils.ThanPastUint64(stock.GetVolumeList(), 3, true))
		fmt.Println(utils.ThanPastUint64(stock.GetVolumeList(), 3, false))
		fmt.Println(stock.GetRangeList())
		fmt.Println(stock.GetOpenList())
		fmt.Println(stock.IsRed())
	}
}

func BenchmarkGet(b *testing.B) {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))
	for i := 0; i <= b.N; i++ {
		d.Get()
	}
}

func BenchmarkGetVolumeList(b *testing.B) {
	var d = NewTWSE("2618", time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local))
	d.Get()
	for i := 0; i <= b.N; i++ {
		d.GetVolumeList()
	}
}

func BenchmarkGetPriceList(b *testing.B) {
	var d = NewTWSE("2618", time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local))
	d.Get()
	for i := 0; i <= b.N; i++ {
		d.GetPriceList()
	}
}

// 新增一個 TWSE 上市股票
func Example_newTWSE() {
	var stock = NewTWSE("2618", time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local))
	stock.Get()
	fmt.Println(stock.RawData[0])
	// output:
	// [104/03/02 13,384,378 305,046,992 23.00 23.05 22.50 22.90 -0.10 3,793]
}

// 新增一個 OTC 上櫃股票
func Example_newOTC() {
	var stock = NewOTC("8446", time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local))
	stock.Get()
	fmt.Println(stock.RawData[0])
	// output:
	// [104/03/02 354 33,018 92.00 94.90 90.80 92.60 3.50 299]
}

func ExampleData_Get_notEnoughData() {
	year, month, _ := time.Now().Date()
	var d = NewTWSE("2618", time.Date(year, month+1, 1, 0, 0, 0, 0, time.Local))

	stockData, err := d.Get()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(stockData)
	}
	// output:
	// Not enough data.
}

func ExampleData_PlusData() {
	var stock = NewTWSE("2618", time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local))
	stock.Get() // 2015/3
	fmt.Println(stock.Date)
	stock.PlusData() // 2015/2
	fmt.Println(stock.Date)
	// output:
	// 2015-03-27 00:00:00 +0800 CST
	// 2015-02-01 00:00:00 +0800 CST
}

func ExampleData_Round() {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))

	fmt.Println(d.Date) // 2014/12

	d.Round()
	fmt.Println(d.Date) // 2014/11

	d.Round()
	fmt.Println(d.Date) // 2014/10
	// output:
	// 2014-12-26 00:00:00 +0800 CST
	// 2014-11-01 00:00:00 +0800 CST
	// 2014-10-01 00:00:00 +0800 CST
}

func TestData_Round(t *testing.T) {
	var now = time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local)
	var past = time.Date(2015, 2, 1, 0, 0, 0, 0, time.Local)
	var d = NewTWSE("2618", now)

	t.Log(d.Date)
	if d.Date == past {
		t.Fatal(d.Date, past)
	}
	d.Round()
	t.Log(d.Date)
	if d.Date != past {
		t.Fatal(d.Date, past)
	}
}

func TestData_PlusData(t *testing.T) {
	var now = time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local)
	var d = NewTWSE("2618", now)
	d.PlusData()
	var d2 = NewTWSE("2618", time.Date(2015, 2, 1, 0, 0, 0, 0, time.Local))
	d2.Get()
	for i := range d2.RawData {
		if d.RawData[i][0] != d2.RawData[i][0] {
			t.Fatal("Data not difference.")
			t.Log(d.RawData, d2.RawData)
		}
	}
}

func TestData_GetByTimeMap(*testing.T) {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))
	fmt.Println(d.GetByTimeMap())
}

func TestData_FormatData(*testing.T) {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))
	d.Get()
	fmt.Println(d.FormatData())
}
<commit_msg>Add example in twse.<commit_after>package twse

import (
	"fmt"
	"reflect"
	"testing"
	"time"

	"github.com/toomore/gogrs/utils"
)

func assertType(t *testing.T, t1 interface{}, t2 interface{}) {
	if reflect.TypeOf(t1) != reflect.TypeOf(t2) {
		t.Errorf("Diff type t1(%s), t2(%s)", reflect.TypeOf(t1), reflect.TypeOf(t2))
	}
}

func TestURL(t *testing.T) {
	var d = NewTWSE("2618", time.Now())
	assertType(t, d, &Data{})
}

func ExampleData() {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))

	stockData, _ := d.Get()
	fmt.Println(stockData[0])
	// output:
	// [103/12/01 64,418,143 1,350,179,448 20.20 21.40 20.20 21.35 +1.35 13,249]
}

func TestData_Get(*testing.T) {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))
	fmt.Println(d)

	stockData, _ := d.Get()
	d.Get() // Test Cache.
	fmt.Println(stockData)
}

var twse = NewTWSE("2329", time.Date(2015, 03, 20, 0, 0, 0, 0, time.Local))
var otc = NewOTC("8446", time.Date(2015, 03, 20, 0, 0, 0, 0, time.Local))

func TestGetList(*testing.T) {
	for _, stock := range []*Data{twse, otc} {

		fmt.Println(stock)
		fmt.Println(stock.URL())
		stock.Get()
		fmt.Println(stock.RawData)
		fmt.Println(stock.MA(6))
		fmt.Println(stock.MAV(6))
		fmt.Println(stock.GetPriceList())
		fmt.Println(utils.ThanPastFloat64(stock.GetPriceList(), 3, true))
		fmt.Println(utils.ThanPastFloat64(stock.GetPriceList(), 3, false))
		fmt.Println(stock.GetVolumeList())
		fmt.Println(utils.ThanPastUint64(stock.GetVolumeList(), 3, true))
		fmt.Println(utils.ThanPastUint64(stock.GetVolumeList(), 3, false))
		fmt.Println(stock.GetRangeList())
		fmt.Println(stock.GetOpenList())
		fmt.Println(stock.IsRed())
	}
}

func BenchmarkGet(b *testing.B) {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))
	for i := 0; i <= b.N; i++ {
		d.Get()
	}
}

func BenchmarkGetVolumeList(b *testing.B) {
	var d = NewTWSE("2618", time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local))
	d.Get()
	for i := 0; i <= b.N; i++ {
		d.GetVolumeList()
	}
}

func BenchmarkGetPriceList(b *testing.B) {
	var d = NewTWSE("2618", time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local))
	d.Get()
	for i := 0; i <= b.N; i++ {
		d.GetPriceList()
	}
}

// 新增一個 TWSE 上市股票
func Example_newTWSE() {
	var stock = NewTWSE("2618", time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local))
	stock.Get()
	fmt.Println(stock.RawData[0])
	// output:
	// [104/03/02 13,384,378 305,046,992 23.00 23.05 22.50 22.90 -0.10 3,793]
}

// 新增一個 OTC 上櫃股票
func Example_newOTC() {
	var stock = NewOTC("8446", time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local))
	stock.Get()
	fmt.Println(stock.RawData[0])
	// output:
	// [104/03/02 354 33,018 92.00 94.90 90.80 92.60 3.50 299]
}

func ExampleData_Get_notEnoughData() {
	year, month, _ := time.Now().Date()
	var d = NewTWSE("2618", time.Date(year, month+1, 1, 0, 0, 0, 0, time.Local))

	stockData, err := d.Get()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(stockData)
	}
	// output:
	// Not enough data.
}

func ExampleData_PlusData() {
	var stock = NewTWSE("2618", time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local))
	stock.Get() // 2015/3
	fmt.Println(stock.Date)
	stock.PlusData() // 2015/2
	fmt.Println(stock.Date)
	// output:
	// 2015-03-27 00:00:00 +0800 CST
	// 2015-02-01 00:00:00 +0800 CST
}

func ExampleData_Round() {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))

	fmt.Println(d.Date) // 2014/12

	d.Round()
	fmt.Println(d.Date) // 2014/11

	d.Round()
	fmt.Println(d.Date) // 2014/10
	// output:
	// 2014-12-26 00:00:00 +0800 CST
	// 2014-11-01 00:00:00 +0800 CST
	// 2014-10-01 00:00:00 +0800 CST
}

func TestData_Round(t *testing.T) {
	var now = time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local)
	var past = time.Date(2015, 2, 1, 0, 0, 0, 0, time.Local)
	var d = NewTWSE("2618", now)

	t.Log(d.Date)
	if d.Date == past {
		t.Fatal(d.Date, past)
	}
	d.Round()
	t.Log(d.Date)
	if d.Date != past {
		t.Fatal(d.Date, past)
	}
}

func TestData_PlusData(t *testing.T) {
	var now = time.Date(2015, 3, 27, 0, 0, 0, 0, time.Local)
	var d = NewTWSE("2618", now)
	d.PlusData()
	var d2 = NewTWSE("2618", time.Date(2015, 2, 1, 0, 0, 0, 0, time.Local))
	d2.Get()
	for i := range d2.RawData {
		if d.RawData[i][0] != d2.RawData[i][0] {
			t.Fatal("Data not difference.")
			t.Log(d.RawData, d2.RawData)
		}
	}
}

func TestData_GetByTimeMap(*testing.T) {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))
	fmt.Println(d.GetByTimeMap())
}

func TestData_FormatData(*testing.T) {
	var d = NewTWSE("2618", time.Date(2014, 12, 26, 0, 0, 0, 0, time.Local))
	d.Get()
	fmt.Println(d.FormatData())
}
<|endoftext|>


<commit_before>// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package formatting

import (
	"bytes"
	"testing"
)

func TestCB58(t *testing.T) {
	addr := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}
	result := CB58{addr}.String()
	expected := "1NVSVezva3bAtJesnUj"
	if result != expected {
		t.Fatalf("Expected %s, got %s", expected, result)
	}
}

func TestCB58Single(t *testing.T) {
	addr := []byte{0}
	result := CB58{addr}.String()
	expected := "1c7hwa"
	if result != expected {
		t.Fatalf("Expected %s, got %s", expected, result)
	}
}

func TestCB58ParseBytes(t *testing.T) {
	ui := "1NVSVezva3bAtJesnUj"
	cb58 := CB58{}
	err := cb58.FromString(ui)
	if err != nil {
		t.Fatalf("Failed to process %s", ui)
	}
	expected := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}
	if !bytes.Equal(cb58.Bytes, expected) {
		t.Fatalf("Expected 0x%x, got 0x%x", expected, cb58.Bytes)
	}
}

func TestCB58ParseBytesSingle(t *testing.T) {
	ui := "1c7hwa"
	cb58 := CB58{}
	err := cb58.FromString(ui)
	if err != nil {
		t.Fatalf("Failed to process %s", ui)
	}
	expected := []byte{0}
	if !bytes.Equal(cb58.Bytes, expected) {
		t.Fatalf("Expected 0x%x, got 0x%x", expected, cb58.Bytes)
	}
}

func TestCB58ParseBytesError(t *testing.T) {
	ui := "0"
	cb58 := CB58{}
	err := cb58.FromString(ui)
	if err == nil {
		t.Fatalf("Incorrectly parsed %s", ui)
	}

	ui = "13pP7vbI"
	err = cb58.FromString(ui)
	if err == nil {
		t.Fatalf("Incorrectly parsed %s", ui)
	}

	ui = "13"
	err = cb58.FromString(ui)
	if err == nil {
		t.Fatalf("Incorrectly parsed %s", ui)
	}

	ui = "13pP7vb3"
	err = cb58.FromString(ui)
	if err == nil {
		t.Fatalf("Incorrectly parsed %s", ui)
	}
}
<commit_msg>utils: Add tests for CB58.UnmarshalJSON<commit_after>// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package formatting

import (
	"bytes"
	"testing"
)

func TestCB58(t *testing.T) {
	addr := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}
	result := CB58{addr}.String()
	expected := "1NVSVezva3bAtJesnUj"
	if result != expected {
		t.Fatalf("Expected %s, got %s", expected, result)
	}
}

func TestCB58Single(t *testing.T) {
	addr := []byte{0}
	result := CB58{addr}.String()
	expected := "1c7hwa"
	if result != expected {
		t.Fatalf("Expected %s, got %s", expected, result)
	}
}

func TestCB58UnmarshalJSON(t *testing.T) {
	expected := CB58{[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}}
	cb58 := CB58{}
	err := cb58.UnmarshalJSON([]byte("\"1NVSVezva3bAtJesnUj\""))
	if err != nil {
		t.Fatalf("CB58.UnmarshalJSON unexpected error unmarshalling: %s", err)
	} else if !bytes.Equal(cb58.Bytes, expected.Bytes) {
		t.Fatalf("CB58.UnmarshalJSON got 0x%x, expected 0x%x", cb58, expected)
	}
}

func TestCB58UnmarshalJSONNull(t *testing.T) {
	cb58 := CB58{}
	err := cb58.UnmarshalJSON([]byte("null"))
	if err != nil {
		t.Fatalf("CB58.UnmarshalJSON unexpected error unmarshalling null: %s", err)
	}
}

func TestCB58UnmarshalJSONError(t *testing.T) {
	tests := []struct {
		in       string
		expected error
	}{
		{"", errMissingQuotes},
		{"\"foo", errMissingQuotes},
		{"foo", errMissingQuotes},
		{"foo\"", errMissingQuotes},
		{"\"foo\"", errMissingChecksum},
		{"\"foobar\"", errBadChecksum},
	}
	cb58 := CB58{}
	for _, tt := range tests {
		t.Run(tt.in, func(t *testing.T) {
			err := cb58.UnmarshalJSON([]byte(tt.in))
			if err != tt.expected {
				t.Errorf("got error %q, expected error %q", err, tt.expected)
			}
		})
	}
}

func TestCB58MarshalJSONError(t *testing.T) {
	cb58 := CB58{[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}}
	expected := []byte("\"1NVSVezva3bAtJesnUj\"")
	result, err := cb58.MarshalJSON()
	if err != nil {
		t.Fatalf("CB58.MarshalJSON unexpected error: %s", err)
	} else if !bytes.Equal(result, expected) {
		t.Fatalf("CB58.MarshalJSON got %q, expected %q", result, expected)
	}
}

func TestCB58ParseBytes(t *testing.T) {
	ui := "1NVSVezva3bAtJesnUj"
	cb58 := CB58{}
	err := cb58.FromString(ui)
	if err != nil {
		t.Fatalf("Failed to process %s", ui)
	}
	expected := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}
	if !bytes.Equal(cb58.Bytes, expected) {
		t.Fatalf("Expected 0x%x, got 0x%x", expected, cb58.Bytes)
	}
}

func TestCB58ParseBytesSingle(t *testing.T) {
	ui := "1c7hwa"
	cb58 := CB58{}
	err := cb58.FromString(ui)
	if err != nil {
		t.Fatalf("Failed to process %s", ui)
	}
	expected := []byte{0}
	if !bytes.Equal(cb58.Bytes, expected) {
		t.Fatalf("Expected 0x%x, got 0x%x", expected, cb58.Bytes)
	}
}

func TestCB58ParseBytesError(t *testing.T) {
	ui := "0"
	cb58 := CB58{}
	err := cb58.FromString(ui)
	if err == nil {
		t.Fatalf("Incorrectly parsed %s", ui)
	}

	ui = "13pP7vbI"
	err = cb58.FromString(ui)
	if err == nil {
		t.Fatalf("Incorrectly parsed %s", ui)
	}

	ui = "13"
	err = cb58.FromString(ui)
	if err == nil {
		t.Fatalf("Incorrectly parsed %s", ui)
	}

	ui = "13pP7vb3"
	err = cb58.FromString(ui)
	if err == nil {
		t.Fatalf("Incorrectly parsed %s", ui)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"time"

	"gitlab.com/gomidi/midi/v2"
	"gitlab.com/gomidi/midi/v2/drivers"
	_ "gitlab.com/gomidi/midi/v2/drivers/rtmididrv" // autoregisters driver
	"gitlab.com/gomidi/midi/v2/smf"
)

type playEvent struct {
	absTime uint64
	sleep   time.Duration
	data    [3]byte
	out     drivers.Out
	trackNo int
}

type player []playEvent

func run() error {
	out, err := drivers.OutByName("FLUID Synth")
	if err != nil {
		return err
	}

	defer out.Close()

	// single track playing
	// for multitrack we would have to collect the tracks events first and properly synchronize playback
	//_, err = smf.ReadTracks("Prelude4.mid", 2).
	_, err = smf.ReadTracks("Prelude4.mid", 1, 2, 3, 4).
		//_, err = smf.ReadTracks("VOYAGER.MID", 1).
		//Only(midi.NoteOnMsg, midi.NoteOffMsg).
		//Only(midi.NoteOnMsg, midi.NoteOffMsg, midi.MetaMsgType).
		Only(midi.NoteMsg).
		Do(
			func(trackNo int, msg smf.Message, delta int64, deltamicroSec int64) {
				fmt.Printf("%s (%s)\n", msg.String(), msg.Kind())
				if mm, ok := msg.(midi.Message); ok {
					time.Sleep(time.Microsecond * time.Duration(deltamicroSec))
					_ = mm
					out.Send(mm.Data)
				}
			},
		)
	return err
}

func main() {
	err := run()

	if err != nil {
		fmt.Printf("ERROR: %s\n", err.Error())
	}
}
<commit_msg>make it work again<commit_after>package main

import (
	"fmt"
	"time"

	"gitlab.com/gomidi/midi/v2"
	"gitlab.com/gomidi/midi/v2/drivers"
	_ "gitlab.com/gomidi/midi/v2/drivers/rtmididrv" // autoregisters driver
	"gitlab.com/gomidi/midi/v2/smf"
)

type playEvent struct {
	absTime uint64
	sleep   time.Duration
	data    [3]byte
	out     drivers.Out
	trackNo int
}

type player []playEvent

func run() error {
	out, err := drivers.OutByName("FLUID Synth")
	if err != nil {
		return err
	}

	defer out.Close()

	// single track playing
	// for multitrack we would have to collect the tracks events first and properly synchronize playback
	//_, err = smf.ReadTracks("Prelude4.mid", 2).
	_, err = smf.ReadTracks("Prelude4.mid", 1, 2, 3, 4).
		//_, err = smf.ReadTracks("VOYAGER.MID", 1).
		//Only(midi.NoteOnMsg, midi.NoteOffMsg).
		//Only(midi.NoteOnMsg, midi.NoteOffMsg, midi.MetaMsgType).
		Only(midi.NoteMsg).
		Do(
			func(trackNo int, msg midi.Message, delta int64, deltamicroSec int64) {
				fmt.Printf("%s (%s)\n", msg.String(), msg.Type())
				if mm, ok := msg.(midi.Msg); ok {
					time.Sleep(time.Microsecond * time.Duration(deltamicroSec))
					_ = mm
					out.Send(mm.Data)
				}
			},
		)
	return err
}

func main() {
	err := run()

	if err != nil {
		fmt.Printf("ERROR: %s\n", err.Error())
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 The Vanadium 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 test

import (
	"path/filepath"
	"time"

	"v.io/x/devtools/internal/collect"
	"v.io/x/devtools/internal/runutil"
	"v.io/x/devtools/internal/test"
	"v.io/x/devtools/internal/tool"
	"v.io/x/devtools/internal/util"
	"v.io/x/devtools/internal/xunit"
)

const (
	defaultProjectTestTimeout = 10 * time.Minute
)

// runProjectTest is a helper for running project tests.
func runProjectTest(ctx *tool.Context, testName, projectName, target string, env map[string]string, profiles []string) (_ *test.Result, e error) {
	// Initialize the test.
	cleanup, err := initTest(ctx, testName, profiles)
	if err != nil {
		return nil, err
	}
	defer collect.Error(func() error { return cleanup() }, &e)

	// Navigate to project directory.
	root, err := util.V23Root()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "release", "projects", projectName)
	if err := ctx.Run().Chdir(testDir); err != nil {
		return nil, err
	}

	// Clean.
	if err := ctx.Run().Command("make", "clean"); err != nil {
		return nil, err
	}

	// Set environment from the env argument map.
	opts := ctx.Run().Opts()
	for k, v := range env {
		opts.Env[k] = v
	}

	// Run the tests.
	if err := ctx.Run().TimedCommandWithOpts(defaultProjectTestTimeout, opts, "make", target); err != nil {
		if err == runutil.CommandTimedOutErr {
			return &test.Result{
				Status:       test.TimedOut,
				TimeoutValue: defaultProjectTestTimeout,
			}, nil
		} else {
			return nil, internalTestError{err, "Make " + target}
		}
	}

	return &test.Result{Status: test.Passed}, nil
}

// vanadiumBrowserTest runs the tests for the Vanadium browser.
func vanadiumBrowserTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	env := map[string]string{
		"XUNIT_OUTPUT_FILE": xunit.ReportPath(testName),
	}
	return runProjectTest(ctx, testName, "browser", "test", env, []string{"nacl", "nodejs"})
}

// vanadiumBrowserTestWeb runs the ui tests for the Vanadium browser.
func vanadiumBrowserTestWeb(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "browser", "test-ui", nil, []string{"nacl", "nodejs"})
}

// vanadiumChatShellTest runs the tests for the chat shell client.
func vanadiumChatShellTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "chat", "test-shell", nil, nil)
}

// vanadiumChatWebTest runs the tests for the chat web client.
func vanadiumChatWebTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "chat", "test-web", nil, []string{"nacl", "nodejs"})
}

// vanadiumChatWebUITest runs the ui tests for the chat web client.
func vanadiumChatWebUITest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "chat", "test-ui", nil, []string{"nacl", "nodejs"})
}

// vanadiumPipe2BrowserTest runs the tests for pipe2browser.
func vanadiumPipe2BrowserTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "pipe2browser", "test", nil, []string{"nacl", "nodejs"})
}

// vanadiumReaderTest runs the tests for the reader example application.
func vanadiumReaderTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "reader", "test", nil, []string{"nacl", "nodejs"})
}

func vanadiumTravelTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "travel", "test", nil, nil)
}
<commit_msg>Adding nodejs dependency to Travel app tests (local runs were succeeding due to local non-v23 install of nodejs)<commit_after>// Copyright 2015 The Vanadium 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 test

import (
	"path/filepath"
	"time"

	"v.io/x/devtools/internal/collect"
	"v.io/x/devtools/internal/runutil"
	"v.io/x/devtools/internal/test"
	"v.io/x/devtools/internal/tool"
	"v.io/x/devtools/internal/util"
	"v.io/x/devtools/internal/xunit"
)

const (
	defaultProjectTestTimeout = 10 * time.Minute
)

// runProjectTest is a helper for running project tests.
func runProjectTest(ctx *tool.Context, testName, projectName, target string, env map[string]string, profiles []string) (_ *test.Result, e error) {
	// Initialize the test.
	cleanup, err := initTest(ctx, testName, profiles)
	if err != nil {
		return nil, err
	}
	defer collect.Error(func() error { return cleanup() }, &e)

	// Navigate to project directory.
	root, err := util.V23Root()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "release", "projects", projectName)
	if err := ctx.Run().Chdir(testDir); err != nil {
		return nil, err
	}

	// Clean.
	if err := ctx.Run().Command("make", "clean"); err != nil {
		return nil, err
	}

	// Set environment from the env argument map.
	opts := ctx.Run().Opts()
	for k, v := range env {
		opts.Env[k] = v
	}

	// Run the tests.
	if err := ctx.Run().TimedCommandWithOpts(defaultProjectTestTimeout, opts, "make", target); err != nil {
		if err == runutil.CommandTimedOutErr {
			return &test.Result{
				Status:       test.TimedOut,
				TimeoutValue: defaultProjectTestTimeout,
			}, nil
		} else {
			return nil, internalTestError{err, "Make " + target}
		}
	}

	return &test.Result{Status: test.Passed}, nil
}

// vanadiumBrowserTest runs the tests for the Vanadium browser.
func vanadiumBrowserTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	env := map[string]string{
		"XUNIT_OUTPUT_FILE": xunit.ReportPath(testName),
	}
	return runProjectTest(ctx, testName, "browser", "test", env, []string{"nacl", "nodejs"})
}

// vanadiumBrowserTestWeb runs the ui tests for the Vanadium browser.
func vanadiumBrowserTestWeb(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "browser", "test-ui", nil, []string{"nacl", "nodejs"})
}

// vanadiumChatShellTest runs the tests for the chat shell client.
func vanadiumChatShellTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "chat", "test-shell", nil, nil)
}

// vanadiumChatWebTest runs the tests for the chat web client.
func vanadiumChatWebTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "chat", "test-web", nil, []string{"nacl", "nodejs"})
}

// vanadiumChatWebUITest runs the ui tests for the chat web client.
func vanadiumChatWebUITest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "chat", "test-ui", nil, []string{"nacl", "nodejs"})
}

// vanadiumPipe2BrowserTest runs the tests for pipe2browser.
func vanadiumPipe2BrowserTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "pipe2browser", "test", nil, []string{"nacl", "nodejs"})
}

// vanadiumReaderTest runs the tests for the reader example application.
func vanadiumReaderTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "reader", "test", nil, []string{"nacl", "nodejs"})
}

func vanadiumTravelTest(ctx *tool.Context, testName string, _ ...Opt) (*test.Result, error) {
	return runProjectTest(ctx, testName, "travel", "test", nil, []string{"nodejs"})
}
<|endoftext|>


<commit_before>package classfile

/*
CONSTANT_Integer_info {
    u1 tag;
    u4 bytes;
}
*/
type ConstantIntegerInfo struct {
    val int32
}
func (self * ConstantIntegerInfo) readInfo(reader *ClassReader) {
    self.val = reader.readInt32()
}

/*
CONSTANT_Float_info {
    u1 tag;
    u4 bytes;
}
*/
type ConstantFloatInfo struct {
    val float32
}
func (self *ConstantFloatInfo) readInfo(reader *ClassReader) {
    self.val = reader.readFloat32()
}

/*
CONSTANT_Long_info {
    u1 tag;
    u4 high_bytes;
    u4 low_bytes;
}
*/
type ConstantLongInfo struct {
    val int64
}
func (self *ConstantLongInfo) readInfo(reader *ClassReader) {
    self.val = reader.readInt64()
}

/*
CONSTANT_Double_info {
    u1 tag;
    u4 high_bytes;
    u4 low_bytes;
}
*/
type ConstantDoubleInfo struct {
    val float64
}
func (self *ConstantDoubleInfo) readInfo(reader *ClassReader) {
    self.val = reader.readFloat64()
}

/*
CONSTANT_Utf8_info {
    u1 tag;
    u2 length;
    u1 bytes[length];
}
*/
type ConstantUtf8Info struct {
    str string
}
func (self *ConstantUtf8Info) readInfo(reader *ClassReader) {
    self.str = reader.readString()
}

/*
CONSTANT_String_info {
    u1 tag;
    u2 string_index;
}
*/
type ConstantStringInfo struct {
    stringIndex uint16
}
func (self *ConstantStringInfo) readInfo(reader *ClassReader) {
    self.stringIndex = reader.readUint16()
}

/*
CONSTANT_Class_info {
    u1 tag;
    u2 name_index;
}
*/
type ConstantClassInfo struct {
    nameIndex uint16
}
func (self *ConstantClassInfo) readInfo(reader *ClassReader) {
    self.nameIndex = reader.readUint16()
}

/*
CONSTANT_MethodType_info {
    u1 tag;
    u2 descriptor_index;
}
*/
type ConstantMethodTypeInfo struct {
    descriptorIndex uint16
}
func (self *ConstantMethodTypeInfo) readInfo(reader *ClassReader) {
    self.descriptorIndex = reader.readUint16()
}

/*
CONSTANT_NameAndType_info {
    u1 tag;
    u2 name_index;
    u2 descriptor_index;
}
*/
type ConstantNameAndTypeInfo struct {
    nameIndex       uint16
    descriptorIndex uint16
}
func (self *ConstantNameAndTypeInfo) readInfo(reader *ClassReader) {
    self.nameIndex = reader.readUint16()
    self.descriptorIndex = reader.readUint16()
}

/*
CONSTANT_Fieldref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}
*/
type ConstantFieldrefInfo struct {
    classIndex       uint16
    nameAndTypeIndex uint16
}
func (self *ConstantFieldrefInfo) readInfo(reader *ClassReader) {
    self.classIndex = reader.readUint16()
    self.nameAndTypeIndex = reader.readUint16()
}

/*
CONSTANT_Methodref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}
*/
type ConstantMethodrefInfo struct {
    classIndex       uint16
    nameAndTypeIndex uint16
}
func (self *ConstantMethodrefInfo) readInfo(reader *ClassReader) {
    self.classIndex = reader.readUint16()
    self.nameAndTypeIndex = reader.readUint16()
}

/*
CONSTANT_InterfaceMethodref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}
*/
type ConstantInterfaceMethodrefInfo struct {
    classIndex       uint16
    nameAndTypeIndex uint16
}
func (self *ConstantInterfaceMethodrefInfo) readInfo(reader *ClassReader) {
    self.classIndex = reader.readUint16()
    self.nameAndTypeIndex = reader.readUint16()
}

/*
CONSTANT_MethodHandle_info {
    u1 tag;
    u1 reference_kind;
    u2 reference_index;
}
*/
type ConstantMethodHandleInfo struct {
    referenceKind  uint8
    referenceIndex uint16
}
func (self *ConstantMethodHandleInfo) readInfo(reader *ClassReader) {
    self.referenceKind = reader.readUint8()
    self.referenceIndex = reader.readUint16()
}

/*
CONSTANT_InvokeDynamic_info {
    u1 tag;
    u2 bootstrap_method_attr_index;
    u2 name_and_type_index;
}
*/
type ConstantInvokeDynamicInfo struct {
    bootstrapMethodAttrIndex uint16
    nameAndTypeIndex         uint16
}
func (self *ConstantInvokeDynamicInfo) readInfo(reader *ClassReader) {
    self.bootstrapMethodAttrIndex = reader.readUint16()
    self.nameAndTypeIndex = reader.readUint16()
}
<commit_msg>code refactor<commit_after>package classfile

/*
CONSTANT_Integer_info {
    u1 tag;
    u4 bytes;
}
*/
type ConstantIntegerInfo struct {
    val int32
}
func (self * ConstantIntegerInfo) readInfo(reader *ClassReader) {
    self.val = reader.readInt32()
}

/*
CONSTANT_Float_info {
    u1 tag;
    u4 bytes;
}
*/
type ConstantFloatInfo struct {
    val float32
}
func (self *ConstantFloatInfo) readInfo(reader *ClassReader) {
    self.val = reader.readFloat32()
}

/*
CONSTANT_Long_info {
    u1 tag;
    u4 high_bytes;
    u4 low_bytes;
}
*/
type ConstantLongInfo struct {
    val int64
}
func (self *ConstantLongInfo) readInfo(reader *ClassReader) {
    self.val = reader.readInt64()
}

/*
CONSTANT_Double_info {
    u1 tag;
    u4 high_bytes;
    u4 low_bytes;
}
*/
type ConstantDoubleInfo struct {
    val float64
}
func (self *ConstantDoubleInfo) readInfo(reader *ClassReader) {
    self.val = reader.readFloat64()
}

/*
CONSTANT_Utf8_info {
    u1 tag;
    u2 length;
    u1 bytes[length];
}
*/
type ConstantUtf8Info struct {
    str string
}
func (self *ConstantUtf8Info) readInfo(reader *ClassReader) {
    self.str = reader.readString()
}

/*
CONSTANT_String_info {
    u1 tag;
    u2 string_index;
}
*/
type ConstantStringInfo struct {
    stringIndex uint16
}
func (self *ConstantStringInfo) readInfo(reader *ClassReader) {
    self.stringIndex = reader.readUint16()
}

/*
CONSTANT_Class_info {
    u1 tag;
    u2 name_index;
}
*/
type ConstantClassInfo struct {
    nameIndex uint16
}
func (self *ConstantClassInfo) readInfo(reader *ClassReader) {
    self.nameIndex = reader.readUint16()
}

/*
CONSTANT_MethodType_info {
    u1 tag;
    u2 descriptor_index;
}
*/
type ConstantMethodTypeInfo struct {
    descriptorIndex uint16
}
func (self *ConstantMethodTypeInfo) readInfo(reader *ClassReader) {
    self.descriptorIndex = reader.readUint16()
}

/*
CONSTANT_NameAndType_info {
    u1 tag;
    u2 name_index;
    u2 descriptor_index;
}
*/
type ConstantNameAndTypeInfo struct {
    nameIndex       uint16
    descriptorIndex uint16
}
func (self *ConstantNameAndTypeInfo) readInfo(reader *ClassReader) {
    self.nameIndex = reader.readUint16()
    self.descriptorIndex = reader.readUint16()
}

/*
CONSTANT_Fieldref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}
*/
type ConstantFieldrefInfo struct {
    classIndex       uint16
    nameAndTypeIndex uint16
}
func (self *ConstantFieldrefInfo) readInfo(reader *ClassReader) {
    self.classIndex = reader.readUint16()
    self.nameAndTypeIndex = reader.readUint16()
}

/*
CONSTANT_Methodref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}
*/
type ConstantMethodrefInfo struct {
    ConstantFieldrefInfo
}

/*
CONSTANT_InterfaceMethodref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}
*/
type ConstantInterfaceMethodrefInfo struct {
    ConstantFieldrefInfo
}

/*
CONSTANT_MethodHandle_info {
    u1 tag;
    u1 reference_kind;
    u2 reference_index;
}
*/
type ConstantMethodHandleInfo struct {
    referenceKind  uint8
    referenceIndex uint16
}
func (self *ConstantMethodHandleInfo) readInfo(reader *ClassReader) {
    self.referenceKind = reader.readUint8()
    self.referenceIndex = reader.readUint16()
}

/*
CONSTANT_InvokeDynamic_info {
    u1 tag;
    u2 bootstrap_method_attr_index;
    u2 name_and_type_index;
}
*/
type ConstantInvokeDynamicInfo struct {
    bootstrapMethodAttrIndex uint16
    nameAndTypeIndex         uint16
}
func (self *ConstantInvokeDynamicInfo) readInfo(reader *ClassReader) {
    self.bootstrapMethodAttrIndex = reader.readUint16()
    self.nameAndTypeIndex = reader.readUint16()
}
<|endoftext|>


<commit_before>package instructions

import "jvmgo/rtda"

//type Ref *rtda.Obj

// Load reference from array
type aaload struct {NoOperandsInstruction}
func (self *aaload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    refArr := arrRef.Fields().([]*rtda.Obj)
    ref := refArr[checkIndex(index, len(refArr))]
    stack.PushRef(ref)
}

// Load byte or boolean from array
type baload struct {NoOperandsInstruction}
func (self *baload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    byteArr := arrRef.Fields().([]int8)
    val := byteArr[checkIndex(index, len(byteArr))]
    stack.PushInt(int32(val))
}

// Load char from array
type caload struct {NoOperandsInstruction}
func (self *caload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    charArr := arrRef.Fields().([]uint16)
    val := charArr[checkIndex(index, len(charArr))]
    stack.PushInt(int32(val))
}

// Load double from array
type daload struct {NoOperandsInstruction}
func (self *daload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    doubleArr := arrRef.Fields().([]float64)
    val := doubleArr[checkIndex(index, len(doubleArr))]
    stack.PushDouble(val)
}

// Load float from array
type faload struct {NoOperandsInstruction}
func (self *faload) execute(thread *rtda.Thread) {
    // todo
}

// Load int from array
type iaload struct {NoOperandsInstruction}
func (self *iaload) execute(thread *rtda.Thread) {
    // todo
}

// Load long from array
type laload struct {NoOperandsInstruction}
func (self *laload) execute(thread *rtda.Thread) {
    // todo
}

// Load short from array
type saload struct {NoOperandsInstruction}
func (self *saload) execute(thread *rtda.Thread) {
    // todo
}

func popArrAndIndex(thread *rtda.Thread) (*rtda.OperandStack, *rtda.Obj, int) {
    stack := thread.CurrentFrame().OperandStack()
    arrRef := stack.PopRef()
    index := int(stack.PopInt())
    if arrRef == nil {
        // todo
        panic("NullPointerException")
    }
    return stack, arrRef, index
}

func checkIndex(index, len int) (int) {
    if index < 0 || index >= len {
        panic("ArrayIndexOutOfBoundsException")
    }
    return index
}
<commit_msg>faload<commit_after>package instructions

import "jvmgo/rtda"

//type Ref *rtda.Obj

// Load reference from array
type aaload struct {NoOperandsInstruction}
func (self *aaload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    refArr := arrRef.Fields().([]*rtda.Obj)
    ref := refArr[checkIndex(index, len(refArr))]
    stack.PushRef(ref)
}

// Load byte or boolean from array
type baload struct {NoOperandsInstruction}
func (self *baload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    byteArr := arrRef.Fields().([]int8)
    val := byteArr[checkIndex(index, len(byteArr))]
    stack.PushInt(int32(val))
}

// Load char from array
type caload struct {NoOperandsInstruction}
func (self *caload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    charArr := arrRef.Fields().([]uint16)
    val := charArr[checkIndex(index, len(charArr))]
    stack.PushInt(int32(val))
}

// Load double from array
type daload struct {NoOperandsInstruction}
func (self *daload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    doubleArr := arrRef.Fields().([]float64)
    val := doubleArr[checkIndex(index, len(doubleArr))]
    stack.PushDouble(val)
}

// Load float from array
type faload struct {NoOperandsInstruction}
func (self *faload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    floatArr := arrRef.Fields().([]float32)
    val := floatArr[checkIndex(index, len(floatArr))]
    stack.PushFloat(val)
}

// Load int from array
type iaload struct {NoOperandsInstruction}
func (self *iaload) execute(thread *rtda.Thread) {
    // todo
}

// Load long from array
type laload struct {NoOperandsInstruction}
func (self *laload) execute(thread *rtda.Thread) {
    // todo
}

// Load short from array
type saload struct {NoOperandsInstruction}
func (self *saload) execute(thread *rtda.Thread) {
    // todo
}

func popArrAndIndex(thread *rtda.Thread) (*rtda.OperandStack, *rtda.Obj, int) {
    stack := thread.CurrentFrame().OperandStack()
    arrRef := stack.PopRef()
    index := int(stack.PopInt())
    if arrRef == nil {
        // todo
        panic("NullPointerException")
    }
    return stack, arrRef, index
}

func checkIndex(index, len int) (int) {
    if index < 0 || index >= len {
        panic("ArrayIndexOutOfBoundsException")
    }
    return index
}
<|endoftext|>


<commit_before>package pluginaction_test

import (
	"errors"
	"io/ioutil"
	"os"
	"path/filepath"

	. "code.cloudfoundry.org/cli/actor/pluginaction"
	"code.cloudfoundry.org/cli/actor/pluginaction/pluginactionfakes"
	"code.cloudfoundry.org/cli/util/configv3"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("UninstallPlugin", func() {
	var (
		actor                 *Actor
		binaryPath            string
		fakeConfig            *pluginactionfakes.FakeConfig
		fakePluginUninstaller *pluginactionfakes.FakePluginUninstaller
		pluginHome            string
		err                   error
	)

	BeforeEach(func() {
		pluginHome, err = ioutil.TempDir("", "")
		Expect(err).ToNot(HaveOccurred())

		binaryPath = filepath.Join(pluginHome, "banana-faceman")
		err = ioutil.WriteFile(binaryPath, nil, 0600)
		Expect(err).ToNot(HaveOccurred())

		plugins := map[string]configv3.Plugin{
			"some-plugin": {
				Location: binaryPath,
			},
		}

		fakePluginUninstaller = new(pluginactionfakes.FakePluginUninstaller)
		fakeConfig = new(pluginactionfakes.FakeConfig)
		actor = NewActor(fakeConfig)

		fakeConfig.PluginsReturns(plugins)
	})

	AfterEach(func() {
		os.RemoveAll(pluginHome)
	})

	Context("when the plugin does not exist", func() {
		It("returns a PluginNotFoundError", func() {
			err := actor.UninstallPlugin(fakePluginUninstaller, "some-non-existent-plugin")
			Expect(err).To(MatchError(PluginNotFoundError{Name: "some-non-existent-plugin"}))
		})
	})

	Context("when the plugin exists", func() {
		Context("when no errors are encountered", func() {
			It("runs the plugin cleanup, deletes the binary and removes the plugin config", func() {
				err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
				Expect(err).ToNot(HaveOccurred())

				Expect(fakeConfig.PluginsCallCount()).To(Equal(1))

				Expect(fakePluginUninstaller.UninstallCallCount()).To(Equal(1))
				Expect(fakePluginUninstaller.UninstallArgsForCall(0)).To(Equal(binaryPath))

				_, err = os.Stat(binaryPath)
				Expect(os.IsNotExist(err)).To(BeTrue())

				Expect(fakeConfig.RemovePluginCallCount()).To(Equal(1))
				Expect(fakeConfig.RemovePluginArgsForCall(0)).To(Equal("some-plugin"))

				Expect(fakeConfig.WritePluginConfigCallCount()).To(Equal(1))
			})
		})

		Context("when the plugin uninstaller returns an error", func() {
			var expectedErr error

			BeforeEach(func() {
				expectedErr = errors.New("some error")
				fakePluginUninstaller.UninstallReturns(expectedErr)
			})

			It("returns the error and does not delete the binary or remove the plugin config", func() {
				err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
				Expect(err).To(MatchError(expectedErr))

				_, err = os.Stat(binaryPath)
				Expect(err).ToNot(HaveOccurred())

				Expect(fakeConfig.RemovePluginCallCount()).To(Equal(0))
			})
		})

		Context("when deleting the plugin binary returns a 'file does not exist' error", func() {
			BeforeEach(func() {
				err = os.Remove(binaryPath)
				Expect(err).ToNot(HaveOccurred())
			})

			It("does not return the error and removes the plugin config", func() {
				err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
				Expect(err).ToNot(HaveOccurred())

				Expect(fakeConfig.RemovePluginCallCount()).To(Equal(1))
			})
		})

		Context("when deleting the plugin binary returns any other error", func() {
			BeforeEach(func() {
				err = os.Chmod(pluginHome, 0000)
				Expect(err).ToNot(HaveOccurred())
			})

			AfterEach(func() {
				err = os.Chmod(pluginHome, 0700)
				Expect(err).ToNot(HaveOccurred())
			})

			It("does not return the error and removes the plugin config", func() {
				err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
				Expect(err).To(MatchError(MatchRegexp("permission denied")))

				Expect(fakeConfig.RemovePluginCallCount()).To(Equal(0))
				Expect(fakeConfig.WritePluginConfigCallCount()).To(Equal(0))
			})
		})

		Context("when writing the config returns an error", func() {
			var expectedErr error

			BeforeEach(func() {
				expectedErr = errors.New("some plugin config write error")

				fakeConfig.WritePluginConfigReturns(expectedErr)
			})

			It("returns the error", func() {
				err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
				Expect(err).To(MatchError(expectedErr))
			})
		})
	})
})
<commit_msg>repair more tests<commit_after>package pluginaction_test

import (
	"errors"
	"io/ioutil"
	"os"
	"path/filepath"

	. "code.cloudfoundry.org/cli/actor/pluginaction"
	"code.cloudfoundry.org/cli/actor/pluginaction/pluginactionfakes"
	"code.cloudfoundry.org/cli/util/configv3"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("UninstallPlugin", func() {
	var (
		actor                 *Actor
		binaryPath            string
		fakeConfig            *pluginactionfakes.FakeConfig
		fakePluginUninstaller *pluginactionfakes.FakePluginUninstaller
		pluginHome            string
		err                   error
	)

	BeforeEach(func() {
		pluginHome, err = ioutil.TempDir("", "")
		Expect(err).ToNot(HaveOccurred())

		binaryPath = filepath.Join(pluginHome, "banana-faceman")
		err = ioutil.WriteFile(binaryPath, nil, 0600)
		Expect(err).ToNot(HaveOccurred())

		plugins := map[string]configv3.Plugin{
			"some-plugin": {
				Location: binaryPath,
			},
		}

		fakePluginUninstaller = new(pluginactionfakes.FakePluginUninstaller)
		fakeConfig = new(pluginactionfakes.FakeConfig)
		actor = NewActor(fakeConfig)

		fakeConfig.PluginsReturns(plugins)
	})

	AfterEach(func() {
		os.RemoveAll(pluginHome)
	})

	Context("when the plugin does not exist", func() {
		It("returns a PluginNotFoundError", func() {
			err := actor.UninstallPlugin(fakePluginUninstaller, "some-non-existent-plugin")
			Expect(err).To(MatchError(PluginNotFoundError{Name: "some-non-existent-plugin"}))
		})
	})

	Context("when the plugin exists", func() {
		Context("when no errors are encountered", func() {
			It("runs the plugin cleanup, deletes the binary and removes the plugin config", func() {
				err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
				Expect(err).ToNot(HaveOccurred())

				Expect(fakeConfig.PluginsCallCount()).To(Equal(1))

				Expect(fakePluginUninstaller.UninstallCallCount()).To(Equal(1))
				Expect(fakePluginUninstaller.UninstallArgsForCall(0)).To(Equal(binaryPath))

				_, err = os.Stat(binaryPath)
				Expect(os.IsNotExist(err)).To(BeTrue())

				Expect(fakeConfig.RemovePluginCallCount()).To(Equal(1))
				Expect(fakeConfig.RemovePluginArgsForCall(0)).To(Equal("some-plugin"))

				Expect(fakeConfig.WritePluginConfigCallCount()).To(Equal(1))
			})
		})

		Context("when the plugin uninstaller returns an error", func() {
			var expectedErr error

			BeforeEach(func() {
				expectedErr = errors.New("some error")
				fakePluginUninstaller.UninstallReturns(expectedErr)
			})

			It("returns the error and does not delete the binary or remove the plugin config", func() {
				err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
				Expect(err).To(MatchError(expectedErr))

				_, err = os.Stat(binaryPath)
				Expect(err).ToNot(HaveOccurred())

				Expect(fakeConfig.RemovePluginCallCount()).To(Equal(0))
			})
		})

		Context("when deleting the plugin binary returns a 'file does not exist' error", func() {
			BeforeEach(func() {
				err = os.Remove(binaryPath)
				Expect(err).ToNot(HaveOccurred())
			})

			It("does not return the error and removes the plugin config", func() {
				err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
				Expect(err).ToNot(HaveOccurred())

				Expect(fakeConfig.RemovePluginCallCount()).To(Equal(1))
			})
		})

		Context("when deleting the plugin binary returns any other error", func() {
			BeforeEach(func() {
				err = os.Remove(binaryPath)
				Expect(err).ToNot(HaveOccurred())
				err = os.Mkdir(binaryPath, 0700)
				Expect(err).ToNot(HaveOccurred())
				err = ioutil.WriteFile(filepath.Join(binaryPath, "foooooo"), nil, 0500)
				Expect(err).ToNot(HaveOccurred())
			})

			It("does not return the error and removes the plugin config", func() {
				err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
				_, ok := err.(*os.PathError)
				Expect(ok).To(BeTrue())

				Expect(fakeConfig.RemovePluginCallCount()).To(Equal(0))
				Expect(fakeConfig.WritePluginConfigCallCount()).To(Equal(0))
			})
		})

		Context("when writing the config returns an error", func() {
			var expectedErr error

			BeforeEach(func() {
				expectedErr = errors.New("some plugin config write error")

				fakeConfig.WritePluginConfigReturns(expectedErr)
			})

			It("returns the error", func() {
				err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
				Expect(err).To(MatchError(expectedErr))
			})
		})
	})
})
<|endoftext|>


<commit_before>package template

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"sync"
	"testing"

	r "github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

var testProviders = map[string]terraform.ResourceProvider{
	"template": Provider(),
}

func TestTemplateRendering(t *testing.T) {
	var cases = []struct {
		vars     string
		template string
		want     string
	}{
		{`{}`, `ABC`, `ABC`},
		{`{a="foo"}`, `$${a}`, `foo`},
		{`{a="hello"}`, `$${replace(a, "ello", "i")}`, `hi`},
		{`{}`, `${1+2+3}`, `6`},
	}

	for _, tt := range cases {
		r.UnitTest(t, r.TestCase{
			Providers: testProviders,
			Steps: []r.TestStep{
				r.TestStep{
					Config: testTemplateConfig(tt.template, tt.vars),
					Check: func(s *terraform.State) error {
						got := s.RootModule().Outputs["rendered"]
						if tt.want != got.Value {
							return fmt.Errorf("template:\n%s\nvars:\n%s\ngot:\n%s\nwant:\n%s\n", tt.template, tt.vars, got, tt.want)
						}
						return nil
					},
				},
			},
		})
	}
}

func TestValidateTemplateAttribute(t *testing.T) {
	file, err := ioutil.TempFile("", "testtemplate")
	if err != nil {
		t.Fatal(err)
	}
	file.WriteString("Hello world.")
	file.Close()
	defer os.Remove(file.Name())

	ws, es := validateTemplateAttribute(file.Name(), "test")

	if len(es) != 0 {
		t.Fatalf("Unexpected errors: %#v", es)
	}

	if len(ws) != 1 {
		t.Fatalf("Expected 1 warning, got %d", len(ws))
	}

	if !strings.Contains(ws[0], "Specifying a path directly is deprecated") {
		t.Fatalf("Expected warning about path, got: %s", ws[0])
	}
}

func TestValidateVarsAttribute(t *testing.T) {
	cases := map[string]struct {
		Vars      map[string]interface{}
		ExpectErr string
	}{
		"lists are invalid": {
			map[string]interface{}{
				"list": []interface{}{},
			},
			`vars: cannot contain non-primitives`,
		},
		"maps are invalid": {
			map[string]interface{}{
				"map": map[string]interface{}{},
			},
			`vars: cannot contain non-primitives`,
		},
		"strings, integers, floats, and bools are AOK": {
			map[string]interface{}{
				"string": "foo",
				"int":    1,
				"bool":   true,
				"float":  float64(1.0),
			},
			``,
		},
	}

	for tn, tc := range cases {
		_, es := validateVarsAttribute(tc.Vars, "vars")
		if len(es) > 0 {
			if tc.ExpectErr == "" {
				t.Fatalf("%s: expected no err, got: %#v", tn, es)
			}
			if !strings.Contains(es[0].Error(), tc.ExpectErr) {
				t.Fatalf("%s: expected\n%s\nto contain\n%s", tn, es[0], tc.ExpectErr)
			}
		} else if tc.ExpectErr != "" {
			t.Fatalf("%s: expected err containing %q, got none!", tn, tc.ExpectErr)
		}
	}
}

// This test covers a panic due to config.Func formerly being a
// shared map, causing multiple template_file resources to try and
// accessing it parallel during their lang.Eval() runs.
//
// Before fix, test fails under `go test -race`
func TestTemplateSharedMemoryRace(t *testing.T) {
	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		go func(wg *sync.WaitGroup, t *testing.T, i int) {
			wg.Add(1)
			out, err := execute("don't panic!", map[string]interface{}{})
			if err != nil {
				t.Fatalf("err: %s", err)
			}
			if out != "don't panic!" {
				t.Fatalf("bad output: %s", out)
			}
			wg.Done()
		}(&wg, t, i)
	}
	wg.Wait()
}

func testTemplateConfig(template, vars string) string {
	return fmt.Sprintf(`
		data "template_file" "t0" {
			template = "%s"
			vars = %s
		}
		output "rendered" {
				value = "${data.template_file.t0.rendered}"
		}`, template, vars)
}
<commit_msg>Fix improper wait group usage in test<commit_after>package template

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"sync"
	"testing"

	r "github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

var testProviders = map[string]terraform.ResourceProvider{
	"template": Provider(),
}

func TestTemplateRendering(t *testing.T) {
	var cases = []struct {
		vars     string
		template string
		want     string
	}{
		{`{}`, `ABC`, `ABC`},
		{`{a="foo"}`, `$${a}`, `foo`},
		{`{a="hello"}`, `$${replace(a, "ello", "i")}`, `hi`},
		{`{}`, `${1+2+3}`, `6`},
	}

	for _, tt := range cases {
		r.UnitTest(t, r.TestCase{
			Providers: testProviders,
			Steps: []r.TestStep{
				r.TestStep{
					Config: testTemplateConfig(tt.template, tt.vars),
					Check: func(s *terraform.State) error {
						got := s.RootModule().Outputs["rendered"]
						if tt.want != got.Value {
							return fmt.Errorf("template:\n%s\nvars:\n%s\ngot:\n%s\nwant:\n%s\n", tt.template, tt.vars, got, tt.want)
						}
						return nil
					},
				},
			},
		})
	}
}

func TestValidateTemplateAttribute(t *testing.T) {
	file, err := ioutil.TempFile("", "testtemplate")
	if err != nil {
		t.Fatal(err)
	}
	file.WriteString("Hello world.")
	file.Close()
	defer os.Remove(file.Name())

	ws, es := validateTemplateAttribute(file.Name(), "test")

	if len(es) != 0 {
		t.Fatalf("Unexpected errors: %#v", es)
	}

	if len(ws) != 1 {
		t.Fatalf("Expected 1 warning, got %d", len(ws))
	}

	if !strings.Contains(ws[0], "Specifying a path directly is deprecated") {
		t.Fatalf("Expected warning about path, got: %s", ws[0])
	}
}

func TestValidateVarsAttribute(t *testing.T) {
	cases := map[string]struct {
		Vars      map[string]interface{}
		ExpectErr string
	}{
		"lists are invalid": {
			map[string]interface{}{
				"list": []interface{}{},
			},
			`vars: cannot contain non-primitives`,
		},
		"maps are invalid": {
			map[string]interface{}{
				"map": map[string]interface{}{},
			},
			`vars: cannot contain non-primitives`,
		},
		"strings, integers, floats, and bools are AOK": {
			map[string]interface{}{
				"string": "foo",
				"int":    1,
				"bool":   true,
				"float":  float64(1.0),
			},
			``,
		},
	}

	for tn, tc := range cases {
		_, es := validateVarsAttribute(tc.Vars, "vars")
		if len(es) > 0 {
			if tc.ExpectErr == "" {
				t.Fatalf("%s: expected no err, got: %#v", tn, es)
			}
			if !strings.Contains(es[0].Error(), tc.ExpectErr) {
				t.Fatalf("%s: expected\n%s\nto contain\n%s", tn, es[0], tc.ExpectErr)
			}
		} else if tc.ExpectErr != "" {
			t.Fatalf("%s: expected err containing %q, got none!", tn, tc.ExpectErr)
		}
	}
}

// This test covers a panic due to config.Func formerly being a
// shared map, causing multiple template_file resources to try and
// accessing it parallel during their lang.Eval() runs.
//
// Before fix, test fails under `go test -race`
func TestTemplateSharedMemoryRace(t *testing.T) {
	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func(t *testing.T, i int) {
			out, err := execute("don't panic!", map[string]interface{}{})
			if err != nil {
				t.Fatalf("err: %s", err)
			}
			if out != "don't panic!" {
				t.Fatalf("bad output: %s", out)
			}
			wg.Done()
		}(t, i)
	}
	wg.Wait()
}

func testTemplateConfig(template, vars string) string {
	return fmt.Sprintf(`
		data "template_file" "t0" {
			template = "%s"
			vars = %s
		}
		output "rendered" {
				value = "${data.template_file.t0.rendered}"
		}`, template, vars)
}
<|endoftext|>


<commit_before>package mount

import (
	"context"
	"github.com/chrislusf/seaweedfs/weed/filer"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/mount/meta_cache"
	"github.com/chrislusf/seaweedfs/weed/util"
	"github.com/hanwen/go-fuse/v2/fuse"
	"math"
	"os"
)

// Directory handling

/** Open directory
 *
 * Unless the 'default_permissions' mount option is given,
 * this method should check if opendir is permitted for this
 * directory. Optionally opendir may also return an arbitrary
 * filehandle in the fuse_file_info structure, which will be
 * passed to readdir, releasedir and fsyncdir.
 */
func (wfs *WFS) OpenDir(cancel <-chan struct{}, input *fuse.OpenIn, out *fuse.OpenOut) (code fuse.Status) {
	if !wfs.inodeToPath.HasInode(input.NodeId) {
		return fuse.ENOENT
	}
	return fuse.OK
}

/** Release directory
 *
 * If the directory has been removed after the call to opendir, the
 * path parameter will be NULL.
 */
func (wfs *WFS) ReleaseDir(input *fuse.ReleaseIn) {
}

/** Synchronize directory contents
 *
 * If the directory has been removed after the call to opendir, the
 * path parameter will be NULL.
 *
 * If the datasync parameter is non-zero, then only the user data
 * should be flushed, not the meta data
 */
func (wfs *WFS) FsyncDir(cancel <-chan struct{}, input *fuse.FsyncIn) (code fuse.Status) {
	return fuse.OK
}

/** Read directory
 *
 * The filesystem may choose between two modes of operation:
 *
 * 1) The readdir implementation ignores the offset parameter, and
 * passes zero to the filler function's offset.  The filler
 * function will not return '1' (unless an error happens), so the
 * whole directory is read in a single readdir operation.
 *
 * 2) The readdir implementation keeps track of the offsets of the
 * directory entries.  It uses the offset parameter and always
 * passes non-zero offset to the filler function.  When the buffer
 * is full (or an error happens) the filler function will return
 * '1'.
 */
func (wfs *WFS) ReadDir(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
	return wfs.doReadDirectory(input, out, false)
}

func (wfs *WFS) ReadDirPlus(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
	return wfs.doReadDirectory(input, out, true)
}

func (wfs *WFS) doReadDirectory(input *fuse.ReadIn, out *fuse.DirEntryList, isPlusMode bool) fuse.Status {
	dirPath := wfs.inodeToPath.GetPath(input.NodeId)

	var counter uint64
	var dirEntry fuse.DirEntry
	if input.Offset == 0 {
		counter++
		dirEntry.Ino = input.NodeId
		dirEntry.Name = "."
		dirEntry.Mode = toSystemMode(os.ModeDir)
		out.AddDirEntry(dirEntry)

		counter++
		parentDir, _ := dirPath.DirAndName()
		parentInode := wfs.inodeToPath.GetInode(util.FullPath(parentDir))
		dirEntry.Ino = parentInode
		dirEntry.Name = ".."
		dirEntry.Mode = toSystemMode(os.ModeDir)
		out.AddDirEntry(dirEntry)

	}

	processEachEntryFn := func(entry *filer.Entry, isLast bool) bool {
		counter++
		if counter <= input.Offset {
			return true
		}
		dirEntry.Name = entry.Name()
		inode := wfs.inodeToPath.GetInode(dirPath.Child(dirEntry.Name))
		dirEntry.Ino = inode
		dirEntry.Mode = toSystemMode(entry.Mode)
		if !isPlusMode {
			if !out.AddDirEntry(dirEntry) {
				return false
			}
		} else {
			entryOut := out.AddDirLookupEntry(dirEntry)
			if entryOut == nil {
				return false
			}
			wfs.outputFilerEntry(entryOut, inode, entry)
		}
		return true
	}

	if err := meta_cache.EnsureVisited(wfs.metaCache, wfs, dirPath); err != nil {
		glog.Errorf("dir ReadDirAll %s: %v", dirPath, err)
		return fuse.EIO
	}
	listErr := wfs.metaCache.ListDirectoryEntries(context.Background(), dirPath, "", false, int64(math.MaxInt32), func(entry *filer.Entry) bool {
		return processEachEntryFn(entry, false)
	})
	if listErr != nil {
		glog.Errorf("list meta cache: %v", listErr)
		return fuse.EIO
	}

	return fuse.OK
}
<commit_msg>mount2: fix for read dir plus on linux<commit_after>package mount

import (
	"context"
	"github.com/chrislusf/seaweedfs/weed/filer"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/mount/meta_cache"
	"github.com/chrislusf/seaweedfs/weed/util"
	"github.com/hanwen/go-fuse/v2/fuse"
	"math"
	"os"
)

// Directory handling

/** Open directory
 *
 * Unless the 'default_permissions' mount option is given,
 * this method should check if opendir is permitted for this
 * directory. Optionally opendir may also return an arbitrary
 * filehandle in the fuse_file_info structure, which will be
 * passed to readdir, releasedir and fsyncdir.
 */
func (wfs *WFS) OpenDir(cancel <-chan struct{}, input *fuse.OpenIn, out *fuse.OpenOut) (code fuse.Status) {
	if !wfs.inodeToPath.HasInode(input.NodeId) {
		return fuse.ENOENT
	}
	return fuse.OK
}

/** Release directory
 *
 * If the directory has been removed after the call to opendir, the
 * path parameter will be NULL.
 */
func (wfs *WFS) ReleaseDir(input *fuse.ReleaseIn) {
}

/** Synchronize directory contents
 *
 * If the directory has been removed after the call to opendir, the
 * path parameter will be NULL.
 *
 * If the datasync parameter is non-zero, then only the user data
 * should be flushed, not the meta data
 */
func (wfs *WFS) FsyncDir(cancel <-chan struct{}, input *fuse.FsyncIn) (code fuse.Status) {
	return fuse.OK
}

/** Read directory
 *
 * The filesystem may choose between two modes of operation:
 *
 * 1) The readdir implementation ignores the offset parameter, and
 * passes zero to the filler function's offset.  The filler
 * function will not return '1' (unless an error happens), so the
 * whole directory is read in a single readdir operation.
 *
 * 2) The readdir implementation keeps track of the offsets of the
 * directory entries.  It uses the offset parameter and always
 * passes non-zero offset to the filler function.  When the buffer
 * is full (or an error happens) the filler function will return
 * '1'.
 */
func (wfs *WFS) ReadDir(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
	return wfs.doReadDirectory(input, out, false)
}

func (wfs *WFS) ReadDirPlus(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
	return wfs.doReadDirectory(input, out, true)
}

func (wfs *WFS) doReadDirectory(input *fuse.ReadIn, out *fuse.DirEntryList, isPlusMode bool) fuse.Status {
	dirPath := wfs.inodeToPath.GetPath(input.NodeId)

	var counter uint64
	var dirEntry fuse.DirEntry
	if input.Offset == 0 && !isPlusMode {
		counter++
		dirEntry.Ino = input.NodeId
		dirEntry.Name = "."
		dirEntry.Mode = toSystemMode(os.ModeDir)
		out.AddDirEntry(dirEntry)

		counter++
		parentDir, _ := dirPath.DirAndName()
		parentInode := wfs.inodeToPath.GetInode(util.FullPath(parentDir))
		dirEntry.Ino = parentInode
		dirEntry.Name = ".."
		dirEntry.Mode = toSystemMode(os.ModeDir)
		out.AddDirEntry(dirEntry)

	}

	processEachEntryFn := func(entry *filer.Entry, isLast bool) bool {
		counter++
		if counter <= input.Offset {
			return true
		}
		dirEntry.Name = entry.Name()
		inode := wfs.inodeToPath.GetInode(dirPath.Child(dirEntry.Name))
		dirEntry.Ino = inode
		dirEntry.Mode = toSystemMode(entry.Mode)
		if !isPlusMode {
			if !out.AddDirEntry(dirEntry) {
				return false
			}
		} else {
			entryOut := out.AddDirLookupEntry(dirEntry)
			if entryOut == nil {
				return false
			}
			wfs.outputFilerEntry(entryOut, inode, entry)
		}
		return true
	}

	if err := meta_cache.EnsureVisited(wfs.metaCache, wfs, dirPath); err != nil {
		glog.Errorf("dir ReadDirAll %s: %v", dirPath, err)
		return fuse.EIO
	}
	listErr := wfs.metaCache.ListDirectoryEntries(context.Background(), dirPath, "", false, int64(math.MaxInt32), func(entry *filer.Entry) bool {
		return processEachEntryFn(entry, false)
	})
	if listErr != nil {
		glog.Errorf("list meta cache: %v", listErr)
		return fuse.EIO
	}

	return fuse.OK
}
<|endoftext|>


<commit_before>// Copyright 2010 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.

// Unix cryptographically secure pseudorandom number
// generator.

package rand

import (
	"crypto/aes"
	"io"
	"os"
	"sync"
	"time"
)

// Easy implementation: read from /dev/urandom.
// This is sufficient on Linux, OS X, and FreeBSD.

func init() { Reader = &devReader{name: "/dev/urandom"} }

// A devReader satisfies reads by reading the file named name.
type devReader struct {
	name string
	f    *os.File
	mu   sync.Mutex
}

func (r *devReader) Read(b []byte) (n int, err os.Error) {
	r.mu.Lock()
	defer r.mu.Unlock()
	if r.f == nil {
		f, err := os.Open(r.name, os.O_RDONLY, 0)
		if f == nil {
			return 0, err
		}
		r.f = f
	}
	return r.f.Read(b)
}

// Alternate pseudo-random implementation for use on
// systems without a reliable /dev/urandom.  So far we
// haven't needed it.

// newReader returns a new pseudorandom generator that
// seeds itself by reading from entropy.  If entropy == nil,
// the generator seeds itself by reading from the system's
// random number generator, typically /dev/random.
// The Read method on the returned reader always returns
// the full amount asked for, or else it returns an error.
//
// The generator uses the X9.31 algorithm with AES-128,
// reseeding after every 1 MB of generated data.
func newReader(entropy io.Reader) io.Reader {
	if entropy == nil {
		entropy = &devReader{name: "/dev/random"}
	}
	return &reader{entropy: entropy}
}

type reader struct {
	mu                   sync.Mutex
	budget               int // number of bytes that can be generated
	cipher               *aes.Cipher
	entropy              io.Reader
	time, seed, dst, key [aes.BlockSize]byte
}

func (r *reader) Read(b []byte) (n int, err os.Error) {
	r.mu.Lock()
	defer r.mu.Unlock()
	n = len(b)

	for len(b) > 0 {
		if r.budget == 0 {
			_, err := io.ReadFull(r.entropy, r.seed[0:])
			if err != nil {
				return n - len(b), err
			}
			_, err = io.ReadFull(r.entropy, r.key[0:])
			if err != nil {
				return n - len(b), err
			}
			r.cipher, err = aes.NewCipher(r.key[0:])
			if err != nil {
				return n - len(b), err
			}
			r.budget = 1 << 20 // reseed after generating 1MB
		}
		r.budget -= aes.BlockSize

		// ANSI X9.31 (== X9.17) algorithm, but using AES in place of 3DES.
		//
		// single block:
		// t = encrypt(time)
		// dst = encrypt(t^seed)
		// seed = encrypt(t^dst)
		ns := time.Nanoseconds()
		r.time[0] = byte(ns >> 56)
		r.time[1] = byte(ns >> 48)
		r.time[2] = byte(ns >> 40)
		r.time[3] = byte(ns >> 32)
		r.time[4] = byte(ns >> 24)
		r.time[5] = byte(ns >> 16)
		r.time[6] = byte(ns >> 8)
		r.time[7] = byte(ns)
		r.cipher.Encrypt(r.time[0:], r.time[0:])
		for i := 0; i < aes.BlockSize; i++ {
			r.dst[i] = r.time[i] ^ r.seed[i]
		}
		r.cipher.Encrypt(r.dst[0:], r.dst[0:])
		for i := 0; i < aes.BlockSize; i++ {
			r.seed[i] = r.time[i] ^ r.dst[i]
		}
		r.cipher.Encrypt(r.seed[0:], r.seed[0:])

		m := copy(b, r.dst[0:])
		b = b[m:]
	}

	return n, nil
}
<commit_msg>crypto/rand: Added read buffer to speed up requests for small amounts of bytes.<commit_after>// Copyright 2010 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.

// Unix cryptographically secure pseudorandom number
// generator.

package rand

import (
	"bufio"
	"crypto/aes"
	"io"
	"os"
	"sync"
	"time"
)

// Easy implementation: read from /dev/urandom.
// This is sufficient on Linux, OS X, and FreeBSD.

func init() { Reader = &devReader{name: "/dev/urandom"} }

// A devReader satisfies reads by reading the file named name.
type devReader struct {
	name string
	f    io.Reader
	mu   sync.Mutex
}

func (r *devReader) Read(b []byte) (n int, err os.Error) {
	r.mu.Lock()
	defer r.mu.Unlock()
	if r.f == nil {
		f, err := os.Open(r.name, os.O_RDONLY, 0)
		if f == nil {
			return 0, err
		}
		r.f = bufio.NewReader(f)
	}
	return r.f.Read(b)
}

// Alternate pseudo-random implementation for use on
// systems without a reliable /dev/urandom.  So far we
// haven't needed it.

// newReader returns a new pseudorandom generator that
// seeds itself by reading from entropy.  If entropy == nil,
// the generator seeds itself by reading from the system's
// random number generator, typically /dev/random.
// The Read method on the returned reader always returns
// the full amount asked for, or else it returns an error.
//
// The generator uses the X9.31 algorithm with AES-128,
// reseeding after every 1 MB of generated data.
func newReader(entropy io.Reader) io.Reader {
	if entropy == nil {
		entropy = &devReader{name: "/dev/random"}
	}
	return &reader{entropy: entropy}
}

type reader struct {
	mu                   sync.Mutex
	budget               int // number of bytes that can be generated
	cipher               *aes.Cipher
	entropy              io.Reader
	time, seed, dst, key [aes.BlockSize]byte
}

func (r *reader) Read(b []byte) (n int, err os.Error) {
	r.mu.Lock()
	defer r.mu.Unlock()
	n = len(b)

	for len(b) > 0 {
		if r.budget == 0 {
			_, err := io.ReadFull(r.entropy, r.seed[0:])
			if err != nil {
				return n - len(b), err
			}
			_, err = io.ReadFull(r.entropy, r.key[0:])
			if err != nil {
				return n - len(b), err
			}
			r.cipher, err = aes.NewCipher(r.key[0:])
			if err != nil {
				return n - len(b), err
			}
			r.budget = 1 << 20 // reseed after generating 1MB
		}
		r.budget -= aes.BlockSize

		// ANSI X9.31 (== X9.17) algorithm, but using AES in place of 3DES.
		//
		// single block:
		// t = encrypt(time)
		// dst = encrypt(t^seed)
		// seed = encrypt(t^dst)
		ns := time.Nanoseconds()
		r.time[0] = byte(ns >> 56)
		r.time[1] = byte(ns >> 48)
		r.time[2] = byte(ns >> 40)
		r.time[3] = byte(ns >> 32)
		r.time[4] = byte(ns >> 24)
		r.time[5] = byte(ns >> 16)
		r.time[6] = byte(ns >> 8)
		r.time[7] = byte(ns)
		r.cipher.Encrypt(r.time[0:], r.time[0:])
		for i := 0; i < aes.BlockSize; i++ {
			r.dst[i] = r.time[i] ^ r.seed[i]
		}
		r.cipher.Encrypt(r.dst[0:], r.dst[0:])
		for i := 0; i < aes.BlockSize; i++ {
			r.seed[i] = r.time[i] ^ r.dst[i]
		}
		r.cipher.Encrypt(r.seed[0:], r.seed[0:])

		m := copy(b, r.dst[0:])
		b = b[m:]
	}

	return n, nil
}
<|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 template

import (
	"fmt"
	"testing"
)

type setParseTest struct {
	name    string
	input   string
	ok      bool
	names   []string
	results []string
}

var setParseTests = []setParseTest{
	{"empty", "", noError,
		nil,
		nil},
	{"one", `{{define "foo"}} FOO {{end}}`, noError,
		[]string{"foo"},
		[]string{`[(text: " FOO ")]`}},
	{"two", `{{define "foo"}} FOO {{end}}{{define "bar"}} BAR {{end}}`, noError,
		[]string{"foo", "bar"},
		[]string{`[(text: " FOO ")]`, `[(text: " BAR ")]`}},
	// errors
	{"missing end", `{{define "foo"}} FOO `, hasError,
		nil,
		nil},
	{"malformed name", `{{define "foo}} FOO `, hasError,
		nil,
		nil},
}

func TestSetParse(t *testing.T) {
	for _, test := range setParseTests {
		set := new(Set)
		err := set.Parse(test.input)
		switch {
		case err == nil && !test.ok:
			t.Errorf("%q: expected error; got none", test.name)
			continue
		case err != nil && test.ok:
			t.Errorf("%q: unexpected error: %v", test.name, err)
			continue
		case err != nil && !test.ok:
			// expected error, got one
			if *debug {
				fmt.Printf("%s: %s\n\t%s\n", test.name, test.input, err)
			}
			continue
		}
		if len(set.tmpl) != len(test.names) {
			t.Errorf("%s: wrong number of templates; wanted %d got %d", test.name, len(test.names), len(set.tmpl))
			continue
		}
		for i, name := range test.names {
			tmpl, ok := set.tmpl[name]
			if !ok {
				t.Errorf("%s: can't find template %q", test.name, name)
				continue
			}
			result := tmpl.root.String()
			if result != test.results[i] {
				t.Errorf("%s=(%q): got\n\t%v\nexpected\n\t%v", test.name, test.input, result, test.results[i])
			}
		}
	}
}

var setExecTests = []execTest{
	{"empty", "", "", nil, true},
	{"text", "some text", "some text", nil, true},
	{"invoke x", `{{template "x" .SI}}`, "TEXT", tVal, true},
	{"invoke x no args", `{{template "x"}}`, "TEXT", tVal, true},
	{"invoke dot int", `{{template "dot" .I}}`, "17", tVal, true},
	{"invoke dot []int", `{{template "dot" .SI}}`, "[3 4 5]", tVal, true},
	{"invoke dotV", `{{template "dotV" .U}}`, "v", tVal, true},
	{"invoke nested int", `{{template "nested" .I}}`, "17", tVal, true},
	{"variable declared by template", `{{template "nested" $x=.SI}},{{index $x 1}}`, "[3 4 5],4", tVal, true},

	// User-defined function: test argument evaluator.
	{"testFunc literal", `{{oneArg "joe"}}`, "oneArg=joe", tVal, true},
	{"testFunc .", `{{oneArg .}}`, "oneArg=joe", "joe", true},
}

// These strings are also in testdata/*.
const setText1 = `
	{{define "x"}}TEXT{{end}}
	{{define "dotV"}}{{.V}}{{end}}
`

const setText2 = `
	{{define "dot"}}{{.}}{{end}}
	{{define "nested"}}{{template "dot" .}}{{end}}
`

func TestSetExecute(t *testing.T) {
	// Declare a set with a couple of templates first.
	set := new(Set)
	err := set.Parse(setText1)
	if err != nil {
		t.Fatalf("error parsing set: %s", err)
	}
	err = set.Parse(setText2)
	if err != nil {
		t.Fatalf("error parsing set: %s", err)
	}
	testExecute(setExecTests, set, t)
}

func TestSetParseFile(t *testing.T) {
	set := new(Set)
	err := set.ParseFile("DOES NOT EXIST")
	if err == nil {
		t.Error("expected error for non-existent file; got none")
	}
	err = set.ParseFile("testdata/file1.tmpl", "testdata/file2.tmpl")
	if err != nil {
		t.Fatalf("error parsing files: %v", err)
	}
	testExecute(setExecTests, set, t)
}

func TestParseSetFile(t *testing.T) {
	set, err := ParseSetFile("DOES NOT EXIST")
	if err == nil {
		t.Error("expected error for non-existent file; got none")
	}
	set, err = ParseSetFile("testdata/file1.tmpl", "testdata/file2.tmpl")
	if err != nil {
		t.Fatalf("error parsing files: %v", err)
	}
	testExecute(setExecTests, set, t)
}

func TestParseSetFiles(t *testing.T) {
	set, err := ParseSetFiles("NO SUCH FILE")
	if err == nil {
		t.Error("expected error for empty file list; got none")
	}
	set, err = ParseSetFiles("[x")
	if err == nil {
		t.Error("expected error for bad pattern; got none")
	}
	set, err = ParseSetFiles("testdata/*.tmpl")
	if err != nil {
		t.Fatalf("error parsing files: %v", err)
	}
	testExecute(setExecTests, set, t)
}
<commit_msg>exp/template: trivial cleanup in test Clean up glitch created by flurry of editing.<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 template

import (
	"fmt"
	"testing"
)

type setParseTest struct {
	name    string
	input   string
	ok      bool
	names   []string
	results []string
}

var setParseTests = []setParseTest{
	{"empty", "", noError,
		nil,
		nil},
	{"one", `{{define "foo"}} FOO {{end}}`, noError,
		[]string{"foo"},
		[]string{`[(text: " FOO ")]`}},
	{"two", `{{define "foo"}} FOO {{end}}{{define "bar"}} BAR {{end}}`, noError,
		[]string{"foo", "bar"},
		[]string{`[(text: " FOO ")]`, `[(text: " BAR ")]`}},
	// errors
	{"missing end", `{{define "foo"}} FOO `, hasError,
		nil,
		nil},
	{"malformed name", `{{define "foo}} FOO `, hasError,
		nil,
		nil},
}

func TestSetParse(t *testing.T) {
	for _, test := range setParseTests {
		set := new(Set)
		err := set.Parse(test.input)
		switch {
		case err == nil && !test.ok:
			t.Errorf("%q: expected error; got none", test.name)
			continue
		case err != nil && test.ok:
			t.Errorf("%q: unexpected error: %v", test.name, err)
			continue
		case err != nil && !test.ok:
			// expected error, got one
			if *debug {
				fmt.Printf("%s: %s\n\t%s\n", test.name, test.input, err)
			}
			continue
		}
		if len(set.tmpl) != len(test.names) {
			t.Errorf("%s: wrong number of templates; wanted %d got %d", test.name, len(test.names), len(set.tmpl))
			continue
		}
		for i, name := range test.names {
			tmpl, ok := set.tmpl[name]
			if !ok {
				t.Errorf("%s: can't find template %q", test.name, name)
				continue
			}
			result := tmpl.root.String()
			if result != test.results[i] {
				t.Errorf("%s=(%q): got\n\t%v\nexpected\n\t%v", test.name, test.input, result, test.results[i])
			}
		}
	}
}

var setExecTests = []execTest{
	{"empty", "", "", nil, true},
	{"text", "some text", "some text", nil, true},
	{"invoke x", `{{template "x" .SI}}`, "TEXT", tVal, true},
	{"invoke x no args", `{{template "x"}}`, "TEXT", tVal, true},
	{"invoke dot int", `{{template "dot" .I}}`, "17", tVal, true},
	{"invoke dot []int", `{{template "dot" .SI}}`, "[3 4 5]", tVal, true},
	{"invoke dotV", `{{template "dotV" .U}}`, "v", tVal, true},
	{"invoke nested int", `{{template "nested" .I}}`, "17", tVal, true},
	{"variable declared by template", `{{template "nested" $x=.SI}},{{index $x 1}}`, "[3 4 5],4", tVal, true},

	// User-defined function: test argument evaluator.
	{"testFunc literal", `{{oneArg "joe"}}`, "oneArg=joe", tVal, true},
	{"testFunc .", `{{oneArg .}}`, "oneArg=joe", "joe", true},
}

// These strings are also in testdata/*.
const setText1 = `
	{{define "x"}}TEXT{{end}}
	{{define "dotV"}}{{.V}}{{end}}
`

const setText2 = `
	{{define "dot"}}{{.}}{{end}}
	{{define "nested"}}{{template "dot" .}}{{end}}
`

func TestSetExecute(t *testing.T) {
	// Declare a set with a couple of templates first.
	set := new(Set)
	err := set.Parse(setText1)
	if err != nil {
		t.Fatalf("error parsing set: %s", err)
	}
	err = set.Parse(setText2)
	if err != nil {
		t.Fatalf("error parsing set: %s", err)
	}
	testExecute(setExecTests, set, t)
}

func TestSetParseFile(t *testing.T) {
	set := new(Set)
	err := set.ParseFile("DOES NOT EXIST")
	if err == nil {
		t.Error("expected error for non-existent file; got none")
	}
	err = set.ParseFile("testdata/file1.tmpl", "testdata/file2.tmpl")
	if err != nil {
		t.Fatalf("error parsing files: %v", err)
	}
	testExecute(setExecTests, set, t)
}

func TestParseSetFile(t *testing.T) {
	set, err := ParseSetFile("DOES NOT EXIST")
	if err == nil {
		t.Error("expected error for non-existent file; got none")
	}
	set, err = ParseSetFile("testdata/file1.tmpl", "testdata/file2.tmpl")
	if err != nil {
		t.Fatalf("error parsing files: %v", err)
	}
	testExecute(setExecTests, set, t)
}

func TestParseSetFiles(t *testing.T) {
	set, err := ParseSetFiles("DOES NOT EXIST")
	if err == nil {
		t.Error("expected error for non-existent file; got none")
	}
	set, err = ParseSetFiles("[x")
	if err == nil {
		t.Error("expected error for bad pattern; got none")
	}
	set, err = ParseSetFiles("testdata/*.tmpl")
	if err != nil {
		t.Fatalf("error parsing files: %v", err)
	}
	testExecute(setExecTests, set, t)
}
<|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.

// Netlink sockets and messages

package syscall

import (
	"unsafe"
)

// Round the length of a netlink message up to align it properly.
func nlmAlignOf(msglen int) int {
	return (msglen + NLMSG_ALIGNTO - 1) & ^(NLMSG_ALIGNTO - 1)
}

// Round the length of a netlink route attribute up to align it
// properly.
func rtaAlignOf(attrlen int) int {
	return (attrlen + RTA_ALIGNTO - 1) & ^(RTA_ALIGNTO - 1)
}

// NetlinkRouteRequest represents the request message to receive
// routing and link states from the kernel.
type NetlinkRouteRequest struct {
	Header NlMsghdr
	Data   RtGenmsg
}

func (rr *NetlinkRouteRequest) toWireFormat() []byte {
	b := make([]byte, rr.Header.Len)
	b[0] = byte(rr.Header.Len)
	b[1] = byte(rr.Header.Len >> 8)
	b[2] = byte(rr.Header.Len >> 16)
	b[3] = byte(rr.Header.Len >> 24)
	b[4] = byte(rr.Header.Type)
	b[5] = byte(rr.Header.Type >> 8)
	b[6] = byte(rr.Header.Flags)
	b[7] = byte(rr.Header.Flags >> 8)
	b[8] = byte(rr.Header.Seq)
	b[9] = byte(rr.Header.Seq >> 8)
	b[10] = byte(rr.Header.Seq >> 16)
	b[11] = byte(rr.Header.Seq >> 24)
	b[12] = byte(rr.Header.Pid)
	b[13] = byte(rr.Header.Pid >> 8)
	b[14] = byte(rr.Header.Pid >> 16)
	b[15] = byte(rr.Header.Pid >> 24)
	b[16] = byte(rr.Data.Family)
	return b
}

func newNetlinkRouteRequest(proto, seq, family int) []byte {
	rr := &NetlinkRouteRequest{}
	rr.Header.Len = NLMSG_HDRLEN + SizeofRtGenmsg
	rr.Header.Type = uint16(proto)
	rr.Header.Flags = NLM_F_DUMP | NLM_F_REQUEST
	rr.Header.Seq = uint32(seq)
	rr.Data.Family = uint8(family)
	return rr.toWireFormat()
}

// NetlinkRIB returns routing information base, as known as RIB,
// which consists of network facility information, states and
// parameters.
func NetlinkRIB(proto, family int) ([]byte, int) {
	var (
		s     int
		e     int
		lsanl SockaddrNetlink
		seq   int
		tab   []byte
	)

	s, e = Socket(AF_NETLINK, SOCK_RAW, 0)
	if e != 0 {
		return nil, e
	}
	defer Close(s)

	lsanl.Family = AF_NETLINK
	e = Bind(s, &lsanl)
	if e != 0 {
		return nil, e
	}

	seq++
	wb := newNetlinkRouteRequest(proto, seq, family)
	e = Sendto(s, wb, 0, &lsanl)
	if e != 0 {
		return nil, e
	}

	for {
		var (
			rb  []byte
			nr  int
			lsa Sockaddr
		)

		rb = make([]byte, Getpagesize())
		nr, _, e = Recvfrom(s, rb, 0)
		if e != 0 {
			return nil, e
		}
		if nr < NLMSG_HDRLEN {
			return nil, EINVAL
		}
		rb = rb[:nr]
		tab = append(tab, rb...)

		msgs, _ := ParseNetlinkMessage(rb)
		for _, m := range msgs {
			if lsa, e = Getsockname(s); e != 0 {
				return nil, e
			}
			switch v := lsa.(type) {
			case *SockaddrNetlink:
				if m.Header.Seq != uint32(seq) || m.Header.Pid != v.Pid {
					return nil, EINVAL
				}
			default:
				return nil, EINVAL
			}
			if m.Header.Type == NLMSG_DONE {
				goto done
			}
			if m.Header.Type == NLMSG_ERROR {
				return nil, EINVAL
			}
		}
	}

done:
	return tab, 0
}

// NetlinkMessage represents the netlink message.
type NetlinkMessage struct {
	Header NlMsghdr
	Data   []byte
}

// ParseNetlinkMessage parses buf as netlink messages and returns
// the slice containing the NetlinkMessage structs.
func ParseNetlinkMessage(buf []byte) ([]NetlinkMessage, int) {
	var (
		h    *NlMsghdr
		dbuf []byte
		dlen int
		e    int
		msgs []NetlinkMessage
	)

	for len(buf) >= NLMSG_HDRLEN {
		h, dbuf, dlen, e = netlinkMessageHeaderAndData(buf)
		if e != 0 {
			break
		}
		m := NetlinkMessage{}
		m.Header = *h
		m.Data = dbuf[:h.Len-NLMSG_HDRLEN]
		msgs = append(msgs, m)
		buf = buf[dlen:]
	}

	return msgs, e
}

func netlinkMessageHeaderAndData(buf []byte) (*NlMsghdr, []byte, int, int) {
	h := (*NlMsghdr)(unsafe.Pointer(&buf[0]))
	if h.Len < NLMSG_HDRLEN || int(h.Len) > len(buf) {
		return nil, nil, 0, EINVAL
	}
	return h, buf[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), 0
}

// NetlinkRouteAttr represents the netlink route attribute.
type NetlinkRouteAttr struct {
	Attr  RtAttr
	Value []byte
}

// ParseNetlinkRouteAttr parses msg's payload as netlink route
// attributes and returns the slice containing the NetlinkRouteAttr
// structs.
func ParseNetlinkRouteAttr(msg *NetlinkMessage) ([]NetlinkRouteAttr, int) {
	var (
		buf   []byte
		a     *RtAttr
		alen  int
		vbuf  []byte
		e     int
		attrs []NetlinkRouteAttr
	)

	switch msg.Header.Type {
	case RTM_NEWLINK:
		buf = msg.Data[SizeofIfInfomsg:]
	case RTM_NEWADDR:
		buf = msg.Data[SizeofIfAddrmsg:]
	default:
		return nil, EINVAL
	}

	for len(buf) >= SizeofRtAttr {
		a, vbuf, alen, e = netlinkRouteAttrAndValue(buf)
		if e != 0 {
			break
		}
		ra := NetlinkRouteAttr{}
		ra.Attr = *a
		ra.Value = vbuf[:a.Len-SizeofRtAttr]
		attrs = append(attrs, ra)
		buf = buf[alen:]
	}

	return attrs, 0
}

func netlinkRouteAttrAndValue(buf []byte) (*RtAttr, []byte, int, int) {
	h := (*RtAttr)(unsafe.Pointer(&buf[0]))
	if h.Len < SizeofRtAttr || int(h.Len) > len(buf) {
		return nil, nil, 0, EINVAL
	}
	return h, buf[SizeofRtAttr:], rtaAlignOf(int(h.Len)), 0
}
<commit_msg>syscall: Handle RTM_NEWROUTE in ParseNetlinkRouteAttr on Linux.<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.

// Netlink sockets and messages

package syscall

import (
	"unsafe"
)

// Round the length of a netlink message up to align it properly.
func nlmAlignOf(msglen int) int {
	return (msglen + NLMSG_ALIGNTO - 1) & ^(NLMSG_ALIGNTO - 1)
}

// Round the length of a netlink route attribute up to align it
// properly.
func rtaAlignOf(attrlen int) int {
	return (attrlen + RTA_ALIGNTO - 1) & ^(RTA_ALIGNTO - 1)
}

// NetlinkRouteRequest represents the request message to receive
// routing and link states from the kernel.
type NetlinkRouteRequest struct {
	Header NlMsghdr
	Data   RtGenmsg
}

func (rr *NetlinkRouteRequest) toWireFormat() []byte {
	b := make([]byte, rr.Header.Len)
	b[0] = byte(rr.Header.Len)
	b[1] = byte(rr.Header.Len >> 8)
	b[2] = byte(rr.Header.Len >> 16)
	b[3] = byte(rr.Header.Len >> 24)
	b[4] = byte(rr.Header.Type)
	b[5] = byte(rr.Header.Type >> 8)
	b[6] = byte(rr.Header.Flags)
	b[7] = byte(rr.Header.Flags >> 8)
	b[8] = byte(rr.Header.Seq)
	b[9] = byte(rr.Header.Seq >> 8)
	b[10] = byte(rr.Header.Seq >> 16)
	b[11] = byte(rr.Header.Seq >> 24)
	b[12] = byte(rr.Header.Pid)
	b[13] = byte(rr.Header.Pid >> 8)
	b[14] = byte(rr.Header.Pid >> 16)
	b[15] = byte(rr.Header.Pid >> 24)
	b[16] = byte(rr.Data.Family)
	return b
}

func newNetlinkRouteRequest(proto, seq, family int) []byte {
	rr := &NetlinkRouteRequest{}
	rr.Header.Len = NLMSG_HDRLEN + SizeofRtGenmsg
	rr.Header.Type = uint16(proto)
	rr.Header.Flags = NLM_F_DUMP | NLM_F_REQUEST
	rr.Header.Seq = uint32(seq)
	rr.Data.Family = uint8(family)
	return rr.toWireFormat()
}

// NetlinkRIB returns routing information base, as known as RIB,
// which consists of network facility information, states and
// parameters.
func NetlinkRIB(proto, family int) ([]byte, int) {
	var (
		s     int
		e     int
		lsanl SockaddrNetlink
		seq   int
		tab   []byte
	)

	s, e = Socket(AF_NETLINK, SOCK_RAW, 0)
	if e != 0 {
		return nil, e
	}
	defer Close(s)

	lsanl.Family = AF_NETLINK
	e = Bind(s, &lsanl)
	if e != 0 {
		return nil, e
	}

	seq++
	wb := newNetlinkRouteRequest(proto, seq, family)
	e = Sendto(s, wb, 0, &lsanl)
	if e != 0 {
		return nil, e
	}

	for {
		var (
			rb  []byte
			nr  int
			lsa Sockaddr
		)

		rb = make([]byte, Getpagesize())
		nr, _, e = Recvfrom(s, rb, 0)
		if e != 0 {
			return nil, e
		}
		if nr < NLMSG_HDRLEN {
			return nil, EINVAL
		}
		rb = rb[:nr]
		tab = append(tab, rb...)

		msgs, _ := ParseNetlinkMessage(rb)
		for _, m := range msgs {
			if lsa, e = Getsockname(s); e != 0 {
				return nil, e
			}
			switch v := lsa.(type) {
			case *SockaddrNetlink:
				if m.Header.Seq != uint32(seq) || m.Header.Pid != v.Pid {
					return nil, EINVAL
				}
			default:
				return nil, EINVAL
			}
			if m.Header.Type == NLMSG_DONE {
				goto done
			}
			if m.Header.Type == NLMSG_ERROR {
				return nil, EINVAL
			}
		}
	}

done:
	return tab, 0
}

// NetlinkMessage represents the netlink message.
type NetlinkMessage struct {
	Header NlMsghdr
	Data   []byte
}

// ParseNetlinkMessage parses buf as netlink messages and returns
// the slice containing the NetlinkMessage structs.
func ParseNetlinkMessage(buf []byte) ([]NetlinkMessage, int) {
	var (
		h    *NlMsghdr
		dbuf []byte
		dlen int
		e    int
		msgs []NetlinkMessage
	)

	for len(buf) >= NLMSG_HDRLEN {
		h, dbuf, dlen, e = netlinkMessageHeaderAndData(buf)
		if e != 0 {
			break
		}
		m := NetlinkMessage{}
		m.Header = *h
		m.Data = dbuf[:h.Len-NLMSG_HDRLEN]
		msgs = append(msgs, m)
		buf = buf[dlen:]
	}

	return msgs, e
}

func netlinkMessageHeaderAndData(buf []byte) (*NlMsghdr, []byte, int, int) {
	h := (*NlMsghdr)(unsafe.Pointer(&buf[0]))
	if h.Len < NLMSG_HDRLEN || int(h.Len) > len(buf) {
		return nil, nil, 0, EINVAL
	}
	return h, buf[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), 0
}

// NetlinkRouteAttr represents the netlink route attribute.
type NetlinkRouteAttr struct {
	Attr  RtAttr
	Value []byte
}

// ParseNetlinkRouteAttr parses msg's payload as netlink route
// attributes and returns the slice containing the NetlinkRouteAttr
// structs.
func ParseNetlinkRouteAttr(msg *NetlinkMessage) ([]NetlinkRouteAttr, int) {
	var (
		buf   []byte
		a     *RtAttr
		alen  int
		vbuf  []byte
		e     int
		attrs []NetlinkRouteAttr
	)

	switch msg.Header.Type {
	case RTM_NEWLINK:
		buf = msg.Data[SizeofIfInfomsg:]
	case RTM_NEWADDR:
		buf = msg.Data[SizeofIfAddrmsg:]
	case RTM_NEWROUTE:
		buf = msg.Data[SizeofRtmsg:]
	default:
		return nil, EINVAL
	}

	for len(buf) >= SizeofRtAttr {
		a, vbuf, alen, e = netlinkRouteAttrAndValue(buf)
		if e != 0 {
			break
		}
		ra := NetlinkRouteAttr{}
		ra.Attr = *a
		ra.Value = vbuf[:a.Len-SizeofRtAttr]
		attrs = append(attrs, ra)
		buf = buf[alen:]
	}

	return attrs, 0
}

func netlinkRouteAttrAndValue(buf []byte) (*RtAttr, []byte, int, int) {
	h := (*RtAttr)(unsafe.Pointer(&buf[0]))
	if h.Len < SizeofRtAttr || int(h.Len) > len(buf) {
		return nil, nil, 0, EINVAL
	}
	return h, buf[SizeofRtAttr:], rtaAlignOf(int(h.Len)), 0
}
<|endoftext|>