<commit_before>package DataFrame

import (
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

// DataFrame Definition
// ====================
type DataFrame struct {
	columns  map[string]Column
	colnames []string
	nCols    int
	nRows    int
}

// DataFrame Methods
// =================
func (df *DataFrame) LoadAndParse(records [][]string, types interface{}) error {
	err := df.LoadData(records)
	if err != nil {
		return err
	}
	switch types.(type) {
	case []string:
		types := types.([]string)
		if df.nCols != len(types) {
			return errors.New("Number of columns different from number of types")
		}
		for k, v := range df.colnames {
			col := df.columns[v]
			col.ParseType(types[k])
			col.colType = types[k]
			df.columns[v] = col
		}
	case map[string]string:
		types := types.(map[string]string)
		for k, v := range types {
			col := df.columns[k]
			col.ParseType(v)
			col.colType = v
			df.columns[k] = col
		}
	}
	return nil
}

func (df DataFrame) SubsetColumns(columns []string) (*DataFrame, error) {

	newDf := DataFrame{
		columns:  make(map[string]Column),
		nRows:    df.nRows,
		colnames: []string{},
	}

	noCols := []string{}
	dupedCols := []string{}
	for _, v := range columns {
		if col, ok := df.columns[v]; ok {
			if _, ok := newDf.columns[v]; ok {
				dupedCols = append(dupedCols, v)
			}
			newDf.colnames = append(newDf.colnames, v)
			newDf.columns[v] = col
		} else {
			noCols = append(noCols, v)
		}
	}
	if len(dupedCols) != 0 {
		errStr := "The following columns appear more than once:\n" + strings.Join(dupedCols, ", ")
		return nil, errors.New(errStr)
	}
	if len(noCols) != 0 {
		errStr := "The following columns are not present on the DataFrame:\n" + strings.Join(noCols, ", ")
		return nil, errors.New(errStr)
	}
	newDf.nCols = len(newDf.colnames)
	return &newDf, nil
}

func (df *DataFrame) LoadData(records [][]string) error {
	// Get DataFrame dimensions
	nRows := len(records) - 1
	if nRows <= 0 {
		return errors.New("Empty dataframe")
	}
	nCols := len(records[0])

	// Generate a virtual df to store the temporary values
	newDf := DataFrame{
		columns:  make(map[string]Column),
		nRows:    nRows,
		nCols:    nCols,
		colnames: records[0],
	}

	for j := 0; j < nCols; j++ {
		col := []string{}
		for i := 1; i < nRows+1; i++ {
			col = append(col, records[i][j])
		}
		column := Column{}
		column.maxCharLength = len(records[0][j])
		column.FillColumn(col)
		newDf.columns[records[0][j]] = column
	}
	*df = newDf
	return nil
}

func (df DataFrame) String() (str string) {
	addLeftPadding := func(s string, nchar int) string {
		for {
			if len(s) >= nchar {
				return s
			}
			s = " " + s
		}
	}
	addRightPadding := func(s string, nchar int) string {
		for {
			if len(s) >= nchar {
				return s
			}
			s += " "
		}
	}
	nRowsPadding := len(fmt.Sprint(df.nRows))
	if len(df.colnames) != 0 {
		str += addLeftPadding("  ", nRowsPadding+2)
		for _, v := range df.colnames {
			str += addRightPadding(v, df.columns[v].maxCharLength)
			str += "  "
		}
		str += "\n"
		str += "\n"
	}
	for i := 0; i < df.nRows; i++ {
		str += addLeftPadding(strconv.Itoa(i+1)+": ", nRowsPadding+2)
		for _, v := range df.colnames {
			str += addRightPadding(fmt.Sprint(df.columns[v].row[i]), df.columns[v].maxCharLength)
			str += "  "
		}
		str += "\n"
	}
	return str
}

// Column Definition
// =================
type Column struct {
	row           []interface{}
	colType       string
	maxCharLength int
}

// Column Methods
// ==============
func (c Column) String() string {
	return fmt.Sprint(c.row)
}

func (c *Column) ParseType(t string) error {
	var newRows interface{}
	switch t {
	case "int":
		newRows = []int{}
	case "float":
		newRows = []float64{}
	case "string":
		newRows = []string{}
	}
	for _, v := range c.row {
		r := fmt.Sprint(v)
		switch t {
		case "int":
			i, err := strconv.Atoi(r)
			if err != nil {
				return err
			}
			newRows = append(newRows.([]int), i)
		case "float":
			i, err := strconv.ParseFloat(r, 64)
			if err != nil {
				return err
			}
			newRows = append(newRows.([]float64), i)
		case "string":
			newRows = append(newRows.([]string), r)
		}
	}
	c.FillColumn(newRows)
	return nil
}

// TODO: Should this return an error?
func (c *Column) FillColumn(values interface{}) {
	switch reflect.TypeOf(values).Kind() {
	case reflect.Slice:
		s := reflect.ValueOf(values)
		c.row = make([]interface{}, 0)
		for i := 0; i < s.Len(); i++ {
			c.row = append(c.row, s.Index(i).Interface())
			c.colType = fmt.Sprint(s.Index(i).Type())
			rowStr := fmt.Sprint(s.Index(i).Interface())
			if len(rowStr) > c.maxCharLength {
				c.maxCharLength = len(rowStr)
			}
		}
	}
}
<commit_msg>Clean padding functions on DataFrame.String()<commit_after>package DataFrame

import (
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

// DataFrame Definition
// ====================
type DataFrame struct {
	columns  map[string]Column
	colnames []string
	nCols    int
	nRows    int
}

// DataFrame Methods
// =================
func (df *DataFrame) LoadAndParse(records [][]string, types interface{}) error {
	err := df.LoadData(records)
	if err != nil {
		return err
	}
	switch types.(type) {
	case []string:
		types := types.([]string)
		if df.nCols != len(types) {
			return errors.New("Number of columns different from number of types")
		}
		for k, v := range df.colnames {
			col := df.columns[v]
			col.ParseType(types[k])
			col.colType = types[k]
			df.columns[v] = col
		}
	case map[string]string:
		types := types.(map[string]string)
		for k, v := range types {
			col := df.columns[k]
			col.ParseType(v)
			col.colType = v
			df.columns[k] = col
		}
	}
	return nil
}

func (df DataFrame) SubsetColumns(columns []string) (*DataFrame, error) {

	newDf := DataFrame{
		columns:  make(map[string]Column),
		nRows:    df.nRows,
		colnames: []string{},
	}

	noCols := []string{}
	dupedCols := []string{}
	for _, v := range columns {
		if col, ok := df.columns[v]; ok {
			if _, ok := newDf.columns[v]; ok {
				dupedCols = append(dupedCols, v)
			}
			newDf.colnames = append(newDf.colnames, v)
			newDf.columns[v] = col
		} else {
			noCols = append(noCols, v)
		}
	}
	if len(dupedCols) != 0 {
		errStr := "The following columns appear more than once:\n" + strings.Join(dupedCols, ", ")
		return nil, errors.New(errStr)
	}
	if len(noCols) != 0 {
		errStr := "The following columns are not present on the DataFrame:\n" + strings.Join(noCols, ", ")
		return nil, errors.New(errStr)
	}
	newDf.nCols = len(newDf.colnames)
	return &newDf, nil
}

func (df *DataFrame) LoadData(records [][]string) error {
	// Get DataFrame dimensions
	nRows := len(records) - 1
	if nRows <= 0 {
		return errors.New("Empty dataframe")
	}
	nCols := len(records[0])

	// Generate a virtual df to store the temporary values
	newDf := DataFrame{
		columns:  make(map[string]Column),
		nRows:    nRows,
		nCols:    nCols,
		colnames: records[0],
	}

	for j := 0; j < nCols; j++ {
		col := []string{}
		for i := 1; i < nRows+1; i++ {
			col = append(col, records[i][j])
		}
		column := Column{}
		column.maxCharLength = len(records[0][j])
		column.FillColumn(col)
		newDf.columns[records[0][j]] = column
	}
	*df = newDf
	return nil
}

func (df DataFrame) String() (str string) {
	addLeftPadding := func(s string, nchar int) string {
		if len(s) < nchar {
			return strings.Repeat(" ", nchar-len(s)) + s
		}
		return s
	}
	addRightPadding := func(s string, nchar int) string {
		if len(s) < nchar {
			return s + strings.Repeat(" ", nchar-len(s))
		}
		return s
	}

	nRowsPadding := len(fmt.Sprint(df.nRows))
	if len(df.colnames) != 0 {
		str += addLeftPadding("  ", nRowsPadding+2)
		for _, v := range df.colnames {
			str += addRightPadding(v, df.columns[v].maxCharLength)
			str += "  "
		}
		str += "\n"
		str += "\n"
	}
	for i := 0; i < df.nRows; i++ {
		str += addLeftPadding(strconv.Itoa(i+1)+": ", nRowsPadding+2)
		for _, v := range df.colnames {
			str += addRightPadding(fmt.Sprint(df.columns[v].row[i]), df.columns[v].maxCharLength)
			str += "  "
		}
		str += "\n"
	}
	return str
}

// Column Definition
// =================
type Column struct {
	row           []interface{}
	colType       string
	maxCharLength int
}

// Column Methods
// ==============
func (c Column) String() string {
	return fmt.Sprint(c.row)
}

func (c *Column) ParseType(t string) error {
	var newRows interface{}
	switch t {
	case "int":
		newRows = []int{}
	case "float":
		newRows = []float64{}
	case "string":
		newRows = []string{}
	}
	for _, v := range c.row {
		r := fmt.Sprint(v)
		switch t {
		case "int":
			i, err := strconv.Atoi(r)
			if err != nil {
				return err
			}
			newRows = append(newRows.([]int), i)
		case "float":
			i, err := strconv.ParseFloat(r, 64)
			if err != nil {
				return err
			}
			newRows = append(newRows.([]float64), i)
		case "string":
			newRows = append(newRows.([]string), r)
		}
	}
	c.FillColumn(newRows)
	return nil
}

// TODO: Should this return an error?
func (c *Column) FillColumn(values interface{}) {
	switch reflect.TypeOf(values).Kind() {
	case reflect.Slice:
		s := reflect.ValueOf(values)
		c.row = make([]interface{}, 0)
		for i := 0; i < s.Len(); i++ {
			c.row = append(c.row, s.Index(i).Interface())
			c.colType = fmt.Sprint(s.Index(i).Type())
			rowStr := fmt.Sprint(s.Index(i).Interface())
			if len(rowStr) > c.maxCharLength {
				c.maxCharLength = len(rowStr)
			}
		}
	}
}
<|endoftext|>


<commit_before>package middleware

import (
	"bytes"
	"encoding/base64"
	"github.com/beatgammit/artichoke"
	"net/http"
	"strings"
)

type Auth struct {
	User          string
	Pass          string
	Authenticated bool
}

func NewAuth(u string, p string, a bool) *Auth {
	auth := new(Auth)
	auth.User = u
	auth.Pass = p
	auth.Authenticated = a

	return auth
}

type AuthError struct {
	err string
}

func NewError(msg string) *AuthError {
	e := new(AuthError)
	e.err = msg
	return e
}

func (e *AuthError) String() string {
	return e.err
}

func GetAuth(d artichoke.Data) *Auth {
	if a, ok := d.Get("auth"); ok {
		return a.(*Auth)
	}

	return nil
}

func BasicAuth(auth map[string]string, required bool) artichoke.Middleware {
	return func(w http.ResponseWriter, r *http.Request, m artichoke.Data) bool {
		buf := bytes.Buffer{}
		str := r.Header.Get("authorization")

		if len(str) == 0 {
			if required {
				w.WriteHeader(http.StatusUnauthorized)
				w.Write([]byte("Authorization required"))
				w.Write([]byte(""))
			}

			return required
		}

		// just get the auth part
		str = strings.Split(str, " ")[1]

		i := len(str)/4*3 - strings.Count(str, "=")
		outBuf := make([]byte, len(str)/4*3)

		dec := base64.NewDecoder(base64.StdEncoding, &buf)
		buf.WriteString(str)
		dec.Read(outBuf)

		cAuth := strings.Split(string(outBuf[:i]), ":")

		user := cAuth[0]
		pass := cAuth[1]

		success := auth[user] == pass
		m.Set("auth", NewAuth(user, pass, success))

		if success {
			if required {
				w.WriteHeader(http.StatusUnauthorized)
				w.Write([]byte("Not authorized"))
				w.Write([]byte(""))
			}

			return required
		}

		return false
	}
}
<commit_msg>Added Authenticated() convenience function to basic auth middleware<commit_after>package middleware

import (
	"bytes"
	"encoding/base64"
	"github.com/beatgammit/artichoke"
	"net/http"
	"strings"
)

type Auth struct {
	User          string
	Pass          string
	Authenticated bool
}

func NewAuth(u string, p string, a bool) *Auth {
	auth := new(Auth)
	auth.User = u
	auth.Pass = p
	auth.Authenticated = a

	return auth
}

type AuthError struct {
	err string
}

func NewError(msg string) *AuthError {
	e := new(AuthError)
	e.err = msg
	return e
}

func (e *AuthError) String() string {
	return e.err
}

func GetAuth(d artichoke.Data) *Auth {
	if a, ok := d.Get("auth"); ok {
		return a.(*Auth)
	}

	return nil
}

func Authenticated(d artichoke.Data) bool {
	if auth := GetAuth(d); auth != nil {
		return auth.Authenticated
	}

	return false
}

func BasicAuth(auth map[string]string, required bool) artichoke.Middleware {
	return func(w http.ResponseWriter, r *http.Request, m artichoke.Data) bool {
		buf := bytes.Buffer{}
		str := r.Header.Get("authorization")

		if len(str) == 0 {
			if required {
				w.WriteHeader(http.StatusUnauthorized)
				w.Write([]byte("Authorization required"))
				w.Write([]byte(""))
			}

			return required
		}

		// just get the auth part
		str = strings.Split(str, " ")[1]

		i := len(str)/4*3 - strings.Count(str, "=")
		outBuf := make([]byte, len(str)/4*3)

		dec := base64.NewDecoder(base64.StdEncoding, &buf)
		buf.WriteString(str)
		dec.Read(outBuf)

		cAuth := strings.Split(string(outBuf[:i]), ":")

		user := cAuth[0]
		pass := cAuth[1]

		success := auth[user] == pass
		m.Set("auth", NewAuth(user, pass, success))

		if success {
			if required {
				w.WriteHeader(http.StatusUnauthorized)
				w.Write([]byte("Not authorized"))
				w.Write([]byte(""))
			}

			return required
		}

		return false
	}
}
<|endoftext|>


<commit_before>package middleware

import (
	"encoding/base64"

	"github.com/labstack/echo"
)

type (
	// BasicAuthConfig defines the config for BasicAuth middleware.
	BasicAuthConfig struct {
		// Skipper defines a function to skip middleware.
		Skipper Skipper

		// Validator is a function to validate BasicAuth credentials.
		// Required.
		Validator BasicAuthValidator
	}

	// BasicAuthValidator defines a function to validate BasicAuth credentials.
	BasicAuthValidator func(string, string, echo.Context) bool
)

const (
	basic = "Basic"
)

var (
	// DefaultBasicAuthConfig is the default BasicAuth middleware config.
	DefaultBasicAuthConfig = BasicAuthConfig{
		Skipper: DefaultSkipper,
	}
)

// BasicAuth returns an BasicAuth middleware.
//
// For valid credentials it calls the next handler.
// For missing or invalid credentials, it sends "401 - Unauthorized" response.
func BasicAuth(fn BasicAuthValidator) echo.MiddlewareFunc {
	c := DefaultBasicAuthConfig
	c.Validator = fn
	return BasicAuthWithConfig(c)
}

// BasicAuthWithConfig returns an BasicAuth middleware with config.
// See `BasicAuth()`.
func BasicAuthWithConfig(config BasicAuthConfig) echo.MiddlewareFunc {
	// Defaults
	if config.Validator == nil {
		panic("basic-auth middleware requires a validator function")
	}
	if config.Skipper == nil {
		config.Skipper = DefaultBasicAuthConfig.Skipper
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			if config.Skipper(c) {
				return next(c)
			}

			auth := c.Request().Header.Get(echo.HeaderAuthorization)
			l := len(basic)

			if len(auth) > l+1 && auth[:l] == basic {
				b, err := base64.StdEncoding.DecodeString(auth[l+1:])
				if err != nil {
					return err
				}
				cred := string(b)
				for i := 0; i < len(cred); i++ {
					if cred[i] == ':' {
						// Verify credentials
						if config.Validator(cred[:i], cred[i+1:], c) {
							return next(c)
						}
					}
				}
			}

			// Need to return `401` for browsers to pop-up login box.
			c.Response().Header().Set(echo.HeaderWWWAuthenticate, basic+" realm=Restricted")
			return echo.ErrUnauthorized
		}
	}
}
<commit_msg>Add BasicAuth Realm support<commit_after>package middleware

import (
	"encoding/base64"
	"strconv"

	"github.com/labstack/echo"
)

type (
	// BasicAuthConfig defines the config for BasicAuth middleware.
	BasicAuthConfig struct {
		// Skipper defines a function to skip middleware.
		Skipper Skipper

		// Validator is a function to validate BasicAuth credentials.
		// Required.
		Validator BasicAuthValidator

		// Realm is a string to define realm attribute of BasicAuth
		Realm string
	}

	// BasicAuthValidator defines a function to validate BasicAuth credentials.
	BasicAuthValidator func(string, string, echo.Context) bool
)

const (
	basic        = "Basic"
	defaultRealm = "Restricted"
)

var (
	// DefaultBasicAuthConfig is the default BasicAuth middleware config.
	DefaultBasicAuthConfig = BasicAuthConfig{
		Skipper: DefaultSkipper,
		Realm:   defaultRealm,
	}
)

// BasicAuth returns an BasicAuth middleware.
//
// For valid credentials it calls the next handler.
// For missing or invalid credentials, it sends "401 - Unauthorized" response.
func BasicAuth(fn BasicAuthValidator) echo.MiddlewareFunc {
	c := DefaultBasicAuthConfig
	c.Validator = fn
	return BasicAuthWithConfig(c)
}

// BasicAuthWithConfig returns an BasicAuth middleware with config.
// See `BasicAuth()`.
func BasicAuthWithConfig(config BasicAuthConfig) echo.MiddlewareFunc {
	// Defaults
	if config.Validator == nil {
		panic("basic-auth middleware requires a validator function")
	}
	if config.Skipper == nil {
		config.Skipper = DefaultBasicAuthConfig.Skipper
	}
	if config.Realm == "" {
		config.Realm = defaultRealm
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			if config.Skipper(c) {
				return next(c)
			}

			auth := c.Request().Header.Get(echo.HeaderAuthorization)
			l := len(basic)

			if len(auth) > l+1 && auth[:l] == basic {
				b, err := base64.StdEncoding.DecodeString(auth[l+1:])
				if err != nil {
					return err
				}
				cred := string(b)
				for i := 0; i < len(cred); i++ {
					if cred[i] == ':' {
						// Verify credentials
						if config.Validator(cred[:i], cred[i+1:], c) {
							return next(c)
						}
					}
				}
			}

			var realm string
			if config.Realm == defaultRealm {
				realm = defaultRealm
			} else {
				realm = strconv.Quote(config.Realm)
			}

			// Need to return `401` for browsers to pop-up login box.
			c.Response().Header().Set(echo.HeaderWWWAuthenticate, basic+" realm="+realm)
			return echo.ErrUnauthorized
		}
	}
}
<|endoftext|>


