<commit_before>package gorm

import (
	"errors"
	"strings"
)

var (
	// ErrRecordNotFound record not found error, happens when haven't find any matched data when looking up with a struct
	ErrRecordNotFound = errors.New("record not found")
	// ErrInvalidSQL invalid SQL error, happens when you passed invalid SQL
	ErrInvalidSQL = errors.New("invalid SQL")
	// ErrInvalidTransaction invalid transaction when you are trying to `Commit` or `Rollback`
	ErrInvalidTransaction = errors.New("no valid transaction")
	// ErrCantStartTransaction can't start transaction when you are trying to start one with `Begin`
	ErrCantStartTransaction = errors.New("can't start transaction")
	// ErrUnaddressable unaddressable value
	ErrUnaddressable = errors.New("using unaddressable value")
)

// Errors contains all happened errors
type Errors []error

// IsRecordNotFoundError returns current error has record not found error or not
func IsRecordNotFoundError(err error) bool {
	if errs, ok := err.(Errors); ok {
		for _, err := range errs {
			if err == ErrRecordNotFound {
				return true
			}
		}
	}
	return err == ErrRecordNotFound
}

// GetErrors gets all happened errors
func (errs Errors) GetErrors() []error {
	return errs
}

// Add adds an error
func (errs Errors) Add(newErrors ...error) Errors {
	for _, err := range newErrors {
		if err == nil {
			continue
		}

		if errors, ok := err.(Errors); ok {
			errs = errs.Add(errors...)
		} else {
			ok = true
			for _, e := range errs {
				if err == e {
					ok = false
				}
			}
			if ok {
				errs = append(errs, err)
			}
		}
	}
	return errs
}

