<commit_before>package flags

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"runtime"
	"testing"
)

func assertCallerInfo() (string, int) {
	ptr := make([]uintptr, 15)
	n := runtime.Callers(1, ptr)

	if n == 0 {
		return "", 0
	}

	mef := runtime.FuncForPC(ptr[0])
	mefile, meline := mef.FileLine(ptr[0])

	for i := 2; i < n; i++ {
		f := runtime.FuncForPC(ptr[i])
		file, line := f.FileLine(ptr[i])

		if file != mefile {
			return file, line
		}
	}

	return mefile, meline
}

func assertErrorf(t *testing.T, format string, args ...interface{}) {
	msg := fmt.Sprintf(format, args...)

	file, line := assertCallerInfo()

	t.Errorf("%s:%d: %s", path.Base(file), line, msg)
}

func assertFatalf(t *testing.T, format string, args ...interface{}) {
	msg := fmt.Sprintf(format, args...)

	file, line := assertCallerInfo()

	t.Fatalf("%s:%d: %s", path.Base(file), line, msg)
}

func assertString(t *testing.T, a string, b string) {
	if a != b {
		assertErrorf(t, "Expected %#v, but got %#v", b, a)
	}
}

func assertStringArray(t *testing.T, a []string, b []string) {
	if len(a) != len(b) {
		assertErrorf(t, "Expected %#v, but got %#v", b, a)
		return
	}

	for i, v := range a {
		if b[i] != v {
			assertErrorf(t, "Expected %#v, but got %#v", b, a)
			return
		}
	}
}

func assertBoolArray(t *testing.T, a []bool, b []bool) {
	if len(a) != len(b) {
		assertErrorf(t, "Expected %#v, but got %#v", b, a)
		return
	}

	for i, v := range a {
		if b[i] != v {
			assertErrorf(t, "Expected %#v, but got %#v", b, a)
			return
		}
	}
}

func assertParserSuccess(t *testing.T, data interface{}, args ...string) (*Parser, []string) {
	parser := NewParser(data, Default&^PrintErrors)
	ret, err := parser.ParseArgs(args)

	if err != nil {
		t.Fatalf("Unexpected parse error: %s", err)
		return nil, nil
	}

	return parser, ret
}

func assertParseSuccess(t *testing.T, data interface{}, args ...string) []string {
	_, ret := assertParserSuccess(t, data, args...)
	return ret
}

func assertError(t *testing.T, err error, typ ErrorType, msg string) {
	if err == nil {
		assertFatalf(t, "Expected error: %s", msg)
		return
	}

	if e, ok := err.(*Error); !ok {
		assertFatalf(t, "Expected Error type, but got %#v", err)
	} else {
		if e.Type != typ {
			assertErrorf(t, "Expected error type {%s}, but got {%s}", typ, e.Type)
		}

		if e.Message != msg {
			assertErrorf(t, "Expected error message %#v, but got %#v", msg, e.Message)
		}
	}
}

func assertParseFail(t *testing.T, typ ErrorType, msg string, data interface{}, args ...string) []string {
	parser := NewParser(data, Default&^PrintErrors)
	ret, err := parser.ParseArgs(args)

	assertError(t, err, typ, msg)
	return ret
}

func diff(a, b string) (string, error) {
	atmp, err := ioutil.TempFile("", "help-diff")

	if err != nil {
		return "", err
	}

	btmp, err := ioutil.TempFile("", "help-diff")

	if err != nil {
		return "", err
	}

	if _, err := io.WriteString(atmp, a); err != nil {
		return "", err
	}

	if _, err := io.WriteString(btmp, b); err != nil {
		return "", err
	}

	ret, err := exec.Command("diff", "-u", "-d", "--label", "got", atmp.Name(), "--label", "expected", btmp.Name()).Output()

	os.Remove(atmp.Name())
	os.Remove(btmp.Name())

	if err.Error() == "exit status 1" {
		return string(ret), nil
	}

	return string(ret), err
}

func assertDiff(t *testing.T, actual, expected, msg string) {
	if actual == expected {
		return
	}

	ret, err := diff(actual, expected)

	if err != nil {
		assertErrorf(t, "Unexpected diff error: %s", err)
		assertErrorf(t, "Unexpected %s, expected:\n\n%s\n\nbut got\n\n%s", msg, expected, actual)
	} else {
		assertErrorf(t, "Unexpected %s:\n\n%s", msg, ret)
	}
}
<commit_msg>Clarify that an error was expected but did not occur<commit_after>package flags

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"runtime"
	"testing"
)

func assertCallerInfo() (string, int) {
	ptr := make([]uintptr, 15)
	n := runtime.Callers(1, ptr)

	if n == 0 {
		return "", 0
	}

	mef := runtime.FuncForPC(ptr[0])
	mefile, meline := mef.FileLine(ptr[0])

	for i := 2; i < n; i++ {
		f := runtime.FuncForPC(ptr[i])
		file, line := f.FileLine(ptr[i])

		if file != mefile {
			return file, line
		}
	}

	return mefile, meline
}

func assertErrorf(t *testing.T, format string, args ...interface{}) {
	msg := fmt.Sprintf(format, args...)

	file, line := assertCallerInfo()

	t.Errorf("%s:%d: %s", path.Base(file), line, msg)
}

func assertFatalf(t *testing.T, format string, args ...interface{}) {
	msg := fmt.Sprintf(format, args...)

	file, line := assertCallerInfo()

	t.Fatalf("%s:%d: %s", path.Base(file), line, msg)
}

func assertString(t *testing.T, a string, b string) {
	if a != b {
		assertErrorf(t, "Expected %#v, but got %#v", b, a)
	}
}

func assertStringArray(t *testing.T, a []string, b []string) {
	if len(a) != len(b) {
		assertErrorf(t, "Expected %#v, but got %#v", b, a)
		return
	}

	for i, v := range a {
		if b[i] != v {
			assertErrorf(t, "Expected %#v, but got %#v", b, a)
			return
		}
	}
}

func assertBoolArray(t *testing.T, a []bool, b []bool) {
	if len(a) != len(b) {
		assertErrorf(t, "Expected %#v, but got %#v", b, a)
		return
	}

	for i, v := range a {
		if b[i] != v {
			assertErrorf(t, "Expected %#v, but got %#v", b, a)
			return
		}
	}
}

func assertParserSuccess(t *testing.T, data interface{}, args ...string) (*Parser, []string) {
	parser := NewParser(data, Default&^PrintErrors)
	ret, err := parser.ParseArgs(args)

	if err != nil {
		t.Fatalf("Unexpected parse error: %s", err)
		return nil, nil
	}

	return parser, ret
}

func assertParseSuccess(t *testing.T, data interface{}, args ...string) []string {
	_, ret := assertParserSuccess(t, data, args...)
	return ret
}

func assertError(t *testing.T, err error, typ ErrorType, msg string) {
	if err == nil {
		assertFatalf(t, "Expected error: \"%s\", but no error occurred", msg)
		return
	}

	if e, ok := err.(*Error); !ok {
		assertFatalf(t, "Expected Error type, but got %#v", err)
	} else {
		if e.Type != typ {
			assertErrorf(t, "Expected error type {%s}, but got {%s}", typ, e.Type)
		}

		if e.Message != msg {
			assertErrorf(t, "Expected error message %#v, but got %#v", msg, e.Message)
		}
	}
}

func assertParseFail(t *testing.T, typ ErrorType, msg string, data interface{}, args ...string) []string {
	parser := NewParser(data, Default&^PrintErrors)
	ret, err := parser.ParseArgs(args)

	assertError(t, err, typ, msg)
	return ret
}

func diff(a, b string) (string, error) {
	atmp, err := ioutil.TempFile("", "help-diff")

	if err != nil {
		return "", err
	}

	btmp, err := ioutil.TempFile("", "help-diff")

	if err != nil {
		return "", err
	}

	if _, err := io.WriteString(atmp, a); err != nil {
		return "", err
	}

	if _, err := io.WriteString(btmp, b); err != nil {
		return "", err
	}

	ret, err := exec.Command("diff", "-u", "-d", "--label", "got", atmp.Name(), "--label", "expected", btmp.Name()).Output()

	os.Remove(atmp.Name())
	os.Remove(btmp.Name())

	if err.Error() == "exit status 1" {
		return string(ret), nil
	}

	return string(ret), err
}

func assertDiff(t *testing.T, actual, expected, msg string) {
	if actual == expected {
		return
	}

	ret, err := diff(actual, expected)

	if err != nil {
		assertErrorf(t, "Unexpected diff error: %s", err)
		assertErrorf(t, "Unexpected %s, expected:\n\n%s\n\nbut got\n\n%s", msg, expected, actual)
	} else {
		assertErrorf(t, "Unexpected %s:\n\n%s", msg, ret)
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Matthew Holt and The Caddy 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.

// +build gofuzz

package caddyfile

func FuzzParseCaddyfile(data []byte) (score int) {
	sb, err := Parse("Caddyfile", data)
	if err != nil {
		// if both an error is received and some ServerBlocks,
		// then the parse was able to parse partially. Mark this
		// result as interesting to push the fuzzer further through the parser.
		if sb != nil && len(sb) > 0 {
			return 1
		}
		return 0
	}
	return 1
}
<commit_msg>ci: fuzz: skip fuzz data that contains `import` (#3214)<commit_after>// Copyright 2015 Matthew Holt and The Caddy 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.

// +build gofuzz

package caddyfile

import "bytes"

func FuzzParseCaddyfile(data []byte) (score int) {
	if bytes.Contains(data, []byte("import")) {
		return -1
	}
	sb, err := Parse("Caddyfile", data)
	if err != nil {
		// if both an error is received and some ServerBlocks,
		// then the parse was able to parse partially. Mark this
		// result as interesting to push the fuzzer further through the parser.
		if sb != nil && len(sb) > 0 {
			return 1
		}
		return 0
	}
	return 1
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"time"

	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/urfave/cli"
	r "gopkg.in/gorethink/gorethink.v3"
)

func main() {

	app := cli.NewApp()

	app.Name = "Aevo Vault"
	app.Usage = "Aevo data storage API."

	app.Version = "1.0-dev"
	app.Copyright = "(c) 2017 Harrison Grodin"
	app.Authors = []cli.Author{
		cli.Author{
			Name:  "Harrison Grodin",
			Email: "grodinh@winchesterthurston.org",
		},
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "ip",
			Value: ":3000",
			Usage: "server IP address",
		},
		cli.StringFlag{
			Name:  "database-ip",
			Value: "localhost:28015",
			Usage: "database IP address",
		},
		cli.StringFlag{
			Name:  "db-data",
			Value: "data",
			Usage: "database for storing data",
		},
		cli.StringFlag{
			Name:  "db-model",
			Value: "model",
			Usage: "database for storing contexts and models",
		},
		cli.StringFlag{
			Name:        "data-primary-key",
			Value:       "time",
			Usage:       "primary data storage key",
			Destination: &primaryKey,
		},
	}

	app.Action = func(c *cli.Context) error {
		route(
			c.String("ip"),
			c.String("database-ip"),
			c.String("db-data"),
			c.String("db-model"),
		)
		return nil
	}

	app.Run(os.Args)

}

func route(IP string, databaseIP string, dbData, dbModel string) {

	router := gin.Default()
	context := router.Group("/context")

	dataSession, err := r.Connect(r.ConnectOpts{
		Address:  databaseIP,
		Database: dbData,
	})
	if err != nil {
		log.Fatalln(err)
	}
	routeState(context, dataSession)

	modelSession, err := r.Connect(r.ConnectOpts{
		Address:  databaseIP,
		Database: dbModel,
	})
	if err != nil {
		log.Fatalln(err)
	}
	routeContext(context, dataSession, modelSession)
	routeModel(context, modelSession)

	router.Run(IP)

}

var primaryKey = "time"

////////

type state map[string]interface{}
type states []state

type dataInput interface {
	parseMapTime()
}

func (state state) parseMapTime() {
	if val, ok := state[primaryKey].(string); ok {

		t, err := time.Parse(time.RFC3339, val)

		if err == nil {
			state[primaryKey] = t
		} else {
			state[primaryKey] = time.Now()
		}

	} else {
		state[primaryKey] = time.Now()
	}
}

func (states states) parseMapTime() {
	for _, state := range states {
		state.parseMapTime()
	}
}

func routeState(router gin.IRouter, session *r.Session) {
	router.GET("/:context", func(c *gin.Context) {
		res, err := r.Table(c.Param("context")).OrderBy(r.OrderByOpts{
			Index: primaryKey,
		}).Run(session)
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "context not registered"})
			return
		}
		defer res.Close()

		var data []interface{}
		if err := res.All(&data); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "error scanning database result"})
			return
		}

		c.JSON(http.StatusOK, data)
	})

	router.POST("/:context", func(c *gin.Context) {
		storeState := func(data dataInput) {
			if c.BindJSON(&data) != nil {
				c.JSON(http.StatusBadRequest, gin.H{"error": "invalid JSON data"})
				return
			}

			data.parseMapTime()

			_, err := r.Table(c.Param("context")).Insert(data, r.InsertOpts{Conflict: "replace"}).RunWrite(session)
			if err != nil {
				c.JSON(http.StatusNotFound, gin.H{"error": "context not registered"})
				return
			}

			c.JSON(http.StatusOK, data)
		}

		multi := c.DefaultQuery("multi", "false")
		if multi != "true" {
			var data state
			storeState(&data)
		} else {
			var data states
			storeState(&data)
		}
	})
}