<commit_before>package dsl

import (
	"strings"

	"bitbucket.org/pkg/inflect"

	"github.com/goadesign/goa/design"
	"github.com/goadesign/goa/dslengine"
	"github.com/goadesign/goa/goagen/codegen"
	"github.com/goadesign/gorma"
)

// Field is a DSL definition for a field in a Relational Model.
// Parameter Options:
//
//	// A field called "Title" with default type `String`.
//	Field("Title")
//
//	// Explicitly specify the type.
//	Field("Title", gorma.String)
//
//	// "Title" field, as `String` with other DSL included.
//	Field("Title", func(){... other field level dsl ...})
//
//	// All options specified: name, type and dsl.
//	Field("Title", gorma.String, func(){... other field level dsl ...})
func Field(name string, args ...interface{}) {
	name = codegen.Goify(name, true)
	name = SanitizeFieldName(name)
	fieldType, dsl := parseFieldArgs(args...)
	if s, ok := relationalModelDefinition(true); ok {
		if s.RelationalFields == nil {
			s.RelationalFields = make(map[string]*gorma.RelationalFieldDefinition)
		}
		field, ok := s.RelationalFields[name]
		if !ok {
			field = gorma.NewRelationalFieldDefinition()
			field.FieldName = name
			field.DefinitionDSL = dsl
			field.Parent = s
			field.Datatype = fieldType
		} else {
			// the field was auto-added by the model parser
			// so we need to update whatever we can from this new definition
			field.DefinitionDSL = dsl
			field.Datatype = fieldType

		}

		if fieldType == gorma.Timestamp {
			field.Timestamp = true
			field.Description = "timestamp"
		}
		if fieldType == gorma.NullableTimestamp {
			field.Timestamp = true
			field.Nullable = true
			field.Description = "nullable timestamp (soft delete)"
		}
		field.DatabaseFieldName = SanitizeDBFieldName(name)

		s.RelationalFields[name] = field
	}
}

// MapsFrom establishes a mapping relationship between a source
// Type field and this model.  The source type must be a UserTypeDefinition "Type"
// in goa.  These are typically Payloads.
func MapsFrom(utd *design.UserTypeDefinition, field string) {
	if f, ok := relationalFieldDefinition(true); ok {
		md := gorma.NewMapDefinition()
		md.RemoteField = field
		md.RemoteType = utd
		f.Mappings[utd.TypeName] = md

	}
}

// MapsTo establishes a mapping relationship between a field in model and
// a MediaType in goa.
func MapsTo(mtd *design.MediaTypeDefinition, field string) {
	if f, ok := relationalFieldDefinition(true); ok {
		md := gorma.NewMapDefinition()
		md.RemoteField = field
		md.RemoteType = mtd.UserTypeDefinition
		f.Mappings[mtd.UserTypeDefinition.TypeName] = md
	}
}

func fixID(s string) string {
	if s == "i_d" {
		return "id"
	}
	return s

}

// Nullable sets the fields nullability
// A Nullable field will be stored as a pointer.  A field that is
// not Nullable won't be stored as a pointer.
func Nullable() {
	if f, ok := relationalFieldDefinition(false); ok {
		f.Nullable = true
	}
}

// PrimaryKey establishes a field as a Primary Key by
// seting the struct tags necessary to create the PK in gorm.
// Valid only for `Integer` datatypes currently
func PrimaryKey() {
	if f, ok := relationalFieldDefinition(true); ok {
		if f.Datatype != gorma.Integer && f.Datatype != gorma.UUID {
			dslengine.ReportError("Integer and UUID are the only supported Primary Key field types.")
		}

		f.PrimaryKey = true
		f.Nullable = false
		f.Description = "primary key"
		f.Parent.PrimaryKeys = append(f.Parent.PrimaryKeys, f)
	}
}

// SanitizeFieldName is exported for testing purposes
func SanitizeFieldName(name string) string {
	name = codegen.Goify(name, true)
	if strings.HasSuffix(name, "Id") {
		name = strings.TrimSuffix(name, "Id")
		name = name + "ID"
	}

	return name
}

// SanitizeDBFieldName is exported for testing purposes
func SanitizeDBFieldName(name string) string {
	name = inflect.Underscore(name)
	if strings.HasSuffix(name, "_i_d") {
		name = strings.TrimSuffix(name, "_i_d")
		name = name + "_id"
	}
	if name == "i_d" {
		name = "id"

	}
	return name
}
func parseFieldArgs(args ...interface{}) (gorma.FieldType, func()) {
	var (
		fieldType gorma.FieldType
		dslp      func()
		ok        bool
	)

	parseFieldType := func(expected string, index int) {
		if fieldType, ok = args[index].(gorma.FieldType); !ok {
			dslengine.InvalidArgError(expected, args[index])
		}
	}
	parseDSL := func(index int, success, failure func()) {
		if dslp, ok = args[index].(func()); ok {
			success()
		} else {
			failure()
		}
	}

	success := func() {}

	switch len(args) {
	case 0:
		fieldType = gorma.NotFound
	case 1:
		parseDSL(0, success, func() { parseFieldType("DataType or func()", 0) })
	case 2:
		parseFieldType("FieldType", 0)
		parseDSL(1, success, func() { dslengine.InvalidArgError("DSL", args[1]) })

	default:
		dslengine.ReportError("too many arguments in call to Attribute")
	}

	return fieldType, dslp
}
<commit_msg>Add DSL for DatabaseFieldName to set custom column name.<commit_after>package dsl

import (
	"strings"

	"bitbucket.org/pkg/inflect"

	"github.com/goadesign/goa/design"
	"github.com/goadesign/goa/dslengine"
	"github.com/goadesign/goa/goagen/codegen"
	"github.com/goadesign/gorma"
)

// DatabaseFieldName allows for customization of the column name
// by seting the struct tags. This is necessary to create correlate
// non standard column naming conventions in gorm.
func DatabaseFieldName(name string) {
	if f, ok := relationalFieldDefinition(true); ok {
		f.DatabaseFieldName = name
	}
}

