<commit_before>package javaclass

import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"
	"os"
)

var (
	ErrNotEnoughBytes   = errors.New("Can't read enough bytes")
	ErrWrongMagicNumber = errors.New("Wrong magic number")
)

func readBytes(f *os.File, buff []byte) error {
	n, err := f.Read(buff)

	if err != nil {
		return err
	}

	if n < len(buff) {
		return ErrNotEnoughBytes
	}

	return nil
}

func readBinary(r io.Reader, data interface{}) error {
	return binary.Read(r, binary.BigEndian, data)
}

func bytesToU2(buf []byte) u2 {
	return u2((buf[0] << 8) + buf[1])
}

func bytesToInt(buf []byte) int {
	intVal := 0

	// not sure this works with negative numbers
	for _, b := range buf {
		// big endian
		intVal <<= 8
		intVal += int(b)
	}

	return intVal
}

func readInt(r io.Reader, data *int, length int) error {
	buf := make([]byte, length)
	if err := readBinary(r, buf); err != nil {
		return err
	}

	*data = bytesToInt(buf)
	return nil
}

func readU2(r io.Reader, data *u2) error {
	buf := make([]byte, 2)
	if err := readBinary(r, buf); err != nil {
		return err
	}

	*data = u2(buf[0]<<8 + buf[1])
	return nil
}

func readU1(r io.Reader, data *u1) error {
	buf := make([]byte, 1)
	if err := readBinary(r, buf); err != nil {
		return err
	}

	*data = u1(buf[0])
	return nil
}

func setFlag(n u2, magic u2, flag *bool) {
	*flag = n&magic == magic
}

func parseInterfaces(cls *JClass, interfaces []byte) error {
	// TODO
	return nil
}

func parseFields(cls *JClass, fields []byte) error {
	// TODO
	return nil
}

func parseMethods(cls *JClass, methods []byte) error {
	// TODO
	return nil
}

func parseAttrs(cls *JClass, attrs []byte) error {
	// TODO
	return nil
}

func ParseClassFromFile(f *os.File) (JClass, error) {

	// magic number
	buf4 := make([]byte, 4)
	if err := readBytes(f, buf4); err != nil {
		return JClass{}, err
	}

	if !bytes.Equal(buf4, []byte{0xCA, 0xFE, 0xBA, 0xBE}) {
		return JClass{}, ErrWrongMagicNumber
	}

	cls := JClass{}

	// minor version number
	if err := readU2(f, &cls.minorVersion); err != nil {
		return cls, err
	}

	// major version number
	if err := readU2(f, &cls.majorVersion); err != nil {
		return cls, err
	}

	// constant pool size
	var constantPoolSize u2
	if err := readU2(f, &constantPoolSize); err != nil {
		return cls, err
	}

	// constant pool
	if err := cls.parseConstantPool(constantPoolSize, f); err != nil {
		return cls, err
	}

	// access flags
	var accessFlags u2
	if err := readU2(f, &accessFlags); err != nil {
		return cls, err
	}
	cls.setAccessFlags(accessFlags)

	// this class
	if err := readU2(f, &cls.classIndex); err != nil {
		return cls, err
	}

	// super class
	if err := readU2(f, &cls.superClassIndex); err != nil {
		return cls, err
	}

	/* TODO

	// interfaces
	var interfacesCount u2
	if err := readU2(f, &interfacesCount); err != nil {
		return cls, err
	}

	interfaces := make([]byte, interfacesCount)
	if err := parseInterfaces(&cls, interfaces); err != nil {
		return cls, err
	}

	// fields
	var fieldsCount u2
	if err := readU2(f, &fieldsCount); err != nil {
		return cls, err
	}

	fields := make([]byte, fieldsCount)
	if err := parseFields(&cls, fields); err != nil {
		return cls, err
	}

	// methods
	var methodsCount u2
	if err := readU2(f, &methodsCount); err != nil {
		return cls, err
	}

	methods := make([]byte, methodsCount)
	if err := parseMethods(&cls, methods); err != nil {
		return cls, err
	}

	// attributes
	var attrsCount u2
	if err := readU2(f, &attrsCount); err != nil {
		return cls, err
	}

	attrs := make([]byte, attrsCount)
	if err := parseAttrs(&cls, attrs); err != nil {
		return cls, err
	}
	*/

	return cls, nil
}
<commit_msg>unused readInt function removed<commit_after>package javaclass

import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"
	"os"
)

var (
	ErrNotEnoughBytes   = errors.New("Can't read enough bytes")
	ErrWrongMagicNumber = errors.New("Wrong magic number")
)

func readBytes(f *os.File, buff []byte) error {
	n, err := f.Read(buff)

	if err != nil {
		return err
	}

	if n < len(buff) {
		return ErrNotEnoughBytes
	}

	return nil
}

func readBinary(r io.Reader, data interface{}) error {
	return binary.Read(r, binary.BigEndian, data)
}

func bytesToU2(buf []byte) u2 {
	return u2((buf[0] << 8) + buf[1])
}

func bytesToInt(buf []byte) int {
	intVal := 0

	// not sure this works with negative numbers
	for _, b := range buf {
		// big endian
		intVal <<= 8
		intVal += int(b)
	}

	return intVal
}

func readU2(r io.Reader, data *u2) error {
	buf := make([]byte, 2)
	if err := readBinary(r, buf); err != nil {
		return err
	}

	*data = bytesToU2(buf)
	return nil
}

func readU1(r io.Reader, data *u1) error {
	buf := make([]byte, 1)
	if err := readBinary(r, buf); err != nil {
		return err
	}

	*data = u1(buf[0])
	return nil
}

func setFlag(n u2, magic u2, flag *bool) {
	*flag = n&magic == magic
}

func parseInterfaces(cls *JClass, interfaces []byte) error {
	// TODO
	return nil
}

func parseFields(cls *JClass, fields []byte) error {
	// TODO
	return nil
}

func parseMethods(cls *JClass, methods []byte) error {
	// TODO
	return nil
}

func parseAttrs(cls *JClass, attrs []byte) error {
	// TODO
	return nil
}

func ParseClassFromFile(f *os.File) (JClass, error) {

	// magic number
	buf4 := make([]byte, 4)
	if err := readBytes(f, buf4); err != nil {
		return JClass{}, err
	}

	if !bytes.Equal(buf4, []byte{0xCA, 0xFE, 0xBA, 0xBE}) {
		return JClass{}, ErrWrongMagicNumber
	}

	cls := JClass{}

	// minor version number
	if err := readU2(f, &cls.minorVersion); err != nil {
		return cls, err
	}

	// major version number
	if err := readU2(f, &cls.majorVersion); err != nil {
		return cls, err
	}

	// constant pool size
	var constantPoolSize u2
	if err := readU2(f, &constantPoolSize); err != nil {
		return cls, err
	}

	// constant pool
	if err := cls.parseConstantPool(constantPoolSize, f); err != nil {
		return cls, err
	}

	// access flags
	var accessFlags u2
	if err := readU2(f, &accessFlags); err != nil {
		return cls, err
	}
	cls.setAccessFlags(accessFlags)

	// this class
	if err := readU2(f, &cls.classIndex); err != nil {
		return cls, err
	}

	// super class
	if err := readU2(f, &cls.superClassIndex); err != nil {
		return cls, err
	}

	/* TODO

	// interfaces
	var interfacesCount u2
	if err := readU2(f, &interfacesCount); err != nil {
		return cls, err
	}

	interfaces := make([]byte, interfacesCount)
	if err := parseInterfaces(&cls, interfaces); err != nil {
		return cls, err
	}

	// fields
	var fieldsCount u2
	if err := readU2(f, &fieldsCount); err != nil {
		return cls, err
	}

	fields := make([]byte, fieldsCount)
	if err := parseFields(&cls, fields); err != nil {
		return cls, err
	}

	// methods
	var methodsCount u2
	if err := readU2(f, &methodsCount); err != nil {
		return cls, err
	}

	methods := make([]byte, methodsCount)
	if err := parseMethods(&cls, methods); err != nil {
		return cls, err
	}

	// attributes
	var attrsCount u2
	if err := readU2(f, &attrsCount); err != nil {
		return cls, err
	}

	attrs := make([]byte, attrsCount)
	if err := parseAttrs(&cls, attrs); err != nil {
		return cls, err
	}
	*/

	return cls, nil
}
<|endoftext|>


<commit_before>package metadata

import "fmt"

type Metadata struct {
	ProductFiles   []ProductFile `yaml:"product_files"`
	ReleaseType    string        `yaml:"release_type"`
	EulaSlug       string        `yaml:"eula_slug"`
	ProductVersion string        `yaml:"product_version"`
}

type ProductFile struct {
	File        string `yaml:"file"`
	Description string `yaml:"description"`
	UploadAs    string `yaml:"upload_as"`
}

func (m Metadata) Validate() error {
	for _, productFile := range m.ProductFiles {
		if productFile.File == "" {
			return fmt.Errorf("empty value for file")
		}
	}
	return nil
}
<commit_msg>Adding more fields to the metadata struct<commit_after>package metadata

import "fmt"

type Metadata struct {
	ProductFiles    []ProductFile `yaml:"product_files"`
	ReleaseType     string        `yaml:"release_type"`
	EulaSlug        string        `yaml:"eula_slug"`
	ProductVersion  string        `yaml:"product_version"`
	ReleaseDate     string        `yaml:"release_date"`
	Description     string        `yaml:"description"`
	ReleaseNotesURL string        `yaml:"release_notes_url"`
}

type ProductFile struct {
	File        string `yaml:"file"`
	Description string `yaml:"description"`
	UploadAs    string `yaml:"upload_as"`
}

func (m Metadata) Validate() error {
	for _, productFile := range m.ProductFiles {
		if productFile.File == "" {
			return fmt.Errorf("empty value for file")
		}
	}
	return nil
}
<|endoftext|>


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

package main

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestSecretMapOperations(t *testing.T) {
	assert := assert.New(t)

	s, err := ParseSecret(fixture("secret.json"))
	assert.NoError(err)

	secretMap := NewSecretMap()
	assert.Equal(0, secretMap.Len())
	assert.Empty(secretMap.Values())

	lookup, ok := secretMap.Get("foo")
	assert.False(ok)

	secretMap.Put("foo", *s)
	assert.Equal(1, secretMap.Len())

	values := secretMap.Values()
	assert.Len(values, 1)
	assert.Equal(*s, values[0].Secret)

	lookup, ok = secretMap.Get("foo")
	assert.True(ok)
	assert.Equal(*s, lookup.Secret)

	put := secretMap.PutIfAbsent("foo", Secret{})
	assert.False(put)

	lookup, ok = secretMap.Get("foo")
	assert.True(ok)
	assert.Equal(*s, lookup.Secret)

	secretMap.Put("foo", Secret{})

	lookup, ok = secretMap.Get("foo")
	assert.True(ok)
	assert.NotEqual(*s, lookup.Secret)
}

func TestSecretMapOverwrite(t *testing.T) {
	assert := assert.New(t)

	s, err := ParseSecret(fixture("secret.json"))
	assert.NoError(err)

	secretMap := NewSecretMap()
	secretMap.Put("foo", Secret{})

	newMap := NewSecretMap()
	newMap.Put("bar", *s)
	secretMap.Overwrite(newMap)

	assert.Equal(1, secretMap.Len())
	lookup, ok := secretMap.Get("bar")
	assert.True(ok)
	assert.Equal(*s, lookup.Secret)
}

