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

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"os"
	"reflect"
	"strings"
	"unicode"
	"utf8"
)

func initRewrite() {
	if *rewriteRule == "" {
		return
	}
	f := strings.Split(*rewriteRule, "->", -1)
	if len(f) != 2 {
		fmt.Fprintf(os.Stderr, "rewrite rule must be of the form 'pattern -> replacement'\n")
		os.Exit(2)
	}
	pattern := parseExpr(f[0], "pattern")
	replace := parseExpr(f[1], "replacement")
	rewrite = func(p *ast.File) *ast.File { return rewriteFile(pattern, replace, p) }
}

// parseExpr parses s as an expression.
// It might make sense to expand this to allow statement patterns,
// but there are problems with preserving formatting and also
// with what a wildcard for a statement looks like.
func parseExpr(s string, what string) ast.Expr {
	x, err := parser.ParseExpr(fset, "input", s)
	if err != nil {
		fmt.Fprintf(os.Stderr, "parsing %s %s: %s\n", what, s, err)
		os.Exit(2)
	}
	return x
}

// rewriteFile applies the rewrite rule 'pattern -> replace' to an entire file.
func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
	m := make(map[string]reflect.Value)
	pat := reflect.NewValue(pattern)
	repl := reflect.NewValue(replace)
	var f func(val reflect.Value) reflect.Value // f is recursive
	f = func(val reflect.Value) reflect.Value {
		for k := range m {
			m[k] = nil, false
		}
		val = apply(f, val)
		if match(m, pat, val) {
			val = subst(m, repl, reflect.NewValue(val.Interface().(ast.Node).Pos()))
		}
		return val
	}
	return apply(f, reflect.NewValue(p)).Interface().(*ast.File)
}

var positionType = reflect.Typeof(token.NoPos)
var identType = reflect.Typeof((*ast.Ident)(nil))

func isWildcard(s string) bool {
	rune, size := utf8.DecodeRuneInString(s)
	return size == len(s) && unicode.IsLower(rune)
}

// apply replaces each AST field x in val with f(x), returning val.
// To avoid extra conversions, f operates on the reflect.Value form.
func apply(f func(reflect.Value) reflect.Value, val reflect.Value) reflect.Value {
	if val == nil {
		return nil
	}
	switch v := reflect.Indirect(val).(type) {
	case *reflect.SliceValue:
		for i := 0; i < v.Len(); i++ {
			e := v.Elem(i)
			e.SetValue(f(e))
		}
	case *reflect.StructValue:
		for i := 0; i < v.NumField(); i++ {
			e := v.Field(i)
			e.SetValue(f(e))
		}
	case *reflect.InterfaceValue:
		e := v.Elem()
		v.SetValue(f(e))
	}
	return val
}

// match returns true if pattern matches val,
// recording wildcard submatches in m.
// If m == nil, match checks whether pattern == val.
func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
	// Wildcard matches any expression.  If it appears multiple
	// times in the pattern, it must match the same expression
	// each time.
	if m != nil && pattern.Type() == identType {
		name := pattern.Interface().(*ast.Ident).Name
		if isWildcard(name) {
			if old, ok := m[name]; ok {
				return match(nil, old, val)
			}
			m[name] = val
			return true
		}
	}

	// Otherwise, the expressions must match recursively.
	if pattern == nil || val == nil {
		return pattern == nil && val == nil
	}
	if pattern.Type() != val.Type() {
		return false
	}

	// Special cases.
	switch pattern.Type() {
	case positionType:
		// token positions don't need to match
		return true
	case identType:
		// For identifiers, only the names need to match
		// (and none of the other *ast.Object information).
		// This is a common case, handle it all here instead
		// of recursing down any further via reflection.
		p := pattern.Interface().(*ast.Ident)
		v := val.Interface().(*ast.Ident)
		return p == nil && v == nil || p != nil && v != nil && p.Name == v.Name
	}

	p := reflect.Indirect(pattern)
	v := reflect.Indirect(val)
	if p == nil || v == nil {
		return p == nil && v == nil
	}

	switch p := p.(type) {
	case *reflect.SliceValue:
		v := v.(*reflect.SliceValue)
		if p.Len() != v.Len() {
			return false
		}
		for i := 0; i < p.Len(); i++ {
			if !match(m, p.Elem(i), v.Elem(i)) {
				return false
			}
		}
		return true

	case *reflect.StructValue:
		v := v.(*reflect.StructValue)
		if p.NumField() != v.NumField() {
			return false
		}
		for i := 0; i < p.NumField(); i++ {
			if !match(m, p.Field(i), v.Field(i)) {
				return false
			}
		}
		return true

	case *reflect.InterfaceValue:
		v := v.(*reflect.InterfaceValue)
		return match(m, p.Elem(), v.Elem())
	}

	// Handle token integers, etc.
	return p.Interface() == v.Interface()
}

// subst returns a copy of pattern with values from m substituted in place
// of wildcards and pos used as the position of tokens from the pattern.
// if m == nil, subst returns a copy of pattern and doesn't change the line
// number information.
func subst(m map[string]reflect.Value, pattern reflect.Value, pos reflect.Value) reflect.Value {
	if pattern == nil {
		return nil
	}

	// Wildcard gets replaced with map value.
	if m != nil && pattern.Type() == identType {
		name := pattern.Interface().(*ast.Ident).Name
		if isWildcard(name) {
			if old, ok := m[name]; ok {
				return subst(nil, old, nil)
			}
		}
	}

	if pos != nil && pattern.Type() == positionType {
		// use new position only if old position was valid in the first place
		if old := pattern.Interface().(token.Position); !old.IsValid() {
			return pattern
		}
		return pos
	}

	// Otherwise copy.
	switch p := pattern.(type) {
	case *reflect.SliceValue:
		v := reflect.MakeSlice(p.Type().(*reflect.SliceType), p.Len(), p.Len())
		for i := 0; i < p.Len(); i++ {
			v.Elem(i).SetValue(subst(m, p.Elem(i), pos))
		}
		return v

	case *reflect.StructValue:
		v := reflect.MakeZero(p.Type()).(*reflect.StructValue)
		for i := 0; i < p.NumField(); i++ {
			v.Field(i).SetValue(subst(m, p.Field(i), pos))
		}
		return v

	case *reflect.PtrValue:
		v := reflect.MakeZero(p.Type()).(*reflect.PtrValue)
		v.PointTo(subst(m, p.Elem(), pos))
		return v

	case *reflect.InterfaceValue:
		v := reflect.MakeZero(p.Type()).(*reflect.InterfaceValue)
		v.SetValue(subst(m, p.Elem(), pos))
		return v
	}

	return pattern
}
<commit_msg>gofmt: rewriter matches apply to expressions only<commit_after>// Copyright 2009 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 main

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"os"
	"reflect"
	"strings"
	"unicode"
	"utf8"
)

func initRewrite() {
	if *rewriteRule == "" {
		return
	}
	f := strings.Split(*rewriteRule, "->", -1)
	if len(f) != 2 {
		fmt.Fprintf(os.Stderr, "rewrite rule must be of the form 'pattern -> replacement'\n")
		os.Exit(2)
	}
	pattern := parseExpr(f[0], "pattern")
	replace := parseExpr(f[1], "replacement")
	rewrite = func(p *ast.File) *ast.File { return rewriteFile(pattern, replace, p) }
}

// parseExpr parses s as an expression.
// It might make sense to expand this to allow statement patterns,
// but there are problems with preserving formatting and also
// with what a wildcard for a statement looks like.
func parseExpr(s string, what string) ast.Expr {
	x, err := parser.ParseExpr(fset, "input", s)
	if err != nil {
		fmt.Fprintf(os.Stderr, "parsing %s %s: %s\n", what, s, err)
		os.Exit(2)
	}
	return x
}

// rewriteFile applies the rewrite rule 'pattern -> replace' to an entire file.
func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
	m := make(map[string]reflect.Value)
	pat := reflect.NewValue(pattern)
	repl := reflect.NewValue(replace)
	var f func(val reflect.Value) reflect.Value // f is recursive
	f = func(val reflect.Value) reflect.Value {
		for k := range m {
			m[k] = nil, false
		}
		val = apply(f, val)
		if match(m, pat, val) {
			val = subst(m, repl, reflect.NewValue(val.Interface().(ast.Node).Pos()))
		}
		return val
	}
	return apply(f, reflect.NewValue(p)).Interface().(*ast.File)
}

var positionType = reflect.Typeof(token.NoPos)
var identType = reflect.Typeof((*ast.Ident)(nil))

func isWildcard(s string) bool {
	rune, size := utf8.DecodeRuneInString(s)
	return size == len(s) && unicode.IsLower(rune)
}

// apply replaces each AST field x in val with f(x), returning val.
// To avoid extra conversions, f operates on the reflect.Value form.
func apply(f func(reflect.Value) reflect.Value, val reflect.Value) reflect.Value {
	if val == nil {
		return nil
	}
	switch v := reflect.Indirect(val).(type) {
	case *reflect.SliceValue:
		for i := 0; i < v.Len(); i++ {
			e := v.Elem(i)
			e.SetValue(f(e))
		}
	case *reflect.StructValue:
		for i := 0; i < v.NumField(); i++ {
			e := v.Field(i)
			e.SetValue(f(e))
		}
	case *reflect.InterfaceValue:
		e := v.Elem()
		v.SetValue(f(e))
	}
	return val
}

// match returns true if pattern matches val,
// recording wildcard submatches in m.
// If m == nil, match checks whether pattern == val.
func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
	// Wildcard matches any expression.  If it appears multiple
	// times in the pattern, it must match the same expression
	// each time.
	if m != nil && pattern.Type() == identType {
		name := pattern.Interface().(*ast.Ident).Name
		if isWildcard(name) {
			// wildcards only match expressions
			if _, ok := val.Interface().(ast.Expr); ok {
				if old, ok := m[name]; ok {
					return match(nil, old, val)
				}
				m[name] = val
				return true
			}
		}
	}

	// Otherwise, pattern and val must match recursively.
	if pattern == nil || val == nil {
		return pattern == nil && val == nil
	}
	if pattern.Type() != val.Type() {
		return false
	}

	// Special cases.
	switch pattern.Type() {
	case positionType:
		// token positions don't need to match
		return true
	case identType:
		// For identifiers, only the names need to match
		// (and none of the other *ast.Object information).
		// This is a common case, handle it all here instead
		// of recursing down any further via reflection.
		p := pattern.Interface().(*ast.Ident)
		v := val.Interface().(*ast.Ident)
		return p == nil && v == nil || p != nil && v != nil && p.Name == v.Name
	}

	p := reflect.Indirect(pattern)
	v := reflect.Indirect(val)
	if p == nil || v == nil {
		return p == nil && v == nil
	}

	switch p := p.(type) {
	case *reflect.SliceValue:
		v := v.(*reflect.SliceValue)
		if p.Len() != v.Len() {
			return false
		}
		for i := 0; i < p.Len(); i++ {
			if !match(m, p.Elem(i), v.Elem(i)) {
				return false
			}
		}
		return true

	case *reflect.StructValue:
		v := v.(*reflect.StructValue)
		if p.NumField() != v.NumField() {
			return false
		}
		for i := 0; i < p.NumField(); i++ {
			if !match(m, p.Field(i), v.Field(i)) {
				return false
			}
		}
		return true

	case *reflect.InterfaceValue:
		v := v.(*reflect.InterfaceValue)
		return match(m, p.Elem(), v.Elem())
	}

	// Handle token integers, etc.
	return p.Interface() == v.Interface()
}