// Field is a DSL definition for a field in a Relational Model.
// Parameter Options:
//
//	// A field called "Title" with default type `String`.
//	Field("Title")
//
//	// Explicitly specify the type.
//	Field("Title", gorma.String)
//
//	// "Title" field, as `String` with other DSL included.
//	Field("Title", func(){... other field level dsl ...})
//
//	// All options specified: name, type and dsl.
//	Field("Title", gorma.String, func(){... other field level dsl ...})
func Field(name string, args ...interface{}) {
	name = codegen.Goify(name, true)
	name = SanitizeFieldName(name)
	fieldType, dsl := parseFieldArgs(args...)
	if s, ok := relationalModelDefinition(true); ok {
		if s.RelationalFields == nil {
			s.RelationalFields = make(map[string]*gorma.RelationalFieldDefinition)
		}
		field, ok := s.RelationalFields[name]
		if !ok {
			field = gorma.NewRelationalFieldDefinition()
			field.FieldName = name
			field.DefinitionDSL = dsl
			field.Parent = s
			field.Datatype = fieldType
		} else {
			// the field was auto-added by the model parser
			// so we need to update whatever we can from this new definition
			field.DefinitionDSL = dsl
			field.Datatype = fieldType

		}

		if fieldType == gorma.Timestamp {
			field.Timestamp = true
			field.Description = "timestamp"
		}
		if fieldType == gorma.NullableTimestamp {
			field.Timestamp = true
			field.Nullable = true
			field.Description = "nullable timestamp (soft delete)"
		}
		field.DatabaseFieldName = SanitizeDBFieldName(name)

		s.RelationalFields[name] = field
	}
}

// MapsFrom establishes a mapping relationship between a source
// Type field and this model.  The source type must be a UserTypeDefinition "Type"
// in goa.  These are typically Payloads.
func MapsFrom(utd *design.UserTypeDefinition, field string) {
	if f, ok := relationalFieldDefinition(true); ok {
		md := gorma.NewMapDefinition()
		md.RemoteField = field
		md.RemoteType = utd
		f.Mappings[utd.TypeName] = md

	}
}

// MapsTo establishes a mapping relationship between a field in model and
// a MediaType in goa.
func MapsTo(mtd *design.MediaTypeDefinition, field string) {
	if f, ok := relationalFieldDefinition(true); ok {
		md := gorma.NewMapDefinition()
		md.RemoteField = field
		md.RemoteType = mtd.UserTypeDefinition
		f.Mappings[mtd.UserTypeDefinition.TypeName] = md
	}
}

func fixID(s string) string {
	if s == "i_d" {
		return "id"
	}
	return s

}

// Nullable sets the fields nullability
// A Nullable field will be stored as a pointer.  A field that is
// not Nullable won't be stored as a pointer.
func Nullable() {
	if f, ok := relationalFieldDefinition(false); ok {
		f.Nullable = true
	}
}

// PrimaryKey establishes a field as a Primary Key by
// seting the struct tags necessary to create the PK in gorm.
// Valid only for `Integer` datatypes currently
func PrimaryKey() {
	if f, ok := relationalFieldDefinition(true); ok {
		if f.Datatype != gorma.Integer && f.Datatype != gorma.UUID {
			dslengine.ReportError("Integer and UUID are the only supported Primary Key field types.")
		}

		f.PrimaryKey = true
		f.Nullable = false
		f.Description = "primary key"
		f.Parent.PrimaryKeys = append(f.Parent.PrimaryKeys, f)
	}
}

// SanitizeFieldName is exported for testing purposes
func SanitizeFieldName(name string) string {
	name = codegen.Goify(name, true)
	if strings.HasSuffix(name, "Id") {
		name = strings.TrimSuffix(name, "Id")
		name = name + "ID"
	}

	return name
}

// SanitizeDBFieldName is exported for testing purposes
func SanitizeDBFieldName(name string) string {
	name = inflect.Underscore(name)
	if strings.HasSuffix(name, "_i_d") {
		name = strings.TrimSuffix(name, "_i_d")
		name = name + "_id"
	}
	if name == "i_d" {
		name = "id"

	}
	return name
}
func parseFieldArgs(args ...interface{}) (gorma.FieldType, func()) {
	var (
		fieldType gorma.FieldType
		dslp      func()
		ok        bool
	)

	parseFieldType := func(expected string, index int) {
		if fieldType, ok = args[index].(gorma.FieldType); !ok {
			dslengine.InvalidArgError(expected, args[index])
		}
	}
	parseDSL := func(index int, success, failure func()) {
		if dslp, ok = args[index].(func()); ok {
			success()
		} else {
			failure()
		}
	}

	success := func() {}

	switch len(args) {
	case 0:
		fieldType = gorma.NotFound
	case 1:
		parseDSL(0, success, func() { parseFieldType("DataType or func()", 0) })
	case 2:
		parseFieldType("FieldType", 0)
		parseDSL(1, success, func() { dslengine.InvalidArgError("DSL", args[1]) })

	default:
		dslengine.ReportError("too many arguments in call to Attribute")
	}

	return fieldType, dslp
}
<|endoftext|>


<commit_before>package network

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

	"golang.org/x/net/context"

	"github.com/docker/docker/api/server/httputils"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/filters"
	"github.com/docker/engine-api/types/network"
	"github.com/docker/libnetwork"
)

func (n *networkRouter) getNetworksList(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	filter := r.Form.Get("filters")
	netFilters, err := filters.FromParam(filter)
	if err != nil {
		return err
	}

	list := []types.NetworkResource{}

	if nr, err := n.clusterProvider.GetNetworks(); err == nil {
		for _, nw := range nr {
			list = append(list, nw)
		}
	}

	// Combine the network list returned by Docker daemon if it is not already
	// returned by the cluster manager
SKIP:
	for _, nw := range n.backend.GetNetworks() {
		for _, nl := range list {
			if nl.ID == nw.ID() {
				continue SKIP
			}
		}
		list = append(list, *n.buildNetworkResource(nw))
	}

	list, err = filterNetworks(list, netFilters)
	if err != nil {
		return err
	}
	return httputils.WriteJSON(w, http.StatusOK, list)
}

func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	nw, err := n.backend.FindNetwork(vars["id"])
	if err != nil {
		if nr, err := n.clusterProvider.GetNetwork(vars["id"]); err == nil {
			return httputils.WriteJSON(w, http.StatusOK, nr)
		}
		return err
	}
	return httputils.WriteJSON(w, http.StatusOK, n.buildNetworkResource(nw))
}

func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	var create types.NetworkCreateRequest

	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	if err := httputils.CheckForJSON(r); err != nil {
		return err
	}

	if err := json.NewDecoder(r.Body).Decode(&create); err != nil {
		return err
	}

	nw, err := n.backend.CreateNetwork(create)
	if err != nil {
		if _, ok := err.(libnetwork.ManagerRedirectError); !ok {
			return err
		}
		id, err := n.clusterProvider.CreateNetwork(create)
		if err != nil {
			return err
		}
		nw = &types.NetworkCreateResponse{ID: id}
	}

	return httputils.WriteJSON(w, http.StatusCreated, nw)
}

func (n *networkRouter) postNetworkConnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	var connect types.NetworkConnect
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	if err := httputils.CheckForJSON(r); err != nil {
		return err
	}

	if err := json.NewDecoder(r.Body).Decode(&connect); err != nil {
		return err
	}

	nw, err := n.backend.FindNetwork(vars["id"])
	if err != nil {
		return err
	}

	return n.backend.ConnectContainerToNetwork(connect.Container, nw.Name(), connect.EndpointConfig)
}

func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	var disconnect types.NetworkDisconnect
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	if err := httputils.CheckForJSON(r); err != nil {
		return err
	}

	if err := json.NewDecoder(r.Body).Decode(&disconnect); err != nil {
		return err
	}

	nw, err := n.backend.FindNetwork(vars["id"])
	if err != nil {
		return err
	}

	return n.backend.DisconnectContainerFromNetwork(disconnect.Container, nw, disconnect.Force)
}

func (n *networkRouter) deleteNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}
	if _, err := n.clusterProvider.GetNetwork(vars["id"]); err == nil {
		return n.clusterProvider.RemoveNetwork(vars["id"])
	}
	if err := n.backend.DeleteNetwork(vars["id"]); err != nil {
		return err
	}
	w.WriteHeader(http.StatusNoContent)
	return nil
}

func (n *networkRouter) buildNetworkResource(nw libnetwork.Network) *types.NetworkResource {
	r := &types.NetworkResource{}
	if nw == nil {
		return r
	}

	info := nw.Info()
	r.Name = nw.Name()
	r.ID = nw.ID()
	r.Scope = info.Scope()
	if n.clusterProvider.IsManager() {
		if _, err := n.clusterProvider.GetNetwork(nw.Name()); err == nil {
			r.Scope = "swarm"
		}
	} else if info.Dynamic() {
		r.Scope = "swarm"
	}
	r.Driver = nw.Type()
	r.EnableIPv6 = info.IPv6Enabled()
	r.Internal = info.Internal()
	r.Options = info.DriverOptions()
	r.Containers = make(map[string]types.EndpointResource)
	buildIpamResources(r, info)
	r.Internal = info.Internal()
	r.Labels = info.Labels()

	epl := nw.Endpoints()
	for _, e := range epl {
		ei := e.Info()
		if ei == nil {
			continue
		}
		sb := ei.Sandbox()
		key := "ep-" + e.ID()
		if sb != nil {
			key = sb.ContainerID()
		}

		r.Containers[key] = buildEndpointResource(e)
	}
	return r
}

func buildIpamResources(r *types.NetworkResource, nwInfo libnetwork.NetworkInfo) {
	id, opts, ipv4conf, ipv6conf := nwInfo.IpamConfig()

	ipv4Info, ipv6Info := nwInfo.IpamInfo()

	r.IPAM.Driver = id

	r.IPAM.Options = opts

	r.IPAM.Config = []network.IPAMConfig{}
	for _, ip4 := range ipv4conf {
		if ip4.PreferredPool == "" {
			continue
		}
		iData := network.IPAMConfig{}
		iData.Subnet = ip4.PreferredPool
		iData.IPRange = ip4.SubPool
		iData.Gateway = ip4.Gateway
		iData.AuxAddress = ip4.AuxAddresses
		r.IPAM.Config = append(r.IPAM.Config, iData)
	}

	if len(r.IPAM.Config) == 0 {
		for _, ip4Info := range ipv4Info {
			iData := network.IPAMConfig{}
			iData.Subnet = ip4Info.IPAMData.Pool.String()
			iData.Gateway = ip4Info.IPAMData.Gateway.String()
			r.IPAM.Config = append(r.IPAM.Config, iData)
		}
	}

	hasIpv6Conf := false
	for _, ip6 := range ipv6conf {
		if ip6.PreferredPool == "" {
			continue
		}
		hasIpv6Conf = true
		iData := network.IPAMConfig{}
		iData.Subnet = ip6.PreferredPool
		iData.IPRange = ip6.SubPool
		iData.Gateway = ip6.Gateway
		iData.AuxAddress = ip6.AuxAddresses
		r.IPAM.Config = append(r.IPAM.Config, iData)
	}

	if !hasIpv6Conf {
		for _, ip6Info := range ipv6Info {
			iData := network.IPAMConfig{}
			iData.Subnet = ip6Info.IPAMData.Pool.String()
			iData.Gateway = ip6Info.IPAMData.Gateway.String()
			r.IPAM.Config = append(r.IPAM.Config, iData)
		}
	}
}

func buildEndpointResource(e libnetwork.Endpoint) types.EndpointResource {
	er := types.EndpointResource{}
	if e == nil {
		return er
	}

	er.EndpointID = e.ID()
	er.Name = e.Name()
	ei := e.Info()
	if ei == nil {
		return er
	}

	if iface := ei.Iface(); iface != nil {
		if mac := iface.MacAddress(); mac != nil {
			er.MacAddress = mac.String()
		}
		if ip := iface.Address(); ip != nil && len(ip.IP) > 0 {
			er.IPv4Address = ip.String()
		}

		if ipv6 := iface.AddressIPv6(); ipv6 != nil && len(ipv6.IP) > 0 {
			er.IPv6Address = ipv6.String()
		}
	}
	return er
}
<commit_msg>fixes #23983<commit_after>package network

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

	"golang.org/x/net/context"

	"github.com/docker/docker/api/server/httputils"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/filters"
	"github.com/docker/engine-api/types/network"
	"github.com/docker/libnetwork"
)