////////

func routeContext(router gin.IRouter, dataSession *r.Session, session *r.Session) {
	router.GET("/:context/context", func(c *gin.Context) {
		res, err := r.Table("context").Get(c.Param("context")).Run(session)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "error scanning database"})
			return
		}
		defer res.Close()

		var result map[string]interface{}
		if err := res.One(&result); err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "model not found"})
			return
		}

		c.JSON(http.StatusOK, result)
	})

	router.POST("/:context/context", func(c *gin.Context) {
		var context map[string]interface{}

		if c.BindJSON(&context) != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "invalid JSON data"})
			return
		}

		invalids := []string{}
		for k, v := range context {

			if v == "id" {
				c.JSON(http.StatusBadRequest, gin.H{"error": "invalid field: 'id'"})
				return
			}

			if _, ok := v.([]interface{}); ok {
				continue
			}

			if v == "bool" {
				continue
			}

			if v == "number" {
				continue
			}

			invalids = append(invalids, k)

		}

		if len(invalids) > 0 {
			c.JSON(http.StatusBadRequest, gin.H{"error": "invalid fields", "fields": invalids})
			return
		}

		context["id"] = c.Param("context")

		if _, err := r.Table("context").Insert(context).RunWrite(session); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "duplicate context"})
			return
		}

		if _, err := r.TableCreate(context["id"], r.TableCreateOpts{PrimaryKey: "time"}).RunWrite(dataSession); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "duplicate context"})
		}

		c.JSON(http.StatusOK, context)
	})
}

////////

type model struct {
	Factors []string `json:"factors" gorethink:"factors"`
	ID      string   `json:"id" gorethink:"id"`
}

func routeModel(router gin.IRouter, session *r.Session) {

	router.GET("/:context/model", func(c *gin.Context) {
		res, err := r.Table("model").Get(c.Param("context")).Run(session)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "error scanning database"})
			return
		}
		defer res.Close()

		var result model
		if err := res.One(&result); err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "model not found"})
			return
		}

		c.JSON(http.StatusOK, result)
	})

	router.POST("/:context/model", func(c *gin.Context) {
		var factors []string
		if c.BindJSON(&factors) != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "invalid JSON data"})
			return
		}

		newModel := model{Factors: factors, ID: c.Param("context")}

		if _, err := r.Table("model").Insert(newModel, r.InsertOpts{Conflict: "replace"}).RunWrite(session); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "storage error"})
			return
		}

		c.JSON(http.StatusOK, newModel)

	})
}
<commit_msg>Implement `generate` CLI command<commit_after>package main

import (
	"log"
	"os"
	"time"

	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/urfave/cli"
	r "gopkg.in/gorethink/gorethink.v3"
)

func main() {

	app := cli.NewApp()

	app.Name = "Aevo Vault"
	app.Usage = "Aevo data storage API."

	app.Version = "1.0-dev"
	app.Copyright = "(c) 2017 Harrison Grodin"
	app.Authors = []cli.Author{
		cli.Author{
			Name:  "Harrison Grodin",
			Email: "grodinh@winchesterthurston.org",
		},
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "ip",
			Value:  ":3000",
			Usage:  "server IP address",
			EnvVar: "AEVO_IP",
		},
		cli.StringFlag{
			Name:   "database-ip",
			Value:  "localhost:28015",
			Usage:  "database IP address",
			EnvVar: "AEVO_DATABASE_IP",
		},
		cli.StringFlag{
			Name:        "db-data",
			Value:       "data",
			Usage:       "database for storing data",
			Destination: &dbData,
			EnvVar:      "AEVO_DB_DATA",
		},
		cli.StringFlag{
			Name:        "db-model",
			Value:       "model",
			Usage:       "database for storing contexts and models",
			Destination: &dbModel,
			EnvVar:      "AEVO_DB_MODEL",
		},
		cli.StringFlag{
			Name:        "data-primary-key",
			Value:       "time",
			Usage:       "primary data storage key",
			Destination: &primaryKey,
			EnvVar:      "AEVO_DATA_PRIMARY_KEY",
		},
	}

	app.Action = func(c *cli.Context) error {
		route(
			c.String("ip"),
			c.String("database-ip"),
		)
		return nil
	}

	app.Commands = []cli.Command{
		{
			Name:    "generate",
			Aliases: []string{"gen", "g"},
			Usage:   "generate databases",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "database-ip",
					Value: "localhost:28015",
					Usage: "database IP address",
				},
			},
			Action: func(c *cli.Context) error {

				session, err := r.Connect(r.ConnectOpts{
					Address: c.String("database-ip"),
				})
				if err != nil {
					log.Fatalln(err)
					return nil
				}

				if _, err := r.DBCreate(dbModel).RunWrite(session); err != nil {
					log.Fatalln("Unable to create model database: ", err)
					return nil
				}

				if _, err := r.DBCreate(dbData).RunWrite(session); err != nil {
					log.Fatalln("Unable to create data database: ", err)
					return nil
				}

				session.Use(dbModel)

				if _, err := r.TableCreate("context").RunWrite(session); err != nil {
					log.Fatalln("Unable to create context table: ", err)
					return nil
				}

				if _, err := r.TableCreate("model").RunWrite(session); err != nil {
					log.Fatalln("Unable to create model table: ", err)
					return nil
				}

				return nil
			},
		},
	}

	app.Run(os.Args)

}

var primaryKey = "time"
var dbModel, dbData = "model", "data"

func route(IP string, databaseIP string) {

	router := gin.Default()
	context := router.Group("/context")

	dataSession, err := r.Connect(r.ConnectOpts{
		Address:  databaseIP,
		Database: dbData,
	})
	if err != nil {
		log.Fatalln(err)
	}
	routeState(context, dataSession)

	modelSession, err := r.Connect(r.ConnectOpts{
		Address:  databaseIP,
		Database: dbModel,
	})
	if err != nil {
		log.Fatalln(err)
	}
	routeContext(context, dataSession, modelSession)
	routeModel(context, modelSession)

	router.Run(IP)

}

////////

type state map[string]interface{}
type states []state

type dataInput interface {
	parseMapTime()
}

func (state state) parseMapTime() {
	if val, ok := state[primaryKey].(string); ok {

		t, err := time.Parse(time.RFC3339, val)

		if err == nil {
			state[primaryKey] = t
		} else {
			state[primaryKey] = time.Now()
		}

	} else {
		state[primaryKey] = time.Now()
	}
}

func (states states) parseMapTime() {
	for _, state := range states {
		state.parseMapTime()
	}
}

func routeState(router gin.IRouter, session *r.Session) {
	router.GET("/:context", func(c *gin.Context) {
		res, err := r.Table(c.Param("context")).OrderBy(r.OrderByOpts{
			Index: primaryKey,
		}).Run(session)
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "context not registered"})
			return
		}
		defer res.Close()

		var data []interface{}
		if err := res.All(&data); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "error scanning database result"})
			return
		}

		c.JSON(http.StatusOK, data)
	})

	router.POST("/:context", func(c *gin.Context) {
		storeState := func(data dataInput) {
			if c.BindJSON(&data) != nil {
				c.JSON(http.StatusBadRequest, gin.H{"error": "invalid JSON data"})
				return
			}

			data.parseMapTime()

			_, err := r.Table(c.Param("context")).Insert(data, r.InsertOpts{Conflict: "replace"}).RunWrite(session)
			if err != nil {
				c.JSON(http.StatusNotFound, gin.H{"error": "context not registered"})
				return
			}

			c.JSON(http.StatusOK, data)
		}

		multi := c.DefaultQuery("multi", "false")
		if multi != "true" {
			var data state
			storeState(&data)
		} else {
			var data states
			storeState(&data)
		}
	})
}

////////

func routeContext(router gin.IRouter, dataSession *r.Session, session *r.Session) {
	router.GET("/:context/context", func(c *gin.Context) {
		res, err := r.Table("context").Get(c.Param("context")).Run(session)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "error scanning database"})
			return
		}
		defer res.Close()

		var result map[string]interface{}
		if err := res.One(&result); err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "model not found"})
			return
		}

		c.JSON(http.StatusOK, result)
	})

	router.POST("/:context/context", func(c *gin.Context) {
		var context map[string]interface{}

		if c.BindJSON(&context) != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "invalid JSON data"})
			return
		}

		invalids := []string{}
		for k, v := range context {

			if v == "id" {
				c.JSON(http.StatusBadRequest, gin.H{"error": "invalid field: 'id'"})
				return
			}

			if _, ok := v.([]interface{}); ok {
				continue
			}

			if v == "bool" {
				continue
			}

			if v == "number" {
				continue
			}

			invalids = append(invalids, k)

		}

		if len(invalids) > 0 {
			c.JSON(http.StatusBadRequest, gin.H{"error": "invalid fields", "fields": invalids})
			return
		}

		context["id"] = c.Param("context")

		if _, err := r.Table("context").Insert(context).RunWrite(session); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "duplicate context"})
			return
		}

		if _, err := r.TableCreate(context["id"], r.TableCreateOpts{PrimaryKey: "time"}).RunWrite(dataSession); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "duplicate context"})
		}

		c.JSON(http.StatusOK, context)
	})
}