// subst returns a copy of pattern with values from m substituted in place
// of wildcards and pos used as the position of tokens from the pattern.
// if m == nil, subst returns a copy of pattern and doesn't change the line
// number information.
func subst(m map[string]reflect.Value, pattern reflect.Value, pos reflect.Value) reflect.Value {
	if pattern == nil {
		return nil
	}

	// Wildcard gets replaced with map value.
	if m != nil && pattern.Type() == identType {
		name := pattern.Interface().(*ast.Ident).Name
		if isWildcard(name) {
			if old, ok := m[name]; ok {
				return subst(nil, old, nil)
			}
		}
	}

	if pos != nil && pattern.Type() == positionType {
		// use new position only if old position was valid in the first place
		if old := pattern.Interface().(token.Pos); !old.IsValid() {
			return pattern
		}
		return pos
	}

	// Otherwise copy.
	switch p := pattern.(type) {
	case *reflect.SliceValue:
		v := reflect.MakeSlice(p.Type().(*reflect.SliceType), p.Len(), p.Len())
		for i := 0; i < p.Len(); i++ {
			v.Elem(i).SetValue(subst(m, p.Elem(i), pos))
		}
		return v

	case *reflect.StructValue:
		v := reflect.MakeZero(p.Type()).(*reflect.StructValue)
		for i := 0; i < p.NumField(); i++ {
			v.Field(i).SetValue(subst(m, p.Field(i), pos))
		}
		return v

	case *reflect.PtrValue:
		v := reflect.MakeZero(p.Type()).(*reflect.PtrValue)
		v.PointTo(subst(m, p.Elem(), pos))
		return v

	case *reflect.InterfaceValue:
		v := reflect.MakeZero(p.Type()).(*reflect.InterfaceValue)
		v.SetValue(subst(m, p.Elem(), pos))
		return v
	}

	return pattern
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"							//used for unifrom database access
	"fmt"									//print statements
	"github.com/go-martini/martini"			//extra frame work build on net/http
	_ "github.com/lib/pq"					//go sql driver
	"net/http"								//framework
	"strings"
	"os"
)

func SetupDB() *sql.DB {
	//  10.254.76.103
	db, err := sql.Open("postgres", "host=os.Getenv(KUBERNETES_SERVICE_HOST) user=postgres dbname=postgres sslmode=disable") 		//my only lib/pq usage? login into postgres database
	PanicIf(err)

	return db
}

func PanicIf(err error) {
	if err != nil {
		panic(err)
	}
}

func ShowDB(db *sql.DB, r *http.Request, rw http.ResponseWriter) { //localhost:3000/?search=name
		search := "%" + r.URL.Query().Get("search") + "%"
		rows, err := db.Query(`SELECT fname, LName, cost, city
                           FROM custauth
                           WHERE FName ILIKE $1
                           OR LName ILIKE $1
                           OR city ILIKE $1`, search)
		PanicIf(err)
		defer rows.Close()

		var FirstName, LastName, cost, city string
		for rows.Next() {
			err := rows.Scan(&FirstName, &LastName, &cost, &city)
			PanicIf(err)
			fmt.Fprintf(rw, "First Name: %s\nLast Name: %s\nCost: %s\nCity: %s\n\n", FirstName, LastName, cost, city)
		}
	}

func InsertPur(r *http.Request, db *sql.DB){
//	_, err := db.Query("INSERT INTO custauth (custid, fname, lname, city,state, country,email,cost,errorflag) VALUES ($1, $2, $3, $4, $5, $6, $7, $8,$9)",
	_, err := db.Exec("INSERT INTO custauth (custid, fname, lname, city,state, country,email,cost,errorflag) VALUES ($1, $2, $3, $4, $5, $6, $7, $8,$9)",
	r.FormValue("custid"),
		r.FormValue("fname"),
		r.FormValue("lname"),
		r.FormValue("city"),
		r.FormValue("state"),
		r.FormValue("country"),
		r.FormValue("email"),
		r.FormValue("cost"),
		r.FormValue("errorflag"))

	PanicIf(err)
}

func main() {
	m := martini.Classic()
	m.Map(SetupDB())
	m.Get("/", func() string {return  "Hello to GoSQL database v1.4"})
  	m.Get("/var", func() string {
	for _, e := range os.Environ() {
        pair := strings.Split(e, "=")
		 fmt.Println(pair[0])}
		 return "yo"
	})
	m.Get("/show", ShowDB)
	m.Post("/add", InsertPur)
	m.Run()
}
<commit_msg>finding env<commit_after>package main

import (
	"database/sql"							//used for unifrom database access
	"fmt"									//print statements
	"github.com/go-martini/martini"			//extra frame work build on net/http
	_ "github.com/lib/pq"					//go sql driver
	"net/http"								//framework
	"strings"
	"os"
)

func SetupDB() *sql.DB {
	//  10.254.76.103
	db, err := sql.Open("postgres", "host=os.Getenv(POSTGRESDB_PORT_5432_TCP_ADDR) user=postgres dbname=postgres sslmode=disable") 		//my only lib/pq usage? login into postgres database
	PanicIf(err)

	return db
}

func PanicIf(err error) {
	if err != nil {
		panic(err)
	}
}

func ShowDB(db *sql.DB, r *http.Request, rw http.ResponseWriter) { //localhost:3000/?search=name
		search := "%" + r.URL.Query().Get("search") + "%"
		rows, err := db.Query(`SELECT fname, LName, cost, city
                           FROM custauth
                           WHERE FName ILIKE $1
                           OR LName ILIKE $1
                           OR city ILIKE $1`, search)
		PanicIf(err)
		defer rows.Close()

		var FirstName, LastName, cost, city string
		for rows.Next() {
			err := rows.Scan(&FirstName, &LastName, &cost, &city)
			PanicIf(err)
			fmt.Fprintf(rw, "First Name: %s\nLast Name: %s\nCost: %s\nCity: %s\n\n", FirstName, LastName, cost, city)
		}
	}

func InsertPur(r *http.Request, db *sql.DB){
//	_, err := db.Query("INSERT INTO custauth (custid, fname, lname, city,state, country,email,cost,errorflag) VALUES ($1, $2, $3, $4, $5, $6, $7, $8,$9)",
	_, err := db.Exec("INSERT INTO custauth (custid, fname, lname, city,state, country,email,cost,errorflag) VALUES ($1, $2, $3, $4, $5, $6, $7, $8,$9)",
	r.FormValue("custid"),
		r.FormValue("fname"),
		r.FormValue("lname"),
		r.FormValue("city"),
		r.FormValue("state"),
		r.FormValue("country"),
		r.FormValue("email"),
		r.FormValue("cost"),
		r.FormValue("errorflag"))

	PanicIf(err)
}

func main() {
	m := martini.Classic()
	m.Map(SetupDB())
	m.Get("/", func() string {return  "Hello to GoSQL database v1.5"})
	m.Get("/Host", func() string {return  os.Getenv(HOSTNAME)})
	m.Get("/post5432tcp", func() string {return  os.Getenv(POSTGRESDB_PORT_5432_TCP)})
	m.Get("/postservhost", func() string {return  os.Getenv(POSTGRESDB_SERVICE_HOST)})
	m.Get("/postservport", func() string {return  os.Getenv(POSTGRESDB_SERVICE_HOST)})
	m.Get("/postport", func() string {return  os.Getenv(POSTGRESDB_SERVICE_HOST)})

  	m.Get("/var", func() string {
	for _, e := range os.Environ() {
        pair := strings.Split(e, "=")
		 fmt.Println(pair[0])}
		 return "yo"
	})
	m.Get("/show", ShowDB)
	m.Post("/add", InsertPur)
	m.Run()
}
<|endoftext|>


<commit_before>// This file is part of Daycount.
//
// Daycount is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// Daycount is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with Daycount.  If not, see
// <http://www.gnu.org/licenses/>.

package views

import (
	"bitbucket.org/zombiezen/gopdf/pdf"
	"bytes"
	"github.com/jtacoma/daycount/days"
	"os"
	"text/template"
)

type PdfView struct {
	options  PdfViewOptions
	template *template.Template
}

type PdfViewOptions struct {
	FontName   string
	FontSize   pdf.Unit
	Margin     pdf.Unit
	Padding    pdf.Unit
	PageWidth  pdf.Unit
	PageHeight pdf.Unit
}

var (
	pdfsimple = template.Must(template.New("simple").Parse(
		"{{.Gregorian}}"))
)

func (v *PdfView) Set(options *PdfViewOptions) {
	if options != nil {
		v.options = *options
	}
	if len(v.options.FontName) == 0 {
		v.options.FontName = pdf.Helvetica
	}
	if v.options.FontSize == 0 {
		v.options.FontSize = 14
	}
	if v.options.Margin == 0 {
		v.options.Margin = 72
	}
	if v.options.Padding == 0 {
		v.options.Padding = 6
	}
	if v.options.PageWidth == 0 {
		v.options.PageWidth = pdf.USLetterWidth
	}
	if v.options.PageHeight == 0 {
		v.options.PageHeight = pdf.USLetterHeight
	}
}

func (v *PdfView) Run(q Query) (err error) {
	v.Set(nil)
	if v.template, err = q.LoadTemplate(pdfsimple); err != nil {
		return err
	}
	doc := pdf.New()
	for _, day := range q.Range() {
		canvas := doc.NewPage(v.options.PageWidth, v.options.PageHeight)
		v.renderPage(canvas, day)
		canvas.Close()
	}
	return doc.Encode(os.Stdout)
}

func (v *PdfView) renderPage(canvas *pdf.Canvas, d days.Day) {
	margin := v.options.Margin
	padding := v.options.Padding
	width := v.options.PageWidth
	height := v.options.PageHeight
	// page border:
	canvas.Translate(0, 0)
	path := new(pdf.Path)
	path.Move(pdf.Point{margin, margin})
	path.Line(pdf.Point{width - margin, margin})
	path.Line(pdf.Point{width - margin, height - margin})
	path.Line(pdf.Point{margin, height - margin})
	path.Line(pdf.Point{margin, margin})
	canvas.Stroke(path)
	// text
	canvas.Translate(margin+padding,
		height-margin-padding-v.options.FontSize/1.2)
	var buf bytes.Buffer
	v.template.Execute(&buf, d)
	text := new(pdf.Text)
	text.SetFont(v.options.FontName, v.options.FontSize)
	text.Text(buf.String())
	canvas.DrawText(text)
}
<commit_msg>Handle mutiline text in PDF view.<commit_after>// This file is part of Daycount.
//
// Daycount is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// Daycount is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with Daycount.  If not, see
// <http://www.gnu.org/licenses/>.

package views

import (
	"bitbucket.org/zombiezen/gopdf/pdf"
	"bytes"
	"github.com/jtacoma/daycount/days"
	"os"
	"strings"
	"text/template"
)

type PdfView struct {
	options  PdfViewOptions
	template *template.Template
}

type PdfViewOptions struct {
	FontName   string
	FontSize   pdf.Unit
	Margin     pdf.Unit
	Padding    pdf.Unit
	PageWidth  pdf.Unit
	PageHeight pdf.Unit
}

var (
	pdfsimple = template.Must(template.New("simple").Parse(
		"{{.Gregorian}}"))
)

func (v *PdfView) Set(options *PdfViewOptions) {
	if options != nil {
		v.options = *options
	}
	if len(v.options.FontName) == 0 {
		v.options.FontName = pdf.Helvetica
	}
	if v.options.FontSize == 0 {
		v.options.FontSize = 14
	}
	if v.options.Margin == 0 {
		v.options.Margin = 72
	}
	if v.options.Padding == 0 {
		v.options.Padding = 6
	}
	if v.options.PageWidth == 0 {
		v.options.PageWidth = pdf.USLetterWidth
	}
	if v.options.PageHeight == 0 {
		v.options.PageHeight = pdf.USLetterHeight
	}
}

func (v *PdfView) Run(q Query) (err error) {
	v.Set(nil)
	if v.template, err = q.LoadTemplate(pdfsimple); err != nil {
		return err
	}
	doc := pdf.New()
	for _, day := range q.Range() {
		canvas := doc.NewPage(v.options.PageWidth, v.options.PageHeight)
		v.renderPage(canvas, day)
		canvas.Close()
	}
	return doc.Encode(os.Stdout)
}

func (v *PdfView) renderPage(canvas *pdf.Canvas, d days.Day) {
	margin := v.options.Margin
	padding := v.options.Padding
	width := v.options.PageWidth
	height := v.options.PageHeight
	// page border:
	canvas.Translate(0, 0)
	path := new(pdf.Path)
	path.Move(pdf.Point{margin, margin})
	path.Line(pdf.Point{width - margin, margin})
	path.Line(pdf.Point{width - margin, height - margin})
	path.Line(pdf.Point{margin, height - margin})
	path.Line(pdf.Point{margin, margin})
	canvas.Stroke(path)
	// text
	canvas.Translate(margin+padding,
		height-margin-padding-v.options.FontSize/1.2)
	var buf bytes.Buffer
	v.template.Execute(&buf, d)
	text := new(pdf.Text)
	text.SetFont(v.options.FontName, v.options.FontSize)
	for i, line := range strings.Split(buf.String(), "\n") {
		if i > 0 {
			text.NextLine()
		}
		text.Text(line)
	}
	canvas.DrawText(text)
}
<|endoftext|>


<commit_before>// © 2016 Steve McCoy under the MIT license. See LICENSE for details.

package ogg

