<commit_before>package io

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime/pprof"
	"strings"
	"time"
)

type TestCaseFunc func(*Input, *Output)

type Parser struct {
	f             TestCaseFunc
	input         *Input
	output        *Output
	compareOutput *CompareOutput

	inputFn   string
	outputFn  string
	correctFn string
	profileFn string
}

func TestCases(f TestCaseFunc) {
	log.SetFlags(0)

	parser := Parser{
		f: f,
	}

	if len(os.Args) < 2 {
		log.Fatalln("You need to specify at least one input file")
	}
	for _, inputFn := range os.Args[1:] {
		parser.SetFn(inputFn)
		parser.ParseFile()
	}
}

func (parser *Parser) SetFn(inputFn string) {
	parser.inputFn = inputFn
	baseFn := strings.TrimSuffix(inputFn, ".in")
	parser.outputFn = baseFn + ".out"
	parser.correctFn = baseFn + ".correct"
	parser.profileFn = baseFn + ".prof"
}

func (parser *Parser) formatDuration(d int64) string {
	var i int
	df := float64(d)
	units := []string{"ns", "us", "ms", "s"}
	for i = 0; df >= 1000; i++ {
		df /= 1000
		if i >= 3 {
			break
		}
	}
	res := fmt.Sprintf("%.2f%s", df, units[i])
	return res
}

func (parser *Parser) ParseFile() {
	inputF, err := os.Open(parser.inputFn)
	if err != nil {
		log.Fatalln("Error opening input file:", err)
	}
	defer inputF.Close()

	outputF, err := os.Create(parser.outputFn)
	if err != nil {
		log.Fatalln("Error creating output file:", err)
	}
	defer outputF.Close()

	scanner := bufio.NewScanner(inputF)
	scanner.Split(bufio.ScanWords)

	parser.output = newOutput(outputF)
	parser.input = newInput(scanner)

	parser.compareOutput = nil
	if _, err := os.Stat(parser.correctFn); err == nil {
		correctF, err := os.Open(parser.correctFn)
		if err != nil {
			log.Fatalln("Error opening correct file:", err)
		}
		defer correctF.Close()

		parser.compareOutput = NewCompareOutput(correctF)
	}

	T := parser.input.Int()

	startTime := time.Now().UnixNano()
	for i := 1; i <= T; i++ {
		parser.runTestCase(i)
	}
	log.Println("Total time:", parser.formatDuration(time.Now().UnixNano()-startTime))
}

func (parser *Parser) runTestCase(i int) {
	warningTimer := time.NewTimer(500 * time.Millisecond)
	startProfileTimer := time.NewTimer(1 * time.Second)
	stopProfileTimer := time.NewTimer(10 * time.Second)

	doneChan := make(chan bool)

	go func() {
		parser.output.init(parser.input, i)
		parser.input.init()

		parser.f(parser.input, parser.output)

		if parser.compareOutput != nil && parser.compareOutput.HasOutput(i) {
			parser.output.AssertEqual(string(parser.compareOutput.GetOutput(i)))
		}

		parser.output.flush()
		doneChan <- true
	}()

	var f *os.File
	var err error

loop:
	for {
		select {
		case <-warningTimer.C:
			parser.output.Debug("Long calculation")
		case <-startProfileTimer.C:
			f, err = os.Create(parser.profileFn)
			if err != nil {
				log.Fatalln("Error opening profile file:", err)
			}
			pprof.StartCPUProfile(f)
		case <-stopProfileTimer.C:
			pprof.StopCPUProfile()
			f = nil
			out, err := exec.Command("go", "tool", "pprof", "-top", os.Args[0], parser.profileFn).CombinedOutput()
			if err != nil {
				log.Fatalln("Error running profile tool:", err)
			}
			parser.output.Debug("CPUProfile:", string(out))
		case <-doneChan:
			break loop
		}
	}
	if f != nil {
		pprof.StopCPUProfile()
	}
}
<commit_msg>Also show pprof graph on very long calculation<commit_after>package io

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime/pprof"
	"strings"
	"time"
)

type TestCaseFunc func(*Input, *Output)

type Parser struct {
	f             TestCaseFunc
	input         *Input
	output        *Output
	compareOutput *CompareOutput

	inputFn   string
	outputFn  string
	correctFn string
	profileFn string
}

func TestCases(f TestCaseFunc) {
	log.SetFlags(0)

	parser := Parser{
		f: f,
	}

	if len(os.Args) < 2 {
		log.Fatalln("You need to specify at least one input file")
	}
	for _, inputFn := range os.Args[1:] {
		parser.SetFn(inputFn)
		parser.ParseFile()
	}
}

func (parser *Parser) SetFn(inputFn string) {
	parser.inputFn = inputFn
	baseFn := strings.TrimSuffix(inputFn, ".in")
	parser.outputFn = baseFn + ".out"
	parser.correctFn = baseFn + ".correct"
	parser.profileFn = baseFn + ".prof"
}

func (parser *Parser) formatDuration(d int64) string {
	var i int
	df := float64(d)
	units := []string{"ns", "us", "ms", "s"}
	for i = 0; df >= 1000; i++ {
		df /= 1000
		if i >= 3 {
			break
		}
	}
	res := fmt.Sprintf("%.2f%s", df, units[i])
	return res
}

func (parser *Parser) ParseFile() {
	inputF, err := os.Open(parser.inputFn)
	if err != nil {
		log.Fatalln("Error opening input file:", err)
	}
	defer inputF.Close()

	outputF, err := os.Create(parser.outputFn)
	if err != nil {
		log.Fatalln("Error creating output file:", err)
	}
	defer outputF.Close()

	scanner := bufio.NewScanner(inputF)
	scanner.Split(bufio.ScanWords)

	parser.output = newOutput(outputF)
	parser.input = newInput(scanner)

	parser.compareOutput = nil
	if _, err := os.Stat(parser.correctFn); err == nil {
		correctF, err := os.Open(parser.correctFn)
		if err != nil {
			log.Fatalln("Error opening correct file:", err)
		}
		defer correctF.Close()

		parser.compareOutput = NewCompareOutput(correctF)
	}

	T := parser.input.Int()

	startTime := time.Now().UnixNano()
	for i := 1; i <= T; i++ {
		parser.runTestCase(i)
	}
	log.Println("Total time:", parser.formatDuration(time.Now().UnixNano()-startTime))
}

func (parser *Parser) runTestCase(i int) {
	warningTimer := time.NewTimer(500 * time.Millisecond)
	startProfileTimer := time.NewTimer(1 * time.Second)
	stopProfileTimer := time.NewTimer(10 * time.Second)

	doneChan := make(chan bool)

	go func() {
		parser.output.init(parser.input, i)
		parser.input.init()

		parser.f(parser.input, parser.output)

		if parser.compareOutput != nil && parser.compareOutput.HasOutput(i) {
			parser.output.AssertEqual(string(parser.compareOutput.GetOutput(i)))
		}

		parser.output.flush()
		doneChan <- true
	}()

	var f *os.File
	var err error

loop:
	for {
		select {
		case <-warningTimer.C:
			parser.output.Debug("Long calculation")
		case <-startProfileTimer.C:
			f, err = os.Create(parser.profileFn)
			if err != nil {
				log.Fatalln("Error opening profile file:", err)
			}
			pprof.StartCPUProfile(f)
		case <-stopProfileTimer.C:
			pprof.StopCPUProfile()
			f = nil
			out, err := exec.Command("go", "tool", "pprof", "-top", os.Args[0], parser.profileFn).CombinedOutput()
			if err != nil {
				log.Fatalln("Error running profile tool:", err)
			}
			parser.output.Debug("CPUProfile:", string(out))

			err = exec.Command("go", "tool", "pprof", "-web", os.Args[0], parser.profileFn).Start()
			if err != nil {
				log.Fatalln("Error running profile tool:", err)
			}
		case <-doneChan:
			break loop
		}
	}
	if f != nil {
		pprof.StopCPUProfile()
	}
}
<|endoftext|>


<commit_before>package catTracks

//Handles
import (
	"bytes"
	"encoding/csv"
	"encoding/json"
	"fmt"
	// "html/template"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"

	"github.com/rotblauer/tileTester2/note"
	"github.com/rotblauer/trackpoints/trackPoint"
	"log"
	// "os"
	// "path"
)

// // the html stuff of this thing
// var templates = func() *template.Template {
// 	// p := path.Join(os.Getenv("GOPATH"), "src", "github.com", "rotblauer", "catTracks", "templates")
// 	// if _, err := os.Stat(p); err != nil {
// 	p := "templates"
// 	// }
// 	p = path.Join(p, "*.html")
// 	// p := path.Join(os.Getenv("GOPATH"), "src", "github.com", "rotblauer", "catTracks", "templates", "*.html")
// 	// p := path.Join(os.Getenv("GOPATH"), "src", "github.com", "rotblauer", "catTracks", "templates", "*.html")
// 	return template.Must(template.ParseGlob(p))
// }()

//W// elcome, loads and servers all (currently) data pointers
// func getIndexTemplate(w http.ResponseWriter, r *http.Request) {
// 	templates.ExecuteTemplate(w, "base", nil)
// }
// func getRaceTemplate(w http.ResponseWriter, r *http.Request) {
// 	templates.ExecuteTemplate(w, "race", nil)
// }
// func getMapTemplate(w http.ResponseWriter, r *http.Request) {
// 	templates.ExecuteTemplate(w, "map", nil)
// }
// func getLeafTemplate(w http.ResponseWriter, r *http.Request) {
// 	templates.ExecuteTemplate(w, "leaf", nil)
// }

func socket(w http.ResponseWriter, r *http.Request) {
	// see ./socket.go
	GetMelody().HandleRequest(w, r)
}

func getRaceJSON(w http.ResponseWriter, r *http.Request) {
	var e error

	var renderer = make(map[string]interface{})
	var spans = map[string]int{
		"today": 1,
		"week":  7,
		"all":   10,
	}

	for span, spanVal := range spans {
		renderer[span], e = buildTimePeriodStats(spanVal)
		if e != nil {
			fmt.Println(e)
			http.Error(w, e.Error(), http.StatusInternalServerError)
		}
	}

	buf, e := json.Marshal(renderer)
	if e != nil {
		fmt.Println(e)
		http.Error(w, e.Error(), http.StatusInternalServerError)
	}
	w.Write(buf)
}

func getPointsJSON(w http.ResponseWriter, r *http.Request) {
	query := parseQuery(r, w)

	data, eq := getData(query)
	if eq != nil {
		http.Error(w, eq.Error(), http.StatusInternalServerError)
	}
	fmt.Println("Receive ajax get data string ")
	w.Write(data)
}
func getData(query *query) ([]byte, error) {
	var data []byte
	allPoints, e := getPointsQT(query)
	if e != nil {
		return data, e
	}
	data, err := json.Marshal(allPoints)
	if err != nil {
		return data, err
	}
	return data, nil
}

var backlogPopulators [][]byte

// > https://stackoverflow.com/questions/24455147/how-do-i-send-a-json-string-in-a-post-request-in-go
// url := "http://restapi3.apiary.io/notes"
// fmt.Println("URL:>", url)

// var jsonStr = []byte(`{"title":"Buy cheese and bread for breakfast."}`)
// req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
// req.Header.Set("X-Custom-Header", "myvalue")
// req.Header.Set("Content-Type", "application/json")

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

// fmt.Println("response Status:", resp.Status)
// fmt.Println("response Headers:", resp.Header)
// body, _ := ioutil.ReadAll(resp.Body)
// fmt.Println("response Body:", string(body))
func handleForwardPopulate(bod []byte) (err error) {

	if forwardPopulate == "" {
		log.Println("no forward url, not forwarding")
		return
	}

	backlogPopulators = append(backlogPopulators, bod)

	log.Println("forwarding to:", forwardPopulate, "#reqs:", len(backlogPopulators))

	var index int
	client := &http.Client{}

	for i, body := range backlogPopulators {
		index = i
		req, e := http.NewRequest("POST", forwardPopulate, bytes.NewBuffer(body))
		if e != nil {
			err = e
			break
		}
		req.Header.Set("Content-Type", "application/json")
		resp, e := client.Do(req)
		if e != nil {
			err = e
			break
		}
		err = resp.Body.Close()
		if err != nil {
			break
		}
	}

	if err == nil {
		backlogPopulators = [][]byte{}
	} else {
		backlogPopulators = backlogPopulators[index:]
	}

	return
}

var iftttWebhoook = "https://maker.ifttt.com/trigger/any_cat_visit/with/key/A_haNpM4rcpvsNYLFAy-8"

type IftttBodyCatVisit struct {
	Name    string `json:"value1"`
	Place   string `json:"value2"`
	MapsURL string `json:"value3"` // catonmap.net/{{value3}}
}