////////

type model struct {
	Factors []string `json:"factors" gorethink:"factors"`
	ID      string   `json:"id" gorethink:"id"`
}

func routeModel(router gin.IRouter, session *r.Session) {

	router.GET("/:context/model", func(c *gin.Context) {
		res, err := r.Table("model").Get(c.Param("context")).Run(session)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "error scanning database"})
			return
		}
		defer res.Close()

		var result model
		if err := res.One(&result); err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "model not found"})
			return
		}

		c.JSON(http.StatusOK, result)
	})

	router.POST("/:context/model", func(c *gin.Context) {
		var factors []string
		if c.BindJSON(&factors) != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "invalid JSON data"})
			return
		}

		newModel := model{Factors: factors, ID: c.Param("context")}

		if _, err := r.Table("model").Insert(newModel, r.InsertOpts{Conflict: "replace"}).RunWrite(session); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "storage error"})
			return
		}

		c.JSON(http.StatusOK, newModel)

	})
}
<|endoftext|>


<commit_before>package sctp

import (
	"bytes"
	"fmt"

	"math"
	"math/rand"
	"time"

	"github.com/pkg/errors"
)

// AssociationState is an enum for the states that an Association will transition
// through while connecting
// https://tools.ietf.org/html/rfc4960#section-13.2
type AssociationState uint8

// AssociationState enums
const (
	Open AssociationState = iota + 1
	CookieEchoed
	CookieWait
	Established
	ShutdownAckSent
	ShutdownPending
	ShutdownReceived
	ShutdownSent
)

func (a AssociationState) String() string {
	switch a {
	case Open:
		return "Open"
	case CookieEchoed:
		return "CookieEchoed"
	case CookieWait:
		return "CookieWait"
	case Established:
		return "Established"
	case ShutdownPending:
		return "ShutdownPending"
	case ShutdownSent:
		return "ShutdownSent"
	case ShutdownReceived:
		return "ShutdownReceived"
	case ShutdownAckSent:
		return "ShutdownAckSent"
	default:
		return fmt.Sprintf("Invalid AssociationState %d", a)
	}
}

// Association represents an SCTP assocation
// 13.2.  Parameters Necessary per Association (i.e., the TCB)
// Peer        : Tag value to be sent in every packet and is received
// Verification: in the INIT or INIT ACK chunk.
// Tag         :
//
// My          : Tag expected in every inbound packet and sent in the
// Verification: INIT or INIT ACK chunk.
//
// Tag         :
// State       : A state variable indicating what state the association
//             : is in, i.e., COOKIE-WAIT, COOKIE-ECHOED, ESTABLISHED,
//             : SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED,
//             : SHUTDOWN-ACK-SENT.
//
//               Note: No "CLOSED" state is illustrated since if a
//               association is "CLOSED" its TCB SHOULD be removed.
type Association struct {
	peerVerificationTag uint32
	myVerificationTag   uint32
	state               AssociationState
	//peerTransportList
	//primaryPath
	//overallErrorCount
	//overallErrorThreshold
	//peerReceiverWindow (peerRwnd)
	myNextTSN   uint32 // nextTSN
	peerLastTSN uint32 // lastRcvdTSN
	//peerMissingTSN (MappingArray)
	//ackState
	//inboundStreams
	//outboundStreams
	//reassemblyQueue
	//localTransportAddressList
	//associationPTMU

	// Non-RFC internal data
	sourcePort              uint16
	destinationPort         uint16
	myMaxNumInboundStreams  uint16
	myMaxNumOutboundStreams uint16
	myReceiverWindowCredit  uint32
	myCookie                *ParamStateCookie

	// TODO are these better as channels
	// Put a blocking goroutine in port-recieve (vs callbacks)
	outboundHandler func(*Packet)
	dataHandler     func([]byte)
}

// PushPacket pushes a SCTP packet onto the assocation
func (a *Association) PushPacket(p *Packet) error {
	if err := checkPacket(p); err != nil {
		return errors.Wrap(err, "Failed validating packet")
	}

	for _, c := range p.Chunks {
		if err := a.handleChunk(p, c); err != nil {
			return errors.Wrap(err, "Failed handling chunk")
		}
	}

	return nil
}

// Close ends the SCTP Association and cleans up any state
func (a *Association) Close() error {
	return nil
}

// NewAssocation creates a new Association and the state needed to manage it
func NewAssocation(outboundHandler func(*Packet), dataHandler func([]byte)) *Association {
	rs := rand.NewSource(time.Now().UnixNano())
	r := rand.New(rs)

	return &Association{
		myVerificationTag: r.Uint32(),
		myNextTSN:         r.Uint32(),
		outboundHandler:   outboundHandler,
		dataHandler:       dataHandler,
		state:             Open,
		myMaxNumOutboundStreams: math.MaxUint16,
		myMaxNumInboundStreams:  math.MaxUint16,
		myReceiverWindowCredit:  10 * 1500, // 10 Max MTU packets buffer
	}
}

func checkPacket(p *Packet) error {
	// All packets must adhere to these rules

	// This is the SCTP sender's port number.  It can be used by the
	// receiver in combination with the source IP address, the SCTP
	// destination port, and possibly the destination IP address to
	// identify the association to which this packet belongs.  The port
	// number 0 MUST NOT be used.
	if p.SourcePort == 0 {
		return errors.New("SCTP Packet must not have a source port of 0")
	}

	// This is the SCTP port number to which this packet is destined.
	// The receiving host will use this port number to de-multiplex the
	// SCTP packet to the correct receiving endpoint/application.  The
	// port number 0 MUST NOT be used.
	if p.DestinationPort == 0 {
		return errors.New("SCTP Packet must not have a destination port of 0")
	}

	// Check values on the packet that are specific to a particular chunk type
	for _, c := range p.Chunks {
		switch c.(type) {
		case *Init:
			// An INIT or INIT ACK chunk MUST NOT be bundled with any other chunk.
			// They MUST be the only chunks present in the SCTP packets that carry
			// them.
			if len(p.Chunks) != 1 {
				return errors.New("INIT chunk must not be bundled with any other chunk")
			}

			// A packet containing an INIT chunk MUST have a zero Verification
			// Tag.
			if p.VerificationTag != 0 {
				return errors.Errorf("INIT chunk expects a verification tag of 0 on the packet when out-of-the-blue")
			}
		}
	}

	return nil
}

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

func (a *Association) handleInit(p *Packet, i *Init) (*Packet, error) {

	// Should we be setting any of these permanently until we've ACKed further?
	a.myMaxNumInboundStreams = min(i.numInboundStreams, a.myMaxNumInboundStreams)
	a.myMaxNumOutboundStreams = min(i.numOutboundStreams, a.myMaxNumOutboundStreams)
	a.peerVerificationTag = i.initiateTag
	a.sourcePort = p.DestinationPort
	a.destinationPort = p.SourcePort

	// 13.2 This is the last TSN received in sequence.  This value
	// is set initially by taking the peer's initial TSN,
	// received in the INIT or INIT ACK chunk, and
	// subtracting one from it.
	a.peerLastTSN = i.initialTSN - 1

	outbound := &Packet{}
	outbound.VerificationTag = a.peerVerificationTag
	outbound.SourcePort = a.sourcePort
	outbound.DestinationPort = a.destinationPort

	initAck := &InitAck{}

	initAck.initialTSN = a.myNextTSN
	initAck.numOutboundStreams = a.myMaxNumOutboundStreams
	initAck.numInboundStreams = a.myMaxNumInboundStreams
	initAck.initiateTag = a.myVerificationTag
	initAck.advertisedReceiverWindowCredit = a.myReceiverWindowCredit

	if a.myCookie == nil {
		a.myCookie = NewRandomStateCookie()
	}

	initAck.params = []Param{a.myCookie}

	outbound.Chunks = []Chunk{initAck}

	return outbound, nil

}

func (a *Association) handleChunk(p *Packet, c Chunk) error {
	if _, err := c.Check(); err != nil {
		errors.Wrap(err, "Failed validating chunk")
		// TODO: Create ABORT
	}

	switch c := c.(type) {
	case *Init:
		switch a.state {
		case Open:
			p, err := a.handleInit(p, c)
			if err != nil {
				return errors.Wrap(err, "Failure handling INIT")
			}
			a.outboundHandler(p)
			return nil
		case CookieEchoed:
			// https://tools.ietf.org/html/rfc4960#section-5.2.1
			// Upon receipt of an INIT in the COOKIE-ECHOED state, an endpoint MUST
			// respond with an INIT ACK using the same parameters it sent in its
			// original INIT chunk (including its Initiate Tag, unchanged)
			return errors.Errorf("TODO respond with original cookie %s", a.state)
		default:
			// 5.2.2.  Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
			//        COOKIE-WAIT, and SHUTDOWN-ACK-SENT
			return errors.Errorf("TODO Handle Init when in state %s", a.state)
		}
	case *Abort:
		fmt.Println("Abort chunk, with errors")
		for _, e := range c.ErrorCauses {
			fmt.Println(e.errorCauseCode())
		}
	case *Heartbeat:
		hbi, ok := c.params[0].(*ParamHeartbeatInfo)
		if !ok {
			fmt.Println("Failed to handle Heartbeat, no ParamHeartbeatInfo")
		}

		a.outboundHandler(&Packet{
			VerificationTag: a.peerVerificationTag,
			SourcePort:      a.sourcePort,
			DestinationPort: a.destinationPort,
			Chunks: []Chunk{&HeartbeatAck{
				params: []Param{
					&ParamHeartbeatInfo{
						HeartbeatInformation: hbi.HeartbeatInformation,
					},
				},
			}},
		})
	case *CookieEcho:
		if bytes.Equal(a.myCookie.Cookie, c.Cookie) {
			a.outboundHandler(&Packet{
				VerificationTag: a.peerVerificationTag,
				SourcePort:      a.sourcePort,
				DestinationPort: a.destinationPort,
				Chunks:          []Chunk{&CookieAck{}},
			})
		} else {
			// TODO Abort
		}
	}

	return nil
}
<commit_msg>Add example payload handling<commit_after>package sctp

import (
	"bytes"
	"fmt"

	"math"
	"math/rand"
	"time"

	"github.com/pkg/errors"
)

// AssociationState is an enum for the states that an Association will transition
// through while connecting
// https://tools.ietf.org/html/rfc4960#section-13.2
type AssociationState uint8

// AssociationState enums
const (
	Open AssociationState = iota + 1
	CookieEchoed
	CookieWait
	Established
	ShutdownAckSent
	ShutdownPending
	ShutdownReceived
	ShutdownSent
)

func (a AssociationState) String() string {
	switch a {
	case Open:
		return "Open"
	case CookieEchoed:
		return "CookieEchoed"
	case CookieWait:
		return "CookieWait"
	case Established:
		return "Established"
	case ShutdownPending:
		return "ShutdownPending"
	case ShutdownSent:
		return "ShutdownSent"
	case ShutdownReceived:
		return "ShutdownReceived"
	case ShutdownAckSent:
		return "ShutdownAckSent"
	default:
		return fmt.Sprintf("Invalid AssociationState %d", a)
	}
}