func (n *networkRouter) getNetworksList(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	filter := r.Form.Get("filters")
	netFilters, err := filters.FromParam(filter)
	if err != nil {
		return err
	}

	list := []types.NetworkResource{}

	if nr, err := n.clusterProvider.GetNetworks(); err == nil {
		for _, nw := range nr {
			list = append(list, nw)
		}
	}

	// Combine the network list returned by Docker daemon if it is not already
	// returned by the cluster manager
SKIP:
	for _, nw := range n.backend.GetNetworks() {
		for _, nl := range list {
			if nl.ID == nw.ID() {
				continue SKIP
			}
		}
		list = append(list, *n.buildNetworkResource(nw))
	}

	list, err = filterNetworks(list, netFilters)
	if err != nil {
		return err
	}
	return httputils.WriteJSON(w, http.StatusOK, list)
}

func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	nw, err := n.backend.FindNetwork(vars["id"])
	if err != nil {
		if nr, err := n.clusterProvider.GetNetwork(vars["id"]); err == nil {
			return httputils.WriteJSON(w, http.StatusOK, nr)
		}
		return err
	}
	return httputils.WriteJSON(w, http.StatusOK, n.buildNetworkResource(nw))
}

func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	var create types.NetworkCreateRequest

	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	if err := httputils.CheckForJSON(r); err != nil {
		return err
	}

	if err := json.NewDecoder(r.Body).Decode(&create); err != nil {
		return err
	}

	if _, err := n.clusterProvider.GetNetwork(create.Name); err == nil {
		return libnetwork.NetworkNameError(create.Name)
	}

	nw, err := n.backend.CreateNetwork(create)
	if err != nil {
		if _, ok := err.(libnetwork.ManagerRedirectError); !ok {
			return err
		}
		id, err := n.clusterProvider.CreateNetwork(create)
		if err != nil {
			return err
		}
		nw = &types.NetworkCreateResponse{ID: id}
	}

	return httputils.WriteJSON(w, http.StatusCreated, nw)
}

func (n *networkRouter) postNetworkConnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	var connect types.NetworkConnect
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	if err := httputils.CheckForJSON(r); err != nil {
		return err
	}

	if err := json.NewDecoder(r.Body).Decode(&connect); err != nil {
		return err
	}

	nw, err := n.backend.FindNetwork(vars["id"])
	if err != nil {
		return err
	}

	return n.backend.ConnectContainerToNetwork(connect.Container, nw.Name(), connect.EndpointConfig)
}

func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	var disconnect types.NetworkDisconnect
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	if err := httputils.CheckForJSON(r); err != nil {
		return err
	}

	if err := json.NewDecoder(r.Body).Decode(&disconnect); err != nil {
		return err
	}

	nw, err := n.backend.FindNetwork(vars["id"])
	if err != nil {
		return err
	}

	return n.backend.DisconnectContainerFromNetwork(disconnect.Container, nw, disconnect.Force)
}

func (n *networkRouter) deleteNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}
	if _, err := n.clusterProvider.GetNetwork(vars["id"]); err == nil {
		return n.clusterProvider.RemoveNetwork(vars["id"])
	}
	if err := n.backend.DeleteNetwork(vars["id"]); err != nil {
		return err
	}
	w.WriteHeader(http.StatusNoContent)
	return nil
}

func (n *networkRouter) buildNetworkResource(nw libnetwork.Network) *types.NetworkResource {
	r := &types.NetworkResource{}
	if nw == nil {
		return r
	}

	info := nw.Info()
	r.Name = nw.Name()
	r.ID = nw.ID()
	r.Scope = info.Scope()
	if n.clusterProvider.IsManager() {
		if _, err := n.clusterProvider.GetNetwork(nw.Name()); err == nil {
			r.Scope = "swarm"
		}
	} else if info.Dynamic() {
		r.Scope = "swarm"
	}
	r.Driver = nw.Type()
	r.EnableIPv6 = info.IPv6Enabled()
	r.Internal = info.Internal()
	r.Options = info.DriverOptions()
	r.Containers = make(map[string]types.EndpointResource)
	buildIpamResources(r, info)
	r.Internal = info.Internal()
	r.Labels = info.Labels()

	epl := nw.Endpoints()
	for _, e := range epl {
		ei := e.Info()
		if ei == nil {
			continue
		}
		sb := ei.Sandbox()
		key := "ep-" + e.ID()
		if sb != nil {
			key = sb.ContainerID()
		}

		r.Containers[key] = buildEndpointResource(e)
	}
	return r
}

func buildIpamResources(r *types.NetworkResource, nwInfo libnetwork.NetworkInfo) {
	id, opts, ipv4conf, ipv6conf := nwInfo.IpamConfig()

	ipv4Info, ipv6Info := nwInfo.IpamInfo()

	r.IPAM.Driver = id

	r.IPAM.Options = opts

	r.IPAM.Config = []network.IPAMConfig{}
	for _, ip4 := range ipv4conf {
		if ip4.PreferredPool == "" {
			continue
		}
		iData := network.IPAMConfig{}
		iData.Subnet = ip4.PreferredPool
		iData.IPRange = ip4.SubPool
		iData.Gateway = ip4.Gateway
		iData.AuxAddress = ip4.AuxAddresses
		r.IPAM.Config = append(r.IPAM.Config, iData)
	}

	if len(r.IPAM.Config) == 0 {
		for _, ip4Info := range ipv4Info {
			iData := network.IPAMConfig{}
			iData.Subnet = ip4Info.IPAMData.Pool.String()
			iData.Gateway = ip4Info.IPAMData.Gateway.String()
			r.IPAM.Config = append(r.IPAM.Config, iData)
		}
	}

	hasIpv6Conf := false
	for _, ip6 := range ipv6conf {
		if ip6.PreferredPool == "" {
			continue
		}
		hasIpv6Conf = true
		iData := network.IPAMConfig{}
		iData.Subnet = ip6.PreferredPool
		iData.IPRange = ip6.SubPool
		iData.Gateway = ip6.Gateway
		iData.AuxAddress = ip6.AuxAddresses
		r.IPAM.Config = append(r.IPAM.Config, iData)
	}

	if !hasIpv6Conf {
		for _, ip6Info := range ipv6Info {
			iData := network.IPAMConfig{}
			iData.Subnet = ip6Info.IPAMData.Pool.String()
			iData.Gateway = ip6Info.IPAMData.Gateway.String()
			r.IPAM.Config = append(r.IPAM.Config, iData)
		}
	}
}

func buildEndpointResource(e libnetwork.Endpoint) types.EndpointResource {
	er := types.EndpointResource{}
	if e == nil {
		return er
	}

	er.EndpointID = e.ID()
	er.Name = e.Name()
	ei := e.Info()
	if ei == nil {
		return er
	}

	if iface := ei.Iface(); iface != nil {
		if mac := iface.MacAddress(); mac != nil {
			er.MacAddress = mac.String()
		}
		if ip := iface.Address(); ip != nil && len(ip.IP) > 0 {
			er.IPv4Address = ip.String()
		}

		if ipv6 := iface.AddressIPv6(); ipv6 != nil && len(ipv6.IP) > 0 {
			er.IPv6Address = ipv6.String()
		}
	}
	return er
}
<|endoftext|>


<commit_before>package protocol

// A PacketNumber in QUIC
type PacketNumber int64

// InvalidPacketNumber is a packet number that is never sent.
// In QUIC, 0 is a valid packet number.
const InvalidPacketNumber PacketNumber = -1

// PacketNumberLen is the length of the packet number in bytes
type PacketNumberLen uint8

const (
	// PacketNumberLenInvalid is the default value and not a valid length for a packet number
	PacketNumberLenInvalid PacketNumberLen = 0
	// PacketNumberLen1 is a packet number length of 1 byte
	PacketNumberLen1 PacketNumberLen = 1
	// PacketNumberLen2 is a packet number length of 2 bytes
	PacketNumberLen2 PacketNumberLen = 2
	// PacketNumberLen3 is a packet number length of 3 bytes
	PacketNumberLen3 PacketNumberLen = 3
	// PacketNumberLen4 is a packet number length of 4 bytes
	PacketNumberLen4 PacketNumberLen = 4
)

// DecodePacketNumber calculates the packet number based on the received packet number, its length and the last seen packet number
func DecodePacketNumber(
	packetNumberLength PacketNumberLen,
	lastPacketNumber PacketNumber,
	wirePacketNumber PacketNumber,
) PacketNumber {
	var epochDelta PacketNumber
	switch packetNumberLength {
	case PacketNumberLen1:
		epochDelta = PacketNumber(1) << 8
	case PacketNumberLen2:
		epochDelta = PacketNumber(1) << 16
	case PacketNumberLen3:
		epochDelta = PacketNumber(1) << 24
	case PacketNumberLen4:
		epochDelta = PacketNumber(1) << 32
	}
	epoch := lastPacketNumber & ^(epochDelta - 1)
	var prevEpochBegin PacketNumber
	if epoch > epochDelta {
		prevEpochBegin = epoch - epochDelta
	}
	nextEpochBegin := epoch + epochDelta
	return closestTo(
		lastPacketNumber+1,
		epoch+wirePacketNumber,
		closestTo(lastPacketNumber+1, prevEpochBegin+wirePacketNumber, nextEpochBegin+wirePacketNumber),
	)
}

func closestTo(target, a, b PacketNumber) PacketNumber {
	if delta(target, a) < delta(target, b) {
		return a
	}
	return b
}

func delta(a, b PacketNumber) PacketNumber {
	if a < b {
		return b - a
	}
	return a - b
}

// GetPacketNumberLengthForHeader gets the length of the packet number for the public header
// it never chooses a PacketNumberLen of 1 byte, since this is too short under certain circumstances
func GetPacketNumberLengthForHeader(packetNumber, leastUnacked PacketNumber) PacketNumberLen {
	diff := uint64(packetNumber - leastUnacked)
	if diff < (1 << (16 - 1)) {
		return PacketNumberLen2
	}
	if diff < (1 << (24 - 1)) {
		return PacketNumberLen3
	}
	return PacketNumberLen4
}
<commit_msg>remove unused protocol.PacketNumberLenInvalid<commit_after>package protocol

// A PacketNumber in QUIC
type PacketNumber int64

// InvalidPacketNumber is a packet number that is never sent.
// In QUIC, 0 is a valid packet number.
const InvalidPacketNumber PacketNumber = -1

// PacketNumberLen is the length of the packet number in bytes
type PacketNumberLen uint8

const (
	// PacketNumberLen1 is a packet number length of 1 byte
	PacketNumberLen1 PacketNumberLen = 1
	// PacketNumberLen2 is a packet number length of 2 bytes
	PacketNumberLen2 PacketNumberLen = 2
	// PacketNumberLen3 is a packet number length of 3 bytes
	PacketNumberLen3 PacketNumberLen = 3
	// PacketNumberLen4 is a packet number length of 4 bytes
	PacketNumberLen4 PacketNumberLen = 4
)

// DecodePacketNumber calculates the packet number based on the received packet number, its length and the last seen packet number
func DecodePacketNumber(
	packetNumberLength PacketNumberLen,
	lastPacketNumber PacketNumber,
	wirePacketNumber PacketNumber,
) PacketNumber {
	var epochDelta PacketNumber
	switch packetNumberLength {
	case PacketNumberLen1:
		epochDelta = PacketNumber(1) << 8
	case PacketNumberLen2:
		epochDelta = PacketNumber(1) << 16
	case PacketNumberLen3:
		epochDelta = PacketNumber(1) << 24
	case PacketNumberLen4:
		epochDelta = PacketNumber(1) << 32
	}
	epoch := lastPacketNumber & ^(epochDelta - 1)
	var prevEpochBegin PacketNumber
	if epoch > epochDelta {
		prevEpochBegin = epoch - epochDelta
	}
	nextEpochBegin := epoch + epochDelta
	return closestTo(
		lastPacketNumber+1,
		epoch+wirePacketNumber,
		closestTo(lastPacketNumber+1, prevEpochBegin+wirePacketNumber, nextEpochBegin+wirePacketNumber),
	)
}

func closestTo(target, a, b PacketNumber) PacketNumber {
	if delta(target, a) < delta(target, b) {
		return a
	}
	return b
}

func delta(a, b PacketNumber) PacketNumber {
	if a < b {
		return b - a
	}
	return a - b
}

// GetPacketNumberLengthForHeader gets the length of the packet number for the public header
// it never chooses a PacketNumberLen of 1 byte, since this is too short under certain circumstances
func GetPacketNumberLengthForHeader(packetNumber, leastUnacked PacketNumber) PacketNumberLen {
	diff := uint64(packetNumber - leastUnacked)
	if diff < (1 << (16 - 1)) {
		return PacketNumberLen2
	}
	if diff < (1 << (24 - 1)) {
		return PacketNumberLen3
	}
	return PacketNumberLen4
}
<|endoftext|>


<commit_before>package routes

import (
	"net/http"

	h "github.com/anonx/sunplate/internal/skeleton/assets/handlers"

	r "github.com/anonx/sunplate/routing"
)

