<commit_before>package v2

import (
	"testing"

	"github.com/gophercloud/gophercloud/acceptance/clients"
	"github.com/gophercloud/gophercloud/openstack/sharedfilesystems/v2/sharetypes"
)

func TestShareTypeCreateDestroy(t *testing.T) {
	client, err := clients.NewSharedFileSystemV2Client()
	if err != nil {
		t.Fatalf("Unable to create shared file system client: %v", err)
	}

	shareType, err := CreateShareType(t, client)
	if err != nil {
		t.Fatalf("Unable to create share type: %v", err)
	}

	PrintShareType(t, shareType)

	defer DeleteShareType(t, client, shareType)
}

func TestShareTypeList(t *testing.T) {
	client, err := clients.NewSharedFileSystemV2Client()
	if err != nil {
		t.Fatalf("Unable to create a shared file system client: %v", err)
	}

	allPages, err := sharetypes.List(client, sharetypes.ListOpts{}).AllPages()
	if err != nil {
		t.Fatalf("Unable to retrieve share types: %v", err)
	}

	allShareTypes, err := sharetypes.ExtractShareTypes(allPages)
	if err != nil {
		t.Fatalf("Unable to extract share types: %v", err)
	}

	for _, shareType := range allShareTypes {
		PrintShareType(t, &shareType)
	}
}

func TestShareTypeGetDefault(t *testing.T) {
	client, err := clients.NewSharedFileSystemV2Client()
	if err != nil {
		t.Fatalf("Unable to create a shared file system client: %v", err)
	}

	shareType, err := sharetypes.GetDefault(client).Extract()
	if err != nil {
		t.Fatalf("Unable to retrieve the default share type: %v", err)
	}

	PrintShareType(t, shareType)
}

func TestShareTypeExtraSpecs(t *testing.T) {
	client, err := clients.NewSharedFileSystemV2Client()
	if err != nil {
		t.Fatalf("Unable to create shared file system client: %v", err)
	}

	shareType, err := CreateShareType(t, client)
	if err != nil {
		t.Fatalf("Unable to create share type: %v", err)
	}

	options := sharetypes.SetExtraSpecsOpts{
		Specs: map[string]interface{}{"my_new_key": "my_value"},
	}

	_, err = sharetypes.SetExtraSpecs(client, shareType.ID, options).Extract()
	if err != nil {
		t.Fatalf("Unable to set extra specs for Share type: %s", shareType.Name)
	}

	extraSpecs, err := sharetypes.GetExtraSpecs(client, shareType.ID).Extract()
	if err != nil {
		t.Fatalf("Unable to retrieve share type: %s", shareType.Name)
	}

	if extraSpecs["driver_handles_share_servers"] != "True" {
		t.Fatal("driver_handles_share_servers was expected to be true")
	}

	if extraSpecs["my_new_key"] != "my_value" {
		t.Fatal("my_new_key was expected to be equal to my_value")
	}

	err = sharetypes.UnsetExtraSpecs(client, shareType.ID, "my_new_key").ExtractErr()
	if err != nil {
		t.Fatalf("Unable to unset extra specs for Share type: %s", shareType.Name)
	}

	extraSpecs, err = sharetypes.GetExtraSpecs(client, shareType.ID).Extract()
	if err != nil {
		t.Fatalf("Unable to retrieve share type: %s", shareType.Name)
	}

	if _, ok := extraSpecs["my_new_key"]; ok {
		t.Fatalf("my_new_key was expected to be unset for Share type: %s", shareType.Name)
	}

	PrintShareType(t, shareType)

	defer DeleteShareType(t, client, shareType)
}

func TestShareTypeAccess(t *testing.T) {
	client, err := clients.NewSharedFileSystemV2Client()
	if err != nil {
		t.Fatalf("Unable to create shared file system client: %v", err)
	}

	shareType, err := CreateShareType(t, client)
	if err != nil {
		t.Fatalf("Unable to create share type: %v", err)
	}

	options := sharetypes.AccessOpts{
		Project: "9e3a5a44e0134445867776ef53a37605",
	}

	err = sharetypes.AddAccess(client, shareType.ID, options).ExtractErr()
	if err != nil {
		t.Fatalf("Unable to add a new access to a share type: %v", err)
	}

	access, err := sharetypes.ShowAccess(client, shareType.ID).Extract()
	if err != nil {
		t.Fatalf("Unable to retrieve the access details for a share type: %v", err)
	}

	expected := []sharetypes.ShareTypeAccess{{ShareTypeID: shareType.ID, ProjectID: options.Project}}

	if access[0] != expected[0] {
		t.Fatal("Share type access is not the same than expected")
	}

	PrintShareType(t, shareType)

	defer DeleteShareType(t, client, shareType)

}
<commit_msg>sfs: Add acceptance tests for share type Remove Access<commit_after>package v2

import (
	"testing"

	"github.com/gophercloud/gophercloud/acceptance/clients"
	"github.com/gophercloud/gophercloud/openstack/sharedfilesystems/v2/sharetypes"
)

func TestShareTypeCreateDestroy(t *testing.T) {
	client, err := clients.NewSharedFileSystemV2Client()
	if err != nil {
		t.Fatalf("Unable to create shared file system client: %v", err)
	}

	shareType, err := CreateShareType(t, client)
	if err != nil {
		t.Fatalf("Unable to create share type: %v", err)
	}

	PrintShareType(t, shareType)

	defer DeleteShareType(t, client, shareType)
}

func TestShareTypeList(t *testing.T) {
	client, err := clients.NewSharedFileSystemV2Client()
	if err != nil {
		t.Fatalf("Unable to create a shared file system client: %v", err)
	}

	allPages, err := sharetypes.List(client, sharetypes.ListOpts{}).AllPages()
	if err != nil {
		t.Fatalf("Unable to retrieve share types: %v", err)
	}

	allShareTypes, err := sharetypes.ExtractShareTypes(allPages)
	if err != nil {
		t.Fatalf("Unable to extract share types: %v", err)
	}

	for _, shareType := range allShareTypes {
		PrintShareType(t, &shareType)
	}
}

func TestShareTypeGetDefault(t *testing.T) {
	client, err := clients.NewSharedFileSystemV2Client()
	if err != nil {
		t.Fatalf("Unable to create a shared file system client: %v", err)
	}

	shareType, err := sharetypes.GetDefault(client).Extract()
	if err != nil {
		t.Fatalf("Unable to retrieve the default share type: %v", err)
	}

	PrintShareType(t, shareType)
}

func TestShareTypeExtraSpecs(t *testing.T) {
	client, err := clients.NewSharedFileSystemV2Client()
	if err != nil {
		t.Fatalf("Unable to create shared file system client: %v", err)
	}

	shareType, err := CreateShareType(t, client)
	if err != nil {
		t.Fatalf("Unable to create share type: %v", err)
	}

	options := sharetypes.SetExtraSpecsOpts{
		Specs: map[string]interface{}{"my_new_key": "my_value"},
	}

	_, err = sharetypes.SetExtraSpecs(client, shareType.ID, options).Extract()
	if err != nil {
		t.Fatalf("Unable to set extra specs for Share type: %s", shareType.Name)
	}

	extraSpecs, err := sharetypes.GetExtraSpecs(client, shareType.ID).Extract()
	if err != nil {
		t.Fatalf("Unable to retrieve share type: %s", shareType.Name)
	}

	if extraSpecs["driver_handles_share_servers"] != "True" {
		t.Fatal("driver_handles_share_servers was expected to be true")
	}

	if extraSpecs["my_new_key"] != "my_value" {
		t.Fatal("my_new_key was expected to be equal to my_value")
	}

	err = sharetypes.UnsetExtraSpecs(client, shareType.ID, "my_new_key").ExtractErr()
	if err != nil {
		t.Fatalf("Unable to unset extra specs for Share type: %s", shareType.Name)
	}

	extraSpecs, err = sharetypes.GetExtraSpecs(client, shareType.ID).Extract()
	if err != nil {
		t.Fatalf("Unable to retrieve share type: %s", shareType.Name)
	}

	if _, ok := extraSpecs["my_new_key"]; ok {
		t.Fatalf("my_new_key was expected to be unset for Share type: %s", shareType.Name)
	}

	PrintShareType(t, shareType)

	defer DeleteShareType(t, client, shareType)
}

func TestShareTypeAccess(t *testing.T) {
	client, err := clients.NewSharedFileSystemV2Client()
	if err != nil {
		t.Fatalf("Unable to create shared file system client: %v", err)
	}

	shareType, err := CreateShareType(t, client)
	if err != nil {
		t.Fatalf("Unable to create share type: %v", err)
	}

	options := sharetypes.AccessOpts{
		Project: "9e3a5a44e0134445867776ef53a37605",
	}

	err = sharetypes.AddAccess(client, shareType.ID, options).ExtractErr()
	if err != nil {
		t.Fatalf("Unable to add a new access to a share type: %v", err)
	}

	access, err := sharetypes.ShowAccess(client, shareType.ID).Extract()
	if err != nil {
		t.Fatalf("Unable to retrieve the access details for a share type: %v", err)
	}

	expected := []sharetypes.ShareTypeAccess{{ShareTypeID: shareType.ID, ProjectID: options.Project}}

	if access[0] != expected[0] {
		t.Fatal("Share type access is not the same than expected")
	}

	err = sharetypes.RemoveAccess(client, shareType.ID, options).ExtractErr()
	if err != nil {
		t.Fatalf("Unable to remove an access from a share type: %v", err)
	}

	access, err = sharetypes.ShowAccess(client, shareType.ID).Extract()
	if err != nil {
		t.Fatalf("Unable to retrieve the access details for a share type: %v", err)
	}

	if len(access) > 0 {
		t.Fatalf("No access should be left for the share type: %s", shareType.Name)
	}

	PrintShareType(t, shareType)

	defer DeleteShareType(t, client, shareType)

}
<|endoftext|>


<commit_before>package pd1_test

import (
	"testing"
	"time"

	"github.com/influxdb/influxdb/tsdb/engine/pd1"
)

func Test_TimeEncoder(t *testing.T) {
	enc := pd1.NewTimeEncoder()

	x := []time.Time{}
	now := time.Unix(0, 0)
	x = append(x, now)
	enc.Write(now)
	for i := 1; i < 4; i++ {
		x = append(x, now.Add(time.Duration(i)*time.Second))
		enc.Write(x[i])
	}

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	dec := pd1.NewTimeDecoder(b)
	for i, v := range x {
		if !dec.Next() {
			t.Fatalf("Next == false, expected true")
		}

		if v != dec.Read() {
			t.Fatalf("Item %d mismatch, got %v, exp %v", i, dec.Read(), v)
		}
	}
}

func Test_TimeEncoder_NoValues(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	dec := pd1.NewTimeDecoder(b)
	if dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}
}

func Test_TimeEncoder_One(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	tm := time.Unix(0, 0)

	enc.Write(tm)
	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	dec := pd1.NewTimeDecoder(b)
	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if tm != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), tm)
	}
}

func Test_TimeEncoder_Two(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	t1 := time.Unix(0, 0)
	t2 := time.Unix(0, 1)
	enc.Write(t1)
	enc.Write(t2)

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	dec := pd1.NewTimeDecoder(b)
	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t1 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t1)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t2 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t2)
	}
}

func Test_TimeEncoder_Three(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	t1 := time.Unix(0, 0)
	t2 := time.Unix(0, 1)
	t3 := time.Unix(0, 2)

	enc.Write(t1)
	enc.Write(t2)
	enc.Write(t3)

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	dec := pd1.NewTimeDecoder(b)
	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t1 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t1)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t2 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t2)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t3 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t3)
	}
}

func Test_TimeEncoder_Large_Range(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	t1 := time.Unix(0, 1442369134000000000)
	t2 := time.Unix(0, 1442369135000000000)
	enc.Write(t1)
	enc.Write(t2)
	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	dec := pd1.NewTimeDecoder(b)
	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t1 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t1)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t2 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t2)
	}
}

func Test_TimeEncoder_Raw(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	t1 := time.Unix(0, 0)
	t2 := time.Unix(1, 0)

	// about 36.5yrs in NS resolution is max range for compressed format
	// This should cause the encoding to fallback to raw points
	t3 := time.Unix(2, (2 << 59))
	enc.Write(t1)
	enc.Write(t2)
	enc.Write(t3)

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("expected error: %v", err)
	}

	if exp := 25; len(b) != exp {
		t.Fatalf("length mismatch: got %v, exp %v", len(b), exp)
	}

	dec := pd1.NewTimeDecoder(b)
	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t1 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t1)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t2 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t2)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t3 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t3)
	}
}

func Test_TimeEncoder_RLE(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	var ts []time.Time
	for i := 0; i < 500; i++ {
		ts = append(ts, time.Unix(int64(i), 0))
	}

	for _, v := range ts {
		enc.Write(v)
	}

	b, err := enc.Bytes()
	if exp := 12; len(b) != exp {
		t.Fatalf("length mismatch: got %v, exp %v", len(b), exp)
	}

	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	dec := pd1.NewTimeDecoder(b)
	for i, v := range ts {
		if !dec.Next() {
			t.Fatalf("Next == false, expected true")
		}

		if v != dec.Read() {
			t.Fatalf("Item %d mismatch, got %v, exp %v", i, dec.Read(), v)
		}
	}

	if dec.Next() {
		t.Fatalf("unexpected extra values")
	}
}

