<commit_before>package main

import "io"
import "os"
import "fmt"
import "sync"
import "time"
import "bytes"
import "strconv"
import "sync/atomic"
import "path/filepath"
import "math/rand"

import "github.com/bnclabs/gostore/api"
import "github.com/bnclabs/gostore/bubt"
import "github.com/bnclabs/gostore/llrb"

func testbubt() error {
	setts := llrb.Defaultsettings()
	mindex := llrb.NewLLRB("dbtest", setts)
	defer mindex.Destroy()

	paths := bubtpaths(options.npaths)

	name := "dbtest"
	rnd := rand.New(rand.NewSource(int64(options.seed)))
	msizes := []int64{4096, 8192, 12288}
	msize := msizes[rnd.Intn(10000)%len(msizes)]
	zsizes := []int64{0, 0, msize, msize * 2, msize * 4}
	zsize := zsizes[rnd.Intn(10000)%len(zsizes)]
	vsizes := []int64{0, 0, zsize, zsize * 2, zsize * 4}
	vsize := vsizes[rnd.Intn(10000)%len(vsizes)]
	mmap := []bool{true, false}[rnd.Intn(10000)%2]
	bt, err := bubt.NewBubt(name, paths, msize, zsize, vsize)
	if err != nil {
		panic(err)
	}

	klen, vlen := int64(options.keylen), int64(options.vallen)
	seed := int64(options.seed)
	iter := makeiterator(klen, vlen, int64(options.load), delmod, mindex)
	md := generatemeta(seed)

	fmsg := "msize: %v zsize:%v vsize: %v mmap:%v mdsize:%v\n"
	fmt.Printf(fmsg, msize, zsize, vsize, mmap, len(md))

	now := time.Now()
	bt.Build(iter, md)
	took := time.Since(now).Round(time.Second)
	fmt.Printf("Took %v to build %v entries\n", took, options.load)
	bt.Close()

	index, err := bubt.OpenSnapshot(name, paths, mmap)
	if err != nil {
		panic(err)
	}
	defer index.Destroy()
	defer index.Close()

	index.Validate()
	index.Log()

	if index.Count() != int64(options.load) {
		panic(fmt.Errorf("expected %v, got %v", options.load, index.Count()))
	} else if index.ID() != name {
		panic(fmt.Errorf("expected %v, got %v", name, index.ID()))
	}

	fin := make(chan struct{})

	var vwg sync.WaitGroup

	vwg.Add(1)
	go bubtvalidator(mindex, index, &vwg, fin)

	var rwg sync.WaitGroup

	for i := 0; i < options.cpu; i++ {
		go bubtGetter(index, int64(options.load), seed, &rwg)
		go bubtRanger(index, int64(options.load), seed, &rwg)
		rwg.Add(2)
	}
	rwg.Wait()
	close(fin)
	vwg.Wait()

	fmt.Printf("BUBT total indexed %v items\n", index.Count())

	return nil
}

func bubtvalidator(
	mindex *llrb.LLRB, index *bubt.Snapshot,
	wg *sync.WaitGroup, fin chan struct{}) {

	defer wg.Done()

	n := uint64(0)
	validate := func() {
		n++
		now := time.Now()

		mview, view := mindex.View(n), index.View(n)

		mcur, err := mview.OpenCursor(nil)
		if err != nil {
			panic(err)
		}
		cur, err := view.OpenCursor(nil)
		if err != nil {
			panic(err)
		}

		count := 0
		mkey, mvalue, _, mdel, merr := mcur.YNext(false /*fin*/)
		key, value, _, del, err := cur.YNext(false /*fin*/)
		for mkey != nil && key != nil {
			if err == io.EOF && merr == io.EOF {
				break
			} else if err != nil {
				panic(err)
			} else if merr != nil {
				panic(merr)
			} else if bytes.Compare(mkey, key) != 0 {
				panic(fmt.Errorf("%s != %s", mkey, key))
			} else if del != mdel {
				panic(fmt.Errorf("for %s : %v != %v", key, mdel, del))
			} else if del == false && bytes.Compare(mvalue, value) != 0 {
				panic(fmt.Errorf("for %s : %s != %s", key, mvalue, value))
			}
			mkey, mvalue, _, mdel, merr = mcur.YNext(false /*fin*/)
			key, value, _, del, err = cur.YNext(false /*fin*/)
			count++
		}

		if mkey != nil {
			panic(fmt.Errorf("mindex key remaining %s", mkey))
		} else if key != nil {
			panic(fmt.Errorf("index key remaining %s", key))
		}

		mview.Abort()
		view.Abort()

		took := time.Since(now).Round(time.Second)
		fmt.Printf("Took %v to validate index\n", took)
	}

	tick := time.NewTicker(10 * time.Second)
	for {
		<-tick.C
		select {
		case <-fin:
			validate()
			return
		default:
		}
		validate()
	}
}

var bubtgets = []func(x *bubt.Snapshot, k, v []byte) ([]byte, uint64, bool, bool){
	bubtGet1, bubtGet2,
}

func bubtGetter(index *bubt.Snapshot, n, seed int64, wg *sync.WaitGroup) {
	defer wg.Done()

	var ngets, nmisses int64
	var key []byte
	var del bool
	g := Generatereadseq(int64(options.keylen), n, seed)

	rnd := rand.New(rand.NewSource(seed))
	epoch, now, markercount := time.Now(), time.Now(), int64(10000000)
	value := make([]byte, 16)
loop:
	for {
		ngets++
		key = g(key, 0)
		ln := len(bubtgets)
		value, _, del, _ = bubtgets[rnd.Intn(1000000)%ln](index, key, value)
		//fmt.Printf("bubtGetter %q %q %v\n", key, value, del)
		if x, xerr := strconv.Atoi(Bytes2str(key)); xerr != nil {
			panic(xerr)
		} else if (int64(x) % 2) != delmod {
			if del {
				panic(fmt.Errorf("unexpected deleted"))
			}
			comparekeyvalue(key, value, options.vallen)
		} else {
			nmisses++
		}

		if ngm := (ngets + nmisses); ngm%markercount == 0 {
			x := time.Since(now).Round(time.Second)
			y := time.Since(epoch).Round(time.Second)
			fmsg := "bubtGetter {%v items in %v} {%v:%v items in %v}\n"
			fmt.Printf(fmsg, markercount, x, ngets, nmisses, y)
		}

		if atomic.AddInt64(&totalreads, 1) > int64(options.reads) {
			break loop
		}
	}
	took := time.Since(epoch).Round(time.Second)
	fmsg := "at exit, bubtGetter %v:%v items in %v\n"
	fmt.Printf(fmsg, ngets, nmisses, took)
}

func bubtGet1(
	index *bubt.Snapshot, key, value []byte) ([]byte, uint64, bool, bool) {

	return index.Get(key, value)
}

func bubtGet2(
	index *bubt.Snapshot, key, value []byte) ([]byte, uint64, bool, bool) {

	view := index.View(0x1235)
	value, _, del, ok := view.Get(key, value)
	if ok == true {
		cur, err := view.OpenCursor(key)
		if err != nil {
			panic(err)
		}
		if ckey, cdel := cur.Key(); cdel != del {
			panic(fmt.Errorf("expected %v, got %v", del, cdel))
		} else if bytes.Compare(ckey, key) != 0 {
			panic(fmt.Errorf("expected %q, got %q", key, ckey))
		} else if cv := cur.Value(); del == false && bytes.Compare(cv, value) != 0 {
			panic(fmt.Errorf("%q expected %q, got %q", key, value, cv))
		}
	}
	view.Abort()
	return value, 0, del, ok
}

var bubtrngs = []func(index *bubt.Snapshot, key, val []byte) int64{
	bubtRange1, bubtRange2,
}

func bubtRanger(index *bubt.Snapshot, n, seed int64, wg *sync.WaitGroup) {
	defer wg.Done()

	var nranges int64
	var key []byte
	g := Generatereadseq(int64(options.keylen), n, seed)

	rnd := rand.New(rand.NewSource(seed))
	epoch, value := time.Now(), make([]byte, 16)
loop:
	for {
		key = g(key, 0)
		ln := len(bubtrngs)
		n := bubtrngs[rnd.Intn(1000000)%ln](index, key, value)
		nranges += n

		if atomic.AddInt64(&totalreads, 1) > int64(options.reads) {
			break loop
		}
	}
	took := time.Since(epoch).Round(time.Second)
	fmt.Printf("at exit, bubtRanger %v items in %v\n", nranges, took)
}

func bubtRange1(index *bubt.Snapshot, key, value []byte) (n int64) {
	//fmt.Printf("bubtRange1 %q\n", key)
	view := index.View(0x1236)
	cur, err := view.OpenCursor(key)
	if err != nil {
		panic(err)
	}
	for i := 0; i < 100; i++ {
		key, value, del, err := cur.GetNext()
		if err == io.EOF {
			continue
		} else if err != nil {
			panic(err)
		}
		if x, xerr := strconv.Atoi(Bytes2str(key)); xerr != nil {
			panic(xerr)
		} else if (int64(x)%2) != delmod && del == true {
			panic("unexpected delete")
		} else if del == false {
			comparekeyvalue(key, value, options.vallen)
		}
		n++
	}
	view.Abort()
	return
}

func bubtRange2(index *bubt.Snapshot, key, value []byte) (n int64) {
	//fmt.Printf("bubtRange2 %q\n", key)
	view := index.View(0x1237)
	cur, err := view.OpenCursor(key)
	if err != nil {
		panic(err)
	}
	for i := 0; i < 100; i++ {
		key, value, _, del, err := cur.YNext(false /*fin*/)
		if err == io.EOF {
			continue
		} else if err != nil {
			panic(err)
		}
		if x, xerr := strconv.Atoi(Bytes2str(key)); xerr != nil {
			panic(xerr)
		} else if (int64(x)%2) != delmod && del == true {
			panic("unexpected delete")
		} else if del == false {
			comparekeyvalue(key, value, options.vallen)
		}
		n++
	}
	view.Abort()
	return
}

func makeiterator(
	klen, vlen, entries, mod int64, mindex *llrb.LLRB) api.Iterator {

	g := Generateloads(klen, vlen, entries)
	key, value := make([]byte, 16), make([]byte, 16)

	return func(fin bool) ([]byte, []byte, uint64, bool, error) {
		opaque := atomic.AddUint64(&seqno, 1)
		key, value = g(key, value, opaque)
		if key != nil {
			x, _ := strconv.Atoi(Bytes2str(key))
			deleted := false
			mindex.Set(key, value, nil)
			if (int64(x) % 2) == mod {
				deleted = true
				mindex.Delete(key, nil, true /*lsm*/)
			}
			//fmt.Printf("iterate %q %q %v %v\n", key, value, opaque, deleted)
			return key, value, opaque, deleted, nil
		}
		return nil, nil, 0, false, io.EOF
	}
}

func generatemeta(seed int64) []byte {
	rnd := rand.New(rand.NewSource(seed))
	md := make([]byte, rnd.Intn(20000))
	for i := range md {
		md[i] = byte(97 + rnd.Intn(26))
	}
	return md
}

func bubtpaths(npaths int) []string {
	path, paths := os.TempDir(), []string{}
	if npaths == 0 {
		npaths = (rand.Intn(10000) % 3) + 1
	}
	for i := 0; i < npaths; i++ {
		base := fmt.Sprintf("%v", i+1)
		paths = append(paths, filepath.Join(path, base))
		fmt.Printf("Path %v %q\n", i+1, filepath.Join(path, base))
	}
	return paths
}
<commit_msg>bubt module, cleanup disk files before starting.<commit_after>package main

import "io"
import "os"
import "fmt"
import "sync"
import "time"
import "bytes"
import "strconv"
import "sync/atomic"
import "path/filepath"
import "math/rand"

import "github.com/bnclabs/gostore/api"
import "github.com/bnclabs/gostore/bubt"
import "github.com/bnclabs/gostore/llrb"

