<commit_before>package editor

import (
	"github.com/elpinal/coco3/complete"
	"github.com/elpinal/coco3/config"
	"github.com/elpinal/coco3/screen"
)

type insert struct {
	streamSet
	*editor
	s    screen.Screen
	conf *config.Config

	needSave bool

	replaceMode bool
	replacedBuf []rune
}

func newInsert(ss streamSet, e *editor, s screen.Screen, conf *config.Config) *insert {
	return &insert{
		streamSet: ss,
		editor:    e,
		s:         s,
		conf:      conf,
	}
}

func newReplace(s streamSet, e *editor) *insert {
	buf := e.buf
	e.buf = nil
	return &insert{
		streamSet:   s,
		editor:      e,
		replaceMode: true,
		replacedBuf: buf,
	}
}

func (e *insert) Mode() mode {
	return modeInsert
}

func (e *insert) Run() (end continuity, next modeChanger, err error) {
	r, _, err := e.streamSet.in.ReadRune()
	if err != nil {
		return end, next, err
	}
start:
	switch r {
	case CharEscape, CharCtrlC:
		if e.replaceMode {
			e.buf = e.overwrite(e.replacedBuf, e.buf, e.pos-len(e.buf))
		}
		e.move(e.pos - 1)
		next = norm()
		if e.needSave {
			e.undoTree.add(e.buf)
		}
	case CharBackspace, CharCtrlH:
		e.deleteChar()
		e.needSave = true
	case CharCtrlM, CharCtrlJ:
		end = execute
		e.needSave = true
	case CharCtrlX:
		r1, _, err := e.streamSet.in.ReadRune()
		if err != nil {
			return end, next, err
		}
		r2, err := e.ctrlX(r1)
		if err != nil {
			return end, next, err
		}
		r = r2
		goto start
	case CharCtrlW:
		e.deleteWord()
		e.needSave = true
	case CharCtrlU:
		e.deleteToBeginning()
		e.needSave = true
	case CharCtrlR:
		r1, _, err := e.in.ReadRune()
		if err != nil {
			return end, next, err
		}
		e.put(r1, e.pos)
		e.needSave = true
	default:
		if r <= CharCtrlZ {
			return
		}
		e.insert([]rune{r}, e.pos)
		e.needSave = true
	}
	return
}

func (e *insert) Runes() []rune {
	if e.replaceMode {
		return e.overwrite(e.replacedBuf, e.editor.buf, e.editor.pos-len(e.buf))
	}
	return e.editor.buf
}

func (e *insert) Position() int {
	return e.editor.pos
}

func (e *insert) Message() []rune {
	if e.replaceMode {
		return []rune("-- REPLACE --")
	}
	return []rune("-- INSERT --")
}

func (e *insert) Highlight() *screen.Hi {
	return nil
}

func (e *insert) ctrlX(r rune) (rune, error) {
	var f func([]rune, int) ([]string, error)
	switch r {
	case CharCtrlF:
		f = complete.File
	default:
		return r, nil
	}

	list, err := f(e.buf, e.pos)
	if err != nil {
		return 0, err
	}
	list = append(list, "")
	e.insert([]rune(list[0]), e.pos)
	e.needSave = true
	n := 0
	for {
		e.s.Refresh(e.conf, false, e.buf, e.pos, e.Highlight())
		r1, _, err := e.streamSet.in.ReadRune()
		if err != nil {
			return 0, err
		}
		n1 := n
		switch r1 {
		case CharCtrlN, r:
			n++
			if len(list) <= n {
				n = 0
			}
		case CharCtrlP:
			n--
			if n < 0 {
				n = len(list) - 1
			}
		case CharCtrlY:
			r2, _, err := e.streamSet.in.ReadRune()
			return r2, err
		case CharCtrlE:
			e.delete(e.pos, e.pos-len(list[n1]))
			e.s.Refresh(e.conf, false, e.buf, e.pos, e.Highlight())
			r2, _, err := e.streamSet.in.ReadRune()
			return r2, err
		default:
			return r1, nil
		}
		e.delete(e.pos, e.pos-len(list[n1]))
		e.insert([]rune(list[n]), e.pos)
	}
}

func (e *insert) deleteChar() {
	if !e.replaceMode {
		e.delete(e.pos-1, e.pos)
		return
	}
	if e.pos == 0 {
		return
	}
	e.pos--
	if len(e.buf) > 0 {
		e.buf = e.buf[:len(e.buf)-1]
	}
}

func (e *insert) deleteWord() {
	if !e.replaceMode {
		pos := e.pos
		e.wordBackward()
		e.delete(pos, e.pos)
		return
	}
	if e.pos == 0 {
		return
	}
	off := e.pos - len(e.buf)
	e.pos -= off
	pos := e.pos
	e.wordBackward()
	if len(e.buf) > 0 {
		e.delete(pos, e.pos)
		e.pos += off
	}
}

func (e *insert) deleteToBeginning() {
	if !e.replaceMode {
		e.delete(0, e.pos)
		return
	}
	if e.pos == 0 {
		return
	}
	off := e.pos - len(e.buf)
	e.pos -= off
	if len(e.buf) > 0 {
		e.delete(0, e.pos)
		e.pos += off
	}
}
<commit_msg>Use short syntax<commit_after>package editor

import (
	"github.com/elpinal/coco3/complete"
	"github.com/elpinal/coco3/config"
	"github.com/elpinal/coco3/screen"
)

type insert struct {
	streamSet
	*editor
	s    screen.Screen
	conf *config.Config

	needSave bool

	replaceMode bool
	replacedBuf []rune
}

func newInsert(ss streamSet, e *editor, s screen.Screen, conf *config.Config) *insert {
	return &insert{
		streamSet: ss,
		editor:    e,
		s:         s,
		conf:      conf,
	}
}

func newReplace(s streamSet, e *editor) *insert {
	buf := e.buf
	e.buf = nil
	return &insert{
		streamSet:   s,
		editor:      e,
		replaceMode: true,
		replacedBuf: buf,
	}
}

func (e *insert) Mode() mode {
	return modeInsert
}

func (e *insert) Run() (end continuity, next modeChanger, err error) {
	r, _, err := e.in.ReadRune()
	if err != nil {
		return end, next, err
	}
start:
	switch r {
	case CharEscape, CharCtrlC:
		if e.replaceMode {
			e.buf = e.overwrite(e.replacedBuf, e.buf, e.pos-len(e.buf))
		}
		e.move(e.pos - 1)
		next = norm()
		if e.needSave {
			e.undoTree.add(e.buf)
		}
	case CharBackspace, CharCtrlH:
		e.deleteChar()
		e.needSave = true
	case CharCtrlM, CharCtrlJ:
		end = execute
		e.needSave = true
	case CharCtrlX:
		r1, _, err := e.in.ReadRune()
		if err != nil {
			return end, next, err
		}
		r2, err := e.ctrlX(r1)
		if err != nil {
			return end, next, err
		}
		r = r2
		goto start
	case CharCtrlW:
		e.deleteWord()
		e.needSave = true
	case CharCtrlU:
		e.deleteToBeginning()
		e.needSave = true
	case CharCtrlR:
		r1, _, err := e.in.ReadRune()
		if err != nil {
			return end, next, err
		}
		e.put(r1, e.pos)
		e.needSave = true
	default:
		if r <= CharCtrlZ {
			return
		}
		e.insert([]rune{r}, e.pos)
		e.needSave = true
	}
	return
}

func (e *insert) Runes() []rune {
	if e.replaceMode {
		return e.overwrite(e.replacedBuf, e.editor.buf, e.editor.pos-len(e.buf))
	}
	return e.editor.buf
}

func (e *insert) Position() int {
	return e.editor.pos
}

func (e *insert) Message() []rune {
	if e.replaceMode {
		return []rune("-- REPLACE --")
	}
	return []rune("-- INSERT --")
}

func (e *insert) Highlight() *screen.Hi {
	return nil
}

func (e *insert) ctrlX(r rune) (rune, error) {
	var f func([]rune, int) ([]string, error)
	switch r {
	case CharCtrlF:
		f = complete.File
	default:
		return r, nil
	}

	list, err := f(e.buf, e.pos)
	if err != nil {
		return 0, err
	}
	list = append(list, "")
	e.insert([]rune(list[0]), e.pos)
	e.needSave = true
	n := 0
	for {
		e.s.Refresh(e.conf, false, e.buf, e.pos, e.Highlight())
		r1, _, err := e.in.ReadRune()
		if err != nil {
			return 0, err
		}
		n1 := n
		switch r1 {
		case CharCtrlN, r:
			n++
			if len(list) <= n {
				n = 0
			}
		case CharCtrlP:
			n--
			if n < 0 {
				n = len(list) - 1
			}
		case CharCtrlY:
			r2, _, err := e.in.ReadRune()
			return r2, err
		case CharCtrlE:
			e.delete(e.pos, e.pos-len(list[n1]))
			e.s.Refresh(e.conf, false, e.buf, e.pos, e.Highlight())
			r2, _, err := e.in.ReadRune()
			return r2, err
		default:
			return r1, nil
		}
		e.delete(e.pos, e.pos-len(list[n1]))
		e.insert([]rune(list[n]), e.pos)
	}
}

func (e *insert) deleteChar() {
	if !e.replaceMode {
		e.delete(e.pos-1, e.pos)
		return
	}
	if e.pos == 0 {
		return
	}
	e.pos--
	if len(e.buf) > 0 {
		e.buf = e.buf[:len(e.buf)-1]
	}
}

func (e *insert) deleteWord() {
	if !e.replaceMode {
		pos := e.pos
		e.wordBackward()
		e.delete(pos, e.pos)
		return
	}
	if e.pos == 0 {
		return
	}
	off := e.pos - len(e.buf)
	e.pos -= off
	pos := e.pos
	e.wordBackward()
	if len(e.buf) > 0 {
		e.delete(pos, e.pos)
		e.pos += off
	}
}

func (e *insert) deleteToBeginning() {
	if !e.replaceMode {
		e.delete(0, e.pos)
		return
	}
	if e.pos == 0 {
		return
	}
	off := e.pos - len(e.buf)
	e.pos -= off
	if len(e.buf) > 0 {
		e.delete(0, e.pos)
		e.pos += off
	}
}
<|endoftext|>


<commit_before>package wallpaper

/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Cocoa
#import <Cocoa/Cocoa.h>

void
setWallpaper(char* name) {
     NSString *nsName =  [NSString stringWithUTF8String:name];
     NSString *urlString = [NSString stringWithFormat:@"file://%@", nsName];
     NSURL *imageURL = [NSURL URLWithString:urlString];
    [[NSWorkspace sharedWorkspace] setDesktopImageURL:imageURL
                                   forScreen:[NSScreen mainScreen]
                                   options:nil
                                   error:nil];
    free(name);
}
*/
import "C"

func Set(name string) error {
	C.setWallpaper(C.CString(name))
	return nil
}
<commit_msg>Pass empty dictionary to options on darwin<commit_after>package wallpaper

/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Cocoa
#import <Cocoa/Cocoa.h>

void
setWallpaper(char* name) {
     NSString *nsName =  [NSString stringWithUTF8String:name];
     NSString *urlString = [NSString stringWithFormat:@"file://%@", nsName];
     NSURL *imageURL = [NSURL URLWithString:urlString];
    [[NSWorkspace sharedWorkspace] setDesktopImageURL:imageURL
                                   forScreen:[NSScreen mainScreen]
                                   options:@{}
                                   error:nil];
    free(name);
}
*/
import "C"

func Set(name string) error {
	C.setWallpaper(C.CString(name))
	return nil
}
<|endoftext|>


<commit_before>package warden

import (
	"io"
)

type Container interface {
	Handle() string

	Stop(kill bool) error

	Info() (ContainerInfo, error)

	StreamIn(dstPath string, tarStream io.Reader) error
	StreamOut(srcPath string) (io.ReadCloser, error)

	LimitBandwidth(limits BandwidthLimits) error
	CurrentBandwidthLimits() (BandwidthLimits, error)

	LimitCPU(limits CPULimits) error
	CurrentCPULimits() (CPULimits, error)

	LimitDisk(limits DiskLimits) error
	CurrentDiskLimits() (DiskLimits, error)

	LimitMemory(limits MemoryLimits) error
	CurrentMemoryLimits() (MemoryLimits, error)

	NetIn(hostPort, containerPort uint32) (uint32, uint32, error)
	NetOut(network string, port uint32) error

	Run(ProcessSpec, ProcessIO) (Process, error)
	Attach(uint32, ProcessIO) (Process, error)
}

type ProcessSpec struct {
	Path       string
	Args       []string
	Dir        string
	Env        []string
	Privileged bool
	Limits     ResourceLimits
}

type ProcessIO struct {
	Stdin  io.Reader // TODO io.ReadCloser
	Stdout io.WriteCloser
	Stderr io.WriteCloser
}

type Process interface {
	ID() uint32
	Wait() (int, error)
}

type PortMapping struct {
	HostPort      uint32
	ContainerPort uint32
}

type ContainerInfo struct {
	State         string
	Events        []string
	HostIP        string
	ContainerIP   string
	ContainerPath string
	ProcessIDs    []uint32
	MemoryStat    ContainerMemoryStat
	CPUStat       ContainerCPUStat
	DiskStat      ContainerDiskStat
	BandwidthStat ContainerBandwidthStat
	Properties    Properties
	MappedPorts   []PortMapping
}