func Test_TimeEncoder_Reverse(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	ts := []time.Time{
		time.Unix(0, 3),
		time.Unix(0, 2),
		time.Unix(0, 1),
	}

	for _, v := range ts {
		enc.Write(v)
	}

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	dec := pd1.NewTimeDecoder(b)
	i := 0
	for dec.Next() {
		if ts[i] != dec.Read() {
			t.Fatalf("read value %d mismatch: got %v, exp %v", i, dec.Read(), ts[i])
		}
		i += 1
	}
}

func Test_TimeEncoder_220SecondDelta(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	var ts []time.Time
	now := time.Now()
	for i := 0; i < 220; i++ {
		ts = append(ts, now.Add(time.Duration(i*60)*time.Second))
	}

	for _, v := range ts {
		enc.Write(v)
	}

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// Using RLE, should get 12 bytes
	if exp := 12; len(b) != exp {
		t.Fatalf("unexpected length: got %v, exp %v", len(b), exp)
	}

	dec := pd1.NewTimeDecoder(b)
	i := 0
	for dec.Next() {
		if ts[i] != dec.Read() {
			t.Fatalf("read value %d mismatch: got %v, exp %v", i, dec.Read(), ts[i])
		}
		i += 1
	}

	if i != len(ts) {
		t.Fatalf("Read too few values: exp %d, got %d", len(ts), i)
	}

	if dec.Next() {
		t.Fatalf("expecte Next() = false, got true")
	}
}

func BenchmarkTimeEncoder(b *testing.B) {
	enc := pd1.NewTimeEncoder()
	x := make([]time.Time, 1024)
	for i := 0; i < len(x); i++ {
		x[i] = time.Now()
		enc.Write(x[i])
	}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		enc.Bytes()
	}
}

func BenchmarkTimeDecoder(b *testing.B) {
	x := make([]time.Time, 1024)
	enc := pd1.NewTimeEncoder()
	for i := 0; i < len(x); i++ {
		x[i] = time.Now()
		enc.Write(x[i])
	}
	bytes, _ := enc.Bytes()

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		b.StopTimer()
		dec := pd1.NewTimeDecoder(bytes)
		b.StartTimer()
		for dec.Next() {
		}
	}
}
<commit_msg>Add test assertions for time encoding type<commit_after>package pd1_test

import (
	"testing"
	"time"

	"github.com/influxdb/influxdb/tsdb/engine/pd1"
)

func Test_TimeEncoder(t *testing.T) {
	enc := pd1.NewTimeEncoder()

	x := []time.Time{}
	now := time.Unix(0, 0)
	x = append(x, now)
	enc.Write(now)
	for i := 1; i < 4; i++ {
		x = append(x, now.Add(time.Duration(i)*time.Second))
		enc.Write(x[i])
	}

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	if got := b[0] >> 4; got != pd1.EncodingPacked {
		t.Fatalf("Wrong encoding used: expected uncompressed, got %v", got)
	}

	dec := pd1.NewTimeDecoder(b)
	for i, v := range x {
		if !dec.Next() {
			t.Fatalf("Next == false, expected true")
		}

		if v != dec.Read() {
			t.Fatalf("Item %d mismatch, got %v, exp %v", i, dec.Read(), v)
		}
	}
}

func Test_TimeEncoder_NoValues(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	dec := pd1.NewTimeDecoder(b)
	if dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}
}

func Test_TimeEncoder_One(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	tm := time.Unix(0, 0)

	enc.Write(tm)
	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	if got := b[0] >> 4; got != pd1.EncodingPacked {
		t.Fatalf("Wrong encoding used: expected uncompressed, got %v", got)
	}

	dec := pd1.NewTimeDecoder(b)
	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if tm != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), tm)
	}
}

func Test_TimeEncoder_Two(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	t1 := time.Unix(0, 0)
	t2 := time.Unix(0, 1)
	enc.Write(t1)
	enc.Write(t2)

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	if got := b[0] >> 4; got != pd1.EncodingPacked {
		t.Fatalf("Wrong encoding used: expected uncompressed, got %v", got)
	}

	dec := pd1.NewTimeDecoder(b)
	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t1 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t1)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t2 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t2)
	}
}

func Test_TimeEncoder_Three(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	t1 := time.Unix(0, 0)
	t2 := time.Unix(0, 1)
	t3 := time.Unix(0, 2)

	enc.Write(t1)
	enc.Write(t2)
	enc.Write(t3)

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	if got := b[0] >> 4; got != pd1.EncodingPacked {
		t.Fatalf("Wrong encoding used: expected uncompressed, got %v", got)
	}

	dec := pd1.NewTimeDecoder(b)
	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t1 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t1)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t2 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t2)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t3 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t3)
	}
}

func Test_TimeEncoder_Large_Range(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	t1 := time.Unix(0, 1442369134000000000)
	t2 := time.Unix(0, 1442369135000000000)
	enc.Write(t1)
	enc.Write(t2)
	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	if got := b[0] >> 4; got != pd1.EncodingPacked {
		t.Fatalf("Wrong encoding used: expected uncompressed, got %v", got)
	}

	dec := pd1.NewTimeDecoder(b)
	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t1 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t1)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t2 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t2)
	}
}

func Test_TimeEncoder_Uncompressed(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	t1 := time.Unix(0, 0)
	t2 := time.Unix(1, 0)

	// about 36.5yrs in NS resolution is max range for compressed format
	// This should cause the encoding to fallback to raw points
	t3 := time.Unix(2, (2 << 59))
	enc.Write(t1)
	enc.Write(t2)
	enc.Write(t3)

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("expected error: %v", err)
	}

	if exp := 25; len(b) != exp {
		t.Fatalf("length mismatch: got %v, exp %v", len(b), exp)
	}

	if got := b[0] >> 4; got != pd1.EncodingUncompressed {
		t.Fatalf("Wrong encoding used: expected uncompressed, got %v", got)
	}

	dec := pd1.NewTimeDecoder(b)
	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t1 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t1)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t2 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t2)
	}

	if !dec.Next() {
		t.Fatalf("unexpected next value: got true, exp false")
	}

	if t3 != dec.Read() {
		t.Fatalf("read value mismatch: got %v, exp %v", dec.Read(), t3)
	}
}

func Test_TimeEncoder_RLE(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	var ts []time.Time
	for i := 0; i < 500; i++ {
		ts = append(ts, time.Unix(int64(i), 0))
	}

	for _, v := range ts {
		enc.Write(v)
	}

	b, err := enc.Bytes()
	if exp := 12; len(b) != exp {
		t.Fatalf("length mismatch: got %v, exp %v", len(b), exp)
	}

	if got := b[0] >> 4; got != pd1.EncodingRLE {
		t.Fatalf("Wrong encoding used: expected uncompressed, got %v", got)
	}

	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	dec := pd1.NewTimeDecoder(b)
	for i, v := range ts {
		if !dec.Next() {
			t.Fatalf("Next == false, expected true")
		}

		if v != dec.Read() {
			t.Fatalf("Item %d mismatch, got %v, exp %v", i, dec.Read(), v)
		}
	}

	if dec.Next() {
		t.Fatalf("unexpected extra values")
	}
}

func Test_TimeEncoder_Reverse(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	ts := []time.Time{
		time.Unix(0, 3),
		time.Unix(0, 2),
		time.Unix(0, 1),
	}

	for _, v := range ts {
		enc.Write(v)
	}

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	if got := b[0] >> 4; got != pd1.EncodingPacked {
		t.Fatalf("Wrong encoding used: expected uncompressed, got %v", got)
	}

	dec := pd1.NewTimeDecoder(b)
	i := 0
	for dec.Next() {
		if ts[i] != dec.Read() {
			t.Fatalf("read value %d mismatch: got %v, exp %v", i, dec.Read(), ts[i])
		}
		i += 1
	}
}

func Test_TimeEncoder_220SecondDelta(t *testing.T) {
	enc := pd1.NewTimeEncoder()
	var ts []time.Time
	now := time.Now()
	for i := 0; i < 220; i++ {
		ts = append(ts, now.Add(time.Duration(i*60)*time.Second))
	}

	for _, v := range ts {
		enc.Write(v)
	}

	b, err := enc.Bytes()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// Using RLE, should get 12 bytes
	if exp := 12; len(b) != exp {
		t.Fatalf("unexpected length: got %v, exp %v", len(b), exp)
	}

	if got := b[0] >> 4; got != pd1.EncodingRLE {
		t.Fatalf("Wrong encoding used: expected uncompressed, got %v", got)
	}

	dec := pd1.NewTimeDecoder(b)
	i := 0
	for dec.Next() {
		if ts[i] != dec.Read() {
			t.Fatalf("read value %d mismatch: got %v, exp %v", i, dec.Read(), ts[i])
		}
		i += 1
	}

	if i != len(ts) {
		t.Fatalf("Read too few values: exp %d, got %d", len(ts), i)
	}

	if dec.Next() {
		t.Fatalf("expecte Next() = false, got true")
	}
}

func BenchmarkTimeEncoder(b *testing.B) {
	enc := pd1.NewTimeEncoder()
	x := make([]time.Time, 1024)
	for i := 0; i < len(x); i++ {
		x[i] = time.Now()
		enc.Write(x[i])
	}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		enc.Bytes()
	}
}

func BenchmarkTimeDecoder(b *testing.B) {
	x := make([]time.Time, 1024)
	enc := pd1.NewTimeEncoder()
	for i := 0; i < len(x); i++ {
		x[i] = time.Now()
		enc.Write(x[i])
	}
	bytes, _ := enc.Bytes()

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		b.StopTimer()
		dec := pd1.NewTimeDecoder(bytes)
		b.StartTimer()
		for dec.Next() {
		}
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"bytes"
	"fmt"
	"log"

	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/mitchellh/goamz/elb"
)

func resourceAwsElb() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsElbCreate,
		Read:   resourceAwsElbRead,
		Update: resourceAwsElbUpdate,
		Delete: resourceAwsElbDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"internal": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				ForceNew: true,
				Computed: true,
			},

			"cross_zone_load_balancing": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
			},

			"availability_zones": &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
				ForceNew: true,
				Computed: true,
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},

			"instances": &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
				Computed: true,
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},

			// TODO: could be not ForceNew
			"security_groups": &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
				ForceNew: true,
				Computed: true,
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},

			// TODO: could be not ForceNew
			"subnets": &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
				ForceNew: true,
				Computed: true,
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},

			// TODO: could be not ForceNew
			"listener": &schema.Schema{
				Type:     schema.TypeSet,
				Required: true,
				ForceNew: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"instance_port": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},

						"instance_protocol": &schema.Schema{
							Type:     schema.TypeString,
							Required: true,
						},

						"lb_port": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},

						"lb_protocol": &schema.Schema{
							Type:     schema.TypeString,
							Required: true,
						},

						"ssl_certificate_id": &schema.Schema{
							Type:     schema.TypeString,
							Optional: true,
						},
					},
				},
				Set: resourceAwsElbListenerHash,
			},

			// TODO: could be not ForceNew
			"health_check": &schema.Schema{
				Type:     schema.TypeSet,
				Optional: true,
				ForceNew: true,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"healthy_threshold": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},

						"unhealthy_threshold": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},

						"target": &schema.Schema{
							Type:     schema.TypeString,
							Required: true,
						},

						"interval": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},

						"timeout": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},
					},
				},
				Set: resourceAwsElbHealthCheckHash,
			},

			"dns_name": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func resourceAwsElbCreate(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	// Expand the "listener" set to goamz compat []elb.Listener
	listeners, err := expandListeners(d.Get("listener").(*schema.Set).List())
	if err != nil {
		return err
	}

	// Provision the elb
	elbOpts := &elb.CreateLoadBalancer{
		LoadBalancerName: d.Get("name").(string),
		Listeners:        listeners,
		Internal:         d.Get("internal").(bool),
	}

	if v, ok := d.GetOk("availability_zones"); ok {
		elbOpts.AvailZone = expandStringList(v.(*schema.Set).List())
	}

	if v, ok := d.GetOk("security_groups"); ok {
		elbOpts.SecurityGroups = expandStringList(v.(*schema.Set).List())
	}

	if v, ok := d.GetOk("subnets"); ok {
		elbOpts.Subnets = expandStringList(v.(*schema.Set).List())
	}

	log.Printf("[DEBUG] ELB create configuration: %#v", elbOpts)
	if _, err := elbconn.CreateLoadBalancer(elbOpts); err != nil {
		return fmt.Errorf("Error creating ELB: %s", err)
	}

	// Assign the elb's unique identifier for use later
	d.SetId(d.Get("name").(string))
	log.Printf("[INFO] ELB ID: %s", d.Id())

	// Enable partial mode and record what we set
	d.Partial(true)
	d.SetPartial("name")
	d.SetPartial("internal")
	d.SetPartial("availability_zones")
	d.SetPartial("listener")
	d.SetPartial("security_groups")
	d.SetPartial("subnets")

	if d.HasChange("health_check") {
		vs := d.Get("health_check").(*schema.Set).List()
		if len(vs) > 0 {
			check := vs[0].(map[string]interface{})

			configureHealthCheckOpts := elb.ConfigureHealthCheck{
				LoadBalancerName: d.Id(),
				Check: elb.HealthCheck{
					HealthyThreshold:   int64(check["healthy_threshold"].(int)),
					UnhealthyThreshold: int64(check["unhealthy_threshold"].(int)),
					Interval:           int64(check["interval"].(int)),
					Target:             check["target"].(string),
					Timeout:            int64(check["timeout"].(int)),
				},
			}

			_, err = elbconn.ConfigureHealthCheck(&configureHealthCheckOpts)
			if err != nil {
				return fmt.Errorf("Failure configuring health check: %s", err)
			}
		}
	}

	return resourceAwsElbUpdate(d, meta)
}

