<commit_before>package config

import (
	"../step"
	"../util"
	"bufio"
	"fmt"
	"time"
)

func GetOdroidStepList(w *bufio.Writer, c *step.StepConfig) *step.StepList {
	// Initialize steps
	stEnterUboot := &step.Step{
		Trigger: "ModeKey Check...",
		OnTrigger: func() {
			util.MustSendCmd(w, "\n", true)
		},
		Expect:  "Exynos4412 #",
		Msg:     "Enter u-boot console",
		Timeout: 10 * time.Second,
	}

	stStartEthernet := &step.Step{
		OnTrigger: func() {
			// Double \n -> uboot bug
			util.MustSendCmd(w, "usb start", true)
		},
		Expect:    "1 Ethernet Device(s) found",
		Msg:       "USB Ethernet start",
		SendProbe: true,
	}

	stSetEnv := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "setenv ethact sms0;setenv ipaddr "+c.IpAddr, false)
			util.MustSendCmd(w, "setenv netmask 255.255.255.0;setenv serverip "+c.ServerAddr, false)
			util.MustSendCmd(w, "setenv ethaddr "+c.MacAddr+";printenv ipaddr", true)
		},
		Expect:    "ipaddr=" + c.IpAddr,
		Msg:       "Setup environment variables",
		SendProbe: true,
	}

	stLoadKernel := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "tftp 0x40008000 odroid/zImage; bootm", true)
		},
		Expect:    "Welcome to Odroid",
		Msg:       "Get zImage via tftp",
		SendProbe: true,
		Timeout:   80 * time.Second,
	}

	stLoginRoot := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "root", true)
		},
		Expect:    "",
		Msg:       "Login as root",
		SendProbe: true,
	}

	stLoadModules := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "modprobe usbnet; modprobe smsc95xx", true)
		},
		Expect:    "registered new interface driver smsc95xx",
		Msg:       "Load modules",
		SendProbe: true,
	}

	stBringUpEth0 := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "ifconfig eth0 up", true)
		},
		Expect:    "eth0: link up",
		Msg:       "Bring up eth0",
		SendProbe: true,
	}

	stAssignIP := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "ip addr add "+c.IpAddr+"/24 dev eth0", false)
			util.MustSendCmd(w, "ip addr show eth0", true)
		},
		Expect:    "inet " + c.IpAddr + "/24",
		Msg:       "Assign IP address",
		SendProbe: true,
	}

	stWriteImage := &step.Step{
		OnTrigger: func() {
			params := "--progress=dot:kilo"
			command := "wget %s http://%s/%s -O -|xzcat -|dd of=%s bs=4M"

			command = fmt.Sprintf(command, params, c.ServerAddr,
				c.ImageFilename, c.Device)
			util.MustSendCmd(w, command, true)
		},
		Expect:    "100%",
		Msg:       "Image rootFS",
		SendProbe: true,
		Timeout:   60 * 3 * time.Second,
	}

	stRepartition:= &step.Step{
	   OnTrigger: func() {
			util.MustSendCmd(w, "", true)
			command := "wget http://%s/odroid/resizefs.sh && chmod +x *.sh && ./resizefs.sh"
			command = fmt.Sprintf(command, c.ServerAddr)
			util.MustSendCmd(w, command, true)
	   },
	   Expect:    "Information",
	   Msg:       "Repartition",
	   SendProbe: true,
	   Timeout:   80 * time.Second,
        }

	//stUpdateUboot := &step.Step{
	//OnTrigger: func() {
	//params := "--progress=dot:dots"
	//command := "wget %s http://%s/%s -O - | tar -xz && ./update.sh"
	//command = fmt.Sprintf(command, params, c.ServerAddr, c.UbootTar)
	//util.MustSendCmd(w, command, true)
	//},
	//Expect:    "U-boot image is fused successfully",
	//Msg:       "Flash U-boot",
	//SendProbe: true,
	//Timeout:   60 * 2 * time.Second,
	//}

	stReboot := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "reboot", true)
		},
		Expect:    "mounted filesystem",
		Msg:       "Reboot",
		SendProbe: true,
	   	Timeout:   20 * time.Second,
	}

	stResizeFS := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "resize2fs /dev/mmcblk0p2 && touch /forcefsck && stat /forcefsck", true)
		},
		Trigger:   "localhost login|root@|ubuntu.com",
		Expect:    "empty file",
		Msg:       "Resize FS",
		SendProbe: true,
		Timeout:   40 * time.Second,
	}

	stPostinstall := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "curl http://"+c.ServerAddr+"/postinstall/odroid/install.sh > i.sh && chmod +x i.sh && ./i.sh "+c.MacAddr+" "+c.Hostname+" >>/tmp/i.log 2>&1", true)
		},
		Trigger:   "localhost login|root@|ubuntu.com",
		Expect:    "",
		Msg:       "Started postinstall",
		SendProbe: true,
		Timeout:   10 * time.Second,
	}

	stepList := step.NewList()
	stepList.Append(stEnterUboot)
	stepList.Append(stSetEnv)
	stepList.Append(stStartEthernet)
	stepList.Append(stLoadKernel)
	stepList.Append(stLoginRoot)
	stepList.Append(stLoadModules)
	stepList.Append(stBringUpEth0)
	stepList.Append(stAssignIP)
	stepList.Append(stWriteImage)
	stepList.Append(stRepartition)
	//stepList.Append(stUpdateUboot)
	stepList.Append(stReboot)
	stepList.Append(stResizeFS)
	stepList.Append(stReboot.Clone())
	stepList.Append(stPostinstall)

	return stepList
}
<commit_msg>Move to background - postinstall<commit_after>package config

import (
	"../step"
	"../util"
	"bufio"
	"fmt"
	"time"
)

func GetOdroidStepList(w *bufio.Writer, c *step.StepConfig) *step.StepList {
	// Initialize steps
	stEnterUboot := &step.Step{
		Trigger: "ModeKey Check...",
		OnTrigger: func() {
			util.MustSendCmd(w, "\n", true)
		},
		Expect:  "Exynos4412 #",
		Msg:     "Enter u-boot console",
		Timeout: 10 * time.Second,
	}

	stStartEthernet := &step.Step{
		OnTrigger: func() {
			// Double \n -> uboot bug
			util.MustSendCmd(w, "usb start", true)
		},
		Expect:    "1 Ethernet Device(s) found",
		Msg:       "USB Ethernet start",
		SendProbe: true,
	}

	stSetEnv := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "setenv ethact sms0;setenv ipaddr "+c.IpAddr, false)
			util.MustSendCmd(w, "setenv netmask 255.255.255.0;setenv serverip "+c.ServerAddr, false)
			util.MustSendCmd(w, "setenv ethaddr "+c.MacAddr+";printenv ipaddr", true)
		},
		Expect:    "ipaddr=" + c.IpAddr,
		Msg:       "Setup environment variables",
		SendProbe: true,
	}

	stLoadKernel := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "tftp 0x40008000 odroid/zImage; bootm", true)
		},
		Expect:    "Welcome to Odroid",
		Msg:       "Get zImage via tftp",
		SendProbe: true,
		Timeout:   80 * time.Second,
	}

	stLoginRoot := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "root", true)
		},
		Expect:    "",
		Msg:       "Login as root",
		SendProbe: true,
	}

	stLoadModules := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "modprobe usbnet; modprobe smsc95xx", true)
		},
		Expect:    "registered new interface driver smsc95xx",
		Msg:       "Load modules",
		SendProbe: true,
	}

	stBringUpEth0 := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "ifconfig eth0 up", true)
		},
		Expect:    "eth0: link up",
		Msg:       "Bring up eth0",
		SendProbe: true,
	}

	stAssignIP := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "ip addr add "+c.IpAddr+"/24 dev eth0", false)
			util.MustSendCmd(w, "ip addr show eth0", true)
		},
		Expect:    "inet " + c.IpAddr + "/24",
		Msg:       "Assign IP address",
		SendProbe: true,
	}

	stWriteImage := &step.Step{
		OnTrigger: func() {
			params := "--progress=dot:kilo"
			command := "wget %s http://%s/%s -O -|xzcat -|dd of=%s bs=4M"

			command = fmt.Sprintf(command, params, c.ServerAddr,
				c.ImageFilename, c.Device)
			util.MustSendCmd(w, command, true)
		},
		Expect:    "100%",
		Msg:       "Image rootFS",
		SendProbe: true,
		Timeout:   60 * 3 * time.Second,
	}

	stRepartition:= &step.Step{
	   OnTrigger: func() {
			util.MustSendCmd(w, "", true)
			command := "wget http://%s/odroid/resizefs.sh && chmod +x *.sh && ./resizefs.sh"
			command = fmt.Sprintf(command, c.ServerAddr)
			util.MustSendCmd(w, command, true)
	   },
	   Expect:    "Information",
	   Msg:       "Repartition",
	   SendProbe: true,
	   Timeout:   80 * time.Second,
        }

	//stUpdateUboot := &step.Step{
	//OnTrigger: func() {
	//params := "--progress=dot:dots"
	//command := "wget %s http://%s/%s -O - | tar -xz && ./update.sh"
	//command = fmt.Sprintf(command, params, c.ServerAddr, c.UbootTar)
	//util.MustSendCmd(w, command, true)
	//},
	//Expect:    "U-boot image is fused successfully",
	//Msg:       "Flash U-boot",
	//SendProbe: true,
	//Timeout:   60 * 2 * time.Second,
	//}

	stReboot := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "reboot", true)
		},
		Expect:    "mounted filesystem",
		Msg:       "Reboot",
		SendProbe: true,
	   	Timeout:   20 * time.Second,
	}

	stResizeFS := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "resize2fs /dev/mmcblk0p2 && touch /forcefsck && stat /forcefsck", true)
		},
		Trigger:   "localhost login|root@|ubuntu.com",
		Expect:    "empty file",
		Msg:       "Resize FS",
		SendProbe: true,
		Timeout:   40 * time.Second,
	}

	stPostinstall := &step.Step{
		OnTrigger: func() {
			util.MustSendCmd(w, "curl http://"+c.ServerAddr+"/postinstall/odroid/install.sh > i.sh && chmod +x i.sh && ./i.sh "+c.MacAddr+" "+c.Hostname+" "+c.IpAddr+" >>/tmp/i.log 2>&1 &", true)
		},
		Trigger:   "localhost login|root@|ubuntu.com",
		Expect:    "",
		Msg:       "Started postinstall",
		SendProbe: true,
		Timeout:   10 * time.Second,
	}

	stepList := step.NewList()
	stepList.Append(stEnterUboot)
	stepList.Append(stSetEnv)
	stepList.Append(stStartEthernet)
	stepList.Append(stLoadKernel)
	stepList.Append(stLoginRoot)
	stepList.Append(stLoadModules)
	stepList.Append(stBringUpEth0)
	stepList.Append(stAssignIP)
	stepList.Append(stWriteImage)
	stepList.Append(stRepartition)
	//stepList.Append(stUpdateUboot)
	stepList.Append(stReboot)
	stepList.Append(stResizeFS)
	stepList.Append(stReboot.Clone())
	stepList.Append(stPostinstall)

	return stepList
}
<|endoftext|>