func testbubt() error {
	setts := llrb.Defaultsettings()
	mindex := llrb.NewLLRB("dbtest", setts)
	defer mindex.Destroy()

	paths := bubtpaths(options.npaths)

	name := "dbtest"
	rnd := rand.New(rand.NewSource(int64(options.seed)))
	msizes := []int64{4096, 8192, 12288}
	msize := msizes[rnd.Intn(10000)%len(msizes)]
	zsizes := []int64{0, 0, msize, msize * 2, msize * 4}
	zsize := zsizes[rnd.Intn(10000)%len(zsizes)]
	vsizes := []int64{0, 0, zsize, zsize * 2, zsize * 4}
	vsize := vsizes[rnd.Intn(10000)%len(vsizes)]
	mmap := []bool{true, false}[rnd.Intn(10000)%2]
	bt, err := bubt.NewBubt(name, paths, msize, zsize, vsize)
	if err != nil {
		panic(err)
	}

	klen, vlen := int64(options.keylen), int64(options.vallen)
	seed := int64(options.seed)
	iter := makeiterator(klen, vlen, int64(options.load), delmod, mindex)
	md := generatemeta(seed)

	fmsg := "msize: %v zsize:%v vsize: %v mmap:%v mdsize:%v\n"
	fmt.Printf(fmsg, msize, zsize, vsize, mmap, len(md))

	now := time.Now()
	bt.Build(iter, md)
	took := time.Since(now).Round(time.Second)
	fmt.Printf("Took %v to build %v entries\n", took, options.load)
	bt.Close()

	index, err := bubt.OpenSnapshot(name, paths, mmap)
	if err != nil {
		panic(err)
	}
	defer index.Destroy()
	defer index.Close()

	index.Validate()
	index.Log()

	if index.Count() != int64(options.load) {
		panic(fmt.Errorf("expected %v, got %v", options.load, index.Count()))
	} else if index.ID() != name {
		panic(fmt.Errorf("expected %v, got %v", name, index.ID()))
	}

	fin := make(chan struct{})

	var vwg sync.WaitGroup

	vwg.Add(1)
	go bubtvalidator(mindex, index, &vwg, fin)

	var rwg sync.WaitGroup

	for i := 0; i < options.cpu; i++ {
		go bubtGetter(index, int64(options.load), seed, &rwg)
		go bubtRanger(index, int64(options.load), seed, &rwg)
		rwg.Add(2)
	}
	rwg.Wait()
	close(fin)
	vwg.Wait()

	fmt.Printf("BUBT total indexed %v items\n", index.Count())

	return nil
}

func bubtvalidator(
	mindex *llrb.LLRB, index *bubt.Snapshot,
	wg *sync.WaitGroup, fin chan struct{}) {

	defer wg.Done()

	n := uint64(0)
	validate := func() {
		n++
		now := time.Now()

		mview, view := mindex.View(n), index.View(n)

		mcur, err := mview.OpenCursor(nil)
		if err != nil {
			panic(err)
		}
		cur, err := view.OpenCursor(nil)
		if err != nil {
			panic(err)
		}

		count := 0
		mkey, mvalue, _, mdel, merr := mcur.YNext(false /*fin*/)
		key, value, _, del, err := cur.YNext(false /*fin*/)
		for mkey != nil && key != nil {
			if err == io.EOF && merr == io.EOF {
				break
			} else if err != nil {
				panic(err)
			} else if merr != nil {
				panic(merr)
			} else if bytes.Compare(mkey, key) != 0 {
				panic(fmt.Errorf("%s != %s", mkey, key))
			} else if del != mdel {
				panic(fmt.Errorf("for %s : %v != %v", key, mdel, del))
			} else if del == false && bytes.Compare(mvalue, value) != 0 {
				panic(fmt.Errorf("for %s : %s != %s", key, mvalue, value))
			}
			mkey, mvalue, _, mdel, merr = mcur.YNext(false /*fin*/)
			key, value, _, del, err = cur.YNext(false /*fin*/)
			count++
		}

		if mkey != nil {
			panic(fmt.Errorf("mindex key remaining %s", mkey))
		} else if key != nil {
			panic(fmt.Errorf("index key remaining %s", key))
		}

		mview.Abort()
		view.Abort()

		took := time.Since(now).Round(time.Second)
		fmt.Printf("Took %v to validate index\n", took)
	}

	tick := time.NewTicker(10 * time.Second)
	for {
		<-tick.C
		select {
		case <-fin:
			validate()
			return
		default:
		}
		validate()
	}
}

var bubtgets = []func(x *bubt.Snapshot, k, v []byte) ([]byte, uint64, bool, bool){
	bubtGet1, bubtGet2,
}

func bubtGetter(index *bubt.Snapshot, n, seed int64, wg *sync.WaitGroup) {
	defer wg.Done()

	var ngets, nmisses int64
	var key []byte
	var del bool
	g := Generatereadseq(int64(options.keylen), n, seed)

	rnd := rand.New(rand.NewSource(seed))
	epoch, now, markercount := time.Now(), time.Now(), int64(10000000)
	value := make([]byte, 16)
loop:
	for {
		ngets++
		key = g(key, 0)
		ln := len(bubtgets)
		value, _, del, _ = bubtgets[rnd.Intn(1000000)%ln](index, key, value)
		//fmt.Printf("bubtGetter %q %q %v\n", key, value, del)
		if x, xerr := strconv.Atoi(Bytes2str(key)); xerr != nil {
			panic(xerr)
		} else if (int64(x) % 2) != delmod {
			if del {
				panic(fmt.Errorf("unexpected deleted"))
			}
			comparekeyvalue(key, value, options.vallen)
		} else {
			nmisses++
		}

		if ngm := (ngets + nmisses); ngm%markercount == 0 {
			x := time.Since(now).Round(time.Second)
			y := time.Since(epoch).Round(time.Second)
			fmsg := "bubtGetter {%v items in %v} {%v:%v items in %v}\n"
			fmt.Printf(fmsg, markercount, x, ngets, nmisses, y)
		}

		if atomic.AddInt64(&totalreads, 1) > int64(options.reads) {
			break loop
		}
	}
	took := time.Since(epoch).Round(time.Second)
	fmsg := "at exit, bubtGetter %v:%v items in %v\n"
	fmt.Printf(fmsg, ngets, nmisses, took)
}

func bubtGet1(
	index *bubt.Snapshot, key, value []byte) ([]byte, uint64, bool, bool) {

	return index.Get(key, value)
}

func bubtGet2(
	index *bubt.Snapshot, key, value []byte) ([]byte, uint64, bool, bool) {

	view := index.View(0x1235)
	value, _, del, ok := view.Get(key, value)
	if ok == true {
		cur, err := view.OpenCursor(key)
		if err != nil {
			panic(err)
		}
		if ckey, cdel := cur.Key(); cdel != del {
			panic(fmt.Errorf("expected %v, got %v", del, cdel))
		} else if bytes.Compare(ckey, key) != 0 {
			panic(fmt.Errorf("expected %q, got %q", key, ckey))
		} else if cv := cur.Value(); del == false && bytes.Compare(cv, value) != 0 {
			panic(fmt.Errorf("%q expected %q, got %q", key, value, cv))
		}
	}
	view.Abort()
	return value, 0, del, ok
}

var bubtrngs = []func(index *bubt.Snapshot, key, val []byte) int64{
	bubtRange1, bubtRange2,
}

func bubtRanger(index *bubt.Snapshot, n, seed int64, wg *sync.WaitGroup) {
	defer wg.Done()

	var nranges int64
	var key []byte
	g := Generatereadseq(int64(options.keylen), n, seed)

	rnd := rand.New(rand.NewSource(seed))
	epoch, value := time.Now(), make([]byte, 16)
loop:
	for {
		key = g(key, 0)
		ln := len(bubtrngs)
		n := bubtrngs[rnd.Intn(1000000)%ln](index, key, value)
		nranges += n

		if atomic.AddInt64(&totalreads, 1) > int64(options.reads) {
			break loop
		}
	}
	took := time.Since(epoch).Round(time.Second)
	fmt.Printf("at exit, bubtRanger %v items in %v\n", nranges, took)
}

func bubtRange1(index *bubt.Snapshot, key, value []byte) (n int64) {
	//fmt.Printf("bubtRange1 %q\n", key)
	view := index.View(0x1236)
	cur, err := view.OpenCursor(key)
	if err != nil {
		panic(err)
	}
	for i := 0; i < 100; i++ {
		key, value, del, err := cur.GetNext()
		if err == io.EOF {
			continue
		} else if err != nil {
			panic(err)
		}
		if x, xerr := strconv.Atoi(Bytes2str(key)); xerr != nil {
			panic(xerr)
		} else if (int64(x)%2) != delmod && del == true {
			panic("unexpected delete")
		} else if del == false {
			comparekeyvalue(key, value, options.vallen)
		}
		n++
	}
	view.Abort()
	return
}

func bubtRange2(index *bubt.Snapshot, key, value []byte) (n int64) {
	//fmt.Printf("bubtRange2 %q\n", key)
	view := index.View(0x1237)
	cur, err := view.OpenCursor(key)
	if err != nil {
		panic(err)
	}
	for i := 0; i < 100; i++ {
		key, value, _, del, err := cur.YNext(false /*fin*/)
		if err == io.EOF {
			continue
		} else if err != nil {
			panic(err)
		}
		if x, xerr := strconv.Atoi(Bytes2str(key)); xerr != nil {
			panic(xerr)
		} else if (int64(x)%2) != delmod && del == true {
			panic("unexpected delete")
		} else if del == false {
			comparekeyvalue(key, value, options.vallen)
		}
		n++
	}
	view.Abort()
	return
}

func makeiterator(
	klen, vlen, entries, mod int64, mindex *llrb.LLRB) api.Iterator {

	g := Generateloads(klen, vlen, entries)
	key, value := make([]byte, 16), make([]byte, 16)

	return func(fin bool) ([]byte, []byte, uint64, bool, error) {
		opaque := atomic.AddUint64(&seqno, 1)
		key, value = g(key, value, opaque)
		if key != nil {
			x, _ := strconv.Atoi(Bytes2str(key))
			deleted := false
			mindex.Set(key, value, nil)
			if (int64(x) % 2) == mod {
				deleted = true
				mindex.Delete(key, nil, true /*lsm*/)
			}
			//fmt.Printf("iterate %q %q %v %v\n", key, value, opaque, deleted)
			return key, value, opaque, deleted, nil
		}
		return nil, nil, 0, false, io.EOF
	}
}

func generatemeta(seed int64) []byte {
	rnd := rand.New(rand.NewSource(seed))
	md := make([]byte, rnd.Intn(20000))
	for i := range md {
		md[i] = byte(97 + rnd.Intn(26))
	}
	return md
}

func bubtpaths(npaths int) []string {
	path, paths := os.TempDir(), []string{}
	if npaths == 0 {
		npaths = (rand.Intn(10000) % 3) + 1
	}
	for i := 0; i < npaths; i++ {
		base := fmt.Sprintf("%v", i+1)
		path := filepath.Join(path, base)
		paths = append(paths, path)
		fmt.Printf("Path %v %q\n", i+1, path)
		if err := os.RemoveAll(path); err != nil {
			panic(err)
		}
		if err := os.MkdirAll(path); err != nil {
			panic(err)
		}
	}
	return paths
}
<|endoftext|>


<commit_before>package model

import (
	"github.com/Sirupsen/logrus"
	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3"
)

var (
	db  gorm.DB
	log *logrus.Logger
)