func resourceAwsElbRead(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	// Retrieve the ELB properties for updating the state
	describeElbOpts := &elb.DescribeLoadBalancer{
		Names: []string{d.Id()},
	}

	describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts)
	if err != nil {
		if ec2err, ok := err.(*elb.Error); ok && ec2err.Code == "LoadBalancerNotFound" {
			// The ELB is gone now, so just remove it from the state
			d.SetId("")
			return nil
		}

		return fmt.Errorf("Error retrieving ELB: %s", err)
	}
	if len(describeResp.LoadBalancers) != 1 {
		return fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancers)
	}

	lb := describeResp.LoadBalancers[0]

	d.Set("name", lb.LoadBalancerName)
	d.Set("dns_name", lb.DNSName)
	d.Set("internal", lb.Scheme == "internal")
	d.Set("availability_zones", lb.AvailabilityZones)
	d.Set("instances", flattenInstances(lb.Instances))
	d.Set("listener", flattenListeners(lb.Listeners))
	d.Set("security_groups", lb.SecurityGroups)
	d.Set("subnets", lb.Subnets)

	// There's only one health check, so save that to state as we
	// currently can
	if lb.HealthCheck.Target != "" {
		d.Set("health_check", flattenHealthCheck(lb.HealthCheck))
	}

	return nil
}

func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	d.Partial(true)

	// If we currently have instances, or did have instances,
	// we want to figure out what to add and remove from the load
	// balancer
	if d.HasChange("instances") {
		o, n := d.GetChange("instances")
		os := o.(*schema.Set)
		ns := n.(*schema.Set)
		remove := expandStringList(os.Difference(ns).List())
		add := expandStringList(ns.Difference(os).List())

		if len(add) > 0 {
			registerInstancesOpts := elb.RegisterInstancesWithLoadBalancer{
				LoadBalancerName: d.Id(),
				Instances:        add,
			}

			_, err := elbconn.RegisterInstancesWithLoadBalancer(&registerInstancesOpts)
			if err != nil {
				return fmt.Errorf("Failure registering instances: %s", err)
			}
		}
		if len(remove) > 0 {
			deRegisterInstancesOpts := elb.DeregisterInstancesFromLoadBalancer{
				LoadBalancerName: d.Id(),
				Instances:        remove,
			}

			_, err := elbconn.DeregisterInstancesFromLoadBalancer(&deRegisterInstancesOpts)
			if err != nil {
				return fmt.Errorf("Failure deregistering instances: %s", err)
			}
		}

		d.SetPartial("instances")
	}

	log.Println("[INFO] outside modify attributes")
	if d.HasChange("cross_zone_load_balancing") {
		log.Println("[INFO] inside modify attributes")
		attrs := elb.ModifyLoadBalancerAttributes{
			LoadBalancerName: d.Get("name").(string),
			LoadBalancerAttributes: elb.LoadBalancerAttributes{
				CrossZoneLoadBalancingEnabled: d.Get("cross_zone_load_balancing").(bool),
			},
		}
		_, err := elbconn.ModifyLoadBalancerAttributes(&attrs)
		if err != nil {
			return fmt.Errorf("Failure configuring health check: %s", err)
		}
		d.SetPartial("cross_zone_load_balancing")
	}

	d.Partial(false)
	return resourceAwsElbRead(d, meta)
}

func resourceAwsElbDelete(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	log.Printf("[INFO] Deleting ELB: %s", d.Id())

	// Destroy the load balancer
	deleteElbOpts := elb.DeleteLoadBalancer{
		LoadBalancerName: d.Id(),
	}
	if _, err := elbconn.DeleteLoadBalancer(&deleteElbOpts); err != nil {
		return fmt.Errorf("Error deleting ELB: %s", err)
	}

	return nil
}

func resourceAwsElbHealthCheckHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	buf.WriteString(fmt.Sprintf("%d-", m["healthy_threshold"].(int)))
	buf.WriteString(fmt.Sprintf("%d-", m["unhealthy_threshold"].(int)))
	buf.WriteString(fmt.Sprintf("%s-", m["target"].(string)))
	buf.WriteString(fmt.Sprintf("%d-", m["interval"].(int)))
	buf.WriteString(fmt.Sprintf("%d-", m["timeout"].(int)))

	return hashcode.String(buf.String())
}

func resourceAwsElbListenerHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	buf.WriteString(fmt.Sprintf("%d-", m["instance_port"].(int)))
	buf.WriteString(fmt.Sprintf("%s-", m["instance_protocol"].(string)))
	buf.WriteString(fmt.Sprintf("%d-", m["lb_port"].(int)))
	buf.WriteString(fmt.Sprintf("%s-", m["lb_protocol"].(string)))

	if v, ok := m["ssl_certificate_id"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}

	return hashcode.String(buf.String())
}
<commit_msg>Changing AWS ELB to not ForceNew when listeners change<commit_after>package aws

import (
	"bytes"
	"fmt"
	"log"

	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/mitchellh/goamz/elb"
)

func resourceAwsElb() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsElbCreate,
		Read:   resourceAwsElbRead,
		Update: resourceAwsElbUpdate,
		Delete: resourceAwsElbDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"internal": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				ForceNew: true,
				Computed: true,
			},

			"cross_zone_load_balancing": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
			},

			"availability_zones": &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
				ForceNew: true,
				Computed: true,
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},

			"instances": &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
				Computed: true,
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},

			// TODO: could be not ForceNew
			"security_groups": &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
				ForceNew: true,
				Computed: true,
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},

			// TODO: could be not ForceNew
			"subnets": &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
				ForceNew: true,
				Computed: true,
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},

			// TODO: could be not ForceNew
			"listener": &schema.Schema{
				Type:     schema.TypeSet,
				Required: true,
				ForceNew: false,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"instance_port": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},

						"instance_protocol": &schema.Schema{
							Type:     schema.TypeString,
							Required: true,
						},

						"lb_port": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},

						"lb_protocol": &schema.Schema{
							Type:     schema.TypeString,
							Required: true,
						},

						"ssl_certificate_id": &schema.Schema{
							Type:     schema.TypeString,
							Optional: true,
						},
					},
				},
				Set: resourceAwsElbListenerHash,
			},

			// TODO: could be not ForceNew
			"health_check": &schema.Schema{
				Type:     schema.TypeSet,
				Optional: true,
				ForceNew: true,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"healthy_threshold": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},

						"unhealthy_threshold": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},

						"target": &schema.Schema{
							Type:     schema.TypeString,
							Required: true,
						},

						"interval": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},

						"timeout": &schema.Schema{
							Type:     schema.TypeInt,
							Required: true,
						},
					},
				},
				Set: resourceAwsElbHealthCheckHash,
			},

			"dns_name": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func resourceAwsElbCreate(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	// Expand the "listener" set to goamz compat []elb.Listener
	listeners, err := expandListeners(d.Get("listener").(*schema.Set).List())
	if err != nil {
		return err
	}

	// Provision the elb
	elbOpts := &elb.CreateLoadBalancer{
		LoadBalancerName: d.Get("name").(string),
		Listeners:        listeners,
		Internal:         d.Get("internal").(bool),
	}

	if v, ok := d.GetOk("availability_zones"); ok {
		elbOpts.AvailZone = expandStringList(v.(*schema.Set).List())
	}

	if v, ok := d.GetOk("security_groups"); ok {
		elbOpts.SecurityGroups = expandStringList(v.(*schema.Set).List())
	}

	if v, ok := d.GetOk("subnets"); ok {
		elbOpts.Subnets = expandStringList(v.(*schema.Set).List())
	}

	log.Printf("[DEBUG] ELB create configuration: %#v", elbOpts)
	if _, err := elbconn.CreateLoadBalancer(elbOpts); err != nil {
		return fmt.Errorf("Error creating ELB: %s", err)
	}

	// Assign the elb's unique identifier for use later
	d.SetId(d.Get("name").(string))
	log.Printf("[INFO] ELB ID: %s", d.Id())

	// Enable partial mode and record what we set
	d.Partial(true)
	d.SetPartial("name")
	d.SetPartial("internal")
	d.SetPartial("availability_zones")
	d.SetPartial("listener")
	d.SetPartial("security_groups")
	d.SetPartial("subnets")

	if d.HasChange("health_check") {
		vs := d.Get("health_check").(*schema.Set).List()
		if len(vs) > 0 {
			check := vs[0].(map[string]interface{})

			configureHealthCheckOpts := elb.ConfigureHealthCheck{
				LoadBalancerName: d.Id(),
				Check: elb.HealthCheck{
					HealthyThreshold:   int64(check["healthy_threshold"].(int)),
					UnhealthyThreshold: int64(check["unhealthy_threshold"].(int)),
					Interval:           int64(check["interval"].(int)),
					Target:             check["target"].(string),
					Timeout:            int64(check["timeout"].(int)),
				},
			}

			_, err = elbconn.ConfigureHealthCheck(&configureHealthCheckOpts)
			if err != nil {
				return fmt.Errorf("Failure configuring health check: %s", err)
			}
		}
	}

	return resourceAwsElbUpdate(d, meta)
}

func resourceAwsElbRead(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	// Retrieve the ELB properties for updating the state
	describeElbOpts := &elb.DescribeLoadBalancer{
		Names: []string{d.Id()},
	}

	describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts)
	if err != nil {
		if ec2err, ok := err.(*elb.Error); ok && ec2err.Code == "LoadBalancerNotFound" {
			// The ELB is gone now, so just remove it from the state
			d.SetId("")
			return nil
		}

		return fmt.Errorf("Error retrieving ELB: %s", err)
	}
	if len(describeResp.LoadBalancers) != 1 {
		return fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancers)
	}

	lb := describeResp.LoadBalancers[0]

	d.Set("name", lb.LoadBalancerName)
	d.Set("dns_name", lb.DNSName)
	d.Set("internal", lb.Scheme == "internal")
	d.Set("availability_zones", lb.AvailabilityZones)
	d.Set("instances", flattenInstances(lb.Instances))
	d.Set("listener", flattenListeners(lb.Listeners))
	d.Set("security_groups", lb.SecurityGroups)
	d.Set("subnets", lb.Subnets)

	// There's only one health check, so save that to state as we
	// currently can
	if lb.HealthCheck.Target != "" {
		d.Set("health_check", flattenHealthCheck(lb.HealthCheck))
	}

	return nil
}

func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	d.Partial(true)

	// If we currently have instances, or did have instances,
	// we want to figure out what to add and remove from the load
	// balancer
	if d.HasChange("instances") {
		o, n := d.GetChange("instances")
		os := o.(*schema.Set)
		ns := n.(*schema.Set)
		remove := expandStringList(os.Difference(ns).List())
		add := expandStringList(ns.Difference(os).List())

		if len(add) > 0 {
			registerInstancesOpts := elb.RegisterInstancesWithLoadBalancer{
				LoadBalancerName: d.Id(),
				Instances:        add,
			}

			_, err := elbconn.RegisterInstancesWithLoadBalancer(&registerInstancesOpts)
			if err != nil {
				return fmt.Errorf("Failure registering instances: %s", err)
			}
		}
		if len(remove) > 0 {
			deRegisterInstancesOpts := elb.DeregisterInstancesFromLoadBalancer{
				LoadBalancerName: d.Id(),
				Instances:        remove,
			}

			_, err := elbconn.DeregisterInstancesFromLoadBalancer(&deRegisterInstancesOpts)
			if err != nil {
				return fmt.Errorf("Failure deregistering instances: %s", err)
			}
		}

		d.SetPartial("instances")
	}

	log.Println("[INFO] outside modify attributes")
	if d.HasChange("cross_zone_load_balancing") {
		log.Println("[INFO] inside modify attributes")
		attrs := elb.ModifyLoadBalancerAttributes{
			LoadBalancerName: d.Get("name").(string),
			LoadBalancerAttributes: elb.LoadBalancerAttributes{
				CrossZoneLoadBalancingEnabled: d.Get("cross_zone_load_balancing").(bool),
			},
		}
		_, err := elbconn.ModifyLoadBalancerAttributes(&attrs)
		if err != nil {
			return fmt.Errorf("Failure configuring health check: %s", err)
		}
		d.SetPartial("cross_zone_load_balancing")
	}

	d.Partial(false)
	return resourceAwsElbRead(d, meta)
}