// Association represents an SCTP assocation
// 13.2.  Parameters Necessary per Association (i.e., the TCB)
// Peer        : Tag value to be sent in every packet and is received
// Verification: in the INIT or INIT ACK chunk.
// Tag         :
//
// My          : Tag expected in every inbound packet and sent in the
// Verification: INIT or INIT ACK chunk.
//
// Tag         :
// State       : A state variable indicating what state the association
//             : is in, i.e., COOKIE-WAIT, COOKIE-ECHOED, ESTABLISHED,
//             : SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED,
//             : SHUTDOWN-ACK-SENT.
//
//               Note: No "CLOSED" state is illustrated since if a
//               association is "CLOSED" its TCB SHOULD be removed.
type Association struct {
	peerVerificationTag uint32
	myVerificationTag   uint32
	state               AssociationState
	//peerTransportList
	//primaryPath
	//overallErrorCount
	//overallErrorThreshold
	//peerReceiverWindow (peerRwnd)
	myNextTSN   uint32 // nextTSN
	peerLastTSN uint32 // lastRcvdTSN
	//peerMissingTSN (MappingArray)
	//ackState
	//inboundStreams
	//outboundStreams
	reassemblyQueue []*PayloadData
	//localTransportAddressList
	//associationPTMU

	// Non-RFC internal data
	sourcePort              uint16
	destinationPort         uint16
	myMaxNumInboundStreams  uint16
	myMaxNumOutboundStreams uint16
	myReceiverWindowCredit  uint32
	myCookie                *ParamStateCookie

	// TODO are these better as channels
	// Put a blocking goroutine in port-recieve (vs callbacks)
	outboundHandler func(*Packet)
	dataHandler     func([]byte)
}

// PushPacket pushes a SCTP packet onto the assocation
func (a *Association) PushPacket(p *Packet) error {
	if err := checkPacket(p); err != nil {
		return errors.Wrap(err, "Failed validating packet")
	}

	for _, c := range p.Chunks {
		if err := a.handleChunk(p, c); err != nil {
			return errors.Wrap(err, "Failed handling chunk")
		}
	}

	return nil
}

// Close ends the SCTP Association and cleans up any state
func (a *Association) Close() error {
	return nil
}

// NewAssocation creates a new Association and the state needed to manage it
func NewAssocation(outboundHandler func(*Packet), dataHandler func([]byte)) *Association {
	rs := rand.NewSource(time.Now().UnixNano())
	r := rand.New(rs)

	return &Association{
		myVerificationTag: r.Uint32(),
		myNextTSN:         r.Uint32(),
		outboundHandler:   outboundHandler,
		dataHandler:       dataHandler,
		state:             Open,
		myMaxNumOutboundStreams: math.MaxUint16,
		myMaxNumInboundStreams:  math.MaxUint16,
		myReceiverWindowCredit:  10 * 1500, // 10 Max MTU packets buffer
	}
}

func checkPacket(p *Packet) error {
	// All packets must adhere to these rules

	// This is the SCTP sender's port number.  It can be used by the
	// receiver in combination with the source IP address, the SCTP
	// destination port, and possibly the destination IP address to
	// identify the association to which this packet belongs.  The port
	// number 0 MUST NOT be used.
	if p.SourcePort == 0 {
		return errors.New("SCTP Packet must not have a source port of 0")
	}

	// This is the SCTP port number to which this packet is destined.
	// The receiving host will use this port number to de-multiplex the
	// SCTP packet to the correct receiving endpoint/application.  The
	// port number 0 MUST NOT be used.
	if p.DestinationPort == 0 {
		return errors.New("SCTP Packet must not have a destination port of 0")
	}

	// Check values on the packet that are specific to a particular chunk type
	for _, c := range p.Chunks {
		switch c.(type) {
		case *Init:
			// An INIT or INIT ACK chunk MUST NOT be bundled with any other chunk.
			// They MUST be the only chunks present in the SCTP packets that carry
			// them.
			if len(p.Chunks) != 1 {
				return errors.New("INIT chunk must not be bundled with any other chunk")
			}

			// A packet containing an INIT chunk MUST have a zero Verification
			// Tag.
			if p.VerificationTag != 0 {
				return errors.Errorf("INIT chunk expects a verification tag of 0 on the packet when out-of-the-blue")
			}
		}
	}

	return nil
}

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

func (a *Association) handleInit(p *Packet, i *Init) (*Packet, error) {

	// Should we be setting any of these permanently until we've ACKed further?
	a.myMaxNumInboundStreams = min(i.numInboundStreams, a.myMaxNumInboundStreams)
	a.myMaxNumOutboundStreams = min(i.numOutboundStreams, a.myMaxNumOutboundStreams)
	a.peerVerificationTag = i.initiateTag
	a.sourcePort = p.DestinationPort
	a.destinationPort = p.SourcePort

	// 13.2 This is the last TSN received in sequence.  This value
	// is set initially by taking the peer's initial TSN,
	// received in the INIT or INIT ACK chunk, and
	// subtracting one from it.
	a.peerLastTSN = i.initialTSN - 1

	outbound := &Packet{}
	outbound.VerificationTag = a.peerVerificationTag
	outbound.SourcePort = a.sourcePort
	outbound.DestinationPort = a.destinationPort

	initAck := &InitAck{}

	initAck.initialTSN = a.myNextTSN
	initAck.numOutboundStreams = a.myMaxNumOutboundStreams
	initAck.numInboundStreams = a.myMaxNumInboundStreams
	initAck.initiateTag = a.myVerificationTag
	initAck.advertisedReceiverWindowCredit = a.myReceiverWindowCredit

	if a.myCookie == nil {
		a.myCookie = NewRandomStateCookie()
	}

	initAck.params = []Param{a.myCookie}

	outbound.Chunks = []Chunk{initAck}

	return outbound, nil

}

func (a *Association) handleData(p *Packet, d *PayloadData) (*Packet, error) {

	if a.peerLastTSN+1 == d.TSN {
		// This is the next TSN
		outbound := &Packet{}
		outbound.VerificationTag = a.peerVerificationTag
		outbound.SourcePort = a.sourcePort
		outbound.DestinationPort = a.destinationPort

		sack := &SelectiveAck{}

		sack.cumulativeTSNAck = d.TSN
		sack.advertisedReceiverWindowCredit = a.myReceiverWindowCredit

		outbound.Chunks = []Chunk{sack}

		a.peerLastTSN = d.TSN

		return outbound, nil
	} else if d.TSN <= a.peerLastTSN {
		// Log duplicate for next SACK
		return nil, errors.Errorf("Duplicate TSN %v", d.TSN)
	} else {
		// Check if already exists? Log duplicate for next SACK
		// If new, append to reassemblyQueue and sort
		// When generating new SACK, generate ACkGaps based on reassemblyQueue
		//a.reassemblyQueue = append(a.reassemblyQueue, d)
		return nil, errors.Errorf("GAP in TSN %v (expected) != %v", a.peerLastTSN+1, d.TSN)
	}
}

func (a *Association) handleChunk(p *Packet, c Chunk) error {
	if _, err := c.Check(); err != nil {
		errors.Wrap(err, "Failed validating chunk")
		// TODO: Create ABORT
	}

	switch c := c.(type) {
	case *Init:
		switch a.state {
		case Open:
			p, err := a.handleInit(p, c)
			if err != nil {
				return errors.Wrap(err, "Failure handling INIT")
			}
			a.outboundHandler(p)
			return nil
		case CookieEchoed:
			// https://tools.ietf.org/html/rfc4960#section-5.2.1
			// Upon receipt of an INIT in the COOKIE-ECHOED state, an endpoint MUST
			// respond with an INIT ACK using the same parameters it sent in its
			// original INIT chunk (including its Initiate Tag, unchanged)
			return errors.Errorf("TODO respond with original cookie %s", a.state)
		default:
			// 5.2.2.  Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
			//        COOKIE-WAIT, and SHUTDOWN-ACK-SENT
			return errors.Errorf("TODO Handle Init when in state %s", a.state)
		}
	case *Abort:
		fmt.Println("Abort chunk, with errors")
		for _, e := range c.ErrorCauses {
			fmt.Println(e.errorCauseCode())
		}
	case *Heartbeat:
		hbi, ok := c.params[0].(*ParamHeartbeatInfo)
		if !ok {
			fmt.Println("Failed to handle Heartbeat, no ParamHeartbeatInfo")
		}

		a.outboundHandler(&Packet{
			VerificationTag: a.peerVerificationTag,
			SourcePort:      a.sourcePort,
			DestinationPort: a.destinationPort,
			Chunks: []Chunk{&HeartbeatAck{
				params: []Param{
					&ParamHeartbeatInfo{
						HeartbeatInformation: hbi.HeartbeatInformation,
					},
				},
			}},
		})
	case *CookieEcho:
		if bytes.Equal(a.myCookie.Cookie, c.Cookie) {
			a.outboundHandler(&Packet{
				VerificationTag: a.peerVerificationTag,
				SourcePort:      a.sourcePort,
				DestinationPort: a.destinationPort,
				Chunks:          []Chunk{&CookieAck{}},
			})
		} else {
			// TODO Abort
		}
	case *PayloadData:
		p, err := a.handleData(p, c)
		if err != nil {
			return errors.Wrap(err, "Failure handling DATA")
		}
		a.outboundHandler(p)
	}

	return nil
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/aws-sdk-go/aws"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccFlowLog_basic(t *testing.T) {
	var flowLog ec2.FlowLog

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckFlowLogDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccFlowLogConfig_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckFlowLogExists("aws_flow_log.test_flow_log", &flowLog),
					testAccCheckAWSFlowLogAttributes(&flowLog),
				),
			},
		},
	})
}

func TestAccFlowLog_subnet(t *testing.T) {
	var flowLog ec2.FlowLog

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckFlowLogDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccFlowLogConfig_subnet,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckFlowLogExists("aws_flow_log.test_flow_log_subnet", &flowLog),
					testAccCheckAWSFlowLogAttributes(&flowLog),
				),
			},
		},
	})
}

func testAccCheckFlowLogExists(n string, flowLog *ec2.FlowLog) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No Flow Log ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).ec2conn
		describeOpts := &ec2.DescribeFlowLogsInput{
			FlowLogIDs: []*string{aws.String(rs.Primary.ID)},
		}
		resp, err := conn.DescribeFlowLogs(describeOpts)
		if err != nil {
			return err
		}

		if len(resp.FlowLogs) > 0 {
			*flowLog = *resp.FlowLogs[0]
			return nil
		}
		return fmt.Errorf("No Flow Logs found for id (%s)", rs.Primary.ID)
	}
}

func testAccCheckAWSFlowLogAttributes(flowLog *ec2.FlowLog) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if flowLog.FlowLogStatus != nil && *flowLog.FlowLogStatus == "ACTIVE" {
			return nil
		}
		if flowLog.FlowLogStatus == nil {
			return fmt.Errorf("Flow Log status is not ACTIVE, is nil")
		} else {
			return fmt.Errorf("Flow Log status is not ACTIVE, got: %s", *flowLog.FlowLogStatus)
		}
	}
}

func testAccCheckFlowLogDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_flow_log" {
			continue
		}

		return nil
	}

	return nil
}

var testAccFlowLogConfig_basic = `
resource "aws_vpc" "default" {
        cidr_block = "10.0.0.0/16"
        tags {
                Name = "tf-flow-log-test"
        }
}

resource "aws_subnet" "test_subnet" {
        vpc_id = "${aws_vpc.default.id}"
        cidr_block = "10.0.1.0/24"

        tags {
                Name = "tf-flow-test"
        }
}

resource "aws_iam_role" "test_role" {
    name = "test_role"
    assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "ec2.amazonaws.com"
        ]
      },
      "Action": [
        "sts:AssumeRole"
      ]
    }
  ]
}
EOF
}

resource "aws_flow_log" "test_flow_log" {
        # log_group_name needs to exist before hand
        # until we have a CloudWatch Log Group Resource
        log_group_name = "tf-test-log-group"
        iam_role_arn = "${aws_iam_role.test_role.arn}"
        vpc_id = "${aws_vpc.default.id}"
        traffic_type = "ALL"
}

resource "aws_flow_log" "test_flow_log_subnet" {
        # log_group_name needs to exist before hand
        # until we have a CloudWatch Log Group Resource
        log_group_name = "tf-test-log-group"
        iam_role_arn = "${aws_iam_role.test_role.arn}"
        subnet_id = "${aws_subnet.test_subnet.id}"
        traffic_type = "ALL"
}
`

var testAccFlowLogConfig_subnet = `
resource "aws_vpc" "default" {
        cidr_block = "10.0.0.0/16"
        tags {
                Name = "tf-flow-log-test"
        }
}

resource "aws_subnet" "test_subnet" {
        vpc_id = "${aws_vpc.default.id}"
        cidr_block = "10.0.1.0/24"

        tags {
                Name = "tf-flow-test"
        }
}

resource "aws_iam_role" "test_role" {
    name = "test_role"
    assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "ec2.amazonaws.com"
        ]
      },
      "Action": [
        "sts:AssumeRole"
      ]
    }
  ]
}
EOF
}

resource "aws_flow_log" "test_flow_log_subnet" {
        # log_group_name needs to exist before hand
        # until we have a CloudWatch Log Group Resource
        log_group_name = "tf-test-log-group"
        iam_role_arn = "${aws_iam_role.test_role.arn}"
        subnet_id = "${aws_subnet.test_subnet.id}"
        traffic_type = "ALL"
}
`
<commit_msg>update test; fix import, interpolate ENV var for log name<commit_after>package aws

import (
	"fmt"
	"os"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccFlowLog_basic(t *testing.T) {
	var flowLog ec2.FlowLog
	lgn := os.Getenv("LOG_GROUP_NAME")

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckFlowLogDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: fmt.Sprintf(testAccFlowLogConfig_basic, lgn),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckFlowLogExists("aws_flow_log.test_flow_log", &flowLog),
					testAccCheckAWSFlowLogAttributes(&flowLog),
				),
			},
		},
	})
}

func TestAccFlowLog_subnet(t *testing.T) {
	var flowLog ec2.FlowLog
	lgn := os.Getenv("LOG_GROUP_NAME")

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckFlowLogDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: fmt.Sprintf(testAccFlowLogConfig_subnet, lgn),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckFlowLogExists("aws_flow_log.test_flow_log_subnet", &flowLog),
					testAccCheckAWSFlowLogAttributes(&flowLog),
				),
			},
		},
	})
}

func testAccCheckFlowLogExists(n string, flowLog *ec2.FlowLog) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No Flow Log ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).ec2conn
		describeOpts := &ec2.DescribeFlowLogsInput{
			FlowLogIDs: []*string{aws.String(rs.Primary.ID)},
		}
		resp, err := conn.DescribeFlowLogs(describeOpts)
		if err != nil {
			return err
		}

		if len(resp.FlowLogs) > 0 {
			*flowLog = *resp.FlowLogs[0]
			return nil
		}
		return fmt.Errorf("No Flow Logs found for id (%s)", rs.Primary.ID)
	}
}

func testAccCheckAWSFlowLogAttributes(flowLog *ec2.FlowLog) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if flowLog.FlowLogStatus != nil && *flowLog.FlowLogStatus == "ACTIVE" {
			return nil
		}
		if flowLog.FlowLogStatus == nil {
			return fmt.Errorf("Flow Log status is not ACTIVE, is nil")
		} else {
			return fmt.Errorf("Flow Log status is not ACTIVE, got: %s", *flowLog.FlowLogStatus)
		}
	}
}

func testAccCheckFlowLogDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_flow_log" {
			continue
		}

		return nil
	}

	return nil
}

var testAccFlowLogConfig_basic = `
resource "aws_vpc" "default" {
        cidr_block = "10.0.0.0/16"
        tags {
                Name = "tf-flow-log-test"
        }
}

resource "aws_subnet" "test_subnet" {
        vpc_id = "${aws_vpc.default.id}"
        cidr_block = "10.0.1.0/24"

        tags {
                Name = "tf-flow-test"
        }
}

resource "aws_iam_role" "test_role" {
    name = "test_role"
    assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "ec2.amazonaws.com"
        ]
      },
      "Action": [
        "sts:AssumeRole"
      ]
    }
  ]
}
EOF
}

resource "aws_flow_log" "test_flow_log" {
        # log_group_name needs to exist before hand
        # until we have a CloudWatch Log Group Resource
        log_group_name = "tf-test-log-group"
        iam_role_arn = "${aws_iam_role.test_role.arn}"
        vpc_id = "${aws_vpc.default.id}"
        traffic_type = "ALL"
}

resource "aws_flow_log" "test_flow_log_subnet" {
        # log_group_name needs to exist before hand
        # until we have a CloudWatch Log Group Resource
        log_group_name = "%s"
        iam_role_arn = "${aws_iam_role.test_role.arn}"
        subnet_id = "${aws_subnet.test_subnet.id}"
        traffic_type = "ALL"
}
`

var testAccFlowLogConfig_subnet = `
resource "aws_vpc" "default" {
        cidr_block = "10.0.0.0/16"
        tags {
                Name = "tf-flow-log-test"
        }
}

resource "aws_subnet" "test_subnet" {
        vpc_id = "${aws_vpc.default.id}"
        cidr_block = "10.0.1.0/24"

        tags {
                Name = "tf-flow-test"
        }
}

resource "aws_iam_role" "test_role" {
    name = "test_role"
    assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "ec2.amazonaws.com"
        ]
      },
      "Action": [
        "sts:AssumeRole"
      ]
    }
  ]
}
EOF
}

resource "aws_flow_log" "test_flow_log_subnet" {
        # log_group_name needs to exist before hand
        # until we have a CloudWatch Log Group Resource
        log_group_name = "%s"
        iam_role_arn = "${aws_iam_role.test_role.arn}"
        subnet_id = "${aws_subnet.test_subnet.id}"
        traffic_type = "ALL"
}
`
<|endoftext|>


<commit_before>package main

import (
	"os"
	"syscall"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"

	commonDb "github.com/Cepave/open-falcon-backend/common/db"
	commonGin "github.com/Cepave/open-falcon-backend/common/gin"
	log "github.com/Cepave/open-falcon-backend/common/logruslog"
	commonOs "github.com/Cepave/open-falcon-backend/common/os"
	commonQueue "github.com/Cepave/open-falcon-backend/common/queue"
	"github.com/Cepave/open-falcon-backend/common/vipercfg"
	"github.com/Cepave/open-falcon-backend/modules/nqm-mng/rdb"
	"github.com/Cepave/open-falcon-backend/modules/nqm-mng/restful"
	"github.com/Cepave/open-falcon-backend/modules/nqm-mng/service/queue"
)

var logger = log.NewDefaultLogger("INFO")

func main() {
	/**
	 * Initialize loader of configurations
	 */
	confLoader := vipercfg.NewOwlConfigLoader()
	confLoader.FlagDefiner = pflagDefine

	confLoader.ProcessTrueValueCallbacks()
	// :~)

	config := confLoader.MustLoadConfigFile()

	rdb.InitRdb(toRdbConfig(config))
	restful.InitGin(toGinConfig(config))
	restful.InitCache(toCacheConfig(config))
	queue.InitNqmHeartbeat(toNqmHeartbeatConfig(config))

	commonOs.HoldingAndWaitSignal(exitApp, syscall.SIGINT, syscall.SIGTERM)
}

func exitApp(signal os.Signal) {
	rdb.ReleaseRdb()
}

func toGinConfig(config *viper.Viper) *commonGin.GinConfig {
	return &commonGin.GinConfig{
		Mode: gin.ReleaseMode,
		Host: config.GetString("restful.listen.host"),
		Port: uint16(config.GetInt("restful.listen.port")),
	}
}

func toRdbConfig(config *viper.Viper) *commonDb.DbConfig {
	return &commonDb.DbConfig{
		Dsn:     config.GetString("rdb.dsn"),
		MaxIdle: config.GetInt("rdb.maxIdle"),
	}
}

func toCacheConfig(config *viper.Viper) *restful.CacheConfig {
	return &restful.CacheConfig{
		Size:     config.GetInt("nqm.pingList.cache.size"),
		Lifetime: config.GetInt("nqm.pingList.cache.lifetime"),
	}
}

func toNqmHeartbeatConfig(config *viper.Viper) *commonQueue.Config {
	return &commonQueue.Config{
		Num: config.GetInt("heartbeat.nqm.batchSize"),
		Dur: time.Duration(config.GetInt("heartbeat.nqm.duration")) * time.Second,
	}
}

func pflagDefine() {
	pflag.StringP("config", "c", "cfg.json", "configuration file")
	pflag.BoolP("help", "h", false, "usage")
}
<commit_msg>[OWL-1730][nqm-mng] Add `CloseNqmHeartbeat()`<commit_after>package main

import (
	"os"
	"syscall"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"

	commonDb "github.com/Cepave/open-falcon-backend/common/db"
	commonGin "github.com/Cepave/open-falcon-backend/common/gin"
	log "github.com/Cepave/open-falcon-backend/common/logruslog"
	commonOs "github.com/Cepave/open-falcon-backend/common/os"
	commonQueue "github.com/Cepave/open-falcon-backend/common/queue"
	"github.com/Cepave/open-falcon-backend/common/vipercfg"
	"github.com/Cepave/open-falcon-backend/modules/nqm-mng/rdb"
	"github.com/Cepave/open-falcon-backend/modules/nqm-mng/restful"
	"github.com/Cepave/open-falcon-backend/modules/nqm-mng/service/queue"
)

var logger = log.NewDefaultLogger("INFO")

func main() {
	/**
	 * Initialize loader of configurations
	 */
	confLoader := vipercfg.NewOwlConfigLoader()
	confLoader.FlagDefiner = pflagDefine

	confLoader.ProcessTrueValueCallbacks()
	// :~)

	config := confLoader.MustLoadConfigFile()

	rdb.InitRdb(toRdbConfig(config))
	restful.InitGin(toGinConfig(config))
	restful.InitCache(toCacheConfig(config))
	queue.InitNqmHeartbeat(toNqmHeartbeatConfig(config))

	commonOs.HoldingAndWaitSignal(exitApp, syscall.SIGINT, syscall.SIGTERM)
}