func InitDB(driver, database string) {
	var err error

	db, err = gorm.Open(driver, database)
	if err != nil {
		panic(err)
	}

	// enable SQL logging
	db.LogMode(true)
	db.SetLogger(&debugLogger{})

	db.AutoMigrate(&Job{}, &LeaveAllowance{}, &LeaveRequest{}, &User{})

	db.Model(&Job{}).AddIndex("id", "id")
	db.Model(&Job{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&LeaveAllowance{}).AddIndex("start_date", "start_date")
	db.Model(&LeaveAllowance{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&LeaveRequest{}).AddIndex("start_date", "start_date")
	db.Model(&LeaveRequest{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&User{}).AddIndex("id", "id")
	db.Model(&User{}).AddIndex("email", "email")
	db.Model(&User{}).AddIndex("deleted_at", "deleted_at")
}

func SetLogger(l *logrus.Logger) {
	log = l
}

// debugLogger satisfies Gorm's logger interface
// so that we can log SQL queries at Logrus' debug level
type debugLogger struct{}

func (*debugLogger) Print(msg ...interface{}) {
	log.Debug(msg)
}
<commit_msg>Rename indicies from start_date to start_time<commit_after>package model

import (
	"github.com/Sirupsen/logrus"
	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3"
)

var (
	db  gorm.DB
	log *logrus.Logger
)

func InitDB(driver, database string) {
	var err error

	db, err = gorm.Open(driver, database)
	if err != nil {
		panic(err)
	}

	// enable SQL logging
	db.LogMode(true)
	db.SetLogger(&debugLogger{})

	db.AutoMigrate(&Job{}, &LeaveAllowance{}, &LeaveRequest{}, &User{})

	db.Model(&Job{}).AddIndex("id", "id")
	db.Model(&Job{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&LeaveAllowance{}).AddIndex("start_time", "start_time")
	db.Model(&LeaveAllowance{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&LeaveRequest{}).AddIndex("start_time", "start_time")
	db.Model(&LeaveRequest{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&User{}).AddIndex("id", "id")
	db.Model(&User{}).AddIndex("email", "email")
	db.Model(&User{}).AddIndex("deleted_at", "deleted_at")
}

func SetLogger(l *logrus.Logger) {
	log = l
}

// debugLogger satisfies Gorm's logger interface
// so that we can log SQL queries at Logrus' debug level
type debugLogger struct{}

func (*debugLogger) Print(msg ...interface{}) {
	log.Debug(msg)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"reflect"
	"sort"
	"strings"

	"github.com/codegangsta/cli"
	mkr "github.com/mackerelio/mackerel-client-go"
	"github.com/mackerelio/mkr/logger"
)

var commandMonitors = cli.Command{
	Name:  "monitors",
	Usage: "Manipurate monitors",
	Description: `
    Manipurate monitor rules.
    Request "GET /api/v0/monitors". See http://help-ja.mackerel.io/entry/spec/api/v0#monitors.
`,
	Action: doMonitorsList,
	Subcommands: []cli.Command{
		{
			Name:   "pull",
			Usage:  "pull rules",
			Action: doMonitorsPull,
		},
		{
			Name:   "diff",
			Usage:  "diff rules",
			Action: doMonitorsDiff,
		},
		{
			Name:   "push",
			Usage:  "pull rules",
			Action: doMonitorsPush,
			Flags: []cli.Flag{
				cli.BoolFlag{Name: "dryRun, d", Usage: "Dry Run."},
				cli.BoolFlag{Name: "verbose, v", Usage: "Verbose output mode"},
			},
		},
	},
}

func monitorSaveRules(rules []*(mkr.Monitor)) error {
	file, err := os.Create("monitors.json")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	monitors := map[string]interface{}{"monitors": rules}
	dataRaw, err := json.MarshalIndent(monitors, "", "    ")
	logger.DieIf(err)
	data := strings.Replace(string(dataRaw), "\\u003c", "<", -1)
	data = strings.Replace(data, "\\u003e", ">", -1)

	_, err = file.WriteString(data)
	if err != nil {
		return err
	}
	return nil
}

func monitorLoadRules() ([]*(mkr.Monitor), error) {
	buff, err := ioutil.ReadFile("monitors.json")
	if err != nil {
		return nil, err
	}

	var data struct {
		Monitors []*(mkr.Monitor) `json:"monitors"`
	}

	err = json.Unmarshal(buff, &data)
	if err != nil {
		return nil, err
	}
	return data.Monitors, nil
}

func doMonitorsList(c *cli.Context) {
	conffile := c.GlobalString("conf")

	monitors, err := newMackerel(conffile).FindMonitors()
	logger.DieIf(err)

	PrettyPrintJSON(monitors)
}

func doMonitorsPull(c *cli.Context) {
	conffile := c.GlobalString("conf")
	isVerbose := c.Bool("verbose")

	monitors, err := newMackerel(conffile).FindMonitors()
	logger.DieIf(err)

	monitorSaveRules(monitors)

	if isVerbose {
		PrettyPrintJSON(monitors)
	}
}

func appendDiff(src []string, name string, a interface{}, b interface{}) []string {
	diff := []string{}
	aType := reflect.TypeOf(a).String()
	format := "\"%s\""
	switch aType {
	case "uint64":
		format = "%d"
	case "float64":
		format = "%f"
	}
	if b != nil && a != b {
		diff = append(src, fmt.Sprintf("-  \"%s\": "+format+",", name, a))
		diff = append(diff, fmt.Sprintf("+  \"%s\": "+format+",", name, b))
	} else {
		diff = append(src, fmt.Sprintf("   \"%s\": "+format+",", name, a))
	}
	return diff
}

func printMonitor(a *mkr.Monitor, prefix string) {
	sA := reflect.ValueOf(a).Elem()
	diff := []string{" {"}
	for i := 0; i < sA.NumField(); i++ {
		fA := sA.Field(i)
		sAType := sA.Type()
		name := strings.Replace(sAType.Field(i).Tag.Get("json"), ",omitempty", "", 1)
		if sAType.Field(i).Type.String() != "[]string" {
			if name == "id" && fA.Interface() == "" {
				continue
			}
			diff = appendDiff(diff, name, fA.Interface(), nil)
		} else {
			diff = append(diff, fmt.Sprintf("   \"%s\": [", name))
			sortA := fA.Interface().([]string)
			sort.Strings(sortA)
			i := 0
			for i < len(sortA) {
				diff = append(diff, fmt.Sprintf("     \"%s\",", sortA[i]))
				i++
			}
			diff = append(diff, "   ],")
		}
	}
	diff = append(diff, " },")
	for _, d := range diff {
		fmt.Println(prefix + d)
	}
}

func diffMonitor(a *mkr.Monitor, b *mkr.Monitor) string {
	diff := []string{"  {"}
	diffNum := 0
	sA := reflect.ValueOf(a).Elem()
	sB := reflect.ValueOf(b).Elem()
	for i := 0; i < sA.NumField(); i++ {
		fA := sA.Field(i)
		fB := sB.Field(i)
		sAType := sA.Type()
		if sAType.Field(i).Type.String() != "[]string" {
			name := strings.Replace(sAType.Field(i).Tag.Get("json"), ",omitempty", "", 1)
			if name == "id" {
				continue
			}
			diff = appendDiff(diff, name, fA.Interface(), fB.Interface())
			if fA.Interface() != fB.Interface() {
				diffNum++
			}
		} else {
			name := strings.Replace(sAType.Field(i).Tag.Get("json"), ",omitempty", "", 1)
			diff = append(diff, fmt.Sprintf("    \"%s\": [", name))
			sortA := fA.Interface().([]string)
			sortB := fB.Interface().([]string)
			sort.Strings(sortA)
			sort.Strings(sortB)
			i := 0
			j := 0
			for i < len(sortA) && j < len(sortB) {
				if sortA[i] == sortB[j] {
					diff = append(diff, fmt.Sprintf("      \"%s\",", sortA[i]))
					i++
					j++
				} else if sortA[i] < sortB[j] {
					diff = append(diff, fmt.Sprintf("-     \"%s\",", sortA[i]))
					i++
					diffNum++
				} else if sortB[j] < sortA[i] {
					diff = append(diff, fmt.Sprintf("+     \"%s\",", sortB[j]))
					j++
					diffNum++
				}
			}
			diff = append(diff, "    ],")
		}
	}

	if diffNum > 0 {
		diff = append(diff, "  },")
		return strings.Join(diff, "\n")
	}
	return ""
}

func isSameMonitor(a *mkr.Monitor, b *mkr.Monitor, flagNameUniqueness bool) (string, bool) {
	if a == nil || b == nil {
		return "", false
	}
	if reflect.DeepEqual(*a, *b) {
		return "", true
	}
	if a.ID == b.ID || (flagNameUniqueness == true && b.ID == "" && a.Name == b.Name) {
		diff := diffMonitor(a, b)
		if diff != "" {
			return diff, false
		}
		return "", true
	}
	return "", false
}

func validateRules(monitors []*(mkr.Monitor), label string) (bool, error) {

	flagNameUniqueness := true
	// check each monitor
	for _, m := range monitors {
		if m.Name == "" {
			return false, errors.New("Monitor should have 'Name'")
		}
		if m.Type != "host" && m.Type != "service" && m.Type != "external" && m.Type != "passive" {
			return false, fmt.Errorf("Unknown type is found: %s", m.Type)
		}
	}

	// check name uniqueness
	names := map[string]bool{}
	for _, m := range monitors {
		if names[m.Name] {
			logger.Log("Warning: ", fmt.Sprintf("Names of %s is not unique.", label))
			flagNameUniqueness = false
		}
		names[m.Name] = true
	}
	return flagNameUniqueness, nil
}

type monitorDiffPair struct {
	remote *mkr.Monitor
	local  *mkr.Monitor
}

type monitorDiff struct {
	onlyRemote []*(mkr.Monitor)
	onlyLocal  []*(mkr.Monitor)
	diff       []*monitorDiffPair
}

func checkMonitorsDiff(c *cli.Context) monitorDiff {
	conffile := c.GlobalString("conf")

	var monitorDiff monitorDiff

	monitorsRemote, err := newMackerel(conffile).FindMonitors()
	logger.DieIf(err)
	flagNameUniquenessRemote, err := validateRules(monitorsRemote, "remote rules")
	logger.DieIf(err)

	monitorsLocal, err := monitorLoadRules()
	logger.DieIf(err)
	flagNameUniquenessLocal, err := validateRules(monitorsLocal, "local rules")
	logger.DieIf(err)

	flagNameUniqueness := flagNameUniquenessLocal && flagNameUniquenessRemote

	for _, remote := range monitorsRemote {
		found := false
		for i, local := range monitorsLocal {
			diff, isSame := isSameMonitor(remote, local, flagNameUniqueness)
			if isSame || diff != "" {
				monitorsLocal[i] = nil
				found = true
				if diff != "" {
					monitorDiff.diff = append(monitorDiff.diff, &monitorDiffPair{remote, local})
				}
				break
			}
		}
		if found == false {
			monitorDiff.onlyRemote = append(monitorDiff.onlyRemote, remote)
		}
	}
	for _, local := range monitorsLocal {
		if local != nil {
			monitorDiff.onlyLocal = append(monitorDiff.onlyLocal, local)
		}
	}

	return monitorDiff
}

func doMonitorsDiff(c *cli.Context) {
	monitorDiff := checkMonitorsDiff(c)

	var diffs []string
	for _, d := range monitorDiff.diff {
		diffs = append(diffs, diffMonitor(d.remote, d.local))
	}

	fmt.Printf("Summary: %d modify, %d append, %d remove\n\n", len(monitorDiff.diff), len(monitorDiff.onlyLocal), len(monitorDiff.onlyRemote))
	for _, diff := range diffs {
		fmt.Println(diff)
	}
	for _, m := range monitorDiff.onlyRemote {
		printMonitor(m, "-")
	}
	for _, m := range monitorDiff.onlyLocal {
		printMonitor(m, "+")
	}
}

func doMonitorsPush(c *cli.Context) {
	monitorDiff := checkMonitorsDiff(c)
	isDryRun := c.Bool("dryRun")
	isVerbose := c.Bool("verbose")

	conffile := c.GlobalString("conf")
	client := newMackerel(conffile)
	if isVerbose {
		client.Verbose = true
	}

	for _, m := range monitorDiff.onlyLocal {
		logger.Log("info", "Create a new rule.")
		printMonitor(m, "")
		if !isDryRun {
			_, err := client.CreateMonitor(m)
			logger.DieIf(err)
		}
	}
	for _, m := range monitorDiff.onlyRemote {
		logger.Log("info", "Delete a rule.")
		printMonitor(m, "")
		if !isDryRun {
			_, err := client.DeleteMonitor(m.ID)
			logger.DieIf(err)
		}
	}
	for _, d := range monitorDiff.diff {
		logger.Log("info", "Update a rule.")
		printMonitor(d.local, "")
		if !isDryRun {
			_, err := client.UpdateMonitor(d.remote.ID, d.local)
			logger.DieIf(err)
		}
	}

}
<commit_msg>add filepath option<commit_after>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"reflect"
	"sort"
	"strings"

	"github.com/codegangsta/cli"
	mkr "github.com/mackerelio/mackerel-client-go"
	"github.com/mackerelio/mkr/logger"
)

var commandMonitors = cli.Command{
	Name:  "monitors",
	Usage: "Manipurate monitors",
	Description: `
    Manipurate monitor rules.
    Request "GET /api/v0/monitors". See http://help-ja.mackerel.io/entry/spec/api/v0#monitors.
`,
	Action: doMonitorsList,
	Subcommands: []cli.Command{
		{
			Name:   "pull",
			Usage:  "pull rules",
			Action: doMonitorsPull,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "filepath, F", Value: "", Usage: "Filename to store monitor rule definitions. default: monitors.json"},
				cli.BoolFlag{Name: "verbose, v", Usage: "Verbose output mode"},
			},
		},
		{
			Name:   "diff",
			Usage:  "diff rules",
			Action: doMonitorsDiff,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "filepath, F", Value: "", Usage: "Filename to store monitor rule definitions. default: monitors.json"},
			},
		},
		{
			Name:   "push",
			Usage:  "pull rules",
			Action: doMonitorsPush,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "filepath, F", Value: "", Usage: "Filename to store monitor rule definitions. default: monitors.json"},
				cli.BoolFlag{Name: "dryrun, d", Usage: "Dry Run."},
				cli.BoolFlag{Name: "verbose, v", Usage: "Verbose output mode"},
			},
		},
	},
}