func resourceAwsElbDelete(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	log.Printf("[INFO] Deleting ELB: %s", d.Id())

	// Destroy the load balancer
	deleteElbOpts := elb.DeleteLoadBalancer{
		LoadBalancerName: d.Id(),
	}
	if _, err := elbconn.DeleteLoadBalancer(&deleteElbOpts); err != nil {
		return fmt.Errorf("Error deleting ELB: %s", err)
	}

	return nil
}

func resourceAwsElbHealthCheckHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	buf.WriteString(fmt.Sprintf("%d-", m["healthy_threshold"].(int)))
	buf.WriteString(fmt.Sprintf("%d-", m["unhealthy_threshold"].(int)))
	buf.WriteString(fmt.Sprintf("%s-", m["target"].(string)))
	buf.WriteString(fmt.Sprintf("%d-", m["interval"].(int)))
	buf.WriteString(fmt.Sprintf("%d-", m["timeout"].(int)))

	return hashcode.String(buf.String())
}

func resourceAwsElbListenerHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	buf.WriteString(fmt.Sprintf("%d-", m["instance_port"].(int)))
	buf.WriteString(fmt.Sprintf("%s-", m["instance_protocol"].(string)))
	buf.WriteString(fmt.Sprintf("%d-", m["lb_port"].(int)))
	buf.WriteString(fmt.Sprintf("%s-", m["lb_protocol"].(string)))

	if v, ok := m["ssl_certificate_id"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}

	return hashcode.String(buf.String())
}
<|endoftext|>


<commit_before>package cables_test

import (
	"fmt"
	"time"

	"gitlab.com/gomidi/midi"
	"gitlab.com/gomidi/midi/reader"

	// replace with e.g. "gitlab.com/gomidi/rtmididrv" for real midi connections
	driver "gitlab.com/gomidi/midi/testdrv"
	"gitlab.com/gomidi/midi/writer"
)

// This example reads from the first input and and writes to the first output port
func Example() {
	// you would take a real driver here e.g. rtmididrv.New()
	drv := driver.New("fake cables: messages written to output port 0 are received on input port 0")

	// make sure to close all open ports at the end
	defer drv.Close()

	ins, err := drv.Ins()
	must(err)

	outs, err := drv.Outs()
	must(err)

	in, out := ins[0], outs[0]

	must(in.Open())
	must(out.Open())

	defer in.Close()
	defer out.Close()

	// the writer we are writing to
	wr := writer.New(out)

	// to disable logging, pass mid.NoLogger() as option
	rd := reader.New(
		reader.NoLogger(),
		// write every message to the out port
		reader.Each(func(pos *reader.Position, msg midi.Message) {
			fmt.Printf("got %s\n", msg)
		}),
	)

	// listen for MIDI
	err = rd.ListenTo(in)
	must(err)

	err = writer.NoteOn(wr, 60, 100)
	must(err)

	time.Sleep(1)
	err = writer.NoteOff(wr, 60)

	must(err)
	// Output: got channel.NoteOn channel 0 key 60 velocity 100
	// got channel.NoteOff channel 0 key 60
}

func must(err error) {
	if err != nil {
		panic(err.Error())
	}
}
<commit_msg>fix cables example<commit_after>package cables_test

import (
	"fmt"
	"time"

	"gitlab.com/gomidi/midi"
	"gitlab.com/gomidi/midi/reader"

	// replace with e.g. "gitlab.com/gomidi/rtmididrv" for real midi connections
	driver "gitlab.com/gomidi/midi/testdrv"
	"gitlab.com/gomidi/midi/writer"
)

// This example reads from the first input and and writes to the first output port
func Example() {
	// you would take a real driver here e.g. rtmididrv.New()
	drv := driver.New("fake cables: messages written to output port 0 are received on input port 0")

	// make sure to close all open ports at the end
	defer drv.Close()

	ins, err := drv.Ins()
	must(err)

	outs, err := drv.Outs()
	must(err)

	in, out := ins[0], outs[0]

	must(in.Open())
	must(out.Open())

	defer in.Close()
	defer out.Close()

	// the writer we are writing to
	wr := writer.New(out)

	// to disable logging, pass mid.NoLogger() as option
	rd := reader.New(
		reader.NoLogger(),
		// write every message to the out port
		reader.Each(func(pos *reader.Position, msg midi.Message) {
			fmt.Printf("got %s\n", msg)
		}),
	)

	// listen for MIDI
	err = rd.ListenTo(in)
	must(err)

	err = writer.NoteOn(wr, 60, 100)
	must(err)

	time.Sleep(100 * time.Millisecond)
	err = writer.NoteOff(wr, 60)

	must(err)
	// Output: got channel.NoteOn channel 0 key 60 velocity 100
	// got channel.NoteOff channel 0 key 60
}