import (
	"bytes"
	"io"
	"math/rand"
	"strings"
	"testing"
)

func TestBasicDecode(t *testing.T) {
	var b bytes.Buffer
	e := NewEncoder(1, &b)

	err := e.EncodeBOS(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected EncodeBOS error:", err)
	}

	d := NewDecoder(&b)

	p, err := d.Decode()
	if err != nil {
		t.Fatal("unexpected Decode error:", err)
	}

	if p.Type != BOS {
		t.Fatal("expected BOS, got", p.Type)
	}

	if p.Serial != 1 {
		t.Fatal("expected serial 1, got", p.Serial)
	}

	if p.Granule != 2 {
		t.Fatal("expected granule 2, got", p.Granule)
	}

	expect := []byte{
		'h', 'e', 'l', 'l', 'o',
	}

	if !bytes.Equal(p.Packet, expect) {
		t.Fatalf("bytes != expected:\n%x\n%x", p.Packet, expect)
	}
}

func TestBadCrc(t *testing.T) {
	var b bytes.Buffer
	e := NewEncoder(1, &b)

	err := e.EncodeBOS(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected EncodeBOS error:", err)
	}

	b.Bytes()[22] = 0

	d := NewDecoder(&b)

	_, err = d.Decode()
	if err == nil {
		t.Fatal("unexpected lack of Decode error")
	}
	if bs, ok := err.(ErrBadCrc); !ok {
		t.Fatal("exected ErrBadCrc, got:", err)
	} else if !strings.HasPrefix(bs.Error(), "invalid crc in packet") {
		t.Fatalf("the error message looks wrong: %q", err.Error())
	}
}

func TestShortDecode(t *testing.T) {
	var b bytes.Buffer
	d := NewDecoder(&b)
	_, err := d.Decode()
	if err != io.EOF {
		t.Fatal("expected EOF, got:", err)
	}

	e := NewEncoder(1, &b)
	err = e.Encode(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected Encode error:", err)
	}
	d = NewDecoder(&io.LimitedReader{R: &b, N: headsz})
	_, err = d.Decode()
	if err != io.EOF {
		t.Fatal("expected EOF, got:", err)
	}

	b.Reset()
	e = NewEncoder(1, &b)
	err = e.Encode(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected Encode error:", err)
	}
	d = NewDecoder(&io.LimitedReader{R: &b, N: int64(b.Len()) - 1})
	_, err = d.Decode()
	if err != io.ErrUnexpectedEOF {
		t.Fatal("expected ErrUnexpectedEOF, got:", err)
	}
}

func TestBadSegs(t *testing.T) {
	var b bytes.Buffer
	e := NewEncoder(1, &b)

	err := e.EncodeBOS(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected EncodeBOS error:", err)
	}

	b.Bytes()[26] = 0

	d := NewDecoder(&b)
	_, err = d.Decode()
	if err != ErrBadSegs {
		t.Fatal("expected ErrBadSegs, got:", err)
	}
}

func TestSyncDecode(t *testing.T) {
	var b bytes.Buffer
	for i := 0; i < headsz-1; i++ {
		b.Write([]byte("x"))
	}
	b.Write([]byte("O"))

	for i := 0; i < headsz-3; i++ {
		b.Write([]byte("x"))
	}
	b.Write([]byte("Og"))

	for i := 0; i < headsz-5; i++ {
		b.Write([]byte("x"))
	}
	b.Write([]byte("Ogg"))

	e := NewEncoder(1, &b)

	err := e.EncodeBOS(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected EncodeBOS error:", err)
	}

	d := NewDecoder(&b)

	p, err := d.Decode()
	if err != nil {
		t.Fatal("unexpected Decode error:", err)
	}

	if p.Type != BOS {
		t.Fatal("expected BOS, got", p.Type)
	}

	if p.Serial != 1 {
		t.Fatal("expected serial 1, got", p.Serial)
	}

	if p.Granule != 2 {
		t.Fatal("expected granule 2, got", p.Granule)
	}

	expect := []byte{
		'h', 'e', 'l', 'l', 'o',
	}

	if !bytes.Equal(p.Packet, expect) {
		t.Fatalf("bytes != expected:\n%x\n%x", p.Packet, expect)
	}
}

func TestLongDecode(t *testing.T) {
	var b bytes.Buffer
	e := NewEncoder(1, &b)

	var junk bytes.Buffer
	for i := 0; i < maxPageSize*2; i++ {
		c := byte(rand.Intn(26)) + 'a'
		junk.WriteByte(c)
	}

	err := e.Encode(2, junk.Bytes())
	if err != nil {
		t.Fatal("unexpected Encode error:", err)
	}

	d := NewDecoder(&b)
	p1, err := d.Decode()
	if err != nil {
		t.Fatal("unexpected Decode error:", err)
	}
	if p1.Type != 0 {
		t.Fatal("unexpected page type:", p1.Type)
	}
	if !bytes.Equal(p1.Packet, junk.Bytes()[:mps]) {
		t.Fatal("packet is wrong:\n\t%x\nvs\n\t%x\n", p1.Packet,  junk.Bytes()[:mps])
	}

	p2, err := d.Decode()
	if err != nil {
		t.Fatal("unexpected Decode error:", err)
	}
	if p2.Type != COP {
		t.Fatal("unexpected page type:", p1.Type)
	}
	if !bytes.Equal(p2.Packet,  junk.Bytes()[mps:mps+mps]) {
		t.Fatal("packet is wrong:\n\t%x\nvs\n\t%x\n", p2.Packet,  junk.Bytes()[mps:mps+mps])
	}

	p3, err := d.Decode()
	if err != nil {
		t.Fatal("unexpected Decode error:", err)
	}
	if p3.Type != COP {
		t.Fatal("unexpected page type:", p1.Type)
	}
	rem := (maxPageSize*2) - mps*2
	if !bytes.Equal(p3.Packet, junk.Bytes()[mps*2:mps*2+rem]) {
		t.Fatal("packet is wrong:\n\t%x\nvs\n\t%x\n", p3.Packet,  junk.Bytes()[mps*2:mps*2+rem])
	}
}
<commit_msg>Formatting<commit_after>// © 2016 Steve McCoy under the MIT license. See LICENSE for details.

package ogg

import (
	"bytes"
	"io"
	"math/rand"
	"strings"
	"testing"
)

func TestBasicDecode(t *testing.T) {
	var b bytes.Buffer
	e := NewEncoder(1, &b)

	err := e.EncodeBOS(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected EncodeBOS error:", err)
	}

	d := NewDecoder(&b)

	p, err := d.Decode()
	if err != nil {
		t.Fatal("unexpected Decode error:", err)
	}

	if p.Type != BOS {
		t.Fatal("expected BOS, got", p.Type)
	}

	if p.Serial != 1 {
		t.Fatal("expected serial 1, got", p.Serial)
	}

	if p.Granule != 2 {
		t.Fatal("expected granule 2, got", p.Granule)
	}

	expect := []byte{
		'h', 'e', 'l', 'l', 'o',
	}

	if !bytes.Equal(p.Packet, expect) {
		t.Fatalf("bytes != expected:\n%x\n%x", p.Packet, expect)
	}
}

func TestBadCrc(t *testing.T) {
	var b bytes.Buffer
	e := NewEncoder(1, &b)

	err := e.EncodeBOS(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected EncodeBOS error:", err)
	}

	b.Bytes()[22] = 0

	d := NewDecoder(&b)

	_, err = d.Decode()
	if err == nil {
		t.Fatal("unexpected lack of Decode error")
	}
	if bs, ok := err.(ErrBadCrc); !ok {
		t.Fatal("exected ErrBadCrc, got:", err)
	} else if !strings.HasPrefix(bs.Error(), "invalid crc in packet") {
		t.Fatalf("the error message looks wrong: %q", err.Error())
	}
}

func TestShortDecode(t *testing.T) {
	var b bytes.Buffer
	d := NewDecoder(&b)
	_, err := d.Decode()
	if err != io.EOF {
		t.Fatal("expected EOF, got:", err)
	}

	e := NewEncoder(1, &b)
	err = e.Encode(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected Encode error:", err)
	}
	d = NewDecoder(&io.LimitedReader{R: &b, N: headsz})
	_, err = d.Decode()
	if err != io.EOF {
		t.Fatal("expected EOF, got:", err)
	}

	b.Reset()
	e = NewEncoder(1, &b)
	err = e.Encode(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected Encode error:", err)
	}
	d = NewDecoder(&io.LimitedReader{R: &b, N: int64(b.Len()) - 1})
	_, err = d.Decode()
	if err != io.ErrUnexpectedEOF {
		t.Fatal("expected ErrUnexpectedEOF, got:", err)
	}
}

func TestBadSegs(t *testing.T) {
	var b bytes.Buffer
	e := NewEncoder(1, &b)

	err := e.EncodeBOS(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected EncodeBOS error:", err)
	}

	b.Bytes()[26] = 0

	d := NewDecoder(&b)
	_, err = d.Decode()
	if err != ErrBadSegs {
		t.Fatal("expected ErrBadSegs, got:", err)
	}
}

func TestSyncDecode(t *testing.T) {
	var b bytes.Buffer
	for i := 0; i < headsz-1; i++ {
		b.Write([]byte("x"))
	}
	b.Write([]byte("O"))

	for i := 0; i < headsz-3; i++ {
		b.Write([]byte("x"))
	}
	b.Write([]byte("Og"))

	for i := 0; i < headsz-5; i++ {
		b.Write([]byte("x"))
	}
	b.Write([]byte("Ogg"))

	e := NewEncoder(1, &b)

	err := e.EncodeBOS(2, []byte("hello"))
	if err != nil {
		t.Fatal("unexpected EncodeBOS error:", err)
	}

	d := NewDecoder(&b)

	p, err := d.Decode()
	if err != nil {
		t.Fatal("unexpected Decode error:", err)
	}

	if p.Type != BOS {
		t.Fatal("expected BOS, got", p.Type)
	}

	if p.Serial != 1 {
		t.Fatal("expected serial 1, got", p.Serial)
	}

	if p.Granule != 2 {
		t.Fatal("expected granule 2, got", p.Granule)
	}

	expect := []byte{
		'h', 'e', 'l', 'l', 'o',
	}

	if !bytes.Equal(p.Packet, expect) {
		t.Fatalf("bytes != expected:\n%x\n%x", p.Packet, expect)
	}
}

func TestLongDecode(t *testing.T) {
	var b bytes.Buffer
	e := NewEncoder(1, &b)

	var junk bytes.Buffer
	for i := 0; i < maxPageSize*2; i++ {
		c := byte(rand.Intn(26)) + 'a'
		junk.WriteByte(c)
	}

	err := e.Encode(2, junk.Bytes())
	if err != nil {
		t.Fatal("unexpected Encode error:", err)
	}

	d := NewDecoder(&b)
	p1, err := d.Decode()
	if err != nil {
		t.Fatal("unexpected Decode error:", err)
	}
	if p1.Type != 0 {
		t.Fatal("unexpected page type:", p1.Type)
	}
	if !bytes.Equal(p1.Packet, junk.Bytes()[:mps]) {
		t.Fatal("packet is wrong:\n\t%x\nvs\n\t%x\n", p1.Packet, junk.Bytes()[:mps])
	}

	p2, err := d.Decode()
	if err != nil {
		t.Fatal("unexpected Decode error:", err)
	}
	if p2.Type != COP {
		t.Fatal("unexpected page type:", p1.Type)
	}
	if !bytes.Equal(p2.Packet, junk.Bytes()[mps:mps+mps]) {
		t.Fatal("packet is wrong:\n\t%x\nvs\n\t%x\n", p2.Packet, junk.Bytes()[mps:mps+mps])
	}

	p3, err := d.Decode()
	if err != nil {
		t.Fatal("unexpected Decode error:", err)
	}
	if p3.Type != COP {
		t.Fatal("unexpected page type:", p1.Type)
	}
	rem := (maxPageSize * 2) - mps*2
	if !bytes.Equal(p3.Packet, junk.Bytes()[mps*2:mps*2+rem]) {
		t.Fatal("packet is wrong:\n\t%x\nvs\n\t%x\n", p3.Packet, junk.Bytes()[mps*2:mps*2+rem])
	}
}
<|endoftext|>


<commit_before>package internal

import (
	"encoding/json"
	"log"
	"os"
)