func monitorSaveRules(rules []*(mkr.Monitor), optFilePath string) error {
	filePath := "monitors.json"
	if optFilePath != "" {
		filePath = optFilePath
	}
	file, err := os.Create(filePath)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	monitors := map[string]interface{}{"monitors": rules}
	dataRaw, err := json.MarshalIndent(monitors, "", "    ")
	logger.DieIf(err)
	data := strings.Replace(string(dataRaw), "\\u003c", "<", -1)
	data = strings.Replace(data, "\\u003e", ">", -1)

	_, err = file.WriteString(data)
	if err != nil {
		return err
	}
	return nil
}

func monitorLoadRules(optFilePath string) ([]*(mkr.Monitor), error) {
	filePath := "monitors.json"
	if optFilePath != "" {
		filePath = optFilePath
	}

	buff, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, err
	}

	var data struct {
		Monitors []*(mkr.Monitor) `json:"monitors"`
	}

	err = json.Unmarshal(buff, &data)
	if err != nil {
		return nil, err
	}
	return data.Monitors, nil
}

func doMonitorsList(c *cli.Context) {
	conffile := c.GlobalString("conf")

	monitors, err := newMackerel(conffile).FindMonitors()
	logger.DieIf(err)

	PrettyPrintJSON(monitors)
}

func doMonitorsPull(c *cli.Context) {
	conffile := c.GlobalString("conf")
	isVerbose := c.Bool("verbose")
	filePath := c.String("filepath")

	monitors, err := newMackerel(conffile).FindMonitors()
	logger.DieIf(err)

	monitorSaveRules(monitors, filePath)

	if isVerbose {
		PrettyPrintJSON(monitors)
	}
}

func appendDiff(src []string, name string, a interface{}, b interface{}) []string {
	diff := []string{}
	aType := reflect.TypeOf(a).String()
	format := "\"%s\""
	switch aType {
	case "uint64":
		format = "%d"
	case "float64":
		format = "%f"
	}
	if b != nil && a != b {
		diff = append(src, fmt.Sprintf("-  \"%s\": "+format+",", name, a))
		diff = append(diff, fmt.Sprintf("+  \"%s\": "+format+",", name, b))
	} else {
		diff = append(src, fmt.Sprintf("   \"%s\": "+format+",", name, a))
	}
	return diff
}

func printMonitor(a *mkr.Monitor, prefix string) {
	sA := reflect.ValueOf(a).Elem()
	diff := []string{" {"}
	for i := 0; i < sA.NumField(); i++ {
		fA := sA.Field(i)
		sAType := sA.Type()
		name := strings.Replace(sAType.Field(i).Tag.Get("json"), ",omitempty", "", 1)
		if sAType.Field(i).Type.String() != "[]string" {
			if name == "id" && fA.Interface() == "" {
				continue
			}
			diff = appendDiff(diff, name, fA.Interface(), nil)
		} else {
			diff = append(diff, fmt.Sprintf("   \"%s\": [", name))
			sortA := fA.Interface().([]string)
			sort.Strings(sortA)
			i := 0
			for i < len(sortA) {
				diff = append(diff, fmt.Sprintf("     \"%s\",", sortA[i]))
				i++
			}
			diff = append(diff, "   ],")
		}
	}
	diff = append(diff, " },")
	for _, d := range diff {
		fmt.Println(prefix + d)
	}
}

func diffMonitor(a *mkr.Monitor, b *mkr.Monitor) string {
	diff := []string{"  {"}
	diffNum := 0
	sA := reflect.ValueOf(a).Elem()
	sB := reflect.ValueOf(b).Elem()
	for i := 0; i < sA.NumField(); i++ {
		fA := sA.Field(i)
		fB := sB.Field(i)
		sAType := sA.Type()
		if sAType.Field(i).Type.String() != "[]string" {
			name := strings.Replace(sAType.Field(i).Tag.Get("json"), ",omitempty", "", 1)
			if name == "id" {
				continue
			}
			diff = appendDiff(diff, name, fA.Interface(), fB.Interface())
			if fA.Interface() != fB.Interface() {
				diffNum++
			}
		} else {
			name := strings.Replace(sAType.Field(i).Tag.Get("json"), ",omitempty", "", 1)
			diff = append(diff, fmt.Sprintf("    \"%s\": [", name))
			sortA := fA.Interface().([]string)
			sortB := fB.Interface().([]string)
			sort.Strings(sortA)
			sort.Strings(sortB)
			i := 0
			j := 0
			for i < len(sortA) && j < len(sortB) {
				if sortA[i] == sortB[j] {
					diff = append(diff, fmt.Sprintf("      \"%s\",", sortA[i]))
					i++
					j++
				} else if sortA[i] < sortB[j] {
					diff = append(diff, fmt.Sprintf("-     \"%s\",", sortA[i]))
					i++
					diffNum++
				} else if sortB[j] < sortA[i] {
					diff = append(diff, fmt.Sprintf("+     \"%s\",", sortB[j]))
					j++
					diffNum++
				}
			}
			diff = append(diff, "    ],")
		}
	}

	if diffNum > 0 {
		diff = append(diff, "  },")
		return strings.Join(diff, "\n")
	}
	return ""
}

func isSameMonitor(a *mkr.Monitor, b *mkr.Monitor, flagNameUniqueness bool) (string, bool) {
	if a == nil || b == nil {
		return "", false
	}
	if reflect.DeepEqual(*a, *b) {
		return "", true
	}
	if a.ID == b.ID || (flagNameUniqueness == true && b.ID == "" && a.Name == b.Name) {
		diff := diffMonitor(a, b)
		if diff != "" {
			return diff, false
		}
		return "", true
	}
	return "", false
}

func validateRules(monitors []*(mkr.Monitor), label string) (bool, error) {

	flagNameUniqueness := true
	// check each monitor
	for _, m := range monitors {
		if m.Name == "" {
			return false, errors.New("Monitor should have 'Name'")
		}
		if m.Type != "host" && m.Type != "service" && m.Type != "external" && m.Type != "passive" {
			return false, fmt.Errorf("Unknown type is found: %s", m.Type)
		}
	}

	// check name uniqueness
	names := map[string]bool{}
	for _, m := range monitors {
		if names[m.Name] {
			logger.Log("Warning: ", fmt.Sprintf("Names of %s is not unique.", label))
			flagNameUniqueness = false
		}
		names[m.Name] = true
	}
	return flagNameUniqueness, nil
}

type monitorDiffPair struct {
	remote *mkr.Monitor
	local  *mkr.Monitor
}

type monitorDiff struct {
	onlyRemote []*(mkr.Monitor)
	onlyLocal  []*(mkr.Monitor)
	diff       []*monitorDiffPair
}

func checkMonitorsDiff(c *cli.Context) monitorDiff {
	conffile := c.GlobalString("conf")
	filePath := c.String("filepath")

	var monitorDiff monitorDiff

	monitorsRemote, err := newMackerel(conffile).FindMonitors()
	logger.DieIf(err)
	flagNameUniquenessRemote, err := validateRules(monitorsRemote, "remote rules")
	logger.DieIf(err)

	monitorsLocal, err := monitorLoadRules(filePath)
	logger.DieIf(err)
	flagNameUniquenessLocal, err := validateRules(monitorsLocal, "local rules")
	logger.DieIf(err)

	flagNameUniqueness := flagNameUniquenessLocal && flagNameUniquenessRemote

	for _, remote := range monitorsRemote {
		found := false
		for i, local := range monitorsLocal {
			diff, isSame := isSameMonitor(remote, local, flagNameUniqueness)
			if isSame || diff != "" {
				monitorsLocal[i] = nil
				found = true
				if diff != "" {
					monitorDiff.diff = append(monitorDiff.diff, &monitorDiffPair{remote, local})
				}
				break
			}
		}
		if found == false {
			monitorDiff.onlyRemote = append(monitorDiff.onlyRemote, remote)
		}
	}
	for _, local := range monitorsLocal {
		if local != nil {
			monitorDiff.onlyLocal = append(monitorDiff.onlyLocal, local)
		}
	}

	return monitorDiff
}

func doMonitorsDiff(c *cli.Context) {
	monitorDiff := checkMonitorsDiff(c)

	var diffs []string
	for _, d := range monitorDiff.diff {
		diffs = append(diffs, diffMonitor(d.remote, d.local))
	}

	fmt.Printf("Summary: %d modify, %d append, %d remove\n\n", len(monitorDiff.diff), len(monitorDiff.onlyLocal), len(monitorDiff.onlyRemote))
	for _, diff := range diffs {
		fmt.Println(diff)
	}
	for _, m := range monitorDiff.onlyRemote {
		printMonitor(m, "-")
	}
	for _, m := range monitorDiff.onlyLocal {
		printMonitor(m, "+")
	}
}

func doMonitorsPush(c *cli.Context) {
	monitorDiff := checkMonitorsDiff(c)
	isDryRun := c.Bool("dryRun")
	isVerbose := c.Bool("verbose")

	conffile := c.GlobalString("conf")
	client := newMackerel(conffile)
	if isVerbose {
		client.Verbose = true
	}

	for _, m := range monitorDiff.onlyLocal {
		logger.Log("info", "Create a new rule.")
		printMonitor(m, "")
		if !isDryRun {
			_, err := client.CreateMonitor(m)
			logger.DieIf(err)
		}
	}
	for _, m := range monitorDiff.onlyRemote {
		logger.Log("info", "Delete a rule.")
		printMonitor(m, "")
		if !isDryRun {
			_, err := client.DeleteMonitor(m.ID)
			logger.DieIf(err)
		}
	}
	for _, d := range monitorDiff.diff {
		logger.Log("info", "Update a rule.")
		printMonitor(d.local, "")
		if !isDryRun {
			_, err := client.UpdateMonitor(d.remote.ID, d.local)
			logger.DieIf(err)
		}
	}

}
<|endoftext|>


<commit_before>package main

import (
	"testing"

)

func TestReadVideo(t *testing.T) {
	in := []byte{2, 5, 6, 3, 4, 5, 6, 5, 4, 3, 4, 0, 0, 0, 1, 8, 8, 4, 6, 5, 8, 3, 9, 2, 0, 4, 9, 5, 8, 0, 0, 0, 1, 9, 8, 2, 7, 4, 5, 2, 7, 4, 8, 9, 3}
	out := []byte{ 2, 5, 6, 3, 4, 5, 6, 5, 4, 3, 4, 8, 8, 4, 6, 5, 8, 3, 9, 2, 0, 4, 9, 5, 8, 9, 8, 2, 7, 4, 5, 2, 7, 4, 8, 9, 3 }

	n := new(Nal)

	if x := n.readVideo(in); x != out {
		t.Fail()
	}

}<commit_msg>Trying to finish...<commit_after>package main

import (
	"testing"
	//"regifted/Nal"

)

func TestReadVideo(t *testing.T) {
	in := []byte{2, 5, 6, 3, 4, 5, 6, 5, 4, 3, 4, 0, 0, 0, 1, 8, 8, 4, 6, 5, 8, 3, 9, 2, 0, 4, 9, 5, 8, 0, 0, 0, 1, 9, 8, 2, 7, 4, 5, 2, 7, 4, 8, 9, 3}
	out := []byte{ 2, 5, 6, 3, 4, 5, 6, 5, 4, 3, 4, 8, 8, 4, 6, 5, 8, 3, 9, 2, 0, 4, 9, 5, 8, 9, 8, 2, 7, 4, 5, 2, 7, 4, 8, 9, 3 }

	n := new(Nal)

	if x := n.readVideo(in); x != out {
		t.Fail()
	}

}<|endoftext|>


<commit_before>package testserver

import (
	"fmt"
	"io"
	"log"
	"mime"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"regexp"
	"runtime"
	"time"
)

const (
	latestSuffix     = "LATEST"
	finishedFileMode = 0555
)