func must(err error) {
	if err != nil {
		panic(err.Error())
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Cisco and/or its affiliates.
//
// 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 cassandra_lib

import (
	"errors"
	"fmt"
	"net"
	"os"

	"github.com/gocql/gocql"
	"github.com/ligato/cn-infra/config"
	"github.com/ligato/cn-infra/db/sql"
	"github.com/ligato/cn-infra/db/sql/cassandra"
	"github.com/willfaught/gockle"
)

// UserTable global variable reused when building queries/statements
var UserTable = &User{}

// User is simple structure used in automated tests
type User struct {
	ID        gocql.UUID `cql:"userid" pk:"userid"`
	FirstName string     `cql:"first_name"`
	LastName  string     `cql:"last_name"`
	//NetIP      net.IP //mapped to native cassandra type
	WrapIP *Wrapper01 //used for custom (un)marshalling
	Udt03  *Udt03
	Udt04  Udt04
	UdtCol []Udt03
}

// SchemaName demo schema name
func (entity *User) SchemaName() string {
	return "demo"
}

func main() {
	cfg, err := loadConfig()
	if err != nil {
		fmt.Println(fmt.Errorf("Failed to load configuration %v", err))
		os.Exit(1)
	}

	clientCfg, err := cassandra.ConfigToClientConfig(&cfg)
	if err != nil {
		fmt.Println(fmt.Errorf("Failed to load configuration %v", err))
		os.Exit(1)
	}

	session, err := cassandra.CreateSessionFromConfig(clientCfg)
	defer session.Close()
	if err != nil {
		fmt.Println(fmt.Errorf("Failed to create session %v", err))
		os.Exit(1)
	}

	err = exampleKeyspace(session)
	if err != nil {
		fmt.Println(fmt.Errorf("Error in creating keyspace %v", err))
		os.Exit(1)
	}

	err = example(session)
	if err != nil {
		fmt.Println(fmt.Errorf("Error in executing DML/DDL statements %v", err))
		os.Exit(1)
	}
}

func loadConfig() (cassandra.Config, error) {
	var cfg cassandra.Config
	if len(os.Args) < 2 {
		return cfg, errors.New("Please provide yaml configuration file path")
	}

	configFileName := os.Args[1]
	err := config.ParseConfigFromYamlFile(configFileName, &cfg)
	return cfg, err
}

func exampleKeyspace(session *gocql.Session) (err error) {
	if err := session.Query("CREATE KEYSPACE IF NOT EXISTS demo WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};").
		Exec(); err != nil {
		return err
	}

	return nil
}

func example(session *gocql.Session) (err error) {
	err = exampleDDL(session)
	if err != nil {
		return err
	}
	err = exampleDML(session)
	if err != nil {
		return err
	}

	return nil
}

func exampleDDL(session *gocql.Session) (err error) {
	if err := session.Query("CREATE KEYSPACE IF NOT EXISTS demo WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};").
		Exec(); err != nil {
		return err
	}
	if err := session.Query(`CREATE TYPE IF NOT EXISTS demo.udt03 (
		tx text,
		tx2 text)`).Exec(); err != nil {
		return err
	}
	if err := session.Query(`CREATE TYPE IF NOT EXISTS demo.udt04 (
		ahoj text,
		caf frozen<udt03>)`).Exec(); err != nil {
		return err
	}

	if err := session.Query(`CREATE TABLE IF NOT EXISTS demo.user (
			userid uuid PRIMARY KEY,
				first_name text,
				last_name text,
				Udt03 frozen<Udt03>,
				Udt04 frozen<Udt04>,
				UdtCol list<frozen<Udt03>>,
				NetIP inet,
				WrapIP text,
				emails set<text>,
				topscores list<int>,
				todo map<timestamp, text>
		);`).
		Exec(); err != nil {
		return err
	}

	if err := session.Query("CREATE INDEX IF NOT EXISTS demo_users_last_name ON demo.user (last_name);").
		Exec(); err != nil {
		return err
	}

	return nil
}

func exampleDML(session *gocql.Session) (err error) {
	_ /*ip01 */, ipPrefix01, err := net.ParseCIDR("192.168.1.2/24")
	if err != nil {
		return err
	}
	db := cassandra.NewBrokerUsingSession(gockle.NewSession(session))
	written := &User{FirstName: "Fero", LastName: "Mrkva", /*ip01, */
		WrapIP: &Wrapper01{ipPrefix01},
		Udt03:  &Udt03{Tx: "tx1", Tx2: "tx2" /*, Inet1: "201.202.203.204"*/},
		Udt04:  Udt04{"kuk", &Udt03{Tx: "txxxxxxxxx1", Tx2: "txxxxxxxxx2" /*, Inet1: "201.202.203.204"*/}},
		UdtCol: []Udt03{{Tx: "txt1Col", Tx2: "txt2Col"}},
	}
	err = db.Put(sql.Exp("userid=c37d661d-7e61-49ea-96a5-68c34e83db3a"), written)
	if err == nil {
		fmt.Println("Successfully written: ", written)
	} else {
		return err
	}

	users := &[]User{}
	err = sql.SliceIt(users, db.ListValues(sql.FROM(UserTable,
		sql.WHERE(sql.Field(&UserTable.LastName, sql.EQ("Mrkva"))))))
	if err == nil {
		fmt.Println("Successfully queried: ", users)
	} else {
		return err
	}

	return nil
}

// Wrapper01 implements gocql.Marshaller, gocql.Unmarshaller
// it uses string representation of net.IPNet
type Wrapper01 struct {
	ip *net.IPNet
}

// MarshalCQL serializes the string representation of net.IPNet
func (w *Wrapper01) MarshalCQL(info gocql.TypeInfo) ([]byte, error) {

	if w.ip == nil {
		return []byte{}, nil
	}

	return []byte(w.ip.String()), nil
}

// UnmarshalCQL deserializes the string representation of net.IPNet
func (w *Wrapper01) UnmarshalCQL(info gocql.TypeInfo, data []byte) error {

	if len(data) > 0 {
		_, ipPrefix, err := net.ParseCIDR(string(data))

		if err != nil {
			return err
		}
		w.ip = ipPrefix
	}

	return nil
}

// String delegates to the ip.String()
func (w *Wrapper01) String() string {
	if w.ip != nil {
		return w.ip.String()
	}

	return ""
}

// Udt03 is a simple User Defined Type with two string fields
type Udt03 struct {
	Tx  string `cql:"tx"`
	Tx2 string `cql:"tx2"`
	//Inet1 string
}

func (u *Udt03) String() string {
	return "{" + u.Tx + ", " + u.Tx2 /*+ ", " + u.Inet1*/ + "}"
}

// Udt04 is a nested User Defined Type
type Udt04 struct {
	Ahoj string `cql:"ahoj"`
	Caf  *Udt03 `cql:"caf"`
	//Inet1 string
}

func (u *Udt04) String() string {
	return "{" + u.Ahoj + ", " + u.Caf.String() /*+ ", " + u.Inet1*/ + "}"
}
<commit_msg>golint<commit_after>// Copyright (c) 2017 Cisco and/or its affiliates.
//
// 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 cassandralib

import (
	"errors"
	"fmt"
	"net"
	"os"

	"github.com/gocql/gocql"
	"github.com/ligato/cn-infra/config"
	"github.com/ligato/cn-infra/db/sql"
	"github.com/ligato/cn-infra/db/sql/cassandra"
	"github.com/willfaught/gockle"
)

// UserTable global variable reused when building queries/statements
var UserTable = &User{}

// User is simple structure used in automated tests
type User struct {
	ID        gocql.UUID `cql:"userid" pk:"userid"`
	FirstName string     `cql:"first_name"`
	LastName  string     `cql:"last_name"`
	//NetIP      net.IP //mapped to native cassandra type
	WrapIP *Wrapper01 //used for custom (un)marshalling
	Udt03  *Udt03
	Udt04  Udt04
	UdtCol []Udt03
}

// SchemaName demo schema name
func (entity *User) SchemaName() string {
	return "demo"
}

func main() {
	cfg, err := loadConfig()
	if err != nil {
		fmt.Println(fmt.Errorf("Failed to load configuration %v", err))
		os.Exit(1)
	}

	clientCfg, err := cassandra.ConfigToClientConfig(&cfg)
	if err != nil {
		fmt.Println(fmt.Errorf("Failed to load configuration %v", err))
		os.Exit(1)
	}

	session, err := cassandra.CreateSessionFromConfig(clientCfg)
	defer session.Close()
	if err != nil {
		fmt.Println(fmt.Errorf("Failed to create session %v", err))
		os.Exit(1)
	}

	err = exampleKeyspace(session)
	if err != nil {
		fmt.Println(fmt.Errorf("Error in creating keyspace %v", err))
		os.Exit(1)
	}

	err = example(session)
	if err != nil {
		fmt.Println(fmt.Errorf("Error in executing DML/DDL statements %v", err))
		os.Exit(1)
	}
}

func loadConfig() (cassandra.Config, error) {
	var cfg cassandra.Config
	if len(os.Args) < 2 {
		return cfg, errors.New("Please provide yaml configuration file path")
	}

	configFileName := os.Args[1]
	err := config.ParseConfigFromYamlFile(configFileName, &cfg)
	return cfg, err
}

func exampleKeyspace(session *gocql.Session) (err error) {
	if err := session.Query("CREATE KEYSPACE IF NOT EXISTS demo WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};").
		Exec(); err != nil {
		return err
	}

	return nil
}

func example(session *gocql.Session) (err error) {
	err = exampleDDL(session)
	if err != nil {
		return err
	}
	err = exampleDML(session)
	if err != nil {
		return err
	}

	return nil
}

func exampleDDL(session *gocql.Session) (err error) {
	if err := session.Query("CREATE KEYSPACE IF NOT EXISTS demo WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};").
		Exec(); err != nil {
		return err
	}
	if err := session.Query(`CREATE TYPE IF NOT EXISTS demo.udt03 (
		tx text,
		tx2 text)`).Exec(); err != nil {
		return err
	}
	if err := session.Query(`CREATE TYPE IF NOT EXISTS demo.udt04 (
		ahoj text,
		caf frozen<udt03>)`).Exec(); err != nil {
		return err
	}

	if err := session.Query(`CREATE TABLE IF NOT EXISTS demo.user (
			userid uuid PRIMARY KEY,
				first_name text,
				last_name text,
				Udt03 frozen<Udt03>,
				Udt04 frozen<Udt04>,
				UdtCol list<frozen<Udt03>>,
				NetIP inet,
				WrapIP text,
				emails set<text>,
				topscores list<int>,
				todo map<timestamp, text>
		);`).
		Exec(); err != nil {
		return err
	}

	if err := session.Query("CREATE INDEX IF NOT EXISTS demo_users_last_name ON demo.user (last_name);").
		Exec(); err != nil {
		return err
	}

	return nil
}

func exampleDML(session *gocql.Session) (err error) {
	_ /*ip01 */, ipPrefix01, err := net.ParseCIDR("192.168.1.2/24")
	if err != nil {
		return err
	}
	db := cassandra.NewBrokerUsingSession(gockle.NewSession(session))
	written := &User{FirstName: "Fero", LastName: "Mrkva", /*ip01, */
		WrapIP: &Wrapper01{ipPrefix01},
		Udt03:  &Udt03{Tx: "tx1", Tx2: "tx2" /*, Inet1: "201.202.203.204"*/},
		Udt04:  Udt04{"kuk", &Udt03{Tx: "txxxxxxxxx1", Tx2: "txxxxxxxxx2" /*, Inet1: "201.202.203.204"*/}},
		UdtCol: []Udt03{{Tx: "txt1Col", Tx2: "txt2Col"}},
	}
	err = db.Put(sql.Exp("userid=c37d661d-7e61-49ea-96a5-68c34e83db3a"), written)
	if err == nil {
		fmt.Println("Successfully written: ", written)
	} else {
		return err
	}

	users := &[]User{}
	err = sql.SliceIt(users, db.ListValues(sql.FROM(UserTable,
		sql.WHERE(sql.Field(&UserTable.LastName, sql.EQ("Mrkva"))))))
	if err == nil {
		fmt.Println("Successfully queried: ", users)
	} else {
		return err
	}

	return nil
}

// Wrapper01 implements gocql.Marshaller, gocql.Unmarshaller
// it uses string representation of net.IPNet
type Wrapper01 struct {
	ip *net.IPNet
}

// MarshalCQL serializes the string representation of net.IPNet
func (w *Wrapper01) MarshalCQL(info gocql.TypeInfo) ([]byte, error) {

	if w.ip == nil {
		return []byte{}, nil
	}

	return []byte(w.ip.String()), nil
}

// UnmarshalCQL deserializes the string representation of net.IPNet
func (w *Wrapper01) UnmarshalCQL(info gocql.TypeInfo, data []byte) error {

	if len(data) > 0 {
		_, ipPrefix, err := net.ParseCIDR(string(data))

		if err != nil {
			return err
		}
		w.ip = ipPrefix
	}

	return nil
}

// String delegates to the ip.String()
func (w *Wrapper01) String() string {
	if w.ip != nil {
		return w.ip.String()
	}

	return ""
}

// Udt03 is a simple User Defined Type with two string fields
type Udt03 struct {
	Tx  string `cql:"tx"`
	Tx2 string `cql:"tx2"`
	//Inet1 string
}

func (u *Udt03) String() string {
	return "{" + u.Tx + ", " + u.Tx2 /*+ ", " + u.Inet1*/ + "}"
}

// Udt04 is a nested User Defined Type
type Udt04 struct {
	Ahoj string `cql:"ahoj"`
	Caf  *Udt03 `cql:"caf"`
	//Inet1 string
}

func (u *Udt04) String() string {
	return "{" + u.Ahoj + ", " + u.Caf.String() /*+ ", " + u.Inet1*/ + "}"
}
<|endoftext|>


<commit_before>// Copyright 2021 The Ebiten 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.

//go:build aix || dragonfly || freebsd || hurd || illumos || linux || netbsd || openbsd || solaris
// +build aix dragonfly freebsd hurd illumos linux netbsd openbsd solaris

package readerdriver

import (
	"io"
	"runtime"
	"sync"
)

type players struct {
	players map[*playerImpl]struct{}
	buf     []float32
	cond    *sync.Cond
}

func newPlayers() *players {
	p := &players{
		cond: sync.NewCond(&sync.Mutex{}),
	}
	go p.loop()
	return p
}

func (ps *players) shouldWait() bool {
	for p := range ps.players {
		if p.canReadSourceToBuffer() {
			return false
		}
	}
	return true
}

func (ps *players) wait() {
	ps.cond.L.Lock()
	defer ps.cond.L.Unlock()

	for ps.shouldWait() {
		ps.cond.Wait()
	}
}

func (ps *players) loop() {
	var players []*playerImpl
	for {
		ps.wait()

		ps.cond.L.Lock()
		players = players[:0]
		for p := range ps.players {
			players = append(players, p)
		}
		ps.cond.L.Unlock()

		for _, p := range players {
			p.readSourceToBuffer()
		}
	}
}

func (ps *players) addPlayer(player *playerImpl) {
	ps.cond.L.Lock()
	defer ps.cond.L.Unlock()

	if ps.players == nil {
		ps.players = map[*playerImpl]struct{}{}
	}
	ps.players[player] = struct{}{}
	ps.cond.Signal()
}

func (ps *players) removePlayer(player *playerImpl) {
	ps.cond.L.Lock()
	defer ps.cond.L.Unlock()

	delete(ps.players, player)
	ps.cond.Signal()
}

func (ps *players) read(buf []float32) {
	ps.cond.L.Lock()
	players := make([]*playerImpl, 0, len(ps.players))
	for p := range ps.players {
		players = append(players, p)
	}
	ps.cond.L.Unlock()

	for _, p := range players {
		p.readBufferAndAdd(buf)
	}
	ps.cond.Signal()
}

type player struct {
	p *playerImpl
}

type playerImpl struct {
	context *context
	players *players
	src     io.Reader
	volume  float64
	err     error
	state   playerState
	buf     []byte
	eof     bool

	m sync.Mutex
}

func (c *context) NewPlayer(src io.Reader) Player {
	return newPlayer(c, c.players, src)
}

func newPlayer(context *context, players *players, src io.Reader) *player {
	p := &player{
		p: &playerImpl{
			context: context,
			players: players,
			src:     src,
			volume:  1,
		},
	}
	runtime.SetFinalizer(p, (*player).Close)
	return p
}

func (p *player) Err() error {
	return p.p.Err()
}

func (p *playerImpl) Err() error {
	p.m.Lock()
	defer p.m.Unlock()

	return p.err
}

func (p *player) Play() {
	p.p.Play()
}

func (p *playerImpl) Play() {
	ch := make(chan struct{})
	go func() {
		p.m.Lock()
		defer p.m.Unlock()

		close(ch)
		p.playImpl()
	}()
	<-ch
}

func (p *playerImpl) playImpl() {
	if p.err != nil {
		return
	}
	if p.state != playerPaused {
		return
	}

	if !p.eof {
		buf := make([]byte, p.context.maxBufferSize())
		for len(p.buf) < p.context.maxBufferSize() {
			n, err := p.src.Read(buf)
			if err != nil && err != io.EOF {
				p.setErrorImpl(err)
				return
			}
			p.buf = append(p.buf, buf[:n]...)
			if err == io.EOF {
				if len(p.buf) == 0 {
					p.eof = true
				}
				break
			}
		}
	}

	if !p.eof || len(p.buf) > 0 {
		p.state = playerPlay
	}

	p.m.Unlock()
	p.players.addPlayer(p)
	p.m.Lock()
}

func (p *player) Pause() {
	p.p.Pause()
}

func (p *playerImpl) Pause() {
	p.m.Lock()
	defer p.m.Unlock()

	if p.state != playerPlay {
		return
	}
	p.state = playerPaused
}

func (p *player) Reset() {
	p.p.Reset()
}

func (p *playerImpl) Reset() {
	p.m.Lock()
	defer p.m.Unlock()
	p.resetImpl()
}

func (p *playerImpl) resetImpl() {
	if p.state == playerClosed {
		return
	}
	p.state = playerPaused
	p.buf = p.buf[:0]
	p.eof = false
}

func (p *player) IsPlaying() bool {
	return p.p.IsPlaying()
}

func (p *playerImpl) IsPlaying() bool {
	p.m.Lock()
	defer p.m.Unlock()
	return p.state == playerPlay
}

func (p *player) Volume() float64 {
	return p.p.Volume()
}

func (p *playerImpl) Volume() float64 {
	p.m.Lock()
	defer p.m.Unlock()
	return p.volume
}

func (p *player) SetVolume(volume float64) {
	p.p.SetVolume(volume)
}

func (p *playerImpl) SetVolume(volume float64) {
	p.m.Lock()
	defer p.m.Unlock()
	p.volume = volume
}

func (p *player) UnplayedBufferSize() int {
	return p.p.UnplayedBufferSize()
}

func (p *playerImpl) UnplayedBufferSize() int {
	p.m.Lock()
	defer p.m.Unlock()
	return len(p.buf)
}

func (p *player) Close() error {
	runtime.SetFinalizer(p, nil)
	return p.p.Close()
}

func (p *playerImpl) Close() error {
	p.m.Lock()
	defer p.m.Unlock()
	return p.closeImpl()
}

func (p *playerImpl) closeImpl() error {
	p.m.Unlock()
	p.players.removePlayer(p)
	p.m.Lock()

	if p.state == playerClosed {
		return nil
	}
	p.state = playerClosed
	p.buf = nil
	return p.err
}

func (p *playerImpl) readBufferAndAdd(buf []float32) int {
	p.m.Lock()

	if p.state != playerPlay {
		p.m.Unlock()
		return 0
	}

	bitDepthInBytes := p.context.bitDepthInBytes
	n := len(p.buf) / bitDepthInBytes
	if n > len(buf) {
		n = len(buf)
	}
	volume := float32(p.volume)
	src := p.buf[:n*bitDepthInBytes]
	p.buf = p.buf[n*bitDepthInBytes:]
	p.m.Unlock()

	for i := 0; i < n; i++ {
		var v float32
		switch bitDepthInBytes {
		case 1:
			v8 := src[i]
			v = float32(v8-(1<<7)) / (1 << 7)
		case 2:
			v16 := int16(src[2*i]) | (int16(src[2*i+1]) << 8)
			v = float32(v16) / (1 << 15)
		}
		buf[i] += v * volume
	}
	return n
}

func (p *playerImpl) canReadSourceToBuffer() bool {
	p.m.Lock()
	defer p.m.Unlock()

	if p.eof {
		return false
	}
	return len(p.buf) < p.context.maxBufferSize()
}

func (p *playerImpl) readSourceToBuffer() {
	p.m.Lock()
	defer p.m.Unlock()

	if p.err != nil {
		return
	}
	if p.state == playerClosed {
		return
	}

	maxBufferSize := p.context.maxBufferSize()
	if len(p.buf) >= maxBufferSize {
		return
	}

	src := p.src
	p.m.Unlock()
	buf := make([]byte, maxBufferSize)
	n, err := src.Read(buf)
	p.m.Lock()

	if err != nil && err != io.EOF {
		p.setErrorImpl(err)
		return
	}

	p.buf = append(p.buf, buf[:n]...)
	if err == io.EOF && len(p.buf) == 0 {
		p.state = playerPaused
		p.eof = true
	}
}

func (p *playerImpl) setErrorImpl(err error) {
	p.err = err
	p.closeImpl()
}
<commit_msg>audio/internal/readerdriver: Bug fix: Race condition on UNIX/Linux<commit_after>// Copyright 2021 The Ebiten 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.

//go:build aix || dragonfly || freebsd || hurd || illumos || linux || netbsd || openbsd || solaris
// +build aix dragonfly freebsd hurd illumos linux netbsd openbsd solaris

package readerdriver

import (
	"io"
	"runtime"
	"sync"
)

type players struct {
	players map[*playerImpl]struct{}
	buf     []float32
	cond    *sync.Cond
}

func newPlayers() *players {
	p := &players{
		cond: sync.NewCond(&sync.Mutex{}),
	}
	go p.loop()
	return p
}

func (ps *players) shouldWait() bool {
	for p := range ps.players {
		if p.canReadSourceToBuffer() {
			return false
		}
	}
	return true
}

func (ps *players) wait() {
	ps.cond.L.Lock()
	defer ps.cond.L.Unlock()

	for ps.shouldWait() {
		ps.cond.Wait()
	}
}

func (ps *players) loop() {
	var players []*playerImpl
	for {
		ps.wait()

		ps.cond.L.Lock()
		players = players[:0]
		for p := range ps.players {
			players = append(players, p)
		}
		ps.cond.L.Unlock()

		for _, p := range players {
			p.readSourceToBuffer()
		}
	}
}

func (ps *players) addPlayer(player *playerImpl) {
	ps.cond.L.Lock()
	defer ps.cond.L.Unlock()

	if ps.players == nil {
		ps.players = map[*playerImpl]struct{}{}
	}
	ps.players[player] = struct{}{}
	ps.cond.Signal()
}

func (ps *players) removePlayer(player *playerImpl) {
	ps.cond.L.Lock()
	defer ps.cond.L.Unlock()

	delete(ps.players, player)
	ps.cond.Signal()
}

func (ps *players) read(buf []float32) {
	ps.cond.L.Lock()
	players := make([]*playerImpl, 0, len(ps.players))
	for p := range ps.players {
		players = append(players, p)
	}
	ps.cond.L.Unlock()

	for _, p := range players {
		p.readBufferAndAdd(buf)
	}
	ps.cond.Signal()
}

type player struct {
	p *playerImpl
}

type playerImpl struct {
	context *context
	players *players
	src     io.Reader
	volume  float64
	err     error
	state   playerState
	buf     []byte
	eof     bool

	m sync.Mutex
}

func (c *context) NewPlayer(src io.Reader) Player {
	return newPlayer(c, c.players, src)
}

func newPlayer(context *context, players *players, src io.Reader) *player {
	p := &player{
		p: &playerImpl{
			context: context,
			players: players,
			src:     src,
			volume:  1,
		},
	}
	runtime.SetFinalizer(p, (*player).Close)
	return p
}

func (p *player) Err() error {
	return p.p.Err()
}

func (p *playerImpl) Err() error {
	p.m.Lock()
	defer p.m.Unlock()

	return p.err
}

func (p *player) Play() {
	p.p.Play()
}

func (p *playerImpl) Play() {
	ch := make(chan struct{})
	go func() {
		p.m.Lock()
		defer p.m.Unlock()

		close(ch)
		p.playImpl()
	}()
	<-ch
}

func (p *playerImpl) playImpl() {
	if p.err != nil {
		return
	}
	if p.state != playerPaused {
		return
	}

	if !p.eof {
		buf := make([]byte, p.context.maxBufferSize())
		for len(p.buf) < p.context.maxBufferSize() {
			n, err := p.src.Read(buf)
			if err != nil && err != io.EOF {
				p.setErrorImpl(err)
				return
			}
			p.buf = append(p.buf, buf[:n]...)
			if err == io.EOF {
				if len(p.buf) == 0 {
					p.eof = true
				}
				break
			}
		}
	}

	if !p.eof || len(p.buf) > 0 {
		p.state = playerPlay
	}

	p.m.Unlock()
	p.players.addPlayer(p)
	p.m.Lock()
}

func (p *player) Pause() {
	p.p.Pause()
}

func (p *playerImpl) Pause() {
	p.m.Lock()
	defer p.m.Unlock()

	if p.state != playerPlay {
		return
	}
	p.state = playerPaused
}

func (p *player) Reset() {
	p.p.Reset()
}

func (p *playerImpl) Reset() {
	p.m.Lock()
	defer p.m.Unlock()
	p.resetImpl()
}

func (p *playerImpl) resetImpl() {
	if p.state == playerClosed {
		return
	}
	p.state = playerPaused
	p.buf = p.buf[:0]
	p.eof = false
}

func (p *player) IsPlaying() bool {
	return p.p.IsPlaying()
}

func (p *playerImpl) IsPlaying() bool {
	p.m.Lock()
	defer p.m.Unlock()
	return p.state == playerPlay
}

func (p *player) Volume() float64 {
	return p.p.Volume()
}

func (p *playerImpl) Volume() float64 {
	p.m.Lock()
	defer p.m.Unlock()
	return p.volume
}

func (p *player) SetVolume(volume float64) {
	p.p.SetVolume(volume)
}

func (p *playerImpl) SetVolume(volume float64) {
	p.m.Lock()
	defer p.m.Unlock()
	p.volume = volume
}

func (p *player) UnplayedBufferSize() int {
	return p.p.UnplayedBufferSize()
}

func (p *playerImpl) UnplayedBufferSize() int {
	p.m.Lock()
	defer p.m.Unlock()
	return len(p.buf)
}

func (p *player) Close() error {
	runtime.SetFinalizer(p, nil)
	return p.p.Close()
}

func (p *playerImpl) Close() error {
	p.m.Lock()
	defer p.m.Unlock()
	return p.closeImpl()
}

func (p *playerImpl) closeImpl() error {
	p.m.Unlock()
	p.players.removePlayer(p)
	p.m.Lock()

	if p.state == playerClosed {
		return nil
	}
	p.state = playerClosed
	p.buf = nil
	return p.err
}

func (p *playerImpl) readBufferAndAdd(buf []float32) int {
	p.m.Lock()

	if p.state != playerPlay {
		p.m.Unlock()
		return 0
	}

	bitDepthInBytes := p.context.bitDepthInBytes
	n := len(p.buf) / bitDepthInBytes
	if n > len(buf) {
		n = len(buf)
	}
	volume := float32(p.volume)
	src := p.buf[:n*bitDepthInBytes]
	p.buf = p.buf[n*bitDepthInBytes:]
	p.m.Unlock()

	for i := 0; i < n; i++ {
		var v float32
		switch bitDepthInBytes {
		case 1:
			v8 := src[i]
			v = float32(v8-(1<<7)) / (1 << 7)
		case 2:
			v16 := int16(src[2*i]) | (int16(src[2*i+1]) << 8)
			v = float32(v16) / (1 << 15)
		}
		buf[i] += v * volume
	}
	return n
}

func (p *playerImpl) canReadSourceToBuffer() bool {
	p.m.Lock()
	defer p.m.Unlock()

	if p.eof {
		return false
	}
	return len(p.buf) < p.context.maxBufferSize()
}

func (p *playerImpl) readSourceToBuffer() {
	p.m.Lock()
	defer p.m.Unlock()

	if p.err != nil {
		return
	}
	if p.state == playerClosed {
		return
	}

	maxBufferSize := p.context.maxBufferSize()
	if len(p.buf) >= maxBufferSize {
		return
	}

	buf := make([]byte, maxBufferSize)
	n, err := p.src.Read(buf)

	if err != nil && err != io.EOF {
		p.setErrorImpl(err)
		return
	}

	p.buf = append(p.buf, buf[:n]...)
	if err == io.EOF && len(p.buf) == 0 {
		p.state = playerPaused
		p.eof = true
	}
}

func (p *playerImpl) setErrorImpl(err error) {
	p.err = err
	p.closeImpl()
}
<|endoftext|>


<commit_before>package mpdocker

import (
	"testing"

	"github.com/fsouza/go-dockerclient"
)

func TestNormalizeMetricName(t *testing.T) {
	testSets := [][]string{
		{"foo/bar", "foo_bar"},
		{"foo:bar", "foo_bar"},
	}

	for _, testSet := range testSets {
		if normalizeMetricName(testSet[0]) != testSet[1] {
			t.Errorf("normalizeMetricName: '%s' should be normalized to '%s', but '%s'", testSet[0], testSet[1], normalizeMetricName(testSet[0]))
		}
	}
}

func TestGraphDefinition(t *testing.T) {
	var docker DockerPlugin

	graphdef := docker.GraphDefinition()
	if len(graphdef) != 6 {
		t.Errorf("GraphDefinition: %d should be 6", len(graphdef))
	}
}

func TestGenerateName(t *testing.T) {
	stub := docker.APIContainers{
		ID:      "bab2b03c736de41ecba6470eba736c5109436f706eedca4f3e0d93d6530eccd4",
		Image:   "tutum/mongodb",
		Command: "/run.sh",
		Created: 1456995574,
		Status:  "Up 4 days",
		Ports: []docker.APIPort{
			{PrivatePort: 28017, Type: "tcp"},
			{PrivatePort: 27017, Type: "tcp"},
		},
		Names:  []string{"/my-mongodb"},
		Labels: map[string]string{"foo": "bar"},
	}
	/* {"Id":"5b963f266d609d2b02aee8f57d664e04d35aa8c23afcbc6bb73bc4a5b2e7c44d",
	   "Image":"memcached",
	   "Command":"/entrypoint.sh memcached",
	   "Created":1456994862,
	   "Status":"Up 4 days",
	   "Ports":[{"PrivatePort":11211,
	   "Type":"tcp"}],
	   "Names":["/my-memcache"]}]`
	*/
	var docker DockerPlugin
	docker.NameFormat = "name_id"
	if docker.generateName(stub) != "my-mongodb_bab2b0" {
		t.Errorf("generateName(name): %s should be 'my-mongodb_bab2b0'", docker.generateName(stub))
	}
	docker.NameFormat = "name"
	if docker.generateName(stub) != "my-mongodb" {
		t.Errorf("generateName(name): %s should be 'my-mongodb'", docker.generateName(stub))
	}
	docker.NameFormat = "id"
	if docker.generateName(stub) != "bab2b03c736de41ecba6470eba736c5109436f706eedca4f3e0d93d6530eccd4" {
		t.Errorf("generateName(name): %s should be 'bab2b03c736de41ecba6470eba736c5109436f706eedca4f3e0d93d6530eccd4'", docker.generateName(stub))
	}
	docker.NameFormat = "image"
	if docker.generateName(stub) != "tutum/mongodb" {
		t.Errorf("generateName(name): %s should be 'tutum/mongodb'", docker.generateName(stub))
	}
	docker.NameFormat = "image_id"
	if docker.generateName(stub) != "tutum/mongodb_bab2b0" {
		t.Errorf("generateName(name): %s should be 'tutum/mongodb_bab2b0'", docker.generateName(stub))
	}
	docker.NameFormat = "image_name"
	if docker.generateName(stub) != "tutum/mongodb_my-mongodb" {
		t.Errorf("generateName(name): %s should be 'tutum/mongodb_my-mongodb'", docker.generateName(stub))
	}
	docker.NameFormat = "label"
	docker.Label = "foo"
	if docker.generateName(stub) != "bar" {
		t.Errorf("generateName(name): %s should be 'bar'", docker.generateName(stub))
	}

}
<commit_msg>add tests for addCPUPercentageStats<commit_after>package mpdocker

import (
	"testing"

	"github.com/fsouza/go-dockerclient"
)

func TestNormalizeMetricName(t *testing.T) {
	testSets := [][]string{
		{"foo/bar", "foo_bar"},
		{"foo:bar", "foo_bar"},
	}

	for _, testSet := range testSets {
		if normalizeMetricName(testSet[0]) != testSet[1] {
			t.Errorf("normalizeMetricName: '%s' should be normalized to '%s', but '%s'", testSet[0], testSet[1], normalizeMetricName(testSet[0]))
		}
	}
}

func TestGraphDefinition(t *testing.T) {
	var docker DockerPlugin

	graphdef := docker.GraphDefinition()
	if len(graphdef) != 6 {
		t.Errorf("GraphDefinition: %d should be 6", len(graphdef))
	}
}

func TestGenerateName(t *testing.T) {
	stub := docker.APIContainers{
		ID:      "bab2b03c736de41ecba6470eba736c5109436f706eedca4f3e0d93d6530eccd4",
		Image:   "tutum/mongodb",
		Command: "/run.sh",
		Created: 1456995574,
		Status:  "Up 4 days",
		Ports: []docker.APIPort{
			{PrivatePort: 28017, Type: "tcp"},
			{PrivatePort: 27017, Type: "tcp"},
		},
		Names:  []string{"/my-mongodb"},
		Labels: map[string]string{"foo": "bar"},
	}
	/* {"Id":"5b963f266d609d2b02aee8f57d664e04d35aa8c23afcbc6bb73bc4a5b2e7c44d",
	   "Image":"memcached",
	   "Command":"/entrypoint.sh memcached",
	   "Created":1456994862,
	   "Status":"Up 4 days",
	   "Ports":[{"PrivatePort":11211,
	   "Type":"tcp"}],
	   "Names":["/my-memcache"]}]`
	*/
	var docker DockerPlugin
	docker.NameFormat = "name_id"
	if docker.generateName(stub) != "my-mongodb_bab2b0" {
		t.Errorf("generateName(name): %s should be 'my-mongodb_bab2b0'", docker.generateName(stub))
	}
	docker.NameFormat = "name"
	if docker.generateName(stub) != "my-mongodb" {
		t.Errorf("generateName(name): %s should be 'my-mongodb'", docker.generateName(stub))
	}
	docker.NameFormat = "id"
	if docker.generateName(stub) != "bab2b03c736de41ecba6470eba736c5109436f706eedca4f3e0d93d6530eccd4" {
		t.Errorf("generateName(name): %s should be 'bab2b03c736de41ecba6470eba736c5109436f706eedca4f3e0d93d6530eccd4'", docker.generateName(stub))
	}
	docker.NameFormat = "image"
	if docker.generateName(stub) != "tutum/mongodb" {
		t.Errorf("generateName(name): %s should be 'tutum/mongodb'", docker.generateName(stub))
	}
	docker.NameFormat = "image_id"
	if docker.generateName(stub) != "tutum/mongodb_bab2b0" {
		t.Errorf("generateName(name): %s should be 'tutum/mongodb_bab2b0'", docker.generateName(stub))
	}
	docker.NameFormat = "image_name"
	if docker.generateName(stub) != "tutum/mongodb_my-mongodb" {
		t.Errorf("generateName(name): %s should be 'tutum/mongodb_my-mongodb'", docker.generateName(stub))
	}
	docker.NameFormat = "label"
	docker.Label = "foo"
	if docker.generateName(stub) != "bar" {
		t.Errorf("generateName(name): %s should be 'bar'", docker.generateName(stub))
	}

}

func TestAddCPUPercentageStats(t *testing.T) {
	stats := map[string]interface{}{
		"docker.cpuacct.containerA._host":  uint64(100000),
		"docker.cpuacct.containerA.user":   uint64(3000),
		"docker.cpuacct.containerA.system": uint64(2000),
		"docker.cpuacct.containerB._host":  uint64(100000),
		"docker.cpuacct.containerB.user":   uint64(3500),
		"docker.cpuacct.containerC.user":   uint64(3300),
		"docker.cpuacct.containerC.system": uint64(2300),
		"docker.cpuacct.containerD._host":  uint64(100000),
		"docker.cpuacct.containerD.user":   uint64(3000),
		"docker.cpuacct.containerD.system": uint64(2000),
	}
	oldStats := map[string]interface{}{
		"docker.cpuacct.containerA._host":  float64(90000),
		"docker.cpuacct.containerA.user":   float64(1000),
		"docker.cpuacct.containerA.system": float64(1500),
		"docker.cpuacct.containerB._host":  float64(90000),
		"docker.cpuacct.containerB.user":   float64(3000),
		"docker.cpuacct.containerC.user":   float64(3000),
		"docker.cpuacct.containerC.system": float64(2000),
		"docker.cpuacct.containerE._host":  float64(100000),
		"docker.cpuacct.containerE.user":   float64(3000),
		"docker.cpuacct.containerE.system": float64(2000),
	}
	addCPUPercentageStats(&stats, oldStats)

	if stat, ok := stats["docker.cpuacct_percentage.containerA.user"]; !ok {
		t.Errorf("docker.cpuacct_percentage.containerA.user should be calculated")
	} else if stat != float64(20.0) {
		t.Errorf("docker.cpuacct_percentage.containerA.user should be %s, but %s", stat, float64(20.0))
	}

	if _, ok := stats["docker.cpuacct_percentage.containerC.user"]; ok {
		t.Errorf("docker.cpuacct_percentage.containerC.user should not be calculated")
	}

	if _, ok := stats["docker.cpuacct_percentage.containerD.user"]; ok {
		t.Errorf("docker.cpuacct_percentage.containerD.user should not be calculated")
	}

	if _, ok := stats["docker.cpuacct_percentage.containerE.user"]; ok {
		t.Errorf("docker.cpuacct_percentage.containerE.user should not be calculated")
	}
}
<|endoftext|>


<commit_before>package chunk

import (
	"bytes"
	"context"
	"io"
	"testing"

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

func Write(t *testing.T, chunks *Storage, n int) ([]*DataRef, []byte) {
	var finalDataRefs []*DataRef
	var seq []byte
	t.Run("Write", func(t *testing.T) {
		w := chunks.NewWriter(context.Background())
		cb := func(dataRefs []*DataRef) error {
			finalDataRefs = append(finalDataRefs, dataRefs...)
			return nil
		}
		seq = RandSeq(n * MB)
		for i := 0; i < n; i++ {
			w.StartRange(cb)
			_, err := w.Write(seq[i*MB : (i+1)*MB])
			require.NoError(t, err)
		}
		require.NoError(t, w.Close())
	})
	return finalDataRefs, seq
}

func TestWriteThenRead(t *testing.T) {
	objC, chunks := LocalStorage(t)
	defer Cleanup(objC, chunks)
	finalDataRefs, seq := Write(t, chunks, 100)
	mid := len(finalDataRefs) / 2
	initialRefs := finalDataRefs[:mid]
	streamRefs := finalDataRefs[mid:]
	r := chunks.NewReader(context.Background(), initialRefs...)
	buf := &bytes.Buffer{}
	t.Run("ReadInitial", func(t *testing.T) {
		_, err := io.Copy(buf, r)
		require.NoError(t, err)
		require.Equal(t, bytes.Compare(buf.Bytes(), seq[:buf.Len()]), 0)
	})
	seq = seq[buf.Len():]
	buf.Reset()
	t.Run("ReadStream", func(t *testing.T) {
		for _, ref := range streamRefs {
			r.NextRange([]*DataRef{ref})
			_, err := io.Copy(buf, r)
			require.NoError(t, err)
		}
		require.Equal(t, bytes.Compare(buf.Bytes(), seq), 0)
	})
}

func BenchmarkWriter(b *testing.B) {
	objC, chunks := LocalStorage(b)
	defer Cleanup(objC, chunks)
	seq := RandSeq(100 * MB)
	b.SetBytes(100 * MB)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		w := chunks.NewWriter(context.Background())
		cb := func(dataRefs []*DataRef) error { return nil }
		for i := 0; i < 100; i++ {
			w.StartRange(cb)
			_, err := w.Write(seq[i*MB : (i+1)*MB])
			require.NoError(b, err)
		}
		require.NoError(b, w.Close())
	}
}

func TestCopyN(t *testing.T) {
	objC, chunks := LocalStorage(t)
	defer Cleanup(objC, chunks)
	// Write the initial data and count the chunks.
	dataRefs1, seq1 := Write(t, chunks, 50)
	dataRefs2, seq2 := Write(t, chunks, 50)
	var initialChunkCount int64
	require.NoError(t, chunks.List(context.Background(), func(_ string) error {
		initialChunkCount++
		return nil
	}))
	// Copy data from readers into new writer.
	w := chunks.NewWriter(context.Background())
	r1 := chunks.NewReader(context.Background(), dataRefs1...)
	r2 := chunks.NewReader(context.Background(), dataRefs2...)
	var finalDataRefs []*DataRef
	cb := func(dataRefs []*DataRef) error {
		finalDataRefs = append(finalDataRefs, dataRefs...)
		return nil
	}
	w.StartRange(cb)
	mid := r1.Len() / 2
	require.NoError(t, CopyN(w, r1, r1.Len()-mid))
	require.NoError(t, CopyN(w, r1, mid))
	mid = r2.Len() / 2
	require.NoError(t, CopyN(w, r2, r2.Len()-mid))
	require.NoError(t, CopyN(w, r2, mid))
	require.NoError(t, w.Close())
	// Check that the initial data equals the final data.
	buf := &bytes.Buffer{}
	finalR := chunks.NewReader(context.Background(), finalDataRefs...)
	_, err := io.Copy(buf, finalR)
	require.NoError(t, err)
	require.Equal(t, append(seq1, seq2...), buf.Bytes())
	// Only one extra chunk should get created when connecting the two sets of data.
	var finalChunkCount int64
	require.NoError(t, chunks.List(context.Background(), func(_ string) error {
		finalChunkCount++
		return nil
	}))
	require.Equal(t, initialChunkCount+1, finalChunkCount)
}
<commit_msg>Add rangeSize for Write utility in test<commit_after>package chunk

import (
	"bytes"
	"context"
	"io"
	"testing"

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

func Write(t *testing.T, chunks *Storage, n, rangeSize int) ([]*DataRef, []byte) {
	var finalDataRefs []*DataRef
	var seq []byte
	t.Run("Write", func(t *testing.T) {
		w := chunks.NewWriter(context.Background())
		cb := func(dataRefs []*DataRef) error {
			finalDataRefs = append(finalDataRefs, dataRefs...)
			return nil
		}
		seq = RandSeq(n * MB)
		for i := 0; i < n/rangeSize; i++ {
			w.StartRange(cb)
			_, err := w.Write(seq[i*MB*rangeSize : (i+1)*MB*rangeSize])
			require.NoError(t, err)
		}
		require.NoError(t, w.Close())
	})
	return finalDataRefs, seq
}

func TestWriteThenRead(t *testing.T) {
	objC, chunks := LocalStorage(t)
	defer Cleanup(objC, chunks)
	finalDataRefs, seq := Write(t, chunks, 100, 1)
	mid := len(finalDataRefs) / 2
	initialRefs := finalDataRefs[:mid]
	streamRefs := finalDataRefs[mid:]
	r := chunks.NewReader(context.Background(), initialRefs...)
	buf := &bytes.Buffer{}
	t.Run("ReadInitial", func(t *testing.T) {
		_, err := io.Copy(buf, r)
		require.NoError(t, err)
		require.Equal(t, bytes.Compare(buf.Bytes(), seq[:buf.Len()]), 0)
	})
	seq = seq[buf.Len():]
	buf.Reset()
	t.Run("ReadStream", func(t *testing.T) {
		for _, ref := range streamRefs {
			r.NextRange([]*DataRef{ref})
			_, err := io.Copy(buf, r)
			require.NoError(t, err)
		}
		require.Equal(t, bytes.Compare(buf.Bytes(), seq), 0)
	})
}

func BenchmarkWriter(b *testing.B) {
	objC, chunks := LocalStorage(b)
	defer Cleanup(objC, chunks)
	seq := RandSeq(100 * MB)
	b.SetBytes(100 * MB)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		w := chunks.NewWriter(context.Background())
		cb := func(dataRefs []*DataRef) error { return nil }
		for i := 0; i < 100; i++ {
			w.StartRange(cb)
			_, err := w.Write(seq[i*MB : (i+1)*MB])
			require.NoError(b, err)
		}
		require.NoError(b, w.Close())
	}
}

func TestCopyN(t *testing.T) {
	objC, chunks := LocalStorage(t)
	defer Cleanup(objC, chunks)
	// Write the initial data and count the chunks.
	dataRefs1, seq1 := Write(t, chunks, 60, 20)
	dataRefs2, seq2 := Write(t, chunks, 60, 20)
	var initialChunkCount int64
	require.NoError(t, chunks.List(context.Background(), func(_ string) error {
		initialChunkCount++
		return nil
	}))
	// Copy data from readers into new writer.
	w := chunks.NewWriter(context.Background())
	r1 := chunks.NewReader(context.Background(), dataRefs1...)
	r2 := chunks.NewReader(context.Background(), dataRefs2...)
	var finalDataRefs []*DataRef
	cb := func(dataRefs []*DataRef) error {
		finalDataRefs = append(finalDataRefs, dataRefs...)
		return nil
	}
	w.StartRange(cb)
	mid := r1.Len() / 2
	require.NoError(t, CopyN(w, r1, r1.Len()-mid))
	require.NoError(t, CopyN(w, r1, mid))
	mid = r2.Len() / 2
	require.NoError(t, CopyN(w, r2, r2.Len()-mid))
	require.NoError(t, CopyN(w, r2, mid))
	require.NoError(t, w.Close())
	// Check that the initial data equals the final data.
	buf := &bytes.Buffer{}
	finalR := chunks.NewReader(context.Background(), finalDataRefs...)
	_, err := io.Copy(buf, finalR)
	require.NoError(t, err)
	require.Equal(t, append(seq1, seq2...), buf.Bytes())
	// Only one extra chunk should get created when connecting the two sets of data.
	var finalChunkCount int64
	require.NoError(t, chunks.List(context.Background(), func(_ string) error {
		finalChunkCount++
		return nil
	}))
	require.Equal(t, initialChunkCount+1, finalChunkCount)
}
<|endoftext|>


<commit_before>package exchangerates

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/OpenBazaar/openbazaar-go/bitcoin/exchange"
	"golang.org/x/net/proxy"
	"net"
	"net/http"
	"strconv"
	"sync"
	"time"
)

type ExchangeRateProvider struct {
	fetchUrl        string
	cache           map[string]float64
	client          *http.Client
	decoder         ExchangeRateDecoder
	bitcoinProvider *exchange.BitcoinPriceFetcher
}

type ExchangeRateDecoder interface {
	decode(dat interface{}, cache map[string]float64, bp *exchange.BitcoinPriceFetcher) (err error)
}

type KrakenDecoder struct{}

type BitcoinCashPriceFetcher struct {
	sync.Mutex
	cache     map[string]float64
	providers []*ExchangeRateProvider
}

func NewBitcoinCashPriceFetcher(dialer proxy.Dialer) *BitcoinCashPriceFetcher {
	bp := exchange.NewBitcoinPriceFetcher(dialer)
	b := BitcoinCashPriceFetcher{
		cache: make(map[string]float64),
	}
	dial := net.Dial
	if dialer != nil {
		dial = dialer.Dial
	}
	tbTransport := &http.Transport{Dial: dial}
	client := &http.Client{Transport: tbTransport, Timeout: time.Minute}

	b.providers = []*ExchangeRateProvider{
		{"https://api.kraken.com/0/public/Ticker?pair=BCHXBT", b.cache, client, KrakenDecoder{}, bp},
	}
	go b.run()
	return &b
}

func (b *BitcoinCashPriceFetcher) GetExchangeRate(currencyCode string) (float64, error) {
	b.Lock()
	defer b.Unlock()
	price, ok := b.cache[currencyCode]
	if !ok {
		return 0, errors.New("Currency not tracked")
	}
	return price, nil
}

func (b *BitcoinCashPriceFetcher) GetLatestRate(currencyCode string) (float64, error) {
	b.fetchCurrentRates()
	b.Lock()
	defer b.Unlock()
	price, ok := b.cache[currencyCode]
	if !ok {
		return 0, errors.New("Currency not tracked")
	}
	return price, nil
}

func (b *BitcoinCashPriceFetcher) GetAllRates() (map[string]float64, error) {
	b.Lock()
	defer b.Unlock()
	return b.cache, nil
}

func (b *BitcoinCashPriceFetcher) UnitsPerCoin() int {
	return exchange.SatoshiPerBTC
}

func (b *BitcoinCashPriceFetcher) fetchCurrentRates() error {
	b.Lock()
	defer b.Unlock()
	for _, provider := range b.providers {
		err := provider.fetch()
		if err == nil {
			return nil
		}
		fmt.Println(err)
	}
	return errors.New("All exchange rate API queries failed")
}

func (b *BitcoinCashPriceFetcher) run() {
	b.fetchCurrentRates()
	ticker := time.NewTicker(time.Minute * 15)
	for range ticker.C {
		b.fetchCurrentRates()
	}
}

func (provider *ExchangeRateProvider) fetch() (err error) {
	if len(provider.fetchUrl) == 0 {
		err = errors.New("Provider has no fetchUrl")
		return err
	}
	resp, err := provider.client.Get(provider.fetchUrl)
	if err != nil {
		return err
	}
	decoder := json.NewDecoder(resp.Body)
	var dataMap interface{}
	err = decoder.Decode(&dataMap)
	if err != nil {
		return err
	}
	return provider.decoder.decode(dataMap, provider.cache, provider.bitcoinProvider)
}

func (b KrakenDecoder) decode(dat interface{}, cache map[string]float64, bp *exchange.BitcoinPriceFetcher) (err error) {
	rates, err := bp.GetAllRates()
	if err != nil {
		return err
	}
	obj, ok := dat.(map[string]interface{})
	if !ok {
		return errors.New("KrackenDecoder type assertion failure")
	}
	result, ok := obj["result"]
	if !ok {
		return errors.New("KrakenDecoder: field `result` not found")
	}
	resultMap, ok := result.(map[string]interface{})
	if !ok {
		return errors.New("KrackenDecoder type assertion failure")
	}
	pair, ok := resultMap["BCHXBT"]
	if !ok {
		return errors.New("KrakenDecoder: field `BCHXBT` not found")
	}
	pairMap, ok := pair.(map[string]interface{})
	if !ok {
		return errors.New("KrackenDecoder type assertion failure")
	}
	c, ok := pairMap["c"]
	if !ok {
		return errors.New("KrakenDecoder: field `c` not found")
	}
	cList, ok := c.([]interface{})
	if !ok {
		return errors.New("KrackenDecoder type assertion failure")
	}
	rateStr, ok := cList[0].(string)
	if !ok {
		return errors.New("KrackenDecoder type assertion failure")
	}
	price, err := strconv.ParseFloat(rateStr, 64)
	if err != nil {
		return err
	}
	rate := price

	if rate == 0 {
		return errors.New("Bitcoin-BitcoinCash price data not available")
	}
	for k, v := range rates {
		cache[k] = v * rate
	}
	return nil
}
<commit_msg>Add additional exchange rate providers<commit_after>package exchangerates

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/OpenBazaar/openbazaar-go/bitcoin/exchange"
	"golang.org/x/net/proxy"
	"net"
	"net/http"
	"strconv"
	"sync"
	"time"
	"reflect"
)