// Config  config struct
type Config struct {
	SourceDSN    string                       `json:"source"`
	DestDSN      string                       `json:"dest"`
	AlterIgnore  map[string]*AlterIgnoreTable `json:"alter_ignore"`
	Tables       []string                     `json:"tables"`
	TablesIGNORE []string                     `json:"tables_ignore"`
	Email        *EmailStruct                 `json:"email"`
	ConfigPath   string
	Sync         bool
	Drop         bool
}

func (cfg *Config) String() string {
	ds, _ := json.MarshalIndent(cfg, "  ", "  ")
	return string(ds)
}

// AlterIgnoreTable table's ignore info
type AlterIgnoreTable struct {
	Column     []string `json:"column"`
	Index      []string `json:"index"`
	ForeignKey []string `json:"foreign"` //外键
}

// IsIgnoreField isIgnore
func (cfg *Config) IsIgnoreField(table string, name string) bool {
	for tname, dit := range cfg.AlterIgnore {
		if simpleMatch(tname, table, "IsIgnoreField_table") {
			for _, col := range dit.Column {
				if simpleMatch(col, name, "IsIgnoreField_colum") {
					return true
				}
			}
		}
	}
	return false
}

// CheckMatchTables check table is match
func (cfg *Config) CheckMatchTables(name string) bool {
	if len(cfg.Tables) == 0 {
		return true
	}
	for _, tableName := range cfg.Tables {
		if simpleMatch(tableName, name, "CheckMatchTables") {
			return true
		}
	}
	return false
}

// CheckMatchIgnoreTables check table_Ignore is match
func (cfg *Config) CheckMatchIgnoreTables(name string) bool {
	if len(cfg.TablesIGNORE) == 0 {
		return false
	}
	for _, tableName := range cfg.TablesIGNORE {
		if simpleMatch(tableName, name, "CheckMatchTables") {
			return true
		}
	}
	return false
}

// Check check config
func (cfg *Config) Check() {
	if cfg.SourceDSN == "" {
		log.Fatal("source dns is empty")
	}
	if cfg.DestDSN == "" {
		log.Fatal("dest dns is empty")
	}
	//	log.Println("config:\n", cfg)
}

// IsIgnoreIndex is index ignore
func (cfg *Config) IsIgnoreIndex(table string, name string) bool {
	for tname, dit := range cfg.AlterIgnore {
		if simpleMatch(tname, table, "IsIgnoreIndex_table") {
			for _, index := range dit.Index {
				if simpleMatch(index, name) {
					return true
				}
			}
		}
	}
	return false
}

// IsIgnoreForeignKey 检查外键是否忽略掉
func (cfg *Config) IsIgnoreForeignKey(table string, name string) bool {
	for tname, dit := range cfg.AlterIgnore {
		if simpleMatch(tname, table, "IsIgnoreForeignKey_table") {
			for _, foreignName := range dit.ForeignKey {
				if simpleMatch(foreignName, name) {
					return true
				}
			}
		}
	}
	return false
}

// SendMailFail send fail mail
func (cfg *Config) SendMailFail(errStr string) {
	if cfg.Email == nil {
		log.Println("email conf is empty,skip send mail")
		return
	}
	_host, _ := os.Hostname()
	title := "[mysql-schema-sync][" + _host + "]failed"
	body := "error:" + errStr + "
"
	body += "host:" + _host + "
"
	body += "config-file:" + cfg.ConfigPath + "
"
	body += "dest_dsn:" + cfg.DestDSN + "
"
	pwd, _ := os.Getwd()
	body += "pwd:" + pwd + "
"
	cfg.Email.SendMail(title, body)
}

// LoadConfig load config file
func LoadConfig(confPath string) *Config {
	var cfg *Config
	err := loadJSONFile(confPath, &cfg)
	if err != nil {
		log.Fatalln("load json conf:", confPath, "failed:", err)
	}
	cfg.ConfigPath = confPath
	//	if *mailTo != "" {
	//		cfg.Email.To = *mailTo
	//	}
	return cfg
}
<commit_msg>Revert "if TablesIGNORE Null check is error"<commit_after>package internal

import (
	"encoding/json"
	"log"
	"os"
)

// Config  config struct
type Config struct {
	SourceDSN    string                       `json:"source"`
	DestDSN      string                       `json:"dest"`
	AlterIgnore  map[string]*AlterIgnoreTable `json:"alter_ignore"`
	Tables       []string                     `json:"tables"`
	TablesIGNORE []string                     `json:"tables_ignore"`
	Email        *EmailStruct                 `json:"email"`
	ConfigPath   string
	Sync         bool
	Drop         bool
}

func (cfg *Config) String() string {
	ds, _ := json.MarshalIndent(cfg, "  ", "  ")
	return string(ds)
}

// AlterIgnoreTable table's ignore info
type AlterIgnoreTable struct {
	Column     []string `json:"column"`
	Index      []string `json:"index"`
	ForeignKey []string `json:"foreign"` //外键
}

// IsIgnoreField isIgnore
func (cfg *Config) IsIgnoreField(table string, name string) bool {
	for tname, dit := range cfg.AlterIgnore {
		if simpleMatch(tname, table, "IsIgnoreField_table") {
			for _, col := range dit.Column {
				if simpleMatch(col, name, "IsIgnoreField_colum") {
					return true
				}
			}
		}
	}
	return false
}

// CheckMatchTables check table is match
func (cfg *Config) CheckMatchTables(name string) bool {
	if len(cfg.Tables) == 0 {
		return true
	}
	for _, tableName := range cfg.Tables {
		if simpleMatch(tableName, name, "CheckMatchTables") {
			return true
		}
	}
	return false
}

// CheckMatchIgnoreTables check table_Ignore is match
func (cfg *Config) CheckMatchIgnoreTables(name string) bool {
	if len(cfg.TablesIGNORE) == 0 {
		return true
	}
	for _, tableName := range cfg.TablesIGNORE {
		if simpleMatch(tableName, name, "CheckMatchTables") {
			return true
		}
	}
	return false
}

// Check check config
func (cfg *Config) Check() {
	if cfg.SourceDSN == "" {
		log.Fatal("source dns is empty")
	}
	if cfg.DestDSN == "" {
		log.Fatal("dest dns is empty")
	}
	//	log.Println("config:\n", cfg)
}

// IsIgnoreIndex is index ignore
func (cfg *Config) IsIgnoreIndex(table string, name string) bool {
	for tname, dit := range cfg.AlterIgnore {
		if simpleMatch(tname, table, "IsIgnoreIndex_table") {
			for _, index := range dit.Index {
				if simpleMatch(index, name) {
					return true
				}
			}
		}
	}
	return false
}

// IsIgnoreForeignKey 检查外键是否忽略掉
func (cfg *Config) IsIgnoreForeignKey(table string, name string) bool {
	for tname, dit := range cfg.AlterIgnore {
		if simpleMatch(tname, table, "IsIgnoreForeignKey_table") {
			for _, foreignName := range dit.ForeignKey {
				if simpleMatch(foreignName, name) {
					return true
				}
			}
		}
	}
	return false
}

// SendMailFail send fail mail
func (cfg *Config) SendMailFail(errStr string) {
	if cfg.Email == nil {
		log.Println("email conf is empty,skip send mail")
		return
	}
	_host, _ := os.Hostname()
	title := "[mysql-schema-sync][" + _host + "]failed"
	body := "error:" + errStr + "
"
	body += "host:" + _host + "
"
	body += "config-file:" + cfg.ConfigPath + "
"
	body += "dest_dsn:" + cfg.DestDSN + "
"
	pwd, _ := os.Getwd()
	body += "pwd:" + pwd + "
"
	cfg.Email.SendMail(title, body)
}

// LoadConfig load config file
func LoadConfig(confPath string) *Config {
	var cfg *Config
	err := loadJSONFile(confPath, &cfg)
	if err != nil {
		log.Fatalln("load json conf:", confPath, "failed:", err)
	}
	cfg.ConfigPath = confPath
	//	if *mailTo != "" {
	//		cfg.Email.To = *mailTo
	//	}
	return cfg
}
<|endoftext|>


<commit_before>// 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 integration provides functionality that needs to be shared between all
// integration tests.
//
// Integration tests are implemented through Go's test framework, as test
// functions that create and execute pipelines using the ptest package. Tests
// should be placed in smaller sub-packages for organizational purposes and
// parallelism (tests are only run in parallel across different packages).
// Integration tests should always begin with a call to CheckFilters to ensure
// test filters can be applied, and each package containing integration tests
// should call ptest.Main in a TestMain function if it uses ptest.
//
// Running integration tests can be done with a go test call with any flags that
// are required by the test pipelines, such as --runner or --endpoint.
// Example:
//    go test -v ./sdks/go/test/integration/... --runner=portable --endpoint=localhost:8099
//
// Alternatively, tests can be executed by running the
// run_validatesrunner_tests.sh script, which also performs much of the
// environment setup, or by calling gradle commands in :sdks:go:test.
package integration

import (
	"fmt"
	"regexp"
	"testing"

	"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
)

// Filters for temporarily skipping integration tests. All filters are regex
// matchers that must match the full name of a test at the point where
// CheckFilters is called. Multiple tests can be skipped by using regex
// wildcards. (ex. "TestXLang_.*" filters all tests starting with TestXLang_)
//
// It is strongly recommended to include, TODOs, Jira issues, or just comments
// describing why tests are being skipped.

// sickbay filters tests that fail due to Go SDK errors. These tests will not
// execute on any runners.
var sickbay = []string{}

// Runner-specific test filters, for features that are not yet supported on
// specific runners.

var directFilters = []string{
	// The direct runner does not yet support cross-language.
	"TestXLang.*",
	"TestKafkaIO.*",
	// Triggers are not yet supported
	"TestTrigger.*",
	// The direct runner does not support the TestStream primitive
	"TestTestStream.*",
}

var portableFilters = []string{
	// The portable runner does not support the TestStream primitive
	"TestTestStream.*",
	// The trigger tests uses TestStream
	"TestTrigger.*",
	// TODO(BEAM-12797): Python portable runner times out on Kafka reads.
	"TestKafkaIO.*",
}

var flinkFilters = []string{
	// TODO(BEAM-11500): Flink tests timing out on reads.
	"TestXLang_Combine.*",
	// TODO(BEAM-12815): Test fails: "Insufficient number of network buffers".
	"TestXLang_Multi",
	// TODO(BEAM-12753): Flink test stream fails for non-string/byte slice inputs
	"TestTestStream.*Sequence.*",
	// Triggers are not yet supported
	"TestTrigger.*",
}

var samzaFilters = []string{
	// TODO(BEAM-12608): Samza tests invalid encoding.
	"TestReshuffle",
	"TestReshuffleKV",
	// The Samza runner does not support the TestStream primitive
	"TestTestStream.*",
	// The trigger tests uses TestStream
	"TestTrigger.*",
}

var sparkFilters = []string{
	// TODO(BEAM-11498): XLang tests broken with Spark runner.
	"TestXLang.*",
	"TestParDoSideInput",
	"TestParDoKVSideInput",
	// The Spark runner does not support the TestStream primitive
	"TestTestStream.*",
	// The trigger tests uses TestStream
	"TestTrigger.*",
}

var dataflowFilters = []string{
	// TODO(BEAM-11576): TestFlattenDup failing on this runner.
	"TestFlattenDup",
	// The Dataflow runner does not support the TestStream primitive
	"TestTestStream.*",
	// The trigger tests uses TestStream
	"TestTrigger.*",
	// There is no infrastructure for running KafkaIO tests with Dataflow.
	"TestKafkaIO.*",
}