type ContainerMemoryStat struct {
	Cache                   uint64
	Rss                     uint64
	MappedFile              uint64
	Pgpgin                  uint64
	Pgpgout                 uint64
	Swap                    uint64
	Pgfault                 uint64
	Pgmajfault              uint64
	InactiveAnon            uint64
	ActiveAnon              uint64
	InactiveFile            uint64
	ActiveFile              uint64
	Unevictable             uint64
	HierarchicalMemoryLimit uint64
	HierarchicalMemswLimit  uint64
	TotalCache              uint64
	TotalRss                uint64
	TotalMappedFile         uint64
	TotalPgpgin             uint64
	TotalPgpgout            uint64
	TotalSwap               uint64
	TotalPgfault            uint64
	TotalPgmajfault         uint64
	TotalInactiveAnon       uint64
	TotalActiveAnon         uint64
	TotalInactiveFile       uint64
	TotalActiveFile         uint64
	TotalUnevictable        uint64
}

type ContainerCPUStat struct {
	Usage  uint64
	User   uint64
	System uint64
}

type ContainerDiskStat struct {
	BytesUsed  uint64
	InodesUsed uint64
}

type ContainerBandwidthStat struct {
	InRate   uint64
	InBurst  uint64
	OutRate  uint64
	OutBurst uint64
}

type BandwidthLimits struct {
	RateInBytesPerSecond      uint64
	BurstRateInBytesPerSecond uint64
}

type DiskLimits struct {
	BlockSoft uint64
	BlockHard uint64

	InodeSoft uint64
	InodeHard uint64

	ByteSoft uint64
	ByteHard uint64
}

type MemoryLimits struct {
	LimitInBytes uint64
}

type CPULimits struct {
	LimitInShares uint64
}

type EnvironmentVariable struct {
	Key   string
	Value string
}

type ResourceLimits struct {
	As         *uint64
	Core       *uint64
	Cpu        *uint64
	Data       *uint64
	Fsize      *uint64
	Locks      *uint64
	Memlock    *uint64
	Msgqueue   *uint64
	Nice       *uint64
	Nofile     *uint64
	Nproc      *uint64
	Rss        *uint64
	Rtprio     *uint64
	Sigpending *uint64
	Stack      *uint64
}
<commit_msg>remove extraneous TODO<commit_after>package warden

import (
	"io"
)

type Container interface {
	Handle() string

	Stop(kill bool) error

	Info() (ContainerInfo, error)

	StreamIn(dstPath string, tarStream io.Reader) error
	StreamOut(srcPath string) (io.ReadCloser, error)

	LimitBandwidth(limits BandwidthLimits) error
	CurrentBandwidthLimits() (BandwidthLimits, error)

	LimitCPU(limits CPULimits) error
	CurrentCPULimits() (CPULimits, error)

	LimitDisk(limits DiskLimits) error
	CurrentDiskLimits() (DiskLimits, error)

	LimitMemory(limits MemoryLimits) error
	CurrentMemoryLimits() (MemoryLimits, error)

	NetIn(hostPort, containerPort uint32) (uint32, uint32, error)
	NetOut(network string, port uint32) error

	Run(ProcessSpec, ProcessIO) (Process, error)
	Attach(uint32, ProcessIO) (Process, error)
}

type ProcessSpec struct {
	Path       string
	Args       []string
	Dir        string
	Env        []string
	Privileged bool
	Limits     ResourceLimits
}

type ProcessIO struct {
	Stdin  io.Reader
	Stdout io.WriteCloser
	Stderr io.WriteCloser
}

type Process interface {
	ID() uint32
	Wait() (int, error)
}

type PortMapping struct {
	HostPort      uint32
	ContainerPort uint32
}

type ContainerInfo struct {
	State         string
	Events        []string
	HostIP        string
	ContainerIP   string
	ContainerPath string
	ProcessIDs    []uint32
	MemoryStat    ContainerMemoryStat
	CPUStat       ContainerCPUStat
	DiskStat      ContainerDiskStat
	BandwidthStat ContainerBandwidthStat
	Properties    Properties
	MappedPorts   []PortMapping
}

type ContainerMemoryStat struct {
	Cache                   uint64
	Rss                     uint64
	MappedFile              uint64
	Pgpgin                  uint64
	Pgpgout                 uint64
	Swap                    uint64
	Pgfault                 uint64
	Pgmajfault              uint64
	InactiveAnon            uint64
	ActiveAnon              uint64
	InactiveFile            uint64
	ActiveFile              uint64
	Unevictable             uint64
	HierarchicalMemoryLimit uint64
	HierarchicalMemswLimit  uint64
	TotalCache              uint64
	TotalRss                uint64
	TotalMappedFile         uint64
	TotalPgpgin             uint64
	TotalPgpgout            uint64
	TotalSwap               uint64
	TotalPgfault            uint64
	TotalPgmajfault         uint64
	TotalInactiveAnon       uint64
	TotalActiveAnon         uint64
	TotalInactiveFile       uint64
	TotalActiveFile         uint64
	TotalUnevictable        uint64
}

type ContainerCPUStat struct {
	Usage  uint64
	User   uint64
	System uint64
}

type ContainerDiskStat struct {
	BytesUsed  uint64
	InodesUsed uint64
}

type ContainerBandwidthStat struct {
	InRate   uint64
	InBurst  uint64
	OutRate  uint64
	OutBurst uint64
}

type BandwidthLimits struct {
	RateInBytesPerSecond      uint64
	BurstRateInBytesPerSecond uint64
}

type DiskLimits struct {
	BlockSoft uint64
	BlockHard uint64

	InodeSoft uint64
	InodeHard uint64

	ByteSoft uint64
	ByteHard uint64
}

type MemoryLimits struct {
	LimitInBytes uint64
}

type CPULimits struct {
	LimitInShares uint64
}

type EnvironmentVariable struct {
	Key   string
	Value string
}

type ResourceLimits struct {
	As         *uint64
	Core       *uint64
	Cpu        *uint64
	Data       *uint64
	Fsize      *uint64
	Locks      *uint64
	Memlock    *uint64
	Msgqueue   *uint64
	Nice       *uint64
	Nofile     *uint64
	Nproc      *uint64
	Rss        *uint64
	Rtprio     *uint64
	Sigpending *uint64
	Stack      *uint64
}
<|endoftext|>


<commit_before>// Copyright 2017 The go-interpreter 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 leb128 provides functions for reading integer values encoded in the
// Little Endian Base 128 (LEB128) format: https://en.wikipedia.org/wiki/LEB128
package leb128

import (
	"io"
)

// ReadVarUint32Size reads a LEB128 encoded unsigned 32-bit integer from r.
// It returns the integer value, the size of the encoded value (in bytes), and
// the error (if any).
func ReadVarUint32Size(r io.Reader) (res uint32, size uint, err error) {
	byte := make([]byte, 1)
	var shift uint
	for {
		_, err := r.Read(byte)
		if err != nil {
			return 0, 0, err
		}
		size++

		cur := uint32(byte[0])
		res |= (cur & 0x7f) << (shift)
		if cur&0x80 == 0 {
			return res, size, nil
		}
		shift += 7
	}
}

// ReadVarUint32 reads a LEB128 encoded unsigned 32-bit integer from r, and
// returns the integer value, and the error (if any).
func ReadVarUint32(r io.Reader) (uint32, error) {
	n, _, err := ReadVarUint32Size(r)
	return n, err
}

// ReadVarint32Size reads a LEB128 encoded signed 32-bit integer from r, and
// returns the integer value, the size of the encoded value, and the error
// (if any)
func ReadVarint32Size(r io.Reader) (res int32, size uint, err error) {
	res64, size, err := ReadVarint64Size(r)
	res = int32(res64)
	return
}

// ReadVarint32 reads a LEB128 encoded signed 32-bit integer from r, and
// returns the integer value, and the error (if any).
func ReadVarint32(r io.Reader) (int32, error) {
	n, _, err := ReadVarint32Size(r)
	return n, err
}

// ReadVarint64Size reads a LEB128 encoded signed 64-bit integer from r, and
// returns the integer value, the size of the encoded value, and the error
// (if any)
func ReadVarint64Size(r io.Reader) (res int64, size uint, err error) {
	var shift uint
	var sign int64 = -1
	byte := make([]byte, 1)

	for {
		_, err = r.Read(byte)
		if err != nil {
			return 0, 0, err
		}
		size++

		cur := int64(byte[0])
		res |= (cur & 0x7f) << shift
		shift += 7
		sign <<= 7
		if cur&0x80 == 0 {
			break
		}
	}

	if ((sign >> 1) & res) != 0 {
		res |= sign
	}
	return res, size, nil
}

// ReadVarint64 reads a LEB128 encoded signed 64-bit integer from r, and
// returns the integer value, and the error (if any).
func ReadVarint64(r io.Reader) (int64, error) {
	n, _, err := ReadVarint64Size(r)
	return n, err
}
<commit_msg>leb128: Use io.ReadFull instead of io.Read.<commit_after>// Copyright 2017 The go-interpreter 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 leb128 provides functions for reading integer values encoded in the
// Little Endian Base 128 (LEB128) format: https://en.wikipedia.org/wiki/LEB128
package leb128

import (
	"io"
)

// ReadVarUint32Size reads a LEB128 encoded unsigned 32-bit integer from r.
// It returns the integer value, the size of the encoded value (in bytes), and
// the error (if any).
func ReadVarUint32Size(r io.Reader) (res uint32, size uint, err error) {
	b := make([]byte, 1)
	var shift uint
	for {
		if _, err = io.ReadFull(r, b); err != nil {
			return
		}

		size++

		cur := uint32(b[0])
		res |= (cur & 0x7f) << (shift)
		if cur&0x80 == 0 {
			return res, size, nil
		}
		shift += 7
	}
}

// ReadVarUint32 reads a LEB128 encoded unsigned 32-bit integer from r, and
// returns the integer value, and the error (if any).
func ReadVarUint32(r io.Reader) (uint32, error) {
	n, _, err := ReadVarUint32Size(r)
	return n, err
}

// ReadVarint32Size reads a LEB128 encoded signed 32-bit integer from r, and
// returns the integer value, the size of the encoded value, and the error
// (if any)
func ReadVarint32Size(r io.Reader) (res int32, size uint, err error) {
	res64, size, err := ReadVarint64Size(r)
	res = int32(res64)
	return
}

// ReadVarint32 reads a LEB128 encoded signed 32-bit integer from r, and
// returns the integer value, and the error (if any).
func ReadVarint32(r io.Reader) (int32, error) {
	n, _, err := ReadVarint32Size(r)
	return n, err
}

// ReadVarint64Size reads a LEB128 encoded signed 64-bit integer from r, and
// returns the integer value, the size of the encoded value, and the error
// (if any)
func ReadVarint64Size(r io.Reader) (res int64, size uint, err error) {
	var shift uint
	var sign int64 = -1
	b := make([]byte, 1)

	for {
		if _, err = io.ReadFull(r, b); err != nil {
			return
		}
		size++

		cur := int64(b[0])
		res |= (cur & 0x7f) << shift
		shift += 7
		sign <<= 7
		if cur&0x80 == 0 {
			break
		}
	}

	if ((sign >> 1) & res) != 0 {
		res |= sign
	}
	return res, size, nil
}

// ReadVarint64 reads a LEB128 encoded signed 64-bit integer from r, and
// returns the integer value, and the error (if any).
func ReadVarint64(r io.Reader) (int64, error) {
	n, _, err := ReadVarint64Size(r)
	return n, err
}
<|endoftext|>