type ExchangeRateProvider struct {
	fetchUrl        string
	cache           map[string]float64
	client          *http.Client
	decoder         ExchangeRateDecoder
	bitcoinProvider *exchange.BitcoinPriceFetcher
}

type ExchangeRateDecoder interface {
	decode(dat interface{}, cache map[string]float64, bp *exchange.BitcoinPriceFetcher) (err error)
}

type KrakenDecoder struct{}
type BitfinexDecoder struct{}
type BittrexDecoder struct{}
type PoloniexDecoder struct{}

type BitcoinCashPriceFetcher struct {
	sync.Mutex
	cache     map[string]float64
	providers []*ExchangeRateProvider
}

func NewBitcoinCashPriceFetcher(dialer proxy.Dialer) *BitcoinCashPriceFetcher {
	bp := exchange.NewBitcoinPriceFetcher(dialer)
	b := BitcoinCashPriceFetcher{
		cache: make(map[string]float64),
	}
	dial := net.Dial
	if dialer != nil {
		dial = dialer.Dial
	}
	tbTransport := &http.Transport{Dial: dial}
	client := &http.Client{Transport: tbTransport, Timeout: time.Minute}

	b.providers = []*ExchangeRateProvider{
		{"https://api.kraken.com/0/public/Ticker?pair=BCHXBT", b.cache, client, KrakenDecoder{}, bp},
		{"https://api.bitfinex.com/v1/pubticker/bchbtc", b.cache, client, BitfinexDecoder{}, bp},
		{"https://bittrex.com/api/v1.1/public/getticker?market=btc-bcc", b.cache, client, BittrexDecoder{}, bp},
		{"https://poloniex.com/public?command=returnTicker", b.cache, client, PoloniexDecoder{}, bp},
	}
	go b.run()
	return &b
}