// CheckFilters checks if an integration test is filtered to be skipped, either
// because the intended runner does not support it, or the test is sickbayed.
// This method should be called at the beginning of any integration test. If
// t.Run is used, CheckFilters should be called within the t.Run callback, so
// that sub-tests can be skipped individually.
func CheckFilters(t *testing.T) {
	// Check for sickbaying first.
	n := t.Name()
	for _, f := range sickbay {
		// Add start and end of string regexp matchers so only a full match is
		// counted.
		f = fmt.Sprintf("^%v$", f)
		match, err := regexp.MatchString(f, n)
		if err != nil {
			t.Errorf("Matching of regex '%v' with test '%v' failed: %v", f, n, err)
		}
		if match {
			t.Skipf("Test %v is currently sickbayed on all runners", n)
		}
	}

	// Test for runner-specific skipping second.
	var filters []string
	runner := *ptest.Runner
	if runner == "" {
		runner = ptest.DefaultRunner()
	}
	switch runner {
	case "direct", "DirectRunner":
		filters = directFilters
	case "portable", "PortableRunner":
		filters = portableFilters
	case "flink", "FlinkRunner":
		filters = flinkFilters
	case "samza", "SamzaRunner":
		filters = samzaFilters
	case "spark", "SparkRunner":
		filters = sparkFilters
	case "dataflow", "DataflowRunner":
		filters = dataflowFilters
	default:
		return
	}

	for _, f := range filters {
		// Add start and end of string regexp matchers so only a full match is
		// counted.
		f = fmt.Sprintf("^%v$", f)
		match, err := regexp.MatchString(f, n)
		if err != nil {
			t.Errorf("Matching of regex '%v' with test '%v' failed: %v", f, n, err)
		}
		if match {
			t.Skipf("Test %v is currently filtered for runner %v", n, runner)
		}
	}
}
<commit_msg>Disable samza counters (#15659)<commit_after>// 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 integration provides functionality that needs to be shared between all
// integration tests.
//
// Integration tests are implemented through Go's test framework, as test
// functions that create and execute pipelines using the ptest package. Tests
// should be placed in smaller sub-packages for organizational purposes and
// parallelism (tests are only run in parallel across different packages).
// Integration tests should always begin with a call to CheckFilters to ensure
// test filters can be applied, and each package containing integration tests
// should call ptest.Main in a TestMain function if it uses ptest.
//
// Running integration tests can be done with a go test call with any flags that
// are required by the test pipelines, such as --runner or --endpoint.
// Example:
//    go test -v ./sdks/go/test/integration/... --runner=portable --endpoint=localhost:8099
//
// Alternatively, tests can be executed by running the
// run_validatesrunner_tests.sh script, which also performs much of the
// environment setup, or by calling gradle commands in :sdks:go:test.
package integration

import (
	"fmt"
	"regexp"
	"testing"

	"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
)

// Filters for temporarily skipping integration tests. All filters are regex
// matchers that must match the full name of a test at the point where
// CheckFilters is called. Multiple tests can be skipped by using regex
// wildcards. (ex. "TestXLang_.*" filters all tests starting with TestXLang_)
//
// It is strongly recommended to include, TODOs, Jira issues, or just comments
// describing why tests are being skipped.

// sickbay filters tests that fail due to Go SDK errors. These tests will not
// execute on any runners.
var sickbay = []string{}

// Runner-specific test filters, for features that are not yet supported on
// specific runners.

var directFilters = []string{
	// The direct runner does not yet support cross-language.
	"TestXLang.*",
	"TestKafkaIO.*",
	// Triggers are not yet supported
	"TestTrigger.*",
	// The direct runner does not support the TestStream primitive
	"TestTestStream.*",
}

var portableFilters = []string{
	// The portable runner does not support the TestStream primitive
	"TestTestStream.*",
	// The trigger tests uses TestStream
	"TestTrigger.*",
	// TODO(BEAM-12797): Python portable runner times out on Kafka reads.
	"TestKafkaIO.*",
}

var flinkFilters = []string{
	// TODO(BEAM-11500): Flink tests timing out on reads.
	"TestXLang_Combine.*",
	// TODO(BEAM-12815): Test fails: "Insufficient number of network buffers".
	"TestXLang_Multi",
	// TODO(BEAM-12753): Flink test stream fails for non-string/byte slice inputs
	"TestTestStream.*Sequence.*",
	// Triggers are not yet supported
	"TestTrigger.*",
}

var samzaFilters = []string{
	// TODO(BEAM-12608): Samza tests invalid encoding.
	"TestReshuffle",
	"TestReshuffleKV",
	// The Samza runner does not support the TestStream primitive
	"TestTestStream.*",
	// The trigger tests uses TestStream
	"TestTrigger.*",
	// TODO(BEAM-13006): Samza doesn't yet support post job metrics, used by WordCount
	"TestWordCount.*",
}

var sparkFilters = []string{
	// TODO(BEAM-11498): XLang tests broken with Spark runner.
	"TestXLang.*",
	"TestParDoSideInput",
	"TestParDoKVSideInput",
	// The Spark runner does not support the TestStream primitive
	"TestTestStream.*",
	// The trigger tests uses TestStream
	"TestTrigger.*",
}

var dataflowFilters = []string{
	// TODO(BEAM-11576): TestFlattenDup failing on this runner.
	"TestFlattenDup",
	// The Dataflow runner does not support the TestStream primitive
	"TestTestStream.*",
	// The trigger tests uses TestStream
	"TestTrigger.*",
	// There is no infrastructure for running KafkaIO tests with Dataflow.
	"TestKafkaIO.*",
}

// CheckFilters checks if an integration test is filtered to be skipped, either
// because the intended runner does not support it, or the test is sickbayed.
// This method should be called at the beginning of any integration test. If
// t.Run is used, CheckFilters should be called within the t.Run callback, so
// that sub-tests can be skipped individually.
func CheckFilters(t *testing.T) {
	// Check for sickbaying first.
	n := t.Name()
	for _, f := range sickbay {
		// Add start and end of string regexp matchers so only a full match is
		// counted.
		f = fmt.Sprintf("^%v$", f)
		match, err := regexp.MatchString(f, n)
		if err != nil {
			t.Errorf("Matching of regex '%v' with test '%v' failed: %v", f, n, err)
		}
		if match {
			t.Skipf("Test %v is currently sickbayed on all runners", n)
		}
	}

	// Test for runner-specific skipping second.
	var filters []string
	runner := *ptest.Runner
	if runner == "" {
		runner = ptest.DefaultRunner()
	}
	switch runner {
	case "direct", "DirectRunner":
		filters = directFilters
	case "portable", "PortableRunner":
		filters = portableFilters
	case "flink", "FlinkRunner":
		filters = flinkFilters
	case "samza", "SamzaRunner":
		filters = samzaFilters
	case "spark", "SparkRunner":
		filters = sparkFilters
	case "dataflow", "DataflowRunner":
		filters = dataflowFilters
	default:
		return
	}

	for _, f := range filters {
		// Add start and end of string regexp matchers so only a full match is
		// counted.
		f = fmt.Sprintf("^%v$", f)
		match, err := regexp.MatchString(f, n)
		if err != nil {
			t.Errorf("Matching of regex '%v' with test '%v' failed: %v", f, n, err)
		}
		if match {
			t.Skipf("Test %v is currently filtered for runner %v", n, runner)
		}
	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"crypto/tls"
	"net/smtp"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/go-errors/errors"
	"github.com/mitchellh/mapstructure"
	irma "github.com/privacybydesign/irmago"
	"github.com/privacybydesign/irmago/server"
	"github.com/privacybydesign/irmago/server/keyshare"
	"github.com/spf13/cast"

	"github.com/sietseringers/cobra"
	"github.com/sietseringers/viper"
	"github.com/sirupsen/logrus"
)

func configureEmail() keyshare.EmailConfiguration {
	// If username/password are specified for the email server, build an authentication object.
	var emailAuth smtp.Auth
	if viper.GetString("email-username") != "" {
		emailAuth = smtp.PlainAuth(
			"",
			viper.GetString("email-username"),
			viper.GetString("email-password"),
			viper.GetString("email-hostname"),
		)
	}

	return keyshare.EmailConfiguration{
		EmailServer:     viper.GetString("email-server"),
		EmailAuth:       emailAuth,
		EmailFrom:       viper.GetString("email-from"),
		DefaultLanguage: viper.GetString("default-language"),
	}
}

func configureIRMAServer() *server.Configuration {
	return &server.Configuration{
		SchemesPath:            viper.GetString("schemes-path"),
		SchemesAssetsPath:      viper.GetString("schemes-assets-path"),
		SchemesUpdateInterval:  viper.GetInt("schemes-update"),
		DisableSchemesUpdate:   viper.GetInt("schemes-update") == 0,
		IssuerPrivateKeysPath:  viper.GetString("privkeys"),
		RevocationDBType:       viper.GetString("revocation-db-type"),
		RevocationDBConnStr:    viper.GetString("revocation-db-str"),
		RevocationSettings:     irma.RevocationSettings{},
		URL:                    viper.GetString("url"),
		DisableTLS:             viper.GetBool("no-tls"),
		Email:                  viper.GetString("email"),
		EnableSSE:              viper.GetBool("sse"),
		Verbose:                viper.GetInt("verbose"),
		Quiet:                  viper.GetBool("quiet"),
		LogJSON:                viper.GetBool("log-json"),
		Logger:                 logger,
		Production:             viper.GetBool("production"),
		JwtIssuer:              viper.GetString("jwt-issuer"),
		JwtPrivateKey:          viper.GetString("jwt-privkey"),
		JwtPrivateKeyFile:      viper.GetString("jwt-privkey-file"),
		AllowUnsignedCallbacks: viper.GetBool("allow-unsigned-callbacks"),
		AugmentClientReturnURL: viper.GetBool("augment-client-return-url"),
	}
}

func configureTLS() *tls.Config {
	conf, err := server.TLSConf(
		viper.GetString("tls-cert"),
		viper.GetString("tls-cert-file"),
		viper.GetString("tls-privkey"),
		viper.GetString("tls-privkey-file"))
	if err != nil {
		die("", err)
	}
	return conf
}

func readConfig(cmd *cobra.Command, name, logname string, configpaths []string, productionDefaults map[string]interface{}) {
	dashReplacer := strings.NewReplacer("-", "_")
	viper.SetEnvKeyReplacer(dashReplacer)
	viper.SetFileKeyReplacer(dashReplacer)
	viper.SetEnvPrefix(strings.ToUpper(name))
	viper.AutomaticEnv()

	if err := viper.BindPFlags(cmd.Flags()); err != nil {
		die("", err)
	}

	// Locate and read configuration file
	confpath := viper.GetString("config")
	if confpath != "" {
		dir, file := filepath.Dir(confpath), filepath.Base(confpath)
		viper.SetConfigName(strings.TrimSuffix(file, filepath.Ext(file)))
		viper.AddConfigPath(dir)
	} else {
		viper.SetConfigName(name)
		for _, path := range configpaths {
			viper.AddConfigPath(path)
		}
	}

	err := viper.ReadInConfig() // Hold error checking until we know how much of it to log

	// Create our logger instance
	logger = server.NewLogger(viper.GetInt("verbose"), viper.GetBool("quiet"), viper.GetBool("log-json"))

	// First log output: hello, development or production mode, log level
	mode := "development"
	if viper.GetBool("production") {
		mode = "production"
		for key, val := range productionDefaults {
			viper.SetDefault(key, val)
		}
	}
	logger.WithFields(logrus.Fields{
		"version":   irma.Version,
		"mode":      mode,
		"verbosity": server.Verbosity(viper.GetInt("verbose")),
	}).Info(logname + " running")

	// Now we finally examine and log any error from viper.ReadInConfig()
	if err != nil {
		if _, notfound := err.(viper.ConfigFileNotFoundError); notfound {
			logger.Info("No configuration file found")
		} else {
			die("", errors.WrapPrefix(err, "Failed to unmarshal configuration file at "+viper.ConfigFileUsed(), 0))
		}
	} else {
		logger.Info("Config file: ", viper.ConfigFileUsed())
	}
}

func handleMapOrString(key string, dest interface{}) error {
	var m map[string]interface{}
	var err error
	if val, flagOrEnv := viper.Get(key).(string); !flagOrEnv || val != "" {
		if m, err = cast.ToStringMapE(viper.Get(key)); err != nil {
			return errors.WrapPrefix(err, "Failed to unmarshal "+key+" from flag or env var", 0)
		}
	}
	if len(m) == 0 {
		return nil
	}
	if err := mapstructure.Decode(m, dest); err != nil {
		return errors.WrapPrefix(err, "Failed to unmarshal "+key+" from config file", 0)
	}
	return nil
}

func handlePermission(typ string) []string {
	if !viper.IsSet(typ) {
		if typ == "revoke-perms" || (viper.GetBool("production") && typ == "issue-perms") {
			return []string{}
		} else {
			return []string{"*"}
		}
	}
	perms := viper.GetStringSlice(typ)
	if perms == nil {
		return []string{}
	}
	return perms
}

// productionMode examines the arguments passed to the executable to see if --production is enabled.
// (This should really be done using viper, but when the help message is printed, viper is not yet
// initialized.)
func productionMode() bool {
	r := regexp.MustCompile("^--production(=(.*))?$")
	for _, arg := range os.Args {
		matches := r.FindStringSubmatch(arg)
		if len(matches) != 3 {
			continue
		}
		if matches[1] == "" {
			return true
		}
		return checkConfVal(matches[2])
	}

	return checkConfVal(os.Getenv("IRMASERVER_PRODUCTION"))
}

func checkConfVal(val string) bool {
	lc := strings.ToLower(val)
	return lc == "1" || lc == "true" || lc == "yes" || lc == "t"
}
<commit_msg>feat: check existence of server configuration file, if specified<commit_after>package cmd

import (
	"crypto/tls"
	"net/smtp"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/go-errors/errors"
	"github.com/mitchellh/mapstructure"
	irma "github.com/privacybydesign/irmago"
	"github.com/privacybydesign/irmago/server"
	"github.com/privacybydesign/irmago/server/keyshare"
	"github.com/spf13/cast"

	"github.com/sietseringers/cobra"
	"github.com/sietseringers/viper"
	"github.com/sirupsen/logrus"
)

func configureEmail() keyshare.EmailConfiguration {
	// If username/password are specified for the email server, build an authentication object.
	var emailAuth smtp.Auth
	if viper.GetString("email-username") != "" {
		emailAuth = smtp.PlainAuth(
			"",
			viper.GetString("email-username"),
			viper.GetString("email-password"),
			viper.GetString("email-hostname"),
		)
	}

	return keyshare.EmailConfiguration{
		EmailServer:     viper.GetString("email-server"),
		EmailAuth:       emailAuth,
		EmailFrom:       viper.GetString("email-from"),
		DefaultLanguage: viper.GetString("default-language"),
	}
}

func configureIRMAServer() *server.Configuration {
	return &server.Configuration{
		SchemesPath:            viper.GetString("schemes-path"),
		SchemesAssetsPath:      viper.GetString("schemes-assets-path"),
		SchemesUpdateInterval:  viper.GetInt("schemes-update"),
		DisableSchemesUpdate:   viper.GetInt("schemes-update") == 0,
		IssuerPrivateKeysPath:  viper.GetString("privkeys"),
		RevocationDBType:       viper.GetString("revocation-db-type"),
		RevocationDBConnStr:    viper.GetString("revocation-db-str"),
		RevocationSettings:     irma.RevocationSettings{},
		URL:                    viper.GetString("url"),
		DisableTLS:             viper.GetBool("no-tls"),
		Email:                  viper.GetString("email"),
		EnableSSE:              viper.GetBool("sse"),
		Verbose:                viper.GetInt("verbose"),
		Quiet:                  viper.GetBool("quiet"),
		LogJSON:                viper.GetBool("log-json"),
		Logger:                 logger,
		Production:             viper.GetBool("production"),
		JwtIssuer:              viper.GetString("jwt-issuer"),
		JwtPrivateKey:          viper.GetString("jwt-privkey"),
		JwtPrivateKeyFile:      viper.GetString("jwt-privkey-file"),
		AllowUnsignedCallbacks: viper.GetBool("allow-unsigned-callbacks"),
		AugmentClientReturnURL: viper.GetBool("augment-client-return-url"),
	}
}

func configureTLS() *tls.Config {
	conf, err := server.TLSConf(
		viper.GetString("tls-cert"),
		viper.GetString("tls-cert-file"),
		viper.GetString("tls-privkey"),
		viper.GetString("tls-privkey-file"))
	if err != nil {
		die("", err)
	}
	return conf
}

func readConfig(cmd *cobra.Command, name, logname string, configpaths []string, productionDefaults map[string]interface{}) {
	dashReplacer := strings.NewReplacer("-", "_")
	viper.SetEnvKeyReplacer(dashReplacer)
	viper.SetFileKeyReplacer(dashReplacer)
	viper.SetEnvPrefix(strings.ToUpper(name))
	viper.AutomaticEnv()

	if err := viper.BindPFlags(cmd.Flags()); err != nil {
		die("", err)
	}

	// Locate and read configuration file
	confpath := viper.GetString("config")
	if confpath != "" {
		info, err := os.Stat(confpath)
		if err != nil {
			if os.IsNotExist(err) {
				die("specified configuration file does not exist", nil)
			} else {
				die("failed to stat configuration file", err)
			}
		}
		if info.IsDir() {
			die("specified configuration file is a directory", nil)
		}
		dir, file := filepath.Dir(confpath), filepath.Base(confpath)
		viper.SetConfigName(strings.TrimSuffix(file, filepath.Ext(file)))
		viper.AddConfigPath(dir)
	} else {
		viper.SetConfigName(name)
		for _, path := range configpaths {
			viper.AddConfigPath(path)
		}
	}

	err := viper.ReadInConfig() // Hold error checking until we know how much of it to log

	// Create our logger instance
	logger = server.NewLogger(viper.GetInt("verbose"), viper.GetBool("quiet"), viper.GetBool("log-json"))

	// First log output: hello, development or production mode, log level
	mode := "development"
	if viper.GetBool("production") {
		mode = "production"
		for key, val := range productionDefaults {
			viper.SetDefault(key, val)
		}
	}
	logger.WithFields(logrus.Fields{
		"version":   irma.Version,
		"mode":      mode,
		"verbosity": server.Verbosity(viper.GetInt("verbose")),
	}).Info(logname + " running")

	// Now we finally examine and log any error from viper.ReadInConfig()
	if err != nil {
		if _, notfound := err.(viper.ConfigFileNotFoundError); notfound {
			logger.Info("No configuration file found")
		} else {
			die("", errors.WrapPrefix(err, "Failed to unmarshal configuration file at "+viper.ConfigFileUsed(), 0))
		}
	} else {
		logger.Info("Config file: ", viper.ConfigFileUsed())
	}
}

func handleMapOrString(key string, dest interface{}) error {
	var m map[string]interface{}
	var err error
	if val, flagOrEnv := viper.Get(key).(string); !flagOrEnv || val != "" {
		if m, err = cast.ToStringMapE(viper.Get(key)); err != nil {
			return errors.WrapPrefix(err, "Failed to unmarshal "+key+" from flag or env var", 0)
		}
	}
	if len(m) == 0 {
		return nil
	}
	if err := mapstructure.Decode(m, dest); err != nil {
		return errors.WrapPrefix(err, "Failed to unmarshal "+key+" from config file", 0)
	}
	return nil
}

func handlePermission(typ string) []string {
	if !viper.IsSet(typ) {
		if typ == "revoke-perms" || (viper.GetBool("production") && typ == "issue-perms") {
			return []string{}
		} else {
			return []string{"*"}
		}
	}
	perms := viper.GetStringSlice(typ)
	if perms == nil {
		return []string{}
	}
	return perms
}

// productionMode examines the arguments passed to the executable to see if --production is enabled.
// (This should really be done using viper, but when the help message is printed, viper is not yet
// initialized.)
func productionMode() bool {
	r := regexp.MustCompile("^--production(=(.*))?$")
	for _, arg := range os.Args {
		matches := r.FindStringSubmatch(arg)
		if len(matches) != 3 {
			continue
		}
		if matches[1] == "" {
			return true
		}
		return checkConfVal(matches[2])
	}

	return checkConfVal(os.Getenv("IRMASERVER_PRODUCTION"))
}

func checkConfVal(val string) bool {
	lc := strings.ToLower(val)
	return lc == "1" || lc == "true" || lc == "yes" || lc == "t"
}
<|endoftext|>


<commit_before>package main

import (
	"log"

	vlc "github.com/adrg/libvlc-go/v3"
)

func main() {
	// Initialize libVLC. Additional command line arguments can be passed in
	// to libVLC by specifying them in the Init function.
	if err := vlc.Init("--no-video", "--quiet"); err != nil {
		log.Fatal(err)
	}
	defer vlc.Release()

	// Create a new list player.
	lp, err := vlc.NewListPlayer()
	if err != nil {
		log.Fatal(err)
	}
	defer func() {
		lp.Stop()
		lp.Release()
	}()

	// Create a new media list.
	list, err := vlc.NewMediaList()
	if err != nil {
		log.Fatal(err)
	}
	defer list.Release()

	// Add media to list.
	media, err := vlc.NewMediaFromPath("localpath/test.mp3")
	if err != nil {
		log.Fatal(err)
	}
	if err = media.Parse(); err != nil {
		log.Fatal(err)
	}

	err = list.AddMedia(media)
	if err != nil {
		log.Fatal(err)
	}

	// Set player media list.
	if err = lp.SetMediaList(list); err != nil {
		log.Fatal(err)
	}

	// Retrieve player event manager.
	manager, err := lp.EventManager()
	if err != nil {
		log.Fatal(err)
	}

	// Create event handler.
	quit := make(chan struct{})
	eventCallback := func(event vlc.Event, userData interface{}) {
		switch event {
		case vlc.MediaListPlayerPlayed:
			log.Println("Player end reached")
			close(quit)
		case vlc.MediaListPlayerNextItemSet:
			// Retrieve underlying player.
			p, err := lp.Player()
			if err != nil {
				log.Println(err)
				break
			}

			// Retrieve currently playing media.
			media, err := p.Media()
			if err != nil {
				log.Println(err)
				break
			}

			// Get media location.
			location, err := media.Location()
			if err != nil {
				log.Println(err)
				break
			}
			log.Println("Media location:", location)

			// Get media title and artist metadata.
			title, err := media.Meta(vlc.MediaTitle)
			if err != nil {
				log.Println(err)
				break
			}

			artist, err := media.Meta(vlc.MediaArtist)
			if err != nil {
				log.Println(err)
				break
			}

			log.Println("Media title:", title)
			log.Println("Media artist:", artist)
		}
	}

	// Register events with the event manager.
	events := []vlc.Event{
		vlc.MediaListPlayerPlayed,
		vlc.MediaListPlayerNextItemSet,
	}

	var eventIDs []vlc.EventID
	for _, event := range events {
		eventID, err := manager.Attach(event, eventCallback, nil)
		if err != nil {
			log.Fatal(err)
		}

		eventIDs = append(eventIDs, eventID)
	}

	// De-register attached events.
	defer func() {
		for _, eventID := range eventIDs {
			manager.Detach(eventID)
		}
	}()

	// Start playing the media list.
	if err = lp.Play(); err != nil {
		log.Fatal(err)
	}

	<-quit
}
<commit_msg>Adapt media information example to parse media asynchronously<commit_after>package main

import (
	"log"

	vlc "github.com/adrg/libvlc-go/v3"
)

func main() {
	// Initialize libVLC. Additional command line arguments can be passed in
	// to libVLC by specifying them in the Init function.
	if err := vlc.Init("--no-video", "--quiet"); err != nil {
		log.Fatal(err)
	}
	defer vlc.Release()

	// Create a new list player.
	lp, err := vlc.NewListPlayer()
	if err != nil {
		log.Fatal(err)
	}
	defer func() {
		lp.Stop()
		lp.Release()
	}()

	// Create a new media list.
	list, err := vlc.NewMediaList()
	if err != nil {
		log.Fatal(err)
	}
	defer list.Release()

	// Add media to list.
	media, err := vlc.NewMediaFromPath("localpath/test.mp3")
	if err != nil {
		log.Fatal(err)
	}

	// Parse media metadata asynchronously.
	err = media.ParseWithOptions(0, vlc.MediaParseLocal, vlc.MediaParseNetwork)
	if err != nil {
		log.Fatal(err)
	}

	// Add media to media list.
	err = list.AddMedia(media)
	if err != nil {
		log.Fatal(err)
	}

	// Set player media list.
	if err = lp.SetMediaList(list); err != nil {
		log.Fatal(err)
	}

	// Retrieve player event manager.
	manager, err := lp.EventManager()
	if err != nil {
		log.Fatal(err)
	}

	// Create event handler.
	quit := make(chan struct{})
	eventCallback := func(event vlc.Event, userData interface{}) {
		switch event {
		case vlc.MediaListPlayerPlayed:
			log.Println("Player end reached")
			close(quit)
		case vlc.MediaListPlayerNextItemSet:
			// Retrieve underlying player.
			p, err := lp.Player()
			if err != nil {
				log.Println(err)
				break
			}

			// Retrieve currently playing media.
			media, err := p.Media()
			if err != nil {
				log.Println(err)
				break
			}

			// Get media location.
			location, err := media.Location()
			if err != nil {
				log.Println(err)
				break
			}
			log.Println("Media location:", location)
		case vlc.MediaParsedChanged:
			// Retrieve media item from user data.
			media, ok := userData.(*vlc.Media)
			if !ok {
				break
			}

			parseStatus, err := media.ParseStatus()
			if err != nil {
				log.Println(err)
				break
			}
			log.Println("Media parse status:", parseStatus)

			if parseStatus != vlc.MediaParseDone {
				break
			}

			// Get media title and artist metadata.
			title, err := media.Meta(vlc.MediaTitle)
			if err != nil {
				log.Println(err)
				break
			}

			artist, err := media.Meta(vlc.MediaArtist)
			if err != nil {
				log.Println(err)
				break
			}

			log.Println("Media title:", title)
			log.Println("Media artist:", artist)
		}
	}

	// Register events with the event manager.
	events := []vlc.Event{
		vlc.MediaListPlayerPlayed,
		vlc.MediaListPlayerNextItemSet,
	}

	var eventIDs []vlc.EventID
	for _, event := range events {
		eventID, err := manager.Attach(event, eventCallback, nil)
		if err != nil {
			log.Fatal(err)
		}

		eventIDs = append(eventIDs, eventID)
	}

	// De-register attached events.
	defer func() {
		for _, eventID := range eventIDs {
			manager.Detach(eventID)
		}
	}()

	// Register media parsed event with the media event manager.
	mEventManager, err := media.EventManager()
	if err != nil {
		log.Fatal(err)
	}

	// Pass media object as user data in order to retrieve it in the callback
	// function. This is useful in order to avoid keeping references to the
	// media file.
	eventID, err := mEventManager.Attach(vlc.MediaParsedChanged, eventCallback, media)
	if err != nil {
		log.Fatal(err)
	}
	defer mEventManager.Detach(eventID)

	// Start playing the media list.
	if err = lp.Play(); err != nil {
		log.Fatal(err)
	}

	<-quit
}
<|endoftext|>


<commit_before>//  Copyright (c) 2017 Rackspace
//
//  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 objectserver

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"path/filepath"
	"sync"
	"time"

	"go.uber.org/zap"

	"github.com/troubling/hummingbird/common"
	"github.com/troubling/hummingbird/common/fs"
	"github.com/troubling/hummingbird/common/pickle"
	"github.com/troubling/hummingbird/common/ring"
	"github.com/troubling/hummingbird/middleware"
)

const asyncPendingSleep = 10 * time.Millisecond

type asyncPending struct {
	Headers   map[string]string `pickle:"headers"`
	Object    string            `pickle:"obj"`
	Account   string            `pickle:"account"`
	Container string            `pickle:"container"`
	Method    string            `pickle:"op"`
}

type updateDevice struct {
	r             *Replicator
	dev           *ring.Device
	canchan       chan struct{}
	policy        int
	lastReconDump time.Time
	reconLock     sync.Mutex
	reconRunning  bool
}

func (ud *updateDevice) updateStat(stat string, amount int64) {
	key := deviceKeyId(ud.dev.Device, ud.policy)
	ud.r.updateStat <- statUpdate{"object-updater", key, stat, amount}
}

func (ud *updateDevice) listAsyncs(c chan string, cancel chan struct{}) {
	defer close(c)
	suffixDirs, err := filepath.Glob(filepath.Join(ud.r.deviceRoot, ud.dev.Device, AsyncDir(ud.policy), "[a-f0-9][a-f0-9][a-f0-9]"))
	if err != nil {
		return
	}
	for i := len(suffixDirs) - 1; i > 0; i-- { // shuffle suffixDirs list
		j := rand.Intn(i + 1)
		suffixDirs[j], suffixDirs[i] = suffixDirs[i], suffixDirs[j]
	}
	for _, suffDir := range suffixDirs {
		asyncs, err := fs.ReadDirNames(suffDir)
		if err != nil {
			return
		}
		for _, async := range asyncs {
			select {
			case c <- filepath.Join(suffDir, async):
			case <-cancel:
				return
			}
		}
	}
}

func (ud *updateDevice) updateContainers(ap *asyncPending) bool {
	successes := uint64(0)
	part := ud.r.containerRing.GetPartition(ap.Account, ap.Container, "")
	header := common.Map2Headers(ap.Headers)
	header.Set("User-Agent", fmt.Sprintf("object-updater %d", os.Getpid()))
	for _, node := range ud.r.containerRing.GetNodes(part) {
		objUrl := fmt.Sprintf("%s://%s:%d/%s/%d/%s/%s/%s", node.Scheme, node.Ip, node.Port, node.Device, part,
			common.Urlencode(ap.Account), common.Urlencode(ap.Container), common.Urlencode(ap.Object))
		req, err := http.NewRequest(ap.Method, objUrl, nil)
		if err != nil {
			ud.r.logger.Error("updateContainers creating new request", zap.Error(err))
			continue
		}
		req.Header = header
		resp, err := ud.r.client.Do(req)
		if err != nil {
			continue
		}
		resp.Body.Close()
		if resp.StatusCode/100 == 2 {
			successes++
		}
	}
	return successes >= (ud.r.containerRing.ReplicaCount()/2)+1
}

func (ud *updateDevice) processAsync(async string) {
	data, err := ioutil.ReadFile(async)
	if err != nil {
		ud.updateStat("Error", 1)
		ud.r.logger.Error("read async_pending fail", zap.String("file", async), zap.Error(err))
		return
	}
	var ap asyncPending
	if err := pickle.Unmarshal(data, &ap); err != nil {
		ud.updateStat("Error", 1)
		ud.r.logger.Error("unmarshal async_pending fail", zap.String("file", async), zap.Error(err))
		return
	}
	if ud.updateContainers(&ap) {
		ud.updateStat("Success", 1)
		os.Remove(async)
		os.Remove(filepath.Dir(async))
	} else {
		ud.updateStat("Failure", 1)
	}
}

func (ud *updateDevice) reconReportAsync() {
	ud.reconLock.Lock()
	if ud.reconRunning {
		return
	}
	ud.reconRunning = true
	ud.reconLock.Unlock()
	defer func() {
		ud.reconLock.Lock()
		ud.reconRunning = false
		ud.reconLock.Unlock()
	}()
	c := make(chan string, 100)
	cancel := make(chan struct{})
	defer close(cancel)
	go ud.listAsyncs(c, cancel)
	cnt := int64(0)
	for range c {
		cnt++
	}
	if err := middleware.DumpReconCache(ud.r.reconCachePath, "object",
		map[string]interface{}{
			fmt.Sprintf("async_pending_%s", ud.dev.Device): cnt}); err != nil {
		ud.r.logger.Error("object-updater saving recon data", zap.Error(err))
	}
}

func (ud *updateDevice) update() {
	ud.updateStat("startRun", 1)
	if ud.lastReconDump.IsZero() || time.Since(ud.lastReconDump) > time.Hour {
		ud.lastReconDump = time.Now()
		go ud.reconReportAsync()
	}
	c := make(chan string, 100)
	cancel := make(chan struct{})
	defer close(cancel)
	go ud.listAsyncs(c, cancel)
	for async := range c {
		ud.updateStat("checkin", 1)
		func() {
			ud.r.updateConcurrencySem <- struct{}{}
			defer func() {
				<-ud.r.updateConcurrencySem
			}()
			ud.processAsync(async)
		}()
		select {
		case <-time.After(asyncPendingSleep):
		case <-ud.canchan:
			return
		}
		if time.Since(ud.lastReconDump) > time.Hour {
			ud.lastReconDump = time.Now()
			go ud.reconReportAsync()
		}
	}
	ud.updateStat("PassComplete", 1)
}

func (ud *updateDevice) updateLoop() {
	for {
		select {
		case <-ud.canchan:
			return
		default:
			ud.update()
		}
		time.Sleep(replicateLoopSleepTime)
		ud.updateStat("checkin", 1)
	}
}

func (ud *updateDevice) cancel() {
	close(ud.canchan)
}

func newUpdateDevice(dev *ring.Device, policy int, r *Replicator) *updateDevice {
	return &updateDevice{
		policy:  policy,
		dev:     dev,
		r:       r,
		canchan: make(chan struct{}),
	}
}
<commit_msg>HUM-880 Update async counter to use Stat<commit_after>//  Copyright (c) 2017 Rackspace
//
//  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 objectserver

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"path/filepath"
	"sync"
	"syscall"
	"time"

	"go.uber.org/zap"

	"github.com/troubling/hummingbird/common"
	"github.com/troubling/hummingbird/common/fs"
	"github.com/troubling/hummingbird/common/pickle"
	"github.com/troubling/hummingbird/common/ring"
	"github.com/troubling/hummingbird/middleware"
)