// List is a slice of routes of the following form:
//	Route:
//		Pattern
//		Handlers:
//			Method: Handler
// If using a standard router just call Context.Build() to get http handler
// as the first argument and an error (or nil) as the second one.
var List = r.Routes{
	r.Get("/", h.App.Index),
	r.Post("/greet/:name", h.App.PostGreet),

	// Serve static files of ./static directory.
	r.Get("/static", http.FileServer(http.Dir("./static")).ServeHTTP),
}
<commit_msg>Fix for correct serve of static files<commit_after>package routes

import (
	"net/http"

	h "github.com/anonx/sunplate/internal/skeleton/assets/handlers"

	r "github.com/anonx/sunplate/routing"
)

// List is a slice of routes of the following form:
//	Route:
//		Pattern
//		Handlers:
//			Method: Handler
// If using a standard router just call Context.Build() to get http handler
// as the first argument and an error (or nil) as the second one.
var List = r.Routes{
	r.Get("/", h.App.Index),
	r.Post("/greet/:name", h.App.PostGreet),

	// Serve static files of ./static directory.
	r.Get("/static/*filepath", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))).ServeHTTP),
}
<|endoftext|>


<commit_before>/*
Copyright 2021 The Kubernetes 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 deployer

import (
	"os"
	"path"
	"strings"

	"gopkg.in/yaml.v2"
	"k8s.io/klog/v2"
	"sigs.k8s.io/kubetest2/pkg/exec"
)

// renderTemplate will render the manifest template with the provided values,
// setting the deployer's manifestPath
func (d *deployer) renderTemplate(values map[string]interface{}) error {
	dir, err := os.MkdirTemp("", "kops-template")
	if err != nil {
		return err
	}

	valuesBytes, err := yaml.Marshal(values)
	if err != nil {
		return err
	}
	valuesPath := path.Join(dir, "values.yaml")
	err = os.WriteFile(valuesPath, valuesBytes, 0o644)
	if err != nil {
		return err
	}

	manifestPath := path.Join(dir, "manifest.yaml")
	d.manifestPath = manifestPath

	args := []string{
		d.KopsBinaryPath, "toolbox", "template",
		"--template", d.TemplatePath,
		"--output", manifestPath,
		"--values", valuesPath,
		"--name", d.ClusterName,
	}
	klog.Info(strings.Join(args, " "))

	cmd := exec.Command(args[0], args[1:]...)
	cmd.SetEnv(d.env()...)

	exec.InheritOutput(cmd)
	err = cmd.Run()
	if err != nil {
		return err
	}
	return nil
}

func (d *deployer) templateValues(zones []string, publicIP string) (map[string]interface{}, error) {
	publicKey, err := os.ReadFile(d.SSHPublicKeyPath)
	if err != nil {
		return nil, err
	}
	return map[string]interface{}{
		"cloudProvider":     d.CloudProvider,
		"clusterName":       d.ClusterName,
		"kubernetesVersion": d.KubernetesVersion,
		"publicIP":          publicIP,
		"stateStore":        d.stateStore(),
		"zones":             zones,
		"sshPublicKey":      string(publicKey),
	}, nil
}
<commit_msg>More descriptive error message when public key file can't be opened<commit_after>/*
Copyright 2021 The Kubernetes 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 deployer

import (
	"fmt"
	"os"
	"path"
	"strings"

	"gopkg.in/yaml.v2"
	"k8s.io/klog/v2"
	"sigs.k8s.io/kubetest2/pkg/exec"
)

// renderTemplate will render the manifest template with the provided values,
// setting the deployer's manifestPath
func (d *deployer) renderTemplate(values map[string]interface{}) error {
	dir, err := os.MkdirTemp("", "kops-template")
	if err != nil {
		return err
	}

	valuesBytes, err := yaml.Marshal(values)
	if err != nil {
		return err
	}
	valuesPath := path.Join(dir, "values.yaml")
	err = os.WriteFile(valuesPath, valuesBytes, 0o644)
	if err != nil {
		return err
	}

	manifestPath := path.Join(dir, "manifest.yaml")
	d.manifestPath = manifestPath

	args := []string{
		d.KopsBinaryPath, "toolbox", "template",
		"--template", d.TemplatePath,
		"--output", manifestPath,
		"--values", valuesPath,
		"--name", d.ClusterName,
	}
	klog.Info(strings.Join(args, " "))

	cmd := exec.Command(args[0], args[1:]...)
	cmd.SetEnv(d.env()...)

	exec.InheritOutput(cmd)
	err = cmd.Run()
	if err != nil {
		return err
	}
	return nil
}

func (d *deployer) templateValues(zones []string, publicIP string) (map[string]interface{}, error) {
	publicKey, err := os.ReadFile(d.SSHPublicKeyPath)
	if err != nil {
		return nil, fmt.Errorf("error reading public key file: %q", err)
	}
	return map[string]interface{}{
		"cloudProvider":     d.CloudProvider,
		"clusterName":       d.ClusterName,
		"kubernetesVersion": d.KubernetesVersion,
		"publicIP":          publicIP,
		"stateStore":        d.stateStore(),
		"zones":             zones,
		"sshPublicKey":      string(publicKey),
	}, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/GeertJohan/go.linenoise"
	"os"
	"strings"
)

func main() {
	fmt.Println("Welcome to go.linenoise example.")
	writeHelp()
	for {
		str, err := linenoise.Line("prompt> ")
		if err != nil {
			if err == linenoise.KillSignalError {
				quit()
			}
			fmt.Println("Unexpected error: %s", err)
			quit()
		}
		fields := strings.Fields(str)

		// check if there is any valid input at all
		if len(fields) == 0 {
			writeUnrecognized()
			continue
		}

		// switch on the command
		switch fields[0] {
		case "help":
			writeHelp()
		case "echo":
			fmt.Printf("echo: %s\n\n", str[5:])
		case "clear":
			linenoise.Clear()
		case "multiline":
			fmt.Println("Setting linenoise to multiline")
			linenoise.SetMultiline(true)
		case "singleline":
			fmt.Println("Setting linenoise to singleline")
			linenoise.SetMultiline(false)
		case "complete":
			fmt.Println("Setting arguments as completion values for linenoise.")
			fmt.Printf("%d arguments: %s\n", len(fields)-1, fields[1:])
			completionHandler := func(in string) []string {
				return fields[1:]
			}
			linenoise.SetCompletionHandler(completionHandler)
		case "printKeyCodes":
			linenoise.PrintKeyCodes()
		case "addHistory":
			if len(str) < 12 {
				fmt.Println("No argument given.")
			}
			err := linenoise.AddHistory(str[11:])
			if err != nil {
				fmt.Printf("Error: %s\n", err)
			}
		case "save":
			if len(fields) != 2 {
				fmt.Println("Error. Expecting 'save <filename>'.")
				continue
			}
			err := linenoise.SaveHistory(fields[1])
			if err != nil {
				fmt.Printf("Error on save: %s\n", err)
			}
		case "load":
			if len(fields) != 2 {
				fmt.Println("Error. Expecting 'load <filename>'.")
				continue
			}
			err := linenoise.LoadHistory(fields[1])
			if err != nil {
				fmt.Printf("Error on load: %s\n", err)
			}
		case "quit":
			quit()
		default:
			writeUnrecognized()
		}
	}
}

func quit() {
	fmt.Println("Thanks for running the go.linenoise example.")
	fmt.Println("")
	os.Exit(0)
}

func writeHelp() {
	fmt.Println("help              write this message")
	fmt.Println("echo ...          echo the arguments")
	fmt.Println("clear             clear the screen")
	fmt.Println("multiline         set linenoise to multiline")
	fmt.Println("singleline        set linenoise to singleline")
	fmt.Println("complete ...      set arguments as completion values")
	fmt.Println("addHistory ...    add arguments to linenoise history")
	fmt.Println("save <filename>   save the history to file")
	fmt.Println("load <filename>   load the history from file")
	fmt.Println("quit              stop the program")
	fmt.Println("")
	fmt.Println("Use the arrow up and down keys to walk through history.")
	fmt.Println("Note that you have to use addHistory to create history entries. Commands are not added to history in this example.")
	fmt.Println("")
}

func writeUnrecognized() {
	fmt.Println("Unrecognized command. Use 'help'.")
}
<commit_msg>Update imports with goimports Fix invalid fmt.Println call<commit_after>package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/GeertJohan/go.linenoise"
)

func main() {
	fmt.Println("Welcome to go.linenoise example.")
	writeHelp()
	for {
		str, err := linenoise.Line("prompt> ")
		if err != nil {
			if err == linenoise.KillSignalError {
				quit()
			}
			fmt.Printf("Unexpected error: %s\n", err)
			quit()
		}
		fields := strings.Fields(str)

		// check if there is any valid input at all
		if len(fields) == 0 {
			writeUnrecognized()
			continue
		}

		// switch on the command
		switch fields[0] {
		case "help":
			writeHelp()
		case "echo":
			fmt.Printf("echo: %s\n\n", str[5:])
		case "clear":
			linenoise.Clear()
		case "multiline":
			fmt.Println("Setting linenoise to multiline")
			linenoise.SetMultiline(true)
		case "singleline":
			fmt.Println("Setting linenoise to singleline")
			linenoise.SetMultiline(false)
		case "complete":
			fmt.Println("Setting arguments as completion values for linenoise.")
			fmt.Printf("%d arguments: %s\n", len(fields)-1, fields[1:])
			completionHandler := func(in string) []string {
				return fields[1:]
			}
			linenoise.SetCompletionHandler(completionHandler)
		case "printKeyCodes":
			linenoise.PrintKeyCodes()
		case "addHistory":
			if len(str) < 12 {
				fmt.Println("No argument given.")
			}
			err := linenoise.AddHistory(str[11:])
			if err != nil {
				fmt.Printf("Error: %s\n", err)
			}
		case "save":
			if len(fields) != 2 {
				fmt.Println("Error. Expecting 'save <filename>'.")
				continue
			}
			err := linenoise.SaveHistory(fields[1])
			if err != nil {
				fmt.Printf("Error on save: %s\n", err)
			}
		case "load":
			if len(fields) != 2 {
				fmt.Println("Error. Expecting 'load <filename>'.")
				continue
			}
			err := linenoise.LoadHistory(fields[1])
			if err != nil {
				fmt.Printf("Error on load: %s\n", err)
			}
		case "quit":
			quit()
		default:
			writeUnrecognized()
		}
	}
}

func quit() {
	fmt.Println("Thanks for running the go.linenoise example.")
	fmt.Println("")
	os.Exit(0)
}

func writeHelp() {
	fmt.Println("help              write this message")
	fmt.Println("echo ...          echo the arguments")
	fmt.Println("clear             clear the screen")
	fmt.Println("multiline         set linenoise to multiline")
	fmt.Println("singleline        set linenoise to singleline")
	fmt.Println("complete ...      set arguments as completion values")
	fmt.Println("addHistory ...    add arguments to linenoise history")
	fmt.Println("save <filename>   save the history to file")
	fmt.Println("load <filename>   load the history from file")
	fmt.Println("quit              stop the program")
	fmt.Println("")
	fmt.Println("Use the arrow up and down keys to walk through history.")
	fmt.Println("Note that you have to use addHistory to create history entries. Commands are not added to history in this example.")
	fmt.Println("")
}

func writeUnrecognized() {
	fmt.Println("Unrecognized command. Use 'help'.")
}
<|endoftext|>


<commit_before>/* Read from /sys/devices/virtual/dmi/id/board_{name,serial,vendor} */
package mbinfo

import (
	"fmt"
	"os/exec"
)

const MB_NAME_FILE = "/sys/devices/virtual/dmi/id/board_name"
const MB_SERIAL_FILE = "/sys/devices/virtual/dmi/id/board_serial"
const MB_VENDOR_FILE = "/sys/devices/virtual/dmi/id/board_vendor"

type MBstats struct {
	Model  string
	Serial string
}

var Motherboard MBstats

func cat_file(filepath string) (ret string) {
	cmd := exec.Command("/bin/cat", filepath)
	buf, err := cmd.Output()
	if err != nil {
		fmt.Println(err)
		return
	}
	ret = string(buf)
	return
}

func init() {
	Motherboard.Model = cat_file(MB_VENDOR_FILE) + cat_file(MB_NAME_FILE)
	Motherboard.Serial = cat_file(MB_SERIAL_FILE)
}
<commit_msg>Remove '\n' character in Motherboard's Model/Serial<commit_after>/* Read from /sys/devices/virtual/dmi/id/board_{name,serial,vendor} */
package mbinfo

import (
	"fmt"
	"os/exec"
	"strings"
)

const MB_NAME_FILE = "/sys/devices/virtual/dmi/id/board_name"
const MB_SERIAL_FILE = "/sys/devices/virtual/dmi/id/board_serial"
const MB_VENDOR_FILE = "/sys/devices/virtual/dmi/id/board_vendor"

type MBstats struct {
	Model  string
	Serial string
}

var Motherboard MBstats