<commit_before>/*
Copyright 2013 CoreOS Inc.

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

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

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

package store

import (
	"encoding/json"
	"sync/atomic"
)

const (
	SetSuccess = iota
	SetFail
	DeleteSuccess
	DeleteFail
	CreateSuccess
	CreateFail
	UpdateSuccess
	UpdateFail
	CompareAndSwapSuccess
	CompareAndSwapFail
	GetSuccess
	GetFail
	ExpireCount
	CompareAndDeleteSuccess
	CompareAndDeleteFail
)

type Stats struct {

	// Number of get requests
	GetSuccess uint64 `json:"getsSuccess"`
	GetFail    uint64 `json:"getsFail"`

	// Number of sets requests
	SetSuccess uint64 `json:"setsSuccess"`
	SetFail    uint64 `json:"setsFail"`

	// Number of delete requests
	DeleteSuccess uint64 `json:"deleteSuccess"`
	DeleteFail    uint64 `json:"deleteFail"`

	// Number of update requests
	UpdateSuccess uint64 `json:"updateSuccess"`
	UpdateFail    uint64 `json:"updateFail"`

	// Number of create requests
	CreateSuccess uint64 `json:"createSuccess"`
	CreateFail    uint64 `json:"createFail"`

	// Number of testAndSet requests
	CompareAndSwapSuccess uint64 `json:"compareAndSwapSuccess"`
	CompareAndSwapFail    uint64 `json:"compareAndSwapFail"`

	// Number of compareAndDelete requests
	CompareAndDeleteSuccess uint64 `json:"compareAndDeleteSuccess"`
	CompareAndDeleteFail    uint64 `json:"compareAndDeleteFail"`

	ExpireCount uint64 `json:"expireCount"`

	Watchers uint64 `json:"watchers"`
}

func newStats() *Stats {
	s := new(Stats)
	return s
}

func (s *Stats) clone() *Stats {
	return &Stats{s.GetSuccess, s.GetFail, s.SetSuccess, s.SetFail,
		s.DeleteSuccess, s.DeleteFail, s.UpdateSuccess, s.UpdateFail, s.CreateSuccess,
		s.CreateFail, s.CompareAndSwapSuccess, s.CompareAndSwapFail,
		s.CompareAndDeleteSuccess, s.CompareAndDeleteFail, s.Watchers, s.ExpireCount}
}

func (s *Stats) toJson() []byte {
	b, _ := json.Marshal(s)
	return b
}

func (s *Stats) TotalReads() uint64 {
	return s.GetSuccess + s.GetFail
}

func (s *Stats) Inc(field int) {
	switch field {
	case SetSuccess:
		atomic.AddUint64(&s.SetSuccess, 1)
	case SetFail:
		atomic.AddUint64(&s.SetFail, 1)
	case CreateSuccess:
		atomic.AddUint64(&s.CreateSuccess, 1)
	case CreateFail:
		atomic.AddUint64(&s.CreateFail, 1)
	case DeleteSuccess:
		atomic.AddUint64(&s.DeleteSuccess, 1)
	case DeleteFail:
		atomic.AddUint64(&s.DeleteFail, 1)
	case GetSuccess:
		atomic.AddUint64(&s.GetSuccess, 1)
	case GetFail:
		atomic.AddUint64(&s.GetFail, 1)
	case UpdateSuccess:
		atomic.AddUint64(&s.UpdateSuccess, 1)
	case UpdateFail:
		atomic.AddUint64(&s.UpdateFail, 1)
	case CompareAndSwapSuccess:
		atomic.AddUint64(&s.CompareAndSwapSuccess, 1)
	case CompareAndSwapFail:
		atomic.AddUint64(&s.CompareAndSwapFail, 1)
	case CompareAndDeleteSuccess:
		atomic.AddUint64(&s.CompareAndDeleteSuccess, 1)
	case CompareAndDeleteFail:
		atomic.AddUint64(&s.CompareAndDeleteFail, 1)
	case ExpireCount:
		atomic.AddUint64(&s.ExpireCount, 1)
	}
}
<commit_msg>store: remove another unused function<commit_after>/*
Copyright 2013 CoreOS Inc.

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

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

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

package store

import (
	"encoding/json"
	"sync/atomic"
)

const (
	SetSuccess = iota
	SetFail
	DeleteSuccess
	DeleteFail
	CreateSuccess
	CreateFail
	UpdateSuccess
	UpdateFail
	CompareAndSwapSuccess
	CompareAndSwapFail
	GetSuccess
	GetFail
	ExpireCount
	CompareAndDeleteSuccess
	CompareAndDeleteFail
)

type Stats struct {

	// Number of get requests
	GetSuccess uint64 `json:"getsSuccess"`
	GetFail    uint64 `json:"getsFail"`

	// Number of sets requests
	SetSuccess uint64 `json:"setsSuccess"`
	SetFail    uint64 `json:"setsFail"`

	// Number of delete requests
	DeleteSuccess uint64 `json:"deleteSuccess"`
	DeleteFail    uint64 `json:"deleteFail"`

	// Number of update requests
	UpdateSuccess uint64 `json:"updateSuccess"`
	UpdateFail    uint64 `json:"updateFail"`

	// Number of create requests
	CreateSuccess uint64 `json:"createSuccess"`
	CreateFail    uint64 `json:"createFail"`

	// Number of testAndSet requests
	CompareAndSwapSuccess uint64 `json:"compareAndSwapSuccess"`
	CompareAndSwapFail    uint64 `json:"compareAndSwapFail"`

	// Number of compareAndDelete requests
	CompareAndDeleteSuccess uint64 `json:"compareAndDeleteSuccess"`
	CompareAndDeleteFail    uint64 `json:"compareAndDeleteFail"`

	ExpireCount uint64 `json:"expireCount"`

	Watchers uint64 `json:"watchers"`
}

func newStats() *Stats {
	s := new(Stats)
	return s
}

func (s *Stats) clone() *Stats {
	return &Stats{s.GetSuccess, s.GetFail, s.SetSuccess, s.SetFail,
		s.DeleteSuccess, s.DeleteFail, s.UpdateSuccess, s.UpdateFail, s.CreateSuccess,
		s.CreateFail, s.CompareAndSwapSuccess, s.CompareAndSwapFail,
		s.CompareAndDeleteSuccess, s.CompareAndDeleteFail, s.Watchers, s.ExpireCount}
}

func (s *Stats) toJson() []byte {
	b, _ := json.Marshal(s)
	return b
}

func (s *Stats) Inc(field int) {
	switch field {
	case SetSuccess:
		atomic.AddUint64(&s.SetSuccess, 1)
	case SetFail:
		atomic.AddUint64(&s.SetFail, 1)
	case CreateSuccess:
		atomic.AddUint64(&s.CreateSuccess, 1)
	case CreateFail:
		atomic.AddUint64(&s.CreateFail, 1)
	case DeleteSuccess:
		atomic.AddUint64(&s.DeleteSuccess, 1)
	case DeleteFail:
		atomic.AddUint64(&s.DeleteFail, 1)
	case GetSuccess:
		atomic.AddUint64(&s.GetSuccess, 1)
	case GetFail:
		atomic.AddUint64(&s.GetFail, 1)
	case UpdateSuccess:
		atomic.AddUint64(&s.UpdateSuccess, 1)
	case UpdateFail:
		atomic.AddUint64(&s.UpdateFail, 1)
	case CompareAndSwapSuccess:
		atomic.AddUint64(&s.CompareAndSwapSuccess, 1)
	case CompareAndSwapFail:
		atomic.AddUint64(&s.CompareAndSwapFail, 1)
	case CompareAndDeleteSuccess:
		atomic.AddUint64(&s.CompareAndDeleteSuccess, 1)
	case CompareAndDeleteFail:
		atomic.AddUint64(&s.CompareAndDeleteFail, 1)
	case ExpireCount:
		atomic.AddUint64(&s.ExpireCount, 1)
	}
}
<|endoftext|>


<commit_before>package store

import (
	"io/ioutil"
	"net/http"
	"sync"
)

type Store struct {
	sync.RWMutex
	entries map[string]entry

	overrideContentType string
	defaultContentType  string
}

func (s *Store) Get(path string) (http.Handler, bool) {
	s.RLock()
	defer s.RUnlock()

	e, ok := s.entries[path]
	return http.Handler(e), ok
}

func (s *Store) Set(path string, req *http.Request) error {
	s.Lock()
	defer s.Unlock()

	contentType := contentTypeFromRequest(req, s.overrideContentType, s.defaultContentType)

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

	s.entries[path] = entry{contentType, body}

	return nil
}

func (s *Store) Del(path string) bool {
	s.Lock()
	defer s.Unlock()

	_, ok := s.entries[path]
	if !ok {
		return false
	}

	delete(s.entries, path)

	return true
}

type option func(*Store)

func WithDefaultContentType(defaultContentType string) option {
	return func(s *Store) {
		s.defaultContentType = defaultContentType
	}
}

func WithContentTypeOverride(overrideContentType string) option {
	return func(s *Store) {
		s.overrideContentType = overrideContentType
	}
}

func New(options ...option) *Store {
	var s Store

	for _, apply := range options {
		apply(&s)
	}

	return &s
}
<commit_msg>Fix map not initialised<commit_after>package store

import (
	"io/ioutil"
	"net/http"
	"sync"
)

type Store struct {
	sync.RWMutex
	entries map[string]entry

	overrideContentType string
	defaultContentType  string
}

func (s *Store) Get(path string) (http.Handler, bool) {
	s.RLock()
	defer s.RUnlock()

	e, ok := s.entries[path]
	return http.Handler(e), ok
}

func (s *Store) Set(path string, req *http.Request) error {
	s.Lock()
	defer s.Unlock()

	contentType := contentTypeFromRequest(req, s.overrideContentType, s.defaultContentType)

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

	s.entries[path] = entry{contentType, body}

	return nil
}

func (s *Store) Del(path string) bool {
	s.Lock()
	defer s.Unlock()

	_, ok := s.entries[path]
	if !ok {
		return false
	}

	delete(s.entries, path)

	return true
}

type option func(*Store)

func WithDefaultContentType(defaultContentType string) option {
	return func(s *Store) {
		s.defaultContentType = defaultContentType
	}
}

func WithContentTypeOverride(overrideContentType string) option {
	return func(s *Store) {
		s.overrideContentType = overrideContentType
	}
}

func New(options ...option) *Store {
	s := Store{
		entries: make(map[string]entry),
	}

	for _, apply := range options {
		apply(&s)
	}

	return &s
}
<|endoftext|>


<commit_before>package ast

import (
	"errors"
	"fmt"
)

const (
	block_none = iota
	h1
	h2
	h3
	h4
	h5
	h6
	ul
	p
	code_block

	state_none = iota
	read_head_space

	read_bq_1
	read_bq_2
	read_bq_3
	code
	read_bq_end_1
	read_bq_end_2
	read_bq_end_3

	read_ul
	read_h1
	read_h2
	text
	text_link_start
	text_link_end
	text_link_url_start
	text_link_url_end
	text_image_1
	text_image_start
	text_image_end
	text_image_url_start
	text_image_url_attr_key
	text_image_url_attr_value
	text_image_url_end
	text_br
)

func Parse(src string) (*Block, error) {
	out := make([]byte, 0, len(src)*2)
	var textValue []byte
	var linkText []byte
	var urlText []byte
	var attrKey []byte
	var attrValue []byte
	var attrs map[string]string
	state := state_none
	block := block_none
	index := 0
	srcLen := len(src)
	root := newBlock(TypeRoot)
	currentBlock := root
	blockStack := make([]*Block, 0)

	for index < srcLen {
		char := src[index]
		switch state {
		case state_none:
			if char == '#' {
				state = read_h1
			} else if char == '`' {
				state = read_bq_1
			} else if char == '\n' {
				if block == ul {
					currentBlock = blockStack[len(blockStack)-1]
					blockStack = blockStack[:len(blockStack)-1]
					out = addBlockEnd(out, block)
					block = block_none
				}
				// ignore
			} else if char == ' ' {
				state = read_head_space
			} else {
				pBlock := newBlock(TypeP)
				textBlock := newBlock(TypeText)
				pBlock.Children = append(pBlock.Children, textBlock)
				currentBlock.Children = append(currentBlock.Children, pBlock)
				blockStack = append(blockStack, currentBlock)
				blockStack = append(blockStack, pBlock)
				currentBlock = textBlock

				state = text
				block = p
				textValue = make([]byte, 0)
				out = appendStr(out, "
")
				index--
			}
		case read_bq_1:
			if char == '`' {
				state = read_bq_2
			} else {
				pBlock := newBlock(TypeP)
				textBlock := newBlock(TypeText)
				pBlock.Children = append(pBlock.Children, textBlock)
				currentBlock.Children = append(currentBlock.Children, pBlock)
				blockStack = append(blockStack, currentBlock)
				blockStack = append(blockStack, pBlock)
				currentBlock = textBlock

				state = text
				block = p
				textValue = make([]byte, 0)
				index--
			}
		case read_bq_2:
			if char == '`' {
				state = read_bq_3
			} else {
				pBlock := newBlock(TypeP)
				textBlock := newBlock(TypeText)
				pBlock.Children = append(pBlock.Children, textBlock)
				currentBlock.Children = append(currentBlock.Children, pBlock)
				blockStack = append(blockStack, currentBlock)
				blockStack = append(blockStack, pBlock)
				currentBlock = textBlock

				state = text
				block = p
				textValue = make([]byte, 0)
				textValue = appendStr(textValue, "``")
				out = appendStr(out, "``")
				index--
			}
		case read_bq_3:
			if char == '\n' {
				state = code
				block = code_block
				codeBlock := newBlock(TypePreCode)
				textBlock := newBlock(TypeText)
				textValue = make([]byte, 0)
				appendChild(currentBlock, codeBlock)
				appendChild(codeBlock, textBlock)
				blockStack = append(blockStack, currentBlock)
				blockStack = append(blockStack, codeBlock)
				currentBlock = textBlock
				out = appendStr(out, "
")
			} else {
				// TODO : check lang
				pBlock := newBlock(TypeP)
				textBlock := newBlock(TypeText)
				pBlock.Children = append(pBlock.Children, textBlock)
				currentBlock.Children = append(currentBlock.Children, pBlock)
				blockStack = append(blockStack, currentBlock)
				blockStack = append(blockStack, pBlock)
				currentBlock = textBlock

				state = text
				block = p
				textValue = make([]byte, 0)
				textValue = appendStr(textValue, "```")

				out = appendStr(out, "```")
				index--
			}
		case code:
			if char == '`' {
				state = read_bq_end_1
			} else if char == '<' {
				textValue = appendStr(textValue, "<")
				out = appendStr(out, "<")
			} else if char == '>' {
				textValue = appendStr(textValue, ">")
				out = appendStr(out, ">")
			} else {
				textValue = append(textValue, char)
				out = append(out, char)
			}
		case read_bq_end_1:
			if char == '`' {
				state = read_bq_end_2
			} else {
				textValue = append(textValue, '`')
				textValue = append(textValue, char)
				state = code
			}
		case read_bq_end_2:
			if char == '`' {
				state = read_bq_end_3
			} else {
				textValue = appendStr(textValue, "``")
				textValue = append(textValue, char)
				state = code
			}
		case read_bq_end_3:
			if char == '\n' {
				setTextValue(currentBlock, textValue)
				currentBlock = blockStack[len(blockStack)-2]
				blockStack = blockStack[:len(blockStack)-2]

				out = appendStr(out, "
\n\n")
				block = block_none
				state = state_none
			} else {
				return nil, errors.New(fmt.Sprintf("\\n expected byt %s at %d", char, index))
			}
		case read_head_space:
			if char == '*' || char == '-' {
				state = read_ul
			} else {
				state = text
				block = p
				out = appendStr(out, "
")
				out = append(out, char)
			}
		case read_ul:
			if char == ' ' {
				state = text
				if block == ul {
					liBlock := newBlock(TypeLI)
					textBlock := newBlock(TypeText)
					appendChild(currentBlock, liBlock)
					appendChild(liBlock, textBlock)
					blockStack = append(blockStack, currentBlock)
					blockStack = append(blockStack, liBlock)
					currentBlock = textBlock
					textValue = make([]byte, 0)
					out = appendStr(out, "
")
				} else {
					ulBlock := newBlock(TypeUL)
					liBlock := newBlock(TypeLI)
					textBlock := newBlock(TypeText)
					appendChild(currentBlock, ulBlock)
					appendChild(ulBlock, liBlock)
					appendChild(liBlock, textBlock)
					blockStack = append(blockStack, currentBlock)
					blockStack = append(blockStack, ulBlock)
					blockStack = append(blockStack, liBlock)
					currentBlock = textBlock
					textValue = make([]byte, 0)
					out = appendStr(out, "
\n
")
					block = ul
				}
			} else {
				return nil, errors.New(fmt.Sprintf("unexpected token at %d", index))
			}
		case text:
			if char == '\n' {
				if block == ul {
					state = state_none
					setTextValue(currentBlock, textValue)
					currentBlock = blockStack[len(blockStack)-2]
					blockStack = blockStack[:len(blockStack)-2]

					out = appendStr(out, "
\n")
				} else {
					state = text_br
				}
			} else if char == '[' {
				state = text_link_start
				linkText = make([]byte, 0)
			} else if char == '!' {
				state = text_image_1
				linkText = make([]byte, 0)
			} else if char == '<' {
				out = appendStr(out, "<")
			} else if char == '>' {
				out = appendStr(out, ">")
			} else {
				textValue = append(textValue, char)
			}
		case text_link_start:
			if char == ']' {
				state = text_link_end
			} else {
				linkText = append(linkText, char)
			}
		case text_link_end:
			if char == '(' {
				state = text_link_url_start
				urlText = make([]byte, 0)
			} else {
				return nil, errors.New(fmt.Sprintf("expected is ( but %s at %d", char, index))
			}
		case text_link_url_start:
			if char == ')' {
				state = text
				textBlock := newBlock(TypeText)
				textBlock.Value = string(textValue)
				textValue = make([]byte, 0)
				appendChild(currentBlock, textBlock)
				aBlock := newBlock(TypeAnchor)
				aBlock.URL = string(urlText)
				aBlock.Value = string(linkText)
				appendChild(currentBlock, aBlock)

				out = appendStr(out, fmt.Sprintf("%s", string(urlText), string(linkText)))
			} else {
				urlText = append(urlText, char)
			}
		case text_image_1:
			if char == '[' {
				state = text_image_start
			} else {
				out = appendStr(out, "!")
				index--
				state = text
			}
		case text_image_start:
			if char == ']' {
				state = text_image_end
			} else {
				linkText = append(linkText, char)
			}
		case text_image_end:
			if char == '(' {
				state = text_image_url_start
				urlText = make([]byte, 0)
			} else {
				return nil, errors.New(fmt.Sprintf("expected is ( but %s at %d", char, index))
			}
		case text_image_url_start:
			if char == ')' {
				state = text
				textBlock := newBlock(TypeText)
				textBlock.Value = string(textValue)
				textValue = make([]byte, 0)
				appendChild(currentBlock, textBlock)
				imageBlock := newBlock(TypeImage)
				imageBlock.URL = string(urlText)
				imageBlock.Value = string(linkText)
				appendChild(currentBlock, imageBlock)

				out = appendStr(out, fmt.Sprintf("", string(urlText), string(linkText)))
			} else if char == ' ' {
				state = text_image_url_attr_key
				attrKey = make([]byte, 0)
				attrs = make(map[string]string)
			} else {
				urlText = append(urlText, char)
			}
		case text_image_url_attr_key:
			if char == '=' {
				state = text_image_url_attr_value
				attrValue = make([]byte, 0)
			} else {
				attrKey = append(attrKey, char)
			}
		case text_image_url_attr_value:
			if char == ' ' {
				state = text_image_url_attr_key
				attrs[string(attrKey)] = string(attrValue)
				attrKey = make([]byte, 0)
			} else if char == ')' {
				attrs[string(attrKey)] = string(attrValue)
				state = text
				textBlock := newBlock(TypeText)
				textBlock.Value = string(textValue)
				textValue = make([]byte, 0)
				appendChild(currentBlock, textBlock)
				imageBlock := newBlock(TypeImage)
				imageBlock.URL = string(urlText)
				imageBlock.Value = string(linkText)
				imageBlock.Attributes = attrs
				appendChild(currentBlock, imageBlock)
			} else {
				attrValue = append(attrValue, char)
			}
		case text_br:
			if char == '\n' {
				state = state_none
				setTextValue(currentBlock, textValue)
				currentBlock = blockStack[len(blockStack)-2]
				blockStack = blockStack[:len(blockStack)-2]

				out = addBlockEnd(out, block)
				block = block_none
			} else {
				state = text
				textValue = append(textValue, ' ')
				textValue = append(textValue, char)
				out = append(out, ' ')
				out = append(out, char)
			}
		case read_h1: // #
			if char == ' ' {
				blockStack, currentBlock =
					addBlockText(blockStack,
						currentBlock,
						TypeH1)
				textValue = make([]byte, 0)

				block = h1
				state = text
				out = appendStr(out, "
")
			} else if char == '#' {
				state = read_h2
			}
		case read_h2: // ##
			if char == ' ' {
				blockStack, currentBlock =
					addBlockText(blockStack,
						currentBlock,
						TypeH2)
				textValue = make([]byte, 0)

				block = h2
				state = text
				out = appendStr(out, "
")
			}
		}
		index++
	}
	if currentBlock.Type == TypeText {
		setTextValue(currentBlock, textValue)
	}
	out = addBlockEnd(out, block)

	return root, nil
}

func addBlockText(stack []*Block, current *Block, blockType BlockType) ([]*Block, *Block) {
	block := newBlock(blockType)
	textBlock := newBlock(TypeText)
	// children
	current.Children = append(current.Children, block)
	block.Children = append(block.Children, textBlock)

	stack = append(stack, current)
	stack = append(stack, block)
	return stack, textBlock
}

func setTextValue(current *Block, value []byte) {
	if len(current.Children) == 0 {
		current.Value = string(value)
	} else {
		el := newBlock(TypeText)
		el.Value = string(value)
		current.Children = append(current.Children, el)
	}
}

func appendChild(b *Block, c *Block) {
	b.Children = append(b.Children, c)
}

func addBlockEnd(out []byte, block int) []byte {
	switch block {
	case h1:
		out = appendStr(out, "
\n\n")
	case h2:
		out = appendStr(out, "
\n\n")
	case ul:
		out = appendStr(out, "
\n\n")
	case p:
		out = appendStr(out, "
\n\n")
	}
	return out
}

func appendStr(out []byte, text string) []byte {
	return append(out, text...)
}
<commit_msg>fix format<commit_after>package ast

import (
	"errors"
	"fmt"
)

const (
	block_none = iota
	h1
	h2
	h3
	h4
	h5
	h6
	ul
	p
	code_block

	state_none = iota
	read_head_space

	read_bq_1
	read_bq_2
	read_bq_3
	code
	read_bq_end_1
	read_bq_end_2
	read_bq_end_3

	read_ul
	read_h1
	read_h2
	text
	text_link_start
	text_link_end
	text_link_url_start
	text_link_url_end
	text_image_1
	text_image_start
	text_image_end
	text_image_url_start
	text_image_url_attr_key
	text_image_url_attr_value
	text_image_url_end
	text_br
)

func Parse(src string) (*Block, error) {
	out := make([]byte, 0, len(src)*2)
	var textValue []byte
	var linkText []byte
	var urlText []byte
	var attrKey []byte
	var attrValue []byte
	var attrs map[string]string
	state := state_none
	block := block_none
	index := 0
	srcLen := len(src)
	root := newBlock(TypeRoot)
	currentBlock := root
	blockStack := make([]*Block, 0)

	for index < srcLen {
		char := src[index]
		switch state {
		case state_none:
			if char == '#' {
				state = read_h1
			} else if char == '`' {
				state = read_bq_1
			} else if char == '\n' {
				if block == ul {
					currentBlock = blockStack[len(blockStack)-1]
					blockStack = blockStack[:len(blockStack)-1]
					out = addBlockEnd(out, block)
					block = block_none
				}
				// ignore
			} else if char == ' ' {
				state = read_head_space
			} else {
				pBlock := newBlock(TypeP)
				textBlock := newBlock(TypeText)
				pBlock.Children = append(pBlock.Children, textBlock)
				currentBlock.Children = append(currentBlock.Children, pBlock)
				blockStack = append(blockStack, currentBlock)
				blockStack = append(blockStack, pBlock)
				currentBlock = textBlock

				state = text
				block = p
				textValue = make([]byte, 0)
				out = appendStr(out, "
")
				index--
			}
		case read_bq_1:
			if char == '`' {
				state = read_bq_2
			} else {
				pBlock := newBlock(TypeP)
				textBlock := newBlock(TypeText)
				pBlock.Children = append(pBlock.Children, textBlock)
				currentBlock.Children = append(currentBlock.Children, pBlock)
				blockStack = append(blockStack, currentBlock)
				blockStack = append(blockStack, pBlock)
				currentBlock = textBlock

				state = text
				block = p
				textValue = make([]byte, 0)
				index--
			}
		case read_bq_2:
			if char == '`' {
				state = read_bq_3
			} else {
				pBlock := newBlock(TypeP)
				textBlock := newBlock(TypeText)
				pBlock.Children = append(pBlock.Children, textBlock)
				currentBlock.Children = append(currentBlock.Children, pBlock)
				blockStack = append(blockStack, currentBlock)
				blockStack = append(blockStack, pBlock)
				currentBlock = textBlock

				state = text
				block = p
				textValue = make([]byte, 0)
				textValue = appendStr(textValue, "``")
				out = appendStr(out, "``")
				index--
			}
		case read_bq_3:
			if char == '\n' {
				state = code
				block = code_block
				codeBlock := newBlock(TypePreCode)
				textBlock := newBlock(TypeText)
				textValue = make([]byte, 0)
				appendChild(currentBlock, codeBlock)
				appendChild(codeBlock, textBlock)
				blockStack = append(blockStack, currentBlock)
				blockStack = append(blockStack, codeBlock)
				currentBlock = textBlock
				out = appendStr(out, "
")
			} else {
				// TODO : check lang
				pBlock := newBlock(TypeP)
				textBlock := newBlock(TypeText)
				pBlock.Children = append(pBlock.Children, textBlock)
				currentBlock.Children = append(currentBlock.Children, pBlock)
				blockStack = append(blockStack, currentBlock)
				blockStack = append(blockStack, pBlock)
				currentBlock = textBlock

				state = text
				block = p
				textValue = make([]byte, 0)
				textValue = appendStr(textValue, "```")

				out = appendStr(out, "```")
				index--
			}
		case code:
			if char == '`' {
				state = read_bq_end_1
			} else if char == '<' {
				textValue = appendStr(textValue, "<")
				out = appendStr(out, "<")
			} else if char == '>' {
				textValue = appendStr(textValue, ">")
				out = appendStr(out, ">")
			} else {
				textValue = append(textValue, char)
				out = append(out, char)
			}
		case read_bq_end_1:
			if char == '`' {
				state = read_bq_end_2
			} else {
				textValue = append(textValue, '`')
				textValue = append(textValue, char)
				state = code
			}
		case read_bq_end_2:
			if char == '`' {
				state = read_bq_end_3
			} else {
				textValue = appendStr(textValue, "``")
				textValue = append(textValue, char)
				state = code
			}
		case read_bq_end_3:
			if char == '\n' {
				setTextValue(currentBlock, textValue)
				currentBlock = blockStack[len(blockStack)-2]
				blockStack = blockStack[:len(blockStack)-2]

				out = appendStr(out, "
\n\n")
				block = block_none
				state = state_none
			} else {
				return nil, errors.New(fmt.Sprintf("\\n expected byte %d at %d", char, index))
			}
		case read_head_space:
			if char == '*' || char == '-' {
				state = read_ul
			} else {
				state = text
				block = p
				out = appendStr(out, "
")
				out = append(out, char)
			}
		case read_ul:
			if char == ' ' {
				state = text
				if block == ul {
					liBlock := newBlock(TypeLI)
					textBlock := newBlock(TypeText)
					appendChild(currentBlock, liBlock)
					appendChild(liBlock, textBlock)
					blockStack = append(blockStack, currentBlock)
					blockStack = append(blockStack, liBlock)
					currentBlock = textBlock
					textValue = make([]byte, 0)
					out = appendStr(out, "
")
				} else {
					ulBlock := newBlock(TypeUL)
					liBlock := newBlock(TypeLI)
					textBlock := newBlock(TypeText)
					appendChild(currentBlock, ulBlock)
					appendChild(ulBlock, liBlock)
					appendChild(liBlock, textBlock)
					blockStack = append(blockStack, currentBlock)
					blockStack = append(blockStack, ulBlock)
					blockStack = append(blockStack, liBlock)
					currentBlock = textBlock
					textValue = make([]byte, 0)
					out = appendStr(out, "
\n
")
					block = ul
				}
			} else {
				return nil, errors.New(fmt.Sprintf("unexpected token at %d", index))
			}
		case text:
			if char == '\n' {
				if block == ul {
					state = state_none
					setTextValue(currentBlock, textValue)
					currentBlock = blockStack[len(blockStack)-2]
					blockStack = blockStack[:len(blockStack)-2]

					out = appendStr(out, "
\n")
				} else {
					state = text_br
				}
			} else if char == '[' {
				state = text_link_start
				linkText = make([]byte, 0)
			} else if char == '!' {
				state = text_image_1
				linkText = make([]byte, 0)
			} else if char == '<' {
				out = appendStr(out, "<")
			} else if char == '>' {
				out = appendStr(out, ">")
			} else {
				textValue = append(textValue, char)
			}
		case text_link_start:
			if char == ']' {
				state = text_link_end
			} else {
				linkText = append(linkText, char)
			}
		case text_link_end:
			if char == '(' {
				state = text_link_url_start
				urlText = make([]byte, 0)
			} else {
				return nil, errors.New(fmt.Sprintf("expected is ( but %d at %d", char, index))
			}
		case text_link_url_start:
			if char == ')' {
				state = text
				textBlock := newBlock(TypeText)
				textBlock.Value = string(textValue)
				textValue = make([]byte, 0)
				appendChild(currentBlock, textBlock)
				aBlock := newBlock(TypeAnchor)
				aBlock.URL = string(urlText)
				aBlock.Value = string(linkText)
				appendChild(currentBlock, aBlock)

				out = appendStr(out, fmt.Sprintf("%s", string(urlText), string(linkText)))
			} else {
				urlText = append(urlText, char)
			}
		case text_image_1:
			if char == '[' {
				state = text_image_start
			} else {
				out = appendStr(out, "!")
				index--
				state = text
			}
		case text_image_start:
			if char == ']' {
				state = text_image_end
			} else {
				linkText = append(linkText, char)
			}
		case text_image_end:
			if char == '(' {
				state = text_image_url_start
				urlText = make([]byte, 0)
			} else {
				return nil, errors.New(fmt.Sprintf("expected is ( but %d at %d", char, index))
			}
		case text_image_url_start:
			if char == ')' {
				state = text
				textBlock := newBlock(TypeText)
				textBlock.Value = string(textValue)
				textValue = make([]byte, 0)
				appendChild(currentBlock, textBlock)
				imageBlock := newBlock(TypeImage)
				imageBlock.URL = string(urlText)
				imageBlock.Value = string(linkText)
				appendChild(currentBlock, imageBlock)

				out = appendStr(out, fmt.Sprintf("", string(urlText), string(linkText)))
			} else if char == ' ' {
				state = text_image_url_attr_key
				attrKey = make([]byte, 0)
				attrs = make(map[string]string)
			} else {
				urlText = append(urlText, char)
			}
		case text_image_url_attr_key:
			if char == '=' {
				state = text_image_url_attr_value
				attrValue = make([]byte, 0)
			} else {
				attrKey = append(attrKey, char)
			}
		case text_image_url_attr_value:
			if char == ' ' {
				state = text_image_url_attr_key
				attrs[string(attrKey)] = string(attrValue)
				attrKey = make([]byte, 0)
			} else if char == ')' {
				attrs[string(attrKey)] = string(attrValue)
				state = text
				textBlock := newBlock(TypeText)
				textBlock.Value = string(textValue)
				textValue = make([]byte, 0)
				appendChild(currentBlock, textBlock)
				imageBlock := newBlock(TypeImage)
				imageBlock.URL = string(urlText)
				imageBlock.Value = string(linkText)
				imageBlock.Attributes = attrs
				appendChild(currentBlock, imageBlock)
			} else {
				attrValue = append(attrValue, char)
			}
		case text_br:
			if char == '\n' {
				state = state_none
				setTextValue(currentBlock, textValue)
				currentBlock = blockStack[len(blockStack)-2]
				blockStack = blockStack[:len(blockStack)-2]

				out = addBlockEnd(out, block)
				block = block_none
			} else {
				state = text
				textValue = append(textValue, ' ')
				textValue = append(textValue, char)
				out = append(out, ' ')
				out = append(out, char)
			}
		case read_h1: // #
			if char == ' ' {
				blockStack, currentBlock =
					addBlockText(blockStack,
						currentBlock,
						TypeH1)
				textValue = make([]byte, 0)

				block = h1
				state = text
				out = appendStr(out, "
")
			} else if char == '#' {
				state = read_h2
			}
		case read_h2: // ##
			if char == ' ' {
				blockStack, currentBlock =
					addBlockText(blockStack,
						currentBlock,
						TypeH2)
				textValue = make([]byte, 0)

				block = h2
				state = text
				out = appendStr(out, "
")
			}
		}
		index++
	}
	if currentBlock.Type == TypeText {
		setTextValue(currentBlock, textValue)
	}
	out = addBlockEnd(out, block)

	return root, nil
}

func addBlockText(stack []*Block, current *Block, blockType BlockType) ([]*Block, *Block) {
	block := newBlock(blockType)
	textBlock := newBlock(TypeText)
	// children
	current.Children = append(current.Children, block)
	block.Children = append(block.Children, textBlock)

	stack = append(stack, current)
	stack = append(stack, block)
	return stack, textBlock
}

func setTextValue(current *Block, value []byte) {
	if len(current.Children) == 0 {
		current.Value = string(value)
	} else {
		el := newBlock(TypeText)
		el.Value = string(value)
		current.Children = append(current.Children, el)
	}
}

func appendChild(b *Block, c *Block) {
	b.Children = append(b.Children, c)
}

func addBlockEnd(out []byte, block int) []byte {
	switch block {
	case h1:
		out = appendStr(out, "
\n\n")
	case h2:
		out = appendStr(out, "
\n\n")
	case ul:
		out = appendStr(out, "
\n\n")
	case p:
		out = appendStr(out, "
\n\n")
	}
	return out
}

func appendStr(out []byte, text string) []byte {
	return append(out, text...)
}
<|endoftext|>


<commit_before>// +build darwin linux

package collectors

import (
	"encoding/json"
	"net/http"
	"sync"
	"time"

	"github.com/StackExchange/scollector/metadata"
	"github.com/StackExchange/scollector/opentsdb"
	"github.com/StackExchange/slog"
)

func init() {
	collectors = append(collectors, &IntervalCollector{F: c_hbase_region, init: hbrInit})
}

var (
	hbaseEnable bool
	hbaseLock   sync.Mutex
)

func hbaseEnabled() (b bool) {
	hbaseLock.Lock()
	b = hbaseEnable
	hbaseLock.Unlock()
	return
}

const hbrURL = "http://localhost:60030/jmx?qry=hadoop:service=RegionServer,name=RegionServerStatistics"

func hbrInit() {
	update := func() {
		resp, err := http.Get(hbrURL)
		hbaseLock.Lock()
		defer hbaseLock.Unlock()
		if err != nil {
			hbaseEnable = false
			return
		}
		resp.Body.Close()
		hbaseEnable = resp.StatusCode == 200
	}
	update()
	go func() {
		for _ = range time.Tick(time.Minute * 5) {
			update()
		}
	}()
}

func c_hbase_region() opentsdb.MultiDataPoint {
	if !hbaseEnabled() {
		return nil
	}
	var md opentsdb.MultiDataPoint
	res, err := http.Get(hbrURL)
	if err != nil {
		slog.Errorln(err)
		return nil
	}
	defer res.Body.Close()
	var r struct {
		Beans []map[string]interface{} `json:"beans"`
	}
	j := json.NewDecoder(res.Body)
	if err := j.Decode(&r); err != nil {
		slog.Errorln(err)
		return nil
	}
	if len(r.Beans) > 0 && len(r.Beans[0]) > 0 {
		for k, v := range r.Beans[0] {
			if _, ok := v.(float64); ok {
				Add(&md, "hbase.region."+k, v, nil, metadata.Unknown, metadata.None, "")
			}
		}
	}
	return md
}
<commit_msg>cmd/scollector: Merge branch 'master' of github.com:StackExchange/scollector<commit_after>// +build darwin linux

package collectors

import (
	"encoding/json"
	"net/http"
	"strings"
	"sync"
	"time"

	"github.com/StackExchange/scollector/metadata"
	"github.com/StackExchange/scollector/opentsdb"
	"github.com/StackExchange/slog"
)

func init() {
	collectors = append(collectors, &IntervalCollector{F: c_hbase_region, init: hbrInit})
	collectors = append(collectors, &IntervalCollector{F: c_hbase_replication, init: hbrepInit})
}

type hEnabled struct {
	Enable bool
	sync.Mutex
}

var (
	hbrEnable   hEnabled
	hbrepEnable hEnabled
)

func (e hEnabled) Enabled() (b bool) {
	e.Lock()
	b = e.Enable
	e.Unlock()
	return
}

const hbrURL = "http://localhost:60030/jmx?qry=hadoop:service=RegionServer,name=RegionServerStatistics"
const hbrepURL = "http://localhost:60030/jmx?qry=hadoop:service=Replication,name=*"

func hTestUrl(url string, e *hEnabled) func() {
	update := func() {
		resp, err := http.Get(url)
		e.Lock()
		defer e.Unlock()
		if err != nil {
			e.Enable = false
			return
		}
		resp.Body.Close()
		e.Enable = resp.StatusCode == 200
	}
	return update
}

func hbrInit() {
	update := hTestUrl(hbrURL, &hbrEnable)
	update()
	go func() {
		for _ = range time.Tick(time.Minute * 5) {
			update()
		}
	}()
}

type jmx struct {
	Beans []map[string]interface{} `json:"beans"`
}

func getBeans(url string, jmx *jmx) error {
	res, err := http.Get(url)
	if err != nil {
		return err
	}
	defer res.Body.Close()
	if err := json.NewDecoder(res.Body).Decode(&jmx); err != nil {
		return err
	}
	return nil
}

func c_hbase_region() opentsdb.MultiDataPoint {
	if !hbrEnable.Enabled() {
		return nil
	}
	var jmx jmx
	if err := getBeans(hbrURL, &jmx); err != nil {
		slog.Errorln(err)
		return nil
	}
	var md opentsdb.MultiDataPoint
	if len(jmx.Beans) > 0 && len(jmx.Beans[0]) > 0 {
		for k, v := range jmx.Beans[0] {
			if _, ok := v.(float64); ok {
				Add(&md, "hbase.region."+k, v, nil, metadata.Unknown, metadata.None, "")
			}
		}
	}
	return md
}

func hbrepInit() {
	update := hTestUrl(hbrepURL, &hbrepEnable)
	update()
	go func() {
		for _ = range time.Tick(time.Minute * 5) {
			update()
		}
	}()
}

func c_hbase_replication() opentsdb.MultiDataPoint {
	if !hbrepEnable.Enabled() {
		return nil
	}
	var jmx jmx
	if err := getBeans(hbrepURL, &jmx); err != nil {
		slog.Errorln(err)
		return nil
	}
	var md opentsdb.MultiDataPoint
	for _, section := range jmx.Beans {
		var tags opentsdb.TagSet
		for k, v := range section {
			if s, ok := v.(string); ok && k == "name" {
				if strings.HasPrefix(s, "hadoop:service=Replication,name=ReplicationSource for") {
					sa := strings.Split(s, " ")
					if len(sa) == 3 {
						tags = opentsdb.TagSet{"instance": sa[2]}
						break
					}
				}
			}
		}
		for k, v := range section {
			if _, ok := v.(float64); ok {
				Add(&md, "hbase.region."+k, v, tags, metadata.Unknown, metadata.None, "")
			}
		}
	}
	return md
}
<|endoftext|>


<commit_before>/*
 * Functions in this file are used to forward syslog messages to the
 * host and must be quite careful about their own logging. In general
 * error messages should go via the console log.Logger defined in this
 * file.
 */