func downloadFile(response *http.Response, filePath string) error {
	output, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0200)
	if err != nil {
		return fmt.Errorf("error creating %s: %s", filePath, err)
	}
	defer output.Close()

	log.Printf("saving %s to %s, this may take some time", response.Request.URL, filePath)

	if _, err := io.Copy(output, response.Body); err != nil {
		return fmt.Errorf("problem saving %s to %s: %s", response.Request.URL, filePath, err)
	}

	// Download was successful, add the rw bits.
	return os.Chmod(filePath, finishedFileMode)
}

var glibcRE = regexp.MustCompile(`(?i)\bglibc\b`)

func downloadLatestBinary() (string, error) {
	goos := runtime.GOOS
	if goos == "linux" {
		goos += func() string {
			// Detect which C library is present on the system. See
			// https://unix.stackexchange.com/a/120381.
			cmd := exec.Command("ldd", "--version")
			out, err := cmd.Output()
			if err != nil {
				log.Printf("%s: out=%q err=%s", cmd.Args, out, err)
			} else if glibcRE.Match(out) {
				return "-gnu"
			}
			return "-musl"
		}()
	}
	binaryName := fmt.Sprintf("cockroach.%s-%s", goos, runtime.GOARCH)
	if runtime.GOOS == "windows" {
		binaryName += ".exe"
	}
	url := &url.URL{
		Scheme: "https",
		Host:   "edge-binaries.cockroachdb.com",
		Path:   path.Join("cockroach", fmt.Sprintf("%s.%s", binaryName, latestSuffix)),
	}
	log.Printf("GET %s", url)
	response, err := http.Get(url.String())
	if err != nil {
		return "", err
	}
	defer response.Body.Close()

	if response.StatusCode != 200 {
		return "", fmt.Errorf("error downloading %s: %d (%s)", url, response.StatusCode, response.Status)
	}

	const contentDisposition = "Content-Disposition"
	_, disposition, err := mime.ParseMediaType(response.Header.Get(contentDisposition))
	if err != nil {
		return "", fmt.Errorf("error parsing %s headers %s: %s", contentDisposition, response.Header, err)
	}

	filename, ok := disposition["filename"]
	if !ok {
		return "", fmt.Errorf("content disposition header %s did not contain filename", disposition)
	}
	localFile := filepath.Join(os.TempDir(), filename)
	for {
		info, err := os.Stat(localFile)
		if os.IsNotExist(err) {
			// File does not exist: download it.
			break
		}
		if err != nil {
			return "", err
		}
		// File already present: check mode.
		if info.Mode().Perm() == finishedFileMode {
			return localFile, nil
		}
		time.Sleep(time.Millisecond * 10)
	}

	if err := downloadFile(response, localFile); err != nil {
		_ = os.Remove(localFile)
		return "", err
	}

	return localFile, nil
}
<commit_msg>testserver: use glibc binary on systems with eglibc<commit_after>package testserver

import (
	"fmt"
	"io"
	"log"
	"mime"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"regexp"
	"runtime"
	"time"
)

const (
	latestSuffix     = "LATEST"
	finishedFileMode = 0555
)

func downloadFile(response *http.Response, filePath string) error {
	output, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0200)
	if err != nil {
		return fmt.Errorf("error creating %s: %s", filePath, err)
	}
	defer output.Close()

	log.Printf("saving %s to %s, this may take some time", response.Request.URL, filePath)

	if _, err := io.Copy(output, response.Body); err != nil {
		return fmt.Errorf("problem saving %s to %s: %s", response.Request.URL, filePath, err)
	}

	// Download was successful, add the rw bits.
	return os.Chmod(filePath, finishedFileMode)
}

var muslRE = regexp.MustCompile(`(?i)\bmusl\b`)

func downloadLatestBinary() (string, error) {
	goos := runtime.GOOS
	if goos == "linux" {
		goos += func() string {
			// Detect which C library is present on the system. See
			// https://unix.stackexchange.com/a/120381.
			cmd := exec.Command("ldd", "--version")
			out, err := cmd.Output()
			if err != nil {
				log.Printf("%s: out=%q err=%s", cmd.Args, out, err)
			} else if muslRE.Match(out) {
				return "-musl"
			}
			return "-gnu"
		}()
	}
	binaryName := fmt.Sprintf("cockroach.%s-%s", goos, runtime.GOARCH)
	if runtime.GOOS == "windows" {
		binaryName += ".exe"
	}
	url := &url.URL{
		Scheme: "https",
		Host:   "edge-binaries.cockroachdb.com",
		Path:   path.Join("cockroach", fmt.Sprintf("%s.%s", binaryName, latestSuffix)),
	}
	log.Printf("GET %s", url)
	response, err := http.Get(url.String())
	if err != nil {
		return "", err
	}
	defer response.Body.Close()

	if response.StatusCode != 200 {
		return "", fmt.Errorf("error downloading %s: %d (%s)", url, response.StatusCode, response.Status)
	}

	const contentDisposition = "Content-Disposition"
	_, disposition, err := mime.ParseMediaType(response.Header.Get(contentDisposition))
	if err != nil {
		return "", fmt.Errorf("error parsing %s headers %s: %s", contentDisposition, response.Header, err)
	}

	filename, ok := disposition["filename"]
	if !ok {
		return "", fmt.Errorf("content disposition header %s did not contain filename", disposition)
	}
	localFile := filepath.Join(os.TempDir(), filename)
	for {
		info, err := os.Stat(localFile)
		if os.IsNotExist(err) {
			// File does not exist: download it.
			break
		}
		if err != nil {
			return "", err
		}
		// File already present: check mode.
		if info.Mode().Perm() == finishedFileMode {
			return localFile, nil
		}
		time.Sleep(time.Millisecond * 10)
	}

	if err := downloadFile(response, localFile); err != nil {
		_ = os.Remove(localFile)
		return "", err
	}

	return localFile, nil
}
<|endoftext|>


<commit_before>package net

func errorLabelValue(err error) string {
	if err == nil {
		return "0"
	}
	return "1"
}
<commit_msg>Change values of «error» label.<commit_after>package net

import (
	"io"
)

// errorLabelValue returns value for Prometheus metric label "error":
// "ok" for no error, "EOF" for io.EOF, "error" otherwise.
func errorLabelValue(err error) string {
	if err == nil {
		return "ok"
	}
	if err == io.EOF {
		return "EOF"
	}
	return "error"
}
<|endoftext|>


<commit_before>package main

import (
	anet "atman/net"
	"atman/net/ip"
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
)

const (
	NETIF_RSP_NULL = 1
)

func main() {
	dev := anet.DefaultDevice

	fmt.Println("Network device initialized:")
	fmt.Printf("  Mac address: %s\n", dev.MacAddr)
	fmt.Printf("  IP address:  %s\n", dev.IPAddr)

	handleEvents(dev)
}

func handleEvents(dev *anet.Device) {
	for {
		dev.EventChannel.Wait()

		for dev.Rx.CheckForResponses() {
			rsp := (*anet.NetifRxResponse)(dev.Rx.NextResponse())

			if rsp.Status > NETIF_RSP_NULL {
				r := newPacketReader(dev, rsp)

				rx(dev, r)
			}

			enqueueRequest(dev, rsp.ID)
		}

		if notify := dev.Rx.PushRequests(); notify {
			dev.EventChannel.Notify()
		}
	}
}

func newPacketReader(dev *anet.Device, rsp *anet.NetifRxResponse) io.Reader {
	var (
		len    = uint16(rsp.Status)
		buf    = dev.RxBuffers[rsp.ID]
		packet = buf.Page.Data[rsp.Offset : rsp.Offset+len]
	)

	return bytes.NewReader(packet)
}

func rx(dev *anet.Device, r io.Reader) {
	var hdr ip.EthernetHeader

	if err := binary.Read(r, binary.BigEndian, &hdr); err != nil {
		fmt.Printf("rx: unable to read header: %s\n", err)
		return
	}

	fmt.Printf(
		"rx: packet from=%q to=%q type=0x%04x (%s)\n",
		hdr.Source,
		hdr.Destination,
		hdr.Type,
		hdr.Type.Name(),
	)
}

func enqueueRequest(dev *anet.Device, id uint16) {
	req := (*anet.NetifRxRequest)(dev.Rx.NextRequest())
	req.ID = id
	req.Gref = dev.RxBuffers[id].Gref
}
<commit_msg>net: update to new buffer type<commit_after>package main

import (
	anet "atman/net"
	"atman/net/ip"
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
)

const (
	NETIF_RSP_NULL = 1
)

func main() {
	dev := anet.DefaultDevice

	fmt.Println("Network device initialized:")
	fmt.Printf("  Mac address: %s\n", dev.MacAddr)
	fmt.Printf("  IP address:  %s\n", dev.IPAddr)

	handleEvents(dev)
}

func handleEvents(dev *anet.Device) {
	for {
		dev.EventChannel.Wait()

		for dev.Rx.CheckForResponses() {
			rsp := (*anet.NetifRxResponse)(dev.Rx.NextResponse())

			if rsp.Status > NETIF_RSP_NULL {
				r := newPacketReader(dev, rsp)

				rx(dev, r)
			}

			enqueueRequest(dev, rsp.ID)
		}

		if notify := dev.Rx.PushRequests(); notify {
			dev.EventChannel.Notify()
		}
	}
}

func newPacketReader(dev *anet.Device, rsp *anet.NetifRxResponse) io.Reader {
	var (
		len    = uint16(rsp.Status)
		buf    = dev.RxBuffers.Lookup(int(rsp.ID))
		packet = buf.Page.Data[rsp.Offset : rsp.Offset+len]
	)

	return bytes.NewReader(packet)
}

func rx(dev *anet.Device, r io.Reader) {
	var hdr ip.EthernetHeader

	if err := binary.Read(r, binary.BigEndian, &hdr); err != nil {
		fmt.Printf("rx: unable to read header: %s\n", err)
		return
	}

	fmt.Printf(
		"rx: packet from=%q to=%q type=0x%04x (%s)\n",
		hdr.Source,
		hdr.Destination,
		hdr.Type,
		hdr.Type.Name(),
	)
}

func enqueueRequest(dev *anet.Device, id uint16) {
	req := (*anet.NetifRxRequest)(dev.Rx.NextRequest())
	req.ID = id
	req.Gref = dev.RxBuffers.Lookup(int(id)).Gref
}
<|endoftext|>


<commit_before>package rogue

import (
	"image/png"
	"os"
	"testing"

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

func BenchmarkGenerateIsland(b *testing.B) {
	for n := 0; n < b.N; n++ {

		generateIsland(666, 220, 140)
	}
}

func prepareIsland() {
	if island == nil {
		seed := int64(123)
		island = generateIsland(seed, 200, 100)

		islandColImgFile, _ := os.Create("island_test.png")
		png.Encode(islandColImgFile, island.ColoredHeightMapAsImage())
	}

	// clear spawns between tests
	island.Spawns = nil
}

func TestWithinRadiusOfType(t *testing.T) {

	prepareIsland()
	assert.Equal(t, true, len(island.Spawns) == 0)

	pos := island.randomPointAboveWater()

	assert.Equal(t, 0, len(island.withinRadiusOfName("small fireplace", 0, pos)))
	assert.Equal(t, 0, len(island.withinRadiusOfName("small fireplace", 30, pos)))
	assert.Equal(t, 0, len(island.withinRadiusOfType("fireplace", 0, pos)))
	assert.Equal(t, 0, len(island.withinRadiusOfType("fireplace", 30, pos)))

	island.addNpcFromName("small fireplace", pos)
	assert.Equal(t, true, len(island.Spawns) == 1)

	assert.Equal(t, 1, len(island.withinRadiusOfName("small fireplace", 0, pos)))
	assert.Equal(t, 1, len(island.withinRadiusOfName("small fireplace", 30, pos)))
	assert.Equal(t, 1, len(island.withinRadiusOfType("fireplace", 0, pos)))
	assert.Equal(t, 1, len(island.withinRadiusOfType("fireplace", 30, pos)))

	pos2 := pos
	pos2.Y++

	assert.Equal(t, 0, len(island.withinRadiusOfName("small fireplace", 0, pos2)))
	assert.Equal(t, 1, len(island.withinRadiusOfName("small fireplace", 1, pos2)))
	assert.Equal(t, 1, len(island.withinRadiusOfName("small fireplace", 30, pos2)))
	assert.Equal(t, 0, len(island.withinRadiusOfType("fireplace", 0, pos2)))
	assert.Equal(t, 1, len(island.withinRadiusOfType("fireplace", 1, pos2)))
	assert.Equal(t, 1, len(island.withinRadiusOfType("fireplace", 30, pos2)))
}

func TestCanBuildAt(t *testing.T) {

	prepareIsland()
	assert.Equal(t, true, len(island.Spawns) == 0)

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())
	assert.Equal(t, true, len(island.Spawns) == 1)

	assert.Equal(t, true, island.canBuildAt(island.Spawns[0].Position))
}