func cat_file(filepath string) (ret string) {
	cmd := exec.Command("/bin/cat", filepath)
	buf, err := cmd.Output()
	if err != nil {
		fmt.Println(err)
		return
	}
	ret = string(buf)
	return
}

func init() {
	Motherboard.Model = cat_file(MB_VENDOR_FILE) + cat_file(MB_NAME_FILE)
	Motherboard.Model = strings.Replace(Motherboard.Model, "\n", " ", -1)

	Motherboard.Serial = cat_file(MB_SERIAL_FILE)
	Motherboard.Serial = strings.Replace(Motherboard.Serial, "\n", " ", -1)
}
<|endoftext|>


<commit_before>// Copyright 2017 ego 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 main

import (
	"log"
	"net/http"

	"github.com/go-ego/riot/net/com"
	rpc "github.com/go-ego/riot/net/grpc"
	rhttp "github.com/go-ego/riot/net/http"

	"github.com/go-ego/riot/engine"
	"github.com/go-vgo/gt/conf"
	"github.com/go-vgo/gt/zlog"
)

var (
	// searcher is coroutine safe
	searcher = engine.Engine{}
)

var config com.Config

func init() {
	zlog.Init("../conf/log.toml")
	conf.Init("../conf/riot.toml", &config)
	go conf.NewWatcher("../conf/riot.toml", &config)
	// go
	rpc.InitEngine(config)

	grpcPort := config.Rpc.GrpcPort
	go rpc.InitGrpc(grpcPort[1])
	distPort := config.Rpc.DistPort
	go rpc.InitGrpc(distPort[1])

	go rpc.InitErpc(1)
}

func main() {
	if config.Engine.Mode == "dev" {
		go func() {
			log.Println(http.ListenAndServe("localhost:6060", nil))
		}()
	}

	http.HandleFunc("/search", rhttp.Search)
	http.HandleFunc("/dist", rhttp.WgDist)
	log.Println("服务器 8081 启动...")
	log.Fatal(http.ListenAndServe(":8081", nil))
}
<commit_msg>Update data riot1<commit_after>// Copyright 2017 ego 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 main

import (
	"log"
	"net/http"

	"github.com/go-ego/riot/net/com"
	rpc "github.com/go-ego/riot/net/grpc"
	rhttp "github.com/go-ego/riot/net/http"

	"github.com/go-ego/riot/engine"
	"github.com/go-vgo/gt/conf"
	"github.com/go-vgo/gt/zlog"
)

var (
	// searcher is coroutine safe
	searcher = engine.Engine{}
)

var config com.Config

func init() {
	zlog.Init("../conf/log.toml")
	conf.Init("../conf/riot.toml", &config)
	go conf.NewWatcher("../conf/riot.toml", &config)
	// go
	rpc.InitEngine(config)

	grpcPort := config.Rpc.GrpcPort
	go rpc.InitGrpc(grpcPort[1])
	distPort := config.Rpc.DistPort
	go rpc.InitGrpc(distPort[1])

	go rpc.InitErpc(1)
}

func main() {
	if config.Engine.Mode == "dev" {
		go func() {
			log.Println(http.ListenAndServe("localhost:6061", nil))
		}()
	}

	http.HandleFunc("/search", rhttp.Search)
	http.HandleFunc("/dist", rhttp.WgDist)
	log.Println("服务器 8081 启动...")
	log.Fatal(http.ListenAndServe(":8081", nil))
}
<|endoftext|>


<commit_before>// Copyright 2020, 2021 Google LLC
//
// 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
//
//     https://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.

// Binary wrap is a test helper program for //elisp:binary_test, which see.
package main

import (
	"encoding/json"
	"flag"
	"io/ioutil"
	"log"
	"os"

	"github.com/google/go-cmp/cmp"
	"github.com/phst/runfiles"
)

func main() {
	log.Println("Args:", os.Args)
	var manifestFile string
	flag.StringVar(&manifestFile, "manifest", "", "")
	flag.Parse()
	if manifestFile == "" {
		log.Fatal("--manifest is empty")
	}
	workspaceDir, err := runfiles.Path("phst_rules_elisp")
	if err != nil {
		log.Fatal(err)
	}
	gotArgs := flag.Args()
	wantArgs := []string{
		"--quick", "--batch",
		"--directory=" + workspaceDir,
		"--option",
		"elisp/binary.cc",
		"/:/tmp/output.dat",
	}
	if diff := cmp.Diff(gotArgs, wantArgs); diff != "" {
		log.Fatalf("positional arguments: -git +want:\n%s", diff)
	}
	jsonData, err := ioutil.ReadFile(manifestFile)
	if err != nil {
		log.Fatalf("can’t read manifest: %s", err)
	}
	var got map[string]interface{}
	if err := json.Unmarshal(jsonData, &got); err != nil {
		log.Fatalf("can’t decode manifest: %s", err)
	}
	want := map[string]interface{}{
		"root":        "RUNFILES_ROOT",
		"tags":        []interface{}{"local", "mytag"},
		"loadPath":    []interface{}{"phst_rules_elisp"},
		"inputFiles":  []interface{}{"phst_rules_elisp/elisp/binary.cc", "phst_rules_elisp/elisp/binary.h"},
		"outputFiles": []interface{}{"/tmp/output.dat"},
	}
	if diff := cmp.Diff(got, want); diff != "" {
		log.Fatalf("manifest: -got +want:\n%s", diff)
	}
}
<commit_msg>Rename confusingly-named variables<commit_after>// Copyright 2020, 2021 Google LLC
//
// 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
//
//     https://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.

// Binary wrap is a test helper program for //elisp:binary_test, which see.
package main

import (
	"encoding/json"
	"flag"
	"io/ioutil"
	"log"
	"os"

	"github.com/google/go-cmp/cmp"
	"github.com/phst/runfiles"
)

func main() {
	log.Println("Args:", os.Args)
	var manifestFile string
	flag.StringVar(&manifestFile, "manifest", "", "")
	flag.Parse()
	if manifestFile == "" {
		log.Fatal("--manifest is empty")
	}
	workspaceDir, err := runfiles.Path("phst_rules_elisp")
	if err != nil {
		log.Fatal(err)
	}
	gotArgs := flag.Args()
	wantArgs := []string{
		"--quick", "--batch",
		"--directory=" + workspaceDir,
		"--option",
		"elisp/binary.cc",
		"/:/tmp/output.dat",
	}
	if diff := cmp.Diff(gotArgs, wantArgs); diff != "" {
		log.Fatalf("positional arguments: -git +want:\n%s", diff)
	}
	jsonData, err := ioutil.ReadFile(manifestFile)
	if err != nil {
		log.Fatalf("can’t read manifest: %s", err)
	}
	var gotManifest map[string]interface{}
	if err := json.Unmarshal(jsonData, &gotManifest); err != nil {
		log.Fatalf("can’t decode manifest: %s", err)
	}
	wantManifest := map[string]interface{}{
		"root":        "RUNFILES_ROOT",
		"tags":        []interface{}{"local", "mytag"},
		"loadPath":    []interface{}{"phst_rules_elisp"},
		"inputFiles":  []interface{}{"phst_rules_elisp/elisp/binary.cc", "phst_rules_elisp/elisp/binary.h"},
		"outputFiles": []interface{}{"/tmp/output.dat"},
	}
	if diff := cmp.Diff(gotManifest, wantManifest); diff != "" {
		log.Fatalf("manifest: -got +want:\n%s", diff)
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 tests

import (
	"errors"
	"net"
	"net/http"
	"net/url"
	"os/exec"
	"strings"
	"testing"
	"time"

	"github.com/gorilla/websocket"

	"github.com/redhat-cip/skydive/agent"
	"github.com/redhat-cip/skydive/config"
	"github.com/redhat-cip/skydive/topology/graph"
)

// FIX(safchain) has to be removed when will be able to stop agent
var globalAgent *agent.Agent

func newClient() (*websocket.Conn, error) {
	conn, err := net.Dial("tcp", "127.0.0.1:8081")
	if err != nil {
		return nil, err
	}

	endpoint := "ws://127.0.0.1:8081/ws/graph"
	u, err := url.Parse(endpoint)
	if err != nil {
		return nil, err
	}

	wsConn, _, err := websocket.NewClient(conn, u, http.Header{"Origin": {endpoint}}, 1024, 1024)
	if err != nil {
		return nil, err
	}

	return wsConn, nil
}

func connectToAgent(timeout int, onReady func(*websocket.Conn)) (*websocket.Conn, error) {
	var ws *websocket.Conn
	var err error

	t := 0
	for {
		if t > timeout {
			return nil, errors.New("Connection timeout reached")
		}

		ws, err = newClient()
		if err == nil {
			break
		}
		time.Sleep(1 * time.Second)
		t++
	}

	ready := false
	h := func(message string) error {
		err := ws.WriteControl(websocket.PongMessage, []byte(message), time.Now().Add(time.Second))
		if err != nil {
			return err
		}
		if !ready {
			ready = true
			onReady(ws)
		}
		return nil
	}
	ws.SetPingHandler(h)

	return ws, nil
}

func processGraphMessage(g *graph.Graph, m []byte) error {
	g.Lock()
	defer g.Unlock()

	msg, err := graph.UnmarshalWSMessage(m)
	if err != nil {
		return err
	}

	switch msg.Type {
	case "NodeUpdated":
		n := msg.Obj.(*graph.Node)
		node := g.GetNode(n.ID)
		if node != nil {
			g.SetMetadatas(node, n.Metadatas())
		}
	case "NodeDeleted":
		g.DelNode(msg.Obj.(*graph.Node))
	case "NodeAdded":
		n := msg.Obj.(*graph.Node)
		if g.GetNode(n.ID) == nil {
			g.AddNode(n)
		}
	case "EdgeUpdated":
		e := msg.Obj.(*graph.Edge)
		edge := g.GetEdge(e.ID)
		if edge != nil {
			g.SetMetadatas(edge, e.Metadatas())
		}
	case "EdgeDeleted":
		g.DelEdge(msg.Obj.(*graph.Edge))
	case "EdgeAdded":
		e := msg.Obj.(*graph.Edge)
		if g.GetEdge(e.ID) == nil {
			g.AddEdge(e)
		}
	}

	return nil
}

func startAgent(t *testing.T) {
	// FIX(safchain) has to be removed see comment around the variable declaration
	if globalAgent != nil {
		return
	}

	config.InitEmptyConfig()

	section, err := config.GetConfig().NewSection("agent")
	if err != nil {
		t.Fatal(err.Error())
	}
	section.NewKey("listen", "8081")
	section.NewKey("flowtable_expire", "5")

	section, err = config.GetConfig().NewSection("cache")
	if err != nil {
		t.Fatal(err.Error())
	}
	section.NewKey("expire", "300")
	section.NewKey("cleanup", "30")

	section, err = config.GetConfig().NewSection("sflow")
	if err != nil {
		t.Fatal(err.Error())
	}
	section.NewKey("listen", "5000")

	section, err = config.GetConfig().NewSection("ovs")
	if err != nil {
		t.Fatal(err.Error())
	}
	section.NewKey("ovsdb", "6400")

	globalAgent = agent.NewAgent()
	go globalAgent.Start()
}

func startTopologyClient(t *testing.T, g *graph.Graph, onReady func(*websocket.Conn), onChange func()) error {
	// ready when got a first ping
	ws, err := connectToAgent(5, onReady)
	if err != nil {
		return err
	}

	for {
		_, m, err := ws.ReadMessage()
		if err != nil {
			break
		}

		err = processGraphMessage(g, m)
		if err != nil {
			return err
		}

		onChange()
	}

	return nil
}

func testTopology(t *testing.T, g *graph.Graph, cmds []string, onChange func(ws *websocket.Conn)) {
	var ws *websocket.Conn

	cmdIndex := 0
	or := func(w *websocket.Conn) {
		ws = w

		// ready to exec the first cmd
		err := exec.Command("sudo", strings.Split(cmds[cmdIndex], " ")...).Run()
		if err != nil {
			t.Fatal(err.Error())
		}
		cmdIndex++
	}

	oc := func() {
		onChange(ws)

		// exec the following command
		if cmdIndex < len(cmds) {
			err := exec.Command("sudo", strings.Split(cmds[cmdIndex], " ")...).Run()
			if err != nil {
				t.Fatal(err.Error())
			}
			cmdIndex++
		}
	}

	err := startTopologyClient(t, g, or, oc)
	if err != nil {
		t.Fatal(err.Error())
	}
}

func TestBridgeOVS(t *testing.T) {
	backend, err := graph.NewMemoryBackend()
	if err != nil {
		t.Fatal(err.Error())
	}

	g, err := graph.NewGraph(backend)
	if err != nil {
		t.Fatal(err.Error())
	}

	startAgent(t)

	setupCmds := []string{
		"ovs-vsctl add-br br-test1",
	}

	tearDownCmds := []string{
		"ovs-vsctl del-br br-test1",
	}

	testPassed := false
	onChange := func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) >= 3 && len(g.GetEdges()) >= 2 {
			ovsbridge := g.LookupFirstNode(graph.Metadatas{"Type": "ovsbridge", "Name": "br-test1"})
			if ovsbridge == nil {
				t.Error("ovs bridge not found")
			}
			ovsports := g.LookupChildren(ovsbridge, graph.Metadatas{"Type": "ovsport"})
			if len(ovsports) != 1 {
				t.Error("ovs port not found or not unique")
			}
			devices := g.LookupChildren(ovsports[0], graph.Metadatas{"Type": "internal", "Driver": "openvswitch"})
			if len(devices) != 1 {
				t.Error("device not found or not unique")
			}

			if ovsbridge.Metadatas()["Host"] == "" || ovsports[0].Metadatas()["Host"] == "" || devices[0].Metadatas()["Host"] == "" {
				t.Error("host binding not found")
			}

			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, setupCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}

	// cleanup side on the test
	testPassed = false
	onChange = func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) == 0 && len(g.GetEdges()) == 0 {
			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, tearDownCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}
}