func (b *BitcoinCashPriceFetcher) GetExchangeRate(currencyCode string) (float64, error) {
	b.Lock()
	defer b.Unlock()
	price, ok := b.cache[currencyCode]
	if !ok {
		return 0, errors.New("Currency not tracked")
	}
	return price, nil
}

func (b *BitcoinCashPriceFetcher) GetLatestRate(currencyCode string) (float64, error) {
	b.fetchCurrentRates()
	b.Lock()
	defer b.Unlock()
	price, ok := b.cache[currencyCode]
	if !ok {
		return 0, errors.New("Currency not tracked")
	}
	return price, nil
}

func (b *BitcoinCashPriceFetcher) GetAllRates() (map[string]float64, error) {
	b.Lock()
	defer b.Unlock()
	return b.cache, nil
}

func (b *BitcoinCashPriceFetcher) UnitsPerCoin() int {
	return exchange.SatoshiPerBTC
}

func (b *BitcoinCashPriceFetcher) fetchCurrentRates() error {
	b.Lock()
	defer b.Unlock()
	for _, provider := range b.providers {
		err := provider.fetch()
		if err == nil {
			return nil
		}
		fmt.Println(err)
	}
	return errors.New("All exchange rate API queries failed")
}

func (b *BitcoinCashPriceFetcher) run() {
	b.fetchCurrentRates()
	ticker := time.NewTicker(time.Minute * 15)
	for range ticker.C {
		b.fetchCurrentRates()
	}
}