<commit_before>package report

import (
	"testing"

	"github.com/weaveworks/scope/test"
	"github.com/weaveworks/scope/test/reflect"
)

func TestEdgeMetadatasAdd(t *testing.T) {
	have := EmptyEdgeMetadatas.
		Add("foo",
		EdgeMetadata{
			EgressPacketCount: newu64(1),
		}).
		Add("foo",
		EdgeMetadata{
			EgressPacketCount: newu64(2),
		})
	if emd, ok := have.Lookup("foo"); !ok || *emd.EgressPacketCount != 3 {
		t.Errorf("foo.EgressPacketCount != 3")
	}
	if emd, ok := have.Lookup("bar"); ok || emd.EgressPacketCount != nil {
		t.Errorf("bar.EgressPacketCount != nil")
	}
	have.ForEach(func(k string, emd EdgeMetadata) {
		if k != "foo" || *emd.EgressPacketCount != 3 {
			t.Errorf("foo.EgressPacketCount != 3")
		}
	})
}

func TestEdgeMetadatasAddNil(t *testing.T) {
	have := EdgeMetadatas{}.Add("foo", EdgeMetadata{EgressPacketCount: newu64(1)})
	if have.Size() != 1 {
		t.Errorf("Adding to a zero-value EdgeMetadatas failed, got: %v", have)
	}
}

func TestEdgeMetadatasDeepEquals(t *testing.T) {
	want := EmptyEdgeMetadatas.
		Add("foo",
		EdgeMetadata{
			EgressPacketCount: newu64(3),
		})
	have := EmptyEdgeMetadatas.
		Add("foo",
		EdgeMetadata{
			EgressPacketCount: newu64(3),
		})
	if !reflect.DeepEqual(want, have) {
		t.Errorf(test.Diff(want, have))
	}
}

func TestEdgeMetadatasMerge(t *testing.T) {
	for name, c := range map[string]struct {
		a, b, want EdgeMetadatas
	}{
		"nils": {
			a:    EdgeMetadatas{},
			b:    EdgeMetadatas{},
			want: EdgeMetadatas{},
		},
		"Empty a": {
			a: EmptyEdgeMetadatas,
			b: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(1),
					MaxConnCountTCP:   newu64(2),
				}),
			want: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(1),
					MaxConnCountTCP:   newu64(2),
				}),
		},
		"Empty b": {
			a: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(12),
					EgressByteCount:   newu64(999),
				}),
			b: EmptyEdgeMetadatas,
			want: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(12),
					EgressByteCount:   newu64(999),
				}),
		},
		"Disjoint a & b": {
			a: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(12),
					EgressByteCount:   newu64(500),
					MaxConnCountTCP:   newu64(4),
				}),
			b: EmptyEdgeMetadatas.
				Add("hostQ|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(1),
					EgressByteCount:   newu64(2),
					MaxConnCountTCP:   newu64(6),
				}),
			want: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(12),
					EgressByteCount:   newu64(500),
					MaxConnCountTCP:   newu64(4),
				}).
				Add("hostQ|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(1),
					EgressByteCount:   newu64(2),
					MaxConnCountTCP:   newu64(6),
				}),
		},
		"Overlapping a & b": {
			a: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(12),
					EgressByteCount:   newu64(1000),
					MaxConnCountTCP:   newu64(7),
				}),
			b: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(1),
					IngressByteCount:  newu64(123),
					EgressByteCount:   newu64(2),
					MaxConnCountTCP:   newu64(9),
				}),
			want: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(13),
					IngressByteCount:  newu64(123),
					EgressByteCount:   newu64(1002),
					MaxConnCountTCP:   newu64(9),
				}),
		},
	} {
		if have := c.a.Merge(c.b); !reflect.DeepEqual(c.want, have) {
			t.Errorf("%s:\n%s", name, test.Diff(c.want, have))
		}
	}
}

func TestEdgeMetadataFlatten(t *testing.T) {
	// Test two EdgeMetadatas flatten to the correct values
	{
		have := (EdgeMetadata{
			EgressPacketCount: newu64(1),
			MaxConnCountTCP:   newu64(2),
		}).Flatten(EdgeMetadata{
			EgressPacketCount: newu64(4),
			EgressByteCount:   newu64(8),
			MaxConnCountTCP:   newu64(16),
		})
		want := EdgeMetadata{
			EgressPacketCount: newu64(1 + 4),
			EgressByteCount:   newu64(8),
			MaxConnCountTCP:   newu64(2 + 16), // flatten should sum MaxConnCountTCP
		}
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}

	// Test an EdgeMetadatas flatten to the correct value (should
	// just sum)
	{
		have := EmptyEdgeMetadatas.
			Add("foo", EdgeMetadata{
			EgressPacketCount: newu64(1),
			MaxConnCountTCP:   newu64(2),
		}).
			Add("bar", EdgeMetadata{
			EgressPacketCount: newu64(3),
			MaxConnCountTCP:   newu64(5),
		}).Flatten()
		want := EdgeMetadata{
			EgressPacketCount: newu64(1 + 3),
			MaxConnCountTCP:   newu64(2 + 5),
		}
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}

	{
		// Should not panic on nil
		have := EdgeMetadatas{}.Flatten()
		want := EdgeMetadata{}
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}
}

func TestEdgeMetadataReversed(t *testing.T) {
	have := EdgeMetadata{
		EgressPacketCount: newu64(1),
	}.Reversed()
	want := EdgeMetadata{
		IngressPacketCount: newu64(1),
	}
	if !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}

func TestEdgeMetadatasEncoding(t *testing.T) {
	want := EmptyEdgeMetadatas.
		Add("foo", EdgeMetadata{
		EgressPacketCount: newu64(1),
		MaxConnCountTCP:   newu64(2),
	}).
		Add("bar", EdgeMetadata{
		EgressPacketCount: newu64(3),
		MaxConnCountTCP:   newu64(5),
	})

	{
		gobs, err := want.GobEncode()
		if err != nil {
			t.Fatal(err)
		}
		have := EmptyEdgeMetadatas
		have.GobDecode(gobs)
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}

	{
		json, err := want.MarshalJSON()
		if err != nil {
			t.Fatal(err)
		}
		have := EmptyEdgeMetadatas
		have.UnmarshalJSON(json)
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}
}

func TestEdgeMetadatasEncodingNil(t *testing.T) {
	want := EdgeMetadatas{}

	{
		gobs, err := want.GobEncode()
		if err != nil {
			t.Fatal(err)
		}
		have := EmptyEdgeMetadatas
		have.GobDecode(gobs)
		if have.psMap == nil {
			t.Error("needed to get back a non-nil psMap for EdgeMetadata")
		}
	}

	{
		json, err := want.MarshalJSON()
		if err != nil {
			t.Fatal(err)
		}
		have := EmptyEdgeMetadatas
		have.UnmarshalJSON(json)
		if have.psMap == nil {
			t.Error("needed to get back a non-nil psMap for EdgeMetadata")
		}
	}
}

func newu64(value uint64) *uint64 { return &value }
<commit_msg>adding test for EdgeMetadata.DeepEqual<commit_after>package report

import (
	"testing"

	"github.com/weaveworks/scope/test"
	"github.com/weaveworks/scope/test/reflect"
)

func TestEdgeMetadatasAdd(t *testing.T) {
	have := EmptyEdgeMetadatas.
		Add("foo",
		EdgeMetadata{
			EgressPacketCount: newu64(1),
		}).
		Add("foo",
		EdgeMetadata{
			EgressPacketCount: newu64(2),
		})
	if emd, ok := have.Lookup("foo"); !ok || *emd.EgressPacketCount != 3 {
		t.Errorf("foo.EgressPacketCount != 3")
	}
	if emd, ok := have.Lookup("bar"); ok || emd.EgressPacketCount != nil {
		t.Errorf("bar.EgressPacketCount != nil")
	}
	have.ForEach(func(k string, emd EdgeMetadata) {
		if k != "foo" || *emd.EgressPacketCount != 3 {
			t.Errorf("foo.EgressPacketCount != 3")
		}
	})
}

func TestEdgeMetadatasAddNil(t *testing.T) {
	have := EdgeMetadatas{}.Add("foo", EdgeMetadata{EgressPacketCount: newu64(1)})
	if have.Size() != 1 {
		t.Errorf("Adding to a zero-value EdgeMetadatas failed, got: %v", have)
	}
}

func TestEdgeMetadatasDeepEquals(t *testing.T) {
	want := EmptyEdgeMetadatas.
		Add("foo",
		EdgeMetadata{
			EgressPacketCount: newu64(3),
		})
	have := EmptyEdgeMetadatas.
		Add("foo",
		EdgeMetadata{
			EgressPacketCount: newu64(3),
		})
	if !reflect.DeepEqual(want, have) {
		t.Errorf(test.Diff(want, have))
	}
}

func TestEdgeMetadatasMerge(t *testing.T) {
	for name, c := range map[string]struct {
		a, b, want EdgeMetadatas
	}{
		"nils": {
			a:    EdgeMetadatas{},
			b:    EdgeMetadatas{},
			want: EdgeMetadatas{},
		},
		"Empty a": {
			a: EmptyEdgeMetadatas,
			b: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(1),
					MaxConnCountTCP:   newu64(2),
				}),
			want: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(1),
					MaxConnCountTCP:   newu64(2),
				}),
		},
		"Empty b": {
			a: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(12),
					EgressByteCount:   newu64(999),
				}),
			b: EmptyEdgeMetadatas,
			want: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(12),
					EgressByteCount:   newu64(999),
				}),
		},
		"Disjoint a & b": {
			a: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(12),
					EgressByteCount:   newu64(500),
					MaxConnCountTCP:   newu64(4),
				}),
			b: EmptyEdgeMetadatas.
				Add("hostQ|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(1),
					EgressByteCount:   newu64(2),
					MaxConnCountTCP:   newu64(6),
				}),
			want: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(12),
					EgressByteCount:   newu64(500),
					MaxConnCountTCP:   newu64(4),
				}).
				Add("hostQ|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(1),
					EgressByteCount:   newu64(2),
					MaxConnCountTCP:   newu64(6),
				}),
		},
		"Overlapping a & b": {
			a: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(12),
					EgressByteCount:   newu64(1000),
					MaxConnCountTCP:   newu64(7),
				}),
			b: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(1),
					IngressByteCount:  newu64(123),
					EgressByteCount:   newu64(2),
					MaxConnCountTCP:   newu64(9),
				}),
			want: EmptyEdgeMetadatas.
				Add("hostA|:192.168.1.1:12345|:192.168.1.2:80",
				EdgeMetadata{
					EgressPacketCount: newu64(13),
					IngressByteCount:  newu64(123),
					EgressByteCount:   newu64(1002),
					MaxConnCountTCP:   newu64(9),
				}),
		},
	} {
		if have := c.a.Merge(c.b); !reflect.DeepEqual(c.want, have) {
			t.Errorf("%s:\n%s", name, test.Diff(c.want, have))
		}
	}
}