func TestFindFoodAndEat(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())
	assert.Equal(t, true, len(island.Spawns) == 1)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	// make npc hungry
	dw.Hunger = dw.hungerCap() + 1
	island.Tick()

	// make sure planned action: find food
	assert.Equal(t, "find food", dw.CurrentAction.Name)
	assert.Equal(t, false, dw.hasItemTypeInInventory("food"))

	// progress until npc found food
	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	// make sure that npc has aged
	assert.Equal(t, true, dw.Age > 0)

	// make sure food was found
	assert.Equal(t, true, len(dw.Inventory) > 0)
	assert.Equal(t, true, dw.hasItemTypeInInventory("food"))
	assert.Equal(t, false, dw.hasItemTypeInInventory("drink"))

	oldHunger := dw.Hunger
	island.Tick()

	// make sure npc consumed food
	assert.Equal(t, false, dw.hasItemTypeInInventory("food"))

	// make sure hunger went down
	assert.Equal(t, true, dw.Hunger < oldHunger)
	assert.Equal(t, false, dw.isHungry())
}

func TestFindWaterAndDrink(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())
	assert.Equal(t, true, len(island.Spawns) == 1)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	// make npc thirsty
	dw.Thirst = dw.thirstCap() + 1
	island.Tick()

	// make sure npc planned action: find water
	assert.Equal(t, "find water", dw.CurrentAction.Name)
	assert.Equal(t, false, dw.hasItemTypeInInventory("drink"))

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	// progress until npc found food
	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	// make sure water was found
	assert.Equal(t, true, len(dw.Inventory) > 0)
	assert.Equal(t, true, dw.hasItemTypeInInventory("drink"))

	oldThirst := dw.Thirst
	island.Tick()

	// make sure npc consumed water
	assert.Equal(t, false, dw.hasItemTypeInInventory("drink"))

	// make sure thirst went down
	assert.Equal(t, true, dw.Thirst < oldThirst)
	assert.Equal(t, false, dw.isThirsty())
}

func TestFindFirewood(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())

	// add nessecities, so they dont need to be built
	island.addNpcFromName("small fireplace", island.Spawns[0].Position)
	island.addNpcFromName("small shelter", island.Spawns[0].Position)
	island.addNpcFromName("apple tree", island.Spawns[0].Position)
	island.addNpcFromName("farmland", island.Spawns[0].Position)

	assert.Equal(t, true, len(island.Spawns) == 5)
	dw := island.Spawns[0]

	island.Tick()
	assert.Equal(t, false, dw.CurrentAction == nil)
	assert.Equal(t, "find firewood", dw.CurrentAction.Name)

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	assert.Equal(t, true, dw.hasItemTypeInInventory("wood"))
}

func TestSleep(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())
	assert.Equal(t, true, len(island.Spawns) == 1)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	// make npc tired
	dw.Tiredness = dw.tirednessCap() + 1
	island.Tick()

	// make sure npc planned action: sleep
	assert.Equal(t, "sleep", dw.CurrentAction.Name)

	oldTiredness := dw.Tiredness

	island.Tick()
	assert.Equal(t, true, dw.isSleeping())

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	// progress until npc wakes up
	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	// make sure tiredness went down
	assert.Equal(t, true, dw.Tiredness < oldTiredness)
	assert.Equal(t, false, dw.isTired())
	assert.Equal(t, false, dw.isSleeping())
}

func TestRabbitDigHole(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("rabbit", island.randomPointAboveWater())
	assert.Equal(t, true, len(island.Spawns) == 1)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	island.Tick()
	assert.Equal(t, "dig small hole", dw.CurrentAction.Name)

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	assert.Equal(t, true, len(island.withinRadiusOfName("small hole", 0, dw.Position)) == 1)
	assert.Equal(t, true, len(island.withinRadiusOfType("shelter", 0, dw.Position)) == 1)
}

func TestBuildFireplace(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())

	// add nessecities nearby, so they dont need to be built
	nextTo := island.Spawns[0].Position
	//nextTo.Y++
	// make sure nextTo is changed
	//assert.Equal(t, false, island.Spawns[0].Position.Y == nextTo.Y)

	island.addNpcFromName("small shelter", nextTo)
	island.addNpcFromName("farmland", nextTo)
	island.addNpcFromName("apple tree", nextTo)

	assert.Equal(t, true, len(island.Spawns) == 4)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	island.Tick()
	assert.Equal(t, false, dw.CurrentAction == nil)
	assert.Equal(t, "build small fireplace", dw.CurrentAction.Name)

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	assert.Equal(t, true, len(island.withinRadiusOfName("small fireplace", 0, dw.Position)) == 1)
	assert.Equal(t, true, len(island.withinRadiusOfType("fireplace", 0, dw.Position)) == 1)
}

func TestBuildShelter(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())

	// add nessecities, so they dont need to be built
	island.addNpcFromName("small fireplace", island.Spawns[0].Position)
	island.addNpcFromName("farmland", island.Spawns[0].Position)
	island.addNpcFromName("apple tree", island.Spawns[0].Position)

	assert.Equal(t, true, len(island.Spawns) == 4)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	assert.Equal(t, true, len(island.withinRadiusOfType("fireplace", 0, dw.Position)) == 1)

	island.Tick()
	assert.Equal(t, false, dw.CurrentAction == nil)
	assert.Equal(t, "build small shelter", dw.CurrentAction.Name)

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	assert.Equal(t, true, len(island.withinRadiusOfType("shelter", 0, dw.Position)) == 1)
}

func TestBuildFarmland(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())

	// add nessecities, so they dont need to be built
	island.addNpcFromName("small fireplace", island.Spawns[0].Position)
	island.addNpcFromName("small shelter", island.Spawns[0].Position)
	island.addNpcFromName("apple tree", island.Spawns[0].Position)

	assert.Equal(t, true, len(island.Spawns) == 4)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	island.Tick()
	assert.Equal(t, false, dw.CurrentAction == nil)
	assert.Equal(t, "build farmland", dw.CurrentAction.Name)

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	assert.Equal(t, 1, len(island.withinRadiusOfName("farmland", 0, dw.Position)))
	assert.Equal(t, 1, len(island.withinRadiusOfType("food producer", 0, dw.Position)))
}

func TestTree(t *testing.T) {

	prepareIsland()

	island.addNpcFromName("oak tree", island.randomPointAboveWater())

	assert.Equal(t, true, len(island.Spawns) == 1)
	//	tr := island.Spawns[0]

	// XXX
}
<commit_msg>minor tweaks<commit_after>package rogue

import (
	"image/png"
	"os"
	"testing"

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

func BenchmarkGenerateIsland(b *testing.B) {
	for n := 0; n < b.N; n++ {

		generateIsland(666, 220, 140)
	}
}

func prepareIsland() {
	if island == nil {
		seed := int64(123)
		island = generateIsland(seed, 200, 100)

		islandColImgFile, _ := os.Create("island_test.png")
		png.Encode(islandColImgFile, island.ColoredHeightMapAsImage())
	}

	// clear spawns between tests
	island.Spawns = nil
}

func TestWithinRadiusOfType(t *testing.T) {

	prepareIsland()
	assert.Equal(t, true, len(island.Spawns) == 0)

	pos := island.randomPointAboveWater()

	assert.Equal(t, 0, len(island.withinRadiusOfName("small fireplace", 0, pos)))
	assert.Equal(t, 0, len(island.withinRadiusOfName("small fireplace", 30, pos)))
	assert.Equal(t, 0, len(island.withinRadiusOfType("fireplace", 0, pos)))
	assert.Equal(t, 0, len(island.withinRadiusOfType("fireplace", 30, pos)))

	island.addNpcFromName("small fireplace", pos)
	assert.Equal(t, true, len(island.Spawns) == 1)

	assert.Equal(t, 1, len(island.withinRadiusOfName("small fireplace", 0, pos)))
	assert.Equal(t, 1, len(island.withinRadiusOfName("small fireplace", 30, pos)))
	assert.Equal(t, 1, len(island.withinRadiusOfType("fireplace", 0, pos)))
	assert.Equal(t, 1, len(island.withinRadiusOfType("fireplace", 30, pos)))

	pos2 := pos
	pos2.Y++

	assert.Equal(t, 0, len(island.withinRadiusOfName("small fireplace", 0, pos2)))
	assert.Equal(t, 1, len(island.withinRadiusOfName("small fireplace", 1, pos2)))
	assert.Equal(t, 1, len(island.withinRadiusOfName("small fireplace", 30, pos2)))
	assert.Equal(t, 0, len(island.withinRadiusOfType("fireplace", 0, pos2)))
	assert.Equal(t, 1, len(island.withinRadiusOfType("fireplace", 1, pos2)))
	assert.Equal(t, 1, len(island.withinRadiusOfType("fireplace", 30, pos2)))
}

func TestCanBuildAt(t *testing.T) {

	prepareIsland()
	assert.Equal(t, true, len(island.Spawns) == 0)

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())
	assert.Equal(t, true, len(island.Spawns) == 1)

	assert.Equal(t, true, island.canBuildAt(island.Spawns[0].Position))

	island.addNpcFromName("small fireplace", island.Spawns[0].Position)

	assert.Equal(t, false, island.canBuildAt(island.Spawns[0].Position))
}

func TestFindFoodAndEat(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())
	assert.Equal(t, true, len(island.Spawns) == 1)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	// make npc hungry
	dw.Hunger = dw.hungerCap() + 1
	island.Tick()

	// make sure planned action: find food
	assert.Equal(t, "find food", dw.CurrentAction.Name)
	assert.Equal(t, false, dw.hasItemTypeInInventory("food"))

	// progress until npc found food
	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	// make sure that npc has aged
	assert.Equal(t, true, dw.Age > 0)

	// make sure food was found
	assert.Equal(t, true, len(dw.Inventory) > 0)
	assert.Equal(t, true, dw.hasItemTypeInInventory("food"))
	assert.Equal(t, false, dw.hasItemTypeInInventory("drink"))

	oldHunger := dw.Hunger
	island.Tick()

	// make sure npc consumed food
	assert.Equal(t, false, dw.hasItemTypeInInventory("food"))

	// make sure hunger went down
	assert.Equal(t, true, dw.Hunger < oldHunger)
	assert.Equal(t, false, dw.isHungry())
}

func TestFindWaterAndDrink(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())
	assert.Equal(t, true, len(island.Spawns) == 1)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	// make npc thirsty
	dw.Thirst = dw.thirstCap() + 1
	island.Tick()

	// make sure npc planned action: find water
	assert.Equal(t, "find water", dw.CurrentAction.Name)
	assert.Equal(t, false, dw.hasItemTypeInInventory("drink"))

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	// progress until npc found food
	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	// make sure water was found
	assert.Equal(t, true, len(dw.Inventory) > 0)
	assert.Equal(t, true, dw.hasItemTypeInInventory("drink"))

	oldThirst := dw.Thirst
	island.Tick()

	// make sure npc consumed water
	assert.Equal(t, false, dw.hasItemTypeInInventory("drink"))

	// make sure thirst went down
	assert.Equal(t, true, dw.Thirst < oldThirst)
	assert.Equal(t, false, dw.isThirsty())
}

func TestFindFirewood(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())

	// add nessecities, so they dont need to be built
	island.addNpcFromName("small fireplace", island.Spawns[0].Position)
	island.addNpcFromName("small shelter", island.Spawns[0].Position)
	island.addNpcFromName("apple tree", island.Spawns[0].Position)
	island.addNpcFromName("farmland", island.Spawns[0].Position)

	assert.Equal(t, true, len(island.Spawns) == 5)
	dw := island.Spawns[0]

	island.Tick()
	assert.Equal(t, false, dw.CurrentAction == nil)
	assert.Equal(t, "find firewood", dw.CurrentAction.Name)

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	assert.Equal(t, true, dw.hasItemTypeInInventory("wood"))
}