package main

import (
	"encoding/binary"
	"errors"
	"log"
	"net"
	"os"
	"strconv"
	"strings"

	"github.com/rneugeba/virtsock/go/hvsock"
	"github.com/rneugeba/virtsock/go/vsock"
)

var (
	console     *log.Logger
	currentConn vConn

	alreadyConnectedOnce bool

	/* When writing we don't discover e.g. EPIPE until the _next_
	 * attempt to write. Therefore we keep a copy of the last
	 * message sent such that we can repeat it after an error.
	 *
	 * Note that this is imperfect since their can be multiple
	 * messages in flight at the point a connection collapses
	 * which will then be lost. This only handles the delayed
	 * notification of such an error to this code.
	 */
	lastMessage []byte
)

func checkedWrite(conn vConn, buf []byte) error {

	var l uint32 = uint32(len(buf))

	err := binary.Write(conn, binary.LittleEndian, l)
	/* XXX todo, check for serious vs retriable errors */
	if err != nil {
		console.Printf("Error in length write: %s", err)
		return err
	}

	_, err = conn.Write(buf)
	/* XXX todo, check for serious vs retriable errors */
	if err != nil {
		console.Printf("Error in buf write: %s", err)
	}

	return err
}

func forwardSyslogDatagram(buf []byte, portstr string) error {
	for try := 0; try < 2; try++ {
		conn := currentConn
		if conn == nil {
			if strings.Contains(portstr, "-") {
				svcid, err := hvsock.GuidFromString(portstr)
				if err != nil {
					console.Fatalln("Failed to parse GUID", portstr, err)
				}

				conn, err = hvsock.Dial(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid})
				if err != nil {
					console.Printf("Failed to dial hvsock port: %s", err)
					continue
				}
			} else {
				port, err := strconv.ParseUint(portstr, 10, 32)
				if err != nil {
					console.Fatalln("Can't convert %s to a uint.", portstr, err)
				}

				conn, err = vsock.Dial(vsock.VSOCK_CID_HOST, uint(port))
				if err != nil {
					console.Printf("Failed to dial vsock port %d: %s", port, err)
					continue
				}
			}

			conn.CloseRead()

			/*
			 * Only log on reconnection, not the initial connection since
			 * that is mostly uninteresting
			 */
			if alreadyConnectedOnce {
				console.Printf("Opened new conn to %s: %#v", portstr, conn)
			}
			alreadyConnectedOnce = true

			if lastMessage != nil {
				console.Printf("Replaying last message: %s", lastMessage)
				err := checkedWrite(conn, lastMessage)
				if err != nil {
					conn.Close()
					continue
				}
				lastMessage = nil
			}

			currentConn = conn
		}

		err := checkedWrite(conn, buf)
		if err != nil {
			currentConn.Close()
			currentConn = nil
			console.Printf("Failed to write: %s", string(buf))
			continue
		}

		if try > 0 {
			console.Printf("Forwarded on attempt %d: %s", try+1, string(buf))
		}

		// Keep a copy in case we get an EPIPE from the next write
		lastMessage = make([]byte, len(buf))
		copy(lastMessage, buf)

		return nil
	}

	lastMessage = nil // No point repeating this now
	return errors.New("Failed to send datagram, too many retries")
}