func exitApp(signal os.Signal) {
	queue.CloseNqmHeartbeat()
	rdb.ReleaseRdb()
}

func toGinConfig(config *viper.Viper) *commonGin.GinConfig {
	return &commonGin.GinConfig{
		Mode: gin.ReleaseMode,
		Host: config.GetString("restful.listen.host"),
		Port: uint16(config.GetInt("restful.listen.port")),
	}
}

func toRdbConfig(config *viper.Viper) *commonDb.DbConfig {
	return &commonDb.DbConfig{
		Dsn:     config.GetString("rdb.dsn"),
		MaxIdle: config.GetInt("rdb.maxIdle"),
	}
}

func toCacheConfig(config *viper.Viper) *restful.CacheConfig {
	return &restful.CacheConfig{
		Size:     config.GetInt("nqm.pingList.cache.size"),
		Lifetime: config.GetInt("nqm.pingList.cache.lifetime"),
	}
}

func toNqmHeartbeatConfig(config *viper.Viper) *commonQueue.Config {
	return &commonQueue.Config{
		Num: config.GetInt("heartbeat.nqm.batchSize"),
		Dur: time.Duration(config.GetInt("heartbeat.nqm.duration")) * time.Second,
	}
}

func pflagDefine() {
	pflag.StringP("config", "c", "cfg.json", "configuration file")
	pflag.BoolP("help", "h", false, "usage")
}
<|endoftext|>


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

package auth

import (
	"crypto/tls"
	"log"
	"os"
	"time"

	"upspin.io/access"
	"upspin.io/errors"
	"upspin.io/upspin"
	"upspin.io/user/usercache"
)

// Config holds the configuration parameters for instantiating a server (HTTP or gRPC).
type Config struct {
	// Lookup looks up user keys.
	Lookup func(userName upspin.UserName) ([]upspin.PublicKey, error)

	// AllowUnauthenticatedConnections allows unauthenticated connections, making it the caller's
	// responsibility to check Handler.IsAuthenticated.
	AllowUnauthenticatedConnections bool

	// TimeFunc returns the current time. If nil, time.Now() will be used. Mostly only used for testing.
	TimeFunc func() time.Time
}

const (
	userServiceAddr = "upspin.io:5582"
)

// NewDefaultTLSConfig creates a new TLS config based on the certificate files given.
func NewDefaultTLSConfig(certFile string, certKeyFile string) (*tls.Config, error) {
	const NewDefaultTLSConfig = "NewDefaultTLSConfig"
	certReadable, err := isReadableFile(certFile)
	if err != nil {
		return nil, errors.E(NewDefaultTLSConfig, errors.Invalid, errors.Errorf("SSL certificate in %q: %q", certFile, err))
	}
	if !certReadable {
		return nil, errors.E(NewDefaultTLSConfig, errors.Invalid, errors.Errorf("certificate file %q not readable", certFile))
	}
	keyReadable, err := isReadableFile(certKeyFile)
	if err != nil {
		return nil, errors.E(NewDefaultTLSConfig, errors.Invalid, errors.Errorf("SSL key in %q: %v", certKeyFile, err))
	}
	if !keyReadable {
		return nil, errors.E(NewDefaultTLSConfig, errors.Invalid, errors.Errorf("certificate key file %q not readable", certKeyFile))
	}

	cert, err := tls.LoadX509KeyPair(certFile, certKeyFile)
	if err != nil {
		return nil, errors.E(NewDefaultTLSConfig, err)
	}

	tlsConfig := &tls.Config{
		CipherSuites: []uint16{
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		},
		MinVersion:               tls.VersionTLS12,
		PreferServerCipherSuites: true, // Use our choice, not the client's choice
		CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
		Certificates:             []tls.Certificate{cert},
	}
	tlsConfig.BuildNameToCertificate()
	return tlsConfig, nil
}

// PublicUserKeyService returns a Lookup function that looks up users public keys.
// The lookup function returned is bound to a well-known public Upspin user service.
func PublicUserKeyService() func(userName upspin.UserName) ([]upspin.PublicKey, error) {
	e := upspin.Endpoint{
		Transport: upspin.Remote,
		NetAddr:   upspin.NetAddr(userServiceAddr),
	}
	context := &upspin.Context{
		User: e,
	}
	user := usercache.New(context)
	return func(userName upspin.UserName) ([]upspin.PublicKey, error) {
		log.Printf("Calling User.Lookup for user %s", userName)
		_, keys, err := user.Lookup(userName)
		log.Printf("Lookup answered: %v, %v", keys, err)
		return keys, errors.E("PublicUserKeyService", err)
	}
}

// isReadableFile reports whether the file exists and is readable.
// If the error is non-nil, it means there might be a file or directory
// with that name but we cannot read it.
func isReadableFile(path string) (bool, error) {
	// Is it stattable and is it a plain file?
	info, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil // Item does not exist.
		}
		return false, err // Item is problematic.
	}
	if info.IsDir() {
		return false, errors.Str("is directory")
	}
	// Is it readable?
	fd, err := os.Open(path)
	if err != nil {
		return false, access.ErrPermissionDenied
	}
	fd.Close()
	return true, nil // Item exists and is readable.
}
<commit_msg>auth: prevent wrapping the error if it's nil<commit_after>// Copyright 2016 The Upspin Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package auth

import (
	"crypto/tls"
	"log"
	"os"
	"time"

	"upspin.io/access"
	"upspin.io/errors"
	"upspin.io/upspin"
	"upspin.io/user/usercache"
)

// Config holds the configuration parameters for instantiating a server (HTTP or gRPC).
type Config struct {
	// Lookup looks up user keys.
	Lookup func(userName upspin.UserName) ([]upspin.PublicKey, error)

	// AllowUnauthenticatedConnections allows unauthenticated connections, making it the caller's
	// responsibility to check Handler.IsAuthenticated.
	AllowUnauthenticatedConnections bool

	// TimeFunc returns the current time. If nil, time.Now() will be used. Mostly only used for testing.
	TimeFunc func() time.Time
}

const (
	userServiceAddr = "upspin.io:5582"
)

// NewDefaultTLSConfig creates a new TLS config based on the certificate files given.
func NewDefaultTLSConfig(certFile string, certKeyFile string) (*tls.Config, error) {
	const NewDefaultTLSConfig = "NewDefaultTLSConfig"
	certReadable, err := isReadableFile(certFile)
	if err != nil {
		return nil, errors.E(NewDefaultTLSConfig, errors.Invalid, errors.Errorf("SSL certificate in %q: %q", certFile, err))
	}
	if !certReadable {
		return nil, errors.E(NewDefaultTLSConfig, errors.Invalid, errors.Errorf("certificate file %q not readable", certFile))
	}
	keyReadable, err := isReadableFile(certKeyFile)
	if err != nil {
		return nil, errors.E(NewDefaultTLSConfig, errors.Invalid, errors.Errorf("SSL key in %q: %v", certKeyFile, err))
	}
	if !keyReadable {
		return nil, errors.E(NewDefaultTLSConfig, errors.Invalid, errors.Errorf("certificate key file %q not readable", certKeyFile))
	}

	cert, err := tls.LoadX509KeyPair(certFile, certKeyFile)
	if err != nil {
		return nil, errors.E(NewDefaultTLSConfig, err)
	}

	tlsConfig := &tls.Config{
		CipherSuites: []uint16{
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		},
		MinVersion:               tls.VersionTLS12,
		PreferServerCipherSuites: true, // Use our choice, not the client's choice
		CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
		Certificates:             []tls.Certificate{cert},
	}
	tlsConfig.BuildNameToCertificate()
	return tlsConfig, nil
}

// PublicUserKeyService returns a Lookup function that looks up users public keys.
// The lookup function returned is bound to a well-known public Upspin user service.
func PublicUserKeyService() func(userName upspin.UserName) ([]upspin.PublicKey, error) {
	e := upspin.Endpoint{
		Transport: upspin.Remote,
		NetAddr:   upspin.NetAddr(userServiceAddr),
	}
	context := &upspin.Context{
		User: e,
	}
	user := usercache.New(context)
	return func(userName upspin.UserName) ([]upspin.PublicKey, error) {
		log.Printf("Calling User.Lookup for user %s", userName)
		_, keys, err := user.Lookup(userName)
		log.Printf("Lookup answered: %v, %v", keys, err)
		if err != nil {
			return nil, errors.E("PublicUserKeyService", err)
		}
		return keys, nil
	}
}

// isReadableFile reports whether the file exists and is readable.
// If the error is non-nil, it means there might be a file or directory
// with that name but we cannot read it.
func isReadableFile(path string) (bool, error) {
	// Is it stattable and is it a plain file?
	info, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil // Item does not exist.
		}
		return false, err // Item is problematic.
	}
	if info.IsDir() {
		return false, errors.Str("is directory")
	}
	// Is it readable?
	fd, err := os.Open(path)
	if err != nil {
		return false, access.ErrPermissionDenied
	}
	fd.Close()
	return true, nil // Item exists and is readable.
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"image"
	"image/color"
	"image/png"
	"math"
	"os"
	"strconv"
	"time"
)

// WIDTH defines the width of the created image
const WIDTH = 640

// HEIGHT defines the height of the created image
const HEIGHT = 400

func euclideanDistance(x1, y1, x2, y2 int) float64 {
	return math.Sqrt(math.Pow(float64(x2-x1), 2) + math.Pow(float64(y2-y1), 2))
}

func fivePoints(randNum int64) [5][2]int {
	var result [5][2]int
	for i, d := range [5]int64{7, 11, 13, 17, 19} {
		x := (int64(randNum/d) + (randNum % (135 * d))) % WIDTH
		y := (int64(3*randNum/d) + (randNum % (287 * d))) % HEIGHT
		result[i][0] = int(x)
		result[i][1] = int(y)
	}
	return result
}

func drawRandom(img *image.RGBA, randNum int64) {
	five := fivePoints(randNum)
	moreWhite := func(v int64) int64 {
		return int64((220*v)/256) + 36
	}

	for x := 0; x < WIDTH; x++ {
		for y := 0; y < HEIGHT; y++ {
			d1 := euclideanDistance(x, y, five[0][0], five[0][1]) + 2*euclideanDistance(x, y, five[1][0], five[1][1])
			d2 := euclideanDistance(x, y, five[2][0], five[2][1]) + d1 - 5*euclideanDistance(x, y, five[3][0], five[3][1])
			d3 := euclideanDistance(x, y, five[4][0], five[4][1])

			r := moreWhite(int64(d1) % 256)
			g := moreWhite(int64(d2) % 256)
			b := moreWhite(int64(d3) % 256)

			c := color.RGBA{uint8(r), uint8(g), uint8(b), 255}
			img.Set(x, y, c)
		}
	}
}

// Draw actually draws an image based on `randNum` and stores the result at `filepath`
func Draw(filepath string, randNum int64) error {
	img := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{WIDTH, HEIGHT}})

	drawRandom(img, randNum)

	fd, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer fd.Close()

	return png.Encode(fd, img)
}