const asyncPendingSleep = 10 * time.Millisecond

type asyncPending struct {
	Headers   map[string]string `pickle:"headers"`
	Object    string            `pickle:"obj"`
	Account   string            `pickle:"account"`
	Container string            `pickle:"container"`
	Method    string            `pickle:"op"`
}

type updateDevice struct {
	r             *Replicator
	dev           *ring.Device
	canchan       chan struct{}
	policy        int
	lastReconDump time.Time
	reconLock     sync.Mutex
	reconRunning  bool
}

func (ud *updateDevice) updateStat(stat string, amount int64) {
	key := deviceKeyId(ud.dev.Device, ud.policy)
	ud.r.updateStat <- statUpdate{"object-updater", key, stat, amount}
}

func (ud *updateDevice) listAsyncs(c chan string, cancel chan struct{}) {
	defer close(c)
	suffixDirs, err := filepath.Glob(filepath.Join(ud.r.deviceRoot, ud.dev.Device, AsyncDir(ud.policy), "[a-f0-9][a-f0-9][a-f0-9]"))
	if err != nil {
		return
	}
	for i := len(suffixDirs) - 1; i > 0; i-- { // shuffle suffixDirs list
		j := rand.Intn(i + 1)
		suffixDirs[j], suffixDirs[i] = suffixDirs[i], suffixDirs[j]
	}
	for _, suffDir := range suffixDirs {
		asyncs, err := fs.ReadDirNames(suffDir)
		if err != nil {
			return
		}
		for _, async := range asyncs {
			select {
			case c <- filepath.Join(suffDir, async):
			case <-cancel:
				return
			}
		}
	}
}