func TestEdgeMetadataFlatten(t *testing.T) {
	// Test two EdgeMetadatas flatten to the correct values
	{
		have := (EdgeMetadata{
			EgressPacketCount: newu64(1),
			MaxConnCountTCP:   newu64(2),
		}).Flatten(EdgeMetadata{
			EgressPacketCount: newu64(4),
			EgressByteCount:   newu64(8),
			MaxConnCountTCP:   newu64(16),
		})
		want := EdgeMetadata{
			EgressPacketCount: newu64(1 + 4),
			EgressByteCount:   newu64(8),
			MaxConnCountTCP:   newu64(2 + 16), // flatten should sum MaxConnCountTCP
		}
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}

	// Test an EdgeMetadatas flatten to the correct value (should
	// just sum)
	{
		have := EmptyEdgeMetadatas.
			Add("foo", EdgeMetadata{
			EgressPacketCount: newu64(1),
			MaxConnCountTCP:   newu64(2),
		}).
			Add("bar", EdgeMetadata{
			EgressPacketCount: newu64(3),
			MaxConnCountTCP:   newu64(5),
		}).Flatten()
		want := EdgeMetadata{
			EgressPacketCount: newu64(1 + 3),
			MaxConnCountTCP:   newu64(2 + 5),
		}
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}

	{
		// Should not panic on nil
		have := EdgeMetadatas{}.Flatten()
		want := EdgeMetadata{}
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}
}

func TestEdgeMetadataReversed(t *testing.T) {
	have := EdgeMetadata{
		EgressPacketCount: newu64(1),
	}.Reversed()
	want := EdgeMetadata{
		IngressPacketCount: newu64(1),
	}
	if !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}

func TestEdgeMetadatasEncoding(t *testing.T) {
	want := EmptyEdgeMetadatas.
		Add("foo", EdgeMetadata{
		EgressPacketCount: newu64(1),
		MaxConnCountTCP:   newu64(2),
	}).
		Add("bar", EdgeMetadata{
		EgressPacketCount: newu64(3),
		MaxConnCountTCP:   newu64(5),
	})

	{
		gobs, err := want.GobEncode()
		if err != nil {
			t.Fatal(err)
		}
		have := EmptyEdgeMetadatas
		have.GobDecode(gobs)
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}

	{
		json, err := want.MarshalJSON()
		if err != nil {
			t.Fatal(err)
		}
		have := EmptyEdgeMetadatas
		have.UnmarshalJSON(json)
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}
}

func TestEdgeMetadatasEncodingNil(t *testing.T) {
	want := EdgeMetadatas{}

	{
		gobs, err := want.GobEncode()
		if err != nil {
			t.Fatal(err)
		}
		have := EmptyEdgeMetadatas
		have.GobDecode(gobs)
		if have.psMap == nil {
			t.Error("needed to get back a non-nil psMap for EdgeMetadata")
		}
	}

	{
		json, err := want.MarshalJSON()
		if err != nil {
			t.Fatal(err)
		}
		have := EmptyEdgeMetadatas
		have.UnmarshalJSON(json)
		if have.psMap == nil {
			t.Error("needed to get back a non-nil psMap for EdgeMetadata")
		}
	}
}

func newu64(value uint64) *uint64 { return &value }

func TestEdgeMetadataDeepEquals(t *testing.T) {
	for _, c := range []struct {
		name string
		a, b interface{}
		want bool
	}{
		{
			name: "zero values",
			a:    EdgeMetadata{},
			b:    EdgeMetadata{},
			want: true,
		},
		{
			name: "matching, but different pointers",
			a:    EdgeMetadata{EgressPacketCount: newu64(3)},
			b:    EdgeMetadata{EgressPacketCount: newu64(3)},
			want: true,
		},
		{
			name: "mismatching",
			a:    EdgeMetadata{EgressPacketCount: newu64(3)},
			b:    EdgeMetadata{EgressPacketCount: newu64(4)},
			want: false,
		},
	} {
		if have := reflect.DeepEqual(c.a, c.b); have != c.want {
			t.Errorf("reflect.DeepEqual(%v, %v) != %v", c.a, c.b, c.want)
		}
	}
}
<|endoftext|>


<commit_before>package space_saving

import (
	"github.com/stretchr/testify/require"
	"testing"
)

func TestTopWithEnoughCounters(t *testing.T) {
	ss := New(3)
	keys := []string{"a", "b", "a", "a", "a", "c", "c", "c", "a"}
	for _, k := range keys {
		err := ss.Process(k)
		require.NoError(t, err)
	}
	topKeys, topCounts := ss.Top(2)
	require.Equal(t, []string{"a", "c"}, topKeys)
	require.Equal(t, []int{5, 3}, topCounts)
}

func TestTopWhenTopElementChanges(t *testing.T) {
	ss := New(3)
	keys := []string{"a", "b", "a", "a", "a", "c", "c", "c", "a", "b", "b", "b", "b", "b"}
	for _, k := range keys {
		err := ss.Process(k)
		require.NoError(t, err)
	}
	topKeys, topCounts := ss.Top(2)
	require.Equal(t, []string{"b", "a"}, topKeys)
	require.Equal(t, []int{6, 5}, topCounts)
}

func TestTopWithoutEnoughCounters(t *testing.T) {
	ss := New(2)
	keys := []string{"a", "b", "a", "a", "a", "c", "c", "c", "d", "d"}
	for _, k := range keys {
		err := ss.Process(k)
		require.NoError(t, err)
	}
	topKeys, topCounts := ss.Top(2)
	require.Equal(t, []string{"d", "a"}, topKeys)
	require.Equal(t, []int{6, 4}, topCounts)
}
<commit_msg>one more test case<commit_after>package space_saving

import (
	"github.com/stretchr/testify/require"
	"testing"
)

func TestTopWithEnoughCounters(t *testing.T) {
	ss := New(3)
	keys := []string{"a", "b", "a", "a", "a", "c", "c", "c", "a"}
	for _, k := range keys {
		err := ss.Process(k)
		require.NoError(t, err)
	}
	topKeys, topCounts := ss.Top(2)
	require.Equal(t, []string{"a", "c"}, topKeys)
	require.Equal(t, []int{5, 3}, topCounts)
}

func TestTopWhenTopElementChanges(t *testing.T) {
	ss := New(3)
	keys := []string{"a", "b", "a", "a", "a", "c", "c", "c", "a", "b", "b", "b", "b", "b"}
	for _, k := range keys {
		err := ss.Process(k)
		require.NoError(t, err)
	}
	topKeys, topCounts := ss.Top(2)
	require.Equal(t, []string{"b", "a"}, topKeys)
	require.Equal(t, []int{6, 5}, topCounts)
}

func TestTopWithoutEnoughCounters(t *testing.T) {
	ss := New(2)
	keys := []string{"a", "b", "a", "a", "a", "c", "c", "c", "d", "d"}
	for _, k := range keys {
		err := ss.Process(k)
		require.NoError(t, err)
	}
	topKeys, topCounts := ss.Top(2)
	require.Equal(t, []string{"d", "a"}, topKeys)
	require.Equal(t, []int{6, 4}, topCounts)
}

func TestTopWhenTopElementChangesWithoutEnoughCounters(t *testing.T) {
	ss := New(2)
	keys := []string{"a", "b", "a", "a", "a", "c", "c", "c", "a", "b", "b", "b", "b", "b"}
	for _, k := range keys {
		err := ss.Process(k)
		require.NoError(t, err)
	}
	topKeys, topCounts := ss.Top(2)
	require.Equal(t, []string{"b", "a"}, topKeys)
	require.Equal(t, []int{9, 5}, topCounts)
}
<|endoftext|>


<commit_before>package validation

import (
	"fmt"
	"strings"

	"github.com/hashicorp/terraform/helper/schema"
)

// IntBetween returns a SchemaValidateFunc which tests if the provided value
// is of type int and is between min and max (inclusive)
func IntBetween(min, max int) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(int)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be int", k))
			return
		}

		if v < min || v > max {
			es = append(es, fmt.Errorf("expected %s to be in the range (%d - %d), got %d", k, min, max, v))
			return
		}

		return
	}
}

// StringInSlice returns a SchemaValidateFunc which tests if the provided value
// is of type string and matches the value of an element in the valid slice
// will test with in lower case if ignoreCase is true
func StringInSlice(valid []string, ignoreCase bool) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		for _, str := range valid {
			if v == str || (ignoreCase && strings.ToLower(v) == strings.ToLower(str)) {
				return
			}
		}

		es = append(es, fmt.Errorf("expected %s to be one of %v, got %s", k, valid, v))
		return
	}
}
<commit_msg>alicloud: simplify validators (#12982)<commit_after>package validation

import (
	"fmt"
	"net"
	"strings"

	"github.com/hashicorp/terraform/helper/schema"
)

// IntBetween returns a SchemaValidateFunc which tests if the provided value
// is of type int and is between min and max (inclusive)
func IntBetween(min, max int) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(int)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be int", k))
			return
		}

		if v < min || v > max {
			es = append(es, fmt.Errorf("expected %s to be in the range (%d - %d), got %d", k, min, max, v))
			return
		}

		return
	}
}

// StringInSlice returns a SchemaValidateFunc which tests if the provided value
// is of type string and matches the value of an element in the valid slice
// will test with in lower case if ignoreCase is true
func StringInSlice(valid []string, ignoreCase bool) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		for _, str := range valid {
			if v == str || (ignoreCase && strings.ToLower(v) == strings.ToLower(str)) {
				return
			}
		}

		es = append(es, fmt.Errorf("expected %s to be one of %v, got %s", k, valid, v))
		return
	}
}

// StringLenBetween returns a SchemaValidateFunc which tests if the provided value
// is of type string and has length between min and max (inclusive)
func StringLenBetween(min, max int) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}
		if len(v) < min || len(v) > max {
			es = append(es, fmt.Errorf("expected length of %s to be in the range (%d - %d), got %s", k, min, max, v))
		}
		return
	}
}

// CIDRNetwork returns a SchemaValidateFunc which tests if the provided value
// is of type string, is in valid CIDR network notation, and has significant bits between min and max (inclusive)
func CIDRNetwork(min, max int) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		_, ipnet, err := net.ParseCIDR(v)
		if err != nil {
			es = append(es, fmt.Errorf(
				"expected %s to contain a valid CIDR, got: %s with err: %s", k, v, err))
			return
		}

		if ipnet == nil || v != ipnet.String() {
			es = append(es, fmt.Errorf(
				"expected %s to contain a valid network CIDR, expected %s, got %s",
				k, ipnet, v))
		}

		sigbits, _ := ipnet.Mask.Size()
		if sigbits < min || sigbits > max {
			es = append(es, fmt.Errorf(
				"expected %q to contain a network CIDR with between %d and %d significant bits, got: %d",
				k, min, max, sigbits))
		}

		return
	}
}
<|endoftext|>


<commit_before>// Package pkgcloud allows you to talk to the PackageCloud API.
package pkgcloud

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strconv"

	"github.com/mlafeldt/pkgcloud/upload"
)

var serviceURL = "https://packagecloud.io"

// A Client is a PackageCloud client.
type Client struct {
	token string
}