func main() {
	var num int64
	var filepath string

	switch len(os.Args) {
	case 1:
		num = time.Now().Unix()
		fmt.Printf("Using current time as random seed: %d\n", num)
	case 2:
		filepath = "randimg.png"
		fallthrough
	case 3:
		n, err := strconv.Atoi(os.Args[1])
		if err != nil {
			panic(fmt.Errorf("Expected integer as positional argument; got '%s'", os.Args[2]))
		}
		num = int64(n)
		filepath = os.Args[2]
	default:
		panic(fmt.Errorf("Unknown arguments; ./randimg <integer> <output.png>"))
	}

	if err := Draw(filepath, num); err != nil {
		panic(err)
	}
}
<commit_msg>Fix CLI bug in randimg.<commit_after>package main

import (
	"fmt"
	"image"
	"image/color"
	"image/png"
	"math"
	"os"
	"strconv"
	"time"
)

// WIDTH defines the width of the created image
const WIDTH = 640

// HEIGHT defines the height of the created image
const HEIGHT = 400

func euclideanDistance(x1, y1, x2, y2 int) float64 {
	return math.Sqrt(math.Pow(float64(x2-x1), 2) + math.Pow(float64(y2-y1), 2))
}

func fivePoints(randNum int64) [5][2]int {
	var result [5][2]int
	for i, d := range [5]int64{7, 11, 13, 17, 19} {
		x := (int64(randNum/d) + (randNum % (135 * d))) % WIDTH
		y := (int64(3*randNum/d) + (randNum % (287 * d))) % HEIGHT
		result[i][0] = int(x)
		result[i][1] = int(y)
	}
	return result
}

func drawRandom(img *image.RGBA, randNum int64) {
	five := fivePoints(randNum)
	moreWhite := func(v int64) int64 {
		return int64((220*v)/256) + 36
	}

	for x := 0; x < WIDTH; x++ {
		for y := 0; y < HEIGHT; y++ {
			d1 := euclideanDistance(x, y, five[0][0], five[0][1]) + 2*euclideanDistance(x, y, five[1][0], five[1][1])
			d2 := euclideanDistance(x, y, five[2][0], five[2][1]) + d1 - 5*euclideanDistance(x, y, five[3][0], five[3][1])
			d3 := euclideanDistance(x, y, five[4][0], five[4][1])

			r := moreWhite(int64(d1) % 256)
			g := moreWhite(int64(d2) % 256)
			b := moreWhite(int64(d3) % 256)

			c := color.RGBA{uint8(r), uint8(g), uint8(b), 255}
			img.Set(x, y, c)
		}
	}
}

// Draw actually draws an image based on `randNum` and stores the result at `filepath`
func Draw(filepath string, randNum int64) error {
	img := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{WIDTH, HEIGHT}})

	drawRandom(img, randNum)

	fd, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer fd.Close()

	return png.Encode(fd, img)
}