func TestSecretMapTimestamp(t *testing.T) {
	assert := assert.New(t)

	secretMap := NewSecretMap()
	secretMap.Put("foo", Secret{})

	val, ok := secretMap.Get("foo")
	assert.True(ok)
	earlierTime := val.Time

	secretMap.Put("foo", Secret{})
	val, ok = secretMap.Get("foo")
	assert.True(ok)
	assert.True(val.Time.After(earlierTime))
}
<commit_msg>Add test for PutIfAbsent on absent key<commit_after>// Copyright 2015 Square Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestSecretMapOperations(t *testing.T) {
	assert := assert.New(t)

	s, err := ParseSecret(fixture("secret.json"))
	assert.NoError(err)

	secretMap := NewSecretMap()
	assert.Equal(0, secretMap.Len())
	assert.Empty(secretMap.Values())

	lookup, ok := secretMap.Get("foo")
	assert.False(ok)

	secretMap.Put("foo", *s)
	assert.Equal(1, secretMap.Len())

	values := secretMap.Values()
	assert.Len(values, 1)
	assert.Equal(*s, values[0].Secret)

	put := secretMap.PutIfAbsent("test", Secret{})
	assert.True(put)

	lookup, ok = secretMap.Get("foo")
	assert.True(ok)
	assert.Equal(*s, lookup.Secret)

	put = secretMap.PutIfAbsent("foo", Secret{})
	assert.False(put)

	lookup, ok = secretMap.Get("foo")
	assert.True(ok)
	assert.Equal(*s, lookup.Secret)

	secretMap.Put("foo", Secret{})

	lookup, ok = secretMap.Get("foo")
	assert.True(ok)
	assert.NotEqual(*s, lookup.Secret)
}

func TestSecretMapOverwrite(t *testing.T) {
	assert := assert.New(t)

	s, err := ParseSecret(fixture("secret.json"))
	assert.NoError(err)

	secretMap := NewSecretMap()
	secretMap.Put("foo", Secret{})

	newMap := NewSecretMap()
	newMap.Put("bar", *s)
	secretMap.Overwrite(newMap)

	assert.Equal(1, secretMap.Len())
	lookup, ok := secretMap.Get("bar")
	assert.True(ok)
	assert.Equal(*s, lookup.Secret)
}

func TestSecretMapTimestamp(t *testing.T) {
	assert := assert.New(t)

	secretMap := NewSecretMap()
	secretMap.Put("foo", Secret{})

	val, ok := secretMap.Get("foo")
	assert.True(ok)
	earlierTime := val.Time

	secretMap.Put("foo", Secret{})
	val, ok = secretMap.Get("foo")
	assert.True(ok)
	assert.True(val.Time.After(earlierTime))
}
<|endoftext|>


<commit_before><commit_msg>golint: punctuation fixes on errors<commit_after><|endoftext|>


<commit_before>package libp2pquic

import (
	"fmt"
	"net"
	"sync"

	tpt "github.com/libp2p/go-libp2p-transport"
	smux "github.com/libp2p/go-stream-muxer"
	quic "github.com/lucas-clemente/quic-go"
	ma "github.com/multiformats/go-multiaddr"
	manet "github.com/multiformats/go-multiaddr-net"
)

type quicConn struct {
	mutex sync.RWMutex

	sess      quic.Session
	transport tpt.Transport

	laddr ma.Multiaddr
	raddr ma.Multiaddr

	closed bool
}

var _ tpt.Conn = &quicConn{}
var _ tpt.MultiStreamConn = &quicConn{}

func newQuicConn(sess quic.Session, t tpt.Transport) (*quicConn, error) {
	// analogues to manet.WrapNetConn
	laddr, err := quicMultiAddress(sess.LocalAddr())
	if err != nil {
		return nil, fmt.Errorf("failed to convert nconn.LocalAddr: %s", err)
	}

	// analogues to manet.WrapNetConn
	raddr, err := quicMultiAddress(sess.RemoteAddr())
	if err != nil {
		return nil, fmt.Errorf("failed to convert nconn.RemoteAddr: %s", err)
	}

	c := &quicConn{
		sess:      sess,
		laddr:     laddr,
		raddr:     raddr,
		transport: t,
	}
	go c.watchClosed()

	return c, nil
}

func (c *quicConn) AcceptStream() (smux.Stream, error) {
	str, err := c.sess.AcceptStream()
	return &stream{str}, err
}

// OpenStream opens a new stream
// It blocks until a new stream can be opened (when limited by the QUIC maximum stream limit)
func (c *quicConn) OpenStream() (smux.Stream, error) {
	str, err := c.sess.OpenStreamSync()
	return &stream{str}, err
}

func (c *quicConn) Close() error {
	return c.sess.Close(nil)
}

func (c *quicConn) watchClosed() {
	<-c.sess.Context().Done()
	c.mutex.Lock()
	c.closed = true
	c.mutex.Unlock()
}

func (c *quicConn) IsClosed() bool {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	return c.closed
}

func (c *quicConn) LocalAddr() net.Addr {
	return c.sess.LocalAddr()
}

func (c *quicConn) LocalMultiaddr() ma.Multiaddr {
	return c.laddr
}

func (c *quicConn) RemoteAddr() net.Addr {
	return c.sess.RemoteAddr()
}

func (c *quicConn) RemoteMultiaddr() ma.Multiaddr {
	return c.raddr
}

func (c *quicConn) Transport() tpt.Transport {
	return c.transport
}

// TODO: there must be a better way to do this
func quicMultiAddress(na net.Addr) (ma.Multiaddr, error) {
	udpMA, err := manet.FromNetAddr(na)
	if err != nil {
		return nil, err
	}
	quicMA, err := ma.NewMultiaddr(udpMA.String() + "/quic")
	if err != nil {
		return nil, err
	}
	return quicMA, nil
}
<commit_msg>use the renamed transport interfaces<commit_after>package libp2pquic

import (
	"fmt"
	"net"
	"sync"

	tpt "github.com/libp2p/go-libp2p-transport"
	smux "github.com/libp2p/go-stream-muxer"
	quic "github.com/lucas-clemente/quic-go"
	ma "github.com/multiformats/go-multiaddr"
	manet "github.com/multiformats/go-multiaddr-net"
)

type quicConn struct {
	mutex sync.RWMutex

	sess      quic.Session
	transport tpt.Transport

	laddr ma.Multiaddr
	raddr ma.Multiaddr

	closed bool
}

var _ tpt.Conn = &quicConn{}
var _ tpt.MultiplexConn = &quicConn{}

func newQuicConn(sess quic.Session, t tpt.Transport) (*quicConn, error) {
	// analogues to manet.WrapNetConn
	laddr, err := quicMultiAddress(sess.LocalAddr())
	if err != nil {
		return nil, fmt.Errorf("failed to convert nconn.LocalAddr: %s", err)
	}

	// analogues to manet.WrapNetConn
	raddr, err := quicMultiAddress(sess.RemoteAddr())
	if err != nil {
		return nil, fmt.Errorf("failed to convert nconn.RemoteAddr: %s", err)
	}

	c := &quicConn{
		sess:      sess,
		laddr:     laddr,
		raddr:     raddr,
		transport: t,
	}
	go c.watchClosed()

	return c, nil
}

func (c *quicConn) AcceptStream() (smux.Stream, error) {
	str, err := c.sess.AcceptStream()
	return &stream{str}, err
}

// OpenStream opens a new stream
// It blocks until a new stream can be opened (when limited by the QUIC maximum stream limit)
func (c *quicConn) OpenStream() (smux.Stream, error) {
	str, err := c.sess.OpenStreamSync()
	return &stream{str}, err
}

func (c *quicConn) Close() error {
	return c.sess.Close(nil)
}

func (c *quicConn) watchClosed() {
	<-c.sess.Context().Done()
	c.mutex.Lock()
	c.closed = true
	c.mutex.Unlock()
}

func (c *quicConn) IsClosed() bool {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	return c.closed
}

func (c *quicConn) LocalAddr() net.Addr {
	return c.sess.LocalAddr()
}

func (c *quicConn) LocalMultiaddr() ma.Multiaddr {
	return c.laddr
}

func (c *quicConn) RemoteAddr() net.Addr {
	return c.sess.RemoteAddr()
}

func (c *quicConn) RemoteMultiaddr() ma.Multiaddr {
	return c.raddr
}

func (c *quicConn) Transport() tpt.Transport {
	return c.transport
}

// TODO: there must be a better way to do this
func quicMultiAddress(na net.Addr) (ma.Multiaddr, error) {
	udpMA, err := manet.FromNetAddr(na)
	if err != nil {
		return nil, err
	}
	quicMA, err := ma.NewMultiaddr(udpMA.String() + "/quic")
	if err != nil {
		return nil, err
	}
	return quicMA, nil
}
<|endoftext|>


<commit_before><commit_msg>bump to 1.0.0<commit_after><|endoftext|>