func handleSyslogForward(cfg string) {
	// logging to the default syslog while trying to do syslog
	// forwarding would result in infinite loops, so log all
	// messages in this callchain to the console instead.
	logFile, err := os.OpenFile("/dev/console", os.O_WRONLY, 0)
	if err != nil {
		/* What are the chances of this going anywhere useful... */
		log.Fatalln("Failed to open /dev/console for syslog forward logging", err)
	}

	console = log.New(logFile, "vsyslog: ", log.LstdFlags)

	s := strings.SplitN(cfg, ":", 2)
	if len(s) != 2 {
		console.Fatalf("Failed to parse: %s", cfg)
	}
	vsock := s[0]
	usock := s[1]

	err = os.Remove(usock)
	if err != nil && !os.IsNotExist(err) {
		console.Printf("Failed to remove %s: %s", usock, err)
		/* Try and carry on... */
	}

	l, err := net.ListenUnixgram("unixgram", &net.UnixAddr{usock, "unixgram"})
	if err != nil {
		console.Fatalf("Failed to listen to unixgram:%s: %s", usock, err)
	}

	var buf [4096]byte // Ugh, no way to peek at the next message's size in Go
	for {
		r, err := l.Read(buf[:])
		if err != nil {
			console.Fatalf("Failed to read: %s", err)
		}

		err = forwardSyslogDatagram(buf[:r], vsock)
		if err != nil {
			console.Printf("Failed to send log: %s: %s",
				err, string(buf[:r]))
		}
	}
}
<commit_msg>vsudd: Use RFC5425 scheme for syslog forwarding<commit_after>/*
 * Functions in this file are used to forward syslog messages to the
 * host and must be quite careful about their own logging. In general
 * error messages should go via the console log.Logger defined in this
 * file.
 */