func (ud *updateDevice) updateContainers(ap *asyncPending) bool {
	successes := uint64(0)
	part := ud.r.containerRing.GetPartition(ap.Account, ap.Container, "")
	header := common.Map2Headers(ap.Headers)
	header.Set("User-Agent", fmt.Sprintf("object-updater %d", os.Getpid()))
	for _, node := range ud.r.containerRing.GetNodes(part) {
		objUrl := fmt.Sprintf("%s://%s:%d/%s/%d/%s/%s/%s", node.Scheme, node.Ip, node.Port, node.Device, part,
			common.Urlencode(ap.Account), common.Urlencode(ap.Container), common.Urlencode(ap.Object))
		req, err := http.NewRequest(ap.Method, objUrl, nil)
		if err != nil {
			ud.r.logger.Error("updateContainers creating new request", zap.Error(err))
			continue
		}
		req.Header = header
		resp, err := ud.r.client.Do(req)
		if err != nil {
			continue
		}
		resp.Body.Close()
		if resp.StatusCode/100 == 2 {
			successes++
		}
	}
	return successes >= (ud.r.containerRing.ReplicaCount()/2)+1
}

func (ud *updateDevice) processAsync(async string) {
	data, err := ioutil.ReadFile(async)
	if err != nil {
		ud.updateStat("Error", 1)
		ud.r.logger.Error("read async_pending fail", zap.String("file", async), zap.Error(err))
		return
	}
	var ap asyncPending
	if err := pickle.Unmarshal(data, &ap); err != nil {
		ud.updateStat("Error", 1)
		ud.r.logger.Error("unmarshal async_pending fail", zap.String("file", async), zap.Error(err))
		return
	}
	if ud.updateContainers(&ap) {
		ud.updateStat("Success", 1)
		os.Remove(async)
		os.Remove(filepath.Dir(async))
	} else {
		ud.updateStat("Failure", 1)
	}
}

func (ud *updateDevice) reconReportAsync() {
	ud.reconLock.Lock()
	if ud.reconRunning {
		return
	}
	ud.reconRunning = true
	ud.reconLock.Unlock()
	defer func() {
		ud.reconLock.Lock()
		ud.reconRunning = false
		ud.reconLock.Unlock()
	}()
	cnt := uint64(0)
	suffixDirs, err := filepath.Glob(filepath.Join(ud.r.deviceRoot, ud.dev.Device, AsyncDir(ud.policy), "[a-f0-9][a-f0-9][a-f0-9]"))
	if err != nil {
		return
	}
	var stat syscall.Stat_t
	for _, suffDir := range suffixDirs {
		if err = syscall.Stat(suffDir, &stat); err != nil {
			ud.r.logger.Error("object-updater unable to stat", zap.String("suffDir", suffDir), zap.Error(err))
			continue
		}
		if stat.Nlink > 1 {
			cnt += stat.Nlink - 1
		}
	}
	if err := middleware.DumpReconCache(ud.r.reconCachePath, "object",
		map[string]interface{}{
			fmt.Sprintf("async_pending_%s", ud.dev.Device): cnt}); err != nil {
		ud.r.logger.Error("object-updater saving recon data", zap.Error(err))
	}
}