// NewClient creates a PackageCloud client. API requests are authenticated
// using an API token. If no token is passed, it will be read from the
// PACKAGECLOUD_TOKEN environment variable.
func NewClient(token string) (*Client, error) {
	if token == "" {
		token = os.Getenv("PACKAGECLOUD_TOKEN")
		if token == "" {
			return nil, errors.New("PACKAGECLOUD_TOKEN unset")
		}
	}
	return &Client{token}, nil
}

func decodeResponse(status int, body []byte) error {
	switch status {
	case http.StatusOK, http.StatusCreated:
		return nil
	case http.StatusUnauthorized, http.StatusNotFound:
		return fmt.Errorf("HTTP status: %s", http.StatusText(status))
	case 422: // Unprocessable Entity
		var v map[string][]string
		if err := json.Unmarshal(body, &v); err != nil {
			return err
		}
		for _, messages := range v {
			for _, msg := range messages {
				// Only return the very first error message
				return errors.New(msg)
			}
			break
		}
		return fmt.Errorf("invalid HTTP body: %s", body)
	default:
		return fmt.Errorf("unexpected HTTP status: %d", status)
	}
}

// CreatePackage pushes a new package to PackageCloud.
func (c Client) CreatePackage(repo, distro, pkgFile string) error {
	distID, err := distroID(filepath.Ext(pkgFile), distro)
	if err != nil {
		return err
	}

	endpoint := fmt.Sprintf("%s/api/v1/repos/%s/packages.json",
		serviceURL, repo)
	extraParams := map[string]string{
		"package[distro_version_id]": strconv.Itoa(distID),
	}
	request, err := upload.NewRequest(endpoint, extraParams,
		"package[package_file]", pkgFile)
	if err != nil {
		return err
	}
	request.SetBasicAuth(c.token, "")

	client := &http.Client{}
	resp, err := client.Do(request)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	return decodeResponse(resp.StatusCode, body)
}
<commit_msg>Expose service URL<commit_after>// Package pkgcloud allows you to talk to the PackageCloud API.
// See https://packagecloud.io/docs/api
package pkgcloud

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strconv"

	"github.com/mlafeldt/pkgcloud/upload"
)

// ServiceURL is the URL of PackageCloud's API.
const ServiceURL = "https://packagecloud.io/api/v1"

// A Client is a PackageCloud client.
type Client struct {
	token string
}

// NewClient creates a PackageCloud client. API requests are authenticated
// using an API token. If no token is passed, it will be read from the
// PACKAGECLOUD_TOKEN environment variable.
func NewClient(token string) (*Client, error) {
	if token == "" {
		token = os.Getenv("PACKAGECLOUD_TOKEN")
		if token == "" {
			return nil, errors.New("PACKAGECLOUD_TOKEN unset")
		}
	}
	return &Client{token}, nil
}

func decodeResponse(status int, body []byte) error {
	switch status {
	case http.StatusOK, http.StatusCreated:
		return nil
	case http.StatusUnauthorized, http.StatusNotFound:
		return fmt.Errorf("HTTP status: %s", http.StatusText(status))
	case 422: // Unprocessable Entity
		var v map[string][]string
		if err := json.Unmarshal(body, &v); err != nil {
			return err
		}
		for _, messages := range v {
			for _, msg := range messages {
				// Only return the very first error message
				return errors.New(msg)
			}
			break
		}
		return fmt.Errorf("invalid HTTP body: %s", body)
	default:
		return fmt.Errorf("unexpected HTTP status: %d", status)
	}
}

// CreatePackage pushes a new package to PackageCloud.
func (c Client) CreatePackage(repo, distro, pkgFile string) error {
	distID, err := distroID(filepath.Ext(pkgFile), distro)
	if err != nil {
		return err
	}

	endpoint := fmt.Sprintf("%s/repos/%s/packages.json",
		ServiceURL, repo)
	extraParams := map[string]string{
		"package[distro_version_id]": strconv.Itoa(distID),
	}
	request, err := upload.NewRequest(endpoint, extraParams,
		"package[package_file]", pkgFile)
	if err != nil {
		return err
	}
	request.SetBasicAuth(c.token, "")

	client := &http.Client{}
	resp, err := client.Do(request)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	return decodeResponse(resp.StatusCode, body)
}
<|endoftext|>


<commit_before>package pki

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"errors"
	"math"
	"math/big"
	"net"
	"time"
)

var (
	Duration365d = time.Hour * 24 * 365
)

type CACertConfig struct {
	CommonName   string
	Organization string
	Duration     time.Duration
}

type ServerCertConfig struct {
	CommonName  string
	DNSNames    []string
	IPAddresses []string
	Duration    time.Duration
}

type ClientCertConfig struct {
	CommonName   string
	Organization []string
	DNSNames     []string
	IPAddresses  []string
	Duration     time.Duration
}

func NewSelfSignedCACertificate(cfg CACertConfig, key *rsa.PrivateKey) (*x509.Certificate, error) {
	if cfg.Duration <= 0 {
		return nil, errors.New("self-signed CA cert duration must not be negative or zero")
	}

	tmpl := x509.Certificate{
		SerialNumber: new(big.Int).SetInt64(0),
		Subject: pkix.Name{
			CommonName:   cfg.CommonName,
			Organization: []string{cfg.Organization},
		},
		NotBefore:             time.Now().UTC(),
		NotAfter:              time.Now().Add(cfg.Duration).UTC(),
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
		BasicConstraintsValid: true,
		IsCA:                  true,
	}

	certDERBytes, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, key.Public(), key)
	if err != nil {
		return nil, err
	}
	return x509.ParseCertificate(certDERBytes)
}

func NewSignedServerCertificate(cfg ServerCertConfig, key *rsa.PrivateKey, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, error) {
	ips := make([]net.IP, len(cfg.IPAddresses))
	for i, ipStr := range cfg.IPAddresses {
		ips[i] = net.ParseIP(ipStr)
	}

	serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
	if err != nil {
		return nil, err
	}

	if cfg.Duration <= 0 {
		return nil, errors.New("signed server cert duration must not be negative or zero")
	}

	certTmpl := x509.Certificate{
		Subject: pkix.Name{
			CommonName:   cfg.CommonName,
			Organization: caCert.Subject.Organization,
		},
		DNSNames:     cfg.DNSNames,
		IPAddresses:  ips,
		SerialNumber: serial,
		NotBefore:    caCert.NotBefore,
		NotAfter:     time.Now().Add(cfg.Duration).UTC(),
		KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
	}
	certDERBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey)
	if err != nil {
		return nil, err
	}
	return x509.ParseCertificate(certDERBytes)
}

func NewSignedClientCertificate(cfg ClientCertConfig, key *rsa.PrivateKey, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, error) {
	ips := make([]net.IP, len(cfg.IPAddresses))
	for i, ipStr := range cfg.IPAddresses {
		ips[i] = net.ParseIP(ipStr)
	}

	serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
	if err != nil {
		return nil, err
	}

	if cfg.Duration <= 0 {
		return nil, errors.New("signed client cert duration must not be negative or zero")
	}

	certTmpl := x509.Certificate{
		Subject: pkix.Name{
			CommonName:   cfg.CommonName,
			Organization: append(caCert.Subject.Organization, cfg.Organization...),
		},
		DNSNames:     cfg.DNSNames,
		IPAddresses:  ips,
		SerialNumber: serial,
		NotBefore:    caCert.NotBefore,
		NotAfter:     time.Now().Add(cfg.Duration).UTC(),
		KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
	}
	certDERBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey)
	if err != nil {
		return nil, err
	}
	return x509.ParseCertificate(certDERBytes)
}
<commit_msg>Server certificates also need to be allowed to be used for client authentication, e.g. etcd servers cross authenticate each other as both servers and clients. (#1757)<commit_after>package pki

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"errors"
	"math"
	"math/big"
	"net"
	"time"
)

var (
	Duration365d = time.Hour * 24 * 365
)

type CACertConfig struct {
	CommonName   string
	Organization string
	Duration     time.Duration
}

type ServerCertConfig struct {
	CommonName  string
	DNSNames    []string
	IPAddresses []string
	Duration    time.Duration
}

type ClientCertConfig struct {
	CommonName   string
	Organization []string
	DNSNames     []string
	IPAddresses  []string
	Duration     time.Duration
}

func NewSelfSignedCACertificate(cfg CACertConfig, key *rsa.PrivateKey) (*x509.Certificate, error) {
	if cfg.Duration <= 0 {
		return nil, errors.New("self-signed CA cert duration must not be negative or zero")
	}

	tmpl := x509.Certificate{
		SerialNumber: new(big.Int).SetInt64(0),
		Subject: pkix.Name{
			CommonName:   cfg.CommonName,
			Organization: []string{cfg.Organization},
		},
		NotBefore:             time.Now().UTC(),
		NotAfter:              time.Now().Add(cfg.Duration).UTC(),
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
		BasicConstraintsValid: true,
		IsCA:                  true,
	}

	certDERBytes, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, key.Public(), key)
	if err != nil {
		return nil, err
	}
	return x509.ParseCertificate(certDERBytes)
}

func NewSignedServerCertificate(cfg ServerCertConfig, key *rsa.PrivateKey, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, error) {
	ips := make([]net.IP, len(cfg.IPAddresses))
	for i, ipStr := range cfg.IPAddresses {
		ips[i] = net.ParseIP(ipStr)
	}

	serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
	if err != nil {
		return nil, err
	}

	if cfg.Duration <= 0 {
		return nil, errors.New("signed server cert duration must not be negative or zero")
	}

	certTmpl := x509.Certificate{
		Subject: pkix.Name{
			CommonName:   cfg.CommonName,
			Organization: caCert.Subject.Organization,
		},
		DNSNames:     cfg.DNSNames,
		IPAddresses:  ips,
		SerialNumber: serial,
		NotBefore:    caCert.NotBefore,
		NotAfter:     time.Now().Add(cfg.Duration).UTC(),
		KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
	}
	certDERBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey)
	if err != nil {
		return nil, err
	}
	return x509.ParseCertificate(certDERBytes)
}

func NewSignedClientCertificate(cfg ClientCertConfig, key *rsa.PrivateKey, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, error) {
	ips := make([]net.IP, len(cfg.IPAddresses))
	for i, ipStr := range cfg.IPAddresses {
		ips[i] = net.ParseIP(ipStr)
	}

	serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
	if err != nil {
		return nil, err
	}

	if cfg.Duration <= 0 {
		return nil, errors.New("signed client cert duration must not be negative or zero")
	}

	certTmpl := x509.Certificate{
		Subject: pkix.Name{
			CommonName:   cfg.CommonName,
			Organization: append(caCert.Subject.Organization, cfg.Organization...),
		},
		DNSNames:     cfg.DNSNames,
		IPAddresses:  ips,
		SerialNumber: serial,
		NotBefore:    caCert.NotBefore,
		NotAfter:     time.Now().Add(cfg.Duration).UTC(),
		KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
	}
	certDERBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey)
	if err != nil {
		return nil, err
	}
	return x509.ParseCertificate(certDERBytes)
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"testing"

	capnp "zombiezen.com/go/capnproto2"

	"github.com/gorilla/mux"
	. "github.com/smartystreets/goconvey/convey"
)