package main

import (
	"errors"
	"fmt"
	"log"
	"net"
	"os"
	"strconv"
	"strings"

	"github.com/rneugeba/virtsock/go/hvsock"
	"github.com/rneugeba/virtsock/go/vsock"
)

var (
	console     *log.Logger
	currentConn vConn

	alreadyConnectedOnce bool

	/* When writing we don't discover e.g. EPIPE until the _next_
	 * attempt to write. Therefore we keep a copy of the last
	 * message sent such that we can repeat it after an error.
	 *
	 * Note that this is imperfect since their can be multiple
	 * messages in flight at the point a connection collapses
	 * which will then be lost. This only handles the delayed
	 * notification of such an error to this code.
	 */
	lastMessage []byte
)

/* rfc5425 like scheme, see section 4.3 */
func rfc5425Write(conn vConn, buf []byte) error {

	msglen := fmt.Sprintf("%d ", len(buf))

	_, err := conn.Write([]byte(msglen))
	/* XXX todo, check for serious vs retriable errors */
	if err != nil {
		console.Printf("Error in length write: %s", err)
		return err
	}

	_, err = conn.Write(buf)
	/* XXX todo, check for serious vs retriable errors */
	if err != nil {
		console.Printf("Error in buf write: %s", err)
	}

	return err
}

func forwardSyslogDatagram(buf []byte, portstr string) error {
	for try := 0; try < 2; try++ {
		conn := currentConn
		if conn == nil {
			if strings.Contains(portstr, "-") {
				svcid, err := hvsock.GuidFromString(portstr)
				if err != nil {
					console.Fatalln("Failed to parse GUID", portstr, err)
				}

				conn, err = hvsock.Dial(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid})
				if err != nil {
					console.Printf("Failed to dial hvsock port: %s", err)
					continue
				}
			} else {
				port, err := strconv.ParseUint(portstr, 10, 32)
				if err != nil {
					console.Fatalln("Can't convert %s to a uint.", portstr, err)
				}

				conn, err = vsock.Dial(vsock.VSOCK_CID_HOST, uint(port))
				if err != nil {
					console.Printf("Failed to dial vsock port %d: %s", port, err)
					continue
				}
			}

			conn.CloseRead()

			/*
			 * Only log on reconnection, not the initial connection since
			 * that is mostly uninteresting
			 */
			if alreadyConnectedOnce {
				console.Printf("Opened new conn to %s: %#v", portstr, conn)
			}
			alreadyConnectedOnce = true

			if lastMessage != nil {
				console.Printf("Replaying last message: %s", lastMessage)
				err := rfc5425Write(conn, lastMessage)
				if err != nil {
					conn.Close()
					continue
				}
				lastMessage = nil
			}

			currentConn = conn
		}

		err := rfc5425Write(conn, buf)
		if err != nil {
			currentConn.Close()
			currentConn = nil
			console.Printf("Failed to write: %s", string(buf))
			continue
		}

		if try > 0 {
			console.Printf("Forwarded on attempt %d: %s", try+1, string(buf))
		}

		// Keep a copy in case we get an EPIPE from the next write
		lastMessage = make([]byte, len(buf))
		copy(lastMessage, buf)

		return nil
	}

	lastMessage = nil // No point repeating this now
	return errors.New("Failed to send datagram, too many retries")
}

func handleSyslogForward(cfg string) {
	// logging to the default syslog while trying to do syslog
	// forwarding would result in infinite loops, so log all
	// messages in this callchain to the console instead.
	logFile, err := os.OpenFile("/dev/console", os.O_WRONLY, 0)
	if err != nil {
		/* What are the chances of this going anywhere useful... */
		log.Fatalln("Failed to open /dev/console for syslog forward logging", err)
	}

	console = log.New(logFile, "vsyslog: ", log.LstdFlags)

	s := strings.SplitN(cfg, ":", 2)
	if len(s) != 2 {
		console.Fatalf("Failed to parse: %s", cfg)
	}
	vsock := s[0]
	usock := s[1]

	err = os.Remove(usock)
	if err != nil && !os.IsNotExist(err) {
		console.Printf("Failed to remove %s: %s", usock, err)
		/* Try and carry on... */
	}

	l, err := net.ListenUnixgram("unixgram", &net.UnixAddr{usock, "unixgram"})
	if err != nil {
		console.Fatalf("Failed to listen to unixgram:%s: %s", usock, err)
	}

	var buf [4096]byte // Ugh, no way to peek at the next message's size in Go
	for {
		r, err := l.Read(buf[:])
		if err != nil {
			console.Fatalf("Failed to read: %s", err)
		}

		err = forwardSyslogDatagram(buf[:r], vsock)
		if err != nil {
			console.Printf("Failed to send log: %s: %s",
				err, string(buf[:r]))
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"math/rand"
	"time"
)

func RandomString(strlen int) string {
	rand.Seed(time.Now().UTC().UnixNano())
	const chars = "abcdefghipqrstuvwxyz0123456789"
	result := make([]byte, strlen)
	for i := 0; i < strlen; i++ {
		result[i] = chars[rand.Intn(len(chars))]
	}
	return string(result)
}

const passLength = 20

func main() {
	fieldnames := []string{
		"router-pass",
		"nats-pass",
		"mysql-admin-password",
		"mysql-bootstrap-password",
		"mysql-proxy-api-password",
		"cc-staging-upload-password",
		"cc-bulk-api-password",
		"cc-internal-api-password",
		"db-uaa-password",
		"db-ccdb-password",
		"db-console-password",
		"diego-db-passphrase",
		"uaa-ldap-user-password",
		"admin-password",
		"push-apps-manager-password",
		"smoke-tests-password",
		"system-services-password",
		"system-verification-password",
		"system-passwords-client-secret",
		"doppler-shared-secret",
		"ssh-proxy-uaa-secret",
		"metron-secret",
		"uaa-admin-secret",
		"opentsdb-firehose-nozzle-client-secret",
		"identity-client-secret",
		"login-client-secret",
		"portal-client-secret",
		"autoscaling-service-client-secret",
		"cc-service-dashboards-client-secret",
		"doppler-client-secret",
		"gorouter-client-secret",
		"notifications-client-secret",
		"notifications-ui-client-secret",
		"cloud-controller-username-lookup-client-secret",
		"cc-routing-client-secret",
		"ssh-proxy-client-secret",
		"apps-metrics-client-secret",
		"apps-metrics-processing-client-secret",
	}
	var passVault map[string]string = make(map[string]string)

	for _, fn := range fieldnames {
		passVault[fn] = RandomString(passLength)
	}
	b, _ := json.Marshal(passVault)
	fmt.Println(string(b))
}
<commit_msg>[#125968975] adding more default keys to the vault passgen script<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"math/rand"
	"time"
)

func RandomString(strlen int) string {
	rand.Seed(time.Now().UTC().UnixNano())
	const chars = "abcdefghipqrstuvwxyz0123456789"
	result := make([]byte, strlen)
	for i := 0; i < strlen; i++ {
		result[i] = chars[rand.Intn(len(chars))]
	}
	return string(result)
}

const passLength = 20

func main() {
	fieldnames := []string{
		"router-pass",
		"nats-pass",
		"mysql-admin-password",
		"mysql-bootstrap-password",
		"mysql-proxy-api-password",
		"cc-staging-upload-password",
		"cc-bulk-api-password",
		"cc-internal-api-password",
		"db-uaa-password",
		"db-ccdb-password",
		"db-console-password",
		"diego-db-passphrase",
		"uaa-ldap-user-password",
		"admin-password",
		"push-apps-manager-password",
		"smoke-tests-password",
		"system-services-password",
		"system-verification-password",
		"system-passwords-client-secret",
		"doppler-shared-secret",
		"ssh-proxy-uaa-secret",
		"metron-secret",
		"uaa-admin-secret",
		"opentsdb-firehose-nozzle-client-secret",
		"identity-client-secret",
		"login-client-secret",
		"portal-client-secret",
		"autoscaling-service-client-secret",
		"cc-service-dashboards-client-secret",
		"doppler-client-secret",
		"gorouter-client-secret",
		"notifications-client-secret",
		"notifications-ui-client-secret",
		"cloud-controller-username-lookup-client-secret",
		"cc-routing-client-secret",
		"ssh-proxy-client-secret",
		"apps-metrics-client-secret",
		"apps-metrics-processing-client-secret",
		"consul-encryption-key",
		"cc-db-encryption-key",
		"host-key-fingerprint",
		"uaa-jwt-signing-key",
		"uaa-jwt-verification-key",
		"uaa-saml-service-provider-key",
	}
	var passVault map[string]string = make(map[string]string)

	for _, fn := range fieldnames {
		passVault[fn] = RandomString(passLength)
	}
	b, _ := json.Marshal(passVault)
	fmt.Println(string(b))
}
<|endoftext|>


<commit_before>package web

import (
	"net"
	"net/http"

	"testing"
)

var testResponse string = "<http>
Raw Text

Paragraph
span</http>"

type testServerHandler struct{}

func (h *testServerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte(testResponse))
}

func TestScrape(t *testing.T) {
	l, e := startServer()
	if e != nil {
		t.Error(e)
	}
	defer l.Close()

	scraper := NewWebScraper()
	addr := "http://" + l.Addr().String() + "/blah/blah"
	t.Logf("Addr '%s'\n", addr)
	s, e := scraper.Scrape(addr)
	if e != nil {
		t.Error(e)
	}
	if s == nil {
		t.Error("Returned nothing")
	}
	if s.Raw() == "" {
		t.Error("Raw result is empty")
	}
	if len(s.Matches()) != 3 {
		t.Error("Found wrong number of matches", len(s.Matches()), s.Matches())
	}
}

func TestCustomScrape(t *testing.T) {
	l, e := startServer()
	if e != nil {
		t.Error(e)
	}
	defer l.Close()

	scraper := NewWebScraper()
	scraper.ScrapePredicates = []ScrapePredicate{HasClass("test3")}
	scraper.ScrapeAction = TextChildren
	addr := "http://" + l.Addr().String() + "/blah/blah"
	t.Logf("Addr '%s'\n", addr)
	s, e := scraper.Scrape(addr)

	if e != nil {
		t.Error(e)
	}
	if s == nil {
		t.Error("Returned nothing")
	}
	if s.Raw() == "" {
		t.Error("Raw result is empty")
	}
	if len(s.Matches()) != 1 {
		t.Error("Found wrong number of matches", len(s.Matches()), s.Matches())
	}
}

func startServer() (net.Listener, error) {
	l, e := net.Listen("tcp", "127.0.0.1:0")
	if e != nil {
		return nil, e
	}
	go http.Serve(l, &testServerHandler{})
	return l, nil
}
<commit_msg>test url scraping<commit_after>package web

import (
	"net"
	"net/http"

	"testing"
)

var testResponse string = "<http>
Raw Text

Paragraph
span</http>"

type testServerHandler struct{}

func (h *testServerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte(testResponse))
}

func TestScrape(t *testing.T) {
	l, e := startServer()
	if e != nil {
		t.Error(e)
	}
	defer l.Close()

	scraper := NewWebScraper()
	addr := "http://" + l.Addr().String() + "/blah/blah"
	t.Logf("Addr '%s'\n", addr)
	s, e := scraper.Scrape(addr)
	if e != nil {
		t.Error(e)
	}
	if s == nil {
		t.Error("Returned nothing")
	}
	if s.Raw() == "" {
		t.Error("Raw result is empty")
	}
	if len(s.Matches()) != 3 {
		t.Error("Found wrong number of matches", len(s.Matches()), s.Matches())
	}
}