func (ud *updateDevice) update() {
	ud.updateStat("startRun", 1)
	if ud.lastReconDump.IsZero() || time.Since(ud.lastReconDump) > time.Hour {
		ud.lastReconDump = time.Now()
		go ud.reconReportAsync()
	}
	c := make(chan string, 100)
	cancel := make(chan struct{})
	defer close(cancel)
	go ud.listAsyncs(c, cancel)
	for async := range c {
		ud.updateStat("checkin", 1)
		func() {
			ud.r.updateConcurrencySem <- struct{}{}
			defer func() {
				<-ud.r.updateConcurrencySem
			}()
			ud.processAsync(async)
		}()
		select {
		case <-time.After(asyncPendingSleep):
		case <-ud.canchan:
			return
		}
		if time.Since(ud.lastReconDump) > time.Hour {
			ud.lastReconDump = time.Now()
			go ud.reconReportAsync()
		}
	}
	ud.updateStat("PassComplete", 1)
}

func (ud *updateDevice) updateLoop() {
	for {
		select {
		case <-ud.canchan:
			return
		default:
			ud.update()
		}
		time.Sleep(replicateLoopSleepTime)
		ud.updateStat("checkin", 1)
	}
}

func (ud *updateDevice) cancel() {
	close(ud.canchan)
}

func newUpdateDevice(dev *ring.Device, policy int, r *Replicator) *updateDevice {
	return &updateDevice{
		policy:  policy,
		dev:     dev,
		r:       r,
		canchan: make(chan struct{}),
	}
}
<|endoftext|>


<commit_before>// +build linux

package main

import (
	"encoding/hex"
	"encoding/json"
	"log"
	"log/syslog"
	"os"

	"github.com/godbus/dbus"
)

var conn *dbus.Conn

type State struct {
	Version string `json:"version"`
	ID      string `json:"id"`
	Pid     int    `json:"pid"`
	Root    string `json:"root"`
}

func Validate(id string) (string, error) {
	for len(id) < 32 {
		id += "0"
	}
	return hex.EncodeToString([]byte(id)), nil
}

// RegisterMachine with systemd on the host system
func RegisterMachine(name string, id string, pid int, root_directory string) error {
	var (
		av  []byte
		err error
	)
	if conn == nil {
		conn, err = dbus.SystemBus()
		if err != nil {
			return err
		}
	}

	av, err = hex.DecodeString(id[0:32])
	if err != nil {
		return err
	}
	obj := conn.Object("org.freedesktop.machine1", "/org/freedesktop/machine1")
	service := os.Getenv("container")
	if service == "" {
		service = "runc"
	}
	/*	return obj.Call("org.freedesktop.machine1.Manager.RegisterMachine", 0, name[0:32], av, service, "container", uint32(pid), root_directory).Err
	 */
	return obj.Call("org.freedesktop.machine1.Manager.RegisterMachine", 0, name[0:32], av, service, "container", uint32(pid), "/").Err
	return nil
}

// TerminateMachine registered with systemd on the host system
func TerminateMachine(name string) error {
	var err error
	if conn == nil {
		conn, err = dbus.SystemBus()
		if err != nil {
			return err
		}
	}
	obj := conn.Object("org.freedesktop.machine1", "/org/freedesktop/machine1")
	return obj.Call("org.freedesktop.machine1.Manager.TerminateMachine", 0, name).Err
	return nil
}

func main() {
	var state State
	logwriter, err := syslog.New(syslog.LOG_NOTICE, "oci-register-machine")
	if err == nil {
		log.SetOutput(logwriter)
	}
	command := os.Args[1]
	if err := json.NewDecoder(os.Stdin).Decode(&state); err != nil {
		log.Fatalf("RegisterMachine Failed %v", err.Error())
	}

	log.Printf("Register machine: %s %d %s %s", command, state.ID, state.Pid, state.Root)
	// ensure id is a hex string at least 32 chars
	passId, err := Validate(state.ID)
	if err != nil {
		log.Fatalf("RegisterMachine Failed %v", err.Error())
	}

	switch command {
	case "prestart":
		{
			if err = RegisterMachine(state.ID, passId, int(state.Pid), state.Root); err != nil {
				log.Fatalf("Register machine failed: %v", err)
			}
			return
		}
	case "poststop":
		{
			if err := TerminateMachine(state.ID); err != nil {
				log.Fatalf("TerminateMachine failed: %v", err)
			}
			return
		}
		log.Fatalf("Invalid command %q must be prestart|poststop", command)
	}
}
<commit_msg>Return proper rootfs<commit_after>// +build linux

package main

import (
	"encoding/hex"
	"encoding/json"
	"log"
	"log/syslog"
	"os"

	"github.com/godbus/dbus"
)

var conn *dbus.Conn

type State struct {
	Version string `json:"version"`
	ID      string `json:"id"`
	Pid     int    `json:"pid"`
	Root    string `json:"root"`
}

func Validate(id string) (string, error) {
	for len(id) < 32 {
		id += "0"
	}
	return hex.EncodeToString([]byte(id)), nil
}

// RegisterMachine with systemd on the host system
func RegisterMachine(name string, id string, pid int, root_directory string) error {
	var (
		av  []byte
		err error
	)
	if conn == nil {
		conn, err = dbus.SystemBus()
		if err != nil {
			return err
		}
	}

	av, err = hex.DecodeString(id[0:32])
	if err != nil {
		return err
	}
	obj := conn.Object("org.freedesktop.machine1", "/org/freedesktop/machine1")
	service := os.Getenv("container")
	if service == "" {
		service = "runc"
	}
	return obj.Call("org.freedesktop.machine1.Manager.RegisterMachine", 0, name[0:32], av, service, "container", uint32(pid), root_directory).Err
}

// TerminateMachine registered with systemd on the host system
func TerminateMachine(name string) error {
	var err error
	if conn == nil {
		conn, err = dbus.SystemBus()
		if err != nil {
			return err
		}
	}
	obj := conn.Object("org.freedesktop.machine1", "/org/freedesktop/machine1")
	return obj.Call("org.freedesktop.machine1.Manager.TerminateMachine", 0, name).Err
	return nil
}

func main() {
	var state State
	logwriter, err := syslog.New(syslog.LOG_NOTICE, "oci-register-machine")
	if err == nil {
		log.SetOutput(logwriter)
	}
	command := os.Args[1]
	if err := json.NewDecoder(os.Stdin).Decode(&state); err != nil {
		log.Fatalf("RegisterMachine Failed %v", err.Error())
	}

	log.Printf("Register machine: %s %d %s %s", command, state.ID, state.Pid, state.Root)
	// ensure id is a hex string at least 32 chars
	passId, err := Validate(state.ID)
	if err != nil {
		log.Fatalf("RegisterMachine Failed %v", err.Error())
	}

	switch command {
	case "prestart":
		{
			if err = RegisterMachine(state.ID, passId, int(state.Pid), state.Root); err != nil {
				log.Fatalf("Register machine failed: %v", err)
			}
			return
		}
	case "poststop":
		{
			if err := TerminateMachine(state.ID); err != nil {
				log.Fatalf("TerminateMachine failed: %v", err)
			}
			return
		}
		log.Fatalf("Invalid command %q must be prestart|poststop", command)
	}
}
<|endoftext|>


<commit_before>package main

import "walnut"

func main() {
    context := MakeContext()

    context.RegisterMessage(func (m Message) string {
        return "Really!"
    })

    context.RegisterCommand("hello", func (m Command) string {
        return "Really?"
    })

    context.Run("hello2")
}

<commit_msg>Really fix naming.<commit_after>package main

import "walnut"

func main() {
    context := walnut.MakeContext()

    context.RegisterMessage(func (m walnut.Message) string {
        return "Really!"
    })

    context.RegisterCommand("hello", func (m walnut.Command) string {
        return "Really?"
    })

    context.Run("hello2")
}

<|endoftext|>


<commit_before>/*
Copyright 2020 The Knative 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 ingress

import (
	"testing"

	"k8s.io/apimachinery/pkg/util/intstr"
	"knative.dev/networking/pkg/apis/networking"
	"knative.dev/networking/pkg/apis/networking/v1alpha1"
	"knative.dev/networking/test"
)

// TestRewriteHost verifies that a RewriteHost rule can be used to implement vanity URLs.
func TestRewriteHost(t *testing.T) {
	t.Parallel()
	clients := test.Setup(t)

	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
	defer cancel()

	// Create a simple Ingress over the Service.
	_, _, cancel = CreateIngressReady(t, clients, v1alpha1.IngressSpec{
		Rules: []v1alpha1.IngressRule{{
			Visibility: v1alpha1.IngressVisibilityClusterLocal,
			Hosts:      []string{name + ".example.com"},
			HTTP: &v1alpha1.HTTPIngressRuleValue{
				Paths: []v1alpha1.HTTPIngressPath{{
					Splits: []v1alpha1.IngressBackendSplit{{
						IngressBackend: v1alpha1.IngressBackend{
							ServiceName:      name,
							ServiceNamespace: test.ServingNamespace,
							ServicePort:      intstr.FromInt(port),
						},
					}},
				}},
			},
		}},
	})
	defer cancel()

	// Now create a RewriteHost ingress to point a custom Host at the Service
	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
		Rules: []v1alpha1.IngressRule{{
			Hosts:      []string{"vanity.ismy.name", "vanity.isalsomy.number"},
			Visibility: v1alpha1.IngressVisibilityExternalIP,
			HTTP: &v1alpha1.HTTPIngressRuleValue{
				Paths: []v1alpha1.HTTPIngressPath{{
					RewriteHost: name + ".example.com",
				}},
			},
		}},
	})
	defer cancel()

	RuntimeRequest(t, client, "http://vanity.ismy.name")
	RuntimeRequest(t, client, "http://vanity.isalsomy.number")
}
<commit_msg>Avoid more host collisions (#90)<commit_after>/*
Copyright 2020 The Knative 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 ingress

import (
	"testing"

	"k8s.io/apimachinery/pkg/util/intstr"
	"knative.dev/networking/pkg/apis/networking"
	"knative.dev/networking/pkg/apis/networking/v1alpha1"
	"knative.dev/networking/test"
)

// TestRewriteHost verifies that a RewriteHost rule can be used to implement vanity URLs.
func TestRewriteHost(t *testing.T) {
	t.Parallel()
	clients := test.Setup(t)

	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
	defer cancel()

	// Create a simple Ingress over the Service.
	_, _, cancel = CreateIngressReady(t, clients, v1alpha1.IngressSpec{
		Rules: []v1alpha1.IngressRule{{
			Visibility: v1alpha1.IngressVisibilityClusterLocal,
			Hosts:      []string{name + ".example.com"},
			HTTP: &v1alpha1.HTTPIngressRuleValue{
				Paths: []v1alpha1.HTTPIngressPath{{
					Splits: []v1alpha1.IngressBackendSplit{{
						IngressBackend: v1alpha1.IngressBackend{
							ServiceName:      name,
							ServiceNamespace: test.ServingNamespace,
							ServicePort:      intstr.FromInt(port),
						},
					}},
				}},
			},
		}},
	})
	defer cancel()

	hosts := []string{
		"vanity.ismy.name",
		"vanity.isalsomy.number",
	}

	// Using fixed hostnames can lead to conflicts when -count=N>1
	// so pseudo-randomize the hostnames to avoid conflicts.
	for i, host := range hosts {
		hosts[i] = name + "." + host
	}

	// Now create a RewriteHost ingress to point a custom Host at the Service
	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
		Rules: []v1alpha1.IngressRule{{
			Hosts:      hosts,
			Visibility: v1alpha1.IngressVisibilityExternalIP,
			HTTP: &v1alpha1.HTTPIngressRuleValue{
				Paths: []v1alpha1.HTTPIngressPath{{
					RewriteHost: name + ".example.com",
				}},
			},
		}},
	})
	defer cancel()

	for _, host := range hosts {
		RuntimeRequest(t, client, host)
	}
}
<|endoftext|>