func TestSleep(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())
	assert.Equal(t, true, len(island.Spawns) == 1)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	// make npc tired
	dw.Tiredness = dw.tirednessCap() + 1
	island.Tick()

	// make sure npc planned action: sleep
	assert.Equal(t, "sleep", dw.CurrentAction.Name)

	oldTiredness := dw.Tiredness

	island.Tick()
	assert.Equal(t, true, dw.isSleeping())

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	// progress until npc wakes up
	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	// make sure tiredness went down
	assert.Equal(t, true, dw.Tiredness < oldTiredness)
	assert.Equal(t, false, dw.isTired())
	assert.Equal(t, false, dw.isSleeping())
}

func TestRabbitDigHole(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("rabbit", island.randomPointAboveWater())
	assert.Equal(t, true, len(island.Spawns) == 1)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	island.Tick()
	assert.Equal(t, "dig small hole", dw.CurrentAction.Name)

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	assert.Equal(t, true, len(island.withinRadiusOfName("small hole", 0, dw.Position)) == 1)
	assert.Equal(t, true, len(island.withinRadiusOfType("shelter", 0, dw.Position)) == 1)
}

func TestBuildFireplace(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())

	// add nessecities nearby, so they dont need to be built
	nextTo := island.Spawns[0].Position
	//nextTo.Y++
	// make sure nextTo is changed
	//assert.Equal(t, false, island.Spawns[0].Position.Y == nextTo.Y)

	island.addNpcFromName("small shelter", nextTo)
	island.addNpcFromName("farmland", nextTo)
	island.addNpcFromName("apple tree", nextTo)

	assert.Equal(t, true, len(island.Spawns) == 4)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	island.Tick()

	// XXX currently failing: npc chose to build shelter even though they are nearby

	assert.Equal(t, false, dw.CurrentAction == nil)
	assert.Equal(t, "build small fireplace", dw.CurrentAction.Name)

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	assert.Equal(t, true, len(island.withinRadiusOfName("small fireplace", 0, dw.Position)) == 1)
	assert.Equal(t, true, len(island.withinRadiusOfType("fireplace", 0, dw.Position)) == 1)
}

func TestBuildShelter(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())

	// add nessecities, so they dont need to be built
	island.addNpcFromName("small fireplace", island.Spawns[0].Position)
	island.addNpcFromName("farmland", island.Spawns[0].Position)
	island.addNpcFromName("apple tree", island.Spawns[0].Position)

	assert.Equal(t, true, len(island.Spawns) == 4)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	assert.Equal(t, true, len(island.withinRadiusOfType("fireplace", 0, dw.Position)) == 1)

	island.Tick()
	assert.Equal(t, false, dw.CurrentAction == nil)
	assert.Equal(t, "build small shelter", dw.CurrentAction.Name)

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	assert.Equal(t, true, len(island.withinRadiusOfType("shelter", 0, dw.Position)) == 1)
}

func TestBuildFarmland(t *testing.T) {

	prepareIsland()

	island.addNpcFromRace("dwarf", island.randomPointAboveWater())

	// add nessecities, so they dont need to be built
	island.addNpcFromName("small fireplace", island.Spawns[0].Position)
	island.addNpcFromName("small shelter", island.Spawns[0].Position)
	island.addNpcFromName("apple tree", island.Spawns[0].Position)

	assert.Equal(t, true, len(island.Spawns) == 4)
	dw := island.Spawns[0]
	dw.addToInventory("firewood")

	island.Tick()
	assert.Equal(t, false, dw.CurrentAction == nil)
	assert.Equal(t, "build farmland", dw.CurrentAction.Name)

	duration := dw.CurrentAction.Duration
	assert.Equal(t, true, duration > 0)

	for i := 0; i <= duration; i++ {
		island.Tick()
	}

	assert.Equal(t, 1, len(island.withinRadiusOfName("farmland", 0, dw.Position)))
	assert.Equal(t, 1, len(island.withinRadiusOfType("food producer", 0, dw.Position)))
}

func TestTree(t *testing.T) {

	prepareIsland()

	island.addNpcFromName("oak tree", island.randomPointAboveWater())

	assert.Equal(t, true, len(island.Spawns) == 1)
	//	tr := island.Spawns[0]

	// XXX
}
<|endoftext|>