func TestPatchOVS(t *testing.T) {
	backend, err := graph.NewMemoryBackend()
	if err != nil {
		t.Fatal(err.Error())
	}

	g, err := graph.NewGraph(backend)
	if err != nil {
		t.Fatal(err.Error())
	}

	startAgent(t)

	setupCmds := []string{
		"ovs-vsctl add-br br-test1",
		"ovs-vsctl add-br br-test2",
		"ovs-vsctl add-port br-test1 patch-br-test2 -- set interface patch-br-test2 type=patch",
		"ovs-vsctl add-port br-test2 patch-br-test1 -- set interface patch-br-test1 type=patch",
		"ovs-vsctl set interface patch-br-test2 option:peer=patch-br-test1",
		"ovs-vsctl set interface patch-br-test1 option:peer=patch-br-test2",
	}

	tearDownCmds := []string{
		"ovs-vsctl del-br br-test1",
		"ovs-vsctl del-br br-test2",
	}

	testPassed := false
	onChange := func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) >= 10 && len(g.GetEdges()) >= 9 {
			patch1 := g.LookupFirstNode(graph.Metadatas{"Type": "patch", "Name": "patch-br-test1", "Driver": "openvswitch"})
			if patch1 == nil {
				t.Error("patch not found")
			}

			patch2 := g.LookupFirstNode(graph.Metadatas{"Type": "patch", "Name": "patch-br-test2", "Driver": "openvswitch"})
			if patch2 == nil {
				t.Error("patch not found")
			}

			if !g.AreLinked(patch1, patch2) {
				t.Error("patch interfaces not linked")
			}

			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, setupCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}

	// cleanup side on the test
	testPassed = false
	onChange = func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) == 0 && len(g.GetEdges()) == 0 {
			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, tearDownCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}
}