func (provider *ExchangeRateProvider) fetch() (err error) {
	if len(provider.fetchUrl) == 0 {
		err = errors.New("Provider has no fetchUrl")
		return err
	}
	resp, err := provider.client.Get(provider.fetchUrl)
	if err != nil {
		return err
	}
	decoder := json.NewDecoder(resp.Body)
	var dataMap interface{}
	err = decoder.Decode(&dataMap)
	if err != nil {
		return err
	}
	return provider.decoder.decode(dataMap, provider.cache, provider.bitcoinProvider)
}

func (b KrakenDecoder) decode(dat interface{}, cache map[string]float64, bp *exchange.BitcoinPriceFetcher) (err error) {
	rates, err := bp.GetAllRates()
	if err != nil {
		return err
	}
	obj, ok := dat.(map[string]interface{})
	if !ok {
		return errors.New("KrackenDecoder type assertion failure")
	}
	result, ok := obj["result"]
	if !ok {
		return errors.New("KrakenDecoder: field `result` not found")
	}
	resultMap, ok := result.(map[string]interface{})
	if !ok {
		return errors.New("KrackenDecoder type assertion failure")
	}
	pair, ok := resultMap["BCHXBT"]
	if !ok {
		return errors.New("KrakenDecoder: field `BCHXBT` not found")
	}
	pairMap, ok := pair.(map[string]interface{})
	if !ok {
		return errors.New("KrackenDecoder type assertion failure")
	}
	c, ok := pairMap["c"]
	if !ok {
		return errors.New("KrakenDecoder: field `c` not found")
	}
	cList, ok := c.([]interface{})
	if !ok {
		return errors.New("KrackenDecoder type assertion failure")
	}
	rateStr, ok := cList[0].(string)
	if !ok {
		return errors.New("KrackenDecoder type assertion failure")
	}
	price, err := strconv.ParseFloat(rateStr, 64)
	if err != nil {
		return err
	}
	rate := price

	if rate == 0 {
		return errors.New("Bitcoin-BitcoinCash price data not available")
	}
	for k, v := range rates {
		cache[k] = v * rate
	}
	return nil
}

func (b BitfinexDecoder) decode(dat interface{}, cache map[string]float64, bp *exchange.BitcoinPriceFetcher) (err error) {
	rates, err := bp.GetAllRates()
	if err != nil {
		return err
	}
	obj, ok := dat.(map[string]interface{})
	if !ok {
		return errors.New("BitfinexDecoder type assertion failure")
	}
	r, ok := obj["last_price"]
	if !ok {
		return errors.New("BitfinexDecoder: field `last_price` not found")
	}
	rateStr, ok := r.(string)
	if !ok {
		return errors.New("BitfinexDecoder type assertion failure")
	}
	price, err := strconv.ParseFloat(rateStr, 64)
	if err != nil {
		return err
	}
	rate := price

	if rate == 0 {
		return errors.New("Bitcoin-BitcoinCash price data not available")
	}
	for k, v := range rates {
		cache[k] = v * rate
	}
	return nil
}

func (b BittrexDecoder) decode(dat interface{}, cache map[string]float64, bp *exchange.BitcoinPriceFetcher) (err error) {
	rates, err := bp.GetAllRates()
	if err != nil {
		return err
	}
	obj, ok := dat.(map[string]interface{})
	if !ok {
		return errors.New("BittrexDecoder type assertion failure")
	}
	result, ok := obj["result"]
	if !ok {
		return errors.New("BittrexDecoder: field `result` not found")
	}
	resultMap, ok := result.(map[string]interface{})
	if !ok {
		return errors.New("BittrexDecoder type assertion failure")
	}
	exRate, ok := resultMap["Last"]
	if !ok {
		return errors.New("BittrexDecoder: field `Last` not found")
	}
	rate, ok := exRate.(float64)
	if !ok {
		return errors.New("BittrexDecoder type assertion failure")
	}

	if rate == 0 {
		return errors.New("Bitcoin-BitcoinCash price data not available")
	}
	for k, v := range rates {
		cache[k] = v * rate
	}
	return nil
}

func (b PoloniexDecoder) decode(dat interface{}, cache map[string]float64, bp *exchange.BitcoinPriceFetcher) (err error) {
	rates, err := bp.GetAllRates()
	if err != nil {
		return err
	}
	data := dat.(map[string]interface{})
	var rate float64
	for k, v := range data {
		if k == "BTC_BCH" {
			val, ok := v.(map[string]interface{})
			if !ok {
				return errors.New(reflect.TypeOf(b).Name() + ".decode: Type assertion failed")
			}
			s, ok := val["last"].(string)
			if !ok {
				return errors.New(reflect.TypeOf(b).Name() + ".decode: Type assertion failed, missing 'last' (string) field")
			}
			price, err := strconv.ParseFloat(s, 64)
			if err != nil {
				return err
			}
			rate = price
		}
	}
	if rate == 0 {
		return errors.New("Bitcoin-BitcoinCash price data not available")
	}
	for k, v := range rates {
		cache[k] = v * rate
	}
	return nil
}<|endoftext|>