func TestPolicy(t *testing.T) {

	Convey("Policy", t, func() {

		Convey("test my knowledge of mux", func() {
			r := mux.NewRouter()
			r.Path("/something/{(1|2)}")

			req, _ := http.NewRequest("GET", "http://localhost:1234/something/1", nil)

			var routeMatch mux.RouteMatch

			result := r.Match(req, &routeMatch)

			So(result, ShouldEqual, true)
		})

		Convey("validates", func() {

			Convey("false", func() {
				Convey("when the request path does not match the policy exact path", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					policy.SetPath("/some/path")

					request, _ := NewHTTPRequest(seg)

					request.SetPath("/some/other/path")

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request path does not match the policy templated path", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					policy.SetPath("/some/path/{id:(1|2)}")

					request, _ := NewHTTPRequest(seg)

					request.SetPath("/some/path/3")

					result := policy.validate(request)
					So(result, ShouldEqual, false)
				})
				Convey("when the request verb does not match a single policy verb", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					verbs, _ := capnp.NewTextList(seg, 1)

					verbs.Set(0, "PUT")

					policy.SetVerbs(verbs)

					request, _ := NewHTTPRequest(seg)

					request.SetVerb("GET")

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request verb does not match a any policy verbs", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					verbs, _ := capnp.NewTextList(seg, 2)

					verbs.Set(0, "PUT")
					verbs.Set(1, "POST")

					policy.SetVerbs(verbs)

					request, _ := NewHTTPRequest(seg)

					request.SetVerb("GET")

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request has a header key which is not present in the header policy", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					headerList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("A")
					headerList.Set(0, keyValuePolicy)

					policy.SetHeaders(headerList)

					request, _ := NewHTTPRequest(seg)

					headers, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("B")
					headers.Set(0, keyValue)

					request.SetHeaders(headers)

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request has a header value which does not match a header policy value for the specified key", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					headerList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("X-Client")

					valuesList, _ := capnp.NewTextList(seg, 3)
					valuesList.Set(0, "1")
					valuesList.Set(0, "2")
					valuesList.Set(0, "3")

					keyValuePolicy.SetValues(valuesList)

					headerList.Set(0, keyValuePolicy)

					policy.SetHeaders(headerList)

					request, _ := NewHTTPRequest(seg)

					headers, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("X-Client")
					keyValue.SetValue("4")
					headers.Set(0, keyValue)

					request.SetHeaders(headers)

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request has a query string key which is not present in the query policy", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					queryList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("A")
					queryList.Set(0, keyValuePolicy)

					policy.SetQuery(queryList)

					request, _ := NewHTTPRequest(seg)

					query, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("B")
					keyValue.SetValue("1")
					query.Set(0, keyValue)

					request.SetQuery(query)

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request has a query value which does not match a query policy value for the specified key", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					queryList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("X-Client")

					valuesList, _ := capnp.NewTextList(seg, 3)
					valuesList.Set(0, "1")
					valuesList.Set(0, "2")
					valuesList.Set(0, "3")

					keyValuePolicy.SetValues(valuesList)

					queryList.Set(0, keyValuePolicy)

					policy.SetQuery(queryList)

					request, _ := NewHTTPRequest(seg)

					query, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("X-Client")
					keyValue.SetValue("4")
					query.Set(0, keyValue)

					request.SetQuery(query)

					So(policy.validate(request), ShouldEqual, false)
				})
			})

			Convey("true", func() {
				Convey("when the request path does match the policy exact path", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					policy.SetPath("/some/path")

					request, _ := NewHTTPRequest(seg)

					request.SetPath("/some/path")

					So(policy.validate(request), ShouldEqual, true)
				})
				Convey("when the request path does match the policy templated path", func() {

				})
				Convey("when the request verb does match a single policy verb", func() {

				})
				Convey("when the request verb does match one of many policy verbs", func() {

				})
				Convey("when the request has a header key which is present in the header policy", func() {

				})
				Convey("when the request has a header value which does match a header policy value for the specified key", func() {

				})
				Convey("when the request has a query string key which is present in the query policy", func() {

				})
				Convey("when the request has a query value which does match a query policy value for the specified key", func() {

				})
			})

		})

	})

}
<commit_msg>        when the request path does match the policy exact path ✔         when the request path does match the policy templated path ✔         when the request verb does match a single policy verb ✔         when the request verb does match one of many policy verbs ✔         when the request has a header key which is present in the header policy ✔         when the request has a header value which does match a header policy value for the specified key ✔         when the request has a query string key which is present in the query policy ✔         when the request has a query value which does match a query policy value for the specified key ✔<commit_after>package main

import (
	"net/http"
	"testing"

	capnp "zombiezen.com/go/capnproto2"

	"github.com/gorilla/mux"
	. "github.com/smartystreets/goconvey/convey"
)

func TestPolicy(t *testing.T) {

	Convey("Policy", t, func() {

		Convey("test my knowledge of mux", func() {
			r := mux.NewRouter()
			r.Path("/something/{(1|2)}")

			req, _ := http.NewRequest("GET", "http://localhost:1234/something/1", nil)

			var routeMatch mux.RouteMatch

			result := r.Match(req, &routeMatch)

			So(result, ShouldEqual, true)
		})

		Convey("validates", func() {

			Convey("false", func() {
				Convey("when the request path does not match the policy exact path", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					policy.SetPath("/some/path")

					request, _ := NewHTTPRequest(seg)

					request.SetPath("/some/other/path")

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request path does not match the policy templated path", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					policy.SetPath("/some/path/{id:(1|2)}")

					request, _ := NewHTTPRequest(seg)

					request.SetPath("/some/path/3")

					result := policy.validate(request)
					So(result, ShouldEqual, false)
				})
				Convey("when the request verb does not match a single policy verb", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					verbs, _ := capnp.NewTextList(seg, 1)

					verbs.Set(0, "PUT")

					policy.SetVerbs(verbs)

					request, _ := NewHTTPRequest(seg)

					request.SetVerb("GET")

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request verb does not match a any policy verbs", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					verbs, _ := capnp.NewTextList(seg, 2)

					verbs.Set(0, "PUT")
					verbs.Set(1, "POST")

					policy.SetVerbs(verbs)

					request, _ := NewHTTPRequest(seg)

					request.SetVerb("GET")

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request has a header key which is not present in the header policy", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					headerList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("A")
					headerList.Set(0, keyValuePolicy)

					policy.SetHeaders(headerList)

					request, _ := NewHTTPRequest(seg)

					headers, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("B")
					headers.Set(0, keyValue)

					request.SetHeaders(headers)

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request has a header value which does not match a header policy value for the specified key", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					headerList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("X-Client")

					valuesList, _ := capnp.NewTextList(seg, 3)
					valuesList.Set(0, "1")
					valuesList.Set(0, "2")
					valuesList.Set(0, "3")

					keyValuePolicy.SetValues(valuesList)

					headerList.Set(0, keyValuePolicy)

					policy.SetHeaders(headerList)

					request, _ := NewHTTPRequest(seg)

					headers, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("X-Client")
					keyValue.SetValue("4")
					headers.Set(0, keyValue)

					request.SetHeaders(headers)

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request has a query string key which is not present in the query policy", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					queryList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("A")
					queryList.Set(0, keyValuePolicy)

					policy.SetQuery(queryList)

					request, _ := NewHTTPRequest(seg)

					query, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("B")
					keyValue.SetValue("1")
					query.Set(0, keyValue)

					request.SetQuery(query)

					So(policy.validate(request), ShouldEqual, false)
				})
				Convey("when the request has a query value which does not match a query policy value for the specified key", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					queryList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("X-Client")

					valuesList, _ := capnp.NewTextList(seg, 3)
					valuesList.Set(0, "1")
					valuesList.Set(0, "2")
					valuesList.Set(0, "3")

					keyValuePolicy.SetValues(valuesList)

					queryList.Set(0, keyValuePolicy)

					policy.SetQuery(queryList)

					request, _ := NewHTTPRequest(seg)

					query, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("X-Client")
					keyValue.SetValue("4")
					query.Set(0, keyValue)

					request.SetQuery(query)

					So(policy.validate(request), ShouldEqual, false)
				})
			})

			Convey("true", func() {
				Convey("when the request path does match the policy exact path", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					policy.SetPath("/some/path")

					request, _ := NewHTTPRequest(seg)

					request.SetPath("/some/path")

					So(policy.validate(request), ShouldEqual, true)
				})
				Convey("when the request path does match the policy templated path", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					policy.SetPath("/some/path/{id:(1|2)}")

					request, _ := NewHTTPRequest(seg)

					request.SetPath("/some/path/1")

					result := policy.validate(request)
					So(result, ShouldEqual, true)
				})
				Convey("when the request verb does match a single policy verb", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					verbs, _ := capnp.NewTextList(seg, 1)

					verbs.Set(0, "PUT")

					policy.SetVerbs(verbs)

					request, _ := NewHTTPRequest(seg)

					request.SetVerb("PUT")

					So(policy.validate(request), ShouldEqual, true)
				})
				Convey("when the request verb does match one of many policy verbs", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					verbs, _ := capnp.NewTextList(seg, 2)

					verbs.Set(0, "PUT")
					verbs.Set(1, "POST")

					policy.SetVerbs(verbs)

					request, _ := NewHTTPRequest(seg)

					request.SetVerb("PUT")

					So(policy.validate(request), ShouldEqual, true)
				})
				Convey("when the request has a header key which is present in the header policy", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					headerList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("A")
					headerList.Set(0, keyValuePolicy)

					policy.SetHeaders(headerList)

					request, _ := NewHTTPRequest(seg)

					headers, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("A")
					headers.Set(0, keyValue)

					request.SetHeaders(headers)

					So(policy.validate(request), ShouldEqual, true)
				})
				Convey("when the request has a header value which does match a header policy value for the specified key", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					headerList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("X-Client")

					valuesList, _ := capnp.NewTextList(seg, 3)
					valuesList.Set(0, "1")
					valuesList.Set(0, "2")
					valuesList.Set(0, "3")

					keyValuePolicy.SetValues(valuesList)

					headerList.Set(0, keyValuePolicy)

					policy.SetHeaders(headerList)

					request, _ := NewHTTPRequest(seg)

					headers, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("X-Client")
					keyValue.SetValue("3")
					headers.Set(0, keyValue)

					request.SetHeaders(headers)

					So(policy.validate(request), ShouldEqual, true)
				})
				Convey("when the request has a query string key which is present in the query policy", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					queryList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("A")
					queryList.Set(0, keyValuePolicy)

					policy.SetQuery(queryList)

					request, _ := NewHTTPRequest(seg)

					query, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("A")
					keyValue.SetValue("1")
					query.Set(0, keyValue)

					request.SetQuery(query)

					So(policy.validate(request), ShouldEqual, true)
				})
				Convey("when the request has a query value which does match a query policy value for the specified key", func() {
					_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))

					policy, _ := NewPolicy(seg)

					queryList, _ := NewKeyValuePolicy_List(seg, 1)
					keyValuePolicy, _ := NewKeyValuePolicy(seg)
					keyValuePolicy.SetKey("X-Client")

					valuesList, _ := capnp.NewTextList(seg, 3)
					valuesList.Set(0, "1")
					valuesList.Set(0, "2")
					valuesList.Set(0, "3")

					keyValuePolicy.SetValues(valuesList)

					queryList.Set(0, keyValuePolicy)

					policy.SetQuery(queryList)

					request, _ := NewHTTPRequest(seg)

					query, _ := NewKeyValue_List(seg, 1)
					keyValue, _ := NewKeyValue(seg)
					keyValue.SetKey("X-Client")
					keyValue.SetValue("3")
					query.Set(0, keyValue)

					request.SetQuery(query)

					So(policy.validate(request), ShouldEqual, true)
				})
			})

		})

	})

}
<|endoftext|>