func TestInterfaceOVS(t *testing.T) {
	backend, err := graph.NewMemoryBackend()
	if err != nil {
		t.Fatal(err.Error())
	}

	g, err := graph.NewGraph(backend)
	if err != nil {
		t.Fatal(err.Error())
	}

	startAgent(t)

	setupCmds := []string{
		"ovs-vsctl add-br br-test1",
		"ovs-vsctl add-port br-test1 intf1 -- set interface intf1 type=internal",
	}

	tearDownCmds := []string{
		"ovs-vsctl del-br br-test1",
	}

	testPassed := false
	onChange := func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) >= 5 && len(g.GetEdges()) >= 4 {
			intf := g.LookupFirstNode(graph.Metadatas{"Type": "internal", "Name": "intf1", "Driver": "openvswitch"})
			if intf != nil {
				if _, ok := intf.Metadatas()["UUID"]; ok {
					// check we don't have another interface potentially added by netlink
					// should only have ovsport and interface
					others := g.LookupNodes(graph.Metadatas{"Name": "intf1"})
					if len(others) > 2 {
						t.Error("found more interface than expected")
					}

					if _, ok := intf.Metadatas()["MAC"]; !ok {
						t.Error("mac not found")
					}

					testPassed = true

					ws.Close()
				}
			}
		}
	}

	testTopology(t, g, setupCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}

	// cleanup side on the test
	testPassed = false
	onChange = func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) == 0 && len(g.GetEdges()) == 0 {
			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, tearDownCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}
}
<commit_msg>Add ovs bond fonctional test<commit_after>/*
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 tests

import (
	"errors"
	"net"
	"net/http"
	"net/url"
	"os/exec"
	"strings"
	"testing"
	"time"

	"github.com/gorilla/websocket"

	"github.com/redhat-cip/skydive/agent"
	"github.com/redhat-cip/skydive/config"
	"github.com/redhat-cip/skydive/topology/graph"
)

// FIX(safchain) has to be removed when will be able to stop agent
var globalAgent *agent.Agent

func newClient() (*websocket.Conn, error) {
	conn, err := net.Dial("tcp", "127.0.0.1:8081")
	if err != nil {
		return nil, err
	}

	endpoint := "ws://127.0.0.1:8081/ws/graph"
	u, err := url.Parse(endpoint)
	if err != nil {
		return nil, err
	}

	wsConn, _, err := websocket.NewClient(conn, u, http.Header{"Origin": {endpoint}}, 1024, 1024)
	if err != nil {
		return nil, err
	}

	return wsConn, nil
}

func connectToAgent(timeout int, onReady func(*websocket.Conn)) (*websocket.Conn, error) {
	var ws *websocket.Conn
	var err error

	t := 0
	for {
		if t > timeout {
			return nil, errors.New("Connection timeout reached")
		}

		ws, err = newClient()
		if err == nil {
			break
		}
		time.Sleep(1 * time.Second)
		t++
	}

	ready := false
	h := func(message string) error {
		err := ws.WriteControl(websocket.PongMessage, []byte(message), time.Now().Add(time.Second))
		if err != nil {
			return err
		}
		if !ready {
			ready = true
			onReady(ws)
		}
		return nil
	}
	ws.SetPingHandler(h)

	return ws, nil
}

func processGraphMessage(g *graph.Graph, m []byte) error {
	g.Lock()
	defer g.Unlock()

	msg, err := graph.UnmarshalWSMessage(m)
	if err != nil {
		return err
	}

	switch msg.Type {
	case "NodeUpdated":
		n := msg.Obj.(*graph.Node)
		node := g.GetNode(n.ID)
		if node != nil {
			g.SetMetadatas(node, n.Metadatas())
		}
	case "NodeDeleted":
		g.DelNode(msg.Obj.(*graph.Node))
	case "NodeAdded":
		n := msg.Obj.(*graph.Node)
		if g.GetNode(n.ID) == nil {
			g.AddNode(n)
		}
	case "EdgeUpdated":
		e := msg.Obj.(*graph.Edge)
		edge := g.GetEdge(e.ID)
		if edge != nil {
			g.SetMetadatas(edge, e.Metadatas())
		}
	case "EdgeDeleted":
		g.DelEdge(msg.Obj.(*graph.Edge))
	case "EdgeAdded":
		e := msg.Obj.(*graph.Edge)
		if g.GetEdge(e.ID) == nil {
			g.AddEdge(e)
		}
	}

	return nil
}

func startAgent(t *testing.T) {
	// FIX(safchain) has to be removed see comment around the variable declaration
	if globalAgent != nil {
		return
	}

	config.InitEmptyConfig()

	section, err := config.GetConfig().NewSection("agent")
	if err != nil {
		t.Fatal(err.Error())
	}
	section.NewKey("listen", "8081")
	section.NewKey("flowtable_expire", "5")

	section, err = config.GetConfig().NewSection("cache")
	if err != nil {
		t.Fatal(err.Error())
	}
	section.NewKey("expire", "300")
	section.NewKey("cleanup", "30")

	section, err = config.GetConfig().NewSection("sflow")
	if err != nil {
		t.Fatal(err.Error())
	}
	section.NewKey("listen", "5000")

	section, err = config.GetConfig().NewSection("ovs")
	if err != nil {
		t.Fatal(err.Error())
	}
	section.NewKey("ovsdb", "6400")

	globalAgent = agent.NewAgent()
	go globalAgent.Start()
}

func startTopologyClient(t *testing.T, g *graph.Graph, onReady func(*websocket.Conn), onChange func()) error {
	// ready when got a first ping
	ws, err := connectToAgent(5, onReady)
	if err != nil {
		return err
	}

	for {
		_, m, err := ws.ReadMessage()
		if err != nil {
			break
		}

		err = processGraphMessage(g, m)
		if err != nil {
			return err
		}

		onChange()
	}

	return nil
}

func testTopology(t *testing.T, g *graph.Graph, cmds []string, onChange func(ws *websocket.Conn)) {
	var ws *websocket.Conn

	cmdIndex := 0
	or := func(w *websocket.Conn) {
		ws = w

		// ready to exec the first cmd
		err := exec.Command("sudo", strings.Split(cmds[cmdIndex], " ")...).Run()
		if err != nil {
			t.Fatal(err.Error())
		}
		cmdIndex++
	}

	oc := func() {
		onChange(ws)

		// exec the following command
		if cmdIndex < len(cmds) {
			err := exec.Command("sudo", strings.Split(cmds[cmdIndex], " ")...).Run()
			if err != nil {
				t.Fatal(err.Error())
			}
			cmdIndex++
		}
	}

	err := startTopologyClient(t, g, or, oc)
	if err != nil {
		t.Fatal(err.Error())
	}
}

func TestBridgeOVS(t *testing.T) {
	backend, err := graph.NewMemoryBackend()
	if err != nil {
		t.Fatal(err.Error())
	}

	g, err := graph.NewGraph(backend)
	if err != nil {
		t.Fatal(err.Error())
	}

	startAgent(t)

	setupCmds := []string{
		"ovs-vsctl add-br br-test1",
	}

	tearDownCmds := []string{
		"ovs-vsctl del-br br-test1",
	}

	testPassed := false
	onChange := func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) >= 3 && len(g.GetEdges()) >= 2 {
			ovsbridge := g.LookupFirstNode(graph.Metadatas{"Type": "ovsbridge", "Name": "br-test1"})
			if ovsbridge == nil {
				t.Error("ovs bridge not found")
			}
			ovsports := g.LookupChildren(ovsbridge, graph.Metadatas{"Type": "ovsport"})
			if len(ovsports) != 1 {
				t.Error("ovs port not found or not unique")
			}
			devices := g.LookupChildren(ovsports[0], graph.Metadatas{"Type": "internal", "Driver": "openvswitch"})
			if len(devices) != 1 {
				t.Error("device not found or not unique")
			}

			if ovsbridge.Metadatas()["Host"] == "" || ovsports[0].Metadatas()["Host"] == "" || devices[0].Metadatas()["Host"] == "" {
				t.Error("host binding not found")
			}

			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, setupCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}

	// cleanup side on the test
	testPassed = false
	onChange = func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) == 0 && len(g.GetEdges()) == 0 {
			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, tearDownCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}
}

func TestPatchOVS(t *testing.T) {
	backend, err := graph.NewMemoryBackend()
	if err != nil {
		t.Fatal(err.Error())
	}

	g, err := graph.NewGraph(backend)
	if err != nil {
		t.Fatal(err.Error())
	}

	startAgent(t)

	setupCmds := []string{
		"ovs-vsctl add-br br-test1",
		"ovs-vsctl add-br br-test2",
		"ovs-vsctl add-port br-test1 patch-br-test2 -- set interface patch-br-test2 type=patch",
		"ovs-vsctl add-port br-test2 patch-br-test1 -- set interface patch-br-test1 type=patch",
		"ovs-vsctl set interface patch-br-test2 option:peer=patch-br-test1",
		"ovs-vsctl set interface patch-br-test1 option:peer=patch-br-test2",
	}

	tearDownCmds := []string{
		"ovs-vsctl del-br br-test1",
		"ovs-vsctl del-br br-test2",
	}

	testPassed := false
	onChange := func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) >= 10 && len(g.GetEdges()) >= 9 {
			patch1 := g.LookupFirstNode(graph.Metadatas{"Type": "patch", "Name": "patch-br-test1", "Driver": "openvswitch"})
			if patch1 == nil {
				t.Error("patch not found")
			}

			patch2 := g.LookupFirstNode(graph.Metadatas{"Type": "patch", "Name": "patch-br-test2", "Driver": "openvswitch"})
			if patch2 == nil {
				t.Error("patch not found")
			}

			if !g.AreLinked(patch1, patch2) {
				t.Error("patch interfaces not linked")
			}

			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, setupCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}

	// cleanup side on the test
	testPassed = false
	onChange = func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) == 0 && len(g.GetEdges()) == 0 {
			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, tearDownCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}
}

func TestInterfaceOVS(t *testing.T) {
	backend, err := graph.NewMemoryBackend()
	if err != nil {
		t.Fatal(err.Error())
	}

	g, err := graph.NewGraph(backend)
	if err != nil {
		t.Fatal(err.Error())
	}

	startAgent(t)

	setupCmds := []string{
		"ovs-vsctl add-br br-test1",
		"ovs-vsctl add-port br-test1 intf1 -- set interface intf1 type=internal",
	}

	tearDownCmds := []string{
		"ovs-vsctl del-br br-test1",
	}

	testPassed := false
	onChange := func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) >= 5 && len(g.GetEdges()) >= 4 {
			intf := g.LookupFirstNode(graph.Metadatas{"Type": "internal", "Name": "intf1", "Driver": "openvswitch"})
			if intf != nil {
				if _, ok := intf.Metadatas()["UUID"]; ok {
					// check we don't have another interface potentially added by netlink
					// should only have ovsport and interface
					others := g.LookupNodes(graph.Metadatas{"Name": "intf1"})
					if len(others) > 2 {
						t.Error("found more interface than expected")
					}

					if _, ok := intf.Metadatas()["MAC"]; !ok {
						t.Error("mac not found")
					}

					testPassed = true

					ws.Close()
				}
			}
		}
	}

	testTopology(t, g, setupCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}

	// cleanup side on the test
	testPassed = false
	onChange = func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) == 0 && len(g.GetEdges()) == 0 {
			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, tearDownCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}
}

func TestBondOVS(t *testing.T) {
	backend, err := graph.NewMemoryBackend()
	if err != nil {
		t.Fatal(err.Error())
	}

	g, err := graph.NewGraph(backend)
	if err != nil {
		t.Fatal(err.Error())
	}

	startAgent(t)

	setupCmds := []string{
		"ovs-vsctl add-br br-test1",
		"ip tuntap add mode tap dev intf1",
		"ip tuntap add mode tap dev intf2",
		"ovs-vsctl add-bond br-test1 bond0 intf1 intf2",
	}

	tearDownCmds := []string{
		"ovs-vsctl del-br br-test1",
		"ip link del intf1",
		"ip link del intf2",
	}

	testPassed := false
	onChange := func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) >= 6 && len(g.GetEdges()) >= 5 {
			bond := g.LookupFirstNode(graph.Metadatas{"Type": "ovsport", "Name": "bond0"})
			if bond != nil {
				intfs := g.LookupChildren(bond, nil)
				if len(intfs) != 2 {
					t.Error("bond interfaces not found")
				}

				testPassed = true

				ws.Close()
			}

		}
	}

	testTopology(t, g, setupCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}

	// cleanup side on the test
	testPassed = false
	onChange = func(ws *websocket.Conn) {
		g.Lock()
		defer g.Unlock()

		if !testPassed && len(g.GetNodes()) == 0 && len(g.GetEdges()) == 0 {
			testPassed = true

			ws.Close()
		}
	}

	testTopology(t, g, tearDownCmds, onChange)
	if !testPassed {
		t.Error("test not executed")
	}
}
<|endoftext|>


<commit_before>// Copyright 2011 The Go 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 pic // import "golang.org/x/tour/pic"

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"image"
	"image/png"
)

func Show(f func(int, int) [][]uint8) {
	const (
		dx = 256
		dy = 256
	)
	data := f(dx, dy)
	m := image.NewNRGBA(image.Rect(0, 0, dx, dy))
	for y := 0; y < dy; y++ {
		for x := 0; x < dx; x++ {
			v := data[y][x]
			i := y*m.Stride + x*4
			m.Pix[i] = v
			m.Pix[i+1] = v
			m.Pix[i+2] = 255
			m.Pix[i+3] = 255
		}
	}
	ShowImage(m)
}

func ShowImage(m image.Image) {
	var buf bytes.Buffer
	err := png.Encode(&buf, m)
	if err != nil {
		panic(err)
	}
	enc := base64.StdEncoding.EncodeToString(buf.Bytes())
	fmt.Println("IMAGE:" + enc)
}
<commit_msg>pic: document package<commit_after>// Copyright 2011 The Go 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 pic implements functions that
// display pictures on the Go playground.
package pic // import "golang.org/x/tour/pic"

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"image"
	"image/png"
)

// Show displays a picture defined by the function f
// when executed on the Go Playground.
//
// f should return a slice of length dy,
// each element of which is a slice of dx
// 8-bit unsigned int. The integers are
// interpreted as bluescale values,
// where the value 0 means full blue,
// and the value 255 means full white.
func Show(f func(dx, dy int) [][]uint8) {
	const (
		dx = 256
		dy = 256
	)
	data := f(dx, dy)
	m := image.NewNRGBA(image.Rect(0, 0, dx, dy))
	for y := 0; y < dy; y++ {
		for x := 0; x < dx; x++ {
			v := data[y][x]
			i := y*m.Stride + x*4
			m.Pix[i] = v
			m.Pix[i+1] = v
			m.Pix[i+2] = 255
			m.Pix[i+3] = 255
		}
	}
	ShowImage(m)
}

// ShowImage displays the image m
// when executed on the Go Playground.
func ShowImage(m image.Image) {
	var buf bytes.Buffer
	err := png.Encode(&buf, m)
	if err != nil {
		panic(err)
	}
	enc := base64.StdEncoding.EncodeToString(buf.Bytes())
	fmt.Println("IMAGE:" + enc)
}
<|endoftext|>


<commit_before>package server

import (
	"net/http/httptest"

	"github.com/gorilla/mux"
	"github.com/pivotal-cf-experimental/warrant/internal/server/clients"
	"github.com/pivotal-cf-experimental/warrant/internal/server/domain"
	"github.com/pivotal-cf-experimental/warrant/internal/server/groups"
	"github.com/pivotal-cf-experimental/warrant/internal/server/tokens"
	"github.com/pivotal-cf-experimental/warrant/internal/server/users"
)

// Config is the set of configuration values to provide
// to the fake server.
type Config struct {
	PublicKey string
}

// UAA is a fake implementation of the UAA HTTP service.
type UAA struct {
	server  *httptest.Server
	users   *domain.Users
	clients *domain.Clients
	groups  *domain.Groups
	tokens  *domain.Tokens

	publicKey string
}

// NewUAA returns a new UAA initialized with the given Config.
func NewUAA(config Config) *UAA {
	tokensCollection := domain.NewTokens(config.PublicKey, []string{
		"scim.read",
		"cloudcontroller.admin",
		"password.write",
		"scim.write",
		"openid",
		"cloud_controller.write",
		"cloud_controller.read",
		"doppler.firehose",
	}) // TODO: use a real RSA key
	usersCollection := domain.NewUsers()
	clientsCollection := domain.NewClients()
	groupsCollection := domain.NewGroups()
	router := mux.NewRouter()

	router.Handle("/Users{anything:.*}", users.NewRouter(usersCollection, tokensCollection))
	router.Handle("/Groups{anything:.*}", groups.NewRouter(groupsCollection, tokensCollection))
	router.Handle("/oauth/clients{anything:.*}", clients.NewRouter(clientsCollection, tokensCollection))
	router.Handle("/oauth/{anything:.*}", tokens.NewRouter(tokensCollection, usersCollection))
	router.Handle("/token_key", tokens.NewRouter(tokensCollection, usersCollection))

	return &UAA{
		server:    httptest.NewUnstartedServer(router),
		tokens:    tokensCollection,
		users:     usersCollection,
		clients:   clientsCollection,
		groups:    groupsCollection,
		publicKey: config.PublicKey,
	}

}

// Start will cause the HTTP server to bind to a port
// and start serving requests.
func (s *UAA) Start() {
	s.server.Start()
}

// Close will cause the HTTP server to stop serving
// requests and close its connection.
func (s *UAA) Close() {
	s.server.Close()
}

// Reset will clear all internal resource state within
// the server. This means that all users, clients, and
// groups will be deleted.
func (s *UAA) Reset() {
	s.users.Clear()
	s.clients.Clear()
	s.groups.Clear()
}

// URL returns the url that the server is hosted on.
func (s *UAA) URL() string {
	return s.server.URL
}

// SetDefaultScopes allows the default scopes applied to a
// user to be configured.
func (s *UAA) SetDefaultScopes(scopes []string) {
	s.tokens.DefaultScopes = scopes
} // TODO: move this configuration onto the Config

// ClientTokenFor returns a client token with the given id,
// scopes, and audiences.
func (s *UAA) ClientTokenFor(clientID string, scopes, audiences []string) string {
	// TODO: remove from API so that tokens are fetched like
	// they would be with a real UAA server.

	return s.tokens.Encrypt(domain.Token{
		ClientID:  clientID,
		Scopes:    scopes,
		Audiences: audiences,
	})
}

// UserTokenFor returns a user token with the given id,
// scopes, and audiences.
func (s *UAA) UserTokenFor(userID string, scopes, audiences []string) string {
	// TODO: remove from API so that tokens are fetched like
	// they would be with a real UAA server.

	return s.tokens.Encrypt(domain.Token{
		UserID:    userID,
		Scopes:    scopes,
		Audiences: audiences,
	})
}
<commit_msg>Makes router paths a little shorter<commit_after>package server

import (
	"net/http/httptest"

	"github.com/gorilla/mux"
	"github.com/pivotal-cf-experimental/warrant/internal/server/clients"
	"github.com/pivotal-cf-experimental/warrant/internal/server/domain"
	"github.com/pivotal-cf-experimental/warrant/internal/server/groups"
	"github.com/pivotal-cf-experimental/warrant/internal/server/tokens"
	"github.com/pivotal-cf-experimental/warrant/internal/server/users"
)

// Config is the set of configuration values to provide
// to the fake server.
type Config struct {
	PublicKey string
}

// UAA is a fake implementation of the UAA HTTP service.
type UAA struct {
	server  *httptest.Server
	users   *domain.Users
	clients *domain.Clients
	groups  *domain.Groups
	tokens  *domain.Tokens

	publicKey string
}

// NewUAA returns a new UAA initialized with the given Config.
func NewUAA(config Config) *UAA {
	tokensCollection := domain.NewTokens(config.PublicKey, []string{
		"scim.read",
		"cloudcontroller.admin",
		"password.write",
		"scim.write",
		"openid",
		"cloud_controller.write",
		"cloud_controller.read",
		"doppler.firehose",
	}) // TODO: use a real RSA key
	usersCollection := domain.NewUsers()
	clientsCollection := domain.NewClients()
	groupsCollection := domain.NewGroups()

	router := mux.NewRouter()
	router.Handle("/Users{a:.*}", users.NewRouter(usersCollection, tokensCollection))
	router.Handle("/Groups{a:.*}", groups.NewRouter(groupsCollection, tokensCollection))
	router.Handle("/oauth/clients{a:.*}", clients.NewRouter(clientsCollection, tokensCollection))
	router.Handle("/oauth{a:.*}", tokens.NewRouter(tokensCollection, usersCollection))
	router.Handle("/token_key", tokens.NewRouter(tokensCollection, usersCollection))

	return &UAA{
		server:    httptest.NewUnstartedServer(router),
		tokens:    tokensCollection,
		users:     usersCollection,
		clients:   clientsCollection,
		groups:    groupsCollection,
		publicKey: config.PublicKey,
	}

}

// Start will cause the HTTP server to bind to a port
// and start serving requests.
func (s *UAA) Start() {
	s.server.Start()
}

// Close will cause the HTTP server to stop serving
// requests and close its connection.
func (s *UAA) Close() {
	s.server.Close()
}

// Reset will clear all internal resource state within
// the server. This means that all users, clients, and
// groups will be deleted.
func (s *UAA) Reset() {
	s.users.Clear()
	s.clients.Clear()
	s.groups.Clear()
}

// URL returns the url that the server is hosted on.
func (s *UAA) URL() string {
	return s.server.URL
}

// SetDefaultScopes allows the default scopes applied to a
// user to be configured.
func (s *UAA) SetDefaultScopes(scopes []string) {
	s.tokens.DefaultScopes = scopes
} // TODO: move this configuration onto the Config

// ClientTokenFor returns a client token with the given id,
// scopes, and audiences.
func (s *UAA) ClientTokenFor(clientID string, scopes, audiences []string) string {
	// TODO: remove from API so that tokens are fetched like
	// they would be with a real UAA server.

	return s.tokens.Encrypt(domain.Token{
		ClientID:  clientID,
		Scopes:    scopes,
		Audiences: audiences,
	})
}

// UserTokenFor returns a user token with the given id,
// scopes, and audiences.
func (s *UAA) UserTokenFor(userID string, scopes, audiences []string) string {
	// TODO: remove from API so that tokens are fetched like
	// they would be with a real UAA server.

	return s.tokens.Encrypt(domain.Token{
		UserID:    userID,
		Scopes:    scopes,
		Audiences: audiences,
	})
}
<|endoftext|>