func TestCustomScrape(t *testing.T) {
	l, e := startServer()
	if e != nil {
		t.Error(e)
	}
	defer l.Close()

	scraper := NewWebScraper()
	scraper.ScrapePredicates = []ScrapePredicate{HasClass("test3")}
	scraper.ScrapeAction = TextChildren
	addr := "http://" + l.Addr().String() + "/blah/blah"
	t.Logf("Addr '%s'\n", addr)
	s, e := scraper.Scrape(addr)

	if e != nil {
		t.Error(e)
	}
	if s == nil {
		t.Error("Returned nothing")
	}
	if s.Raw() == "" {
		t.Error("Raw result is empty")
	}
	if len(s.Matches()) != 1 {
		t.Error("Found wrong number of matches", len(s.Matches()), s.Matches())
	}
}

func TestGetAttr(t *testing.T) {
	l, e := startServer()
	if e != nil {
		t.Error(e)
	}
	defer l.Close()

	scraper := NewWebScraper()
	scraper.ScrapePredicates = []ScrapePredicate{HasAttr("href")}
	scraper.ScrapeAction = AttrValue("href")
	addr := "http://" + l.Addr().String() + "/blah/blah"
	t.Logf("Addr '%s'\n", addr)
	s, e := scraper.Scrape(addr)

	if e != nil {
		t.Error(e)
	}
	if s == nil {
		t.Error("Returned nothing")
	}
	if s.Raw() == "" {
		t.Error("Raw result is empty")
	}
	expected, got := []interface{}{"fakeurl", "fakeurl2"}, s.Matches()
	if len(got) != 2 {
		t.Error("Found wrong number of matches", len(got), got)
	}
	if !same(expected, got) {
		t.Error("Expected: ", expected, ", Got: ", got)
	}
}

func same(expected, got []interface{}) bool {
	if len(expected) != len(got) {
		return false
	}
	for ix, v := range expected {
		if v != got[ix] {
			return false
		}
	}
	return true
}
func startServer() (net.Listener, error) {
	l, e := net.Listen("tcp", "127.0.0.1:0")
	if e != nil {
		return nil, e
	}
	go http.Serve(l, &testServerHandler{})
	return l, nil
}
<|endoftext|>


<commit_before>package webdb

import (
	"github.com/altairsix/pkg/dbase"
	"github.com/altairsix/pkg/web"
	"github.com/jinzhu/gorm"
)

const (
	accessorKey = "accessor"
	refKey      = "ref"
)

type reference struct {
	db *gorm.DB
}

func fetch(c web.Context) (*gorm.DB, bool) {
	if v := c.Get(refKey); v != nil {
		if ref, ok := v.(*reference); ok {
			return ref.db, true
		}
	}

	return nil, false
}

func Open(c web.Context) (*gorm.DB, error) {
	db, ok := fetch(c)
	if ok {
		return db, nil
	}

	accessor := c.Get(accessorKey).(dbase.Accessor)
	db, err := accessor.Open()
	if err != nil {
		return nil, err
	}

	ref := &reference{db: db}
	c.Set(refKey, ref)

	return db, nil
}

func Filter(accessor dbase.Accessor) web.Filter {
	return func(h web.HandlerFunc) web.HandlerFunc {
		return func(c web.Context) error {
			c.Set(accessorKey, accessor)
			err := h(c)

			if db, ok := fetch(c); ok {
				if err != nil {
					accessor.Rollback(db)
				} else {
					accessor.Commit(db)
				}
				accessor.Close(db)
			}

			return err
		}
	}
}
<commit_msg>- ensuring webdb Filter always closes db connection<commit_after>package webdb

import (
	"github.com/altairsix/pkg/dbase"
	"github.com/altairsix/pkg/web"
	"github.com/jinzhu/gorm"
)

const (
	accessorKey = "accessor"
	refKey      = "ref"
)

type reference struct {
	db *gorm.DB
}

func fetch(c web.Context) (*gorm.DB, bool) {
	if v := c.Get(refKey); v != nil {
		if ref, ok := v.(*reference); ok {
			return ref.db, true
		}
	}

	return nil, false
}

func Open(c web.Context) (*gorm.DB, error) {
	db, ok := fetch(c)
	if ok {
		return db, nil
	}

	accessor := c.Get(accessorKey).(dbase.Accessor)
	db, err := accessor.Open()
	if err != nil {
		return nil, err
	}

	ref := &reference{db: db}
	c.Set(refKey, ref)

	return db, nil
}

func Filter(accessor dbase.Accessor) web.Filter {
	return func(h web.HandlerFunc) web.HandlerFunc {
		return func(c web.Context) error {
			c.Set(accessorKey, accessor)
			err := h(c)

			if db, ok := fetch(c); ok {
				defer accessor.Close(db)

				if err != nil {
					accessor.Rollback(db)
				} else {
					accessor.Commit(db)
				}
			}

			return err
		}
	}
}
<|endoftext|>


<commit_before>package opencv

import (
	"image"
	"image/color"
	"unsafe"
)

/* DecodeImageMem decodes an image from an in memory byte buffer. */
func DecodeImageMem(data []byte) *IplImage {
	buf := CreateMatHeader(1, len(data), CV_8U)
	buf.SetData(unsafe.Pointer(&data[0]), CV_AUTOSTEP)
	defer buf.Release()

	return DecodeImage(unsafe.Pointer(buf), CV_LOAD_IMAGE_UNCHANGED)
}

/* FromImage converts a go image.Image to an opencv.IplImage. */
func FromImage(img image.Image) *IplImage {
	b := img.Bounds()
	model := color.RGBAModel
	dst := CreateImage(
		b.Max.X-b.Min.X,
		b.Max.Y-b.Min.Y,
		IPL_DEPTH_8U, 4)

	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			px := img.At(x, y)
			c := model.Convert(px).(color.RGBA)

			value := NewScalar(float64(c.B), float64(c.G), float64(c.R), float64(c.A))
			dst.Set2D(x-b.Min.X, y-b.Min.Y, value)
		}
	}

	return dst
}

/* FromImageUnsafe create an opencv.IplImage that shares the buffer with the
go image.RGBA image. All changes made from opencv might affect go! */
func FromImageUnsafe(img *image.RGBA) *IplImage {
	b := img.Bounds()
	buf := CreateImageHeader(
		b.Max.X-b.Min.X,
		b.Max.Y-b.Min.Y,
		IPL_DEPTH_8U, 4)
	dst := CreateImage(
		b.Max.X-b.Min.X,
		b.Max.Y-b.Min.Y,
		IPL_DEPTH_8U, 4)

	buf.SetData(unsafe.Pointer(&img.Pix[0]), CV_AUTOSTEP)
	CvtColor(buf, dst, CV_RGBA2BGRA)
	buf.Release()

	return dst
}

/* ToImage converts a opencv.IplImage to an go image.Image */
func (img *IplImage) ToImage() image.Image {
	out := image.NewNRGBA(image.Rect(0, 0, img.Width(), img.Height()))
	if img.Depth() != IPL_DEPTH_8U {
		return nil // TODO return error
	}

	for y := 0; y < img.Height(); y++ {
		for x := 0; x < img.Width(); x++ {
			s := img.Get2D(x, y).Val()
			b, g, r, a := s[2], s[1], s[0], s[3]

			c := color.NRGBA{uint8(r), uint8(g), uint8(b), uint8(a)}
			out.Set(x, y, c)
		}
	}

	return out
}
<commit_msg>Fix channel ordering and 0 alpha channel<commit_after>package opencv

import (
	"image"
	"image/color"
	"unsafe"
)

/* DecodeImageMem decodes an image from an in memory byte buffer. */
func DecodeImageMem(data []byte) *IplImage {
	buf := CreateMatHeader(1, len(data), CV_8U)
	buf.SetData(unsafe.Pointer(&data[0]), CV_AUTOSTEP)
	defer buf.Release()

	return DecodeImage(unsafe.Pointer(buf), CV_LOAD_IMAGE_UNCHANGED)
}

/* FromImage converts a go image.Image to an opencv.IplImage. */
func FromImage(img image.Image) *IplImage {
	b := img.Bounds()
	model := color.RGBAModel
	dst := CreateImage(
		b.Max.X-b.Min.X,
		b.Max.Y-b.Min.Y,
		IPL_DEPTH_8U, 4)

	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			px := img.At(x, y)
			c := model.Convert(px).(color.RGBA)

			value := NewScalar(float64(c.B), float64(c.G), float64(c.R), float64(c.A))
			dst.Set2D(x-b.Min.X, y-b.Min.Y, value)
		}
	}

	return dst
}

/* FromImageUnsafe create an opencv.IplImage that shares the buffer with the
go image.RGBA image. All changes made from opencv might affect go! */
func FromImageUnsafe(img *image.RGBA) *IplImage {
	b := img.Bounds()
	buf := CreateImageHeader(
		b.Max.X-b.Min.X,
		b.Max.Y-b.Min.Y,
		IPL_DEPTH_8U, 4)
	dst := CreateImage(
		b.Max.X-b.Min.X,
		b.Max.Y-b.Min.Y,
		IPL_DEPTH_8U, 4)

	buf.SetData(unsafe.Pointer(&img.Pix[0]), CV_AUTOSTEP)
	CvtColor(buf, dst, CV_RGBA2BGRA)
	buf.Release()

	return dst
}

/* ToImage converts a opencv.IplImage to an go image.Image */
func (img *IplImage) ToImage() image.Image {
	out := image.NewNRGBA(image.Rect(0, 0, img.Width(), img.Height()))
	if img.Depth() != IPL_DEPTH_8U {
		return nil // TODO return error
	}

	for y := 0; y < img.Height(); y++ {
		for x := 0; x < img.Width(); x++ {
			s := img.Get2D(x, y).Val()

			b, g, r := s[0], s[1], s[2]

			c := color.NRGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: uint8(255)}
			out.Set(x, y, c)
		}
	}

	return out
}
<|endoftext|>


<commit_before>package webui

import (
	"encoding/json"
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/gocraft/work"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
	"sync"
	"testing"
	"time"
)

func TestWebUIStartStop(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "work"
	cleanKeyspace(ns, pool)

	s := NewWebUIServer(ns, pool, ":6666")
	s.Start()
	s.Stop()
}

type TestContext struct{}

func TestWebUIJobs(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "work"
	cleanKeyspace(ns, pool)

	// Get some stuff to to show up in the jobs:
	enqueuer := work.NewEnqueuer(ns, pool)
	err := enqueuer.Enqueue("wat", 1, 2)
	assert.NoError(t, err)
	enqueuer.Enqueue("foo", 3, 4)
	enqueuer.Enqueue("zaz", 3, 4)

	// Start a pool to work on it. It's going to work on the queues
	// side effect of that is knowing which jobs are avail
	wp := work.NewWorkerPool(TestContext{}, 10, ns, pool)
	wp.Job("wat", func(job *work.Job) error {
		return nil
	})
	wp.Job("foo", func(job *work.Job) error {
		return nil
	})
	wp.Job("zaz", func(job *work.Job) error {
		return nil
	})
	wp.Start()
	time.Sleep(20 * time.Millisecond)
	wp.Stop()

	// Now that we have the jobs, populate some queues
	enqueuer.Enqueue("wat", 1, 2)
	enqueuer.Enqueue("wat", 1, 2)
	enqueuer.Enqueue("wat", 1, 2)
	enqueuer.Enqueue("foo", 3, 4)
	enqueuer.Enqueue("foo", 3, 4)
	enqueuer.Enqueue("zaz", 3, 4)

	s := NewWebUIServer(ns, pool, ":6666")

	recorder := httptest.NewRecorder()
	request, _ := http.NewRequest("GET", "/queues", nil)
	s.ServeHTTP(recorder, request)
	assert.Equal(t, 200, recorder.Code)

	var res []interface{}
	err = json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)

	assert.Equal(t, 3, len(res))

	foomap, ok := res[0].(map[string]interface{})
	assert.True(t, ok)
	assert.Equal(t, "foo", foomap["JobName"])
	assert.Equal(t, 2, foomap["Count"])
	assert.Equal(t, 0, foomap["Latency"])
}

func TestWebUIWorkerPools(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "work"
	cleanKeyspace(ns, pool)

	wp := work.NewWorkerPool(TestContext{}, 10, ns, pool)
	wp.Job("wat", func(job *work.Job) error { return nil })
	wp.Job("bob", func(job *work.Job) error { return nil })
	wp.Start()
	defer wp.Stop()

	wp2 := work.NewWorkerPool(TestContext{}, 11, ns, pool)
	wp2.Job("foo", func(job *work.Job) error { return nil })
	wp2.Job("bar", func(job *work.Job) error { return nil })
	wp2.Start()
	defer wp2.Stop()

	time.Sleep(20 * time.Millisecond)

	s := NewWebUIServer(ns, pool, ":6666")

	recorder := httptest.NewRecorder()
	request, _ := http.NewRequest("GET", "/worker_pools", nil)
	s.ServeHTTP(recorder, request)
	assert.Equal(t, 200, recorder.Code)

	var res []interface{}
	err := json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)

	assert.Equal(t, 2, len(res))

	w1stat, ok := res[0].(map[string]interface{})
	assert.True(t, ok)
	assert.True(t, w1stat["WorkerPoolID"] != "")
	// NOTE: WorkerPoolStatus is tested elsewhere.
}