func populatePoints(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")

	log.Println("handling pop:", r)

	var trackPoints trackPoint.TrackPoints

	var bod []byte
	var err error
	if forwardPopulate != "" {
		bod, err = ioutil.ReadAll(r.Body)
		// bod := []byte{}
		// n, err :=
		if err != nil {
			log.Println("err reading body", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		// log.Println("read body ok, read nbytes=", len(bod))
		log.Println("read body ok, read nbytes=", len(bod))
		// log.Println("bod=", string(bod))
		// And now set a new body, which will simulate the same data we read:
		// > https://stackoverflow.com/questions/43021058/golang-read-request-body#43021236
		r.Body = ioutil.NopCloser(bytes.NewBuffer(bod))
	}

	if r.Body == nil {
		log.Println("error: body nil")
		http.Error(w, "Please send a request body", 500)
		return
	}
	err = json.NewDecoder(r.Body).Decode(&trackPoints)
	if err != nil {
		log.Println("error: decode json")
		http.Error(w, err.Error(), 400)
		return
	}

	// goroutine keeps http req from blocking while points are processed
	go func() {
		errS := storePoints(trackPoints)
		if errS != nil {
			log.Println("store err:", errS)
			// http.Error(w, errS.Error(), http.StatusInternalServerError)
			return
		}
		log.Println("stored trackpoints", "len:", trackPoints.Len())
	}()

	// return empty json of empty trackpoints to not have to download tons of shit
	if errW := json.NewEncoder(w).Encode(&trackPoint.TrackPoints{}); errW != nil {
		log.Println("respond write err:", errW)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	// if --forward-populate set, then make POST to set urls
	// --forward-populate=[]string{<downstream.urls.that.wants.points/put/em/here>}
	// goroutine keeps this request from block while pending this outgoing request
	// this keeps an original POST from being dependent on a forward POST
	go func() {
		if err := handleForwardPopulate(bod); err != nil {
			log.Println("forward populate error: ", err)
			// this just to persist any request that fails in case this process is terminated (backlogs are stored in mem)
			ioutil.WriteFile(fmt.Sprintf("dfp-%d", time.Now().UnixNano()), bod, 0666)
		} else {
			log.Println("forward populate finished OK")
		}
	}()

	for _, t := range trackPoints {
		if ns, e := note.NotesField(t.Notes).AsNoteStructured(); e == nil {
			if ns.HasValidVisit() {
				info := IftttBodyCatVisit{
					Name:  t.Name,
					Place: ns.Visit.Place,
					// x = lat, y = long
					MapsURL: fmt.Sprintf("?z=%d&x=%d&y=%d&t=tile-dark&l=recent&s=", 14, t.Lat, t.Lng),
				}
				b, e := json.Marshal(info)
				if e != nil {
					log.Println("err marshal visit", e)
					return
				}
				go http.Post(iftttWebhoook, "application/json", bytes.NewBuffer(b))
			}
		}
	}
}

func uploadCSV(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(32 << 30)
	file, _, err := r.FormFile("uploadfile")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer file.Close()

	lines, err := csv.NewReader(file).ReadAll()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	for _, line := range lines {
		var tp trackPoint.TrackPoint

		tp.Name = line[0]

		if tp.Time, err = time.Parse(time.UnixDate, line[1]); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if tp.Lat, err = strconv.ParseFloat(line[2], 64); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if tp.Lng, err = strconv.ParseFloat(line[3], 64); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		errS := storePoint(tp)
		if errS != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

	}

	http.Redirect(w, r, "/", 302) //the 300

}

func getLastKnown(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Access-Control-Allow-Origin", "*")
	b, e := getLastKnownData()
	//b, e := json.Marshal(lastKnownMap)
	if e != nil {
		log.Println(e)
		http.Error(w, e.Error(), http.StatusInternalServerError)
	}
	fmt.Println("Got lastknown:", len(b), "bytes")
	w.Write(b)
}

func getMetaData(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Access-Control-Allow-Origin", "*")

	b, e := getmetadata()
	if e != nil {
		log.Println(e)
		http.Error(w, e.Error(), http.StatusInternalServerError)
	}
	fmt.Println("Got metadata:", len(b), "bytes")
	w.Write(b)
}
<commit_msg>:floppy_disk:<commit_after>package catTracks

//Handles
import (
	"bytes"
	"encoding/csv"
	"encoding/json"
	"fmt"
	// "html/template"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"

	"github.com/rotblauer/tileTester2/note"
	"github.com/rotblauer/trackpoints/trackPoint"
	"log"
	// "os"
	// "path"
)

// // the html stuff of this thing
// var templates = func() *template.Template {
// 	// p := path.Join(os.Getenv("GOPATH"), "src", "github.com", "rotblauer", "catTracks", "templates")
// 	// if _, err := os.Stat(p); err != nil {
// 	p := "templates"
// 	// }
// 	p = path.Join(p, "*.html")
// 	// p := path.Join(os.Getenv("GOPATH"), "src", "github.com", "rotblauer", "catTracks", "templates", "*.html")
// 	// p := path.Join(os.Getenv("GOPATH"), "src", "github.com", "rotblauer", "catTracks", "templates", "*.html")
// 	return template.Must(template.ParseGlob(p))
// }()

//W// elcome, loads and servers all (currently) data pointers
// func getIndexTemplate(w http.ResponseWriter, r *http.Request) {
// 	templates.ExecuteTemplate(w, "base", nil)
// }
// func getRaceTemplate(w http.ResponseWriter, r *http.Request) {
// 	templates.ExecuteTemplate(w, "race", nil)
// }
// func getMapTemplate(w http.ResponseWriter, r *http.Request) {
// 	templates.ExecuteTemplate(w, "map", nil)
// }
// func getLeafTemplate(w http.ResponseWriter, r *http.Request) {
// 	templates.ExecuteTemplate(w, "leaf", nil)
// }

func socket(w http.ResponseWriter, r *http.Request) {
	// see ./socket.go
	GetMelody().HandleRequest(w, r)
}

func getRaceJSON(w http.ResponseWriter, r *http.Request) {
	var e error

	var renderer = make(map[string]interface{})
	var spans = map[string]int{
		"today": 1,
		"week":  7,
		"all":   10,
	}

	for span, spanVal := range spans {
		renderer[span], e = buildTimePeriodStats(spanVal)
		if e != nil {
			fmt.Println(e)
			http.Error(w, e.Error(), http.StatusInternalServerError)
		}
	}

	buf, e := json.Marshal(renderer)
	if e != nil {
		fmt.Println(e)
		http.Error(w, e.Error(), http.StatusInternalServerError)
	}
	w.Write(buf)
}

func getPointsJSON(w http.ResponseWriter, r *http.Request) {
	query := parseQuery(r, w)

	data, eq := getData(query)
	if eq != nil {
		http.Error(w, eq.Error(), http.StatusInternalServerError)
	}
	fmt.Println("Receive ajax get data string ")
	w.Write(data)
}
func getData(query *query) ([]byte, error) {
	var data []byte
	allPoints, e := getPointsQT(query)
	if e != nil {
		return data, e
	}
	data, err := json.Marshal(allPoints)
	if err != nil {
		return data, err
	}
	return data, nil
}

var backlogPopulators [][]byte

// > https://stackoverflow.com/questions/24455147/how-do-i-send-a-json-string-in-a-post-request-in-go
// url := "http://restapi3.apiary.io/notes"
// fmt.Println("URL:>", url)

// var jsonStr = []byte(`{"title":"Buy cheese and bread for breakfast."}`)
// req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
// req.Header.Set("X-Custom-Header", "myvalue")
// req.Header.Set("Content-Type", "application/json")

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

// fmt.Println("response Status:", resp.Status)
// fmt.Println("response Headers:", resp.Header)
// body, _ := ioutil.ReadAll(resp.Body)
// fmt.Println("response Body:", string(body))
func handleForwardPopulate(bod []byte) (err error) {

	if forwardPopulate == "" {
		log.Println("no forward url, not forwarding")
		return
	}

	backlogPopulators = append(backlogPopulators, bod)

	log.Println("forwarding to:", forwardPopulate, "#reqs:", len(backlogPopulators))

	var index int
	client := &http.Client{}

	for i, body := range backlogPopulators {
		index = i
		req, e := http.NewRequest("POST", forwardPopulate, bytes.NewBuffer(body))
		if e != nil {
			err = e
			break
		}
		req.Header.Set("Content-Type", "application/json")
		resp, e := client.Do(req)
		if e != nil {
			err = e
			break
		}
		err = resp.Body.Close()
		if err != nil {
			break
		}
	}

	if err == nil {
		backlogPopulators = [][]byte{}
	} else {
		backlogPopulators = backlogPopulators[index:]
	}

	return
}

var iftttWebhoook = "https://maker.ifttt.com/trigger/any_cat_visit/with/key/A_haNpM4rcpvsNYLFAy-8"

type IftttBodyCatVisit struct {
	Name    string `json:"value1"`
	Place   string `json:"value2"`
	MapsURL string `json:"value3"` // catonmap.net/{{value3}}
}

func populatePoints(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")

	log.Println("handling pop:", r)

	var trackPoints trackPoint.TrackPoints

	var bod []byte
	var err error
	if forwardPopulate != "" {
		bod, err = ioutil.ReadAll(r.Body)
		// bod := []byte{}
		// n, err :=
		if err != nil {
			log.Println("err reading body", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		// log.Println("read body ok, read nbytes=", len(bod))
		log.Println("read body ok, read nbytes=", len(bod))
		// log.Println("bod=", string(bod))
		// And now set a new body, which will simulate the same data we read:
		// > https://stackoverflow.com/questions/43021058/golang-read-request-body#43021236
		r.Body = ioutil.NopCloser(bytes.NewBuffer(bod))
	}

	if r.Body == nil {
		log.Println("error: body nil")
		http.Error(w, "Please send a request body", 500)
		return
	}
	err = json.NewDecoder(r.Body).Decode(&trackPoints)
	if err != nil {
		log.Println("error: decode json")
		http.Error(w, err.Error(), 400)
		return
	}

	// goroutine keeps http req from blocking while points are processed
	go func() {
		errS := storePoints(trackPoints)
		if errS != nil {
			log.Println("store err:", errS)
			// http.Error(w, errS.Error(), http.StatusInternalServerError)
			return
		}
		log.Println("stored trackpoints", "len:", trackPoints.Len())
	}()

	// return empty json of empty trackpoints to not have to download tons of shit
	if errW := json.NewEncoder(w).Encode(&trackPoint.TrackPoints{}); errW != nil {
		log.Println("respond write err:", errW)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	// if --forward-populate set, then make POST to set urls
	// --forward-populate=[]string{<downstream.urls.that.wants.points/put/em/here>}
	// goroutine keeps this request from block while pending this outgoing request
	// this keeps an original POST from being dependent on a forward POST
	go func() {
		if err := handleForwardPopulate(bod); err != nil {
			log.Println("forward populate error: ", err)
			// this just to persist any request that fails in case this process is terminated (backlogs are stored in mem)
			ioutil.WriteFile(fmt.Sprintf("dfp-%d", time.Now().UnixNano()), bod, 0666)
		} else {
			log.Println("forward populate finished OK")
		}
	}()

	for _, t := range trackPoints {
		if ns, e := note.NotesField(t.Notes).AsNoteStructured(); e == nil {
			if ns.HasValidVisit() {
				info := IftttBodyCatVisit{
					Name:  t.Name,
					Place: ns.Visit.Place,
					// x = lat, y = long
					MapsURL: fmt.Sprintf("?z=%d&x=%d&y=%d&t=tile-dark&l=recent&s=", 14, t.Lat, t.Lng),
				}
				b, e := json.Marshal(info)
				if e != nil {
					log.Println("err marshal visit", e)
					return
				}
				log.Println("sending ifttt webhook", "url=", iftttWebhoook, "info=", info)
				go http.Post(iftttWebhoook, "application/json", bytes.NewBuffer(b))
			}
		}
	}
}

func uploadCSV(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(32 << 30)
	file, _, err := r.FormFile("uploadfile")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer file.Close()

	lines, err := csv.NewReader(file).ReadAll()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	for _, line := range lines {
		var tp trackPoint.TrackPoint

		tp.Name = line[0]

		if tp.Time, err = time.Parse(time.UnixDate, line[1]); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if tp.Lat, err = strconv.ParseFloat(line[2], 64); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if tp.Lng, err = strconv.ParseFloat(line[3], 64); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		errS := storePoint(tp)
		if errS != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

	}

	http.Redirect(w, r, "/", 302) //the 300

}

func getLastKnown(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Access-Control-Allow-Origin", "*")
	b, e := getLastKnownData()
	//b, e := json.Marshal(lastKnownMap)
	if e != nil {
		log.Println(e)
		http.Error(w, e.Error(), http.StatusInternalServerError)
	}
	fmt.Println("Got lastknown:", len(b), "bytes")
	w.Write(b)
}

func getMetaData(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Access-Control-Allow-Origin", "*")

	b, e := getmetadata()
	if e != nil {
		log.Println(e)
		http.Error(w, e.Error(), http.StatusInternalServerError)
	}
	fmt.Println("Got metadata:", len(b), "bytes")
	w.Write(b)
}
<|endoftext|>


<commit_before>// Package multierror defines an error Accumulator to contain multiple errors.
package multierror

import (
	"bytes"
	"fmt"
)

// Accumulator is an error accumulator.
//
// Usage:
//
//     var errors multierror.Accumulator
//     errors.Push(returnsErrOrNil())
//     errors.Push(returnsErrOrNil())
//     errors.Push(returnsErrOrNil())
//     return errors.Error()
type Accumulator []error

// Push adds an error to the Accumulator.  If err is nil, then Accumulator is
// not affected.
func (m *Accumulator) Push(err error) {
	if err == nil {
		return
	}
	// Check for a Accumulator
	if e, ok := err.(_error); ok {
		*m = append(*m, e...)
		return
	}

	*m = append(*m, err)
}

// Pushf adds a formatted error string to the Accumulator.  It is a shortcut
// for Push(fmt.Error(...)).
func (m *Accumulator) Pushf(fmtstr string, args ...interface{}) {
	*m = append(*m, fmt.Errorf(fmtstr, args...))
}

// Error returns the accumulated errors.  If no errors have been pushed onto the
// accumulator, then nil will be returned.
func (m *Accumulator) Error() error {
	if len(*m) == 0 {
		return nil
	}
	return _error(*m)
}

// String prints the accumulated errors or "nil" if no errors have been pushed.
func (m Accumulator) String() string {
	return _error(m).Error()
}

// This type implements the actual error interface.  This is separate from
// Accumulator so to avoid accidentally returning an interface to a nil pointer.
type _error []error

func (m _error) Error() string {
	if len(m) == 0 {
		return "nil"
	}
	if len(m) == 1 {
		return m[0].Error()
	}

	buf := &bytes.Buffer{}
	fmt.Fprintf(buf, "%d errors: [", len(m))
	for i, err := range m {
		if i != 0 {
			fmt.Fprint(buf, ", ")
		}
		fmt.Fprintf(buf, `"%v"`, err)
	}
	fmt.Fprint(buf, "]")
	return buf.String()
}
<commit_msg>If there's only 1 error, don't wrap that error.<commit_after>// Package multierror defines an error Accumulator to contain multiple errors.
package multierror

import (
	"bytes"
	"fmt"
)

// Accumulator is an error accumulator.
//
// Usage:
//
//     var errors multierror.Accumulator
//     errors.Push(returnsErrOrNil())
//     errors.Push(returnsErrOrNil())
//     errors.Push(returnsErrOrNil())
//     return errors.Error()
type Accumulator []error

// Push adds an error to the Accumulator.  If err is nil, then Accumulator is
// not affected.
func (m *Accumulator) Push(err error) {
	if err == nil {
		return
	}
	// Check for a Accumulator
	if e, ok := err.(_error); ok {
		*m = append(*m, e...)
		return
	}

	*m = append(*m, err)
}

// Pushf adds a formatted error string to the Accumulator.  It is a shortcut
// for Push(fmt.Error(...)).
func (m *Accumulator) Pushf(fmtstr string, args ...interface{}) {
	*m = append(*m, fmt.Errorf(fmtstr, args...))
}

// Error returns the accumulated errors.  If no errors have been pushed onto the
// accumulator, then nil will be returned.
func (m *Accumulator) Error() error {
	if len(*m) == 0 {
		return nil
	} else if len(*m) == 1 {
		return (*m)[0]
	}
	return _error(*m)
}

// String prints the accumulated errors or "nil" if no errors have been pushed.
func (m Accumulator) String() string {
	return _error(m).Error()
}

// This type implements the actual error interface.  This is separate from
// Accumulator so to avoid accidentally returning an interface to a nil pointer.
type _error []error

func (m _error) Error() string {
	if len(m) == 0 {
		return "nil"
	}
	if len(m) == 1 {
		return m[0].Error()
	}

	buf := &bytes.Buffer{}
	fmt.Fprintf(buf, "%d errors: [", len(m))
	for i, err := range m {
		if i != 0 {
			fmt.Fprint(buf, ", ")
		}
		fmt.Fprintf(buf, `"%v"`, err)
	}
	fmt.Fprint(buf, "]")
	return buf.String()
}
<|endoftext|>


<commit_before>package object

import (
	"bytes"
	"fmt"
	"hash/fnv"
	"io"
	"strconv"
	"strings"

	"github.com/nitrogen-lang/nitrogen/src/ast"
)

type ObjectType int

func (o ObjectType) String() string {
	return objectTypeNames[o]
}

// These are all the internal object types used in the interpreter
const (
	IntergerObj ObjectType = iota
	FloatObj
	BooleanObj
	NullObj
	ReturnObj
	ExceptionObj
	ErrorObj
	FunctionObj
	StringObj
	BuiltinObj
	ArrayObj
	HashObj
	LoopControlObj
	// ResourceObj can be used by modules to denote a generic resource. The implementation may be module specific.
	ResourceObj
	ModuleObj
	ClassObj
	InstanceObj
	BuiltinMethodObj
	BoundMethodObj
)

var objectTypeNames = map[ObjectType]string{
	IntergerObj:      "INTEGER",
	FloatObj:         "FLOAT",
	BooleanObj:       "BOOLEAN",
	NullObj:          "NULL",
	ReturnObj:        "RETURN",
	ExceptionObj:     "EXCEPTION",
	ErrorObj:         "ERROR",
	FunctionObj:      "FUNCTION",
	StringObj:        "STRING",
	BuiltinObj:       "BUILTIN",
	ArrayObj:         "ARRAY",
	HashObj:          "MAP",
	ResourceObj:      "RESOURCE",
	ModuleObj:        "MODULE",
	ClassObj:         "CLASS",
	InstanceObj:      "INSTANCE",
	BuiltinMethodObj: "BUILTIN METHOD",
	BoundMethodObj:   "BOUND METHOD",
}

const maxStaticInt = 255

// These are all constants in the language that can be represented with a single instance
var (
	NullConst  = &Null{}
	TrueConst  = &Boolean{Value: true}
	FalseConst = &Boolean{Value: false}
	staticInts [maxStaticInt + 1]*Integer
)

func init() {
	for i := 0; i <= maxStaticInt; i++ {
		staticInts[i] = &Integer{Value: int64(i)}
	}
}

type Interpreter interface {
	Eval(node ast.Node, env *Environment) Object
	GetCurrentScriptPath() string
	GetStdout() io.Writer
	GetStderr() io.Writer
	GetStdin() io.Reader
}

type BuiltinFunction func(i Interpreter, env *Environment, args ...Object) Object

type BuiltinMethodFunction func(i Interpreter, self *Instance, env *Environment, args ...Object) Object

type Object interface {
	Type() ObjectType
	Inspect() string // Returns the value the object represents
	Dup() Object     // Returns a duplicate of the object
}

type Integer struct {
	Value int64
}

func (i *Integer) Inspect() string  { return strconv.FormatInt(i.Value, 10) }
func (i *Integer) Type() ObjectType { return IntergerObj }
func (i *Integer) Dup() Object      { return &Integer{Value: i.Value} }

func MakeIntObj(v int64) *Integer {
	if v <= maxStaticInt {
		return staticInts[v]
	}
	return &Integer{Value: v}
}

type Float struct {
	Value float64
}

func (f *Float) Inspect() string  { return strconv.FormatFloat(f.Value, 'G', -1, 64) }
func (f *Float) Type() ObjectType { return FloatObj }
func (f *Float) Dup() Object      { return &Float{Value: f.Value} }

func MakeFloatObj(v float64) *Float {
	return &Float{Value: v}
}

type String struct {
	Value []rune
}

func (s *String) Inspect() string  { return string(s.Value) }
func (s *String) String() string   { return string(s.Value) } // Dedicated to the stringified value, no inspection
func (s *String) Type() ObjectType { return StringObj }
func (s *String) Dup() Object {
	dup := make([]rune, len(s.Value))
	copy(dup, s.Value)
	return &String{Value: dup}
}

func MakeStringObj(s string) *String {
	return &String{Value: []rune(s)}
}

func MakeStringObjRunes(r []rune) *String {
	return &String{Value: r}
}

type Boolean struct {
	Value bool
}

func (b *Boolean) Inspect() string {
	if b.Value {
		return "true"
	}
	return "false"
}
func (b *Boolean) Type() ObjectType { return BooleanObj }
func (b *Boolean) Dup() Object {
	if b.Value {
		return TrueConst
	}
	return FalseConst
}

func NativeBoolToBooleanObj(input bool) *Boolean {
	if input {
		return TrueConst
	}
	return FalseConst
}

type Null struct{}

func (n *Null) Inspect() string  { return "nil" }
func (n *Null) Type() ObjectType { return NullObj }
func (n *Null) Dup() Object      { return NullConst }

type ReturnValue struct {
	Value Object
}

func (r *ReturnValue) Inspect() string  { return r.Value.Inspect() }
func (r *ReturnValue) Type() ObjectType { return ReturnObj }
func (r *ReturnValue) Dup() Object      { return &ReturnValue{Value: r.Value.Dup()} }

// TODO: Expand with line/column numbers and stack trace
type Exception struct {
	Catchable bool
	Message   string
	Caught    bool
}

func (e *Exception) Inspect() string  { return e.Message }
func (e *Exception) Type() ObjectType { return ExceptionObj }
func (e *Exception) Dup() Object      { return &Exception{Message: e.Message} }
func (e *Exception) String() string   { return e.Message }

type Error struct {
	Message string
}

func (e *Error) Inspect() string  { return "Error: " + e.Message }
func (e *Error) Type() ObjectType { return ErrorObj }
func (e *Error) Dup() Object      { return &Error{Message: e.Message} }
func (e *Error) String() string   { return "Error: " + e.Message }

type Function struct {
	Name       string
	Parameters []*ast.Identifier
	Body       *ast.BlockStatement
	Env        *Environment
	Instance   *Instance
}

func (f *Function) Inspect() string {
	var out bytes.Buffer
	params := []string{}

	for _, p := range f.Parameters {
		params = append(params, p.String())
	}

	out.WriteString("func")
	out.WriteByte(' ')
	out.WriteString(f.Name)
	out.WriteByte('(')
	out.WriteString(strings.Join(params, ", "))
	out.WriteString(") {")
	out.WriteString(f.Body.String())
	out.WriteByte('}')

	return out.String()
}
func (f *Function) Type() ObjectType { return FunctionObj }
func (f *Function) Dup() Object      { return f }
func (f *Function) ClassMethod()     {}

type Builtin struct {
	Fn BuiltinFunction
}

func (b *Builtin) Inspect() string  { return "builtin function" }
func (b *Builtin) Type() ObjectType { return BuiltinObj }
func (b *Builtin) Dup() Object      { return b }

type BuiltinMethod struct {
	Fn       BuiltinMethodFunction
	Instance *Instance
}

func (b *BuiltinMethod) Inspect() string  { return "builtin method" }
func (b *BuiltinMethod) Type() ObjectType { return BuiltinMethodObj }
func (b *BuiltinMethod) Dup() Object      { return b }
func (b *BuiltinMethod) ClassMethod()     {}

func MakeBuiltinMethod(fn BuiltinMethodFunction) *BuiltinMethod {
	return &BuiltinMethod{Fn: fn}
}

type Array struct {
	Elements []Object
}

func (a *Array) Inspect() string {
	var out bytes.Buffer
	elements := []string{}

	for _, e := range a.Elements {
		if e.Type() == StringObj {
			elements = append(elements, fmt.Sprintf(`"%s"`, e.Inspect()))
		} else {
			elements = append(elements, e.Inspect())
		}
	}

	out.WriteByte('[')
	out.WriteString(strings.Join(elements, ", "))
	out.WriteByte(']')

	return out.String()
}
func (a *Array) Type() ObjectType { return ArrayObj }
func (a *Array) Dup() Object {
	newElements := make([]Object, len(a.Elements))

	for i, element := range a.Elements {
		newElements[i] = element.Dup()
	}

	return &Array{Elements: newElements}
}

func MakeStringArray(e []string) *Array {
	length := len(e)
	newElements := make([]Object, length, length)
	for i, s := range e {
		newElements[i] = MakeStringObj(s)
	}
	return &Array{Elements: newElements}
}

func ArrayToStringSlice(a *Array) []string {
	if a == nil {
		return []string{}
	}

	strs := make([]string, 0, len(a.Elements))
	for _, e := range a.Elements {
		if !(e.Type() == StringObj) {
			continue
		}
		strs = append(strs, string((e.(*String)).Value))
	}
	return strs
}

type Hashable interface {
	HashKey() HashKey
}

type HashKey struct {
	Type  ObjectType
	Value uint64
}

func (k HashKey) Dup() HashKey {
	return HashKey{
		Type:  k.Type,
		Value: k.Value,
	}
}

func (i *Integer) HashKey() HashKey {
	return HashKey{Type: i.Type(), Value: uint64(i.Value)}
}

func (s *String) HashKey() HashKey {
	h := fnv.New64a()
	h.Write([]byte(string(s.Value)))
	return HashKey{Type: s.Type(), Value: h.Sum64()}
}

type HashPair struct {
	Key   Object
	Value Object
}

func (p HashPair) Dup() HashPair {
	return HashPair{
		Key:   p.Key.Dup(),
		Value: p.Value.Dup(),
	}
}

type Hash struct {
	Pairs map[HashKey]HashPair
}

func (h *Hash) Type() ObjectType { return HashObj }
func (h *Hash) Inspect() string {
	var out bytes.Buffer

	pairs := []string{}
	for _, pair := range h.Pairs {
		var val string

		if pair.Value.Type() == StringObj {
			val = fmt.Sprintf(`"%s"`, pair.Value.Inspect())
		} else {
			val = pair.Value.Inspect()
		}

		pairs = append(pairs, fmt.Sprintf("%s: %s", pair.Key.Inspect(), val))
	}

	out.WriteByte('{')
	out.WriteString(strings.Join(pairs, ", "))
	out.WriteByte('}')
	return out.String()
}
func (h *Hash) Dup() Object {
	newElements := make(map[HashKey]HashPair, len(h.Pairs))

	for key, pair := range h.Pairs {
		newElements[key.Dup()] = pair.Dup()
	}

	return &Hash{Pairs: newElements}
}
func (h *Hash) LookupKey(key string) Object {
	keyObj := MakeStringObj(key)
	pair, ok := h.Pairs[keyObj.HashKey()]
	if !ok {
		return nil
	}
	return pair.Value
}
func (h *Hash) SetKey(key string, val Object) {
	keyObj := MakeStringObj(key)
	h.Pairs[keyObj.HashKey()] = HashPair{
		Key:   keyObj,
		Value: val,
	}
}

func MakeEmptyHash() *Hash {
	return &Hash{Pairs: make(map[HashKey]HashPair)}
}

func StringMapToHash(src map[string]string) *Hash {
	m := &Hash{Pairs: make(map[HashKey]HashPair)}
	for k, v := range src {
		key := MakeStringObj(k)
		m.Pairs[key.HashKey()] = HashPair{
			Key:   key,
			Value: MakeStringObj(v),
		}
	}
	return m
}

type LoopControl struct {
	Continue bool
}

func (lc *LoopControl) Type() ObjectType { return LoopControlObj }
func (lc *LoopControl) Inspect() string {
	if lc.Continue {
		return "continue"
	}
	return "break"
}
func (lc *LoopControl) Dup() Object { return &LoopControl{Continue: lc.Continue} }

type Module struct {
	Name    string
	Methods map[string]BuiltinFunction
	Vars    map[string]Object
}

func (m *Module) Inspect() string  { return fmt.Sprintf("Module %s", m.Name) }
func (m *Module) Type() ObjectType { return ModuleObj }
func (m *Module) Dup() Object      { return NullConst }

func NewException(format string, a ...interface{}) *Exception {
	return &Exception{
		Message:   fmt.Sprintf(format, a...),
		Catchable: true,
	}
}

func NewPanic(format string, a ...interface{}) *Exception {
	return &Exception{Message: fmt.Sprintf(format, a...)}
}

func NewError(format string, a ...interface{}) *Error {
	return &Error{Message: fmt.Sprintf(format, a...)}
}

func ObjectsAre(t ObjectType, o ...Object) bool {
	for _, obj := range o {
		if obj.Type() != t {
			return false
		}
	}
	return true
}

func ObjectIs(o Object, t ...ObjectType) bool {
	if o != nil {
		for _, ot := range t {
			if o.Type() == ot {
				return true
			}
		}
	}
	return false
}
<commit_msg>Check for negative numbers with cache<commit_after>package object

import (
	"bytes"
	"fmt"
	"hash/fnv"
	"io"
	"strconv"
	"strings"

	"github.com/nitrogen-lang/nitrogen/src/ast"
)

type ObjectType int

func (o ObjectType) String() string {
	return objectTypeNames[o]
}

// These are all the internal object types used in the interpreter
const (
	IntergerObj ObjectType = iota
	FloatObj
	BooleanObj
	NullObj
	ReturnObj
	ExceptionObj
	ErrorObj
	FunctionObj
	StringObj
	BuiltinObj
	ArrayObj
	HashObj
	LoopControlObj
	// ResourceObj can be used by modules to denote a generic resource. The implementation may be module specific.
	ResourceObj
	ModuleObj
	ClassObj
	InstanceObj
	BuiltinMethodObj
	BoundMethodObj
)

var objectTypeNames = map[ObjectType]string{
	IntergerObj:      "INTEGER",
	FloatObj:         "FLOAT",
	BooleanObj:       "BOOLEAN",
	NullObj:          "NULL",
	ReturnObj:        "RETURN",
	ExceptionObj:     "EXCEPTION",
	ErrorObj:         "ERROR",
	FunctionObj:      "FUNCTION",
	StringObj:        "STRING",
	BuiltinObj:       "BUILTIN",
	ArrayObj:         "ARRAY",
	HashObj:          "MAP",
	ResourceObj:      "RESOURCE",
	ModuleObj:        "MODULE",
	ClassObj:         "CLASS",
	InstanceObj:      "INSTANCE",
	BuiltinMethodObj: "BUILTIN METHOD",
	BoundMethodObj:   "BOUND METHOD",
}

const maxStaticInt = 255

// These are all constants in the language that can be represented with a single instance
var (
	NullConst  = &Null{}
	TrueConst  = &Boolean{Value: true}
	FalseConst = &Boolean{Value: false}
	staticInts [maxStaticInt + 1]*Integer
)

func init() {
	for i := 0; i <= maxStaticInt; i++ {
		staticInts[i] = &Integer{Value: int64(i)}
	}
}

type Interpreter interface {
	Eval(node ast.Node, env *Environment) Object
	GetCurrentScriptPath() string
	GetStdout() io.Writer
	GetStderr() io.Writer
	GetStdin() io.Reader
}

type BuiltinFunction func(i Interpreter, env *Environment, args ...Object) Object

type BuiltinMethodFunction func(i Interpreter, self *Instance, env *Environment, args ...Object) Object

type Object interface {
	Type() ObjectType
	Inspect() string // Returns the value the object represents
	Dup() Object     // Returns a duplicate of the object
}

type Integer struct {
	Value int64
}

func (i *Integer) Inspect() string  { return strconv.FormatInt(i.Value, 10) }
func (i *Integer) Type() ObjectType { return IntergerObj }
func (i *Integer) Dup() Object      { return &Integer{Value: i.Value} }

func MakeIntObj(v int64) *Integer {
	if v >= 0 && v <= maxStaticInt {
		return staticInts[v]
	}
	return &Integer{Value: v}
}

type Float struct {
	Value float64
}

func (f *Float) Inspect() string  { return strconv.FormatFloat(f.Value, 'G', -1, 64) }
func (f *Float) Type() ObjectType { return FloatObj }
func (f *Float) Dup() Object      { return &Float{Value: f.Value} }

func MakeFloatObj(v float64) *Float {
	return &Float{Value: v}
}

type String struct {
	Value []rune
}

func (s *String) Inspect() string  { return string(s.Value) }
func (s *String) String() string   { return string(s.Value) } // Dedicated to the stringified value, no inspection
func (s *String) Type() ObjectType { return StringObj }
func (s *String) Dup() Object {
	dup := make([]rune, len(s.Value))
	copy(dup, s.Value)
	return &String{Value: dup}
}

func MakeStringObj(s string) *String {
	return &String{Value: []rune(s)}
}

func MakeStringObjRunes(r []rune) *String {
	return &String{Value: r}
}

type Boolean struct {
	Value bool
}

func (b *Boolean) Inspect() string {
	if b.Value {
		return "true"
	}
	return "false"
}
func (b *Boolean) Type() ObjectType { return BooleanObj }
func (b *Boolean) Dup() Object {
	if b.Value {
		return TrueConst
	}
	return FalseConst
}

func NativeBoolToBooleanObj(input bool) *Boolean {
	if input {
		return TrueConst
	}
	return FalseConst
}

type Null struct{}

func (n *Null) Inspect() string  { return "nil" }
func (n *Null) Type() ObjectType { return NullObj }
func (n *Null) Dup() Object      { return NullConst }

type ReturnValue struct {
	Value Object
}

func (r *ReturnValue) Inspect() string  { return r.Value.Inspect() }
func (r *ReturnValue) Type() ObjectType { return ReturnObj }
func (r *ReturnValue) Dup() Object      { return &ReturnValue{Value: r.Value.Dup()} }

// TODO: Expand with line/column numbers and stack trace
type Exception struct {
	Catchable bool
	Message   string
	Caught    bool
}

func (e *Exception) Inspect() string  { return e.Message }
func (e *Exception) Type() ObjectType { return ExceptionObj }
func (e *Exception) Dup() Object      { return &Exception{Message: e.Message} }
func (e *Exception) String() string   { return e.Message }

type Error struct {
	Message string
}

func (e *Error) Inspect() string  { return "Error: " + e.Message }
func (e *Error) Type() ObjectType { return ErrorObj }
func (e *Error) Dup() Object      { return &Error{Message: e.Message} }
func (e *Error) String() string   { return "Error: " + e.Message }

type Function struct {
	Name       string
	Parameters []*ast.Identifier
	Body       *ast.BlockStatement
	Env        *Environment
	Instance   *Instance
}

func (f *Function) Inspect() string {
	var out bytes.Buffer
	params := []string{}

	for _, p := range f.Parameters {
		params = append(params, p.String())
	}

	out.WriteString("func")
	out.WriteByte(' ')
	out.WriteString(f.Name)
	out.WriteByte('(')
	out.WriteString(strings.Join(params, ", "))
	out.WriteString(") {")
	out.WriteString(f.Body.String())
	out.WriteByte('}')

	return out.String()
}
func (f *Function) Type() ObjectType { return FunctionObj }
func (f *Function) Dup() Object      { return f }
func (f *Function) ClassMethod()     {}

type Builtin struct {
	Fn BuiltinFunction
}

func (b *Builtin) Inspect() string  { return "builtin function" }
func (b *Builtin) Type() ObjectType { return BuiltinObj }
func (b *Builtin) Dup() Object      { return b }

type BuiltinMethod struct {
	Fn       BuiltinMethodFunction
	Instance *Instance
}

func (b *BuiltinMethod) Inspect() string  { return "builtin method" }
func (b *BuiltinMethod) Type() ObjectType { return BuiltinMethodObj }
func (b *BuiltinMethod) Dup() Object      { return b }
func (b *BuiltinMethod) ClassMethod()     {}

func MakeBuiltinMethod(fn BuiltinMethodFunction) *BuiltinMethod {
	return &BuiltinMethod{Fn: fn}
}

type Array struct {
	Elements []Object
}

func (a *Array) Inspect() string {
	var out bytes.Buffer
	elements := []string{}

	for _, e := range a.Elements {
		if e.Type() == StringObj {
			elements = append(elements, fmt.Sprintf(`"%s"`, e.Inspect()))
		} else {
			elements = append(elements, e.Inspect())
		}
	}

	out.WriteByte('[')
	out.WriteString(strings.Join(elements, ", "))
	out.WriteByte(']')

	return out.String()
}
func (a *Array) Type() ObjectType { return ArrayObj }
func (a *Array) Dup() Object {
	newElements := make([]Object, len(a.Elements))

	for i, element := range a.Elements {
		newElements[i] = element.Dup()
	}

	return &Array{Elements: newElements}
}

func MakeStringArray(e []string) *Array {
	length := len(e)
	newElements := make([]Object, length, length)
	for i, s := range e {
		newElements[i] = MakeStringObj(s)
	}
	return &Array{Elements: newElements}
}

func ArrayToStringSlice(a *Array) []string {
	if a == nil {
		return []string{}
	}

	strs := make([]string, 0, len(a.Elements))
	for _, e := range a.Elements {
		if !(e.Type() == StringObj) {
			continue
		}
		strs = append(strs, string((e.(*String)).Value))
	}
	return strs
}

type Hashable interface {
	HashKey() HashKey
}

type HashKey struct {
	Type  ObjectType
	Value uint64
}

func (k HashKey) Dup() HashKey {
	return HashKey{
		Type:  k.Type,
		Value: k.Value,
	}
}

func (i *Integer) HashKey() HashKey {
	return HashKey{Type: i.Type(), Value: uint64(i.Value)}
}

func (s *String) HashKey() HashKey {
	h := fnv.New64a()
	h.Write([]byte(string(s.Value)))
	return HashKey{Type: s.Type(), Value: h.Sum64()}
}

type HashPair struct {
	Key   Object
	Value Object
}

func (p HashPair) Dup() HashPair {
	return HashPair{
		Key:   p.Key.Dup(),
		Value: p.Value.Dup(),
	}
}

type Hash struct {
	Pairs map[HashKey]HashPair
}

func (h *Hash) Type() ObjectType { return HashObj }
func (h *Hash) Inspect() string {
	var out bytes.Buffer

	pairs := []string{}
	for _, pair := range h.Pairs {
		var val string

		if pair.Value.Type() == StringObj {
			val = fmt.Sprintf(`"%s"`, pair.Value.Inspect())
		} else {
			val = pair.Value.Inspect()
		}

		pairs = append(pairs, fmt.Sprintf("%s: %s", pair.Key.Inspect(), val))
	}

	out.WriteByte('{')
	out.WriteString(strings.Join(pairs, ", "))
	out.WriteByte('}')
	return out.String()
}
func (h *Hash) Dup() Object {
	newElements := make(map[HashKey]HashPair, len(h.Pairs))

	for key, pair := range h.Pairs {
		newElements[key.Dup()] = pair.Dup()
	}

	return &Hash{Pairs: newElements}
}
func (h *Hash) LookupKey(key string) Object {
	keyObj := MakeStringObj(key)
	pair, ok := h.Pairs[keyObj.HashKey()]
	if !ok {
		return nil
	}
	return pair.Value
}
func (h *Hash) SetKey(key string, val Object) {
	keyObj := MakeStringObj(key)
	h.Pairs[keyObj.HashKey()] = HashPair{
		Key:   keyObj,
		Value: val,
	}
}

func MakeEmptyHash() *Hash {
	return &Hash{Pairs: make(map[HashKey]HashPair)}
}

func StringMapToHash(src map[string]string) *Hash {
	m := &Hash{Pairs: make(map[HashKey]HashPair)}
	for k, v := range src {
		key := MakeStringObj(k)
		m.Pairs[key.HashKey()] = HashPair{
			Key:   key,
			Value: MakeStringObj(v),
		}
	}
	return m
}

type LoopControl struct {
	Continue bool
}

func (lc *LoopControl) Type() ObjectType { return LoopControlObj }
func (lc *LoopControl) Inspect() string {
	if lc.Continue {
		return "continue"
	}
	return "break"
}
func (lc *LoopControl) Dup() Object { return &LoopControl{Continue: lc.Continue} }

type Module struct {
	Name    string
	Methods map[string]BuiltinFunction
	Vars    map[string]Object
}

func (m *Module) Inspect() string  { return fmt.Sprintf("Module %s", m.Name) }
func (m *Module) Type() ObjectType { return ModuleObj }
func (m *Module) Dup() Object      { return NullConst }

func NewException(format string, a ...interface{}) *Exception {
	return &Exception{
		Message:   fmt.Sprintf(format, a...),
		Catchable: true,
	}
}

func NewPanic(format string, a ...interface{}) *Exception {
	return &Exception{Message: fmt.Sprintf(format, a...)}
}

func NewError(format string, a ...interface{}) *Error {
	return &Error{Message: fmt.Sprintf(format, a...)}
}

func ObjectsAre(t ObjectType, o ...Object) bool {
	for _, obj := range o {
		if obj.Type() != t {
			return false
		}
	}
	return true
}

func ObjectIs(o Object, t ...ObjectType) bool {
	if o != nil {
		for _, ot := range t {
			if o.Type() == ot {
				return true
			}
		}
	}
	return false
}
<|endoftext|>


<commit_before>package js

import (
	"errors"
	log "github.com/Sirupsen/logrus"
	"github.com/loadimpact/speedboat/stats"
	"github.com/robertkrimen/otto"
	"io/ioutil"
	"net/http"
	neturl "net/url"
	"time"
)

var (
	mRequests = stats.Stat{Name: "requests", Type: stats.HistogramType, Intent: stats.TimeIntent}
	mErrors   = stats.Stat{Name: "errors", Type: stats.CounterType}

	ErrTooManyRedirects = errors.New("too many redirects")
)

type HTTPParams struct {
	Follow  bool
	Quiet   bool
	Headers map[string]string
}

type HTTPResponse struct {
	Status  int
	Headers map[string]string
	Body    string
}

func (res HTTPResponse) ToValue(vm *otto.Otto) (otto.Value, error) {
	obj, err := Make(vm, "HTTPResponse")
	if err != nil {
		return otto.UndefinedValue(), err
	}

	obj.Set("status", res.Status)
	obj.Set("headers", res.Headers)
	obj.Set("body", res.Body)

	return vm.ToValue(obj)
}

func (u *VU) HTTPRequest(method, url, body string, params HTTPParams, redirects int) (HTTPResponse, error) {
	parsedURL, err := neturl.Parse(url)
	if err != nil {
		return HTTPResponse{}, err
	}

	req := http.Request{
		Method: method,
		URL:    parsedURL,
		Header: make(http.Header),
	}

	if method == "GET" || method == "HEAD" {
		req.URL.RawQuery = body
	} else {
		// NOT IMPLEMENTED! I'm just testing stuff out.
		// req.SetBodyString(body)
	}

	for key, value := range params.Headers {
		req.Header[key] = []string{value}
	}

	startTime := time.Now()
	resp, err := u.Client.Do(&req)
	duration := time.Since(startTime)

	var status int
	var respBody []byte
	if err == nil {
		status = resp.StatusCode
		respBody, _ = ioutil.ReadAll(resp.Body)
		resp.Body.Close()
	}

	tags := stats.Tags{
		"url":    url,
		"method": method,
		"status": status,
		"proto":  resp.Proto,
	}

	if !params.Quiet {
		u.Collector.Add(stats.Sample{
			Stat:   &mRequests,
			Tags:   tags,
			Values: stats.Values{"duration": float64(duration)},
		})
	}

	if err != nil {
		if !params.Quiet {
			u.Collector.Add(stats.Sample{
				Stat:   &mErrors,
				Tags:   tags,
				Values: stats.Value(1),
			})
		}
		return HTTPResponse{}, err
	}

	// switch resp.StatusCode {
	// case 301, 302, 303, 307, 308:
	// 	if !params.Follow {
	// 		break
	// 	}
	// 	if redirects >= u.FollowDepth {
	// 		return HTTPResponse{}, ErrTooManyRedirects
	// 	}

	// 	redirectURL := url
	// 	resp.Header.VisitAll(func(key, value []byte) {
	// 		if string(key) != "Location" {
	// 			return
	// 		}

	// 		redirectURL = resolveRedirect(url, string(value))
	// 	})

	// 	redirectMethod := method
	// 	redirectBody := body
	// 	if status == 301 || status == 302 || status == 303 {
	// 		redirectMethod = "GET"
	// 		redirectBody = ""
	// 	}
	// 	return u.HTTPRequest(redirectMethod, redirectURL, redirectBody, params, redirects+1)
	// }

	headers := make(map[string]string)
	for key, vals := range resp.Header {
		headers[key] = vals[0]
	}

	return HTTPResponse{
		Status:  resp.StatusCode,
		Headers: headers,
		Body:    string(respBody),
	}, nil
}

func (u *VU) Sleep(t float64) {
	time.Sleep(time.Duration(t * float64(time.Second)))
}

func (u *VU) Log(level, msg string, fields map[string]interface{}) {
	e := u.Runner.logger.WithFields(log.Fields(fields))

	switch level {
	case "debug":
		e.Debug(msg)
	case "info":
		e.Info(msg)
	case "warn":
		e.Warn(msg)
	case "error":
		e.Error(msg)
	}
}
<commit_msg>[fix] Crash on failed requests<commit_after>package js

import (
	"errors"
	log "github.com/Sirupsen/logrus"
	"github.com/loadimpact/speedboat/stats"
	"github.com/robertkrimen/otto"
	"io/ioutil"
	"net/http"
	neturl "net/url"
	"time"
)

var (
	mRequests = stats.Stat{Name: "requests", Type: stats.HistogramType, Intent: stats.TimeIntent}
	mErrors   = stats.Stat{Name: "errors", Type: stats.CounterType}

	ErrTooManyRedirects = errors.New("too many redirects")
)

type HTTPParams struct {
	Follow  bool
	Quiet   bool
	Headers map[string]string
}

type HTTPResponse struct {
	Status  int
	Headers map[string]string
	Body    string
}

func (res HTTPResponse) ToValue(vm *otto.Otto) (otto.Value, error) {
	obj, err := Make(vm, "HTTPResponse")
	if err != nil {
		return otto.UndefinedValue(), err
	}

	obj.Set("status", res.Status)
	obj.Set("headers", res.Headers)
	obj.Set("body", res.Body)

	return vm.ToValue(obj)
}

func (u *VU) HTTPRequest(method, url, body string, params HTTPParams, redirects int) (HTTPResponse, error) {
	parsedURL, err := neturl.Parse(url)
	if err != nil {
		return HTTPResponse{}, err
	}

	req := http.Request{
		Method: method,
		URL:    parsedURL,
		Header: make(http.Header),
	}

	if method == "GET" || method == "HEAD" {
		req.URL.RawQuery = body
	} else {
		// NOT IMPLEMENTED! I'm just testing stuff out.
		// req.SetBodyString(body)
	}

	for key, value := range params.Headers {
		req.Header[key] = []string{value}
	}

	startTime := time.Now()
	resp, err := u.Client.Do(&req)
	duration := time.Since(startTime)

	tags := stats.Tags{
		"url":    url,
		"method": method,
		"status": 0,
	}

	var respBody []byte
	if err == nil {
		tags["status"] = resp.StatusCode
		tags["proto"] = resp.Proto
		respBody, _ = ioutil.ReadAll(resp.Body)
		resp.Body.Close()
	}

	if !params.Quiet {
		u.Collector.Add(stats.Sample{
			Stat:   &mRequests,
			Tags:   tags,
			Values: stats.Values{"duration": float64(duration)},
		})
	}

	if err != nil {
		if !params.Quiet {
			u.Collector.Add(stats.Sample{
				Stat:   &mErrors,
				Tags:   tags,
				Values: stats.Value(1),
			})
		}
		return HTTPResponse{}, err
	}

	// switch resp.StatusCode {
	// case 301, 302, 303, 307, 308:
	// 	if !params.Follow {
	// 		break
	// 	}
	// 	if redirects >= u.FollowDepth {
	// 		return HTTPResponse{}, ErrTooManyRedirects
	// 	}

	// 	redirectURL := url
	// 	resp.Header.VisitAll(func(key, value []byte) {
	// 		if string(key) != "Location" {
	// 			return
	// 		}

	// 		redirectURL = resolveRedirect(url, string(value))
	// 	})

	// 	redirectMethod := method
	// 	redirectBody := body
	// 	if status == 301 || status == 302 || status == 303 {
	// 		redirectMethod = "GET"
	// 		redirectBody = ""
	// 	}
	// 	return u.HTTPRequest(redirectMethod, redirectURL, redirectBody, params, redirects+1)
	// }

	headers := make(map[string]string)
	for key, vals := range resp.Header {
		headers[key] = vals[0]
	}

	return HTTPResponse{
		Status:  resp.StatusCode,
		Headers: headers,
		Body:    string(respBody),
	}, nil
}

func (u *VU) Sleep(t float64) {
	time.Sleep(time.Duration(t * float64(time.Second)))
}

func (u *VU) Log(level, msg string, fields map[string]interface{}) {
	e := u.Runner.logger.WithFields(log.Fields(fields))

	switch level {
	case "debug":
		e.Debug(msg)
	case "info":
		e.Info(msg)
	case "warn":
		e.Warn(msg)
	case "error":
		e.Error(msg)
	}
}
<|endoftext|>


<commit_before>/*
    Spacedex, the new and improved Docker index.
 */
package main

import (
  "fmt"
  "github.com/codegangsta/cli"
  "github.com/ricallinson/forgery"
  "github.com/ricallinson/stackr"
  "github.com/Southern/logger"
  "github.com/Southern/middleware"
  "github.com/spacedock-io/index/config"
  "github.com/spacedock-io/registry/db"
  "github.com/spacedock-io/index/models"
  _ "github.com/lib/pq"
  "os"
)

func main() {
  // Initialize new CLI app
  app := cli.NewApp()

  // Initialize new Forgery server
  server := f.CreateServer()
  server.Use(middleware.BodyParser)
  server.Use(func(req *stackr.Request, res *stackr.Response, next func()) {
    res.SetHeader("X-Docker-Registry-Version", "0.7.4")
    next()
  })

  app.Name = "spacedex"
  app.Author = "Spacedock"
  app.Email = "hello@spacedock.io"
  app.Usage = "Run a standalone Docker index"
  app.Version = "0.0.1"
  app.Flags = []cli.Flag {
    // No default value here, so that our <env>.config.json file will override
    // it.
    cli.StringFlag{"port, p", "", "Port to listen on"},
    cli.StringFlag{"env, e", "dev", "Default environment"},
    cli.StringFlag{"config, c", "", "Configuration directory"},
  }

  app.Action = func (c *cli.Context) {
    env := c.String("env")
    dir := c.String("config")

    // Default to dev if someone enters a blank string
    if len(env) == 0 {
      env = "dev"
    }
    if len(dir) > 0 {
      config.Dir = dir
    }

    config.Global = config.Load(env)
    config.Logger = logger.New()

    port := c.Int("port")
    if port == 0 {
      // Bug(Colton): Not quite sure why port is being picked up as Float64 at
      // the moment. Still looking into this. It may be intended functionality.
      port = int(config.Global.Get("port").Float64())
    }

    config.Logger.Debug = config.Global.Get("logger.debug").Bool(false)
    config.Logger.Exit = config.Global.Get("logger.exit").Bool(false)

    db := db.New(config.Global)
    db.AutoMigrate(&models.User{})
    db.AutoMigrate(&models.Access{})
    db.AutoMigrate(&models.Email{})
    db.AutoMigrate(&models.Repo{})
    db.AutoMigrate(&models.Token{})
    db.AutoMigrate(&models.Image{})

    Routes(server)

    config.Logger.Log("Index listening on port " + fmt.Sprint(port))
    server.Listen(port)
  }

  app.Run(os.Args)
}
<commit_msg>Use ErrorHandler middleware<commit_after>/*
    Spacedex, the new and improved Docker index.
 */
package main

import (
  "fmt"
  "github.com/codegangsta/cli"
  "github.com/ricallinson/forgery"
  "github.com/ricallinson/stackr"
  "github.com/Southern/logger"
  "github.com/Southern/middleware"
  "github.com/spacedock-io/index/config"
  "github.com/spacedock-io/registry/db"
  "github.com/spacedock-io/index/models"
  _ "github.com/lib/pq"
  "os"
)

func main() {
  // Initialize new CLI app
  app := cli.NewApp()

  // Initialize new Forgery server
  server := f.CreateServer()
  server.Use(f.ErrorHandler())
  server.Use(middleware.BodyParser)
  server.Use(func(req *stackr.Request, res *stackr.Response, next func()) {
    res.SetHeader("X-Docker-Registry-Version", "0.7.4")
    next()
  })

  app.Name = "spacedex"
  app.Author = "Spacedock"
  app.Email = "hello@spacedock.io"
  app.Usage = "Run a standalone Docker index"
  app.Version = "0.0.1"
  app.Flags = []cli.Flag {
    // No default value here, so that our <env>.config.json file will override
    // it.
    cli.StringFlag{"port, p", "", "Port to listen on"},
    cli.StringFlag{"env, e", "dev", "Default environment"},
    cli.StringFlag{"config, c", "", "Configuration directory"},
  }

  app.Action = func (c *cli.Context) {
    env := c.String("env")
    dir := c.String("config")

    // Default to dev if someone enters a blank string
    if len(env) == 0 {
      env = "dev"
    }
    if len(dir) > 0 {
      config.Dir = dir
    }

    config.Global = config.Load(env)
    config.Logger = logger.New()

    port := c.Int("port")
    if port == 0 {
      // Bug(Colton): Not quite sure why port is being picked up as Float64 at
      // the moment. Still looking into this. It may be intended functionality.
      port = int(config.Global.Get("port").Float64())
    }

    config.Logger.Debug = config.Global.Get("logger.debug").Bool(false)
    config.Logger.Exit = config.Global.Get("logger.exit").Bool(false)

    db := db.New(config.Global)
    db.AutoMigrate(&models.User{})
    db.AutoMigrate(&models.Access{})
    db.AutoMigrate(&models.Email{})
    db.AutoMigrate(&models.Repo{})
    db.AutoMigrate(&models.Token{})
    db.AutoMigrate(&models.Image{})

    Routes(server)

    config.Logger.Log("Index listening on port " + fmt.Sprint(port))
    server.Listen(port)
  }

  app.Run(os.Args)
}
<|endoftext|>


<commit_before>package listeners

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

	"github.com/getlantern/measured"
)

const (
	rateInterval = 1 * time.Second
)

// MeasuredReportFN is a function that gets called to report stats from the
// measured connection. deltaStats is like stats except that SentTotal and
// RecvTotal are deltas relative to the prior reported stats. final indicates
// whether this is the last call for a connection (i.e. connection has been
// closed).
type MeasuredReportFN func(ctx map[string]interface{}, stats *measured.Stats, deltaStats *measured.Stats,
	final bool)

// Wrapped stateAwareMeasuredListener that generates the wrapped wrapMeasuredConn
type stateAwareMeasuredListener struct {
	net.Listener
	reportInterval time.Duration
	report         MeasuredReportFN
}

func NewMeasuredListener(l net.Listener, reportInterval time.Duration, report MeasuredReportFN) net.Listener {
	return &stateAwareMeasuredListener{l, reportInterval, report}
}

func (l *stateAwareMeasuredListener) Accept() (c net.Conn, err error) {
	c, err = l.Listener.Accept()
	if err != nil {
		return nil, err
	}
	fs := make(chan *measured.Stats)
	wc := &wrapMeasuredConn{
		Conn: measured.Wrap(c, rateInterval, func(mc measured.Conn) {
			fs <- mc.Stats()
		}),
		ctx:        make(map[string]interface{}),
		finalStats: fs,
	}
	sac, _ := c.(WrapConnEmbeddable)
	wc.WrapConnEmbeddable = sac
	go wc.track(l.reportInterval, l.report)
	return wc, nil
}

// Wrapped MeasuredConn that supports OnState
type wrapMeasuredConn struct {
	WrapConnEmbeddable
	measured.Conn
	ctx        map[string]interface{}
	ctxMx      sync.RWMutex
	finalStats chan *measured.Stats
}

func (c *wrapMeasuredConn) track(reportInterval time.Duration, report MeasuredReportFN) {
	ticker := time.NewTicker(reportInterval)
	var priorStats *measured.Stats
	applyStats := func(stats *measured.Stats, final bool) {
		deltaStats := &measured.Stats{}
		// Copy stats
		*deltaStats = *stats
		if priorStats != nil {
			deltaStats.SentTotal -= priorStats.SentTotal
			deltaStats.RecvTotal -= priorStats.RecvTotal
		}
		priorStats = stats
		c.ctxMx.RLock()
		ctx := c.ctx
		c.ctxMx.RUnlock()
		report(ctx, stats, deltaStats, final)
	}

	for {
		select {
		case <-ticker.C:
			applyStats(c.Conn.Stats(), false)
		case stats := <-c.finalStats:
			applyStats(stats, true)
			return
		}
	}
}

func (c *wrapMeasuredConn) OnState(s http.ConnState) {
	if c.WrapConnEmbeddable != nil {
		c.WrapConnEmbeddable.OnState(s)
	}
}

// Responds to the "measured" message type
func (c *wrapMeasuredConn) ControlMessage(msgType string, data interface{}) {
	if msgType == "measured" {
		ctxUpdate := data.(map[string]interface{})
		c.ctxMx.Lock()
		newContext := make(map[string]interface{}, len(c.ctx))
		// Copy context
		for key, value := range c.ctx {
			newContext[key] = value
		}
		// Update context
		for key, value := range ctxUpdate {
			newContext[key] = value
		}
		c.ctx = newContext
		c.ctxMx.Unlock()
	}

	if c.WrapConnEmbeddable != nil {
		// Pass it down too, just in case other wrapper does something with
		c.WrapConnEmbeddable.ControlMessage(msgType, data)
	}
}
<commit_msg>Stopping measured ticker when done tracking<commit_after>package listeners

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

	"github.com/getlantern/measured"
)

const (
	rateInterval = 1 * time.Second
)

// MeasuredReportFN is a function that gets called to report stats from the
// measured connection. deltaStats is like stats except that SentTotal and
// RecvTotal are deltas relative to the prior reported stats. final indicates
// whether this is the last call for a connection (i.e. connection has been
// closed).
type MeasuredReportFN func(ctx map[string]interface{}, stats *measured.Stats, deltaStats *measured.Stats,
	final bool)

// Wrapped stateAwareMeasuredListener that generates the wrapped wrapMeasuredConn
type stateAwareMeasuredListener struct {
	net.Listener
	reportInterval time.Duration
	report         MeasuredReportFN
}

func NewMeasuredListener(l net.Listener, reportInterval time.Duration, report MeasuredReportFN) net.Listener {
	return &stateAwareMeasuredListener{l, reportInterval, report}
}

func (l *stateAwareMeasuredListener) Accept() (c net.Conn, err error) {
	c, err = l.Listener.Accept()
	if err != nil {
		return nil, err
	}
	fs := make(chan *measured.Stats)
	wc := &wrapMeasuredConn{
		Conn: measured.Wrap(c, rateInterval, func(mc measured.Conn) {
			fs <- mc.Stats()
		}),
		ctx:        make(map[string]interface{}),
		finalStats: fs,
	}
	sac, _ := c.(WrapConnEmbeddable)
	wc.WrapConnEmbeddable = sac
	go wc.track(l.reportInterval, l.report)
	return wc, nil
}

// Wrapped MeasuredConn that supports OnState
type wrapMeasuredConn struct {
	WrapConnEmbeddable
	measured.Conn
	ctx        map[string]interface{}
	ctxMx      sync.RWMutex
	finalStats chan *measured.Stats
}

func (c *wrapMeasuredConn) track(reportInterval time.Duration, report MeasuredReportFN) {
	ticker := time.NewTicker(reportInterval)
	defer ticker.Stop()

	var priorStats *measured.Stats
	applyStats := func(stats *measured.Stats, final bool) {
		deltaStats := &measured.Stats{}
		// Copy stats
		*deltaStats = *stats
		if priorStats != nil {
			deltaStats.SentTotal -= priorStats.SentTotal
			deltaStats.RecvTotal -= priorStats.RecvTotal
		}
		priorStats = stats
		c.ctxMx.RLock()
		ctx := c.ctx
		c.ctxMx.RUnlock()
		report(ctx, stats, deltaStats, final)
	}

	for {
		select {
		case <-ticker.C:
			applyStats(c.Conn.Stats(), false)
		case stats := <-c.finalStats:
			applyStats(stats, true)
			return
		}
	}
}

func (c *wrapMeasuredConn) OnState(s http.ConnState) {
	if c.WrapConnEmbeddable != nil {
		c.WrapConnEmbeddable.OnState(s)
	}
}

// Responds to the "measured" message type
func (c *wrapMeasuredConn) ControlMessage(msgType string, data interface{}) {
	if msgType == "measured" {
		ctxUpdate := data.(map[string]interface{})
		c.ctxMx.Lock()
		newContext := make(map[string]interface{}, len(c.ctx))
		// Copy context
		for key, value := range c.ctx {
			newContext[key] = value
		}
		// Update context
		for key, value := range ctxUpdate {
			newContext[key] = value
		}
		c.ctx = newContext
		c.ctxMx.Unlock()
	}

	if c.WrapConnEmbeddable != nil {
		// Pass it down too, just in case other wrapper does something with
		c.WrapConnEmbeddable.ControlMessage(msgType, data)
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 The Cockroach Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	  http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.

package acceptance

import "testing"

func TestDockerFinagle(t *testing.T) {
	testDockerSuccess(t, "finagle", []string{"/bin/sh", "-c", finagle})
}

const finagle = `
set -e
openssl pkcs12 -export -in $PGSSLCERT -inkey $PGSSLKEY -out /client.p12 -name "Whatever" -password pass:
echo "CREATE DATABASE finagle_postgres_test" | psql
PGHOSTPORT=$PGHOST:$PGPORT USE_PG_SSL=1 RUN_PG_INTEGRATION_TESTS=1 PGUSER="root" PG_PKCS12=/client.p12 java -jar /finagle-postgres-tests.jar com.twitter.finagle.postgres.integration.IntegrationSpec
`
<commit_msg>acceptance: disable TestDockerFinagle<commit_after>// Copyright 2016 The Cockroach Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	  http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.

package acceptance

import "testing"

func TestDockerFinagle(t *testing.T) {
	t.Skip("TODO(dt): #5951, #5928, and needs #5484")
	testDockerSuccess(t, "finagle", []string{"/bin/sh", "-c", finagle})
}

const finagle = `
set -e
openssl pkcs12 -export -in $PGSSLCERT -inkey $PGSSLKEY -out /client.p12 -name "Whatever" -password pass:
echo "CREATE DATABASE finagle_postgres_test" | psql
PGHOSTPORT=$PGHOST:$PGPORT USE_PG_SSL=1 RUN_PG_INTEGRATION_TESTS=1 PGUSER="root" PG_PKCS12=/client.p12 java -jar /finagle-postgres-tests.jar com.twitter.finagle.postgres.integration.IntegrationSpec
`
<|endoftext|>


<commit_before>package handler

import (
	"encoding/json"
	"errors"
	"net/http"

	"github.com/gilcrest/go-API-template/appuser"
	"github.com/gilcrest/go-API-template/env"
	"github.com/gilcrest/go-API-template/server/errorHandler"
)

// CreateUser creates a user in the database
func CreateUser(env *env.Env, w http.ResponseWriter, req *http.Request) error {

	// Get a new logger instance
	log := env.Logger

	log.Debug().Msg("Start handler.CreateUser")
	defer log.Debug().Msg("Finish handler.CreateUser")

	// retrieve the context from the http.Request
	ctx := req.Context()

	var err error

	// Declare cur as an instance of createUserRequest
	// Decode JSON HTTP request body into a Decoder type
	//  and unmarshal that into cur
	cur := new(appuser.CreateUserRequest)
	err = json.NewDecoder(req.Body).Decode(&cur)
	if err != nil {
		return errorHandler.HTTPErr{
			Code: http.StatusBadRequest,
			Type: "invalid_request",
			Err:  err,
		}
	}
	defer req.Body.Close()

	usr, err := appuser.NewUser(ctx, env, cur)
	if err != nil {
		// newUser returns a proper HTTPErr, so just return it
		return err
	}

	// Call the create method of the appUser object to validate data and write to db
	tx, err := usr.Create(ctx, env)
	if err != nil {
		return errorHandler.HTTPErr{
			Code: http.StatusBadRequest,
			Type: "validation_failed",
			Err:  err,
		}
	}

	if !usr.UpdateTimestamp().IsZero() {
		// If we have successfully written rows to the db, we commit the transaction
		// CreateDate should only be populated if the db transaction was successful
		// and everything is in order
		err = tx.Commit()
		if err != nil {
			// We return an HTTPErr here, which wraps the error
			// returned from our DB queries. You could argue that you may not
			// want to send db related info back to the caller...
			return errorHandler.HTTPErr{
				Code: http.StatusBadRequest,
				Type: "database_error",
				Err:  err,
			}
		}
	} else {
		return errorHandler.HTTPErr{
			Code: http.StatusBadRequest,
			Type: "database_error",
			Err:  errors.New("Create Date not set"),
		}
	}

	// If we successfully committed the db transaction, we can consider this
	// transaction successful and return a response with the response body
	curs, err := newCreateUserResponse(usr)
	if err != nil {
		return errorHandler.HTTPErr{
			Code: http.StatusBadRequest,
			Type: "response_error",
			Err:  errors.New("Unable to setup Response"),
		}
	}

	// Encode usr struct to JSON for the response body
	json.NewEncoder(w).Encode(*curs)
	if err != nil {
		return errorHandler.HTTPErr{
			Code: http.StatusInternalServerError,
			Type: "encode_error",
			Err:  err,
		}
	}

	return nil

}

// newCreateMemberResponse wires the member object to createMemberResponse object
// if you need to perform any manipulation from your business object to the response object
// you can do it here.  For instance, here's where I convert the CreateDate from a timestamp
// to Unix time
func newCreateUserResponse(usr *appuser.User) (*appuser.CreateUserResponse, error) {
	cur := new(appuser.CreateUserResponse)
	cur.Username = usr.Username()
	cur.MobileID = usr.MobileID()
	cur.Email = usr.Email()
	cur.FirstName = usr.FirstName()
	cur.LastName = usr.LastName()
	cur.UpdateUserID = usr.UpdateUserID()
	cur.UpdateUnixTime = usr.UpdateTimestamp().Unix()

	return cur, nil
}
<commit_msg>Error handling<commit_after>package handler

import (
	"encoding/json"
	"errors"
	"net/http"

	"github.com/gilcrest/go-API-template/appuser"
	"github.com/gilcrest/go-API-template/env"
	"github.com/gilcrest/go-API-template/server/errorHandler"
)

// CreateUser creates a user in the database
func CreateUser(env *env.Env, w http.ResponseWriter, req *http.Request) error {

	// Get a new logger instance
	log := env.Logger

	log.Debug().Msg("Start handler.CreateUser")
	defer log.Debug().Msg("Finish handler.CreateUser")

	// retrieve the context from the http.Request
	ctx := req.Context()

	var err error

	// Declare cur as an instance of createUserRequest
	// Decode JSON HTTP request body into a Decoder type
	//  and unmarshal that into cur
	cur := new(appuser.CreateUserRequest)
	err = json.NewDecoder(req.Body).Decode(&cur)
	if err != nil {
		return errorHandler.HTTPErr{
			Code: http.StatusBadRequest,
			Type: "invalid_request",
			Err:  err,
		}
	}
	defer req.Body.Close()

	usr, err := appuser.NewUser(ctx, env, cur)
	if err != nil {
		// initialize an errorHandler with the default Code and Type for
		// service validations (Err is set to nil as it will be set later)
		return errorHandler.HTTPErr{
			Code: http.StatusBadRequest,
			Type: "validation_error",
			Err:  err,
		}
	}
	// Call the create method of the appUser object to validate data and write to db
	tx, err := usr.Create(ctx, env)
	if err != nil {
		return errorHandler.HTTPErr{
			Code: http.StatusBadRequest,
			Type: "validation_failed",
			Err:  err,
		}
	}

	if !usr.UpdateTimestamp().IsZero() {
		// If we have successfully written rows to the db, we commit the transaction
		// CreateDate should only be populated if the db transaction was successful
		// and everything is in order
		err = tx.Commit()
		if err != nil {
			// We return an HTTPErr here, which wraps the error
			// returned from our DB queries. You could argue that you may not
			// want to send db related info back to the caller...
			return errorHandler.HTTPErr{
				Code: http.StatusBadRequest,
				Type: "database_error",
				Err:  err,
			}
		}
	} else {
		return errorHandler.HTTPErr{
			Code: http.StatusBadRequest,
			Type: "database_error",
			Err:  errors.New("Create Date not set"),
		}
	}

	// If we successfully committed the db transaction, we can consider this
	// transaction successful and return a response with the response body
	curs, err := newCreateUserResponse(usr)
	if err != nil {
		return errorHandler.HTTPErr{
			Code: http.StatusBadRequest,
			Type: "response_error",
			Err:  errors.New("Unable to setup Response"),
		}
	}

	// Encode usr struct to JSON for the response body
	json.NewEncoder(w).Encode(*curs)
	if err != nil {
		return errorHandler.HTTPErr{
			Code: http.StatusInternalServerError,
			Type: "encode_error",
			Err:  err,
		}
	}

	return nil

}

// newCreateMemberResponse wires the member object to createMemberResponse object
// if you need to perform any manipulation from your business object to the response object
// you can do it here.  For instance, here's where I convert the CreateDate from a timestamp
// to Unix time
func newCreateUserResponse(usr *appuser.User) (*appuser.CreateUserResponse, error) {
	cur := new(appuser.CreateUserResponse)
	cur.Username = usr.Username()
	cur.MobileID = usr.MobileID()
	cur.Email = usr.Email()
	cur.FirstName = usr.FirstName()
	cur.LastName = usr.LastName()
	cur.UpdateUserID = usr.UpdateUserID()
	cur.UpdateUnixTime = usr.UpdateTimestamp().Unix()

	return cur, nil
}
<|endoftext|>


<commit_before>package js

import (
	"errors"
	log "github.com/Sirupsen/logrus"
	"github.com/loadimpact/speedboat/stats"
	"github.com/robertkrimen/otto"
	"io/ioutil"
	"net/http"
	neturl "net/url"
	"time"
)

var (
	mRequests = stats.Stat{Name: "requests", Type: stats.HistogramType, Intent: stats.TimeIntent}
	mErrors   = stats.Stat{Name: "errors", Type: stats.CounterType}

	ErrTooManyRedirects = errors.New("too many redirects")
)

type HTTPParams struct {
	Follow  bool
	Quiet   bool
	Headers map[string]string
}

type HTTPResponse struct {
	Status  int
	Headers map[string]string
	Body    string
}

func (res HTTPResponse) ToValue(vm *otto.Otto) (otto.Value, error) {
	obj, err := Make(vm, "HTTPResponse")
	if err != nil {
		return otto.UndefinedValue(), err
	}

	obj.Set("status", res.Status)
	obj.Set("headers", res.Headers)
	obj.Set("body", res.Body)

	return vm.ToValue(obj)
}

func (u *VU) HTTPRequest(method, url, body string, params HTTPParams, redirects int) (HTTPResponse, error) {
	parsedURL, err := neturl.Parse(url)
	if err != nil {
		return HTTPResponse{}, err
	}

	req := http.Request{
		Method: method,
		URL:    parsedURL,
		Header: make(http.Header),
	}

	if method == "GET" || method == "HEAD" {
		req.URL.RawQuery = body
	} else {
		// NOT IMPLEMENTED! I'm just testing stuff out.
		// req.SetBodyString(body)
	}

	for key, value := range params.Headers {
		req.Header[key] = []string{value}
	}

	startTime := time.Now()
	resp, err := u.Client.Do(&req)
	duration := time.Since(startTime)

	var status int
	var respBody []byte
	if err == nil {
		status = resp.StatusCode
		respBody, _ = ioutil.ReadAll(resp.Body)
		resp.Body.Close()
	}

	tags := stats.Tags{
		"url":    url,
		"method": method,
		"status": status,
	}

	if !params.Quiet {
		u.Collector.Add(stats.Sample{
			Stat:   &mRequests,
			Tags:   tags,
			Values: stats.Values{"duration": float64(duration)},
		})
	}

	if err != nil {
		if !params.Quiet {
			u.Collector.Add(stats.Sample{
				Stat:   &mErrors,
				Tags:   tags,
				Values: stats.Value(1),
			})
		}
		return HTTPResponse{}, err
	}

	// switch resp.StatusCode {
	// case 301, 302, 303, 307, 308:
	// 	if !params.Follow {
	// 		break
	// 	}
	// 	if redirects >= u.FollowDepth {
	// 		return HTTPResponse{}, ErrTooManyRedirects
	// 	}

	// 	redirectURL := url
	// 	resp.Header.VisitAll(func(key, value []byte) {
	// 		if string(key) != "Location" {
	// 			return
	// 		}

	// 		redirectURL = resolveRedirect(url, string(value))
	// 	})

	// 	redirectMethod := method
	// 	redirectBody := body
	// 	if status == 301 || status == 302 || status == 303 {
	// 		redirectMethod = "GET"
	// 		redirectBody = ""
	// 	}
	// 	return u.HTTPRequest(redirectMethod, redirectURL, redirectBody, params, redirects+1)
	// }

	headers := make(map[string]string)
	for key, vals := range resp.Header {
		headers[key] = vals[0]
	}

	return HTTPResponse{
		Status:  resp.StatusCode,
		Headers: headers,
		Body:    string(respBody),
	}, nil
}

func (u *VU) Sleep(t float64) {
	time.Sleep(time.Duration(t * float64(time.Second)))
}

func (u *VU) Log(level, msg string, fields map[string]interface{}) {
	e := u.Runner.logger.WithFields(log.Fields(fields))

	switch level {
	case "debug":
		e.Debug(msg)
	case "info":
		e.Info(msg)
	case "warn":
		e.Warn(msg)
	case "error":
		e.Error(msg)
	}
}
<commit_msg>[experiment] Report HTTP version<commit_after>package js

import (
	"errors"
	log "github.com/Sirupsen/logrus"
	"github.com/loadimpact/speedboat/stats"
	"github.com/robertkrimen/otto"
	"io/ioutil"
	"net/http"
	neturl "net/url"
	"time"
)

var (
	mRequests = stats.Stat{Name: "requests", Type: stats.HistogramType, Intent: stats.TimeIntent}
	mErrors   = stats.Stat{Name: "errors", Type: stats.CounterType}

	ErrTooManyRedirects = errors.New("too many redirects")
)

type HTTPParams struct {
	Follow  bool
	Quiet   bool
	Headers map[string]string
}

type HTTPResponse struct {
	Status  int
	Headers map[string]string
	Body    string
}

func (res HTTPResponse) ToValue(vm *otto.Otto) (otto.Value, error) {
	obj, err := Make(vm, "HTTPResponse")
	if err != nil {
		return otto.UndefinedValue(), err
	}

	obj.Set("status", res.Status)
	obj.Set("headers", res.Headers)
	obj.Set("body", res.Body)

	return vm.ToValue(obj)
}

func (u *VU) HTTPRequest(method, url, body string, params HTTPParams, redirects int) (HTTPResponse, error) {
	parsedURL, err := neturl.Parse(url)
	if err != nil {
		return HTTPResponse{}, err
	}

	req := http.Request{
		Method: method,
		URL:    parsedURL,
		Header: make(http.Header),
	}

	if method == "GET" || method == "HEAD" {
		req.URL.RawQuery = body
	} else {
		// NOT IMPLEMENTED! I'm just testing stuff out.
		// req.SetBodyString(body)
	}

	for key, value := range params.Headers {
		req.Header[key] = []string{value}
	}

	startTime := time.Now()
	resp, err := u.Client.Do(&req)
	duration := time.Since(startTime)

	var status int
	var respBody []byte
	if err == nil {
		status = resp.StatusCode
		respBody, _ = ioutil.ReadAll(resp.Body)
		resp.Body.Close()
	}

	tags := stats.Tags{
		"url":    url,
		"method": method,
		"status": status,
		"proto":  resp.Proto,
	}

	if !params.Quiet {
		u.Collector.Add(stats.Sample{
			Stat:   &mRequests,
			Tags:   tags,
			Values: stats.Values{"duration": float64(duration)},
		})
	}

	if err != nil {
		if !params.Quiet {
			u.Collector.Add(stats.Sample{
				Stat:   &mErrors,
				Tags:   tags,
				Values: stats.Value(1),
			})
		}
		return HTTPResponse{}, err
	}

	// switch resp.StatusCode {
	// case 301, 302, 303, 307, 308:
	// 	if !params.Follow {
	// 		break
	// 	}
	// 	if redirects >= u.FollowDepth {
	// 		return HTTPResponse{}, ErrTooManyRedirects
	// 	}

	// 	redirectURL := url
	// 	resp.Header.VisitAll(func(key, value []byte) {
	// 		if string(key) != "Location" {
	// 			return
	// 		}

	// 		redirectURL = resolveRedirect(url, string(value))
	// 	})

	// 	redirectMethod := method
	// 	redirectBody := body
	// 	if status == 301 || status == 302 || status == 303 {
	// 		redirectMethod = "GET"
	// 		redirectBody = ""
	// 	}
	// 	return u.HTTPRequest(redirectMethod, redirectURL, redirectBody, params, redirects+1)
	// }

	headers := make(map[string]string)
	for key, vals := range resp.Header {
		headers[key] = vals[0]
	}

	return HTTPResponse{
		Status:  resp.StatusCode,
		Headers: headers,
		Body:    string(respBody),
	}, nil
}

func (u *VU) Sleep(t float64) {
	time.Sleep(time.Duration(t * float64(time.Second)))
}

func (u *VU) Log(level, msg string, fields map[string]interface{}) {
	e := u.Runner.logger.WithFields(log.Fields(fields))

	switch level {
	case "debug":
		e.Debug(msg)
	case "info":
		e.Info(msg)
	case "warn":
		e.Warn(msg)
	case "error":
		e.Error(msg)
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bootstrap

import (
	"bytes"
	"flag"
	"fmt"
	"github.com/google/blueprint"
	"github.com/google/blueprint/deptools"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime/pprof"
)

var (
	outFile      string
	depFile      string
	checkFile    string
	manifestFile string
	cpuprofile   string
)

// topLevelBlueprintsFile is set by Main as a way to pass this information on to
// the bootstrap build manifest generators.  This information was not passed via
// the config object so as to allow the caller of Main to use whatever Config
// object it wants.
var topLevelBlueprintsFile string

func init() {
	flag.StringVar(&outFile, "o", "build.ninja.in", "the Ninja file to output")
	flag.StringVar(&depFile, "d", "", "the dependency file to output")
	flag.StringVar(&checkFile, "c", "", "the existing file to check against")
	flag.StringVar(&manifestFile, "m", "", "the bootstrap manifest file")
	flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file")
}

func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...string) {
	if !flag.Parsed() {
		flag.Parse()
	}

	if cpuprofile != "" {
		f, err := os.Create(cpuprofile)
		if err != nil {
			fatalf("error opening cpuprofile: %s", err)
		}
		pprof.StartCPUProfile(f)
		defer f.Close()
		defer pprof.StopCPUProfile()
	}

	ctx.RegisterModuleType("bootstrap_go_package", newGoPackageModule)
	ctx.RegisterModuleType("bootstrap_go_binary", newGoBinaryModule)
	ctx.RegisterSingletonType("bootstrap", newSingleton)

	if flag.NArg() != 1 {
		fatalf("no Blueprints file specified")
	}

	topLevelBlueprintsFile = flag.Arg(0)

	deps, errs := ctx.ParseBlueprintsFiles(topLevelBlueprintsFile)
	if len(errs) > 0 {
		fatalErrors(errs)
	}

	// Add extra ninja file dependencies
	deps = append(deps, extraNinjaFileDeps...)

	extraDeps, errs := ctx.PrepareBuildActions(config)
	if len(errs) > 0 {
		fatalErrors(errs)
	}
	deps = append(deps, extraDeps...)

	buf := bytes.NewBuffer(nil)
	err := ctx.WriteBuildFile(buf)
	if err != nil {
		fatalf("error generating Ninja file contents: %s", err)
	}

	const outFilePermissions = 0666
	err = ioutil.WriteFile(outFile, buf.Bytes(), outFilePermissions)
	if err != nil {
		fatalf("error writing %s: %s", outFile, err)
	}

	if checkFile != "" {
		checkData, err := ioutil.ReadFile(checkFile)
		if err != nil {
			fatalf("error reading %s: %s", checkFile, err)
		}

		matches := buf.Len() == len(checkData)
		if matches {
			for i, value := range buf.Bytes() {
				if value != checkData[i] {
					matches = false
					break
				}
			}
		}

		if matches {
			// The new file content matches the check-file content, so we set
			// the new file's mtime and atime to match that of the check-file.
			checkFileInfo, err := os.Stat(checkFile)
			if err != nil {
				fatalf("error stat'ing %s: %s", checkFile, err)
			}

			time := checkFileInfo.ModTime()
			err = os.Chtimes(outFile, time, time)
			if err != nil {
				fatalf("error setting timestamps for %s: %s", outFile, err)
			}
		}
	}

	if depFile != "" {
		err := deptools.WriteDepFile(depFile, outFile, deps)
		if err != nil {
			fatalf("error writing depfile: %s", err)
		}
	}

	srcDir := filepath.Dir(topLevelBlueprintsFile)
	err = removeAbandonedFiles(ctx, config, srcDir, manifestFile)
	if err != nil {
		fatalf("error removing abandoned files: %s", err)
	}
}

func fatalf(format string, args ...interface{}) {
	fmt.Printf(format, args...)
	os.Exit(1)
}

func fatalErrors(errs []error) {
	for _, err := range errs {
		switch err.(type) {
		case *blueprint.Error:
			_, _ = fmt.Printf("%s\n", err.Error())
		default:
			_, _ = fmt.Printf("internal error: %s\n", err)
		}
	}
	os.Exit(1)
}
<commit_msg>Set GOMAXPROCS to number of CPUs<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bootstrap

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime/pprof"
	"runtime"

	"github.com/google/blueprint"
	"github.com/google/blueprint/deptools"
)

var (
	outFile      string
	depFile      string
	checkFile    string
	manifestFile string
	cpuprofile   string
)

// topLevelBlueprintsFile is set by Main as a way to pass this information on to
// the bootstrap build manifest generators.  This information was not passed via
// the config object so as to allow the caller of Main to use whatever Config
// object it wants.
var topLevelBlueprintsFile string

func init() {
	flag.StringVar(&outFile, "o", "build.ninja.in", "the Ninja file to output")
	flag.StringVar(&depFile, "d", "", "the dependency file to output")
	flag.StringVar(&checkFile, "c", "", "the existing file to check against")
	flag.StringVar(&manifestFile, "m", "", "the bootstrap manifest file")
	flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file")
}

func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...string) {
	if !flag.Parsed() {
		flag.Parse()
	}

	runtime.GOMAXPROCS(runtime.NumCPU())

	if cpuprofile != "" {
		f, err := os.Create(cpuprofile)
		if err != nil {
			fatalf("error opening cpuprofile: %s", err)
		}
		pprof.StartCPUProfile(f)
		defer f.Close()
		defer pprof.StopCPUProfile()
	}

	ctx.RegisterModuleType("bootstrap_go_package", newGoPackageModule)
	ctx.RegisterModuleType("bootstrap_go_binary", newGoBinaryModule)
	ctx.RegisterSingletonType("bootstrap", newSingleton)

	if flag.NArg() != 1 {
		fatalf("no Blueprints file specified")
	}

	topLevelBlueprintsFile = flag.Arg(0)

	deps, errs := ctx.ParseBlueprintsFiles(topLevelBlueprintsFile)
	if len(errs) > 0 {
		fatalErrors(errs)
	}

	// Add extra ninja file dependencies
	deps = append(deps, extraNinjaFileDeps...)

	extraDeps, errs := ctx.PrepareBuildActions(config)
	if len(errs) > 0 {
		fatalErrors(errs)
	}
	deps = append(deps, extraDeps...)

	buf := bytes.NewBuffer(nil)
	err := ctx.WriteBuildFile(buf)
	if err != nil {
		fatalf("error generating Ninja file contents: %s", err)
	}

	const outFilePermissions = 0666
	err = ioutil.WriteFile(outFile, buf.Bytes(), outFilePermissions)
	if err != nil {
		fatalf("error writing %s: %s", outFile, err)
	}

	if checkFile != "" {
		checkData, err := ioutil.ReadFile(checkFile)
		if err != nil {
			fatalf("error reading %s: %s", checkFile, err)
		}

		matches := buf.Len() == len(checkData)
		if matches {
			for i, value := range buf.Bytes() {
				if value != checkData[i] {
					matches = false
					break
				}
			}
		}

		if matches {
			// The new file content matches the check-file content, so we set
			// the new file's mtime and atime to match that of the check-file.
			checkFileInfo, err := os.Stat(checkFile)
			if err != nil {
				fatalf("error stat'ing %s: %s", checkFile, err)
			}

			time := checkFileInfo.ModTime()
			err = os.Chtimes(outFile, time, time)
			if err != nil {
				fatalf("error setting timestamps for %s: %s", outFile, err)
			}
		}
	}

	if depFile != "" {
		err := deptools.WriteDepFile(depFile, outFile, deps)
		if err != nil {
			fatalf("error writing depfile: %s", err)
		}
	}

	srcDir := filepath.Dir(topLevelBlueprintsFile)
	err = removeAbandonedFiles(ctx, config, srcDir, manifestFile)
	if err != nil {
		fatalf("error removing abandoned files: %s", err)
	}
}

func fatalf(format string, args ...interface{}) {
	fmt.Printf(format, args...)
	os.Exit(1)
}

func fatalErrors(errs []error) {
	for _, err := range errs {
		switch err.(type) {
		case *blueprint.Error:
			_, _ = fmt.Printf("%s\n", err.Error())
		default:
			_, _ = fmt.Printf("internal error: %s\n", err)
		}
	}
	os.Exit(1)
}
<|endoftext|>


<commit_before>// Copyright 2015 Cocoon Alarm Ltd.
//
// See LICENSE file for terms and conditions.

package libflac

import (
	"crypto/md5"
	"io"
	"io/ioutil"
	"os"
	"testing"

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

func TestDecode(t *testing.T) {
	a := assert.New(t)

	d, err := NewDecoder("data/nonexistent.flac")

	a.Equal(d, (*Decoder)(nil), "decoder is nil")

	d, err = NewDecoder("data/sine24-00.flac")

	a.Equal(err, nil, "err is nil")
	a.Equal(d.Channels, 1, "channels is 1")
	a.Equal(d.Depth, 24, "depth is 24")
	a.Equal(d.Rate, 48000, "depth is 48000")

	samples := 0

	f, err := d.ReadFrame()

	a.Equal(err, nil, "err is nil")
	a.Equal(f.Channels, 1, "channels is 1")
	a.Equal(f.Depth, 24, "depth is 24")
	a.Equal(f.Rate, 48000, "depth is 48000")

	samples = samples + len(f.Buffer)

	for {
		f, err := d.ReadFrame()

		if err == nil || err == io.EOF {
			if f != nil {
				samples = samples + len(f.Buffer)
			}
		} else {
			a.Equal(err, nil, "error reported")
			break
		}

		if err == io.EOF {
			break
		}
	}

	a.Equal(samples, 200000, "all samples read")
	d.Close()
}

func TestEncode(t *testing.T) {
	a := assert.New(t)

	fileName := "data/test.flac"

	e, err := NewEncoder(fileName, 2, 24, 48000)

	a.Equal(err, nil, "err is nil")

	f := Frame{Channels: 1, Depth: 24, Rate: 48000}

	err = e.WriteFrame(f)

	a.Error(err, "channels mismatch")

	f.Channels = 2
	f.Buffer = make([]int32, 2*100)

	err = e.WriteFrame(f)

	a.Equal(err, nil, "frame encoded")

	e.Close()

	os.Remove(fileName)
}

func TestRoundTrip(t *testing.T) {
	a := assert.New(t)

	inputFile := "data/sine24-00.flac"
	outputFile := "data/test.flac"

	d, err := NewDecoder(inputFile)

	a.Equal(err, nil, "err is nil")

	e, err := NewEncoder(outputFile, d.Channels, d.Depth, d.Rate)

	samples := 0

	for {
		f, err := d.ReadFrame()
		if err == nil || err == io.EOF {
			if f != nil {
				_ = e.WriteFrame(*f)
				samples = samples + len(f.Buffer)
			}
		} else {
			a.Equal(err, nil, "error reported")
			break
		}

		if err == io.EOF {
			break
		}
	}

	a.Equal(samples, 200000, "all samples read")
	d.Close()
	e.Close()

	inFile, err := os.Open(inputFile)
	a.Equal(err, nil, "err is nil")
	outFile, err := os.Open(outputFile)
	a.Equal(err, nil, "err is nil")

	inData, _ := ioutil.ReadAll(inFile)
	outData, _ := ioutil.ReadAll(outFile)

	a.Equal(md5.Sum(inData), md5.Sum(outData), "files md5sum the same")

	os.Remove(outputFile)
}

func TestRoundTripStereo(t *testing.T) {
	a := assert.New(t)

	inputFile := "data/sine16-12.flac"
	outputFile := "data/test.flac"

	d, err := NewDecoder(inputFile)

	a.Equal(err, nil, "err is nil")

	e, err := NewEncoder(outputFile, d.Channels, d.Depth, d.Rate)

	samples := 0

	for {
		f, err := d.ReadFrame()
		if err == nil || err == io.EOF {
			if f != nil {
				_ = e.WriteFrame(*f)
				samples = samples + len(f.Buffer)
			}
		} else {
			a.Equal(err, nil, "error reported")
			break
		}

		if err == io.EOF {
			break
		}
	}

	a.Equal(samples, 400000, "all samples read")
	d.Close()
	e.Close()

	inFile, err := os.Open(inputFile)
	a.Equal(err, nil, "err is nil")
	outFile, err := os.Open(outputFile)
	a.Equal(err, nil, "err is nil")

	inData, _ := ioutil.ReadAll(inFile)
	outData, _ := ioutil.ReadAll(outFile)

	a.Equal(md5.Sum(inData), md5.Sum(outData), "files md5sum the same")

	os.Remove(outputFile)
}
<commit_msg>libflac_test.go: Remove md5sum from roundtrip tests<commit_after>// Copyright 2015 Cocoon Alarm Ltd.
//
// See LICENSE file for terms and conditions.

package libflac

import (
	"io"
	"os"
	"testing"

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

func TestDecode(t *testing.T) {
	a := assert.New(t)

	d, err := NewDecoder("data/nonexistent.flac")

	a.Equal(d, (*Decoder)(nil), "decoder is nil")

	d, err = NewDecoder("data/sine24-00.flac")

	a.Equal(err, nil, "err is nil")
	a.Equal(d.Channels, 1, "channels is 1")
	a.Equal(d.Depth, 24, "depth is 24")
	a.Equal(d.Rate, 48000, "depth is 48000")

	samples := 0

	f, err := d.ReadFrame()

	a.Equal(err, nil, "err is nil")
	a.Equal(f.Channels, 1, "channels is 1")
	a.Equal(f.Depth, 24, "depth is 24")
	a.Equal(f.Rate, 48000, "depth is 48000")

	samples = samples + len(f.Buffer)

	for {
		f, err := d.ReadFrame()

		if err == nil || err == io.EOF {
			if f != nil {
				samples = samples + len(f.Buffer)
			}
		} else {
			a.Equal(err, nil, "error reported")
			break
		}

		if err == io.EOF {
			break
		}
	}

	a.Equal(samples, 200000, "all samples read")
	d.Close()
}

func TestEncode(t *testing.T) {
	a := assert.New(t)

	fileName := "data/test.flac"

	e, err := NewEncoder(fileName, 2, 24, 48000)

	a.Equal(err, nil, "err is nil")

	f := Frame{Channels: 1, Depth: 24, Rate: 48000}

	err = e.WriteFrame(f)

	a.Error(err, "channels mismatch")

	f.Channels = 2
	f.Buffer = make([]int32, 2*100)

	err = e.WriteFrame(f)

	a.Equal(err, nil, "frame encoded")

	e.Close()

	os.Remove(fileName)
}

func TestRoundTrip(t *testing.T) {
	a := assert.New(t)

	inputFile := "data/sine24-00.flac"
	outputFile := "data/test.flac"

	d, err := NewDecoder(inputFile)

	a.Equal(err, nil, "err is nil")

	e, err := NewEncoder(outputFile, d.Channels, d.Depth, d.Rate)

	samples := 0

	for {
		f, err := d.ReadFrame()
		if err == nil || err == io.EOF {
			if f != nil {
				_ = e.WriteFrame(*f)
				samples = samples + len(f.Buffer)
			}
		} else {
			a.Equal(err, nil, "error reported")
			break
		}

		if err == io.EOF {
			break
		}
	}

	a.Equal(samples, 200000, "all samples read")
	d.Close()
	e.Close()

	os.Remove(outputFile)
}

func TestRoundTripStereo(t *testing.T) {
	a := assert.New(t)

	inputFile := "data/sine16-12.flac"
	outputFile := "data/test.flac"

	d, err := NewDecoder(inputFile)

	a.Equal(err, nil, "err is nil")

	e, err := NewEncoder(outputFile, d.Channels, d.Depth, d.Rate)

	samples := 0

	for {
		f, err := d.ReadFrame()
		if err == nil || err == io.EOF {
			if f != nil {
				_ = e.WriteFrame(*f)
				samples = samples + len(f.Buffer)
			}
		} else {
			a.Equal(err, nil, "error reported")
			break
		}

		if err == io.EOF {
			break
		}
	}

	a.Equal(samples, 400000, "all samples read")
	d.Close()
	e.Close()

	os.Remove(outputFile)
}
<|endoftext|>