<commit_before>/*
   Copyright 2016 Simon Schmidt

   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 joinf

import "github.com/maxymania/metaclusterfs/resource"
import "io"
import "syscall"
import "strconv"
import "encoding/gob"
import "encoding/csv"
import "errors"
import "bytes"

type DirPage struct{
	Version int64
}
func LoadDPs(r *resource.Resource, part string) (*DirPage,error) {
	m,e := r.Open(part+"inf")
	if e!=nil { return nil,e }
	f := new(DirPage)
	defer m.Close()
	dec := gob.NewDecoder(io.NewSectionReader(m,0,MB64))
	e = dec.Decode(f)
	return f,e
}
func SaveDPs(r *resource.Resource,f *DirPage, part string) error {
	if f==nil { return errors.New("BARF!") }
	m,e := r.Create(part+"inf")
	if e!=nil { return e }
	defer m.Close()
	b := new(bytes.Buffer)
	enc := gob.NewEncoder(b)
	e = enc.Encode(f)
	if e!=nil { return e }
	_,e = m.WriteAt(b.Bytes(),0)
	return e
}

const MAXDIR = 1<<10

func CreateDir(r *resource.Resource) error {
	m,e := LoadMeta(r)
	if e!=nil { m = new(FileMetadata) }
	m.IsDir = true
	return SaveMeta(r,m)
}

type Directory struct{
	R *resource.Resource
	F *FileMetadata
}
func (dir *Directory) load(i int64) ([][]string,error) {
	part := strconv.FormatInt(i,10)+"."
	p,e := LoadDPs(dir.R,part)
	if e!=nil { return nil,e }
	pver := part+strconv.FormatInt(p.Version,10)
	f,e := dir.R.Open(pver)
	if e!=nil { return nil,e }
	defer f.Close()
	s,e := f.Stat()
	if e!=nil { return nil,e }
	nr := csv.NewReader(io.NewSectionReader(f,0,s.Size()))
	return nr.ReadAll()
}
func (dir *Directory) save(i int64,l [][]string) error {
	b := new(bytes.Buffer)
	w := csv.NewWriter(b)
	w.WriteAll(l)
	w.Flush()

	// done!

	part := strconv.FormatInt(i,10)+"."
	p,e := LoadDPs(dir.R,part)
	if e!=nil { p = new(DirPage); e=nil }
	p.Version = ( p.Version + 1 ) % 8
	e = SaveDPs(dir.R,p,part)
	if e!=nil { return e }
	pver := part+strconv.FormatInt(p.Version,10)
	f,e := dir.R.Create(pver)
	if e!=nil { return e }
	defer f.Close()
	e = f.Truncate(int64(b.Len() ))
	if e!=nil { return e }
	_,e = f.WriteAt(b.Bytes(),0)
	return e
}
func (dir *Directory) find(i int64,s string) (string,error) {
	l,e := dir.load(i)
	if e!=nil { return "",e }
	for _,row := range l {
		if len(row)<2 { continue }
		if row[0]==s { return row[1],nil }
	}
	return "",nil
}
func (dir *Directory) Find(s string) (string,error) {
	for i := int64(0) ; i<dir.F.Pages ; i++ {
		s,e := dir.find(i,s)
		if e!=nil { return "",e }
		if s!="" { return s,nil }
	}
	return "",syscall.ENOENT
}
func (dir *Directory) delete(i int64,s string) (string,error) {
	l,e := dir.load(i)
	if e!=nil { return "",e }
	for j,row := range l {
		if len(row)<2 { continue }
		if row[0]==s {
			r := row[1]
			copy(l[j:],l[j+1:])
			l = l[:len(l)-1]
			dir.save(i,l)
			return r,nil
		}
	}
	return "",nil
}
func (dir *Directory) Delete(s string) (string,error) {
	for i := int64(0) ; i<dir.F.Pages ; i++ {
		s,e := dir.delete(i,s)
		if e!=nil { return "",e }
		if s!="" { return s,nil }
	}
	return "",syscall.ENOENT
}
func (dir *Directory) Insert(s, id string) error {
	for i := int64(0) ; i<dir.F.Pages ; i++ {
		println(i,dir.F.Pages)
		l,_ := dir.load(i)
		if len(l)>=MAXDIR { continue }
		l = append(l,[]string{s,id})
		return dir.save(i,l)
	}
	dir.F.Pages++
	e := SaveMeta(dir.R,dir.F)
	if e!=nil { return e }
	return dir.save(dir.F.Pages-1,[][]string{[]string{s,id}})
}
func (dir *Directory) ListUp() (r [][]string) {
	for i := int64(0) ; i<dir.F.Pages ; i++ {
		l,_ := dir.load(i)
		r = append(r,l...)
	}
	return
}

<commit_msg>remove annoying println<commit_after>/*
   Copyright 2016 Simon Schmidt

   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 joinf

import "github.com/maxymania/metaclusterfs/resource"
import "io"
import "syscall"
import "strconv"
import "encoding/gob"
import "encoding/csv"
import "errors"
import "bytes"

type DirPage struct{
	Version int64
}
func LoadDPs(r *resource.Resource, part string) (*DirPage,error) {
	m,e := r.Open(part+"inf")
	if e!=nil { return nil,e }
	f := new(DirPage)
	defer m.Close()
	dec := gob.NewDecoder(io.NewSectionReader(m,0,MB64))
	e = dec.Decode(f)
	return f,e
}
func SaveDPs(r *resource.Resource,f *DirPage, part string) error {
	if f==nil { return errors.New("BARF!") }
	m,e := r.Create(part+"inf")
	if e!=nil { return e }
	defer m.Close()
	b := new(bytes.Buffer)
	enc := gob.NewEncoder(b)
	e = enc.Encode(f)
	if e!=nil { return e }
	_,e = m.WriteAt(b.Bytes(),0)
	return e
}

const MAXDIR = 1<<10

func CreateDir(r *resource.Resource) error {
	m,e := LoadMeta(r)
	if e!=nil { m = new(FileMetadata) }
	m.IsDir = true
	return SaveMeta(r,m)
}

type Directory struct{
	R *resource.Resource
	F *FileMetadata
}
func (dir *Directory) load(i int64) ([][]string,error) {
	part := strconv.FormatInt(i,10)+"."
	p,e := LoadDPs(dir.R,part)
	if e!=nil { return nil,e }
	pver := part+strconv.FormatInt(p.Version,10)
	f,e := dir.R.Open(pver)
	if e!=nil { return nil,e }
	defer f.Close()
	s,e := f.Stat()
	if e!=nil { return nil,e }
	nr := csv.NewReader(io.NewSectionReader(f,0,s.Size()))
	return nr.ReadAll()
}
func (dir *Directory) save(i int64,l [][]string) error {
	b := new(bytes.Buffer)
	w := csv.NewWriter(b)
	w.WriteAll(l)
	w.Flush()

	// done!

	part := strconv.FormatInt(i,10)+"."
	p,e := LoadDPs(dir.R,part)
	if e!=nil { p = new(DirPage); e=nil }
	p.Version = ( p.Version + 1 ) % 8
	e = SaveDPs(dir.R,p,part)
	if e!=nil { return e }
	pver := part+strconv.FormatInt(p.Version,10)
	f,e := dir.R.Create(pver)
	if e!=nil { return e }
	defer f.Close()
	e = f.Truncate(int64(b.Len() ))
	if e!=nil { return e }
	_,e = f.WriteAt(b.Bytes(),0)
	return e
}
func (dir *Directory) find(i int64,s string) (string,error) {
	l,e := dir.load(i)
	if e!=nil { return "",e }
	for _,row := range l {
		if len(row)<2 { continue }
		if row[0]==s { return row[1],nil }
	}
	return "",nil
}
func (dir *Directory) Find(s string) (string,error) {
	for i := int64(0) ; i<dir.F.Pages ; i++ {
		s,e := dir.find(i,s)
		if e!=nil { return "",e }
		if s!="" { return s,nil }
	}
	return "",syscall.ENOENT
}
func (dir *Directory) delete(i int64,s string) (string,error) {
	l,e := dir.load(i)
	if e!=nil { return "",e }
	for j,row := range l {
		if len(row)<2 { continue }
		if row[0]==s {
			r := row[1]
			copy(l[j:],l[j+1:])
			l = l[:len(l)-1]
			dir.save(i,l)
			return r,nil
		}
	}
	return "",nil
}
func (dir *Directory) Delete(s string) (string,error) {
	for i := int64(0) ; i<dir.F.Pages ; i++ {
		s,e := dir.delete(i,s)
		if e!=nil { return "",e }
		if s!="" { return s,nil }
	}
	return "",syscall.ENOENT
}
func (dir *Directory) Insert(s, id string) error {
	for i := int64(0) ; i<dir.F.Pages ; i++ {
		l,_ := dir.load(i)
		if len(l)>=MAXDIR { continue }
		l = append(l,[]string{s,id})
		return dir.save(i,l)
	}
	dir.F.Pages++
	e := SaveMeta(dir.R,dir.F)
	if e!=nil { return e }
	return dir.save(dir.F.Pages-1,[][]string{[]string{s,id}})
}
func (dir *Directory) ListUp() (r [][]string) {
	for i := int64(0) ; i<dir.F.Pages ; i++ {
		l,_ := dir.load(i)
		r = append(r,l...)
	}
	return
}

<|endoftext|>


<commit_before>// +build !darwin,!freebsd,!linux,!openbsd,!netbsd,!dragonfly

package libedit

import (
	"bufio"
	"os"
)

type state struct {
	reader                *bufio.Reader
	promptGenLeft         LeftPromptGenerator
	line                  string
	stdin, stdout, stderr *os.File
}

var editors []state

func InitFiles(stdin, stdout, stderr *os.File) (EditLine, error) {
	st := state{
		reader: bufio.NewReader(stdin),
		stdin:  stdin, stdout: stdout, stderr: stderr,
	}
	editors = append(editors, st)
	return EditLine(len(editors) - 1), nil
}

func (el EditLine) Close()                                {}
func (el EditLine) SaveHistory() error                    { return nil }
func (el EditLine) AddHistory(_ string) error             { return nil }
func (el EditLine) LoadHistory(_ string) error            { return nil }
func (el EditLine) SetAutoSaveHistory(_ string, _ bool)   {}
func (el EditLine) UseHistory(_ int, _ bool) error        { return nil }
func (el EditLine) SetCompleter(_ CompletionGenerator)    {}
func (el EditLine) SetLeftPrompt(_ LeftPromptGenerator)   {}
func (el EditLine) SetRightPrompt(_ RightPromptGenerator) {}

func (el EditLine) Stdin() *os.File {
	return editors[el].stdin
}

func (el EditLine) Stdout() *os.File {
	return editors[el].stdout
}

func (el EditLine) Stderr() *os.File {
	return editors[el].stderr
}

func (el EditLine) GetLineInfo() (string, int) {
	return el.line, len(el.line)
}

func (el EditLine) GetLine() (string, error) {
	st := &editors[el]
	if st.promptGenLeft != nil {
		st.stdout.WriteString(st.promptGenLeft.GetLeftPrompt())
		st.stdout.Sync()
	}
	line, err := st.reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	st.line = line
	return st.line, nil
}
<commit_msg>Add a misisng interface.<commit_after>// +build !darwin,!freebsd,!linux,!openbsd,!netbsd,!dragonfly

package libedit

import (
	"bufio"
	"os"
)

type state struct {
	reader                *bufio.Reader
	promptGenLeft         LeftPromptGenerator
	line                  string
	stdin, stdout, stderr *os.File
}

var editors []state

func Init(x string) (EditLine, error) {
	return InitFiles(x, os.Stdin, os.Stdout, os.Stderr)
}

func InitFiles(_ string, stdin, stdout, stderr *os.File) (EditLine, error) {
	st := state{
		reader: bufio.NewReader(stdin),
		stdin:  stdin, stdout: stdout, stderr: stderr,
	}
	editors = append(editors, st)
	return EditLine(len(editors) - 1), nil
}

func (el EditLine) Close()                                {}
func (el EditLine) SaveHistory() error                    { return nil }
func (el EditLine) AddHistory(_ string) error             { return nil }
func (el EditLine) LoadHistory(_ string) error            { return nil }
func (el EditLine) SetAutoSaveHistory(_ string, _ bool)   {}
func (el EditLine) UseHistory(_ int, _ bool) error        { return nil }
func (el EditLine) SetCompleter(_ CompletionGenerator)    {}
func (el EditLine) SetLeftPrompt(_ LeftPromptGenerator)   {}
func (el EditLine) SetRightPrompt(_ RightPromptGenerator) {}

func (el EditLine) Stdin() *os.File {
	return editors[el].stdin
}

func (el EditLine) Stdout() *os.File {
	return editors[el].stdout
}

func (el EditLine) Stderr() *os.File {
	return editors[el].stderr
}

func (el EditLine) GetLineInfo() (string, int) {
	return el.line, len(el.line)
}

func (el EditLine) GetLine() (string, error) {
	st := &editors[el]
	if st.promptGenLeft != nil {
		st.stdout.WriteString(st.promptGenLeft.GetLeftPrompt())
		st.stdout.Sync()
	}
	line, err := st.reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	st.line = line
	return st.line, nil
}
<|endoftext|>


<commit_before>package handlers

import (
	"encoding/json"
	"log"
	"net/http"
	"straitjacket/engine"
)

type ExecutionResult struct {
	Stdout     string `json:"stdout"`
	Stderr     string `json:"stderr"`
	ExitStatus int    `json:"exit_status"`
	Time       string `json:"time"`
	Error      string `json:"error"`
}

func ExecuteHandler(res http.ResponseWriter, req *http.Request) {
	req.ParseForm()

	languageName := req.PostFormValue("language")
	source := req.PostFormValue("source")
	stdin := req.PostFormValue("stdin")
	timelimit := req.PostFormValue("timelimit")

	log.Println(languageName, source, stdin, timelimit)

	language, err := engine.TheEngine.FindLanguage(languageName)
	if err != nil {
		panic(err)
	}

	runResult, err := language.Run(&engine.RunOptions{
		Source: source,
		Stdin:  stdin,
	})
	if err != nil {
		panic(err)
	}

	result := ExecutionResult{
		Stdout:     runResult.Stdout,
		Stderr:     runResult.Stderr,
		ExitStatus: runResult.ExitCode,
	}
	json, err := json.Marshal(result)
	if err != nil {
		panic(err)
	}

	res.Header().Set("Content-Type", "application/json")
	_, err = res.Write(json)
	if err != nil {
		panic(err)
	}
}
<commit_msg>fix reading multipart form values so curl works<commit_after>package handlers

import (
	"encoding/json"
	"log"
	"net/http"
	"straitjacket/engine"
)

type ExecutionResult struct {
	Stdout     string `json:"stdout"`
	Stderr     string `json:"stderr"`
	ExitStatus int    `json:"exit_status"`
	Time       string `json:"time"`
	Error      string `json:"error"`
}

func ExecuteHandler(res http.ResponseWriter, req *http.Request) {
	languageName := req.FormValue("language")
	source := req.FormValue("source")
	stdin := req.FormValue("stdin")
	timelimit := req.FormValue("timelimit")

	log.Println(languageName, source, stdin, timelimit)

	language, err := engine.TheEngine.FindLanguage(languageName)
	if err != nil {
		panic(err)
	}

	runResult, err := language.Run(&engine.RunOptions{
		Source: source,
		Stdin:  stdin,
	})
	if err != nil {
		panic(err)
	}

	result := ExecutionResult{
		Stdout:     runResult.Stdout,
		Stderr:     runResult.Stderr,
		ExitStatus: runResult.ExitCode,
	}
	json, err := json.Marshal(result)
	if err != nil {
		panic(err)
	}

	res.Header().Set("Content-Type", "application/json")
	_, err = res.Write(json)
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package handlers

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

	"github.com/golang/glog"
	"github.com/zefer/mothership/mpd"
)

type FileListEntry struct {
	Path         string `json:"path"`
	Type         string `json:"type"`
	Base         string `json:"base"`
	LastModified string `json:"lastModified"`
}

type ByDate []*FileListEntry
type ByName []*FileListEntry

func (a ByDate) Len() int           { return len(a) }
func (a ByDate) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByDate) Less(i, j int) bool { return a[i].LastModified < a[j].LastModified }

func (a ByName) Len() int           { return len(a) }
func (a ByName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByName) Less(i, j int) bool { return a[i].Path < a[j].Path }

func FileListHandler(c *mpd.Client) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "GET" {
			w.WriteHeader(http.StatusMethodNotAllowed)
		}
		data, err := c.C.ListInfo(r.FormValue("uri"))
		if err != nil {
			glog.Errorln(err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		out := make([]*FileListEntry, len(data))
		for i, item := range data {
			for _, t := range []string{"file", "directory", "playlist"} {
				if p, ok := item[t]; ok {
					out[i] = &FileListEntry{
						Path:         p,
						Type:         t,
						Base:         path.Base(p),
						LastModified: item["last-modified"],
					}
					break
				}
			}
		}

		// Sort the list by the specified field and direction.
		s := r.FormValue("sort")
		d := r.FormValue("direction")
		if s == "date" {
			if d == "desc" {
				sort.Sort(sort.Reverse(ByDate(out)))
			} else {
				sort.Sort(ByDate(out))
			}
		} else {
			if d == "desc" {
				sort.Sort(sort.Reverse(ByName(out)))
			} else {
				sort.Sort(ByName(out))
			}
		}

		b, err := json.Marshal(out)
		w.Header().Add("Content-Type", "application/json")
		fmt.Fprint(w, string(b))
	})
}

func LibraryUpdateHandler(c *mpd.Client) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "PUT" && r.Method != "POST" {
			w.WriteHeader(http.StatusMethodNotAllowed)
			return
		}
		// Parse the JSON body.
		decoder := json.NewDecoder(r.Body)
		var params map[string]interface{}
		err := decoder.Decode(&params)
		if err != nil {
			glog.Errorln(err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		uri := params["uri"].(string)
		if uri == "" {
			w.WriteHeader(http.StatusBadRequest)
			return
		}
		_, err = c.C.Update(uri)
		if err != nil {
			glog.Errorln(err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.WriteHeader(http.StatusOK)
		return
	})
}
<commit_msg>refactor to reduce nesting<commit_after>package handlers

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

	"github.com/golang/glog"
	"github.com/zefer/mothership/mpd"
)

type FileListEntry struct {
	Path         string `json:"path"`
	Type         string `json:"type"`
	Base         string `json:"base"`
	LastModified string `json:"lastModified"`
}

type ByDate []*FileListEntry
type ByName []*FileListEntry

func (a ByDate) Len() int           { return len(a) }
func (a ByDate) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByDate) Less(i, j int) bool { return a[i].LastModified < a[j].LastModified }

func (a ByName) Len() int           { return len(a) }
func (a ByName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByName) Less(i, j int) bool { return a[i].Path < a[j].Path }

func FileListHandler(c *mpd.Client) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "GET" {
			w.WriteHeader(http.StatusMethodNotAllowed)
		}
		data, err := c.C.ListInfo(r.FormValue("uri"))
		if err != nil {
			glog.Errorln(err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		out := make([]*FileListEntry, len(data))
		for i, item := range data {
			for _, t := range []string{"file", "directory", "playlist"} {
				if p, ok := item[t]; ok {
					out[i] = &FileListEntry{
						Path:         p,
						Type:         t,
						Base:         path.Base(p),
						LastModified: item["last-modified"],
					}
					break
				}
			}
		}

		// Sort the list by the specified field and direction.
		s := r.FormValue("sort")
		d := r.FormValue("direction")
		var t sort.Interface
		// Sort by date or name?
		if s == "date" {
			t = ByDate(out)
		} else {
			t = ByName(out)
		}
		// Sort ascending or descending?
		if d == "desc" {
			sort.Sort(sort.Reverse(t))
		} else {
			sort.Sort(t)
		}

		b, err := json.Marshal(out)
		w.Header().Add("Content-Type", "application/json")
		fmt.Fprint(w, string(b))
	})
}

func LibraryUpdateHandler(c *mpd.Client) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "PUT" && r.Method != "POST" {
			w.WriteHeader(http.StatusMethodNotAllowed)
			return
		}
		// Parse the JSON body.
		decoder := json.NewDecoder(r.Body)
		var params map[string]interface{}
		err := decoder.Decode(&params)
		if err != nil {
			glog.Errorln(err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		uri := params["uri"].(string)
		if uri == "" {
			w.WriteHeader(http.StatusBadRequest)
			return
		}
		_, err = c.C.Update(uri)
		if err != nil {
			glog.Errorln(err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.WriteHeader(http.StatusOK)
		return
	})
}
<|endoftext|>