func TestWebUIBusyWorkers(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "work"
	cleanKeyspace(ns, pool)

	// Keep a job in the in-progress state without using sleeps
	wgroup := sync.WaitGroup{}
	wgroup2 := sync.WaitGroup{}
	wgroup2.Add(1)

	wp := work.NewWorkerPool(TestContext{}, 10, ns, pool)
	wp.Job("wat", func(job *work.Job) error {
		wgroup2.Done()
		wgroup.Wait()
		return nil
	})
	wp.Start()
	defer wp.Stop()

	wp2 := work.NewWorkerPool(TestContext{}, 11, ns, pool)
	wp2.Start()
	defer wp2.Stop()

	time.Sleep(10 * time.Millisecond)

	s := NewWebUIServer(ns, pool, ":6666")

	recorder := httptest.NewRecorder()
	request, _ := http.NewRequest("GET", "/busy_workers", nil)
	s.ServeHTTP(recorder, request)
	assert.Equal(t, 200, recorder.Code)

	var res []interface{}
	err := json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)
	assert.Equal(t, 0, len(res))

	wgroup.Add(1)

	// Ok, now let's make a busy worker
	enqueuer := work.NewEnqueuer(ns, pool)
	enqueuer.Enqueue("wat", 1, 2)
	wgroup2.Wait()
	time.Sleep(5 * time.Millisecond) // need to let obsever process

	recorder = httptest.NewRecorder()
	request, _ = http.NewRequest("GET", "/busy_workers", nil)
	s.ServeHTTP(recorder, request)
	wgroup.Done()
	assert.Equal(t, 200, recorder.Code)
	err = json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)
	assert.Equal(t, 1, len(res))

	if len(res) == 1 {
		hash, ok := res[0].(map[string]interface{})
		assert.True(t, ok)
		assert.Equal(t, "wat", hash["JobName"])
		assert.Equal(t, true, hash["IsBusy"])
	}
}

func TestWebUIRetryQueue(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "work"
	cleanKeyspace(ns, pool)

	enqueuer := work.NewEnqueuer(ns, pool)
	err := enqueuer.Enqueue("wat", 1, 2)
	assert.Nil(t, err)

	wp := work.NewWorkerPool(TestContext{}, 2, ns, pool)
	wp.Job("wat", func(job *work.Job) error {
		return fmt.Errorf("ohno")
	})
	wp.Start()
	wp.Join()
	wp.Stop()

	s := NewWebUIServer(ns, pool, ":6666")

	recorder := httptest.NewRecorder()
	request, _ := http.NewRequest("GET", "/retry_jobs", nil)
	s.ServeHTTP(recorder, request)
	assert.Equal(t, 200, recorder.Code)
	var res struct {
		Count int64
		Jobs  []struct {
			RetryAt int64
			Name    string `json:"name"`
			Fails   int64  `json:"fails"`
		}
	}
	err = json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)

	assert.Equal(t, 1, res.Count)
	assert.Equal(t, 1, len(res.Jobs))
	if len(res.Jobs) == 1 {
		assert.True(t, res.Jobs[0].RetryAt > 0)
		assert.Equal(t, "wat", res.Jobs[0].Name)
		assert.Equal(t, 1, res.Jobs[0].Fails)
	}

}

func newTestPool(addr string) *redis.Pool {
	return &redis.Pool{
		MaxActive:   3,
		MaxIdle:     3,
		IdleTimeout: 240 * time.Second,
		Dial: func() (redis.Conn, error) {
			return redis.Dial("tcp", addr)
		},
		Wait: true,
	}
}

func cleanKeyspace(namespace string, pool *redis.Pool) {
	conn := pool.Get()
	defer conn.Close()

	keys, err := redis.Strings(conn.Do("KEYS", namespace+"*"))
	if err != nil {
		panic("could not get keys: " + err.Error())
	}
	for _, k := range keys {
		if _, err := conn.Do("DEL", k); err != nil {
			panic("could not del: " + err.Error())
		}
	}
}
<commit_msg>tests for scheduled/dead<commit_after>package webui

import (
	"encoding/json"
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/gocraft/work"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
	"sync"
	"testing"
	"time"
)

func TestWebUIStartStop(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "work"
	cleanKeyspace(ns, pool)

	s := NewWebUIServer(ns, pool, ":6666")
	s.Start()
	s.Stop()
}

type TestContext struct{}

func TestWebUIJobs(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "work"
	cleanKeyspace(ns, pool)

	// Get some stuff to to show up in the jobs:
	enqueuer := work.NewEnqueuer(ns, pool)
	err := enqueuer.Enqueue("wat", 1, 2)
	assert.NoError(t, err)
	enqueuer.Enqueue("foo", 3, 4)
	enqueuer.Enqueue("zaz", 3, 4)

	// Start a pool to work on it. It's going to work on the queues
	// side effect of that is knowing which jobs are avail
	wp := work.NewWorkerPool(TestContext{}, 10, ns, pool)
	wp.Job("wat", func(job *work.Job) error {
		return nil
	})
	wp.Job("foo", func(job *work.Job) error {
		return nil
	})
	wp.Job("zaz", func(job *work.Job) error {
		return nil
	})
	wp.Start()
	time.Sleep(20 * time.Millisecond)
	wp.Stop()

	// Now that we have the jobs, populate some queues
	enqueuer.Enqueue("wat", 1, 2)
	enqueuer.Enqueue("wat", 1, 2)
	enqueuer.Enqueue("wat", 1, 2)
	enqueuer.Enqueue("foo", 3, 4)
	enqueuer.Enqueue("foo", 3, 4)
	enqueuer.Enqueue("zaz", 3, 4)

	s := NewWebUIServer(ns, pool, ":6666")

	recorder := httptest.NewRecorder()
	request, _ := http.NewRequest("GET", "/queues", nil)
	s.ServeHTTP(recorder, request)
	assert.Equal(t, 200, recorder.Code)

	var res []interface{}
	err = json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)

	assert.Equal(t, 3, len(res))

	foomap, ok := res[0].(map[string]interface{})
	assert.True(t, ok)
	assert.Equal(t, "foo", foomap["JobName"])
	assert.Equal(t, 2, foomap["Count"])
	assert.Equal(t, 0, foomap["Latency"])
}

func TestWebUIWorkerPools(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "work"
	cleanKeyspace(ns, pool)

	wp := work.NewWorkerPool(TestContext{}, 10, ns, pool)
	wp.Job("wat", func(job *work.Job) error { return nil })
	wp.Job("bob", func(job *work.Job) error { return nil })
	wp.Start()
	defer wp.Stop()

	wp2 := work.NewWorkerPool(TestContext{}, 11, ns, pool)
	wp2.Job("foo", func(job *work.Job) error { return nil })
	wp2.Job("bar", func(job *work.Job) error { return nil })
	wp2.Start()
	defer wp2.Stop()

	time.Sleep(20 * time.Millisecond)

	s := NewWebUIServer(ns, pool, ":6666")

	recorder := httptest.NewRecorder()
	request, _ := http.NewRequest("GET", "/worker_pools", nil)
	s.ServeHTTP(recorder, request)
	assert.Equal(t, 200, recorder.Code)

	var res []interface{}
	err := json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)

	assert.Equal(t, 2, len(res))

	w1stat, ok := res[0].(map[string]interface{})
	assert.True(t, ok)
	assert.True(t, w1stat["WorkerPoolID"] != "")
	// NOTE: WorkerPoolStatus is tested elsewhere.
}

func TestWebUIBusyWorkers(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "work"
	cleanKeyspace(ns, pool)

	// Keep a job in the in-progress state without using sleeps
	wgroup := sync.WaitGroup{}
	wgroup2 := sync.WaitGroup{}
	wgroup2.Add(1)

	wp := work.NewWorkerPool(TestContext{}, 10, ns, pool)
	wp.Job("wat", func(job *work.Job) error {
		wgroup2.Done()
		wgroup.Wait()
		return nil
	})
	wp.Start()
	defer wp.Stop()

	wp2 := work.NewWorkerPool(TestContext{}, 11, ns, pool)
	wp2.Start()
	defer wp2.Stop()

	time.Sleep(10 * time.Millisecond)

	s := NewWebUIServer(ns, pool, ":6666")

	recorder := httptest.NewRecorder()
	request, _ := http.NewRequest("GET", "/busy_workers", nil)
	s.ServeHTTP(recorder, request)
	assert.Equal(t, 200, recorder.Code)

	var res []interface{}
	err := json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)
	assert.Equal(t, 0, len(res))

	wgroup.Add(1)

	// Ok, now let's make a busy worker
	enqueuer := work.NewEnqueuer(ns, pool)
	enqueuer.Enqueue("wat", 1, 2)
	wgroup2.Wait()
	time.Sleep(5 * time.Millisecond) // need to let obsever process

	recorder = httptest.NewRecorder()
	request, _ = http.NewRequest("GET", "/busy_workers", nil)
	s.ServeHTTP(recorder, request)
	wgroup.Done()
	assert.Equal(t, 200, recorder.Code)
	err = json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)
	assert.Equal(t, 1, len(res))

	if len(res) == 1 {
		hash, ok := res[0].(map[string]interface{})
		assert.True(t, ok)
		assert.Equal(t, "wat", hash["JobName"])
		assert.Equal(t, true, hash["IsBusy"])
	}
}

func TestWebUIRetryJobs(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "work"
	cleanKeyspace(ns, pool)

	enqueuer := work.NewEnqueuer(ns, pool)
	err := enqueuer.Enqueue("wat", 1, 2)
	assert.Nil(t, err)

	wp := work.NewWorkerPool(TestContext{}, 2, ns, pool)
	wp.Job("wat", func(job *work.Job) error {
		return fmt.Errorf("ohno")
	})
	wp.Start()
	wp.Join()
	wp.Stop()

	s := NewWebUIServer(ns, pool, ":6666")

	recorder := httptest.NewRecorder()
	request, _ := http.NewRequest("GET", "/retry_jobs", nil)
	s.ServeHTTP(recorder, request)
	assert.Equal(t, 200, recorder.Code)
	var res struct {
		Count int64
		Jobs  []struct {
			RetryAt int64
			Name    string `json:"name"`
			Fails   int64  `json:"fails"`
		}
	}
	err = json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)

	assert.Equal(t, 1, res.Count)
	assert.Equal(t, 1, len(res.Jobs))
	if len(res.Jobs) == 1 {
		assert.True(t, res.Jobs[0].RetryAt > 0)
		assert.Equal(t, "wat", res.Jobs[0].Name)
		assert.Equal(t, 1, res.Jobs[0].Fails)
	}
}

func TestWebUIScheduledJobs(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "testwork"
	cleanKeyspace(ns, pool)

	enqueuer := work.NewEnqueuer(ns, pool)
	err := enqueuer.EnqueueIn("watter", 1, 1, 2)
	assert.Nil(t, err)

	s := NewWebUIServer(ns, pool, ":6666")

	recorder := httptest.NewRecorder()
	request, _ := http.NewRequest("GET", "/scheduled_jobs", nil)
	s.ServeHTTP(recorder, request)
	assert.Equal(t, 200, recorder.Code)
	var res struct {
		Count int64
		Jobs  []struct {
			RunAt int64
			Name  string `json:"name"`
		}
	}
	err = json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)

	assert.Equal(t, 1, res.Count)
	assert.Equal(t, 1, len(res.Jobs))
	if len(res.Jobs) == 1 {
		assert.True(t, res.Jobs[0].RunAt > 0)
		assert.Equal(t, "watter", res.Jobs[0].Name)
	}
}

func TestWebUIDeadJobs(t *testing.T) {
	pool := newTestPool(":6379")
	ns := "testwork"
	cleanKeyspace(ns, pool)

	enqueuer := work.NewEnqueuer(ns, pool)
	err := enqueuer.Enqueue("wat", 1, 2)
	assert.Nil(t, err)

	wp := work.NewWorkerPool(TestContext{}, 2, ns, pool)
	wp.JobWithOptions("wat", work.JobOptions{Priority: 1, MaxFails: 0}, func(job *work.Job) error {
		return fmt.Errorf("ohno")
	})
	wp.Start()
	wp.Join()
	wp.Stop()

	s := NewWebUIServer(ns, pool, ":6666")

	recorder := httptest.NewRecorder()
	request, _ := http.NewRequest("GET", "/dead_jobs", nil)
	s.ServeHTTP(recorder, request)
	assert.Equal(t, 200, recorder.Code)
	var res struct {
		Count int64
		Jobs  []struct {
			DiedAt int64
			Name   string `json:"name"`
			Fails  int64  `json:"fails"`
		}
	}
	err = json.Unmarshal(recorder.Body.Bytes(), &res)
	assert.NoError(t, err)

	assert.Equal(t, 1, res.Count)
	assert.Equal(t, 1, len(res.Jobs))
	if len(res.Jobs) == 1 {
		assert.True(t, res.Jobs[0].DiedAt > 0)
		assert.Equal(t, "wat", res.Jobs[0].Name)
		assert.Equal(t, 1, res.Jobs[0].Fails)
	}
}

func newTestPool(addr string) *redis.Pool {
	return &redis.Pool{
		MaxActive:   3,
		MaxIdle:     3,
		IdleTimeout: 240 * time.Second,
		Dial: func() (redis.Conn, error) {
			return redis.Dial("tcp", addr)
		},
		Wait: true,
	}
}

func cleanKeyspace(namespace string, pool *redis.Pool) {
	conn := pool.Get()
	defer conn.Close()

	keys, err := redis.Strings(conn.Do("KEYS", namespace+"*"))
	if err != nil {
		panic("could not get keys: " + err.Error())
	}
	for _, k := range keys {
		if _, err := conn.Do("DEL", k); err != nil {
			panic("could not del: " + err.Error())
		}
	}
}
<|endoftext|>