// Error format happened errors
func (errs Errors) Error() string {
	var errors = []string{}
	for _, e := range errs {
		errors = append(errors, e.Error())
	}
	return strings.Join(errors, "; ")
}
<commit_msg>doc: document ErrRecordNotFound error more clear (#2015)<commit_after>package gorm

import (
	"errors"
	"strings"
)

var (
	// ErrRecordNotFound record not found error, happens when only haven't find any matched data when looking up with a struct, finding a slice won't return this error
	ErrRecordNotFound = errors.New("record not found")
	// ErrInvalidSQL invalid SQL error, happens when you passed invalid SQL
	ErrInvalidSQL = errors.New("invalid SQL")
	// ErrInvalidTransaction invalid transaction when you are trying to `Commit` or `Rollback`
	ErrInvalidTransaction = errors.New("no valid transaction")
	// ErrCantStartTransaction can't start transaction when you are trying to start one with `Begin`
	ErrCantStartTransaction = errors.New("can't start transaction")
	// ErrUnaddressable unaddressable value
	ErrUnaddressable = errors.New("using unaddressable value")
)

// Errors contains all happened errors
type Errors []error

// IsRecordNotFoundError returns current error has record not found error or not
func IsRecordNotFoundError(err error) bool {
	if errs, ok := err.(Errors); ok {
		for _, err := range errs {
			if err == ErrRecordNotFound {
				return true
			}
		}
	}
	return err == ErrRecordNotFound
}

// GetErrors gets all happened errors
func (errs Errors) GetErrors() []error {
	return errs
}

// Add adds an error
func (errs Errors) Add(newErrors ...error) Errors {
	for _, err := range newErrors {
		if err == nil {
			continue
		}

		if errors, ok := err.(Errors); ok {
			errs = errs.Add(errors...)
		} else {
			ok = true
			for _, e := range errs {
				if err == e {
					ok = false
				}
			}
			if ok {
				errs = append(errs, err)
			}
		}
	}
	return errs
}

// Error format happened errors
func (errs Errors) Error() string {
	var errors = []string{}
	for _, e := range errs {
		errors = append(errors, e.Error())
	}
	return strings.Join(errors, "; ")
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 Kohei YOSHIDA. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of The BSD 3-Clause License
// that can be found in the LICENSE file.

package uritemplate

import (
	"bytes"
	"strings"
	"unicode"
	"unicode/utf8"
)

var (
	hex = []byte("0123456789ABCDEF")
	// reserved   = gen-delims / sub-delims
	// gen-delims =  ":" / "/" / "?" / "#" / "[" / "]" / "@"
	// sub-delims =  "!" / "$" / "&" / "’" / "(" / ")"
	//            /  "*" / "+" / "," / ";" / "="
	rangeReserved = &unicode.RangeTable{
		R16: []unicode.Range16{
			unicode.Range16{Lo: 0x21, Hi: 0x21, Stride: 1}, // '!'
			unicode.Range16{Lo: 0x23, Hi: 0x24, Stride: 1}, // '#' - '$'
			unicode.Range16{Lo: 0x26, Hi: 0x2C, Stride: 1}, // '&' - ','
			unicode.Range16{Lo: 0x2F, Hi: 0x2F, Stride: 1}, // '/'
			unicode.Range16{Lo: 0x3A, Hi: 0x3B, Stride: 1}, // ':' - ';'
			unicode.Range16{Lo: 0x3D, Hi: 0x3D, Stride: 1}, // '='
			unicode.Range16{Lo: 0x3F, Hi: 0x40, Stride: 1}, // '?' - '@'
			unicode.Range16{Lo: 0x5B, Hi: 0x5B, Stride: 1}, // '['
			unicode.Range16{Lo: 0x5D, Hi: 0x5D, Stride: 1}, // ']'
		},
		LatinOffset: 9,
	}
	reReserved = `\x21\x23\x24\x26-\x2c\x2f\x3a\x3b\x3d\x3f\x40\x5b\x5d`
	// ALPHA      = %x41-5A / %x61-7A
	// DIGIT      = %x30-39
	// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
	rangeUnreserved = &unicode.RangeTable{
		R16: []unicode.Range16{
			unicode.Range16{Lo: 0x2D, Hi: 0x2E, Stride: 1}, // '-' - '.'
			unicode.Range16{Lo: 0x30, Hi: 0x39, Stride: 1}, // '0' - '9'
			unicode.Range16{Lo: 0x41, Hi: 0x5A, Stride: 1}, // 'A' - 'Z'
			unicode.Range16{Lo: 0x5F, Hi: 0x5F, Stride: 1}, // '_'
			unicode.Range16{Lo: 0x61, Hi: 0x7A, Stride: 1}, // 'a' - 'z'
			unicode.Range16{Lo: 0x7E, Hi: 0x7E, Stride: 1}, // '~'
		},
	}
	reUnreserved = `\x2d\x2e\x30-\x39\x41-\x5a\x5f\x61-\x7a\x7e`
)

type runeClass uint8

const (
	runeClassU runeClass = 1 << iota
	runeClassR
	runeClassPctE
	runeClassLast

	runeClassUR = runeClassU | runeClassR
)

var runeClassNames = []string{
	"U",
	"R",
	"pct-encoded",
}

func (rc runeClass) String() string {
	ret := make([]string, 0, len(runeClassNames))
	for i, j := 0, runeClass(1); j < runeClassLast; j <<= 1 {
		if rc&j == j {
			ret = append(ret, runeClassNames[i])
		}
		i++
	}
	return strings.Join(ret, "+")
}

func pctEncode(w *bytes.Buffer, r rune) {
	if s := r >> 24 & 0xff; s > 0 {
		w.Write([]byte{'%', hex[s/16], hex[s%16]})
	}
	if s := r >> 16 & 0xff; s > 0 {
		w.Write([]byte{'%', hex[s/16], hex[s%16]})
	}
	if s := r >> 8 & 0xff; s > 0 {
		w.Write([]byte{'%', hex[s/16], hex[s%16]})
	}
	if s := r & 0xff; s > 0 {
		w.Write([]byte{'%', hex[s/16], hex[s%16]})
	}
}

type escapeFunc func(*bytes.Buffer, string) error

func escapeLiteral(w *bytes.Buffer, v string) error {
	w.WriteString(v)
	return nil
}

func escapeExceptU(w *bytes.Buffer, v string) error {
	for i := 0; i < len(v); {
		r, size := utf8.DecodeRuneInString(v[i:])
		if r == utf8.RuneError {
			return errorf(i, "invalid encoding")
		}
		if unicode.Is(rangeUnreserved, r) {
			w.WriteRune(r)
		} else {
			pctEncode(w, r)
		}
		i += size
	}
	return nil
}

func escapeExceptUR(w *bytes.Buffer, v string) error {
	for i := 0; i < len(v); {
		r, size := utf8.DecodeRuneInString(v[i:])
		if r == utf8.RuneError {
			return errorf(i, "invalid encoding")
		}
		// TODO(yosida95): is pct-encoded triplets allowed here?
		if unicode.In(r, rangeUnreserved, rangeReserved) {
			w.WriteRune(r)
		} else {
			pctEncode(w, r)
		}
		i += size
	}
	return nil
}
<commit_msg>implement pctDecode<commit_after>// Copyright (C) 2016 Kohei YOSHIDA. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of The BSD 3-Clause License
// that can be found in the LICENSE file.

package uritemplate

import (
	"bytes"
	"strings"
	"unicode"
	"unicode/utf8"
)

var (
	hex = []byte("0123456789ABCDEF")
	// reserved   = gen-delims / sub-delims
	// gen-delims =  ":" / "/" / "?" / "#" / "[" / "]" / "@"
	// sub-delims =  "!" / "$" / "&" / "’" / "(" / ")"
	//            /  "*" / "+" / "," / ";" / "="
	rangeReserved = &unicode.RangeTable{
		R16: []unicode.Range16{
			unicode.Range16{Lo: 0x21, Hi: 0x21, Stride: 1}, // '!'
			unicode.Range16{Lo: 0x23, Hi: 0x24, Stride: 1}, // '#' - '$'
			unicode.Range16{Lo: 0x26, Hi: 0x2C, Stride: 1}, // '&' - ','
			unicode.Range16{Lo: 0x2F, Hi: 0x2F, Stride: 1}, // '/'
			unicode.Range16{Lo: 0x3A, Hi: 0x3B, Stride: 1}, // ':' - ';'
			unicode.Range16{Lo: 0x3D, Hi: 0x3D, Stride: 1}, // '='
			unicode.Range16{Lo: 0x3F, Hi: 0x40, Stride: 1}, // '?' - '@'
			unicode.Range16{Lo: 0x5B, Hi: 0x5B, Stride: 1}, // '['
			unicode.Range16{Lo: 0x5D, Hi: 0x5D, Stride: 1}, // ']'
		},
		LatinOffset: 9,
	}
	reReserved = `\x21\x23\x24\x26-\x2c\x2f\x3a\x3b\x3d\x3f\x40\x5b\x5d`
	// ALPHA      = %x41-5A / %x61-7A
	// DIGIT      = %x30-39
	// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
	rangeUnreserved = &unicode.RangeTable{
		R16: []unicode.Range16{
			unicode.Range16{Lo: 0x2D, Hi: 0x2E, Stride: 1}, // '-' - '.'
			unicode.Range16{Lo: 0x30, Hi: 0x39, Stride: 1}, // '0' - '9'
			unicode.Range16{Lo: 0x41, Hi: 0x5A, Stride: 1}, // 'A' - 'Z'
			unicode.Range16{Lo: 0x5F, Hi: 0x5F, Stride: 1}, // '_'
			unicode.Range16{Lo: 0x61, Hi: 0x7A, Stride: 1}, // 'a' - 'z'
			unicode.Range16{Lo: 0x7E, Hi: 0x7E, Stride: 1}, // '~'
		},
	}
	reUnreserved = `\x2d\x2e\x30-\x39\x41-\x5a\x5f\x61-\x7a\x7e`
)

type runeClass uint8

const (
	runeClassU runeClass = 1 << iota
	runeClassR
	runeClassPctE
	runeClassLast

	runeClassUR = runeClassU | runeClassR
)

var runeClassNames = []string{
	"U",
	"R",
	"pct-encoded",
}

func (rc runeClass) String() string {
	ret := make([]string, 0, len(runeClassNames))
	for i, j := 0, runeClass(1); j < runeClassLast; j <<= 1 {
		if rc&j == j {
			ret = append(ret, runeClassNames[i])
		}
		i++
	}
	return strings.Join(ret, "+")
}

func pctEncode(w *bytes.Buffer, r rune) {
	if s := r >> 24 & 0xff; s > 0 {
		w.Write([]byte{'%', hex[s/16], hex[s%16]})
	}
	if s := r >> 16 & 0xff; s > 0 {
		w.Write([]byte{'%', hex[s/16], hex[s%16]})
	}
	if s := r >> 8 & 0xff; s > 0 {
		w.Write([]byte{'%', hex[s/16], hex[s%16]})
	}
	if s := r & 0xff; s > 0 {
		w.Write([]byte{'%', hex[s/16], hex[s%16]})
	}
}

func unhex(c byte) byte {
	switch {
	case '0' <= c && c <= '9':
		return c - '0'
	case 'a' <= c && c <= 'f':
		return c - 'a' + 10
	case 'A' <= c && c <= 'F':
		return c - 'A' + 10
	}
	return 0
}

func pctDecode(s string) string {
	size := len(s)
	for i := 0; i < len(s); {
		switch s[i] {
		case '%':
			size -= 2
			i += 3
		default:
			i++
		}
	}
	if size == len(s) {
		return s
	}

	buf := make([]byte, size)
	j := 0
	for i := 0; i < len(s); {
		switch c := s[i]; c {
		case '%':
			buf[j] = unhex(s[i+1])<<4 | unhex(s[i+2])
			i += 3
			j++
		default:
			buf[j] = c
			i++
			j++
		}
	}
	return string(buf)
}

type escapeFunc func(*bytes.Buffer, string) error

func escapeLiteral(w *bytes.Buffer, v string) error {
	w.WriteString(v)
	return nil
}

func escapeExceptU(w *bytes.Buffer, v string) error {
	for i := 0; i < len(v); {
		r, size := utf8.DecodeRuneInString(v[i:])
		if r == utf8.RuneError {
			return errorf(i, "invalid encoding")
		}
		if unicode.Is(rangeUnreserved, r) {
			w.WriteRune(r)
		} else {
			pctEncode(w, r)
		}
		i += size
	}
	return nil
}

func escapeExceptUR(w *bytes.Buffer, v string) error {
	for i := 0; i < len(v); {
		r, size := utf8.DecodeRuneInString(v[i:])
		if r == utf8.RuneError {
			return errorf(i, "invalid encoding")
		}
		// TODO(yosida95): is pct-encoded triplets allowed here?
		if unicode.In(r, rangeUnreserved, rangeReserved) {
			w.WriteRune(r)
		} else {
			pctEncode(w, r)
		}
		i += size
	}
	return nil
}
<|endoftext|>


<commit_before>package dom

import (
	"time"

	"github.com/gopherjs/gopherjs/js"
)

func WrapEvent(o *js.Object) Event {
	return wrapEvent(o)
}

func wrapEvent(o *js.Object) Event {
	if o == nil || o == js.Undefined {
		return nil
	}
	ev := &BasicEvent{o}
	c := o.Get("constructor")
	switch c {
	case js.Global.Get("AnimationEvent"):
		return &AnimationEvent{ev}
	case js.Global.Get("AudioProcessingEvent"):
		return &AudioProcessingEvent{ev}
	case js.Global.Get("BeforeInputEvent"):
		return &BeforeInputEvent{ev}
	case js.Global.Get("BeforeUnloadEvent"):
		return &BeforeUnloadEvent{ev}
	case js.Global.Get("BlobEvent"):
		return &BlobEvent{ev}
	case js.Global.Get("ClipboardEvent"):
		return &ClipboardEvent{ev}
	case js.Global.Get("CloseEvent"):
		return &CloseEvent{BasicEvent: ev}
	case js.Global.Get("CompositionEvent"):
		return &CompositionEvent{ev}
	case js.Global.Get("CSSFontFaceLoadEvent"):
		return &CSSFontFaceLoadEvent{ev}
	case js.Global.Get("CustomEvent"):
		return &CustomEvent{ev}
	case js.Global.Get("DeviceLightEvent"):
		return &DeviceLightEvent{ev}
	case js.Global.Get("DeviceMotionEvent"):
		return &DeviceMotionEvent{ev}
	case js.Global.Get("DeviceOrientationEvent"):
		return &DeviceOrientationEvent{ev}
	case js.Global.Get("DeviceProximityEvent"):
		return &DeviceProximityEvent{ev}
	case js.Global.Get("DOMTransactionEvent"):
		return &DOMTransactionEvent{ev}
	case js.Global.Get("DragEvent"):
		return &DragEvent{ev}
	case js.Global.Get("EditingBeforeInputEvent"):
		return &EditingBeforeInputEvent{ev}
	case js.Global.Get("ErrorEvent"):
		return &ErrorEvent{ev}
	case js.Global.Get("FocusEvent"):
		return &FocusEvent{ev}
	case js.Global.Get("GamepadEvent"):
		return &GamepadEvent{ev}
	case js.Global.Get("HashChangeEvent"):
		return &HashChangeEvent{ev}
	case js.Global.Get("IDBVersionChangeEvent"):
		return &IDBVersionChangeEvent{ev}
	case js.Global.Get("KeyboardEvent"):
		return &KeyboardEvent{BasicEvent: ev}
	case js.Global.Get("MediaStreamEvent"):
		return &MediaStreamEvent{ev}
	case js.Global.Get("MessageEvent"):
		return &MessageEvent{BasicEvent: ev}
	case js.Global.Get("MouseEvent"):
		return &MouseEvent{UIEvent: &UIEvent{ev}}
	case js.Global.Get("MutationEvent"):
		return &MutationEvent{ev}
	case js.Global.Get("OfflineAudioCompletionEvent"):
		return &OfflineAudioCompletionEvent{ev}
	case js.Global.Get("PageTransitionEvent"):
		return &PageTransitionEvent{ev}
	case js.Global.Get("PointerEvent"):
		return &PointerEvent{ev}
	case js.Global.Get("PopStateEvent"):
		return &PopStateEvent{ev}
	case js.Global.Get("ProgressEvent"):
		return &ProgressEvent{ev}
	case js.Global.Get("RelatedEvent"):
		return &RelatedEvent{ev}
	case js.Global.Get("RTCPeerConnectionIceEvent"):
		return &RTCPeerConnectionIceEvent{ev}
	case js.Global.Get("SensorEvent"):
		return &SensorEvent{ev}
	case js.Global.Get("StorageEvent"):
		return &StorageEvent{ev}
	case js.Global.Get("SVGEvent"):
		return &SVGEvent{ev}
	case js.Global.Get("SVGZoomEvent"):
		return &SVGZoomEvent{ev}
	case js.Global.Get("TimeEvent"):
		return &TimeEvent{ev}
	case js.Global.Get("TouchEvent"):
		return &TouchEvent{ev}
	case js.Global.Get("TrackEvent"):
		return &TrackEvent{ev}
	case js.Global.Get("TransitionEvent"):
		return &TransitionEvent{ev}
	case js.Global.Get("UIEvent"):
		return &UIEvent{ev}
	case js.Global.Get("UserProximityEvent"):
		return &UserProximityEvent{ev}
	case js.Global.Get("WheelEvent"):
		return &WheelEvent{BasicEvent: ev}
	default:
		return ev
	}
}

const (
	EvPhaseNone      = 0
	EvPhaseCapturing = 1
	EvPhaseAtTarget  = 2
	EvPhaseBubbling  = 3
)

type Event interface {
	Bubbles() bool
	Cancelable() bool
	CurrentTarget() Element
	DefaultPrevented() bool
	EventPhase() int
	Target() Element
	Timestamp() time.Time
	Type() string
	PreventDefault()
	StopImmediatePropagation()
	StopPropagation()
}

// Type BasicEvent implements the Event interface and is embedded by
// concrete event types.
type BasicEvent struct{ *js.Object }

func (ev *BasicEvent) Bubbles() bool {
	return ev.Get("bubbles").Bool()
}

func (ev *BasicEvent) Cancelable() bool {
	return ev.Get("cancelable").Bool()
}

func (ev *BasicEvent) CurrentTarget() Element {
	return wrapElement(ev.Get("currentTarget"))
}

func (ev *BasicEvent) DefaultPrevented() bool {
	return ev.Get("defaultPrevented").Bool()
}

func (ev *BasicEvent) EventPhase() int {
	return ev.Get("eventPhase").Int()
}

func (ev *BasicEvent) Target() Element {
	return wrapElement(ev.Get("target"))
}

func (ev *BasicEvent) Timestamp() time.Time {
	ms := ev.Get("timeStamp").Int()
	s := ms / 1000
	ns := (ms % 1000 * 1e6)
	return time.Unix(int64(s), int64(ns))
}

func (ev *BasicEvent) Type() string {
	return ev.Get("type").String()
}

func (ev *BasicEvent) PreventDefault() {
	ev.Call("preventDefault")
}

func (ev *BasicEvent) StopImmediatePropagation() {
	ev.Call("stopImmediatePropagation")
}

func (ev *BasicEvent) StopPropagation() {
	ev.Call("stopPropagation")
}

type AnimationEvent struct{ *BasicEvent }
type AudioProcessingEvent struct{ *BasicEvent }
type BeforeInputEvent struct{ *BasicEvent }
type BeforeUnloadEvent struct{ *BasicEvent }
type BlobEvent struct{ *BasicEvent }
type ClipboardEvent struct{ *BasicEvent }

type CloseEvent struct {
	*BasicEvent
	Code     int    `js:"code"`
	Reason   string `js:"reason"`
	WasClean bool   `js:"wasClean"`
}

type CompositionEvent struct{ *BasicEvent }
type CSSFontFaceLoadEvent struct{ *BasicEvent }
type CustomEvent struct{ *BasicEvent }
type DeviceLightEvent struct{ *BasicEvent }
type DeviceMotionEvent struct{ *BasicEvent }
type DeviceOrientationEvent struct{ *BasicEvent }
type DeviceProximityEvent struct{ *BasicEvent }
type DOMTransactionEvent struct{ *BasicEvent }
type DragEvent struct{ *BasicEvent }
type EditingBeforeInputEvent struct{ *BasicEvent }
type ErrorEvent struct{ *BasicEvent }
type FocusEvent struct{ *BasicEvent }
type GamepadEvent struct{ *BasicEvent }
type HashChangeEvent struct{ *BasicEvent }
type IDBVersionChangeEvent struct{ *BasicEvent }

const (
	KeyLocationStandard = 0
	KeyLocationLeft     = 1
	KeyLocationRight    = 2
	KeyLocationNumpad   = 3
)

type KeyboardEvent struct {
	*BasicEvent
	AltKey        bool   `js:"altKey"`
	CharCode      int    `js:"charCode"`
	CtrlKey       bool   `js:"ctrlKey"`
	Key           string `js:"key"`
	KeyIdentifier string `js:"keyIdentifier"`
	KeyCode       int    `js:"keyCode"`
	Locale        string `js:"locale"`
	Location      int    `js:"location"`
	KeyLocation   int    `js:"keyLocation"`
	MetaKey       bool   `js:"metaKey"`
	Repeat        bool   `js:"repeat"`
	ShiftKey      bool   `js:"shiftKey"`
}

func (ev *KeyboardEvent) ModifierState(mod string) bool {
	return ev.Call("getModifierState", mod).Bool()
}

type MediaStreamEvent struct{ *BasicEvent }

type MessageEvent struct {
	*BasicEvent
	Data *js.Object `js:"data"`
}

type MouseEvent struct {
	*UIEvent
	AltKey    bool `js:"altKey"`
	Button    int  `js:"button"`
	ClientX   int  `js:"clientX"`
	ClientY   int  `js:"clientY"`
	CtrlKey   bool `js:"ctrlKey"`
	MetaKey   bool `js:"metaKey"`
	MovementX int  `js:"movementX"`
	MovementY int  `js:"movementY"`
	ScreenX   int  `js:"screenX"`
	ScreenY   int  `js:"screenY"`
	ShiftKey  bool `js:"shiftKey"`
}

func (ev *MouseEvent) RelatedTarget() Element {
	return wrapElement(ev.Get("target"))
}

func (ev *MouseEvent) ModifierState(mod string) bool {
	return ev.Call("getModifierState", mod).Bool()
}

type MutationEvent struct{ *BasicEvent }
type OfflineAudioCompletionEvent struct{ *BasicEvent }
type PageTransitionEvent struct{ *BasicEvent }
type PointerEvent struct{ *BasicEvent }
type PopStateEvent struct{ *BasicEvent }
type ProgressEvent struct{ *BasicEvent }
type RelatedEvent struct{ *BasicEvent }
type RTCPeerConnectionIceEvent struct{ *BasicEvent }
type SensorEvent struct{ *BasicEvent }
type StorageEvent struct{ *BasicEvent }
type SVGEvent struct{ *BasicEvent }
type SVGZoomEvent struct{ *BasicEvent }
type TimeEvent struct{ *BasicEvent }
type TouchEvent struct{ *BasicEvent }
type TrackEvent struct{ *BasicEvent }
type TransitionEvent struct{ *BasicEvent }
type UIEvent struct{ *BasicEvent }
type UserProximityEvent struct{ *BasicEvent }

const (
	DeltaPixel = 0
	DeltaLine  = 1
	DeltaPage  = 2
)

type WheelEvent struct {
	*BasicEvent
	DeltaX    float64 `js:"deltaX"`
	DeltaY    float64 `js:"deltaY"`
	DeltaZ    float64 `js:"deltaZ"`
	DeltaMode int     `js:"deltaMode"`
}

type EventTarget interface {
	// AddEventListener adds a new event listener and returns the
	// wrapper function it generated. If using RemoveEventListener,
	// that wrapper has to be used.
	AddEventListener(typ string, useCapture bool, listener func(Event)) func(*js.Object)
	RemoveEventListener(typ string, useCapture bool, listener func(*js.Object))
	// DispatchEvent() // TODO
}
<commit_msg>Add Underlying method to Event interface<commit_after>package dom

import (
	"time"

	"github.com/gopherjs/gopherjs/js"
)

func WrapEvent(o *js.Object) Event {
	return wrapEvent(o)
}

func wrapEvent(o *js.Object) Event {
	if o == nil || o == js.Undefined {
		return nil
	}
	ev := &BasicEvent{o}
	c := o.Get("constructor")
	switch c {
	case js.Global.Get("AnimationEvent"):
		return &AnimationEvent{ev}
	case js.Global.Get("AudioProcessingEvent"):
		return &AudioProcessingEvent{ev}
	case js.Global.Get("BeforeInputEvent"):
		return &BeforeInputEvent{ev}
	case js.Global.Get("BeforeUnloadEvent"):
		return &BeforeUnloadEvent{ev}
	case js.Global.Get("BlobEvent"):
		return &BlobEvent{ev}
	case js.Global.Get("ClipboardEvent"):
		return &ClipboardEvent{ev}
	case js.Global.Get("CloseEvent"):
		return &CloseEvent{BasicEvent: ev}
	case js.Global.Get("CompositionEvent"):
		return &CompositionEvent{ev}
	case js.Global.Get("CSSFontFaceLoadEvent"):
		return &CSSFontFaceLoadEvent{ev}
	case js.Global.Get("CustomEvent"):
		return &CustomEvent{ev}
	case js.Global.Get("DeviceLightEvent"):
		return &DeviceLightEvent{ev}
	case js.Global.Get("DeviceMotionEvent"):
		return &DeviceMotionEvent{ev}
	case js.Global.Get("DeviceOrientationEvent"):
		return &DeviceOrientationEvent{ev}
	case js.Global.Get("DeviceProximityEvent"):
		return &DeviceProximityEvent{ev}
	case js.Global.Get("DOMTransactionEvent"):
		return &DOMTransactionEvent{ev}
	case js.Global.Get("DragEvent"):
		return &DragEvent{ev}
	case js.Global.Get("EditingBeforeInputEvent"):
		return &EditingBeforeInputEvent{ev}
	case js.Global.Get("ErrorEvent"):
		return &ErrorEvent{ev}
	case js.Global.Get("FocusEvent"):
		return &FocusEvent{ev}
	case js.Global.Get("GamepadEvent"):
		return &GamepadEvent{ev}
	case js.Global.Get("HashChangeEvent"):
		return &HashChangeEvent{ev}
	case js.Global.Get("IDBVersionChangeEvent"):
		return &IDBVersionChangeEvent{ev}
	case js.Global.Get("KeyboardEvent"):
		return &KeyboardEvent{BasicEvent: ev}
	case js.Global.Get("MediaStreamEvent"):
		return &MediaStreamEvent{ev}
	case js.Global.Get("MessageEvent"):
		return &MessageEvent{BasicEvent: ev}
	case js.Global.Get("MouseEvent"):
		return &MouseEvent{UIEvent: &UIEvent{ev}}
	case js.Global.Get("MutationEvent"):
		return &MutationEvent{ev}
	case js.Global.Get("OfflineAudioCompletionEvent"):
		return &OfflineAudioCompletionEvent{ev}
	case js.Global.Get("PageTransitionEvent"):
		return &PageTransitionEvent{ev}
	case js.Global.Get("PointerEvent"):
		return &PointerEvent{ev}
	case js.Global.Get("PopStateEvent"):
		return &PopStateEvent{ev}
	case js.Global.Get("ProgressEvent"):
		return &ProgressEvent{ev}
	case js.Global.Get("RelatedEvent"):
		return &RelatedEvent{ev}
	case js.Global.Get("RTCPeerConnectionIceEvent"):
		return &RTCPeerConnectionIceEvent{ev}
	case js.Global.Get("SensorEvent"):
		return &SensorEvent{ev}
	case js.Global.Get("StorageEvent"):
		return &StorageEvent{ev}
	case js.Global.Get("SVGEvent"):
		return &SVGEvent{ev}
	case js.Global.Get("SVGZoomEvent"):
		return &SVGZoomEvent{ev}
	case js.Global.Get("TimeEvent"):
		return &TimeEvent{ev}
	case js.Global.Get("TouchEvent"):
		return &TouchEvent{ev}
	case js.Global.Get("TrackEvent"):
		return &TrackEvent{ev}
	case js.Global.Get("TransitionEvent"):
		return &TransitionEvent{ev}
	case js.Global.Get("UIEvent"):
		return &UIEvent{ev}
	case js.Global.Get("UserProximityEvent"):
		return &UserProximityEvent{ev}
	case js.Global.Get("WheelEvent"):
		return &WheelEvent{BasicEvent: ev}
	default:
		return ev
	}
}

const (
	EvPhaseNone      = 0
	EvPhaseCapturing = 1
	EvPhaseAtTarget  = 2
	EvPhaseBubbling  = 3
)

type Event interface {
	Bubbles() bool
	Cancelable() bool
	CurrentTarget() Element
	DefaultPrevented() bool
	EventPhase() int
	Target() Element
	Timestamp() time.Time
	Type() string
	PreventDefault()
	StopImmediatePropagation()
	StopPropagation()
	Underlying() *js.Object
}

// Type BasicEvent implements the Event interface and is embedded by
// concrete event types.
type BasicEvent struct{ *js.Object }

func (ev *BasicEvent) Bubbles() bool {
	return ev.Get("bubbles").Bool()
}

func (ev *BasicEvent) Cancelable() bool {
	return ev.Get("cancelable").Bool()
}

func (ev *BasicEvent) CurrentTarget() Element {
	return wrapElement(ev.Get("currentTarget"))
}

func (ev *BasicEvent) DefaultPrevented() bool {
	return ev.Get("defaultPrevented").Bool()
}

func (ev *BasicEvent) EventPhase() int {
	return ev.Get("eventPhase").Int()
}

func (ev *BasicEvent) Target() Element {
	return wrapElement(ev.Get("target"))
}

func (ev *BasicEvent) Timestamp() time.Time {
	ms := ev.Get("timeStamp").Int()
	s := ms / 1000
	ns := (ms % 1000 * 1e6)
	return time.Unix(int64(s), int64(ns))
}

func (ev *BasicEvent) Type() string {
	return ev.Get("type").String()
}

func (ev *BasicEvent) PreventDefault() {
	ev.Call("preventDefault")
}

func (ev *BasicEvent) StopImmediatePropagation() {
	ev.Call("stopImmediatePropagation")
}

func (ev *BasicEvent) StopPropagation() {
	ev.Call("stopPropagation")
}

func (ev *BasicEvent) Underlying() *js.Object {
	return ev.Object
}

type AnimationEvent struct{ *BasicEvent }
type AudioProcessingEvent struct{ *BasicEvent }
type BeforeInputEvent struct{ *BasicEvent }
type BeforeUnloadEvent struct{ *BasicEvent }
type BlobEvent struct{ *BasicEvent }
type ClipboardEvent struct{ *BasicEvent }

type CloseEvent struct {
	*BasicEvent
	Code     int    `js:"code"`
	Reason   string `js:"reason"`
	WasClean bool   `js:"wasClean"`
}

type CompositionEvent struct{ *BasicEvent }
type CSSFontFaceLoadEvent struct{ *BasicEvent }
type CustomEvent struct{ *BasicEvent }
type DeviceLightEvent struct{ *BasicEvent }
type DeviceMotionEvent struct{ *BasicEvent }
type DeviceOrientationEvent struct{ *BasicEvent }
type DeviceProximityEvent struct{ *BasicEvent }
type DOMTransactionEvent struct{ *BasicEvent }
type DragEvent struct{ *BasicEvent }
type EditingBeforeInputEvent struct{ *BasicEvent }
type ErrorEvent struct{ *BasicEvent }
type FocusEvent struct{ *BasicEvent }
type GamepadEvent struct{ *BasicEvent }
type HashChangeEvent struct{ *BasicEvent }
type IDBVersionChangeEvent struct{ *BasicEvent }

const (
	KeyLocationStandard = 0
	KeyLocationLeft     = 1
	KeyLocationRight    = 2
	KeyLocationNumpad   = 3
)

type KeyboardEvent struct {
	*BasicEvent
	AltKey        bool   `js:"altKey"`
	CharCode      int    `js:"charCode"`
	CtrlKey       bool   `js:"ctrlKey"`
	Key           string `js:"key"`
	KeyIdentifier string `js:"keyIdentifier"`
	KeyCode       int    `js:"keyCode"`
	Locale        string `js:"locale"`
	Location      int    `js:"location"`
	KeyLocation   int    `js:"keyLocation"`
	MetaKey       bool   `js:"metaKey"`
	Repeat        bool   `js:"repeat"`
	ShiftKey      bool   `js:"shiftKey"`
}

func (ev *KeyboardEvent) ModifierState(mod string) bool {
	return ev.Call("getModifierState", mod).Bool()
}

type MediaStreamEvent struct{ *BasicEvent }

type MessageEvent struct {
	*BasicEvent
	Data *js.Object `js:"data"`
}

type MouseEvent struct {
	*UIEvent
	AltKey    bool `js:"altKey"`
	Button    int  `js:"button"`
	ClientX   int  `js:"clientX"`
	ClientY   int  `js:"clientY"`
	CtrlKey   bool `js:"ctrlKey"`
	MetaKey   bool `js:"metaKey"`
	MovementX int  `js:"movementX"`
	MovementY int  `js:"movementY"`
	ScreenX   int  `js:"screenX"`
	ScreenY   int  `js:"screenY"`
	ShiftKey  bool `js:"shiftKey"`
}

func (ev *MouseEvent) RelatedTarget() Element {
	return wrapElement(ev.Get("target"))
}

func (ev *MouseEvent) ModifierState(mod string) bool {
	return ev.Call("getModifierState", mod).Bool()
}

type MutationEvent struct{ *BasicEvent }
type OfflineAudioCompletionEvent struct{ *BasicEvent }
type PageTransitionEvent struct{ *BasicEvent }
type PointerEvent struct{ *BasicEvent }
type PopStateEvent struct{ *BasicEvent }
type ProgressEvent struct{ *BasicEvent }
type RelatedEvent struct{ *BasicEvent }
type RTCPeerConnectionIceEvent struct{ *BasicEvent }
type SensorEvent struct{ *BasicEvent }
type StorageEvent struct{ *BasicEvent }
type SVGEvent struct{ *BasicEvent }
type SVGZoomEvent struct{ *BasicEvent }
type TimeEvent struct{ *BasicEvent }
type TouchEvent struct{ *BasicEvent }
type TrackEvent struct{ *BasicEvent }
type TransitionEvent struct{ *BasicEvent }
type UIEvent struct{ *BasicEvent }
type UserProximityEvent struct{ *BasicEvent }

const (
	DeltaPixel = 0
	DeltaLine  = 1
	DeltaPage  = 2
)

type WheelEvent struct {
	*BasicEvent
	DeltaX    float64 `js:"deltaX"`
	DeltaY    float64 `js:"deltaY"`
	DeltaZ    float64 `js:"deltaZ"`
	DeltaMode int     `js:"deltaMode"`
}

type EventTarget interface {
	// AddEventListener adds a new event listener and returns the
	// wrapper function it generated. If using RemoveEventListener,
	// that wrapper has to be used.
	AddEventListener(typ string, useCapture bool, listener func(Event)) func(*js.Object)
	RemoveEventListener(typ string, useCapture bool, listener func(*js.Object))
	// DispatchEvent() // TODO
}
<|endoftext|>


<commit_before>package webhook

import (
	"github.com/aetrion/dnsimple-go/dnsimple"
)

func switchEvent(name string, payload []byte) (Event, error) {
	var event Event

	switch name {
	case // contact
		"contact.create",
		"contact.update",
		"contact.delete":
		event = &ContactEvent{}
	case // domain
		"domain.auto_renewal_enable",
		"domain.auto_renewal_disable",
		"domain.create",
		"domain.delete",
		"domain.register",
		"domain.renew",
		"domain.delegation_change",  // TODO
		"domain.registrant_change",  // TODO
		"domain.resolution_enable",  // TODO
		"domain.resolution_disable", // TODO
		"domain.token_reset",
		"domain.transfer": // TODO
		event = &DomainEvent{}
	case // webhook
		"webhook.create",
		"webhook.delete":
		event = &WebhookEvent{}
	case // zone record
		"record.create",
		"record.update",
		"record.delete":
		event = &ZoneRecordEvent{}
	default:
		event = &GenericEvent{}
	}

	return event, event.parse(payload)
}

//
// GenericEvent represents a generic event, where the data is a simple map of strings.
//
type GenericEvent struct {
	Event_Header
	Data interface{} `json:"data"`
}

func (e *GenericEvent) parse(payload []byte) error {
	e.payload = payload
	return unmashalEvent(payload, e)
}

// ParseGenericEvent unpacks the data into a GenericEvent.
func ParseGenericEvent(e *GenericEvent, payload []byte) error {
	return e.parse(payload)
}

//
// ContactEvent represents the base event sent for a contact action.
//
type ContactEvent struct {
	Event_Header
	Data    *ContactEvent     `json:"data"`
	Contact *dnsimple.Contact `json:"contact"`
}

// ParseContactEvent unpacks the data into a ContactEvent.
func ParseContactEvent(e *ContactEvent, payload []byte) error {
	return e.parse(payload)
}

func (e *ContactEvent) parse(payload []byte) error {
	e.payload, e.Data = payload, e
	return unmashalEvent(payload, e)
}

//
// DomainEvent represents the base event sent for a domain action.
//
type DomainEvent struct {
	Event_Header
	Data   *DomainEvent     `json:"data"`
	Domain *dnsimple.Domain `json:"domain"`
}

// ParseDomainEvent unpacks the payload into a DomainEvent.
func ParseDomainEvent(e *DomainEvent, payload []byte) error {
	return e.parse(payload)
}

func (e *DomainEvent) parse(payload []byte) error {
	e.payload, e.Data = payload, e
	return unmashalEvent(payload, e)
}

//
// ZoneRecordEvent represents the base event sent for a webhook action.
//
type ZoneRecordEvent struct {
	Event_Header
	Data       *ZoneRecordEvent     `json:"data"`
	ZoneRecord *dnsimple.ZoneRecord `json:"record"`
}

// ParseZoneRecordEvent unpacks the data into a ZoneRecordEvent.
func ParseZoneRecordEvent(e *ZoneRecordEvent, payload []byte) error {
	return e.parse(payload)
}

func (e *ZoneRecordEvent) parse(payload []byte) error {
	e.payload, e.Data = payload, e
	return unmashalEvent(payload, e)
}

//
// WebhookEvent represents the base event sent for a webhook action.
//
type WebhookEvent struct {
	Event_Header
	Data    *WebhookEvent     `json:"data"`
	Webhook *dnsimple.Webhook `json:"webhook"`
}

// ParseWebhookEvent unpacks the data into a WebhookEvent.
func ParseWebhookEvent(e *WebhookEvent, payload []byte) error {
	return e.parse(payload)
}

func (e *WebhookEvent) parse(payload []byte) error {
	e.payload, e.Data = payload, e
	return unmashalEvent(payload, e)
}
<commit_msg>webhook: Support Account events<commit_after>package webhook

import (
	"github.com/aetrion/dnsimple-go/dnsimple"
)

func switchEvent(name string, payload []byte) (Event, error) {
	var event Event

	switch name {
	case // account
		"account.update",                  // TODO
		"account.billing_settings_update", // TODO
		"account.payment_details_update",  // TODO
		"account.add_user",                // TODO
		"account.remove_user":             // TODO
		event = &AccountEvent{}
	case // contact
		"contact.create",
		"contact.update",
		"contact.delete":
		event = &ContactEvent{}
	case // domain
		"domain.auto_renewal_enable",
		"domain.auto_renewal_disable",
		"domain.create",
		"domain.delete",
		"domain.register",
		"domain.renew",
		"domain.delegation_change",  // TODO
		"domain.registrant_change",  // TODO
		"domain.resolution_enable",  // TODO
		"domain.resolution_disable", // TODO
		"domain.token_reset",
		"domain.transfer": // TODO
		event = &DomainEvent{}
	case // webhook
		"webhook.create",
		"webhook.delete":
		event = &WebhookEvent{}
	case // zone record
		"record.create",
		"record.update",
		"record.delete":
		event = &ZoneRecordEvent{}
	default:
		event = &GenericEvent{}
	}

	return event, event.parse(payload)
}

//
// GenericEvent
//

// GenericEvent represents a generic event, where the data is a simple map of strings.
type GenericEvent struct {
	Event_Header
	Data interface{} `json:"data"`
}

func (e *GenericEvent) parse(payload []byte) error {
	e.payload = payload
	return unmashalEvent(payload, e)
}

// ParseGenericEvent unpacks the data into a GenericEvent.
func ParseGenericEvent(e *GenericEvent, payload []byte) error {
	return e.parse(payload)
}

//
// AccountEvent
//

// AccountEvent represents the base event sent for an account action.
type AccountEvent struct {
	Event_Header
	Data    *AccountEvent     `json:"data"`
	Account *dnsimple.Account `json:"account"`
}

// ParseAccountEvent unpacks the data into an AccountEvent.
func ParseAccountEvent(e *AccountEvent, payload []byte) error {
	return e.parse(payload)
}

func (e *AccountEvent) parse(payload []byte) error {
	e.payload, e.Data = payload, e
	return unmashalEvent(payload, e)
}

//
// ContactEvent
//

// ContactEvent represents the base event sent for a contact action.
type ContactEvent struct {
	Event_Header
	Data    *ContactEvent     `json:"data"`
	Contact *dnsimple.Contact `json:"contact"`
}

// ParseContactEvent unpacks the data into a ContactEvent.
func ParseContactEvent(e *ContactEvent, payload []byte) error {
	return e.parse(payload)
}

func (e *ContactEvent) parse(payload []byte) error {
	e.payload, e.Data = payload, e
	return unmashalEvent(payload, e)
}

//
// DomainEvent
//

// DomainEvent represents the base event sent for a domain action.
type DomainEvent struct {
	Event_Header
	Data   *DomainEvent     `json:"data"`
	Domain *dnsimple.Domain `json:"domain"`
}

// ParseDomainEvent unpacks the payload into a DomainEvent.
func ParseDomainEvent(e *DomainEvent, payload []byte) error {
	return e.parse(payload)
}

func (e *DomainEvent) parse(payload []byte) error {
	e.payload, e.Data = payload, e
	return unmashalEvent(payload, e)
}

//
// ZoneRecordEvent
//

// ZoneRecordEvent represents the base event sent for a webhook action.
type ZoneRecordEvent struct {
	Event_Header
	Data       *ZoneRecordEvent     `json:"data"`
	ZoneRecord *dnsimple.ZoneRecord `json:"record"`
}

// ParseZoneRecordEvent unpacks the data into a ZoneRecordEvent.
func ParseZoneRecordEvent(e *ZoneRecordEvent, payload []byte) error {
	return e.parse(payload)
}

func (e *ZoneRecordEvent) parse(payload []byte) error {
	e.payload, e.Data = payload, e
	return unmashalEvent(payload, e)
}

//
// WebhookEvent
//

// WebhookEvent represents the base event sent for a webhook action.
type WebhookEvent struct {
	Event_Header
	Data    *WebhookEvent     `json:"data"`
	Webhook *dnsimple.Webhook `json:"webhook"`
}

// ParseWebhookEvent unpacks the data into a WebhookEvent.
func ParseWebhookEvent(e *WebhookEvent, payload []byte) error {
	return e.parse(payload)
}

func (e *WebhookEvent) parse(payload []byte) error {
	e.payload, e.Data = payload, e
	return unmashalEvent(payload, e)
}
<|endoftext|>


<commit_before>/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

    * Neither the name of "The Computer Language Benchmarks Game" nor the
    name of "The Computer Language Shootout Benchmarks" nor the names of
    its contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

/* The Computer Language Benchmarks Game
 * http://shootout.alioth.debian.org/
 *
 * contributed by The Go Authors.
 * Based on C program by Joern Inge Vestgaarden
 * and Jorge Peixoto de Morais Neto.
 */

package main

import (
	"bufio";
	"flag";
	"os";
	"strings";
)

var out *bufio.Writer

var n = flag.Int("n", 1000, "length of result")

const WIDTH = 60	// Fold lines after WIDTH bytes

func min(a, b int) int {
	if a < b {
		return a
	}
	return b;
}

type AminoAcid struct {
	p	float;
	c	byte;
}

var lastrandom uint32 = 42

// Random number between 0.0 and 1.0
func myrandom() float {
	const (
		IM	= 139968;
		IA	= 3877;
		IC	= 29573;
	)
	lastrandom = (lastrandom*IA + IC) % IM;
	// Integer to float conversions are faster if the integer is signed.
	return float(int32(lastrandom)) / IM;
}

func AccumulateProbabilities(genelist []AminoAcid) {
	for i := 1; i < len(genelist); i++ {
		genelist[i].p += genelist[i-1].p
	}
}

// RepeatFasta prints the characters of the byte slice s. When it
// reaches the end of the slice, it goes back to the beginning.
// It stops after generating count characters.
// After each WIDTH characters it prints a newline.
// It assumes that WIDTH <= len(s) + 1.
func RepeatFasta(s []byte, count int) {
	pos := 0;
	s2 := make([]byte, len(s)+WIDTH);
	copy(s2, s);
	copy(s2[len(s):], s);
	for count > 0 {
		line := min(WIDTH, count);
		out.Write(s2[pos : pos+line]);
		out.WriteByte('\n');
		pos += line;
		if pos >= len(s) {
			pos -= len(s)
		}
		count -= line;
	}
}

// Each element of genelist is a struct with a character and
// a floating point number p between 0 and 1.
// RandomFasta generates a random float r and
// finds the first element such that p >= r.
// This is a weighted random selection.
// RandomFasta then prints the character of the array element.
// This sequence is repeated count times.
// Between each WIDTH consecutive characters, the function prints a newline.
func RandomFasta(genelist []AminoAcid, count int) {
	buf := make([]byte, WIDTH+1);
	for count > 0 {
		line := min(WIDTH, count);
		for pos := 0; pos < line; pos++ {
			r := myrandom();
			var i int;
			for i = 0; genelist[i].p < r; i++ {
			}
			buf[pos] = genelist[i].c;
		}
		buf[line] = '\n';
		out.Write(buf[0 : line+1]);
		count -= line;
	}
}

func main() {
	out = bufio.NewWriter(os.Stdout);
	defer out.Flush();

	flag.Parse();

	iub := []AminoAcid{
		AminoAcid{0.27, 'a'},
		AminoAcid{0.12, 'c'},
		AminoAcid{0.12, 'g'},
		AminoAcid{0.27, 't'},
		AminoAcid{0.02, 'B'},
		AminoAcid{0.02, 'D'},
		AminoAcid{0.02, 'H'},
		AminoAcid{0.02, 'K'},
		AminoAcid{0.02, 'M'},
		AminoAcid{0.02, 'N'},
		AminoAcid{0.02, 'R'},
		AminoAcid{0.02, 'S'},
		AminoAcid{0.02, 'V'},
		AminoAcid{0.02, 'W'},
		AminoAcid{0.02, 'Y'},
	};

	homosapiens := []AminoAcid{
		AminoAcid{0.3029549426680, 'a'},
		AminoAcid{0.1979883004921, 'c'},
		AminoAcid{0.1975473066391, 'g'},
		AminoAcid{0.3015094502008, 't'},
	};

	AccumulateProbabilities(iub);
	AccumulateProbabilities(homosapiens);

	alu := strings.Bytes(
		"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"
			"GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"
			"CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"
			"ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA"
			"GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG"
			"AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC"
			"AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA");

	out.WriteString(">ONE Homo sapiens alu\n");
	RepeatFasta(alu, 2**n);
	out.WriteString(">TWO IUB ambiguity codes\n");
	RandomFasta(iub, 3**n);
	out.WriteString(">THREE Homo sapiens frequency\n");
	RandomFasta(homosapiens, 5**n);
}
<commit_msg>test/bench: faster fasta (mostly due to bufio fix)<commit_after>/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

    * Neither the name of "The Computer Language Benchmarks Game" nor the
    name of "The Computer Language Shootout Benchmarks" nor the names of
    its contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

/* The Computer Language Benchmarks Game
 * http://shootout.alioth.debian.org/
 *
 * contributed by The Go Authors.
 * Based on C program by Joern Inge Vestgaarden
 * and Jorge Peixoto de Morais Neto.
 */

package main

import (
	"bufio";
	"flag";
	"os";
	"strings";
)

var out *bufio.Writer

var n = flag.Int("n", 1000, "length of result")

const WIDTH = 60	// Fold lines after WIDTH bytes

func min(a, b int) int {
	if a < b {
		return a
	}
	return b;
}

type AminoAcid struct {
	p	float;
	c	byte;
}

func AccumulateProbabilities(genelist []AminoAcid) {
	for i := 1; i < len(genelist); i++ {
		genelist[i].p += genelist[i-1].p
	}
}

// RepeatFasta prints the characters of the byte slice s. When it
// reaches the end of the slice, it goes back to the beginning.
// It stops after generating count characters.
// After each WIDTH characters it prints a newline.
// It assumes that WIDTH <= len(s) + 1.
func RepeatFasta(s []byte, count int) {
	pos := 0;
	s2 := make([]byte, len(s)+WIDTH);
	copy(s2, s);
	copy(s2[len(s):], s);
	for count > 0 {
		line := min(WIDTH, count);
		out.Write(s2[pos : pos+line]);
		out.WriteByte('\n');
		pos += line;
		if pos >= len(s) {
			pos -= len(s)
		}
		count -= line;
	}
}

var lastrandom uint32 = 42

const (
	IM	= 139968;
	IA	= 3877;
	IC	= 29573;
)

// Each element of genelist is a struct with a character and
// a floating point number p between 0 and 1.
// RandomFasta generates a random float r and
// finds the first element such that p >= r.
// This is a weighted random selection.
// RandomFasta then prints the character of the array element.
// This sequence is repeated count times.
// Between each WIDTH consecutive characters, the function prints a newline.
func RandomFasta(genelist []AminoAcid, count int) {
	buf := make([]byte, WIDTH+1);
	for count > 0 {
		line := min(WIDTH, count);
		for pos := 0; pos < line; pos++ {
			lastrandom = (lastrandom*IA + IC) % IM;
			// Integer to float conversions are faster if the integer is signed.
			r := float(int32(lastrandom)) / IM;
			for _, v := range genelist {
				if v.p >= r {
					buf[pos] = v.c;
					break;
				}
			}
		}
		buf[line] = '\n';
		out.Write(buf[0 : line+1]);
		count -= line;
	}
}

func main() {
	out = bufio.NewWriter(os.Stdout);
	defer out.Flush();

	flag.Parse();

	iub := []AminoAcid{
		AminoAcid{0.27, 'a'},
		AminoAcid{0.12, 'c'},
		AminoAcid{0.12, 'g'},
		AminoAcid{0.27, 't'},
		AminoAcid{0.02, 'B'},
		AminoAcid{0.02, 'D'},
		AminoAcid{0.02, 'H'},
		AminoAcid{0.02, 'K'},
		AminoAcid{0.02, 'M'},
		AminoAcid{0.02, 'N'},
		AminoAcid{0.02, 'R'},
		AminoAcid{0.02, 'S'},
		AminoAcid{0.02, 'V'},
		AminoAcid{0.02, 'W'},
		AminoAcid{0.02, 'Y'},
	};

	homosapiens := []AminoAcid{
		AminoAcid{0.3029549426680, 'a'},
		AminoAcid{0.1979883004921, 'c'},
		AminoAcid{0.1975473066391, 'g'},
		AminoAcid{0.3015094502008, 't'},
	};

	AccumulateProbabilities(iub);
	AccumulateProbabilities(homosapiens);

	alu := strings.Bytes(
		"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"
			"GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"
			"CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"
			"ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA"
			"GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG"
			"AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC"
			"AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA");

	out.WriteString(">ONE Homo sapiens alu\n");
	RepeatFasta(alu, 2**n);
	out.WriteString(">TWO IUB ambiguity codes\n");
	RandomFasta(iub, 3**n);
	out.WriteString(">THREE Homo sapiens frequency\n");
	RandomFasta(homosapiens, 5**n);
}
<|endoftext|>


<commit_before>package nxcore

import (
	"encoding/json"
	"fmt"
	"net"
	"sync"
	"sync/atomic"
	"time"

	"github.com/jaracil/ei"
	"github.com/jaracil/smartio"
	"golang.org/x/net/context"
)

const (
	ErrParse            = -32700
	ErrInvalidRequest   = -32600
	ErrInternal         = -32603
	ErrInvalidParams    = -32602
	ErrMethodNotFound   = -32601
	ErrTtlExpired       = -32011
	ErrPermissionDenied = -32010
	ErrConnClosed       = -32007
	ErrLockNotOwned     = -32006
	ErrUserExists       = -32005
	ErrInvalidUser      = -32004
	ErrInvalidPipe      = -32003
	ErrInvalidTask      = -32002
	ErrCancel           = -32001
	ErrTimeout          = -32000
)

var ErrStr = map[int]string{
	ErrParse:            "Parse error",
	ErrInvalidRequest:   "Invalid request",
	ErrMethodNotFound:   "Method not found",
	ErrInvalidParams:    "Invalid params",
	ErrInternal:         "Internal error",
	ErrTimeout:          "Timeout",
	ErrCancel:           "Cancel",
	ErrInvalidTask:      "Invalid task",
	ErrInvalidPipe:      "Invalid pipe",
	ErrInvalidUser:      "Invalid user",
	ErrUserExists:       "User already exists",
	ErrPermissionDenied: "Permission denied",
	ErrTtlExpired:       "TTL expired",
	ErrLockNotOwned:     "Lock not owned",
	ErrConnClosed:       "Connection is closed",
}

type JsonRpcErr struct {
	Cod  int         `json:"code"`
	Mess string      `json:"message"`
	Dat  interface{} `json:"data,omitempty"`
}

func (e *JsonRpcErr) Error() string {
	return fmt.Sprintf("[%d] %s", e.Cod, e.Mess)
}

func (e *JsonRpcErr) Code() int {
	return e.Cod
}

func (e *JsonRpcErr) Data() interface{} {
	return e.Dat
}

// NewJsonRpcErr creates new JSON-RPC error.
//
// code is the JSON-RPC error code.
// message is optional in case of well known error code (negative values).
// data is an optional extra info object.
func NewJsonRpcErr(code int, message string, data interface{}) error {
	if code < 0 {
		if errstr, ok := ErrStr[code]; ok {
			if message != "" {
				message = fmt.Sprintf("%s:[%s]", errstr, message)
			} else {
				message = errstr
			}
		}
	}

	return &JsonRpcErr{Cod: code, Mess: message, Dat: data}
}

type JsonRpcReq struct {
	Jsonrpc string      `json:"jsonrpc"`
	Id      uint64      `json:"id,omitempty"`
	Method  string      `json:"method"`
	Params  interface{} `json:"params"`
	nc      *NexusConn
}

type JsonRpcRes struct {
	Jsonrpc string      `json:"jsonrpc"`
	Id      uint64      `json:"id,omitempty"`
	Result  interface{} `json:"result,omitempty"`
	Error   *JsonRpcErr `json:"error,omitempty"`
}

// NexusConn represents the Nexus connection.
type NexusConn struct {
	connId            string
	conn              net.Conn
	connRx            *smartio.SmartReader
	connTx            *smartio.SmartWriter
	reqCount          uint64
	resTable          map[uint64]chan *JsonRpcRes
	resTableLock      sync.Mutex
	chReq             chan *JsonRpcReq
	closed            int32 //Goroutine safe bool
	context           context.Context
	cancelFun         context.CancelFunc
	wdog              int64
	NexusVersion      *NxVersion
	inactivityTimeout time.Duration
	inactivityTimer   *time.Timer
}

type NxVersion struct {
	Major int
	Minor int
	Patch int
}

func (v *NxVersion) String() string {
	return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
}

// Task represents a task pushed to Nexus.
type Task struct {
	nc           *NexusConn
	Id           string                 `json:"id"`
	Stat         string                 `json:"state""`
	Path         string                 `json:"path"`
	Prio         int                    `json:"priority"`
	Ttl          int                    `json:"ttl"`
	Detach       bool                   `json:"detached"`
	User         string                 `json:"user"`
	Method       string                 `json:"method"`
	Params       interface{}            `json:"params"`
	LocalId      interface{}            `json:"-"`
	Tses         string                 `json:"targetSession"`
	Result       interface{}            `json:"result"`
	ErrCode      *int                   `json:"errCode"`
	ErrStr       string                 `json:"errString"`
	ErrObj       interface{}            `json:"errObject"`
	Tags         map[string]interface{} `json:"tags"`
	CreationTime time.Time              `json:"creationTime"`
	DeadLine     time.Time              `json:"deadline"`
}

// TaskOpts represents task push options.
type TaskOpts struct {
	// Task priority default 0 (Set negative value for lower priority)
	Priority int
	// Task ttl default 5
	Ttl int
	// Task detach. If true, task is detached from creating session.
	// If task is detached and creating session deads, task is not removed from tasks queue.
	Detach bool
}

// Pipe represents a pipe.
// Pipes can only be read from the connection that created them and
// can be written from any conection.
type Pipe struct {
	nc        *NexusConn
	pipeId    string
	context   context.Context
	cancelFun context.CancelFunc
}

// Msg represents a pipe single message
type Msg struct {
	Count int64       // Message counter (unique and correlative)
	Msg   interface{} // Pipe message
}

// PipeData represents a pipe messages group obtained in read ops.
type PipeData struct {
	Msgs    []*Msg // Messages
	Waiting int    // Number of messages waiting in Nexus server since last read
	Drops   int    // Number of messages dropped (pipe overflows) since last read
}

// TopicMsg represents a single topic message
type TopicMsg struct {
	Topic string      // Topic the message was published to
	Count int64       // Message counter (unique and correlative)
	Msg   interface{} // The message itself
}

// TopicData represents a topic messages group obtained in read ops.
type TopicData struct {
	Msgs    []*TopicMsg // Messages
	Waiting int         // Number of messages waiting in Nexus server since last read
	Drops   int         // Number of messages dropped (pipe overflows) since last read
}

// PipeOpts represents pipe creation options
type PipeOpts struct {
	Length int // Pipe buffer capacity
}

// NewNexusConn creates new nexus connection from net.conn
func NewNexusConn(conn net.Conn) *NexusConn {
	nc := &NexusConn{
		conn:              conn,
		connRx:            smartio.NewSmartReader(conn),
		connTx:            smartio.NewSmartWriter(conn),
		resTable:          make(map[uint64]chan *JsonRpcRes),
		chReq:             make(chan *JsonRpcReq, 16),
		wdog:              60,
		NexusVersion:      &NxVersion{0, 0, 0},
		inactivityTimeout: -1 * time.Second,
		inactivityTimer:   time.NewTimer(-1 * time.Second),
	}
	<-nc.inactivityTimer.C
	nc.context, nc.cancelFun = context.WithCancel(context.Background())
	go nc.sendWorker()
	go nc.recvWorker()
	go nc.mainWorker()
	return nc
}

func (nc *NexusConn) pushReq(req *JsonRpcReq) (err error) {
	select {
	case nc.chReq <- req:
	case <-nc.context.Done():
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
	}
	return
}

func (nc *NexusConn) pullReq() (req *JsonRpcReq, err error) {
	select {
	case req = <-nc.chReq:
	case <-nc.context.Done():
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
	}
	return
}

func (nc *NexusConn) mainWorker() {
	defer nc.Close()
	tick := time.NewTicker(10 * time.Second)
	defer tick.Stop()
	for {
		select {
		case <-nc.inactivityTimer.C:
			return
		case <-tick.C:
			now := time.Now().Unix()
			wdog := atomic.LoadInt64(&nc.wdog)
			max := wdog * 2
			if (now-nc.connRx.GetLast() > max) &&
				(now-nc.connTx.GetLast() > max) {
				return
			}
			if (now-nc.connRx.GetLast() >= wdog) &&
				(now-nc.connTx.GetLast() >= wdog) {
				if err := nc.Ping(10 * time.Second); err != nil {
					if time.Now().Unix()-nc.connTx.GetLast() > 5 {
						return
					}
				}
			}
		case <-nc.context.Done():
			return
		}
	}
}

func (nc *NexusConn) sendWorker() {
	defer nc.Close()
	for {
		req, err := nc.pullReq()
		if err != nil {
			break
		}
		req.Jsonrpc = "2.0"
		buf, err := json.Marshal(req)
		if err != nil {
			break
		}
		if !nc.Closed() {
			_, err = nc.connTx.Write(buf)
			if err != nil {
				break
			}
		} else {
			break
		}
	}
}

func (nc *NexusConn) recvWorker() {
	defer nc.Close()
	dec := json.NewDecoder(nc.connRx)
	for dec.More() {
		res := &JsonRpcRes{}
		err := dec.Decode(res)
		if err != nil {
			break
		}
		nc.resTableLock.Lock()
		ch := nc.resTable[res.Id]
		nc.resTableLock.Unlock()
		if ch != nil {
			select {
			case ch <- res:
			default:
			}
		}
	}
}

func (nc *NexusConn) newId() (uint64, chan *JsonRpcRes) {
	id := atomic.AddUint64(&nc.reqCount, 1)
	ch := make(chan *JsonRpcRes, 1)
	nc.resTableLock.Lock()
	defer nc.resTableLock.Unlock()
	nc.resTable[id] = ch
	return id, ch
}

func (nc *NexusConn) delId(id uint64) {
	nc.resTableLock.Lock()
	delete(nc.resTable, id)
	nc.resTableLock.Unlock()
}

// GetContext returns internal connection context.
func (nc *NexusConn) GetContext() context.Context {
	return nc.context
}

// Close closes nexus connection.
func (nc *NexusConn) Close() {
	if atomic.CompareAndSwapInt32(&nc.closed, 0, 1) {
		nc.cancelFun()
		nc.conn.Close()
	}
}

// Closed returns Nexus connection state.
func (nc *NexusConn) Closed() bool {
	return atomic.LoadInt32(&nc.closed) == 1
}

// ExecNoWait is a low level JSON-RPC call function, it don't wait response from server.
func (nc *NexusConn) ExecNoWait(method string, params interface{}) (id uint64, rch chan *JsonRpcRes, err error) {
	if nc.Closed() {
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
		return
	}

	if method != "sys.ping" && nc.inactivityTimeout != (-1*time.Second) {
		nc.inactivityTimer.Reset(nc.inactivityTimeout)
	}

	id, rch = nc.newId()
	req := &JsonRpcReq{
		Id:     id,
		Method: method,
		Params: params,
	}
	err = nc.pushReq(req)
	if err != nil {
		nc.delId(id)
		return 0, nil, err
	}
	return
}

// Exec is a low level JSON-RPC call function.
func (nc *NexusConn) Exec(method string, params interface{}) (result interface{}, err error) {
	id, rch, err := nc.ExecNoWait(method, params)
	if err != nil {
		return nil, err
	}
	defer nc.delId(id)
	select {
	case res := <-rch:
		if res.Error != nil {
			err = res.Error
		} else {
			result = res.Result
		}
	case <-nc.context.Done():
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
	}
	return
}

// Ping pings Nexus server, timeout is the max time waiting for server response,
// after that ErrTimeout is returned.
func (nc *NexusConn) Ping(timeout time.Duration) (err error) {
	id, rch, err := nc.ExecNoWait("sys.ping", nil)
	if err != nil {
		return
	}
	defer nc.delId(id)
	select {
	case <-rch:
		break
	case <-time.After(timeout):
		err = NewJsonRpcErr(ErrTimeout, "", nil)
	case <-nc.context.Done():
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
	}
	return
}

//SetSessionExpirationTimeout sets an expiration timeout. When it is reached the connection will be closed
func (nc *NexusConn) SetInactivityControl(timeout time.Duration) (err error) {
	if nc.Closed() {
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
		return
	}
	nc.inactivityTimeout = timeout
	nc.inactivityTimer = time.NewTimer(timeout)
	return
}

// Login attempts to login using user and pass.
// Returns the response object from Nexus or error.
func (nc *NexusConn) Login(user string, pass string) (interface{}, error) {
	par := map[string]interface{}{
		"user": user,
		"pass": pass,
	}
	res, err := nc.Exec("sys.login", par)
	if err != nil {
		return nil, err
	}
	nc.connId = ei.N(res).M("connid").StringZ()
	return res, nil
}

// Version retrieves the server version
// Returns the response object from Nexus or error.
func (nc *NexusConn) Version() (interface{}, error) {
	par := map[string]interface{}{}
	res, err := nc.Exec("sys.version", par)
	if err != nil {
		return nil, err
	}
	return res, nil
}

// Id returns the connection id after a login.
func (nc *NexusConn) Id() string {
	return nc.connId
}
<commit_msg>Added session inactivity control<commit_after>package nxcore

import (
	"encoding/json"
	"fmt"
	"net"
	"sync"
	"sync/atomic"
	"time"

	"github.com/jaracil/ei"
	"github.com/jaracil/smartio"
	"golang.org/x/net/context"
)

const (
	ErrParse            = -32700
	ErrInvalidRequest   = -32600
	ErrInternal         = -32603
	ErrInvalidParams    = -32602
	ErrMethodNotFound   = -32601
	ErrTtlExpired       = -32011
	ErrPermissionDenied = -32010
	ErrConnClosed       = -32007
	ErrLockNotOwned     = -32006
	ErrUserExists       = -32005
	ErrInvalidUser      = -32004
	ErrInvalidPipe      = -32003
	ErrInvalidTask      = -32002
	ErrCancel           = -32001
	ErrTimeout          = -32000
)

var ErrStr = map[int]string{
	ErrParse:            "Parse error",
	ErrInvalidRequest:   "Invalid request",
	ErrMethodNotFound:   "Method not found",
	ErrInvalidParams:    "Invalid params",
	ErrInternal:         "Internal error",
	ErrTimeout:          "Timeout",
	ErrCancel:           "Cancel",
	ErrInvalidTask:      "Invalid task",
	ErrInvalidPipe:      "Invalid pipe",
	ErrInvalidUser:      "Invalid user",
	ErrUserExists:       "User already exists",
	ErrPermissionDenied: "Permission denied",
	ErrTtlExpired:       "TTL expired",
	ErrLockNotOwned:     "Lock not owned",
	ErrConnClosed:       "Connection is closed",
}

type JsonRpcErr struct {
	Cod  int         `json:"code"`
	Mess string      `json:"message"`
	Dat  interface{} `json:"data,omitempty"`
}

func (e *JsonRpcErr) Error() string {
	return fmt.Sprintf("[%d] %s", e.Cod, e.Mess)
}

func (e *JsonRpcErr) Code() int {
	return e.Cod
}

func (e *JsonRpcErr) Data() interface{} {
	return e.Dat
}

// NewJsonRpcErr creates new JSON-RPC error.
//
// code is the JSON-RPC error code.
// message is optional in case of well known error code (negative values).
// data is an optional extra info object.
func NewJsonRpcErr(code int, message string, data interface{}) error {
	if code < 0 {
		if errstr, ok := ErrStr[code]; ok {
			if message != "" {
				message = fmt.Sprintf("%s:[%s]", errstr, message)
			} else {
				message = errstr
			}
		}
	}

	return &JsonRpcErr{Cod: code, Mess: message, Dat: data}
}

type JsonRpcReq struct {
	Jsonrpc string      `json:"jsonrpc"`
	Id      uint64      `json:"id,omitempty"`
	Method  string      `json:"method"`
	Params  interface{} `json:"params"`
	nc      *NexusConn
}

type JsonRpcRes struct {
	Jsonrpc string      `json:"jsonrpc"`
	Id      uint64      `json:"id,omitempty"`
	Result  interface{} `json:"result,omitempty"`
	Error   *JsonRpcErr `json:"error,omitempty"`
}

// NexusConn represents the Nexus connection.
type NexusConn struct {
	connId            string
	conn              net.Conn
	connRx            *smartio.SmartReader
	connTx            *smartio.SmartWriter
	reqCount          uint64
	resTable          map[uint64]chan *JsonRpcRes
	resTableLock      sync.Mutex
	chReq             chan *JsonRpcReq
	closed            int32 //Goroutine safe bool
	context           context.Context
	cancelFun         context.CancelFunc
	wdog              int64
	NexusVersion      *NxVersion
	inactivityTimeout time.Duration
	inactivityTimer   *time.Timer
}

type NxVersion struct {
	Major int
	Minor int
	Patch int
}

func (v *NxVersion) String() string {
	return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
}

// Task represents a task pushed to Nexus.
type Task struct {
	nc           *NexusConn
	Id           string                 `json:"id"`
	Stat         string                 `json:"state"`
	Path         string                 `json:"path"`
	Prio         int                    `json:"priority"`
	Ttl          int                    `json:"ttl"`
	Detach       bool                   `json:"detached"`
	User         string                 `json:"user"`
	Method       string                 `json:"method"`
	Params       interface{}            `json:"params"`
	LocalId      interface{}            `json:"-"`
	Tses         string                 `json:"targetSession"`
	Result       interface{}            `json:"result"`
	ErrCode      *int                   `json:"errCode"`
	ErrStr       string                 `json:"errString"`
	ErrObj       interface{}            `json:"errObject"`
	Tags         map[string]interface{} `json:"tags"`
	CreationTime time.Time              `json:"creationTime"`
	DeadLine     time.Time              `json:"deadline"`
}

// TaskOpts represents task push options.
type TaskOpts struct {
	// Task priority default 0 (Set negative value for lower priority)
	Priority int
	// Task ttl default 5
	Ttl int
	// Task detach. If true, task is detached from creating session.
	// If task is detached and creating session deads, task is not removed from tasks queue.
	Detach bool
}

// Pipe represents a pipe.
// Pipes can only be read from the connection that created them and
// can be written from any conection.
type Pipe struct {
	nc        *NexusConn
	pipeId    string
	context   context.Context
	cancelFun context.CancelFunc
}

// Msg represents a pipe single message
type Msg struct {
	Count int64       // Message counter (unique and correlative)
	Msg   interface{} // Pipe message
}

// PipeData represents a pipe messages group obtained in read ops.
type PipeData struct {
	Msgs    []*Msg // Messages
	Waiting int    // Number of messages waiting in Nexus server since last read
	Drops   int    // Number of messages dropped (pipe overflows) since last read
}

// TopicMsg represents a single topic message
type TopicMsg struct {
	Topic string      // Topic the message was published to
	Count int64       // Message counter (unique and correlative)
	Msg   interface{} // The message itself
}

// TopicData represents a topic messages group obtained in read ops.
type TopicData struct {
	Msgs    []*TopicMsg // Messages
	Waiting int         // Number of messages waiting in Nexus server since last read
	Drops   int         // Number of messages dropped (pipe overflows) since last read
}

// PipeOpts represents pipe creation options
type PipeOpts struct {
	Length int // Pipe buffer capacity
}

// NewNexusConn creates new nexus connection from net.conn
func NewNexusConn(conn net.Conn) *NexusConn {
	nc := &NexusConn{
		conn:              conn,
		connRx:            smartio.NewSmartReader(conn),
		connTx:            smartio.NewSmartWriter(conn),
		resTable:          make(map[uint64]chan *JsonRpcRes),
		chReq:             make(chan *JsonRpcReq, 16),
		wdog:              60,
		NexusVersion:      &NxVersion{0, 0, 0},
		inactivityTimeout: -1 * time.Second,
		inactivityTimer:   time.NewTimer(-1 * time.Second),
	}
	<-nc.inactivityTimer.C
	nc.context, nc.cancelFun = context.WithCancel(context.Background())
	go nc.sendWorker()
	go nc.recvWorker()
	go nc.mainWorker()
	return nc
}

func (nc *NexusConn) pushReq(req *JsonRpcReq) (err error) {
	select {
	case nc.chReq <- req:
	case <-nc.context.Done():
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
	}
	return
}

func (nc *NexusConn) pullReq() (req *JsonRpcReq, err error) {
	select {
	case req = <-nc.chReq:
	case <-nc.context.Done():
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
	}
	return
}

func (nc *NexusConn) mainWorker() {
	defer nc.Close()
	tick := time.NewTicker(10 * time.Second)
	defer tick.Stop()
	for {
		select {
		case <-nc.inactivityTimer.C:
			return
		case <-tick.C:
			now := time.Now().Unix()
			wdog := atomic.LoadInt64(&nc.wdog)
			max := wdog * 2
			if (now-nc.connRx.GetLast() > max) &&
				(now-nc.connTx.GetLast() > max) {
				return
			}
			if (now-nc.connRx.GetLast() >= wdog) &&
				(now-nc.connTx.GetLast() >= wdog) {
				if err := nc.Ping(10 * time.Second); err != nil {
					if time.Now().Unix()-nc.connTx.GetLast() > 5 {
						return
					}
				}
			}
		case <-nc.context.Done():
			return
		}
	}
}

func (nc *NexusConn) sendWorker() {
	defer nc.Close()
	for {
		req, err := nc.pullReq()
		if err != nil {
			break
		}
		req.Jsonrpc = "2.0"
		buf, err := json.Marshal(req)
		if err != nil {
			break
		}
		if !nc.Closed() {
			_, err = nc.connTx.Write(buf)
			if err != nil {
				break
			}
		} else {
			break
		}
	}
}

func (nc *NexusConn) recvWorker() {
	defer nc.Close()
	dec := json.NewDecoder(nc.connRx)
	for dec.More() {
		res := &JsonRpcRes{}
		err := dec.Decode(res)
		if err != nil {
			break
		}
		nc.resTableLock.Lock()
		ch := nc.resTable[res.Id]
		nc.resTableLock.Unlock()
		if ch != nil {
			select {
			case ch <- res:
			default:
			}
		}
	}
}

func (nc *NexusConn) newId() (uint64, chan *JsonRpcRes) {
	id := atomic.AddUint64(&nc.reqCount, 1)
	ch := make(chan *JsonRpcRes, 1)
	nc.resTableLock.Lock()
	defer nc.resTableLock.Unlock()
	nc.resTable[id] = ch
	return id, ch
}

func (nc *NexusConn) delId(id uint64) {
	nc.resTableLock.Lock()
	delete(nc.resTable, id)
	nc.resTableLock.Unlock()
}

// GetContext returns internal connection context.
func (nc *NexusConn) GetContext() context.Context {
	return nc.context
}

// Close closes nexus connection.
func (nc *NexusConn) Close() {
	if atomic.CompareAndSwapInt32(&nc.closed, 0, 1) {
		nc.cancelFun()
		nc.conn.Close()
	}
}

// Closed returns Nexus connection state.
func (nc *NexusConn) Closed() bool {
	return atomic.LoadInt32(&nc.closed) == 1
}

// ExecNoWait is a low level JSON-RPC call function, it don't wait response from server.
func (nc *NexusConn) ExecNoWait(method string, params interface{}) (id uint64, rch chan *JsonRpcRes, err error) {
	if nc.Closed() {
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
		return
	}

	if method != "sys.ping" && nc.inactivityTimeout != (-1*time.Second) {
		nc.inactivityTimer.Reset(nc.inactivityTimeout)
	}

	id, rch = nc.newId()
	req := &JsonRpcReq{
		Id:     id,
		Method: method,
		Params: params,
	}
	err = nc.pushReq(req)
	if err != nil {
		nc.delId(id)
		return 0, nil, err
	}
	return
}

// Exec is a low level JSON-RPC call function.
func (nc *NexusConn) Exec(method string, params interface{}) (result interface{}, err error) {
	id, rch, err := nc.ExecNoWait(method, params)
	if err != nil {
		return nil, err
	}
	defer nc.delId(id)
	select {
	case res := <-rch:
		if res.Error != nil {
			err = res.Error
		} else {
			result = res.Result
		}
	case <-nc.context.Done():
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
	}
	return
}

// Ping pings Nexus server, timeout is the max time waiting for server response,
// after that ErrTimeout is returned.
func (nc *NexusConn) Ping(timeout time.Duration) (err error) {
	id, rch, err := nc.ExecNoWait("sys.ping", nil)
	if err != nil {
		return
	}
	defer nc.delId(id)
	select {
	case <-rch:
		break
	case <-time.After(timeout):
		err = NewJsonRpcErr(ErrTimeout, "", nil)
	case <-nc.context.Done():
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
	}
	return
}

//SetSessionExpirationTimeout sets an expiration timeout. When it is reached the connection will be closed
func (nc *NexusConn) SetInactivityTimeout(timeout time.Duration) (err error) {
	if nc.Closed() {
		err = NewJsonRpcErr(ErrConnClosed, "", nil)
		return
	}
	nc.inactivityTimeout = timeout
	nc.inactivityTimer = time.NewTimer(timeout)
	return
}

// Login attempts to login using user and pass.
// Returns the response object from Nexus or error.
func (nc *NexusConn) Login(user string, pass string) (interface{}, error) {
	par := map[string]interface{}{
		"user": user,
		"pass": pass,
	}
	res, err := nc.Exec("sys.login", par)
	if err != nil {
		return nil, err
	}
	nc.connId = ei.N(res).M("connid").StringZ()
	return res, nil
}

// Version retrieves the server version
// Returns the response object from Nexus or error.
func (nc *NexusConn) Version() (interface{}, error) {
	par := map[string]interface{}{}
	res, err := nc.Exec("sys.version", par)
	if err != nil {
		return nil, err
	}
	return res, nil
}

// Id returns the connection id after a login.
func (nc *NexusConn) Id() string {
	return nc.connId
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors All rights reserved.

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

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

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

package e2e

import (
	"fmt"
	"math"
	"strconv"
	"time"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/controller/framework"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

// This test suite can take a long time to run, so by default it is added to
// the ginkgo.skip list (see driver.go).
// To run this suite you must explicitly ask for it by setting the
// -t/--test flag or ginkgo.focus flag.
var _ = Describe("Density", func() {
	var c *client.Client
	var minionCount int
	var RCName string
	var ns string

	BeforeEach(func() {
		var err error
		c, err = loadClient()
		expectNoError(err)
		minions, err := c.Nodes().List(labels.Everything(), fields.Everything())
		expectNoError(err)
		minionCount = len(minions.Items)
		Expect(minionCount).NotTo(BeZero())
		nsForTesting, err := createTestingNS("density", c)
		ns = nsForTesting.Name
		expectNoError(err)
	})

	AfterEach(func() {
		// Remove any remaining pods from this test if the
		// replication controller still exists and the replica count
		// isn't 0.  This means the controller wasn't cleaned up
		// during the test so clean it up here
		rc, err := c.ReplicationControllers(ns).Get(RCName)
		if err == nil && rc.Spec.Replicas != 0 {
			By("Cleaning up the replication controller")
			err := DeleteRC(c, ns, RCName)
			expectNoError(err)
		}

		By(fmt.Sprintf("Destroying namespace for this suite %v", ns))
		if err := c.Namespaces().Delete(ns); err != nil {
			Failf("Couldn't delete ns %s", err)
		}

		// Verify latency metrics
		// TODO: Update threshold to 1s once we reach this goal
		// TODO: We should reset metrics before the test. Currently previous tests influence latency metrics.
		highLatencyRequests, err := HighLatencyRequests(c, 10*time.Second, util.NewStringSet("events"))
		expectNoError(err)
		Expect(highLatencyRequests).NotTo(BeNumerically(">", 0))
	})

	// Tests with "Skipped" substring in their name will be skipped when running
	// e2e test suite without --ginkgo.focus & --ginkgo.skip flags.
	type Density struct {
		skip          bool
		podsPerMinion int
	}

	densityTests := []Density{
		// This test should always run, even if larger densities are skipped.
		{podsPerMinion: 3, skip: false},
		{podsPerMinion: 30, skip: false},
		// More than 30 pods per node is outside our v1.0 goals.
		// We might want to enable those tests in the future.
		{podsPerMinion: 50, skip: true},
		{podsPerMinion: 100, skip: true},
	}

	for _, testArg := range densityTests {
		name := fmt.Sprintf("should allow starting %d pods per node", testArg.podsPerMinion)
		if testArg.podsPerMinion <= 30 {
			name = "[Performance suite] " + name
		}
		if testArg.skip {
			name = "[Skipped] " + name
		}
		itArg := testArg
		It(name, func() {
			totalPods := itArg.podsPerMinion * minionCount
			nameStr := strconv.Itoa(totalPods) + "-" + string(util.NewUUID())
			RCName = "my-hostname-density" + nameStr

			// Create a listener for events.
			events := make([](*api.Event), 0)
			_, controller := framework.NewInformer(
				&cache.ListWatch{
					ListFunc: func() (runtime.Object, error) {
						return c.Events(ns).List(labels.Everything(), fields.Everything())
					},
					WatchFunc: func(rv string) (watch.Interface, error) {
						return c.Events(ns).Watch(labels.Everything(), fields.Everything(), rv)
					},
				},
				&api.Event{},
				0,
				framework.ResourceEventHandlerFuncs{
					AddFunc: func(obj interface{}) {
						events = append(events, obj.(*api.Event))
					},
				},
			)
			stop := make(chan struct{})
			go controller.Run(stop)

			// Start the replication controller.
			startTime := time.Now()
			expectNoError(RunRC(c, RCName, ns, "gcr.io/google_containers/pause:go", totalPods))
			e2eStartupTime := time.Now().Sub(startTime)
			Logf("E2E startup time for %d pods: %v", totalPods, e2eStartupTime)

			By("Waiting for all events to be recorded")
			last := -1
			current := len(events)
			timeout := 10 * time.Minute
			for start := time.Now(); last < current && time.Since(start) < timeout; time.Sleep(10 * time.Second) {
				last = current
				current = len(events)
			}
			close(stop)

			if current != last {
				Logf("Warning: Not all events were recorded after waiting %.2f minutes", timeout.Minutes())
			}
			Logf("Found %d events", current)

			// Tune the threshold for allowed failures.
			badEvents := BadEvents(events)
			Expect(badEvents).NotTo(BeNumerically(">", int(math.Floor(0.01*float64(totalPods)))))
		})
	}
})
<commit_msg>Reduce threshold for request latency in density tests to 5 sec<commit_after>/*
Copyright 2015 The Kubernetes Authors All rights reserved.

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

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

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

package e2e

import (
	"fmt"
	"math"
	"strconv"
	"time"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/controller/framework"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

// This test suite can take a long time to run, so by default it is added to
// the ginkgo.skip list (see driver.go).
// To run this suite you must explicitly ask for it by setting the
// -t/--test flag or ginkgo.focus flag.
var _ = Describe("Density", func() {
	var c *client.Client
	var minionCount int
	var RCName string
	var ns string

	BeforeEach(func() {
		var err error
		c, err = loadClient()
		expectNoError(err)
		minions, err := c.Nodes().List(labels.Everything(), fields.Everything())
		expectNoError(err)
		minionCount = len(minions.Items)
		Expect(minionCount).NotTo(BeZero())
		nsForTesting, err := createTestingNS("density", c)
		ns = nsForTesting.Name
		expectNoError(err)
	})

	AfterEach(func() {
		// Remove any remaining pods from this test if the
		// replication controller still exists and the replica count
		// isn't 0.  This means the controller wasn't cleaned up
		// during the test so clean it up here
		rc, err := c.ReplicationControllers(ns).Get(RCName)
		if err == nil && rc.Spec.Replicas != 0 {
			By("Cleaning up the replication controller")
			err := DeleteRC(c, ns, RCName)
			expectNoError(err)
		}

		By(fmt.Sprintf("Destroying namespace for this suite %v", ns))
		if err := c.Namespaces().Delete(ns); err != nil {
			Failf("Couldn't delete ns %s", err)
		}

		// Verify latency metrics
		// TODO: Update threshold to 1s once we reach this goal
		// TODO: We should reset metrics before the test. Currently previous tests influence latency metrics.
		highLatencyRequests, err := HighLatencyRequests(c, 5*time.Second, util.NewStringSet("events"))
		expectNoError(err)
		Expect(highLatencyRequests).NotTo(BeNumerically(">", 0))
	})

	// Tests with "Skipped" substring in their name will be skipped when running
	// e2e test suite without --ginkgo.focus & --ginkgo.skip flags.
	type Density struct {
		skip          bool
		podsPerMinion int
	}

	densityTests := []Density{
		// This test should always run, even if larger densities are skipped.
		{podsPerMinion: 3, skip: false},
		{podsPerMinion: 30, skip: false},
		// More than 30 pods per node is outside our v1.0 goals.
		// We might want to enable those tests in the future.
		{podsPerMinion: 50, skip: true},
		{podsPerMinion: 100, skip: true},
	}

	for _, testArg := range densityTests {
		name := fmt.Sprintf("should allow starting %d pods per node", testArg.podsPerMinion)
		if testArg.podsPerMinion <= 30 {
			name = "[Performance suite] " + name
		}
		if testArg.skip {
			name = "[Skipped] " + name
		}
		itArg := testArg
		It(name, func() {
			totalPods := itArg.podsPerMinion * minionCount
			nameStr := strconv.Itoa(totalPods) + "-" + string(util.NewUUID())
			RCName = "my-hostname-density" + nameStr

			// Create a listener for events.
			events := make([](*api.Event), 0)
			_, controller := framework.NewInformer(
				&cache.ListWatch{
					ListFunc: func() (runtime.Object, error) {
						return c.Events(ns).List(labels.Everything(), fields.Everything())
					},
					WatchFunc: func(rv string) (watch.Interface, error) {
						return c.Events(ns).Watch(labels.Everything(), fields.Everything(), rv)
					},
				},
				&api.Event{},
				0,
				framework.ResourceEventHandlerFuncs{
					AddFunc: func(obj interface{}) {
						events = append(events, obj.(*api.Event))
					},
				},
			)
			stop := make(chan struct{})
			go controller.Run(stop)

			// Start the replication controller.
			startTime := time.Now()
			expectNoError(RunRC(c, RCName, ns, "gcr.io/google_containers/pause:go", totalPods))
			e2eStartupTime := time.Now().Sub(startTime)
			Logf("E2E startup time for %d pods: %v", totalPods, e2eStartupTime)

			By("Waiting for all events to be recorded")
			last := -1
			current := len(events)
			timeout := 10 * time.Minute
			for start := time.Now(); last < current && time.Since(start) < timeout; time.Sleep(10 * time.Second) {
				last = current
				current = len(events)
			}
			close(stop)

			if current != last {
				Logf("Warning: Not all events were recorded after waiting %.2f minutes", timeout.Minutes())
			}
			Logf("Found %d events", current)

			// Tune the threshold for allowed failures.
			badEvents := BadEvents(events)
			Expect(badEvents).NotTo(BeNumerically(">", int(math.Floor(0.01*float64(totalPods)))))
		})
	}
})
<|endoftext|>


<commit_before>// Copyright ©2013 The bíogo 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 blast

import (
	"flag"
	"testing"
	"time"

	"gopkg.in/check.v1"
)

const (
	tool    = "biogo.ncbi/blast-testsuite"
	retries = 3
)

// Helpers
func intPtr(i int) *int           { return &i }
func floatPtr(f float64) *float64 { return &f }
func stringPtr(s string) *string  { return &s }

// Tests
func Test(t *testing.T) { check.TestingT(t) }

type S struct{}

var _ = check.Suite(&S{})

func (s *S) TestLimiter(c *check.C) {
	var count int
	for i := 0; i < 10; i++ {
		go func() {
			for j := 0; j < 10; j++ {
				Limit.Wait()
				count++
			}
		}()
	}
	time.Sleep(9 * time.Second)
	c.Check(count, check.Equals, 3)
}

var net = flag.String("net", "", "Runs tests involving network connections if given an email address.")

func (s *S) TestBlast(c *check.C) {
	if *net == "" {
		c.Skip("Network tests not requested.")
	}
	for _, t := range []struct {
		query     string
		putParams *PutParameters
		getParams *GetParameters
		expect    *Output
	}{
		{
			query:     "X14032.1",
			putParams: &PutParameters{Program: "blastn", Database: "nr"},
			getParams: nil,
			expect: &Output{
				Program:   "blastn",
				Reference: "Stephen F. Altschul, Thomas L. Madden, Alejandro A. Schäffer, Jinghui Zhang, Zheng Zhang, Webb Miller, and David J. Lipman (1997), \"Gapped BLAST and PSI-BLAST: a new generation of protein database search programs\", Nucleic Acids Res. 25:3389-3402.",
				Database:  "nr",
				QueryId:   "gi|322|emb|X14032.1|",
				Parameters: Parameters{
					MatrixName:  nil,
					Expect:      10,
					Include:     nil,
					Match:       intPtr(2),
					Mismatch:    intPtr(-3),
					GapOpen:     5,
					GapExtend:   2,
					Filter:      stringPtr("L;m;"),
					PhiPattern:  nil,
					EntrezQuery: nil,
				},
				Iterations: []Iteration{
					{
						N:        1,
						QueryId:  stringPtr("gi|322|emb|X14032.1|"),
						QueryDef: stringPtr("Bovine mRNA for EDGF II (acidic eye-derived growth factor II)"),
						QueryLen: intPtr(668),
						Hits: []Hit{
							{
								N:         1,
								Id:        "gi|163047|gb|M35608.1|BOVFGFAA",
								Def:       "Bovine acidic eye-derived fibroblast growth factor (EDGF II) mRNA, complete cds >gi|322|emb|X14032.1| Bovine mRNA for EDGF II (acidic eye-derived growth factor II)",
								Accession: "M35608",
								Len:       668,
								Hsps: []Hsp{
									{
										N:              1,
										BitScore:       1205.94,
										Score:          1336,
										EValue:         0,
										QueryFrom:      1,
										QueryTo:        668,
										HitFrom:        1,
										HitTo:          668,
										PhiPatternFrom: nil,
										PhiPatternTo:   nil,
										QueryFrame:     intPtr(1),
										HitFrame:       intPtr(1),
										HspIdentity:    intPtr(668),
										HspPositive:    intPtr(668),
										HspGaps:        intPtr(0),
										AlignLen:       intPtr(668),
										Density:        nil,
										QuerySeq:       []byte("GGATCCTCTTTCCCTTCTACTGGAGAGGAAAAGCCCTCAGCCTGCAAGCTGTTCAGCCTTGAAACAGCCACAACCAGCAGCTGCTGAGCCATGGCTGAAGGAGAAACCACGACCTTCACGGCCCTGACTGAGAAGTTTAACCTGCCTCTAGGCAATTACAAGAAGCCCAAGCTCCTCTACTGCAGCAACGGGGGCTACTTCCTGAGAATCCTCCCAGATGGCACAGTGGATGGGACGAAGGACAGGAGCGACCAGCACATTCAGCTGCAGCTCTGTGCGGAAAGCATAGGGGAGGTGTATATTAAGAGTACGGAGACTGGCCAGTTCTTGGCCATGGACACCGACGGGCTTTTGTACGGCTCACAGACACCCAATGAGGAATGTTTGTTCCTGGAAAGGTTGGAGGAAAACCATTACAACACCTACATATCCAAGAAGCATGCAGAGAAGCATTGGTTCGTTGGTCTCAAGAAGAACGGAAGGTCTAAACTCGGTCCTCGGACTCACTTCGGCCAGAAAGCCATCTTGTTTCTCCCCCTGCCAGTCTCCTCTGATTAAAGAAATCTGTTGTGGGTGCTGAGCCACTCCAGAGGAATCTGAAGGGGTCCTCACCTGGCTGACCCCAGATTGTACCCTTTACCATTGGCCGTGCTAACCCCTGGCCCACA"),
										SubjectSeq:     []byte("GGATCCTCTTTCCCTTCTACTGGAGAGGAAAAGCCCTCAGCCTGCAAGCTGTTCAGCCTTGAAACAGCCACAACCAGCAGCTGCTGAGCCATGGCTGAAGGAGAAACCACGACCTTCACGGCCCTGACTGAGAAGTTTAACCTGCCTCTAGGCAATTACAAGAAGCCCAAGCTCCTCTACTGCAGCAACGGGGGCTACTTCCTGAGAATCCTCCCAGATGGCACAGTGGATGGGACGAAGGACAGGAGCGACCAGCACATTCAGCTGCAGCTCTGTGCGGAAAGCATAGGGGAGGTGTATATTAAGAGTACGGAGACTGGCCAGTTCTTGGCCATGGACACCGACGGGCTTTTGTACGGCTCACAGACACCCAATGAGGAATGTTTGTTCCTGGAAAGGTTGGAGGAAAACCATTACAACACCTACATATCCAAGAAGCATGCAGAGAAGCATTGGTTCGTTGGTCTCAAGAAGAACGGAAGGTCTAAACTCGGTCCTCGGACTCACTTCGGCCAGAAAGCCATCTTGTTTCTCCCCCTGCCAGTCTCCTCTGATTAAAGAAATCTGTTGTGGGTGCTGAGCCACTCCAGAGGAATCTGAAGGGGTCCTCACCTGGCTGACCCCAGATTGTACCCTTTACCATTGGCCGTGCTAACCCCTGGCCCACA"),
										FormatMidline:  []byte("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"),
									},
								},
							},
						},
					},
				},
			},
		},
	} {
		r, err := Put(t.query, t.putParams, tool, *net)
		c.Assert(err, check.Equals, nil)
		var o *Output
		for k := 0; k < retries; k++ {
			var s *SearchInfo
			s, err = r.SearchInfo(tool, *net)
			c.Assert(err, check.Equals, nil)
			c.Check(s.Status, check.Equals, "READY")
			if !s.HaveHits {
				continue
			}
			c.Check(s.Rid.String(), check.Equals, r.String())
			o, err = r.GetOutput(t.getParams, tool, *net)
			if err == nil {
				break
			}
		}
		c.Assert(err, check.Equals, nil)
		c.Check(o.Program, check.Equals, t.expect.Program)
		c.Check(o.Reference, check.Equals, t.expect.Reference)
		c.Check(o.Database, check.Equals, t.expect.Database)
		c.Check(o.QueryId, check.Equals, t.expect.QueryId)
		c.Check(o.Parameters, check.DeepEquals, t.expect.Parameters)
		c.Assert(len(o.Iterations) > 0, check.Equals, true)
		c.Assert(len(o.Iterations[0].Hits) > 0, check.Equals, true)
		c.Check(o.Iterations[0].Hits[0], check.DeepEquals, t.expect.Iterations[0].Hits[0])
	}
}
<commit_msg>blast: make net test more robust to NCBI response<commit_after>// Copyright ©2013 The bíogo 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 blast

import (
	"flag"
	"testing"
	"time"

	"gopkg.in/check.v1"
)

const (
	tool    = "biogo.ncbi/blast-testsuite"
	retries = 3
)

// Helpers
func intPtr(i int) *int           { return &i }
func floatPtr(f float64) *float64 { return &f }
func stringPtr(s string) *string  { return &s }

// Tests
func Test(t *testing.T) { check.TestingT(t) }

type S struct{}

var _ = check.Suite(&S{})

func (s *S) TestLimiter(c *check.C) {
	var count int
	for i := 0; i < 10; i++ {
		go func() {
			for j := 0; j < 10; j++ {
				Limit.Wait()
				count++
			}
		}()
	}
	time.Sleep(9 * time.Second)
	c.Check(count, check.Equals, 3)
}

var net = flag.String("net", "", "Runs tests involving network connections if given an email address.")

func (s *S) TestBlast(c *check.C) {
	if *net == "" {
		c.Skip("Network tests not requested.")
	}
	for _, t := range []struct {
		query     string
		putParams *PutParameters
		getParams *GetParameters
		expect    *Output
	}{
		{
			query:     "X14032.1",
			putParams: &PutParameters{Program: "blastn", Database: "nr"},
			getParams: nil,
			expect: &Output{
				Program:   "blastn",
				Reference: "Stephen F. Altschul, Thomas L. Madden, Alejandro A. Schäffer, Jinghui Zhang, Zheng Zhang, Webb Miller, and David J. Lipman (1997), \"Gapped BLAST and PSI-BLAST: a new generation of protein database search programs\", Nucleic Acids Res. 25:3389-3402.",
				Database:  "nr",
				QueryId:   "gi|322|emb|X14032.1|",
				Parameters: Parameters{
					MatrixName:  nil,
					Expect:      10,
					Include:     nil,
					Match:       intPtr(2),
					Mismatch:    intPtr(-3),
					GapOpen:     5,
					GapExtend:   2,
					Filter:      stringPtr("L;m;"),
					PhiPattern:  nil,
					EntrezQuery: nil,
				},
				Iterations: []Iteration{
					{
						N:        1,
						QueryId:  stringPtr("gi|322|emb|X14032.1|"),
						QueryDef: stringPtr("Bovine mRNA for EDGF II (acidic eye-derived growth factor II)"),
						QueryLen: intPtr(668),
						Hits: []Hit{
							{
								N:         1,
								Id:        "gi|163047|gb|M35608.1|BOVFGFAA",
								Def:       "Bovine acidic eye-derived fibroblast growth factor (EDGF II) mRNA, complete cds >gi|322|emb|X14032.1| Bovine mRNA for EDGF II (acidic eye-derived growth factor II)",
								Accession: "M35608",
								Len:       668,
								Hsps: []Hsp{
									{
										N:              1,
										BitScore:       1205.94,
										Score:          1336,
										EValue:         0,
										QueryFrom:      1,
										QueryTo:        668,
										HitFrom:        1,
										HitTo:          668,
										PhiPatternFrom: nil,
										PhiPatternTo:   nil,
										QueryFrame:     intPtr(1),
										HitFrame:       intPtr(1),
										HspIdentity:    intPtr(668),
										HspPositive:    intPtr(668),
										HspGaps:        intPtr(0),
										AlignLen:       intPtr(668),
										Density:        nil,
										QuerySeq:       []byte("GGATCCTCTTTCCCTTCTACTGGAGAGGAAAAGCCCTCAGCCTGCAAGCTGTTCAGCCTTGAAACAGCCACAACCAGCAGCTGCTGAGCCATGGCTGAAGGAGAAACCACGACCTTCACGGCCCTGACTGAGAAGTTTAACCTGCCTCTAGGCAATTACAAGAAGCCCAAGCTCCTCTACTGCAGCAACGGGGGCTACTTCCTGAGAATCCTCCCAGATGGCACAGTGGATGGGACGAAGGACAGGAGCGACCAGCACATTCAGCTGCAGCTCTGTGCGGAAAGCATAGGGGAGGTGTATATTAAGAGTACGGAGACTGGCCAGTTCTTGGCCATGGACACCGACGGGCTTTTGTACGGCTCACAGACACCCAATGAGGAATGTTTGTTCCTGGAAAGGTTGGAGGAAAACCATTACAACACCTACATATCCAAGAAGCATGCAGAGAAGCATTGGTTCGTTGGTCTCAAGAAGAACGGAAGGTCTAAACTCGGTCCTCGGACTCACTTCGGCCAGAAAGCCATCTTGTTTCTCCCCCTGCCAGTCTCCTCTGATTAAAGAAATCTGTTGTGGGTGCTGAGCCACTCCAGAGGAATCTGAAGGGGTCCTCACCTGGCTGACCCCAGATTGTACCCTTTACCATTGGCCGTGCTAACCCCTGGCCCACA"),
										SubjectSeq:     []byte("GGATCCTCTTTCCCTTCTACTGGAGAGGAAAAGCCCTCAGCCTGCAAGCTGTTCAGCCTTGAAACAGCCACAACCAGCAGCTGCTGAGCCATGGCTGAAGGAGAAACCACGACCTTCACGGCCCTGACTGAGAAGTTTAACCTGCCTCTAGGCAATTACAAGAAGCCCAAGCTCCTCTACTGCAGCAACGGGGGCTACTTCCTGAGAATCCTCCCAGATGGCACAGTGGATGGGACGAAGGACAGGAGCGACCAGCACATTCAGCTGCAGCTCTGTGCGGAAAGCATAGGGGAGGTGTATATTAAGAGTACGGAGACTGGCCAGTTCTTGGCCATGGACACCGACGGGCTTTTGTACGGCTCACAGACACCCAATGAGGAATGTTTGTTCCTGGAAAGGTTGGAGGAAAACCATTACAACACCTACATATCCAAGAAGCATGCAGAGAAGCATTGGTTCGTTGGTCTCAAGAAGAACGGAAGGTCTAAACTCGGTCCTCGGACTCACTTCGGCCAGAAAGCCATCTTGTTTCTCCCCCTGCCAGTCTCCTCTGATTAAAGAAATCTGTTGTGGGTGCTGAGCCACTCCAGAGGAATCTGAAGGGGTCCTCACCTGGCTGACCCCAGATTGTACCCTTTACCATTGGCCGTGCTAACCCCTGGCCCACA"),
										FormatMidline:  []byte("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"),
									},
								},
							},
						},
					},
				},
			},
		},
	} {
		r, err := Put(t.query, t.putParams, tool, *net)
		c.Assert(err, check.Equals, nil)
		var o *Output
		for k := 0; k < retries; k++ {
			var s *SearchInfo
			s, err = r.SearchInfo(tool, *net)
			c.Assert(err, check.Equals, nil)
			if !s.HaveHits {
				c.Check(s.Status, check.Equals, "WAITING")
				if k == retries-1 {
					c.Logf("NCBI server timed out: %v", s)
					return
				}
				continue
			}
			c.Check(s.Status, check.Equals, "READY")
			c.Check(s.Rid.String(), check.Equals, r.String())
			o, err = r.GetOutput(t.getParams, tool, *net)
			if err == nil {
				break
			}
		}
		c.Assert(err, check.Equals, nil)
		c.Check(o.Program, check.Equals, t.expect.Program)
		c.Check(o.Reference, check.Equals, t.expect.Reference)
		c.Check(o.Database, check.Equals, t.expect.Database)
		c.Check(o.QueryId, check.Equals, t.expect.QueryId)
		c.Check(o.Parameters, check.DeepEquals, t.expect.Parameters)
		c.Assert(len(o.Iterations) > 0, check.Equals, true)
		c.Assert(len(o.Iterations[0].Hits) > 0, check.Equals, true)
		c.Check(o.Iterations[0].Hits[0], check.DeepEquals, t.expect.Iterations[0].Hits[0])
	}
}
<|endoftext|>