<commit_before>package com

import "runtime"

const (
	IsWindows = runtime.GOOS == "windows"
	IsLinux   = runtime.GOOS == "linux"
	IsMac     = runtime.GOOS == "darwin"
	Is32Bit   = runtime.GOARCH == "386"
	Is64Bit   = runtime.GOARCH == "amd64"
)
<commit_msg>update<commit_after>package com

import (
	"os"
	"runtime"
)

const (
	IsWindows = runtime.GOOS == "windows"
	IsLinux   = runtime.GOOS == "linux"
	IsMac     = runtime.GOOS == "darwin"
	Is32Bit   = runtime.GOARCH == "386"
	Is64Bit   = runtime.GOARCH == "amd64"
)

// ExitOnSuccess 成功时推出程序
func ExitOnSuccess(msg string) {
	os.Stdout.WriteString(msg)
	os.Exit(0)
}

// ExitOnFailure 失败时推出程序
func ExitOnFailure(msg string, errCodes ...int) {
	errCode := 1
	if len(errCodes) > 0 {
		errCode = errCodes[0]
	}
	os.Stderr.WriteString(msg)
	os.Exit(errCode)
}
<|endoftext|>


<commit_before>package test

import (
	"testing"

	//	ctypes "github.com/eris-ltd/eris-db/rpc/core/types"
	_ "github.com/tendermint/tendermint/config/tendermint_test"
)

// When run with `-test.short` we only run:
// TestHTTPStatus, TestHTTPBroadcast, TestJSONStatus, TestJSONBroadcast, TestWSConnect, TestWSSend