func main() {
	var num int64
	var filepath string

	switch len(os.Args) {
	case 1:
		num = time.Now().Unix()
		fmt.Printf("Using current time as random seed: %d\n", num)
	case 2:
		filepath = "randimg.png"
		fallthrough
	case 3:
		n, err := strconv.Atoi(os.Args[1])
		if err != nil {
			panic(fmt.Errorf("Expected integer as positional argument; got '%s'", os.Args[1]))
		}
		num = int64(n)
		if len(os.Args) > 2 {
			filepath = os.Args[2]
		}
	default:
		panic(fmt.Errorf("usage: ./randimg <integer> <output.png>"))
	}

	if err := Draw(filepath, num); err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package gps

import (
	"fmt"
	"net/url"
	"path/filepath"

	"github.com/Masterminds/vcs"
)

type source interface {
	checkExistence(projectExistence) bool
	exportVersionTo(Version, string) error
	getManifestAndLock(ProjectRoot, Version) (Manifest, Lock, error)
	listPackages(ProjectRoot, Version) (PackageTree, error)
	listVersions() ([]Version, error)
	revisionPresentIn(ProjectRoot, Revision) (bool, error)
}

// TODO(sdboyer) de-export these fields
type projectDataCache struct {
	Version  string                   `json:"version"` // TODO(sdboyer) use this
	Infos    map[Revision]projectInfo `json:"infos"`
	Packages map[Revision]PackageTree `json:"packages"`
	VMap     map[Version]Revision     `json:"vmap"`
	RMap     map[Revision][]Version   `json:"rmap"`
	// granular mutexes for each map. this has major complexity costs, so we
	// handle elsewhere - but keep these mutexes here as a TODO(sdboyer) to
	// remind that we may want to do this eventually
	//imut, pmut, vmut, rmut sync.RWMutex
}

func newDataCache() *projectDataCache {
	return &projectDataCache{
		Infos:    make(map[Revision]projectInfo),
		Packages: make(map[Revision]PackageTree),
		VMap:     make(map[Version]Revision),
		RMap:     make(map[Revision][]Version),
	}
}

type maybeSource interface {
	try(cachedir string, an ProjectAnalyzer) (source, error)
}

type maybeSources []maybeSource

type maybeGitSource struct {
	n   string
	url *url.URL
}

func (s maybeGitSource) try(cachedir string, an ProjectAnalyzer) (source, error) {
	path := filepath.Join(cachedir, "sources", sanitizer.Replace(s.url.String()))
	pm := &gitSource{
		baseSource: baseSource{
			an: an,
			dc: newDataCache(),
			crepo: &repo{
				r:     vcs.NewGitRepo(path, s.url.String()),
				rpath: path,
			},
		},
	}

	_, err := pm.ListVersions()
	if err != nil {
		return nil, err
		//} else if pm.ex.f&existsUpstream == existsUpstream {
		//return pm, nil
	}

	return pm, nil
}

type baseSource struct {
	// Object for the cache repository
	crepo *repo

	// Indicates the extent to which we have searched for, and verified, the
	// existence of the project/repo.
	ex existence

	// ProjectAnalyzer used to fulfill getManifestAndLock
	an ProjectAnalyzer

	// Whether the cache has the latest info on versions
	cvsync bool

	// The project metadata cache. This is persisted to disk, for reuse across
	// solver runs.
	// TODO(sdboyer) protect with mutex
	dc *projectDataCache
}

func (bs *baseSource) getManifestAndLock(r ProjectRoot, v Version) (Manifest, Lock, error) {
	if err := bs.ensureCacheExistence(); err != nil {
		return nil, nil, err
	}

	if r, exists := bs.dc.VMap[v]; exists {
		if pi, exists := bs.dc.Infos[r]; exists {
			return pi.Manifest, pi.Lock, nil
		}
	}

	bs.crepo.mut.Lock()
	var err error
	if !bs.crepo.synced {
		err = bs.crepo.r.Update()
		if err != nil {
			return nil, nil, fmt.Errorf("Could not fetch latest updates into repository")
		}
		bs.crepo.synced = true
	}

	// Always prefer a rev, if it's available
	if pv, ok := v.(PairedVersion); ok {
		err = bs.crepo.r.UpdateVersion(pv.Underlying().String())
	} else {
		err = bs.crepo.r.UpdateVersion(v.String())
	}
	bs.crepo.mut.Unlock()
	if err != nil {
		// TODO(sdboyer) More-er proper-er error
		panic(fmt.Sprintf("canary - why is checkout/whatever failing: %s %s %s", bs.n, v.String(), err))
	}

	bs.crepo.mut.RLock()
	m, l, err := bs.an.DeriveManifestAndLock(bs.crepo.rpath, r)
	// TODO(sdboyer) cache results
	bs.crepo.mut.RUnlock()

	if err == nil {
		if l != nil {
			l = prepLock(l)
		}

		// If m is nil, prebsanifest will provide an empty one.
		pi := projectInfo{
			Manifest: prebsanifest(m),
			Lock:     l,
		}

		// TODO(sdboyer) this just clobbers all over and ignores the paired/unpaired
		// distinction; serious fix is needed
		if r, exists := bs.dc.VMap[v]; exists {
			bs.dc.Infos[r] = pi
		}

		return pi.Manifest, pi.Lock, nil
	}

	return nil, nil, err
}

type gitSource struct {
	bs baseSource
}
<commit_msg>Pull most of projectManager over into baseSource<commit_after>package gps

import (
	"fmt"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/Masterminds/vcs"
)

type source interface {
	checkExistence(projectExistence) bool
	exportVersionTo(Version, string) error
	getManifestAndLock(ProjectRoot, Version) (Manifest, Lock, error)
	listPackages(ProjectRoot, Version) (PackageTree, error)
	listVersions() ([]Version, error)
	revisionPresentIn(ProjectRoot, Revision) (bool, error)
}

// TODO(sdboyer) de-export these fields
type projectDataCache struct {
	Version  string                   `json:"version"` // TODO(sdboyer) use this
	Infos    map[Revision]projectInfo `json:"infos"`
	Packages map[Revision]PackageTree `json:"packages"`
	VMap     map[Version]Revision     `json:"vmap"`
	RMap     map[Revision][]Version   `json:"rmap"`
	// granular mutexes for each map. this has major complexity costs, so we
	// handle elsewhere - but keep these mutexes here as a TODO(sdboyer) to
	// remind that we may want to do this eventually
	//imut, pmut, vmut, rmut sync.RWMutex
}

func newDataCache() *projectDataCache {
	return &projectDataCache{
		Infos:    make(map[Revision]projectInfo),
		Packages: make(map[Revision]PackageTree),
		VMap:     make(map[Version]Revision),
		RMap:     make(map[Revision][]Version),
	}
}

type maybeSource interface {
	try(cachedir string, an ProjectAnalyzer) (source, error)
}

type maybeSources []maybeSource

type maybeGitSource struct {
	n   string
	url *url.URL
}

type gitSource struct {
	baseSource
}

func (m maybeGitSource) try(cachedir string, an ProjectAnalyzer) (source, error) {
	path := filepath.Join(cachedir, "sources", sanitizer.Replace(m.url.String()))
	r, err := vcs.NewGitRepo(path, m.url.String())
	if err != nil {
		return nil, err
	}

	pm := &gitSource{
		baseSource: baseSource{
			an: an,
			dc: newDataCache(),
			crepo: &repo{
				r:     r,
				rpath: path,
			},
		},
	}

	_, err = pm.listVersions()
	if err != nil {
		return nil, err
		//} else if pm.ex.f&existsUpstream == existsUpstream {
		//return pm, nil
	}

	return pm, nil
}

type baseSource struct { // TODO(sdboyer) rename to baseVCSSource
	// Object for the cache repository
	crepo *repo

	// Indicates the extent to which we have searched for, and verified, the
	// existence of the project/repo.
	ex existence

	// ProjectAnalyzer used to fulfill getManifestAndLock
	an ProjectAnalyzer

	// Whether the cache has the latest info on versions
	cvsync bool

	// The project metadata cache. This is persisted to disk, for reuse across
	// solver runs.
	// TODO(sdboyer) protect with mutex
	dc *projectDataCache
}

func (bs *baseSource) getManifestAndLock(r ProjectRoot, v Version) (Manifest, Lock, error) {
	if err := bs.ensureCacheExistence(); err != nil {
		return nil, nil, err
	}

	if r, exists := bs.dc.VMap[v]; exists {
		if pi, exists := bs.dc.Infos[r]; exists {
			return pi.Manifest, pi.Lock, nil
		}
	}

	bs.crepo.mut.Lock()
	var err error
	if !bs.crepo.synced {
		err = bs.crepo.r.Update()
		if err != nil {
			return nil, nil, fmt.Errorf("Could not fetch latest updates into repository")
		}
		bs.crepo.synced = true
	}

	// Always prefer a rev, if it's available
	if pv, ok := v.(PairedVersion); ok {
		err = bs.crepo.r.UpdateVersion(pv.Underlying().String())
	} else {
		err = bs.crepo.r.UpdateVersion(v.String())
	}
	bs.crepo.mut.Unlock()
	if err != nil {
		// TODO(sdboyer) More-er proper-er error
		panic(fmt.Sprintf("canary - why is checkout/whatever failing: %s %s %s", bs.crepo.r.LocalPath(), v.String(), err))
	}

	bs.crepo.mut.RLock()
	m, l, err := bs.an.DeriveManifestAndLock(bs.crepo.r.LocalPath(), r)
	// TODO(sdboyer) cache results
	bs.crepo.mut.RUnlock()

	if err == nil {
		if l != nil {
			l = prepLock(l)
		}

		// If m is nil, prebsanifest will provide an empty one.
		pi := projectInfo{
			Manifest: prepManifest(m),
			Lock:     l,
		}

		// TODO(sdboyer) this just clobbers all over and ignores the paired/unpaired
		// distinction; serious fix is needed
		if r, exists := bs.dc.VMap[v]; exists {
			bs.dc.Infos[r] = pi
		}

		return pi.Manifest, pi.Lock, nil
	}

	return nil, nil, err
}

func (bs *baseSource) listVersions() (vlist []Version, err error) {
	if !bs.cvsync {
		// This check only guarantees that the upstream exists, not the cache
		bs.ex.s |= existsUpstream
		vpairs, exbits, err := bs.crepo.getCurrentVersionPairs()
		// But it *may* also check the local existence
		bs.ex.s |= exbits
		bs.ex.f |= exbits

		if err != nil {
			// TODO(sdboyer) More-er proper-er error
			return nil, err
		}

		vlist = make([]Version, len(vpairs))
		// mark our cache as synced if we got ExistsUpstream back
		if exbits&existsUpstream == existsUpstream {
			bs.cvsync = true
		}

		// Process the version data into the cache
		// TODO(sdboyer) detect out-of-sync data as we do this?
		for k, v := range vpairs {
			bs.dc.VMap[v] = v.Underlying()
			bs.dc.RMap[v.Underlying()] = append(bs.dc.RMap[v.Underlying()], v)
			vlist[k] = v
		}
	} else {
		vlist = make([]Version, len(bs.dc.VMap))
		k := 0
		// TODO(sdboyer) key type of VMap should be string; recombine here
		//for v, r := range bs.dc.VMap {
		for v := range bs.dc.VMap {
			vlist[k] = v
			k++
		}
	}

	return
}

func (bs *baseSource) ensureCacheExistence() error {
	// Technically, methods could could attempt to return straight from the
	// metadata cache even if the repo cache doesn't exist on disk. But that
	// would allow weird state inconsistencies (cache exists, but no repo...how
	// does that even happen?) that it'd be better to just not allow so that we
	// don't have to think about it elsewhere
	if !bs.checkExistence(existsInCache) {
		if bs.checkExistence(existsUpstream) {
			bs.crepo.mut.Lock()
			err := bs.crepo.r.Get()
			bs.crepo.mut.Unlock()

			if err != nil {
				return fmt.Errorf("failed to create repository cache for %s", bs.crepo.r.Remote())
			}
			bs.ex.s |= existsInCache
			bs.ex.f |= existsInCache
		} else {
			return fmt.Errorf("project %s does not exist upstream", bs.crepo.r.Remote())
		}
	}

	return nil
}

// checkExistence provides a direct method for querying existence levels of the
// source. It will only perform actual searching (local fs or over the network)
// if no previous attempt at that search has been made.
//
// Note that this may perform read-ish operations on the cache repo, and it
// takes a lock accordingly. This makes it unsafe to call from a segment where
// the cache repo mutex is already write-locked, as deadlock will occur.
func (bs *baseSource) checkExistence(ex projectExistence) bool {
	if bs.ex.s&ex != ex {
		if ex&existsInVendorRoot != 0 && bs.ex.s&existsInVendorRoot == 0 {
			panic("should now be implemented in bridge")
		}
		if ex&existsInCache != 0 && bs.ex.s&existsInCache == 0 {
			bs.crepo.mut.RLock()
			bs.ex.s |= existsInCache
			if bs.crepo.r.CheckLocal() {
				bs.ex.f |= existsInCache
			}
			bs.crepo.mut.RUnlock()
		}
		if ex&existsUpstream != 0 && bs.ex.s&existsUpstream == 0 {
			bs.crepo.mut.RLock()
			bs.ex.s |= existsUpstream
			if bs.crepo.r.Ping() {
				bs.ex.f |= existsUpstream
			}
			bs.crepo.mut.RUnlock()
		}
	}

	return ex&bs.ex.f == ex
}

func (bs *baseSource) listPackages(pr ProjectRoot, v Version) (ptree PackageTree, err error) {
	if err = bs.ensureCacheExistence(); err != nil {
		return
	}

	// See if we can find it in the cache
	var r Revision
	switch v.(type) {
	case Revision, PairedVersion:
		var ok bool
		if r, ok = v.(Revision); !ok {
			r = v.(PairedVersion).Underlying()
		}

		if ptree, cached := bs.dc.Packages[r]; cached {
			return ptree, nil
		}
	default:
		var has bool
		if r, has = bs.dc.VMap[v]; has {
			if ptree, cached := bs.dc.Packages[r]; cached {
				return ptree, nil
			}
		}
	}

	// TODO(sdboyer) handle the case where we have a version w/out rev, and not in cache

	// Not in the cache; check out the version and do the analysis
	bs.crepo.mut.Lock()
	// Check out the desired version for analysis
	if r != "" {
		// Always prefer a rev, if it's available
		err = bs.crepo.r.UpdateVersion(string(r))
	} else {
		// If we don't have a rev, ensure the repo is up to date, otherwise we
		// could have a desync issue
		if !bs.crepo.synced {
			err = bs.crepo.r.Update()
			if err != nil {
				return PackageTree{}, fmt.Errorf("Could not fetch latest updates into repository: %s", err)
			}
			bs.crepo.synced = true
		}
		err = bs.crepo.r.UpdateVersion(v.String())
	}

	ptree, err = listPackages(bs.crepo.r.LocalPath(), string(pr))
	bs.crepo.mut.Unlock()

	// TODO(sdboyer) cache errs?
	if err != nil {
		bs.dc.Packages[r] = ptree
	}

	return
}

func (s *gitSource) exportVersionTo(v Version, to string) error {
	s.crepo.mut.Lock()
	defer s.crepo.mut.Unlock()

	r := s.crepo.r
	// Back up original index
	idx, bak := filepath.Join(r.LocalPath(), ".git", "index"), filepath.Join(r.LocalPath(), ".git", "origindex")
	err := os.Rename(idx, bak)
	if err != nil {
		return err
	}

	// TODO(sdboyer) could have an err here
	defer os.Rename(bak, idx)

	vstr := v.String()
	if rv, ok := v.(PairedVersion); ok {
		vstr = rv.Underlying().String()
	}
	_, err = r.RunFromDir("git", "read-tree", vstr)
	if err != nil {
		return err
	}

	// Ensure we have exactly one trailing slash
	to = strings.TrimSuffix(to, string(os.PathSeparator)) + string(os.PathSeparator)
	// Checkout from our temporary index to the desired target location on disk;
	// now it's git's job to make it fast. Sadly, this approach *does* also
	// write out vendor dirs. There doesn't appear to be a way to make
	// checkout-index respect sparse checkout rules (-a supercedes it);
	// the alternative is using plain checkout, though we have a bunch of
	// housekeeping to do to set up, then tear down, the sparse checkout
	// controls, as well as restore the original index and HEAD.
	_, err = r.RunFromDir("git", "checkout-index", "-a", "--prefix="+to)
	return err
}
<|endoftext|>


<commit_before>package slack_incoming_webhooks

type Attachment struct {
	Fallback   string   `json:"fallback,omitempty"`
	Color      string   `json:"color,omitempty"`
	Pretext    string   `json:"pretext,omitempty"`
	AuthorName string   `json:"author_name,omitempty"`
	AuthorLink string   `json:"author_link,omitempty"`
	AuthorIcon string   `json:"author_icon,omitempty"`
	Title      string   `json:"title,omitempty"`
	TitleLink  string   `json:"title_link,omitempty"`
	Text       string   `json:"text,omitempty"`
	Fields     []*Field `json:"fields,omitempty"`
	ImageURL   string   `json:"image_url,omitempty"`
	ThumbURL   string   `json:"thumb_url,omitempty"`
	MarkdownIn []string `json:"mrkdwn_in,omitempty"`
}

func (a Attachment) IsEmpty() bool {
	return a.Fallback == "" &&
		a.Color == "" &&
		a.Pretext == "" &&
		a.AuthorName == "" &&
		a.AuthorLink == "" &&
		a.AuthorIcon == "" &&
		a.Title == "" &&
		a.TitleLink == "" &&
		a.Text == "" &&
		len(a.Fields) == 0 &&
		a.ImageURL == "" &&
		a.ThumbURL == "" &&
		len(a.MarkdownIn) == 0
}

func (a *Attachment) AddField(f *Field) {
	if !f.IsEmpty() {
		a.Fields = append(a.Fields, f)
	}
}
<commit_msg>Add ts support to attachment<commit_after>package slack_incoming_webhooks

type Attachment struct {
	Fallback   string   `json:"fallback,omitempty"`
	Color      string   `json:"color,omitempty"`
	Pretext    string   `json:"pretext,omitempty"`
	AuthorName string   `json:"author_name,omitempty"`
	AuthorLink string   `json:"author_link,omitempty"`
	AuthorIcon string   `json:"author_icon,omitempty"`
	Title      string   `json:"title,omitempty"`
	TitleLink  string   `json:"title_link,omitempty"`
	Text       string   `json:"text,omitempty"`
	Fields     []*Field `json:"fields,omitempty"`
	ImageURL   string   `json:"image_url,omitempty"`
	ThumbURL   string   `json:"thumb_url,omitempty"`
	Timestamp  int64    `json:"ts,omitempty"`
	MarkdownIn []string `json:"mrkdwn_in,omitempty"`
}

func (a Attachment) IsEmpty() bool {
	return a.Fallback == "" &&
		a.Color == "" &&
		a.Pretext == "" &&
		a.AuthorName == "" &&
		a.AuthorLink == "" &&
		a.AuthorIcon == "" &&
		a.Title == "" &&
		a.TitleLink == "" &&
		a.Text == "" &&
		len(a.Fields) == 0 &&
		a.ImageURL == "" &&
		a.ThumbURL == "" &&
		len(a.MarkdownIn) == 0
}

func (a *Attachment) AddField(f *Field) {
	if !f.IsEmpty() {
		a.Fields = append(a.Fields, f)
	}
}
<|endoftext|>