<commit_before>/*
Copyright 2020 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package aws

import (
	"errors"
	"math/rand"
	"sort"
)

var allZones = []string{
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"ap-northeast-1a",
	//"ap-northeast-1c",
	//"ap-northeast-1d",
	// AZ does not exist, so we're breaking the 3 AZs per region target here
	//"ap-northeast-2b",
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"ap-northeast-2a",
	//"ap-northeast-2c",
	//"ap-northeast-2d",
	// Disabled until etcd-manager supports the region and the AMIs used in testing are present
	//"ap-northeast-3a",
	//"ap-northeast-3b",
	//"ap-northeast-3c",
	"ap-south-1a",
	"ap-south-1b",
	"ap-south-1c",
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"ap-southeast-1a",
	//"ap-southeast-1b",
	//"ap-southeast-1c",
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"ap-southeast-2a",
	//"ap-southeast-2b",
	//"ap-southeast-2c",
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"ca-central-1a",
	//"ca-central-1b",
	//"ca-central-1d",
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"eu-central-1a",
	//"eu-central-1b",
	//"eu-central-1c",
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"eu-north-1a",
	//"eu-north-1b",
	//"eu-north-1c",
	"eu-west-1a",
	"eu-west-1b",
	"eu-west-1c",
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"eu-west-2a",
	//"eu-west-2b",
	//"eu-west-2c",
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"eu-west-3a",
	//"eu-west-3b",
	//"eu-west-3c",
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"sa-east-1a",
	//"sa-east-1b",
	//"sa-east-1c",
	"us-east-1a",
	"us-east-1b",
	"us-east-1c",
	"us-east-1d",
	"us-east-1e",
	"us-east-1f",
	"us-east-2a",
	"us-east-2b",
	"us-east-2c",
	"us-west-1a",
	"us-west-1b",
	//"us-west-1c", AZ does not exist, so we're breaking the 3 AZs per region target here
	"us-west-2a",
	"us-west-2b",
	"us-west-2c",
	"us-west-2d",
}

// ErrNoEligibleRegion indicates the requested number of zones is not available in any region
var ErrNoEligibleRegion = errors.New("No eligible AWS region found with enough zones")

// RandomZones returns a random set of availability zones within a region
func RandomZones(count int) ([]string, error) {
	regions := make(map[string][]string)
	for _, zone := range allZones {
		region := zone[:len(zone)-1]
		regions[region] = append(regions[region], zone)
	}
	eligibleRegions := make([][]string, 0)
	for _, zones := range regions {
		if len(zones) >= count {
			eligibleRegions = append(eligibleRegions, zones)
		}
	}
	if len(eligibleRegions) == 0 {
		return nil, ErrNoEligibleRegion
	}
	chosenRegion := eligibleRegions[rand.Int()%len(eligibleRegions)]

	chosenZones := make([]string, 0)
	randIndexes := rand.Perm(len(chosenRegion))
	for i := 0; i < count; i++ {
		chosenZones = append(chosenZones, chosenRegion[randIndexes[i]])
	}
	sort.Strings(chosenZones)
	return chosenZones, nil
}
<commit_msg>Run tests in all regions with increased limits<commit_after>/*
Copyright 2020 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package aws

import (
	"errors"
	"math/rand"
	"sort"
)

var allZones = []string{
	"ap-northeast-1a",
	"ap-northeast-1c",
	"ap-northeast-1d",
	// AZ does not exist, so we're breaking the 3 AZs per region target here
	//"ap-northeast-2b",
	"ap-northeast-2a",
	"ap-northeast-2c",
	"ap-northeast-2d",
	// Disabled until etcd-manager supports the region and the AMIs used in testing are present
	//"ap-northeast-3a",
	//"ap-northeast-3b",
	//"ap-northeast-3c",
	"ap-south-1a",
	"ap-south-1b",
	"ap-south-1c",
	"ap-southeast-1a",
	"ap-southeast-1b",
	"ap-southeast-1c",
	"ap-southeast-2a",
	"ap-southeast-2b",
	"ap-southeast-2c",
	"ca-central-1a",
	"ca-central-1b",
	"ca-central-1d",
	"eu-central-1a",
	"eu-central-1b",
	"eu-central-1c",
	// Disabled until region limits are increased https://github.com/kubernetes/k8s.io/issues/1921
	//"eu-north-1a",
	//"eu-north-1b",
	//"eu-north-1c",
	"eu-west-1a",
	"eu-west-1b",
	"eu-west-1c",
	"eu-west-2a",
	"eu-west-2b",
	"eu-west-2c",
	"eu-west-3a",
	"eu-west-3b",
	"eu-west-3c",
	"sa-east-1a",
	"sa-east-1b",
	"sa-east-1c",
	"us-east-1a",
	"us-east-1b",
	"us-east-1c",
	"us-east-1d",
	"us-east-1e",
	"us-east-1f",
	"us-east-2a",
	"us-east-2b",
	"us-east-2c",
	"us-west-1a",
	"us-west-1b",
	//"us-west-1c", AZ does not exist, so we're breaking the 3 AZs per region target here
	"us-west-2a",
	"us-west-2b",
	"us-west-2c",
	"us-west-2d",
}

// ErrNoEligibleRegion indicates the requested number of zones is not available in any region
var ErrNoEligibleRegion = errors.New("No eligible AWS region found with enough zones")

// RandomZones returns a random set of availability zones within a region
func RandomZones(count int) ([]string, error) {
	regions := make(map[string][]string)
	for _, zone := range allZones {
		region := zone[:len(zone)-1]
		regions[region] = append(regions[region], zone)
	}
	eligibleRegions := make([][]string, 0)
	for _, zones := range regions {
		if len(zones) >= count {
			eligibleRegions = append(eligibleRegions, zones)
		}
	}
	if len(eligibleRegions) == 0 {
		return nil, ErrNoEligibleRegion
	}
	chosenRegion := eligibleRegions[rand.Int()%len(eligibleRegions)]

	chosenZones := make([]string, 0)
	randIndexes := rand.Perm(len(chosenRegion))
	for i := 0; i < count; i++ {
		chosenZones = append(chosenZones, chosenRegion[randIndexes[i]])
	}
	sort.Strings(chosenZones)
	return chosenZones, nil
}
<|endoftext|>


<commit_before>package libpeerpipe

import (
	"fmt"
	"log"
	"math/rand"
	"net"
	"os"
	"strconv"
	"strings"
	"time"
)

type Peerpipe struct {
	Port      int
	peerHash  string
	ListenUDP *net.UDPConn
	ListenTCP *net.TCPListener
}

func New() (*Peerpipe, error) {
	peerpipe := new(Peerpipe)
	peerpipe.listen()
	peerpipe.generateHash(false)
	return peerpipe, nil
}

func (self *Peerpipe) Connect(peerhash string) {
	log.Println("Connecting to", peerhash)
}

func (self *Peerpipe) generateHash(shortHash bool) string {
	peerHash := ""

	externalIP, err := GetExternalIP()
	if err != nil {
		fmt.Println(err)
	} else {
		peerHash = MakeReadable(externalIP.To4())
	}

	addresses, err := net.InterfaceAddrs()
	for _, addr := range addresses {
		// Parse out our IP
		address := strings.Split(addr.String(), "/")
		ip := net.ParseIP(address[0])
		// Skip local and loopbacks
		if !ip.IsGlobalUnicast() {
			continue
		}
		// Convert our IP to a hash
		ip = ip.To4()
		peerHash += MakeReadable(ip)
	}
	self.peerHash = peerHash + IntToChar(self.Port)
	return peerHash
}

func (self *Peerpipe) GetHash() string {
	return self.peerHash
}

func (self *Peerpipe) listen() {
	var err error
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	self.Port = r.Intn(65535 - 1024)
	_, err = net.Listen("tcp", ":"+strconv.Itoa(self.Port))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	log.Println("Ready for connections")
}
<commit_msg>Shifted port properly. Setup address collection for better output once the listening socket is ready.<commit_after>package libpeerpipe

import (
	"fmt"
	"log"
	"math/rand"
	"net"
	"os"
	"strconv"
	"strings"
	"time"
)

type Peerpipe struct {
	Port      int
	peerHash  string
	ListenUDP *net.UDPConn
	ListenTCP *net.TCPListener
	addresses string
}

func New() (*Peerpipe, error) {
	peerpipe := new(Peerpipe)
	peerpipe.listen()
	peerpipe.generateHash(false)
	log.Println("Ready for connections on port", peerpipe.Port, "at", peerpipe.addresses)
	return peerpipe, nil
}

func (self *Peerpipe) Connect(peerhash string) {
	log.Println("Connecting to", peerhash)
}

func (self *Peerpipe) generateHash(shortHash bool) string {
	peerHash := ""

	externalIP, err := GetExternalIP()
	if err != nil {
		fmt.Println(err)
	} else {
		peerHash = MakeReadable(externalIP.To4())
	}

	addresses, err := net.InterfaceAddrs()
	for _, addr := range addresses {
		// Parse out our IP
		address := strings.Split(addr.String(), "/")
		ip := net.ParseIP(address[0])
		// Skip local and loopbacks
		if !ip.IsGlobalUnicast() {
			continue
		}
		self.addresses += address[0] + " "
		// Convert our IP to a hash
		ip = ip.To4()
		peerHash += MakeReadable(ip)
	}
	self.peerHash = peerHash + IntToChar(self.Port)
	return peerHash
}

func (self *Peerpipe) GetHash() string {
	return self.peerHash
}

func (self *Peerpipe) listen() {
	var err error
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	self.Port = r.Intn(65535 - 1024) + 1024
	_, err = net.Listen("tcp", ":"+strconv.Itoa(self.Port))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package integration_test

import (
	. "github.com/bobtfish/AWSnycast/tests/integration"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"testing"
)

var _ = Describe("Integration", func() {
	if testing.Short() {
		Skip("skipping test in short mode.")
	}
	var internalIPs []string
	BeforeEach(func() {
		RunMake()
		RunTerraform()
		internalIPs = InternalIPs()
	})
	Describe("Basic NAT machine tests", func() {
		Context("A availability zone", func() {
			It("should be able to ping 8.8.8.8", func() {
				Ssh("ping -c 2 8.8.8.8", NatA())
			})
		})
		Context("B availability zone", func() {
			It("should be able to ping 8.8.8.8", func() {
				Ssh("ping -c 2 8.8.8.8", NatB())
			})
		})
	})
	Describe("NAT works from inside, both AZs", func() {
		for _, ip := range internalIPs {
			Context(ip, func() {
				It("should be able to ping 8.8.8.8", func() {
					out := Ssh("nc "+ip+" 8732", NatA())
					Ω(out).Should(ContainSubstring("OK"))
				})
			})
		}
	})
})
<commit_msg>Try BeforeAll<commit_after>package integration_test

import (
	. "github.com/bobtfish/AWSnycast/tests/integration"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"testing"
)

var _ = Describe("Integration", func() {
	if testing.Short() {
		Skip("skipping test in short mode.")
	}
	var internalIPs []string
	BeforeAll(func() {
		RunMake()
		RunTerraform()
		internalIPs = InternalIPs()
	})
	Describe("Basic NAT machine tests", func() {
		Context("A availability zone", func() {
			It("should be able to ping 8.8.8.8", func() {
				Ssh("ping -c 2 8.8.8.8", NatA())
			})
		})
		Context("B availability zone", func() {
			It("should be able to ping 8.8.8.8", func() {
				Ssh("ping -c 2 8.8.8.8", NatB())
			})
		})
	})
	Describe("NAT works from inside, both AZs", func() {
		for _, ip := range internalIPs {
			Context(ip, func() {
				It("should be able to ping 8.8.8.8", func() {
					out := Ssh("nc "+ip+" 8732", NatA())
					Ω(out).Should(ContainSubstring("OK"))
				})
			})
		}
	})
})
<|endoftext|>


<commit_before>package server

import (
	"encoding/json"
	"fmt"
	"net/http"
	"path/filepath"

	"github.com/go-zoo/bone"
)

// ContainerInfo stores information about containers
type ContainerInfo struct {
	Pid         int               `json:"pid"`
	Image       string            `json:"image"`
	CreatedTime int64             `json:"created_time"`
	Labels      map[string]string `json:"labels"`
	Annotations map[string]string `json:"annotations"`
	LogPath     string            `json:"log_path"`
	Root        string            `json:"root"`
}

// CrioInfo stores information about the crio daemon
type CrioInfo struct {
	StorageDriver string `json:"storage_driver"`
	StorageRoot   string `json:"storage_root"`
}

// GetInfoMux returns the mux used to serve info requests
func (s *Server) GetInfoMux() *bone.Mux {
	mux := bone.New()

	mux.Get("/info", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		ci := CrioInfo{
			StorageDriver: s.config.Config.Storage,
			StorageRoot:   s.config.Config.Root,
		}
		js, err := json.Marshal(ci)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		w.Write(js)
	}))

	mux.Get("/containers/:id", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		containerID := bone.GetValue(req, "id")
		ctr := s.GetContainer(containerID)
		if ctr == nil {
			http.Error(w, fmt.Sprintf("container with id: %s not found", containerID), http.StatusNotFound)
			return
		}
		ctrState := ctr.State()
		if ctrState == nil {
			http.Error(w, fmt.Sprintf("container %s state is nil", containerID), http.StatusNotFound)
			return
		}

		ci := ContainerInfo{
			Pid:         ctrState.Pid,
			Image:       ctr.Image(),
			CreatedTime: ctrState.Created.UnixNano(),
			Labels:      ctr.Labels(),
			Annotations: ctr.Annotations(),
			Root:        ctr.MountPoint(),
			LogPath:     filepath.Dir(ctr.LogPath()),
		}
		js, err := json.Marshal(ci)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		w.Write(js)
	}))

	return mux
}
<commit_msg>server: Add sandbox to container info<commit_after>package server

import (
	"encoding/json"
	"fmt"
	"net/http"
	"path/filepath"

	"github.com/go-zoo/bone"
)

// ContainerInfo stores information about containers
type ContainerInfo struct {
	Pid         int               `json:"pid"`
	Image       string            `json:"image"`
	CreatedTime int64             `json:"created_time"`
	Labels      map[string]string `json:"labels"`
	Annotations map[string]string `json:"annotations"`
	LogPath     string            `json:"log_path"`
	Root        string            `json:"root"`
	Sandbox     string            `json:"sandbox"`
}

// CrioInfo stores information about the crio daemon
type CrioInfo struct {
	StorageDriver string `json:"storage_driver"`
	StorageRoot   string `json:"storage_root"`
}

// GetInfoMux returns the mux used to serve info requests
func (s *Server) GetInfoMux() *bone.Mux {
	mux := bone.New()

	mux.Get("/info", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		ci := CrioInfo{
			StorageDriver: s.config.Config.Storage,
			StorageRoot:   s.config.Config.Root,
		}
		js, err := json.Marshal(ci)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		w.Write(js)
	}))

	mux.Get("/containers/:id", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		containerID := bone.GetValue(req, "id")
		ctr := s.GetContainer(containerID)
		if ctr == nil {
			http.Error(w, fmt.Sprintf("container with id: %s not found", containerID), http.StatusNotFound)
			return
		}
		ctrState := ctr.State()
		if ctrState == nil {
			http.Error(w, fmt.Sprintf("container %s state is nil", containerID), http.StatusNotFound)
			return
		}

		ci := ContainerInfo{
			Pid:         ctrState.Pid,
			Image:       ctr.Image(),
			CreatedTime: ctrState.Created.UnixNano(),
			Labels:      ctr.Labels(),
			Annotations: ctr.Annotations(),
			Root:        ctr.MountPoint(),
			LogPath:     filepath.Dir(ctr.LogPath()),
			Sandbox:     ctr.Sandbox(),
		}
		js, err := json.Marshal(ci)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		w.Write(js)
	}))

	return mux
}
<|endoftext|>


<commit_before>package rpcclient

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"reflect"
	"strings"

	"github.com/pkg/errors"
	types "github.com/tendermint/tendermint/rpc/lib/types"
	cmn "github.com/tendermint/tmlibs/common"
)

// HTTPClient is a common interface for JSONRPCClient and URIClient.
type HTTPClient interface {
	Call(method string, params map[string]interface{}, result interface{}) (interface{}, error)
}

// TODO: Deprecate support for IP:PORT or /path/to/socket
func makeHTTPDialer(remoteAddr string) (string, func(string, string) (net.Conn, error)) {

	parts := strings.SplitN(remoteAddr, "://", 2)
	var protocol, address string
	if len(parts) != 2 {
		cmn.PanicSanity(fmt.Sprintf("Expected fully formed listening address, including the tcp:// or unix:// prefix, given %s", remoteAddr))
	} else {
		protocol, address = parts[0], parts[1]
	}

	trimmedAddress := strings.Replace(address, "/", ".", -1) // replace / with . for http requests (dummy domain)
	return trimmedAddress, func(proto, addr string) (net.Conn, error) {
		return net.Dial(protocol, address)
	}
}

// We overwrite the http.Client.Dial so we can do http over tcp or unix.
// remoteAddr should be fully featured (eg. with tcp:// or unix://)
func makeHTTPClient(remoteAddr string) (string, *http.Client) {
	address, dialer := makeHTTPDialer(remoteAddr)
	return "http://" + address, &http.Client{
		Transport: &http.Transport{
			Dial: dialer,
		},
	}
}

//------------------------------------------------------------------------------------

// JSON rpc takes params as a slice
type JSONRPCClient struct {
	address string
	client  *http.Client
}

func NewJSONRPCClient(remote string) *JSONRPCClient {
	address, client := makeHTTPClient(remote)
	return &JSONRPCClient{
		address: address,
		client:  client,
	}
}

func (c *JSONRPCClient) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
	request, err := types.MapToRequest("", method, params)
	if err != nil {
		return nil, err
	}
	requestBytes, err := json.Marshal(request)
	if err != nil {
		return nil, err
	}
	// log.Info(string(requestBytes))
	requestBuf := bytes.NewBuffer(requestBytes)
	// log.Info(Fmt("RPC request to %v (%v): %v", c.remote, method, string(requestBytes)))
	httpResponse, err := c.client.Post(c.address, "text/json", requestBuf)
	if err != nil {
		return nil, err
	}
	defer httpResponse.Body.Close()
	responseBytes, err := ioutil.ReadAll(httpResponse.Body)
	if err != nil {
		return nil, err
	}
	// 	log.Info(Fmt("RPC response: %v", string(responseBytes)))
	return unmarshalResponseBytes(responseBytes, result)
}

//-------------------------------------------------------------

// URI takes params as a map
type URIClient struct {
	address string
	client  *http.Client
}

func NewURIClient(remote string) *URIClient {
	address, client := makeHTTPClient(remote)
	return &URIClient{
		address: address,
		client:  client,
	}
}

func (c *URIClient) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
	values, err := argsToURLValues(params)
	if err != nil {
		return nil, err
	}
	// log.Info(Fmt("URI request to %v (%v): %v", c.address, method, values))
	resp, err := c.client.PostForm(c.address+"/"+method, values)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	responseBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return unmarshalResponseBytes(responseBytes, result)
}

//------------------------------------------------

func unmarshalResponseBytes(responseBytes []byte, result interface{}) (interface{}, error) {
	// read response
	// if rpc/core/types is imported, the result will unmarshal
	// into the correct type
	// log.Notice("response", "response", string(responseBytes))
	var err error
	response := &types.RPCResponse{}
	err = json.Unmarshal(responseBytes, response)
	if err != nil {
		return nil, errors.Errorf("Error unmarshalling rpc response: %v", err)
	}
	errorStr := response.Error
	if errorStr != "" {
		return nil, errors.Errorf("Response error: %v", errorStr)
	}
	// unmarshal the RawMessage into the result
	err = json.Unmarshal(*response.Result, result)
	if err != nil {
		return nil, errors.Errorf("Error unmarshalling rpc response result: %v", err)
	}
	return result, nil
}

func argsToURLValues(args map[string]interface{}) (url.Values, error) {
	values := make(url.Values)
	if len(args) == 0 {
		return values, nil
	}
	err := argsToJson(args)
	if err != nil {
		return nil, err
	}
	for key, val := range args {
		values.Set(key, val.(string))
	}
	return values, nil
}

func argsToJson(args map[string]interface{}) error {
	for k, v := range args {
		rt := reflect.TypeOf(v)
		isByteSlice := rt.Kind() == reflect.Slice && rt.Elem().Kind() == reflect.Uint8
		if isByteSlice {
			bytes := reflect.ValueOf(v).Bytes()
			args[k] = fmt.Sprintf("0x%X", bytes)
			continue
		}

		// Pass everything else to go-wire
		data, err := json.Marshal(v)
		if err != nil {
			return err
		}
		args[k] = string(data)
	}
	return nil
}
<commit_msg>httpDialer accepts no prefix or http:// as tcp://<commit_after>package rpcclient

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"reflect"
	"strings"

	"github.com/pkg/errors"
	types "github.com/tendermint/tendermint/rpc/lib/types"
)

// HTTPClient is a common interface for JSONRPCClient and URIClient.
type HTTPClient interface {
	Call(method string, params map[string]interface{}, result interface{}) (interface{}, error)
}

// TODO: Deprecate support for IP:PORT or /path/to/socket
func makeHTTPDialer(remoteAddr string) (string, func(string, string) (net.Conn, error)) {
	parts := strings.SplitN(remoteAddr, "://", 2)
	var protocol, address string
	if len(parts) == 1 {
		// default to tcp if nothing specified
		protocol, address = "tcp", remoteAddr
	} else if len(parts) == 2 {
		protocol, address = parts[0], parts[1]
	} else {
		// return a invalid message
		msg := fmt.Sprintf("Invalid addr: %s", remoteAddr)
		return msg, func(_ string, _ string) (net.Conn, error) {
			return nil, errors.New(msg)
		}
	}
	// accept http as an alias for tcp
	if protocol == "http" {
		protocol = "tcp"
	}

	trimmedAddress := strings.Replace(address, "/", ".", -1) // replace / with . for http requests (dummy domain)
	return trimmedAddress, func(proto, addr string) (net.Conn, error) {
		return net.Dial(protocol, address)
	}
}

// We overwrite the http.Client.Dial so we can do http over tcp or unix.
// remoteAddr should be fully featured (eg. with tcp:// or unix://)
func makeHTTPClient(remoteAddr string) (string, *http.Client) {
	address, dialer := makeHTTPDialer(remoteAddr)
	return "http://" + address, &http.Client{
		Transport: &http.Transport{
			Dial: dialer,
		},
	}
}

//------------------------------------------------------------------------------------

// JSON rpc takes params as a slice
type JSONRPCClient struct {
	address string
	client  *http.Client
}

func NewJSONRPCClient(remote string) *JSONRPCClient {
	address, client := makeHTTPClient(remote)
	return &JSONRPCClient{
		address: address,
		client:  client,
	}
}

func (c *JSONRPCClient) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
	request, err := types.MapToRequest("", method, params)
	if err != nil {
		return nil, err
	}
	requestBytes, err := json.Marshal(request)
	if err != nil {
		return nil, err
	}
	// log.Info(string(requestBytes))
	requestBuf := bytes.NewBuffer(requestBytes)
	// log.Info(Fmt("RPC request to %v (%v): %v", c.remote, method, string(requestBytes)))
	httpResponse, err := c.client.Post(c.address, "text/json", requestBuf)
	if err != nil {
		return nil, err
	}
	defer httpResponse.Body.Close()
	responseBytes, err := ioutil.ReadAll(httpResponse.Body)
	if err != nil {
		return nil, err
	}
	// 	log.Info(Fmt("RPC response: %v", string(responseBytes)))
	return unmarshalResponseBytes(responseBytes, result)
}

//-------------------------------------------------------------

// URI takes params as a map
type URIClient struct {
	address string
	client  *http.Client
}

func NewURIClient(remote string) *URIClient {
	address, client := makeHTTPClient(remote)
	return &URIClient{
		address: address,
		client:  client,
	}
}

func (c *URIClient) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
	values, err := argsToURLValues(params)
	if err != nil {
		return nil, err
	}
	// log.Info(Fmt("URI request to %v (%v): %v", c.address, method, values))
	resp, err := c.client.PostForm(c.address+"/"+method, values)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	responseBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return unmarshalResponseBytes(responseBytes, result)
}

//------------------------------------------------

func unmarshalResponseBytes(responseBytes []byte, result interface{}) (interface{}, error) {
	// read response
	// if rpc/core/types is imported, the result will unmarshal
	// into the correct type
	// log.Notice("response", "response", string(responseBytes))
	var err error
	response := &types.RPCResponse{}
	err = json.Unmarshal(responseBytes, response)
	if err != nil {
		return nil, errors.Errorf("Error unmarshalling rpc response: %v", err)
	}
	errorStr := response.Error
	if errorStr != "" {
		return nil, errors.Errorf("Response error: %v", errorStr)
	}
	// unmarshal the RawMessage into the result
	err = json.Unmarshal(*response.Result, result)
	if err != nil {
		return nil, errors.Errorf("Error unmarshalling rpc response result: %v", err)
	}
	return result, nil
}

func argsToURLValues(args map[string]interface{}) (url.Values, error) {
	values := make(url.Values)
	if len(args) == 0 {
		return values, nil
	}
	err := argsToJson(args)
	if err != nil {
		return nil, err
	}
	for key, val := range args {
		values.Set(key, val.(string))
	}
	return values, nil
}

func argsToJson(args map[string]interface{}) error {
	for k, v := range args {
		rt := reflect.TypeOf(v)
		isByteSlice := rt.Kind() == reflect.Slice && rt.Elem().Kind() == reflect.Uint8
		if isByteSlice {
			bytes := reflect.ValueOf(v).Bytes()
			args[k] = fmt.Sprintf("0x%X", bytes)
			continue
		}

		// Pass everything else to go-wire
		data, err := json.Marshal(v)
		if err != nil {
			return err
		}
		args[k] = string(data)
	}
	return nil
}
<|endoftext|>


<commit_before>package test

var defaultConfig = `# Copyright 2015, 2016 Eris Industries (UK) Ltd.
# This file is part of Eris-RT
#
# Eris-RT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Eris-RT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.

# This is a TOML configuration for Eris-DB chains

[chain]

# ChainId is a human-readable name to identify the chain.
# This must correspond to the chain_id defined in the genesis file
# and the assertion here provides a safe-guard on misconfiguring chains.
assert_chain_id = "MyChainId"
# semantic major and minor version
major_version = 0
minor_version = 12
# genesis file, relative path is to eris-db working directory
genesis_file = "genesis.json"

###############################################################################
##
##  consensus
##
###############################################################################

  [chain.consensus]
  # consensus defines the module to use for consensus and
  # this will define the peer-to-peer consensus network;
  # accepted values are "noops", "tmsp", "tendermint"
  name = "tendermint"
  # version is the major and minor semantic version;
  # the version will be asserted on
  major_version = 0
  minor_version = 6
  # relative path to consensus' module root folder
  relative_root = "tendermint"

###############################################################################
##
##  application manager
##
###############################################################################

  [chain.manager]
  # application manager name defines the module to use for handling
  name = "erismint"
  # version is the major and minor semantic version;
  # the version will be asserted on
  major_version = 0
  minor_version = 12
  # relative path to application manager root folder
  relative_root = "erismint"

################################################################################
################################################################################
##
## Server configurations
##
################################################################################
################################################################################

[servers]

  [servers.bind]
  address = ""
  port = 1337

  [servers.tls]
  tls = false
  cert_path = ""
  key_path = ""

  [servers.cors]
  enable = false
  allow_origins = []
  allow_credentials = false
  allow_methods = []
  allow_headers = []
  expose_headers = []
  max_age = 0

  [servers.http]
  json_rpc_endpoint = "/rpc"

  [servers.websocket]
  endpoint = "/socketrpc"
  max_sessions = 50
  read_buffer_size = 4096
  write_buffer_size = 4096

	[servers.tendermint]
	# Multiple listeners can be separated with a comma
	rpc_local_address = "0.0.0.0:36657"
	endpoint = "/websocket"

  [servers.logging]
  console_log_level = "info"
  file_log_level = "warn"
  log_file = ""

################################################################################
################################################################################
##
## Module configurations - dynamically loaded based on chain configuration
##
################################################################################
################################################################################

################################################################################
##
## Tendermint Socket Protocol (TMSP)
## version 0.6.0
##
## TMSP expects a tendermint consensus process to run and connect to Eris-DB
##
################################################################################

[tmsp]
# listener address for accepting tendermint socket protocol connections
listener = "tcp://0.0.0.0:46658"

################################################################################
##
## Tendermint
## version 0.6.0
##
## in-process execution of Tendermint consensus engine
##
################################################################################

[tendermint]
# private validator file is used by tendermint to keep the status
# of the private validator, but also (currently) holds the private key
# for the private vaildator to sign with.  This private key needs to be moved
# out and directly managed by eris-keys
# This file needs to be in the root directory
private_validator_file = "priv_validator.json"

  # Tendermint requires additional configuration parameters.
  # Eris-DB's tendermint consensus module will load [tendermint.configuration]
  # as the configuration for Tendermint.
  # Eris-DB will respect the configurations set in this file where applicable,
  # but reserves the option to override or block conflicting settings.
  [tendermint.configuration]
  # moniker is the name of the node on the tendermint p2p network
  moniker = "anonymous_marmot"
  # seeds lists the peers tendermint can connect to join the network
  seeds = ""
  # fast_sync allows a tendermint node to catch up faster when joining
  # the network.
  # NOTE: Tendermint has reported potential issues with fast_sync enabled.
  # The recommended setting is for keeping it disabled.
  fast_sync = false
  db_backend = "leveldb"
  log_level = "info"
  # node local address
  node_laddr = "0.0.0.0:46656"
  # rpc local address
	# NOTE: value is ignored when run in-process as RPC is
	# handled by [servers.tendermint]
  rpc_laddr = ""
  # proxy application address - used for tmsp connections,
  # and this port should not be exposed for in-process Tendermint
  proxy_app = "tcp://127.0.0.1:46658"

  # Extended Tendermint configuration settings
  # for reference to Tendermint see https://github.com/tendermint/tendermint/blob/master/config/tendermint/config.go

  # genesis_file = "./data/tendermint/genesis.json"
  # skip_upnp = false
  # addrbook_file = "./data/tendermint/addrbook.json"
  # priv_validator_file = "./data/tendermint/priv_validator.json"
  # db_dir = "./data/tendermint/data"
  # prof_laddr = ""
  # revision_file = "./data/tendermint/revision"
  # cswal = "./data/tendermint/data/cswal"
  # cswal_light = false

  # block_size = 10000
  # disable_data_hash = false
  # timeout_propose = 3000
  # timeout_propose_delta = 500
  # timeout_prevote = 1000
  # timeout_prevote_delta = 500
  # timeout_precommit = 1000
  # timeout_precommit_delta = 500
  # timeout_commit = 1000
  # mempool_recheck = true
  # mempool_recheck_empty = true
  # mempool_broadcast = true

################################################################################
##
## Eris-Mint
## version 0.12.0
##
## The original Ethereum virtual machine with IAVL merkle trees
## and tendermint/go-wire encoding
##
################################################################################

[erismint]
# Database backend to use for ErisMint state database.
db_backend = "leveldb"
`
<commit_msg>rpc/tendermint: config file has explicit copy, manually update version<commit_after>package test

var defaultConfig = `# Copyright 2015, 2016 Eris Industries (UK) Ltd.
# This file is part of Eris-RT
#
# Eris-RT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Eris-RT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.

# This is a TOML configuration for Eris-DB chains

[chain]

# ChainId is a human-readable name to identify the chain.
# This must correspond to the chain_id defined in the genesis file
# and the assertion here provides a safe-guard on misconfiguring chains.
assert_chain_id = "MyChainId"
# semantic major and minor version
major_version = 0
minor_version = 12
# genesis file, relative path is to eris-db working directory
genesis_file = "genesis.json"

###############################################################################
##
##  consensus
##
###############################################################################

  [chain.consensus]
  # consensus defines the module to use for consensus and
  # this will define the peer-to-peer consensus network;
  # accepted values are "noops", "tmsp", "tendermint"
  name = "tendermint"
  # version is the major and minor semantic version;
  # the version will be asserted on
  major_version = 0
  minor_version = 6
  # relative path to consensus' module root folder
  relative_root = "tendermint"

###############################################################################
##
##  application manager
##
###############################################################################

  [chain.manager]
  # application manager name defines the module to use for handling
  name = "erismint"
  # version is the major and minor semantic version;
  # the version will be asserted on
  major_version = 0
  minor_version = 16
  # relative path to application manager root folder
  relative_root = "erismint"

################################################################################
################################################################################
##
## Server configurations
##
################################################################################
################################################################################

[servers]

  [servers.bind]
  address = ""
  port = 1337

  [servers.tls]
  tls = false
  cert_path = ""
  key_path = ""

  [servers.cors]
  enable = false
  allow_origins = []
  allow_credentials = false
  allow_methods = []
  allow_headers = []
  expose_headers = []
  max_age = 0

  [servers.http]
  json_rpc_endpoint = "/rpc"

  [servers.websocket]
  endpoint = "/socketrpc"
  max_sessions = 50
  read_buffer_size = 4096
  write_buffer_size = 4096

	[servers.tendermint]
	# Multiple listeners can be separated with a comma
	rpc_local_address = "0.0.0.0:36657"
	endpoint = "/websocket"

  [servers.logging]
  console_log_level = "info"
  file_log_level = "warn"
  log_file = ""

################################################################################
################################################################################
##
## Module configurations - dynamically loaded based on chain configuration
##
################################################################################
################################################################################

################################################################################
##
## Tendermint Socket Protocol (TMSP)
## version 0.6.0
##
## TMSP expects a tendermint consensus process to run and connect to Eris-DB
##
################################################################################

[tmsp]
# listener address for accepting tendermint socket protocol connections
listener = "tcp://0.0.0.0:46658"

################################################################################
##
## Tendermint
## version 0.6.0
##
## in-process execution of Tendermint consensus engine
##
################################################################################

[tendermint]
# private validator file is used by tendermint to keep the status
# of the private validator, but also (currently) holds the private key
# for the private vaildator to sign with.  This private key needs to be moved
# out and directly managed by eris-keys
# This file needs to be in the root directory
private_validator_file = "priv_validator.json"

  # Tendermint requires additional configuration parameters.
  # Eris-DB's tendermint consensus module will load [tendermint.configuration]
  # as the configuration for Tendermint.
  # Eris-DB will respect the configurations set in this file where applicable,
  # but reserves the option to override or block conflicting settings.
  [tendermint.configuration]
  # moniker is the name of the node on the tendermint p2p network
  moniker = "anonymous_marmot"
  # seeds lists the peers tendermint can connect to join the network
  seeds = ""
  # fast_sync allows a tendermint node to catch up faster when joining
  # the network.
  # NOTE: Tendermint has reported potential issues with fast_sync enabled.
  # The recommended setting is for keeping it disabled.
  fast_sync = false
  db_backend = "leveldb"
  log_level = "info"
  # node local address
  node_laddr = "0.0.0.0:46656"
  # rpc local address
	# NOTE: value is ignored when run in-process as RPC is
	# handled by [servers.tendermint]
  rpc_laddr = ""
  # proxy application address - used for tmsp connections,
  # and this port should not be exposed for in-process Tendermint
  proxy_app = "tcp://127.0.0.1:46658"

  # Extended Tendermint configuration settings
  # for reference to Tendermint see https://github.com/tendermint/tendermint/blob/master/config/tendermint/config.go

  # genesis_file = "./data/tendermint/genesis.json"
  # skip_upnp = false
  # addrbook_file = "./data/tendermint/addrbook.json"
  # priv_validator_file = "./data/tendermint/priv_validator.json"
  # db_dir = "./data/tendermint/data"
  # prof_laddr = ""
  # revision_file = "./data/tendermint/revision"
  # cswal = "./data/tendermint/data/cswal"
  # cswal_light = false

  # block_size = 10000
  # disable_data_hash = false
  # timeout_propose = 3000
  # timeout_propose_delta = 500
  # timeout_prevote = 1000
  # timeout_prevote_delta = 500
  # timeout_precommit = 1000
  # timeout_precommit_delta = 500
  # timeout_commit = 1000
  # mempool_recheck = true
  # mempool_recheck_empty = true
  # mempool_broadcast = true

################################################################################
##
## Eris-Mint
## version 0.12.0
##
## The original Ethereum virtual machine with IAVL merkle trees
## and tendermint/go-wire encoding
##
################################################################################

[erismint]
# Database backend to use for ErisMint state database.
db_backend = "leveldb"
`
<|endoftext|>


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

package oto

import (
	"fmt"
	"reflect"
	"runtime"
	"unsafe"

	"golang.org/x/sys/windows"
)

type comThread struct {
	funcCh chan func()
}

func newCOMThread() (*comThread, error) {
	funcCh := make(chan func())
	errCh := make(chan error)
	go func() {
		runtime.LockOSThread()
		defer runtime.UnlockOSThread()

		if err := _CoInitializeEx(nil, _COINIT_MULTITHREADED); err != nil {
			errCh <- err
		}
		defer _CoUninitialize()

		close(errCh)

		for f := range funcCh {
			f()
		}
	}()

	if err := <-errCh; err != nil {
		return nil, err
	}

	return &comThread{
		funcCh: funcCh,
	}, nil
}

func (c *comThread) Run(f func()) {
	ch := make(chan struct{})
	c.funcCh <- func() {
		f()
		close(ch)
	}
	<-ch
}

type wasapiContext struct {
	sampleRate   int
	channelCount int
	players      *players

	comThread *comThread
	err       atomicError

	sampleReadyEvent windows.Handle
	client           *_IAudioClient2
	mixFormat        *_WAVEFORMATEXTENSIBLE
	bufferFrames     uint32
	renderClient     *_IAudioRenderClient
}

func newWASAPIContext(sampleRate, channelCount int, players *players) (*wasapiContext, chan struct{}, error) {
	t, err := newCOMThread()
	if err != nil {
		return nil, nil, err
	}

	c := &wasapiContext{
		sampleRate:   sampleRate,
		channelCount: channelCount,
		players:      players,
		comThread:    t,
	}

	var cerr error
	t.Run(func() {
		if err := c.initOnCOMThread(); err != nil {
			cerr = err
			return
		}
	})
	if cerr != nil {
		return nil, nil, cerr
	}

	ready := make(chan struct{})
	close(ready)

	return c, ready, nil
}

func (c *wasapiContext) initOnCOMThread() error {
	e, err := _CoCreateInstance(&uuidMMDeviceEnumerator, nil, uint32(_CLSCTX_ALL), &uuidIMMDeviceEnumerator)
	if err != nil {
		return err
	}
	enumerator := (*_IMMDeviceEnumerator)(e)
	defer enumerator.Release()

	device, err := enumerator.GetDefaultAudioEndPoint(eRender, eConsole)
	if err != nil {
		return err
	}
	defer device.Release()

	client, err := device.Activate(&uuidIAudioClient2, uint32(_CLSCTX_ALL), nil)
	if err != nil {
		return err
	}
	c.client = (*_IAudioClient2)(client)

	if err := c.client.SetClientProperties(&_AudioClientProperties{
		cbSize:     uint32(unsafe.Sizeof(_AudioClientProperties{})),
		bIsOffload: 0,                    // false
		eCategory:  _AudioCategory_Other, // In the example, AudioCategory_ForegroundOnlyMedia was used, but this value is deprecated.
	}); err != nil {
		return err
	}

	// Check the format is supported by WASAPI.
	// Stereo with 48000 [Hz] is likely supported, but mono and/or other sample rates are unlikely supported.
	// Fallback to WinMM in this case anyway.
	const bitsPerSample = 32
	nBlockAlign := c.channelCount * bitsPerSample / 8
	var channelMask uint32
	switch c.channelCount {
	case 1:
		channelMask = _SPEAKER_FRONT_CENTER
	case 2:
		channelMask = _SPEAKER_FRONT_LEFT | _SPEAKER_FRONT_RIGHT
	}
	f := &_WAVEFORMATEXTENSIBLE{
		wFormatTag:      _WAVE_FORMAT_EXTENSIBLE,
		nChannels:       uint16(c.channelCount),
		nSamplesPerSec:  uint32(c.sampleRate),
		nAvgBytesPerSec: uint32(c.sampleRate * nBlockAlign),
		nBlockAlign:     uint16(nBlockAlign),
		wBitsPerSample:  bitsPerSample,
		cbSize:          0x16,
		Samples:         bitsPerSample,
		dwChannelMask:   channelMask,
		SubFormat:       _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT,
	}
	closest, err := c.client.IsFormatSupported(_AUDCLNT_SHAREMODE_SHARED, f)
	if err != nil {
		return err
	}
	if closest != nil {
		return fmt.Errorf("oto: the specified format is not supported (there is the closest format instead)")
	}
	c.mixFormat = f

	if err := c.client.Initialize(_AUDCLNT_SHAREMODE_SHARED,
		_AUDCLNT_STREAMFLAGS_EVENTCALLBACK|_AUDCLNT_STREAMFLAGS_NOPERSIST,
		0, 0, c.mixFormat, nil); err != nil {
		return err
	}

	frames, err := c.client.GetBufferSize()
	if err != nil {
		return err
	}
	c.bufferFrames = frames

	renderClient, err := c.client.GetService(&uuidIAudioRenderClient)
	if err != nil {
		return err
	}
	c.renderClient = (*_IAudioRenderClient)(renderClient)

	ev, err := windows.CreateEventEx(nil, nil, 0, windows.EVENT_ALL_ACCESS)
	if err != nil {
		return err
	}
	c.sampleReadyEvent = ev

	if err := c.client.SetEventHandle(c.sampleReadyEvent); err != nil {
		return err
	}

	// TODO: Should some errors be allowed? See WASAPIManager.cpp in the official example SimpleWASAPIPlaySound.

	if err := c.client.Start(); err != nil {
		return err
	}

	go func() {
		runtime.LockOSThread()
		defer runtime.UnlockOSThread()

		if err := _CoInitializeEx(nil, _COINIT_MULTITHREADED); err != nil {
			c.client.Stop()
			c.err.TryStore(err)
			return
		}
		defer _CoUninitialize()

		if err := c.loopOnRenderThread(); err != nil {
			c.client.Stop()
			c.err.TryStore(err)
			return
		}
	}()

	return nil
}

func (c *wasapiContext) loopOnRenderThread() error {
	var buf []float32
	for {
		evt, err := windows.WaitForSingleObject(c.sampleReadyEvent, 2000)
		if err != nil {
			return err
		}
		if evt != windows.WAIT_OBJECT_0 {
			return fmt.Errorf("oto: WaitForSingleObject failed: returned value: %d", evt)
		}

		paddingFrames, err := c.client.GetCurrentPadding()
		if err != nil {
			return err
		}

		frames := c.bufferFrames - paddingFrames
		if frames <= 0 {
			continue
		}

		// Get the destination buffer.
		dstBuf, err := c.renderClient.GetBuffer(frames)
		if err != nil {
			return err
		}

		// Calculate the buffer size.
		buflen := int(frames) * c.channelCount
		if cap(buf) < buflen {
			buf = make([]float32, buflen)
		} else {
			buf = buf[:buflen]
		}

		// Read the buffer from the players.
		c.players.read(buf)

		// Copy the read buf to the destination buffer.
		var dst []float32
		h := (*reflect.SliceHeader)(unsafe.Pointer(&dst))
		h.Data = uintptr(unsafe.Pointer(dstBuf))
		h.Len = buflen
		h.Cap = buflen
		copy(dst, buf)

		// Release the buffer.
		if err := c.renderClient.ReleaseBuffer(frames, 0); err != nil {
			return err
		}

		buf = buf[:0]
	}
}

func (c *wasapiContext) Suspend() error {
	return nil
}

func (c *wasapiContext) Resume() error {
	return nil
}

func (c *wasapiContext) Err() error {
	return c.err.Load()
}
<commit_msg>wasapi: implement Suspend and Resume<commit_after>// Copyright 2022 The Oto Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package oto

import (
	"fmt"
	"reflect"
	"runtime"
	"unsafe"

	"golang.org/x/sys/windows"
)

type comThread struct {
	funcCh chan func()
}

func newCOMThread() (*comThread, error) {
	funcCh := make(chan func())
	errCh := make(chan error)
	go func() {
		runtime.LockOSThread()
		defer runtime.UnlockOSThread()

		if err := _CoInitializeEx(nil, _COINIT_MULTITHREADED); err != nil {
			errCh <- err
		}
		defer _CoUninitialize()

		close(errCh)

		for f := range funcCh {
			f()
		}
	}()

	if err := <-errCh; err != nil {
		return nil, err
	}

	return &comThread{
		funcCh: funcCh,
	}, nil
}

func (c *comThread) Run(f func()) {
	ch := make(chan struct{})
	c.funcCh <- func() {
		f()
		close(ch)
	}
	<-ch
}

type wasapiContext struct {
	sampleRate   int
	channelCount int
	players      *players

	comThread *comThread
	err       atomicError

	sampleReadyEvent windows.Handle
	client           *_IAudioClient2
	mixFormat        *_WAVEFORMATEXTENSIBLE
	bufferFrames     uint32
	renderClient     *_IAudioRenderClient
}

func newWASAPIContext(sampleRate, channelCount int, players *players) (*wasapiContext, chan struct{}, error) {
	t, err := newCOMThread()
	if err != nil {
		return nil, nil, err
	}

	c := &wasapiContext{
		sampleRate:   sampleRate,
		channelCount: channelCount,
		players:      players,
		comThread:    t,
	}

	var cerr error
	t.Run(func() {
		if err := c.initOnCOMThread(); err != nil {
			cerr = err
			return
		}
	})
	if cerr != nil {
		return nil, nil, cerr
	}

	ready := make(chan struct{})
	close(ready)

	return c, ready, nil
}

func (c *wasapiContext) initOnCOMThread() error {
	e, err := _CoCreateInstance(&uuidMMDeviceEnumerator, nil, uint32(_CLSCTX_ALL), &uuidIMMDeviceEnumerator)
	if err != nil {
		return err
	}
	enumerator := (*_IMMDeviceEnumerator)(e)
	defer enumerator.Release()

	device, err := enumerator.GetDefaultAudioEndPoint(eRender, eConsole)
	if err != nil {
		return err
	}
	defer device.Release()

	client, err := device.Activate(&uuidIAudioClient2, uint32(_CLSCTX_ALL), nil)
	if err != nil {
		return err
	}
	c.client = (*_IAudioClient2)(client)

	if err := c.client.SetClientProperties(&_AudioClientProperties{
		cbSize:     uint32(unsafe.Sizeof(_AudioClientProperties{})),
		bIsOffload: 0,                    // false
		eCategory:  _AudioCategory_Other, // In the example, AudioCategory_ForegroundOnlyMedia was used, but this value is deprecated.
	}); err != nil {
		return err
	}

	// Check the format is supported by WASAPI.
	// Stereo with 48000 [Hz] is likely supported, but mono and/or other sample rates are unlikely supported.
	// Fallback to WinMM in this case anyway.
	const bitsPerSample = 32
	nBlockAlign := c.channelCount * bitsPerSample / 8
	var channelMask uint32
	switch c.channelCount {
	case 1:
		channelMask = _SPEAKER_FRONT_CENTER
	case 2:
		channelMask = _SPEAKER_FRONT_LEFT | _SPEAKER_FRONT_RIGHT
	}
	f := &_WAVEFORMATEXTENSIBLE{
		wFormatTag:      _WAVE_FORMAT_EXTENSIBLE,
		nChannels:       uint16(c.channelCount),
		nSamplesPerSec:  uint32(c.sampleRate),
		nAvgBytesPerSec: uint32(c.sampleRate * nBlockAlign),
		nBlockAlign:     uint16(nBlockAlign),
		wBitsPerSample:  bitsPerSample,
		cbSize:          0x16,
		Samples:         bitsPerSample,
		dwChannelMask:   channelMask,
		SubFormat:       _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT,
	}
	closest, err := c.client.IsFormatSupported(_AUDCLNT_SHAREMODE_SHARED, f)
	if err != nil {
		return err
	}
	if closest != nil {
		return fmt.Errorf("oto: the specified format is not supported (there is the closest format instead)")
	}
	c.mixFormat = f

	if err := c.client.Initialize(_AUDCLNT_SHAREMODE_SHARED,
		_AUDCLNT_STREAMFLAGS_EVENTCALLBACK|_AUDCLNT_STREAMFLAGS_NOPERSIST,
		0, 0, c.mixFormat, nil); err != nil {
		return err
	}

	frames, err := c.client.GetBufferSize()
	if err != nil {
		return err
	}
	c.bufferFrames = frames

	renderClient, err := c.client.GetService(&uuidIAudioRenderClient)
	if err != nil {
		return err
	}
	c.renderClient = (*_IAudioRenderClient)(renderClient)

	ev, err := windows.CreateEventEx(nil, nil, 0, windows.EVENT_ALL_ACCESS)
	if err != nil {
		return err
	}
	c.sampleReadyEvent = ev

	if err := c.client.SetEventHandle(c.sampleReadyEvent); err != nil {
		return err
	}

	// TODO: Should some errors be allowed? See WASAPIManager.cpp in the official example SimpleWASAPIPlaySound.

	if err := c.client.Start(); err != nil {
		return err
	}

	go func() {
		runtime.LockOSThread()
		defer runtime.UnlockOSThread()

		if err := _CoInitializeEx(nil, _COINIT_MULTITHREADED); err != nil {
			c.client.Stop()
			c.err.TryStore(err)
			return
		}
		defer _CoUninitialize()

		if err := c.loopOnRenderThread(); err != nil {
			c.client.Stop()
			c.err.TryStore(err)
			return
		}
	}()

	return nil
}

func (c *wasapiContext) loopOnRenderThread() error {
	var buf []float32
	for {
		evt, err := windows.WaitForSingleObject(c.sampleReadyEvent, 2000)
		if err != nil {
			return err
		}
		if evt != windows.WAIT_OBJECT_0 {
			return fmt.Errorf("oto: WaitForSingleObject failed: returned value: %d", evt)
		}

		paddingFrames, err := c.client.GetCurrentPadding()
		if err != nil {
			return err
		}

		frames := c.bufferFrames - paddingFrames
		if frames <= 0 {
			continue
		}

		// Get the destination buffer.
		dstBuf, err := c.renderClient.GetBuffer(frames)
		if err != nil {
			return err
		}

		// Calculate the buffer size.
		buflen := int(frames) * c.channelCount
		if cap(buf) < buflen {
			buf = make([]float32, buflen)
		} else {
			buf = buf[:buflen]
		}

		// Read the buffer from the players.
		c.players.read(buf)

		// Copy the read buf to the destination buffer.
		var dst []float32
		h := (*reflect.SliceHeader)(unsafe.Pointer(&dst))
		h.Data = uintptr(unsafe.Pointer(dstBuf))
		h.Len = buflen
		h.Cap = buflen
		copy(dst, buf)

		// Release the buffer.
		if err := c.renderClient.ReleaseBuffer(frames, 0); err != nil {
			return err
		}

		buf = buf[:0]
	}
}

func (c *wasapiContext) Suspend() error {
	if err := c.client.Stop(); err != nil {
		return err
	}
	return nil
}

func (c *wasapiContext) Resume() error {
	if err := c.client.Start(); err != nil {
		return err
	}
	return nil
}

func (c *wasapiContext) Err() error {
	return c.err.Load()
}
<|endoftext|>


<commit_before>// Copyright ©2012 The bíogo.bam 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 bgzf

import (
	"errors"
	"os"
)

const (
	BlockSize    = 0x0ff00 // Size of input data block.
	MaxBlockSize = 0x10000 // Maximum size of output block.
)

const (
	bgzfExtra = "BC\x02\x00\x00\x00"
	minFrame  = 20 + len(bgzfExtra) // Minimum bgzf header+footer length.

	// Magic EOF block.
	magicBlock = "\x1f\x8b\x08\x04\x00\x00\x00\x00\x00\xff\x06\x00\x42\x43\x02\x00\x1b\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00"
)

var bgzfExtraPrefix = []byte(bgzfExtra[:4])

func compressBound(srcLen int) int {
	return srcLen + srcLen>>12 + srcLen>>14 + srcLen>>25 + 13 + minFrame
}

func init() {
	if compressBound(BlockSize) > MaxBlockSize {
		panic("bam: BlockSize too large")
	}
}

var (
	ErrClosed            = errors.New("bgzf: use of closed writer")
	ErrBlockOverflow     = errors.New("bgzf: block overflow")
	ErrWrongFileType     = errors.New("bgzf: file is a directory")
	ErrNotASeeker        = errors.New("bgzf: not a seeker")
	ErrNoBlockSize       = errors.New("bgzf: could not determine block size")
	ErrBlockSizeMismatch = errors.New("bgzf: unexpected block size")
)

func CheckEOF(f *os.File) (bool, error) {
	fi, err := f.Stat()
	if err != nil || fi.IsDir() {
		return false, ErrWrongFileType
	}

	b := make([]byte, len(magicBlock))
	_, err = f.ReadAt(b, fi.Size()-int64(len(magicBlock)))
	if err != nil {
		return false, err
	}
	for i := range b {
		if b[i] != magicBlock[i] {
			return false, nil
		}
	}
	return true, nil
}
<commit_msg>Properly differentiate Stat errors<commit_after>// Copyright ©2012 The bíogo.bam 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 bgzf

import (
	"errors"
	"os"
)

const (
	BlockSize    = 0x0ff00 // Size of input data block.
	MaxBlockSize = 0x10000 // Maximum size of output block.
)

const (
	bgzfExtra = "BC\x02\x00\x00\x00"
	minFrame  = 20 + len(bgzfExtra) // Minimum bgzf header+footer length.

	// Magic EOF block.
	magicBlock = "\x1f\x8b\x08\x04\x00\x00\x00\x00\x00\xff\x06\x00\x42\x43\x02\x00\x1b\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00"
)

var bgzfExtraPrefix = []byte(bgzfExtra[:4])

func compressBound(srcLen int) int {
	return srcLen + srcLen>>12 + srcLen>>14 + srcLen>>25 + 13 + minFrame
}

func init() {
	if compressBound(BlockSize) > MaxBlockSize {
		panic("bam: BlockSize too large")
	}
}

var (
	ErrClosed            = errors.New("bgzf: use of closed writer")
	ErrBlockOverflow     = errors.New("bgzf: block overflow")
	ErrWrongFileType     = errors.New("bgzf: file is a directory")
	ErrNotASeeker        = errors.New("bgzf: not a seeker")
	ErrNoBlockSize       = errors.New("bgzf: could not determine block size")
	ErrBlockSizeMismatch = errors.New("bgzf: unexpected block size")
)

func CheckEOF(f *os.File) (bool, error) {
	fi, err := f.Stat()
	if err != nil {
		return false, err
	}
	if fi.IsDir() {
		return false, ErrWrongFileType
	}

	b := make([]byte, len(magicBlock))
	_, err = f.ReadAt(b, fi.Size()-int64(len(magicBlock)))
	if err != nil {
		return false, err
	}
	for i := range b {
		if b[i] != magicBlock[i] {
			return false, nil
		}
	}
	return true, nil
}
<|endoftext|>


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

// Package main is the vflow IPFIX consumer for the ClickHouse database (https://clickhouse.yandex)
package main

import (
	"database/sql"
	"encoding/json"
	"flag"
	"log"
	"sync"
	"time"

	cluster "github.com/bsm/sarama-cluster"
	"github.com/kshvakov/clickhouse"
)

type options struct {
	Broker  string
	Topic   string
	Id      int
	Value   string
	Debug   bool
	Workers int
}

type dataField struct {
	I int
	V interface{}
}

type ipfix struct {
	AgentID  string
	DataSets [][]dataField
}

type dIPFIXSample struct {
	device string
	src    string
	dst    string
	srcASN uint64
	dstASN uint64
	proto  uint8
}

var opts options

func init() {
	flag.StringVar(&opts.Broker, "broker", "127.0.0.1:9092", "broker ipaddress:port")
	flag.StringVar(&opts.Topic, "topic", "vflow.ipfix", "kafka topic")
	flag.StringVar(&opts.Value, "value", "8.8.8.8", "element value - string")
	flag.BoolVar(&opts.Debug, "debug", false, "enabled/disabled debug")
	flag.IntVar(&opts.Id, "id", 12, "IPFIX element ID")
	flag.IntVar(&opts.Workers, "workers", 16, "workers number / partition number")

	flag.Parse()
}

func main() {
	var (
		wg sync.WaitGroup
		ch = make(chan []byte, 1000)
	)

	config := cluster.NewConfig()
	config.Consumer.Return.Errors = true
	config.Group.Return.Notifications = true

	go ingestClickHouse(ch)

	wg.Add(opts.Workers)

	for i := 0; i < opts.Workers; i++ {
		go func(ti int) {
			brokers := []string{opts.Broker}
			topics := []string{opts.Topic}
			consumer, err := cluster.NewConsumer(brokers, "mygroup", topics, config)

			if err != nil {
				panic(err)
			}
			defer consumer.Close()

			pCount := 0
			count := 0
			tik := time.Tick(10 * time.Second)

			for {
				select {
				case <-tik:
					if opts.Debug {
						log.Printf("partition GroupId#%d,  rate=%d\n", ti, (count-pCount)/10)
					}
					pCount = count
				case msg, more := <-consumer.Messages():
					if more {
						ch <- msg.Value
						consumer.MarkOffset(msg, "")
						count++
					}
				}
			}
		}(i)
	}

	wg.Wait()
}

func ingestClickHouse(ch chan []byte) {
	var objmap ipfix

	connect, err := sql.Open("clickhouse", "tcp://127.0.0.1:9000?debug=false")
	if err != nil {
		log.Fatal(err)
	}
	if err := connect.Ping(); err != nil {
		if exception, ok := err.(*clickhouse.Exception); ok {
			log.Printf("[%d] %s \n%s\n", exception.Code, exception.Message, exception.StackTrace)
		} else {
			log.Println(err)
		}
		return
	}

	_, err = connect.Exec(`use vflow`)
	if err != nil {
		log.Fatal(err)
	}

	for {
		tx, _ := connect.Begin()
		stmt, _ := tx.Prepare("INSERT INTO samples (date,time,device,src,dst,srcASN,dstASN, proto) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
		for i := 0; i < 1000; i++ {

			sample := <-ch
			if err := json.Unmarshal(sample, &objmap); err != nil {
				log.Println(err)
			}

			for _, data := range objmap.DataSets {

				s := dIPFIXSample{}
				for _, dd := range data {
					switch dd.I {
					case 8, 27:
						s.src = dd.V.(string)
					case 12, 28:
						s.dst = dd.V.(string)
					case 16:
						s.srcASN = uint64(dd.V.(float64))
					case 17:
						s.dstASN = uint64(dd.V.(float64))
					case 4:
						s.proto = uint8(dd.V.(float64))
					}
				}
				if _, err := stmt.Exec(
					time.Now(),
					time.Now(),
					objmap.AgentID,
					s.src,
					s.dst,
					s.srcASN,
					s.dstASN,
					s.proto,
				); err != nil {
					log.Fatal(err)
				}

			}
		}

		if err := tx.Commit(); err != nil {
			log.Fatal(err)
		}
	}
}
<commit_msg>multi ingest, removed use vflow<commit_after>//: ----------------------------------------------------------------------------
//: Copyright (C) 2017 Verizon.  All Rights Reserved.
//: All Rights Reserved
//:
//: file:    main.go
//: details: TODO
//: author:  Mehrdad Arshad Rad
//: date:    06/01/2017
//:
//: Licensed under the Apache License, Version 2.0 (the "License");
//: you may not use this file except in compliance with the License.
//: You may obtain a copy of the License at
//:
//:     http://www.apache.org/licenses/LICENSE-2.0
//:
//: Unless required by applicable law or agreed to in writing, software
//: distributed under the License is distributed on an "AS IS" BASIS,
//: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//: See the License for the specific language governing permissions and
//: limitations under the License.
//: ----------------------------------------------------------------------------

// Package main is the vflow IPFIX consumer for the ClickHouse database (https://clickhouse.yandex)
package main

import (
	"database/sql"
	"encoding/json"
	"flag"
	"log"
	"sync"
	"time"

	cluster "github.com/bsm/sarama-cluster"
	"github.com/kshvakov/clickhouse"
)

type options struct {
	Broker  string
	Topic   string
	Id      int
	Value   string
	Debug   bool
	Workers int
}

type dataField struct {
	I int
	V interface{}
}

type ipfix struct {
	AgentID  string
	DataSets [][]dataField
}

type dIPFIXSample struct {
	device string
	src    string
	dst    string
	srcASN uint64
	dstASN uint64
	proto  uint8
}

var opts options

func init() {
	flag.StringVar(&opts.Broker, "broker", "127.0.0.1:9092", "broker ipaddress:port")
	flag.StringVar(&opts.Topic, "topic", "vflow.ipfix", "kafka topic")
	flag.StringVar(&opts.Value, "value", "8.8.8.8", "element value - string")
	flag.BoolVar(&opts.Debug, "debug", false, "enabled/disabled debug")
	flag.IntVar(&opts.Id, "id", 12, "IPFIX element ID")
	flag.IntVar(&opts.Workers, "workers", 16, "workers number / partition number")

	flag.Parse()
}

func main() {
	var (
		wg sync.WaitGroup
		ch = make(chan ipfix, 10000)
	)

	config := cluster.NewConfig()
	config.Consumer.Return.Errors = true
	config.Group.Return.Notifications = true

	for i := 0; i < 5; i++ {
		go ingestClickHouse(ch)
	}

	wg.Add(opts.Workers)

	for i := 0; i < opts.Workers; i++ {
		go func(ti int) {
			brokers := []string{opts.Broker}
			topics := []string{opts.Topic}
			consumer, err := cluster.NewConsumer(brokers, "mygroup", topics, config)

			if err != nil {
				panic(err)
			}
			defer consumer.Close()

			pCount := 0
			count := 0
			tik := time.Tick(10 * time.Second)

			for {
				select {
				case <-tik:
					if opts.Debug {
						log.Printf("partition GroupId#%d,  rate=%d\n", ti, (count-pCount)/10)
					}
					pCount = count
				case msg, more := <-consumer.Messages():
					objmap := ipfix{}
					if more {
						if err := json.Unmarshal(msg.Value, &objmap); err != nil {
							log.Println(err)
						} else {
							ch <- objmap
						}
						consumer.MarkOffset(msg, "")
						count++
					}
				}
			}
		}(i)
	}

	wg.Wait()
}

func ingestClickHouse(ch chan ipfix) {
	var sample ipfix

	connect, err := sql.Open("clickhouse", "tcp://127.0.0.1:9000?debug=false")
	if err != nil {
		log.Fatal(err)
	}
	if err := connect.Ping(); err != nil {
		if exception, ok := err.(*clickhouse.Exception); ok {
			log.Printf("[%d] %s \n%s\n", exception.Code, exception.Message, exception.StackTrace)
		} else {
			log.Println(err)
		}
		return
	}

	for {
		tx, err := connect.Begin()
		if err != nil {
			log.Fatal(err)
		}
		stmt, err := tx.Prepare("INSERT INTO vflow.samples (date,time,device,src,dst,srcASN,dstASN, proto) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
		if err != nil {
			log.Fatal(err)
		}

		for i := 0; i < 10000; i++ {

			sample = <-ch
			for _, data := range sample.DataSets {
				s := dIPFIXSample{}
				for _, dd := range data {
					switch dd.I {
					case 8, 27:
						s.src = dd.V.(string)
					case 12, 28:
						s.dst = dd.V.(string)
					case 16:
						s.srcASN = uint64(dd.V.(float64))
					case 17:
						s.dstASN = uint64(dd.V.(float64))
					case 4:
						s.proto = uint8(dd.V.(float64))
					}
				}
				if _, err := stmt.Exec(
					time.Now(),
					time.Now(),
					sample.AgentID,
					s.src,
					s.dst,
					s.srcASN,
					s.dstASN,
					s.proto,
				); err != nil {
					log.Fatal(err)
				}

			}
		}

		go func(tx *sql.Tx) {
			if err := tx.Commit(); err != nil {
				log.Fatal(err)
			}
		}(tx)
	}
}
<|endoftext|>


<commit_before>package incata

import (
	"testing"
	"time"
)

func TestJSONSerializer(t *testing.T) {

	expectedString := `{"version":1,"name":"Joe","balance":12.99,"birth_date":"2015-12-13T23:59:59+02:00"}`

	location, err := time.LoadLocation("Europe/Athens")

	if err != nil {
		t.Fatalf("Error getting location!")
	}

	testData := TestData{
		Version:   1,
		Name:      "Joe",
		Balance:   12.99,
		BirthDate: time.Date(2015, 12, 13, 23, 59, 59, 0, location),
	}

	serializedString, err := NewJSONMarshaller().Serialize(testData)

	if err != nil {
		t.Fatalf("Error in serialization! %s", err)
	}

	if expectedString != serializedString {
		t.Fatalf("Expected %s is different than serialized %s", expectedString, serializedString)
	}
}

func TestJSONSerializerWithNull(t *testing.T) {

	var m = make(map[int]int, 0)
	payload, err := NewJSONMarshaller().Serialize(m)

	if err == nil {
		t.Fatalf("Should have failed! %s", payload)
	}
}

func TestJsonDeserializer(t *testing.T) {

	location, err := time.LoadLocation("Europe/Athens")

	if err != nil {
		t.Fatalf("Error getting location!")
	}

	expected := TestData{
		Version:   1,
		Name:      "Joe",
		Balance:   12.99,
		BirthDate: time.Date(2015, 12, 13, 23, 59, 59, 0, location),
	}

	actualData := `{"version":1,"name":"Joe","balance":12.99,"birth_date":"2015-12-13T23:59:59+02:00"}`
	var actual TestData

	err = NewJSONMarshaller().Deserialize(actualData, &actual)

	if expected.Version != actual.Version {
		t.Fatalf("Version Expected: %s Actual: %s", expected, actual)
	}

	if expected.Name != actual.Name {
		t.Fatalf("Name Expected: %s Actual: %s", expected, actual)
	}

	if expected.Balance != actual.Balance {
		t.Fatalf("Balance Expected: %s Actual: %s", expected, actual)
	}

	if !expected.BirthDate.Equal(actual.BirthDate) {
		t.Fatalf("BirthDate Expected: %s Actual: %s", expected, actual)
	}
}

func TestJsonDeserializerError(t *testing.T) {

	actualData := `{"version":1,"name":"Joe","balance":12.99,"birth_date":"2015-12-13T23:59:59+02:00------"}`

	var actual TestData

	err := NewJSONMarshaller().Deserialize(actualData, &actual)

	if err == nil {
		t.Fatal("Should have raised a error")
	}
}

func TestJsonDeserializerWrongTypeError(t *testing.T) {

	var actual TestData

	err := NewJSONMarshaller().Deserialize(123, &actual)

	if err == nil {
		t.Fatal("Should have raised a error")
	}
}

func BenchmarkJSONSerializer(b *testing.B) {

	var sert = NewJSONMarshaller()

	location, err := time.LoadLocation("Europe/Athens")

	if err != nil {
		b.Fatalf("Error getting location!")
	}

	testData := TestData{
		Version:   1,
		Name:      "Joe",
		Balance:   12.99,
		BirthDate: time.Date(2015, 12, 13, 23, 59, 59, 0, location),
	}

	for n := 0; n < b.N; n++ {
		sert.Serialize(testData)
	}
}
<commit_msg>govet fix<commit_after>package incata

import (
	"testing"
	"time"
)

func TestJSONSerializer(t *testing.T) {

	expectedString := `{"version":1,"name":"Joe","balance":12.99,"birth_date":"2015-12-13T23:59:59+02:00"}`

	location, err := time.LoadLocation("Europe/Athens")

	if err != nil {
		t.Fatalf("Error getting location!")
	}

	testData := TestData{
		Version:   1,
		Name:      "Joe",
		Balance:   12.99,
		BirthDate: time.Date(2015, 12, 13, 23, 59, 59, 0, location),
	}

	serializedString, err := NewJSONMarshaller().Serialize(testData)

	if err != nil {
		t.Fatalf("Error in serialization! %s", err)
	}

	if expectedString != serializedString {
		t.Fatalf("Expected %s is different than serialized %s", expectedString, serializedString)
	}
}

func TestJSONSerializerWithNull(t *testing.T) {

	var m = make(map[int]int, 0)
	payload, err := NewJSONMarshaller().Serialize(m)

	if err == nil {
		t.Fatalf("Should have failed! %s", payload)
	}
}

func TestJsonDeserializer(t *testing.T) {

	location, err := time.LoadLocation("Europe/Athens")

	if err != nil {
		t.Fatalf("Error getting location!")
	}

	expected := TestData{
		Version:   1,
		Name:      "Joe",
		Balance:   12.99,
		BirthDate: time.Date(2015, 12, 13, 23, 59, 59, 0, location),
	}

	actualData := `{"version":1,"name":"Joe","balance":12.99,"birth_date":"2015-12-13T23:59:59+02:00"}`
	var actual TestData

	err = NewJSONMarshaller().Deserialize(actualData, &actual)

	if expected.Version != actual.Version {
		t.Fatalf("Version Expected: %s Actual: %s", expected.Version, actual.Version)
	}

	if expected.Name != actual.Name {
		t.Fatalf("Name Expected: %s Actual: %s", expected.Name, actual.Name)
	}

	if expected.Balance != actual.Balance {
		t.Fatalf("Balance Expected: %d Actual: %d", expected.Balance, actual.Balance)
	}

	if !expected.BirthDate.Equal(actual.BirthDate) {
		t.Fatalf("BirthDate Expected: %s Actual: %s", expected.BirthDate, actual.BirthDate)
	}
}

func TestJsonDeserializerError(t *testing.T) {

	actualData := `{"version":1,"name":"Joe","balance":12.99,"birth_date":"2015-12-13T23:59:59+02:00------"}`

	var actual TestData

	err := NewJSONMarshaller().Deserialize(actualData, &actual)

	if err == nil {
		t.Fatal("Should have raised a error")
	}
}

func TestJsonDeserializerWrongTypeError(t *testing.T) {

	var actual TestData

	err := NewJSONMarshaller().Deserialize(123, &actual)

	if err == nil {
		t.Fatal("Should have raised a error")
	}
}

func BenchmarkJSONSerializer(b *testing.B) {

	var sert = NewJSONMarshaller()

	location, err := time.LoadLocation("Europe/Athens")

	if err != nil {
		b.Fatalf("Error getting location!")
	}

	testData := TestData{
		Version:   1,
		Name:      "Joe",
		Balance:   12.99,
		BirthDate: time.Date(2015, 12, 13, 23, 59, 59, 0, location),
	}

	for n := 0; n < b.N; n++ {
		sert.Serialize(testData)
	}
}
<|endoftext|>