//--------------------------------------------------------------------------------
func TestHTTPStatus(t *testing.T) {
	testStatus(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPGetAccount(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testGetAccount(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPBroadcastTx(t *testing.T) {
	testBroadcastTx(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPGetStorage(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testGetStorage(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPCallCode(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testCallCode(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPCallContract(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testCall(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPNameReg(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testNameReg(t, "HTTP")
}

//--------------------------------------------------------------------------------
// Test the JSONRPC client

func TestJSONStatus(t *testing.T) {
	testStatus(t, "JSONRPC")
}

func TestJSONGetAccount(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testGetAccount(t, "JSONRPC")
}

func TestJSONBroadcastTx(t *testing.T) {
	testBroadcastTx(t, "JSONRPC")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testJSONGetStorage(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testGetStorage(t, "JSONRPC")
}

func TestJSONCallCode(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testCallCode(t, "JSONRPC")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testJSONCallContract(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testCall(t, "JSONRPC")
}

func TestJSONNameReg(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testNameReg(t, "JSONRPC")
}
<commit_msg>correct: /rpc/tendermint TestHTTPNameReg was passing<commit_after>package test

import (
	"testing"

	//	ctypes "github.com/eris-ltd/eris-db/rpc/core/types"
	_ "github.com/tendermint/tendermint/config/tendermint_test"
)

// When run with `-test.short` we only run:
// TestHTTPStatus, TestHTTPBroadcast, TestJSONStatus, TestJSONBroadcast, TestWSConnect, TestWSSend

//--------------------------------------------------------------------------------
func TestHTTPStatus(t *testing.T) {
	testStatus(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPGetAccount(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testGetAccount(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPBroadcastTx(t *testing.T) {
	testBroadcastTx(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPGetStorage(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testGetStorage(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPCallCode(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testCallCode(t, "HTTP")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testHTTPCallContract(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testCall(t, "HTTP")
}

func TestHTTPNameReg(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testNameReg(t, "HTTP")
}

//--------------------------------------------------------------------------------
// Test the JSONRPC client

func TestJSONStatus(t *testing.T) {
	testStatus(t, "JSONRPC")
}

func TestJSONGetAccount(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testGetAccount(t, "JSONRPC")
}

func TestJSONBroadcastTx(t *testing.T) {
	testBroadcastTx(t, "JSONRPC")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testJSONGetStorage(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testGetStorage(t, "JSONRPC")
}

func TestJSONCallCode(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testCallCode(t, "JSONRPC")
}

// TODO: test has been disabled and needs to be re-enabled; tracked in issue
// https://github.com/eris-ltd/eris-db/issues/238
func testJSONCallContract(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testCall(t, "JSONRPC")
}

func TestJSONNameReg(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	testNameReg(t, "JSONRPC")
}
<|endoftext|>


<commit_before>// Copyright ©2012 The bíogo.bam Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package bam

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"net/url"
	"strconv"
	"time"
)

var (
	badHeader = errors.New("bam: malformed header line")
	dupTag    = errors.New("bam: duplicate field")
)

type tag [2]byte

var (
	headerTag       = tag{'H', 'D'}
	versionTag      = tag{'V', 'N'}
	sortOrderTag    = tag{'S', 'O'}
	groupOrderTag   = tag{'G', 'O'}
	refDictTag      = tag{'S', 'Q'}
	refNameTag      = tag{'S', 'N'}
	refLengthTag    = tag{'L', 'N'}
	assemblyIDTag   = tag{'A', 'S'}
	md5Tag          = tag{'M', '5'}
	speciesTag      = tag{'S', 'P'}
	uriTag          = tag{'U', 'R'}
	readGroupTag    = tag{'R', 'G'}
	centerTag       = tag{'C', 'N'}
	descriptionTag  = tag{'D', 'S'}
	dateTag         = tag{'D', 'T'}
	flowOrderTag    = tag{'F', 'O'}
	keySequenceTag  = tag{'K', 'S'}
	libraryTag      = tag{'L', 'B'}
	insertSizeTag   = tag{'P', 'I'}
	platformTag     = tag{'P', 'L'}
	platformUnitTag = tag{'P', 'U'}
	sampleTag       = tag{'S', 'M'}
	programTag      = tag{'P', 'G'}
	idTag           = tag{'I', 'D'}
	programNameTag  = tag{'P', 'N'}
	commandLineTag  = tag{'C', 'L'}
	previousProgTag = tag{'P', 'P'}
	commentTag      = tag{'C', 'O'}
)

var bamMagic = [4]byte{'B', 'A', 'M', 0x1}

func (bh *Header) read(r io.Reader) error {
	var (
		lText, nRef int32
		err         error
	)
	var magic [4]byte
	err = binary.Read(r, Endian, &magic)
	if err != nil {
		return err
	}
	if magic != bamMagic {
		return errors.New("bam: magic number mismatch")
	}
	err = binary.Read(r, Endian, &lText)
	if err != nil {
		return err
	}
	text := make([]byte, lText)
	n, err := r.Read(text)
	if err != nil {
		return err
	}
	if n != int(lText) {
		return errors.New("bam: truncated header")
	}
	err = bh.parseHeader(text)
	if err != nil {
		return err
	}
	err = binary.Read(r, Endian, &nRef)
	if err != nil {
		return err
	}
	refs, err := readRefRecords(r, nRef)
	if err != nil {
		return err
	}
	for _, r := range refs {
		err = bh.AddReference(r)
		if err != nil {
			return err
		}
	}
	return nil
}

func readRefRecords(r io.Reader, n int32) ([]*Reference, error) {
	rr := make([]*Reference, n)
	var (
		lName int32
		err   error
	)
	for i := range rr {
		rr[i] = &Reference{id: int32(i)}
		err = binary.Read(r, Endian, &lName)
		if err != nil {
			return nil, err
		}
		name := make([]byte, lName)
		n, err := r.Read(name)
		if err != nil {
			return nil, err
		}
		if n != int(lName) || name[n-1] != 0 {
			return nil, errors.New("bam: truncated reference name")
		}
		rr[i].name = string(name[:n-1])
		err = binary.Read(r, Endian, &rr[i].lRef)
		if err != nil {
			return nil, err
		}
	}
	return rr, nil
}

func (bh *Header) parseHeader(text []byte) error {
	var t tag
	for i, l := range bytes.Split(text, []byte{'\n'}) {
		if len(l) > 0 && l[len(l)-1] == '\r' {
			l = l[:len(l)-1]
		}
		if len(l) == 0 {
			continue
		}
		if l[0] != '@' || len(l) < 3 {
			return badHeader
		}
		copy(t[:], l[1:3])
		var err error
		switch {
		case t == headerTag:
			err = headerLine(l, bh)
		case t == refDictTag:
			err = referenceLine(l, bh)
		case t == readGroupTag:
			err = readGroupLine(l, bh)
		case t == programTag:
			err = programLine(l, bh)
		case t == commentTag:
			err = commentLine(l, bh)
		default:
			return badHeader
		}
		if err != nil {
			return fmt.Errorf("%v: line %d: %q", err, i+1, l)
		}
	}

	return nil
}

func headerLine(l []byte, bh *Header) error {
	fields := bytes.Split(l, []byte{'\t'})
	if len(fields) < 2 {
		return badHeader
	}

	var t tag
	for _, f := range fields[1:] {
		if f[2] != ':' {
			return badHeader
		}
		copy(t[:], f[:2])
		fs := string(f[3:])
		switch {
		case t == versionTag:
			if bh.Version != "" {
				return badHeader
			}
			bh.Version = fs
		case t == sortOrderTag:
			if bh.SortOrder != UnknownOrder {
				return badHeader
			}
			bh.SortOrder = sortOrderMap[fs]
		case t == groupOrderTag:
			if bh.GroupOrder != GroupUnspecified {
				return badHeader
			}
			bh.GroupOrder = groupOrderMap[fs]
		default:
			return badHeader
		}
	}

	if bh.Version == "" {
		return badHeader
	}

	return nil
}

func referenceLine(l []byte, bh *Header) error {
	fields := bytes.Split(l, []byte{'\t'})
	if len(fields) < 3 {
		return badHeader
	}

	var (
		t        tag
		rf       = &Reference{}
		seen     = map[tag]struct{}{}
		nok, lok bool
		dupID    int32
		dup      bool
	)

	for _, f := range fields[1:] {
		if f[2] != ':' {
			return badHeader
		}
		copy(t[:], f[:2])
		if _, ok := seen[t]; ok {
			return dupTag
		}
		seen[t] = struct{}{}
		fs := string(f[3:])
		switch {
		case t == refNameTag:
			dupID, dup = bh.seenRefs[fs]
			rf.name = fs
			nok = true
		case t == refLengthTag:
			l, err := strconv.Atoi(fs)
			if err != nil {
				return badHeader
			}
			if !validLen(l) {
				return badLen
			}
			rf.lRef = int32(l)
			lok = true
		case t == assemblyIDTag:
			rf.assemID = fs
		case t == md5Tag:
			hb := [16]byte{}
			n, err := hex.Decode(hb[:], f[3:])
			if err != nil {
				return err
			}
			if n != 16 {
				return badHeader
			}
			rf.md5 = &hb
		case t == speciesTag:
			rf.species = fs
		case t == uriTag:
			var err error
			rf.uri, err = url.Parse(fs)
			if err != nil {
				return err
			}
			if rf.uri.Scheme != "http" || rf.uri.Scheme != "ftp" {
				rf.uri.Scheme = "file"
			}
		default:
			return badHeader
		}
	}

	if dup {
		if er := bh.refs[dupID]; *er == *rf {
			return nil
		} else if tr := (Reference{id: er.id, name: er.name, lRef: er.lRef}); *er != tr {
			return dupReference
		}
		bh.refs[dupID] = rf
		return nil
	}
	if !nok || !lok {
		return badHeader
	}
	id := int32(len(bh.refs))
	rf.id = id
	bh.seenRefs[rf.name] = id
	bh.refs = append(bh.refs, rf)

	return nil
}

// http://en.wikipedia.org/wiki/ISO_8601
//
// Date: 2014-08-13
// Time: 2014-08-13T16:02:01Z
//     : 2014-08-13T16:02:01+00:00
//
const (
	iso8601Date      = "2006-01-02"
	iso8601TimeDateZ = "2006-01-02T15:04:05Z"
	iso8601TimeDateN = "2006-01-02T15:04:05-0700"
)

var iso8601 = []string{iso8601Date, iso8601TimeDateZ, iso8601TimeDateN}

func readGroupLine(l []byte, bh *Header) error {
	fields := bytes.Split(l, []byte{'\t'})
	if len(fields) < 2 {
		return badHeader
	}

	var (
		t    tag
		rg   = &ReadGroup{}
		seen = map[tag]struct{}{}
		idok bool
	)

L:
	for _, f := range fields[1:] {
		if f[2] != ':' {
			return badHeader
		}
		copy(t[:], f[:2])
		if _, ok := seen[t]; ok {
			return dupTag
		}
		seen[t] = struct{}{}
		fs := string(f[3:])
		switch {
		case t == idTag:
			if _, ok := bh.seenRefs[fs]; ok {
				return dupReadGroup
			}
			rg.name = fs
			idok = true
		case t == centerTag:
			rg.center = fs
		case t == descriptionTag:
			rg.description = fs
		case t == dateTag:
			var err error
			for _, tf := range iso8601 {
				rg.date, err = time.Parse(tf, fs)
				if err == nil {
					continue L
				}
			}
			return err
		case t == flowOrderTag:
			rg.flowOrder = append([]byte(nil), fs...)
		case t == keySequenceTag:
			rg.keySeq = append([]byte(nil), fs...)
		case t == libraryTag:
			rg.library = fs
		case t == programTag:
			rg.program = fs
		case t == insertSizeTag:
			i, err := strconv.Atoi(fs)
			if err != nil {
				return err
			}
			if !validInt32(i) {
				return badLen
			}
			rg.insertSize = i
		case t == platformTag:
			rg.platform = fs
		case t == platformUnitTag:
			rg.platformUnit = fs
		case t == sampleTag:
			rg.sample = fs
		default:
			return badHeader
		}
	}

	if !idok {
		return badHeader
	}
	id := int32(len(bh.rgs))
	rg.id = id
	bh.seenGroups[rg.name] = id
	bh.rgs = append(bh.rgs, rg)

	return nil
}

func programLine(l []byte, bh *Header) error {
	fields := bytes.Split(l, []byte{'\t'})
	if len(fields) < 2 {
		return badHeader
	}

	var (
		t    tag
		p    = &Program{}
		seen = map[tag]struct{}{}
		idok bool
	)

	for _, f := range fields[1:] {
		if f[2] != ':' {
			return badHeader
		}
		copy(t[:], f[:2])
		if _, ok := seen[t]; ok {
			return dupTag
		}
		seen[t] = struct{}{}
		fs := string(f[3:])
		switch {
		case t == idTag:
			if _, ok := bh.seenProgs[fs]; ok {
				return dupProgram
			}
			p.uid = fs
			idok = true
		case t == programNameTag:
			p.name = fs
		case t == commandLineTag:
			p.command = fs
		case t == previousProgTag:
			p.previous = fs
		case t == versionTag:
			p.version = fs
		default:
			return badHeader
		}
	}

	if !idok {
		return badHeader
	}
	id := int32(len(bh.progs))
	p.id = id
	bh.seenProgs[p.uid] = id
	bh.progs = append(bh.progs, p)

	return nil
}

func commentLine(l []byte, bh *Header) error {
	fields := bytes.Split(l, []byte{'\t'})
	if len(fields) < 2 {
		return badHeader
	}
	bh.Comments = append(bh.Comments, string(fields[1]))
	return nil
}
<commit_msg>Use ParseInLocation for date parsing<commit_after>// Copyright ©2012 The bíogo.bam Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package bam

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"net/url"
	"strconv"
	"time"
)

var (
	badHeader = errors.New("bam: malformed header line")
	dupTag    = errors.New("bam: duplicate field")
)

type tag [2]byte

var (
	headerTag       = tag{'H', 'D'}
	versionTag      = tag{'V', 'N'}
	sortOrderTag    = tag{'S', 'O'}
	groupOrderTag   = tag{'G', 'O'}
	refDictTag      = tag{'S', 'Q'}
	refNameTag      = tag{'S', 'N'}
	refLengthTag    = tag{'L', 'N'}
	assemblyIDTag   = tag{'A', 'S'}
	md5Tag          = tag{'M', '5'}
	speciesTag      = tag{'S', 'P'}
	uriTag          = tag{'U', 'R'}
	readGroupTag    = tag{'R', 'G'}
	centerTag       = tag{'C', 'N'}
	descriptionTag  = tag{'D', 'S'}
	dateTag         = tag{'D', 'T'}
	flowOrderTag    = tag{'F', 'O'}
	keySequenceTag  = tag{'K', 'S'}
	libraryTag      = tag{'L', 'B'}
	insertSizeTag   = tag{'P', 'I'}
	platformTag     = tag{'P', 'L'}
	platformUnitTag = tag{'P', 'U'}
	sampleTag       = tag{'S', 'M'}
	programTag      = tag{'P', 'G'}
	idTag           = tag{'I', 'D'}
	programNameTag  = tag{'P', 'N'}
	commandLineTag  = tag{'C', 'L'}
	previousProgTag = tag{'P', 'P'}
	commentTag      = tag{'C', 'O'}
)

var bamMagic = [4]byte{'B', 'A', 'M', 0x1}

func (bh *Header) read(r io.Reader) error {
	var (
		lText, nRef int32
		err         error
	)
	var magic [4]byte
	err = binary.Read(r, Endian, &magic)
	if err != nil {
		return err
	}
	if magic != bamMagic {
		return errors.New("bam: magic number mismatch")
	}
	err = binary.Read(r, Endian, &lText)
	if err != nil {
		return err
	}
	text := make([]byte, lText)
	n, err := r.Read(text)
	if err != nil {
		return err
	}
	if n != int(lText) {
		return errors.New("bam: truncated header")
	}
	err = bh.parseHeader(text)
	if err != nil {
		return err
	}
	err = binary.Read(r, Endian, &nRef)
	if err != nil {
		return err
	}
	refs, err := readRefRecords(r, nRef)
	if err != nil {
		return err
	}
	for _, r := range refs {
		err = bh.AddReference(r)
		if err != nil {
			return err
		}
	}
	return nil
}

func readRefRecords(r io.Reader, n int32) ([]*Reference, error) {
	rr := make([]*Reference, n)
	var (
		lName int32
		err   error
	)
	for i := range rr {
		rr[i] = &Reference{id: int32(i)}
		err = binary.Read(r, Endian, &lName)
		if err != nil {
			return nil, err
		}
		name := make([]byte, lName)
		n, err := r.Read(name)
		if err != nil {
			return nil, err
		}
		if n != int(lName) || name[n-1] != 0 {
			return nil, errors.New("bam: truncated reference name")
		}
		rr[i].name = string(name[:n-1])
		err = binary.Read(r, Endian, &rr[i].lRef)
		if err != nil {
			return nil, err
		}
	}
	return rr, nil
}

func (bh *Header) parseHeader(text []byte) error {
	var t tag
	for i, l := range bytes.Split(text, []byte{'\n'}) {
		if len(l) > 0 && l[len(l)-1] == '\r' {
			l = l[:len(l)-1]
		}
		if len(l) == 0 {
			continue
		}
		if l[0] != '@' || len(l) < 3 {
			return badHeader
		}
		copy(t[:], l[1:3])
		var err error
		switch {
		case t == headerTag:
			err = headerLine(l, bh)
		case t == refDictTag:
			err = referenceLine(l, bh)
		case t == readGroupTag:
			err = readGroupLine(l, bh)
		case t == programTag:
			err = programLine(l, bh)
		case t == commentTag:
			err = commentLine(l, bh)
		default:
			return badHeader
		}
		if err != nil {
			return fmt.Errorf("%v: line %d: %q", err, i+1, l)
		}
	}

	return nil
}

func headerLine(l []byte, bh *Header) error {
	fields := bytes.Split(l, []byte{'\t'})
	if len(fields) < 2 {
		return badHeader
	}

	var t tag
	for _, f := range fields[1:] {
		if f[2] != ':' {
			return badHeader
		}
		copy(t[:], f[:2])
		fs := string(f[3:])
		switch {
		case t == versionTag:
			if bh.Version != "" {
				return badHeader
			}
			bh.Version = fs
		case t == sortOrderTag:
			if bh.SortOrder != UnknownOrder {
				return badHeader
			}
			bh.SortOrder = sortOrderMap[fs]
		case t == groupOrderTag:
			if bh.GroupOrder != GroupUnspecified {
				return badHeader
			}
			bh.GroupOrder = groupOrderMap[fs]
		default:
			return badHeader
		}
	}

	if bh.Version == "" {
		return badHeader
	}

	return nil
}

func referenceLine(l []byte, bh *Header) error {
	fields := bytes.Split(l, []byte{'\t'})
	if len(fields) < 3 {
		return badHeader
	}

	var (
		t        tag
		rf       = &Reference{}
		seen     = map[tag]struct{}{}
		nok, lok bool
		dupID    int32
		dup      bool
	)

	for _, f := range fields[1:] {
		if f[2] != ':' {
			return badHeader
		}
		copy(t[:], f[:2])
		if _, ok := seen[t]; ok {
			return dupTag
		}
		seen[t] = struct{}{}
		fs := string(f[3:])
		switch {
		case t == refNameTag:
			dupID, dup = bh.seenRefs[fs]
			rf.name = fs
			nok = true
		case t == refLengthTag:
			l, err := strconv.Atoi(fs)
			if err != nil {
				return badHeader
			}
			if !validLen(l) {
				return badLen
			}
			rf.lRef = int32(l)
			lok = true
		case t == assemblyIDTag:
			rf.assemID = fs
		case t == md5Tag:
			hb := [16]byte{}
			n, err := hex.Decode(hb[:], f[3:])
			if err != nil {
				return err
			}
			if n != 16 {
				return badHeader
			}
			rf.md5 = &hb
		case t == speciesTag:
			rf.species = fs
		case t == uriTag:
			var err error
			rf.uri, err = url.Parse(fs)
			if err != nil {
				return err
			}
			if rf.uri.Scheme != "http" || rf.uri.Scheme != "ftp" {
				rf.uri.Scheme = "file"
			}
		default:
			return badHeader
		}
	}

	if dup {
		if er := bh.refs[dupID]; *er == *rf {
			return nil
		} else if tr := (Reference{id: er.id, name: er.name, lRef: er.lRef}); *er != tr {
			return dupReference
		}
		bh.refs[dupID] = rf
		return nil
	}
	if !nok || !lok {
		return badHeader
	}
	id := int32(len(bh.refs))
	rf.id = id
	bh.seenRefs[rf.name] = id
	bh.refs = append(bh.refs, rf)

	return nil
}

// http://en.wikipedia.org/wiki/ISO_8601
//
// Date: 2014-08-13
// Time: 2014-08-13T16:02:01Z
//     : 2014-08-13T16:02:01+00:00
//
const (
	iso8601Date      = "2006-01-02"
	iso8601TimeDateZ = "2006-01-02T15:04:05Z"
	iso8601TimeDateN = "2006-01-02T15:04:05-0700"
)

var iso8601 = []string{iso8601Date, iso8601TimeDateZ, iso8601TimeDateN}

func readGroupLine(l []byte, bh *Header) error {
	fields := bytes.Split(l, []byte{'\t'})
	if len(fields) < 2 {
		return badHeader
	}

	var (
		t    tag
		rg   = &ReadGroup{}
		seen = map[tag]struct{}{}
		idok bool
	)

L:
	for _, f := range fields[1:] {
		if f[2] != ':' {
			return badHeader
		}
		copy(t[:], f[:2])
		if _, ok := seen[t]; ok {
			return dupTag
		}
		seen[t] = struct{}{}
		fs := string(f[3:])
		switch {
		case t == idTag:
			if _, ok := bh.seenRefs[fs]; ok {
				return dupReadGroup
			}
			rg.name = fs
			idok = true
		case t == centerTag:
			rg.center = fs
		case t == descriptionTag:
			rg.description = fs
		case t == dateTag:
			var err error
			for _, tf := range iso8601 {
				rg.date, err = time.ParseInLocation(tf, fs, nil)
				if err == nil {
					continue L
				}
			}
			return err
		case t == flowOrderTag:
			rg.flowOrder = append([]byte(nil), fs...)
		case t == keySequenceTag:
			rg.keySeq = append([]byte(nil), fs...)
		case t == libraryTag:
			rg.library = fs
		case t == programTag:
			rg.program = fs
		case t == insertSizeTag:
			i, err := strconv.Atoi(fs)
			if err != nil {
				return err
			}
			if !validInt32(i) {
				return badLen
			}
			rg.insertSize = i
		case t == platformTag:
			rg.platform = fs
		case t == platformUnitTag:
			rg.platformUnit = fs
		case t == sampleTag:
			rg.sample = fs
		default:
			return badHeader
		}
	}

	if !idok {
		return badHeader
	}
	id := int32(len(bh.rgs))
	rg.id = id
	bh.seenGroups[rg.name] = id
	bh.rgs = append(bh.rgs, rg)

	return nil
}

func programLine(l []byte, bh *Header) error {
	fields := bytes.Split(l, []byte{'\t'})
	if len(fields) < 2 {
		return badHeader
	}

	var (
		t    tag
		p    = &Program{}
		seen = map[tag]struct{}{}
		idok bool
	)

	for _, f := range fields[1:] {
		if f[2] != ':' {
			return badHeader
		}
		copy(t[:], f[:2])
		if _, ok := seen[t]; ok {
			return dupTag
		}
		seen[t] = struct{}{}
		fs := string(f[3:])
		switch {
		case t == idTag:
			if _, ok := bh.seenProgs[fs]; ok {
				return dupProgram
			}
			p.uid = fs
			idok = true
		case t == programNameTag:
			p.name = fs
		case t == commandLineTag:
			p.command = fs
		case t == previousProgTag:
			p.previous = fs
		case t == versionTag:
			p.version = fs
		default:
			return badHeader
		}
	}

	if !idok {
		return badHeader
	}
	id := int32(len(bh.progs))
	p.id = id
	bh.seenProgs[p.uid] = id
	bh.progs = append(bh.progs, p)

	return nil
}

func commentLine(l []byte, bh *Header) error {
	fields := bytes.Split(l, []byte{'\t'})
	if len(fields) < 2 {
		return badHeader
	}
	bh.Comments = append(bh.Comments, string(fields[1]))
	return nil
}
<|endoftext|>


<commit_before>package connection

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"time"

	"github.com/cloudfoundry-incubator/garden"
	"github.com/cloudfoundry-incubator/garden/routes"
	"github.com/tedsuo/rata"
)

type DialerFunc func(network, address string) (net.Conn, error)

type hijackable struct {
	req               *rata.RequestGenerator
	noKeepaliveClient *http.Client
	dialer            DialerFunc
}

func NewHijackStreamer(network, address string) HijackStreamer {
	return NewHijackStreamerWithDialer(func(string, string) (net.Conn, error) {
		return net.DialTimeout(network, address, time.Second)
	})
}

func NewHijackStreamerWithDialer(dialFunc DialerFunc) HijackStreamer {
	return &hijackable{
		req:    rata.NewRequestGenerator("http://api", routes.Routes),
		dialer: dialFunc,
		noKeepaliveClient: &http.Client{
			Transport: &http.Transport{
				Dial:              dialFunc,
				DisableKeepAlives: true,
			},
		},
	}
}

func (h *hijackable) Hijack(handler string, body io.Reader, params rata.Params, query url.Values, contentType string) (net.Conn, *bufio.Reader, error) {
	request, err := h.req.CreateRequest(handler, params, body)
	if err != nil {
		return nil, nil, err
	}

	if contentType != "" {
		request.Header.Set("Content-Type", contentType)
	}

	if query != nil {
		request.URL.RawQuery = query.Encode()
	}

	conn, err := h.dialer("tcp", "api") // net/addr don't matter here
	if err != nil {
		return nil, nil, err
	}

	client := httputil.NewClientConn(conn, nil)

	httpResp, err := client.Do(request)
	if err != nil {
		return nil, nil, err
	}

	if httpResp.StatusCode < 200 || httpResp.StatusCode > 299 {
		defer httpResp.Body.Close()

		errRespBytes, err := ioutil.ReadAll(httpResp.Body)
		if err != nil {
			return nil, nil, fmt.Errorf("Backend error: Exit status: %d, error reading response body: %s", httpResp.StatusCode, err)
		}

		return nil, nil, fmt.Errorf("Backend error: Exit status: %d, message: %s", httpResp.StatusCode, errRespBytes)
	}

	hijackedConn, hijackedResponseReader := client.Hijack()

	return hijackedConn, hijackedResponseReader, nil
}

func (c *hijackable) Stream(handler string, body io.Reader, params rata.Params, query url.Values, contentType string) (io.ReadCloser, error) {
	request, err := c.req.CreateRequest(handler, params, body)
	if err != nil {
		return nil, err
	}

	if contentType != "" {
		request.Header.Set("Content-Type", contentType)
	}

	if query != nil {
		request.URL.RawQuery = query.Encode()
	}

	httpResp, err := c.noKeepaliveClient.Do(request)
	if err != nil {
		return nil, err
	}

	if httpResp.StatusCode < 200 || httpResp.StatusCode > 299 {
		var result garden.Error
		err := json.NewDecoder(httpResp.Body).Decode(&result)
		if err != nil {
			return nil, fmt.Errorf("bad response: %s", err)
		}

		return nil, result.Err
	}

	return httpResp.Body, nil
}
<commit_msg>Bump dialer timeout<commit_after>package connection

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"time"

	"github.com/cloudfoundry-incubator/garden"
	"github.com/cloudfoundry-incubator/garden/routes"
	"github.com/tedsuo/rata"
)

type DialerFunc func(network, address string) (net.Conn, error)

type hijackable struct {
	req               *rata.RequestGenerator
	noKeepaliveClient *http.Client
	dialer            DialerFunc
}

func NewHijackStreamer(network, address string) HijackStreamer {
	return NewHijackStreamerWithDialer(func(string, string) (net.Conn, error) {
		return net.DialTimeout(network, address, 2*time.Second)
	})
}

func NewHijackStreamerWithDialer(dialFunc DialerFunc) HijackStreamer {
	return &hijackable{
		req:    rata.NewRequestGenerator("http://api", routes.Routes),
		dialer: dialFunc,
		noKeepaliveClient: &http.Client{
			Transport: &http.Transport{
				Dial:              dialFunc,
				DisableKeepAlives: true,
			},
		},
	}
}

func (h *hijackable) Hijack(handler string, body io.Reader, params rata.Params, query url.Values, contentType string) (net.Conn, *bufio.Reader, error) {
	request, err := h.req.CreateRequest(handler, params, body)
	if err != nil {
		return nil, nil, err
	}

	if contentType != "" {
		request.Header.Set("Content-Type", contentType)
	}

	if query != nil {
		request.URL.RawQuery = query.Encode()
	}

	conn, err := h.dialer("tcp", "api") // net/addr don't matter here
	if err != nil {
		return nil, nil, err
	}

	client := httputil.NewClientConn(conn, nil)

	httpResp, err := client.Do(request)
	if err != nil {
		return nil, nil, err
	}

	if httpResp.StatusCode < 200 || httpResp.StatusCode > 299 {
		defer httpResp.Body.Close()

		errRespBytes, err := ioutil.ReadAll(httpResp.Body)
		if err != nil {
			return nil, nil, fmt.Errorf("Backend error: Exit status: %d, error reading response body: %s", httpResp.StatusCode, err)
		}

		return nil, nil, fmt.Errorf("Backend error: Exit status: %d, message: %s", httpResp.StatusCode, errRespBytes)
	}

	hijackedConn, hijackedResponseReader := client.Hijack()

	return hijackedConn, hijackedResponseReader, nil
}

func (c *hijackable) Stream(handler string, body io.Reader, params rata.Params, query url.Values, contentType string) (io.ReadCloser, error) {
	request, err := c.req.CreateRequest(handler, params, body)
	if err != nil {
		return nil, err
	}

	if contentType != "" {
		request.Header.Set("Content-Type", contentType)
	}

	if query != nil {
		request.URL.RawQuery = query.Encode()
	}

	httpResp, err := c.noKeepaliveClient.Do(request)
	if err != nil {
		return nil, err
	}

	if httpResp.StatusCode < 200 || httpResp.StatusCode > 299 {
		var result garden.Error
		err := json.NewDecoder(httpResp.Body).Decode(&result)
		if err != nil {
			return nil, fmt.Errorf("bad response: %s", err)
		}

		return nil, result.Err
	}

	return httpResp.Body, nil
}
<|endoftext|>