<commit_before>// Released under an MIT-style license. See LICENSE.

// +build linux darwin dragonfly freebsd openbsd netbsd solaris

package task

import (
	. "github.com/michaelmacinnis/oh/pkg/cell"
	"os"
	"os/signal"
	"path"
	"syscall"
	"unsafe"
)

type notification struct {
	pid    int
	status syscall.WaitStatus
}

type registration struct {
	pid int
	cb  chan notification
}

var (
	Platform string = "unix"
	done0    chan Cell
	eval0    chan Cell
	incoming chan os.Signal
	register chan registration
)

func BecomeProcessGroupLeader() int {
	pid := syscall.Getpid()
	pgid := syscall.Getpgrp()
	if pid != pgid {
		syscall.Setpgid(0, 0)
	}

	return pid
}

func ContinueProcess(pid int) {
	syscall.Kill(pid, syscall.SIGCONT)
}

func GetHistoryFilePath() (string, error) {
	return path.Join(os.Getenv("HOME"), ".oh_history"), nil
}

func InitSignalHandling() {
	signal.Ignore(syscall.SIGTTOU, syscall.SIGTTIN)

	signals := []os.Signal{syscall.SIGINT, syscall.SIGTSTP}
	incoming = make(chan os.Signal, len(signals))

	signal.Notify(incoming, signals...)

	go broker()
}

func JobControlSupported() bool {
	return true
}

func JoinProcess(proc *os.Process) int {
	response := make(chan notification)
	register <- registration{proc.Pid, response}

	return (<-response).status.ExitStatus()
}

func SetForegroundGroup(group int) {
	syscall.Syscall(syscall.SYS_IOCTL, uintptr(syscall.Stdin),
		syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&group)))
}

func SuspendProcess(pid int) {
	syscall.Kill(pid, syscall.SIGSTOP)
}

func SysProcAttr(group int) *syscall.SysProcAttr {
	sys := &syscall.SysProcAttr{}

	if group == 0 {
		sys.Ctty = syscall.Stdout
		sys.Foreground = true
	} else {
		sys.Setpgid = true
		sys.Pgid = group
	}

	return sys
}

func TerminateProcess(pid int) {
	syscall.Kill(pid, syscall.SIGTERM)
}

func broker() {
	var c Cell
	for c == nil && task0.Stack != Null {
		for c == nil {
			select {
			case <-incoming:
			case c = <-eval0:
			}
		}
		task0.Eval <- c
		for c != nil {
			prev := task0
			select {
			case sig := <-incoming:
				// Handle signals.
				switch sig {
				case syscall.SIGTSTP:
					task0.Suspend()
					last := 0
					for k := range jobs {
						if k > last {
							last = k
						}
					}
					last++

					jobs[last] = task0

					fallthrough
				case syscall.SIGINT:
					if sig == syscall.SIGINT {
						task0.Stop()
					}

					LaunchForegroundTask()
					c = nil
				}

			case c = <-task0.Done:
				if task0 != prev {
					c = Null
					continue
				}
			}
		}
		done0 <- c
	}
	os.Exit(status(Car(task0.Scratch)))
}

func evaluate(c Cell) {
	eval0 <- c
	<-done0

	task0.Job.Command = ""
	task0.Job.Group = 0
}

func init() {
	done0 = make(chan Cell)
	eval0 = make(chan Cell)

	active := make(chan bool)
	notify := make(chan notification)
	register = make(chan registration)

	go monitor(active, notify)
	go registrar(active, notify)
}

func monitor(active chan bool, notify chan notification) {
	for {
		monitoring := <-active
		for monitoring {
			var rusage syscall.Rusage
			var status syscall.WaitStatus
			options := syscall.WUNTRACED
			pid, err := syscall.Wait4(-1, &status, options, &rusage)
			if err != nil {
				println("Wait4:", err.Error())
			}
			if pid <= 0 {
				break
			}

			if status.Stopped() {
				if pid == task0.Job.Group {
					incoming <- syscall.SIGTSTP
				}
				continue
			}

			if status.Signaled() {
				if status.Signal() == syscall.SIGINT &&
					pid == task0.Job.Group {
					incoming <- syscall.SIGINT
				}
				status += 128
			}

			notify <- notification{pid, status}
			monitoring = <-active
		}
	}
}

func registrar(active chan bool, notify chan notification) {
	preregistered := make(map[int]notification)
	registered := make(map[int]registration)
	for {
		select {
		case n := <-notify:
			r, ok := registered[n.pid]
			if ok {
				r.cb <- n
				delete(registered, n.pid)
			} else {
				preregistered[n.pid] = n
			}
			active <- len(registered) != 0
		case r := <-register:
			if n, ok := preregistered[r.pid]; ok {
				r.cb <- n
				delete(preregistered, r.pid)
			} else {
				registered[r.pid] = r
				if len(registered) == 1 {
					active <- true
				}
			}
		}
	}
}
<commit_msg>Static history path.<commit_after>// Released under an MIT-style license. See LICENSE.

// +build linux darwin dragonfly freebsd openbsd netbsd solaris

package task

import (
	. "github.com/michaelmacinnis/oh/pkg/cell"
	"os"
	"os/signal"
	"path"
	"syscall"
	"unsafe"
)

type notification struct {
	pid    int
	status syscall.WaitStatus
}

type registration struct {
	pid int
	cb  chan notification
}

var (
	Platform string = "unix"
	done0    chan Cell
	eval0    chan Cell
	history  string = ""
	incoming chan os.Signal
	register chan registration
)

func BecomeProcessGroupLeader() int {
	pid := syscall.Getpid()
	pgid := syscall.Getpgrp()
	if pid != pgid {
		syscall.Setpgid(0, 0)
	}

	return pid
}

func ContinueProcess(pid int) {
	syscall.Kill(pid, syscall.SIGCONT)
}

func GetHistoryFilePath() (string, error) {
	if history == "" {
		history = path.Join(os.Getenv("HOME"), ".oh_history")
	}
	return history, nil
}

func InitSignalHandling() {
	signal.Ignore(syscall.SIGTTOU, syscall.SIGTTIN)

	signals := []os.Signal{syscall.SIGINT, syscall.SIGTSTP}
	incoming = make(chan os.Signal, len(signals))

	signal.Notify(incoming, signals...)

	go broker()
}

func JobControlSupported() bool {
	return true
}

func JoinProcess(proc *os.Process) int {
	response := make(chan notification)
	register <- registration{proc.Pid, response}

	return (<-response).status.ExitStatus()
}

func SetForegroundGroup(group int) {
	syscall.Syscall(syscall.SYS_IOCTL, uintptr(syscall.Stdin),
		syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&group)))
}

func SuspendProcess(pid int) {
	syscall.Kill(pid, syscall.SIGSTOP)
}

func SysProcAttr(group int) *syscall.SysProcAttr {
	sys := &syscall.SysProcAttr{}

	if group == 0 {
		sys.Ctty = syscall.Stdout
		sys.Foreground = true
	} else {
		sys.Setpgid = true
		sys.Pgid = group
	}

	return sys
}

func TerminateProcess(pid int) {
	syscall.Kill(pid, syscall.SIGTERM)
}

func broker() {
	var c Cell
	for c == nil && task0.Stack != Null {
		for c == nil {
			select {
			case <-incoming:
			case c = <-eval0:
			}
		}
		task0.Eval <- c
		for c != nil {
			prev := task0
			select {
			case sig := <-incoming:
				// Handle signals.
				switch sig {
				case syscall.SIGTSTP:
					task0.Suspend()
					last := 0
					for k := range jobs {
						if k > last {
							last = k
						}
					}
					last++

					jobs[last] = task0

					fallthrough
				case syscall.SIGINT:
					if sig == syscall.SIGINT {
						task0.Stop()
					}

					LaunchForegroundTask()
					c = nil
				}

			case c = <-task0.Done:
				if task0 != prev {
					c = Null
					continue
				}
			}
		}
		done0 <- c
	}
	os.Exit(status(Car(task0.Scratch)))
}

func evaluate(c Cell) {
	eval0 <- c
	<-done0

	task0.Job.Command = ""
	task0.Job.Group = 0
}

func init() {
	done0 = make(chan Cell)
	eval0 = make(chan Cell)

	active := make(chan bool)
	notify := make(chan notification)
	register = make(chan registration)

	go monitor(active, notify)
	go registrar(active, notify)
}

func monitor(active chan bool, notify chan notification) {
	for {
		monitoring := <-active
		for monitoring {
			var rusage syscall.Rusage
			var status syscall.WaitStatus
			options := syscall.WUNTRACED
			pid, err := syscall.Wait4(-1, &status, options, &rusage)
			if err != nil {
				println("Wait4:", err.Error())
			}
			if pid <= 0 {
				break
			}

			if status.Stopped() {
				if pid == task0.Job.Group {
					incoming <- syscall.SIGTSTP
				}
				continue
			}

			if status.Signaled() {
				if status.Signal() == syscall.SIGINT &&
					pid == task0.Job.Group {
					incoming <- syscall.SIGINT
				}
				status += 128
			}

			notify <- notification{pid, status}
			monitoring = <-active
		}
	}
}

func registrar(active chan bool, notify chan notification) {
	preregistered := make(map[int]notification)
	registered := make(map[int]registration)
	for {
		select {
		case n := <-notify:
			r, ok := registered[n.pid]
			if ok {
				r.cb <- n
				delete(registered, n.pid)
			} else {
				preregistered[n.pid] = n
			}
			active <- len(registered) != 0
		case r := <-register:
			if n, ok := preregistered[r.pid]; ok {
				r.cb <- n
				delete(preregistered, r.pid)
			} else {
				registered[r.pid] = r
				if len(registered) == 1 {
					active <- true
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>// @author Couchbase <info@couchbase.com>
// @copyright 2014 Couchbase, Inc.
//
// 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 cbauth

import (
	"errors"
	"fmt"
	"net/http"
	"net/rpc"
	"net/url"
	"os"
	"path/filepath"
	"time"

	"github.com/couchbase/cbauth/cbauthimpl"
	"github.com/couchbase/cbauth/revrpc"
)

// Default variable holds default authenticator. Default authenticator
// is constructed automatically from environment variables passed by
// ns_server. It is nil if your process was not (correctly) spawned by
// ns_server.
var Default Authenticator

var errDisconnected = errors.New("revrpc connection to ns_server was closed")

const waitBeforeStale = time.Minute

func runRPCForSvc(rpcsvc *revrpc.Service, svc *cbauthimpl.Svc) error {
	defPolicy := revrpc.DefaultBabysitErrorPolicy.New()
	// error restart policy that we're going to use simply
	// resets service before delegating to default restart
	// policy. That way we always mark service as stale
	// right after some error occurred.
	cbauthPolicy := func(err error) error {
		resetErr := err
		if err == nil {
			resetErr = errDisconnected
		}
		cbauthimpl.ResetSvc(svc, &DBStaleError{resetErr})
		return defPolicy(err)
	}
	return revrpc.BabysitService(func(s *rpc.Server) error {
		return s.RegisterName("AuthCacheSvc", svc)
	}, rpcsvc, revrpc.FnBabysitErrorPolicy(cbauthPolicy))
}

func startDefault(rpcsvc *revrpc.Service) {
	svc := cbauthimpl.NewSVC(waitBeforeStale, &DBStaleError{})
	Default = &authImpl{svc}
	go func() {
		panic(runRPCForSvc(rpcsvc, svc))
	}()
}

func init() {
	rpcsvc, err := revrpc.GetDefaultServiceFromEnv("cbauth")
	if err != nil {
		ErrNotInitialized = fmt.Errorf("Unable to initialize cbauth's revrpc: %s", err)
		return
	}
	startDefault(rpcsvc)
}

// InternalRetryDefaultInit can be used by golang services that are
// willing to perform manual initialization of cbauth (i.e. for easier
// testing). This API is subject to change and should be used only if
// really needed. Returns false if Default Authenticator was already
// initialized.
func InternalRetryDefaultInit(mgmtHostPort, user, password string) (bool, error) {
	service:= filepath.Base(os.Args[0])
	return InternalRetryDefaultInitWithService(service, mgmtHostPort, user, password)
}

func InternalRetryDefaultInitWithService(service, mgmtHostPort, user, password string) (bool, error) {
	if Default != nil {
		return false, nil
	}
	serviceName := service + "-cbauth"
	host, port, err := SplitHostPort(mgmtHostPort)
	if err != nil {
		return false, nil
	}
	baseurl := fmt.Sprintf("http://%s:%d/%s", host, port, serviceName)
	u, err := url.Parse(baseurl)
	if err != nil {
		return false, fmt.Errorf("Failed to parse constructed url `%s': %s", baseurl, err)
	}
	u.User = url.UserPassword(user, password)

	startDefault(revrpc.MustService(u.String()))

	return true, nil
}

// ErrNotInitialized is used to signal that ns_server environment
// variables are not set, and thus Default authenticator is not
// configured for calls that use default authenticator.
var ErrNotInitialized = errors.New("cbauth was not initialized")

// WithDefault calls given body with default authenticator. If default
// authenticator is not configured, it returns ErrNotInitialized.
func WithDefault(body func(a Authenticator) error) error {
	return WithAuthenticator(nil, body)
}

// WithAuthenticator calls given body with either passed authenticator
// or default authenticator if `a' is nil. ErrNotInitialized is
// returned if a is nil and default authenticator is not configured.
func WithAuthenticator(a Authenticator, body func(a Authenticator) error) error {
	if a == nil {
		a = Default
		if a == nil {
			return ErrNotInitialized
		}
	}
	return body(a)
}

// AuthWebCreds method extracts credentials from given http request
// using default authenticator.
func AuthWebCreds(req *http.Request) (creds Creds, err error) {
	if Default == nil {
		return nil, ErrNotInitialized
	}
	return Default.AuthWebCreds(req)
}

// Auth method constructs credentials from given user and password
// pair. Uses default authenticator.
func Auth(user, pwd string) (creds Creds, err error) {
	if Default == nil {
		return nil, ErrNotInitialized
	}
	return Default.Auth(user, pwd)
}

// GetHTTPServiceAuth returns user/password creds giving "admin"
// access to given http service inside couchbase cluster. Uses default
// authenticator.
func GetHTTPServiceAuth(hostport string) (user, pwd string, err error) {
	if Default == nil {
		return "", "", ErrNotInitialized
	}
	return Default.GetHTTPServiceAuth(hostport)
}

// GetMemcachedServiceAuth returns user/password creds given "admin"
// access to given memcached service. Uses default authenticator.
func GetMemcachedServiceAuth(hostport string) (user, pwd string, err error) {
	if Default == nil {
		return "", "", ErrNotInitialized
	}
	return Default.GetMemcachedServiceAuth(hostport)
}
<commit_msg>formatting<commit_after>// @author Couchbase <info@couchbase.com>
// @copyright 2014 Couchbase, Inc.
//
// 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 cbauth

import (
	"errors"
	"fmt"
	"net/http"
	"net/rpc"
	"net/url"
	"os"
	"path/filepath"
	"time"

	"github.com/couchbase/cbauth/cbauthimpl"
	"github.com/couchbase/cbauth/revrpc"
)

// Default variable holds default authenticator. Default authenticator
// is constructed automatically from environment variables passed by
// ns_server. It is nil if your process was not (correctly) spawned by
// ns_server.
var Default Authenticator

var errDisconnected = errors.New("revrpc connection to ns_server was closed")

const waitBeforeStale = time.Minute

func runRPCForSvc(rpcsvc *revrpc.Service, svc *cbauthimpl.Svc) error {
	defPolicy := revrpc.DefaultBabysitErrorPolicy.New()
	// error restart policy that we're going to use simply
	// resets service before delegating to default restart
	// policy. That way we always mark service as stale
	// right after some error occurred.
	cbauthPolicy := func(err error) error {
		resetErr := err
		if err == nil {
			resetErr = errDisconnected
		}
		cbauthimpl.ResetSvc(svc, &DBStaleError{resetErr})
		return defPolicy(err)
	}
	return revrpc.BabysitService(func(s *rpc.Server) error {
		return s.RegisterName("AuthCacheSvc", svc)
	}, rpcsvc, revrpc.FnBabysitErrorPolicy(cbauthPolicy))
}

func startDefault(rpcsvc *revrpc.Service) {
	svc := cbauthimpl.NewSVC(waitBeforeStale, &DBStaleError{})
	Default = &authImpl{svc}
	go func() {
		panic(runRPCForSvc(rpcsvc, svc))
	}()
}

func init() {
	rpcsvc, err := revrpc.GetDefaultServiceFromEnv("cbauth")
	if err != nil {
		ErrNotInitialized = fmt.Errorf("Unable to initialize cbauth's revrpc: %s", err)
		return
	}
	startDefault(rpcsvc)
}

// InternalRetryDefaultInit can be used by golang services that are
// willing to perform manual initialization of cbauth (i.e. for easier
// testing). This API is subject to change and should be used only if
// really needed. Returns false if Default Authenticator was already
// initialized.
func InternalRetryDefaultInit(mgmtHostPort, user, password string) (bool, error) {
	service := filepath.Base(os.Args[0])
	return InternalRetryDefaultInitWithService(service, mgmtHostPort, user, password)
}

func InternalRetryDefaultInitWithService(service, mgmtHostPort, user, password string) (bool, error) {
	if Default != nil {
		return false, nil
	}
	serviceName := service + "-cbauth"
	host, port, err := SplitHostPort(mgmtHostPort)
	if err != nil {
		return false, nil
	}
	baseurl := fmt.Sprintf("http://%s:%d/%s", host, port, serviceName)
	u, err := url.Parse(baseurl)
	if err != nil {
		return false, fmt.Errorf("Failed to parse constructed url `%s': %s", baseurl, err)
	}
	u.User = url.UserPassword(user, password)

	startDefault(revrpc.MustService(u.String()))

	return true, nil
}

// ErrNotInitialized is used to signal that ns_server environment
// variables are not set, and thus Default authenticator is not
// configured for calls that use default authenticator.
var ErrNotInitialized = errors.New("cbauth was not initialized")

// WithDefault calls given body with default authenticator. If default
// authenticator is not configured, it returns ErrNotInitialized.
func WithDefault(body func(a Authenticator) error) error {
	return WithAuthenticator(nil, body)
}

// WithAuthenticator calls given body with either passed authenticator
// or default authenticator if `a' is nil. ErrNotInitialized is
// returned if a is nil and default authenticator is not configured.
func WithAuthenticator(a Authenticator, body func(a Authenticator) error) error {
	if a == nil {
		a = Default
		if a == nil {
			return ErrNotInitialized
		}
	}
	return body(a)
}

// AuthWebCreds method extracts credentials from given http request
// using default authenticator.
func AuthWebCreds(req *http.Request) (creds Creds, err error) {
	if Default == nil {
		return nil, ErrNotInitialized
	}
	return Default.AuthWebCreds(req)
}

// Auth method constructs credentials from given user and password
// pair. Uses default authenticator.
func Auth(user, pwd string) (creds Creds, err error) {
	if Default == nil {
		return nil, ErrNotInitialized
	}
	return Default.Auth(user, pwd)
}

// GetHTTPServiceAuth returns user/password creds giving "admin"
// access to given http service inside couchbase cluster. Uses default
// authenticator.
func GetHTTPServiceAuth(hostport string) (user, pwd string, err error) {
	if Default == nil {
		return "", "", ErrNotInitialized
	}
	return Default.GetHTTPServiceAuth(hostport)
}

// GetMemcachedServiceAuth returns user/password creds given "admin"
// access to given memcached service. Uses default authenticator.
func GetMemcachedServiceAuth(hostport string) (user, pwd string, err error) {
	if Default == nil {
		return "", "", ErrNotInitialized
	}
	return Default.GetMemcachedServiceAuth(hostport)
}
<|endoftext|>


<commit_before>package momos

import (
	"strings"
	"testing"

	"github.com/PuerkitoBio/goquery"
	"github.com/nats-io/nuid"
	"github.com/stretchr/testify/assert"
)

func TestCreateElement(t *testing.T) {

	html := `
	<ssi
	name="basket"
	timeout="2000"
	template="true"
	src="http://localhost:8081">
		Default content!

		<ssi-timeout>
		Please try it again! {{.DateLocal}}
		</ssi-timeout>

		<ssi-error>
		Please call the support!
		</ssi-error>
	</ssi>
	`

	r := strings.NewReader(html)
	doc, _ := goquery.NewDocumentFromReader(r)
	element := doc.Find("ssi")
	se := SSIElement{Element: element}

	se.SetTimeout(element.AttrOr("timeout", "2000"))
	se.SetSrc(element.AttrOr("src", ""))
	se.SetName(element.AttrOr("name", nuid.Next()))
	se.SetTemplate(element.AttrOr("template", "false"))
	se.SetFilterIncludes(element.AttrOr("no-scripts", "true"))

	assert.Equal(t, se.timeout.String(), "2s", "should be 2s")
	assert.Equal(t, se.name, "basket", "should be the name of the name attribute")
	assert.Equal(t, se.hasTemplate, true, "should be the timeout of the timeout attribute")
	assert.Equal(t, se.src, "http://localhost:8081", "should be the url from url attribute")
}

func TestReplaceWithDefaultHTML(t *testing.T) {

	html := `
	<ssi
	name="basket"
	timeout="2000"
	template="true"
	src="http://localhost:8081">
		Default content!

		<ssi-timeout>
		Please try it again! {{.DateLocal}}
		</ssi-timeout>

		<ssi-error>
		Please call the support!
		</ssi-error>
	</ssi>
	`

	r := strings.NewReader(html)
	doc, _ := goquery.NewDocumentFromReader(r)
	element := doc.Find("ssi")
	se := SSIElement{Element: element}

	se.SetTimeout(element.AttrOr("timeout", "2000"))
	se.SetSrc(element.AttrOr("src", ""))
	se.SetName(element.AttrOr("name", nuid.Next()))
	se.SetTemplate(element.AttrOr("template", "false"))
	se.SetFilterIncludes(element.AttrOr("no-scripts", "true"))

	assert.Equal(t, se.timeout.String(), "2s", "should be 2s")
	assert.Equal(t, se.name, "basket", "should be the name of the name attribute")
	assert.Equal(t, se.hasTemplate, true, "should be the timeout of the timeout attribute")
	assert.Equal(t, se.src, "http://localhost:8081", "should be the url from url attribute")

	se.replaceWithDefaultHTML()

	html, _ = doc.Html()
	assert.Equal(t, html, "\n\t\tDefault content!\n\t\t\n\t\t\n\t\t\n\t\t\n\t\n\t", "should contain the default html")
}
func TestReplaceWithErrorHTML(t *testing.T) {

	html := `
		<ssi
		name="basket"
		timeout="2000"
		template="true"
		src="http://localhost:8081">
			Default content!

			<ssi-timeout>
			Please try it again! {{.DateLocal}}
			</ssi-timeout>

			<ssi-error>
			Please call the support!
			</ssi-error>
		</ssi>
		`

	r := strings.NewReader(html)
	doc, _ := goquery.NewDocumentFromReader(r)
	element := doc.Find("ssi")
	se := SSIElement{Element: element}

	se.SetTimeout(element.AttrOr("timeout", "2000"))
	se.SetSrc(element.AttrOr("src", ""))
	se.SetName(element.AttrOr("name", nuid.Next()))
	se.SetTemplate(element.AttrOr("template", "false"))
	se.SetFilterIncludes(element.AttrOr("no-scripts", "true"))

	assert.Equal(t, se.timeout.String(), "2s", "should be 2s")
	assert.Equal(t, se.name, "basket", "should be the name of the name attribute")
	assert.Equal(t, se.hasTemplate, true, "should be the timeout of the timeout attribute")
	assert.Equal(t, se.src, "http://localhost:8081", "should be the url from url attribute")

	se.GetErrorTag()

	assert.Equal(t, se.HasErrorTag, true, "should be true")

	se.replaceWithErrorHTML()

	html, _ = doc.Html()
	assert.Equal(t, html, "\n\t\t\tPlease call the support!\n\t\t\t\n\t\t", "should contain the default html")
}

func TestReplaceWithTimeoutHTML(t *testing.T) {

	html := `
	<ssi
	name="basket"
	timeout="2000"
	template="true"
	src="http://localhost:8081">
		Default content!

		<ssi-timeout>
		Please try it again! {{.DateLocal}}
		</ssi-timeout>

		<ssi-error>
		Please call the support!
		</ssi-error>
	</ssi>
	`

	r := strings.NewReader(html)
	doc, _ := goquery.NewDocumentFromReader(r)
	element := doc.Find("ssi")
	se := SSIElement{Element: element}

	se.SetTimeout(element.AttrOr("timeout", "2000"))
	se.SetSrc(element.AttrOr("src", ""))
	se.SetName(element.AttrOr("name", nuid.Next()))
	se.SetTemplate(element.AttrOr("template", "false"))
	se.SetFilterIncludes(element.AttrOr("no-scripts", "true"))

	assert.Equal(t, se.timeout.String(), "2s", "should be 2s")
	assert.Equal(t, se.name, "basket", "should be the name of the name attribute")
	assert.Equal(t, se.hasTemplate, true, "should be the timeout of the timeout attribute")
	assert.Equal(t, se.src, "http://localhost:8081", "should be the url from url attribute")

	se.GetTimeoutTag()

	assert.Equal(t, se.HasTimeoutTag, true, "should be true")

	se.replaceWithTimeoutHTML()

	html, _ = doc.Html()
	assert.Equal(t, html, "\n\t\tPlease try it again! \n\t\t\n\t", "should contain the default html")
}
<commit_msg>improve tests<commit_after>package momos

import (
	"strings"
	"testing"

	"github.com/PuerkitoBio/goquery"
	"github.com/nats-io/nuid"
	"github.com/stretchr/testify/assert"
)

var html = "<ssi name=\"basket\" timeout=\"2000\" template=\"true\" src=\"http://localhost:8081\">Default content!<ssi-timeout>Please try it again!{{.DateLocal}}</ssi-timeout><ssi-error>Please call the support!</ssi-error></ssi>"

func TestCreateElement(t *testing.T) {

	r := strings.NewReader(html)
	doc, _ := goquery.NewDocumentFromReader(r)
	element := doc.Find("ssi")
	se := SSIElement{Element: element}

	se.SetTimeout(element.AttrOr("timeout", "2000"))
	se.SetSrc(element.AttrOr("src", ""))
	se.SetName(element.AttrOr("name", nuid.Next()))
	se.SetTemplate(element.AttrOr("template", "false"))
	se.SetFilterIncludes(element.AttrOr("no-scripts", "true"))

	assert.Equal(t, se.timeout.String(), "2s", "should be 2s")
	assert.Equal(t, se.name, "basket", "should be the name of the name attribute")
	assert.Equal(t, se.hasTemplate, true, "should be the timeout of the timeout attribute")
	assert.Equal(t, se.src, "http://localhost:8081", "should be the url from url attribute")
}

func TestReplaceWithDefaultHTML(t *testing.T) {

	r := strings.NewReader(html)
	doc, _ := goquery.NewDocumentFromReader(r)
	element := doc.Find("ssi")
	se := SSIElement{Element: element}

	se.SetTimeout(element.AttrOr("timeout", "2000"))
	se.SetSrc(element.AttrOr("src", ""))
	se.SetName(element.AttrOr("name", nuid.Next()))
	se.SetTemplate(element.AttrOr("template", "false"))
	se.SetFilterIncludes(element.AttrOr("no-scripts", "true"))

	assert.Equal(t, se.timeout.String(), "2s", "should be 2s")
	assert.Equal(t, se.name, "basket", "should be the name of the name attribute")
	assert.Equal(t, se.hasTemplate, true, "should be the timeout of the timeout attribute")
	assert.Equal(t, se.src, "http://localhost:8081", "should be the url from url attribute")

	se.replaceWithDefaultHTML()

	h, _ := doc.Html()
	assert.Equal(t, h, "Default content!", "should contain the default html")
}
func TestReplaceWithErrorHTML(t *testing.T) {

	r := strings.NewReader(html)
	doc, _ := goquery.NewDocumentFromReader(r)
	element := doc.Find("ssi")
	se := SSIElement{Element: element}

	se.SetTimeout(element.AttrOr("timeout", "2000"))
	se.SetSrc(element.AttrOr("src", ""))
	se.SetName(element.AttrOr("name", nuid.Next()))
	se.SetTemplate(element.AttrOr("template", "false"))
	se.SetFilterIncludes(element.AttrOr("no-scripts", "true"))

	assert.Equal(t, se.timeout.String(), "2s", "should be 2s")
	assert.Equal(t, se.name, "basket", "should be the name of the name attribute")
	assert.Equal(t, se.hasTemplate, true, "should be the timeout of the timeout attribute")
	assert.Equal(t, se.src, "http://localhost:8081", "should be the url from url attribute")

	se.GetErrorTag()

	assert.Equal(t, se.HasErrorTag, true, "should be true")

	se.replaceWithErrorHTML()

	h, _ := doc.Html()
	assert.Equal(t, h, "Please call the support!", "should contain the default html")
}

func TestReplaceWithTimeoutHTML(t *testing.T) {

	r := strings.NewReader(html)
	doc, _ := goquery.NewDocumentFromReader(r)
	element := doc.Find("ssi")
	se := SSIElement{Element: element}

	se.SetTimeout(element.AttrOr("timeout", "2000"))
	se.SetSrc(element.AttrOr("src", ""))
	se.SetName(element.AttrOr("name", nuid.Next()))
	se.SetTemplate(element.AttrOr("template", "false"))
	se.SetFilterIncludes(element.AttrOr("no-scripts", "true"))

	assert.Equal(t, se.timeout.String(), "2s", "should be 2s")
	assert.Equal(t, se.name, "basket", "should be the name of the name attribute")
	assert.Equal(t, se.hasTemplate, true, "should be the timeout of the timeout attribute")
	assert.Equal(t, se.src, "http://localhost:8081", "should be the url from url attribute")

	se.GetTimeoutTag()

	assert.Equal(t, se.HasTimeoutTag, true, "should be true")

	se.replaceWithTimeoutHTML()

	h, _ := doc.Html()
	assert.Equal(t, h, "Please try it again!", "should contain the default html")
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/rand"
	"crypto/rsa"
	"fmt"
	"io/ioutil"
	"math/big"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"strconv"
	"strings"
)

const (
	rStudioPubKeyURL = "http://localhost:8787/auth-public-key"
	rStudioLoginURL  = "http://localhost:8787/auth-do-sign-in"
	userAgent        = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0"
)

func getPubkey() (*rsa.PublicKey, error) {
	req, err := http.NewRequest("GET", rStudioPubKeyURL, nil)
	if err != nil {
		return nil, err
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("Failed to get pubkey from %s", rStudioPubKeyURL)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	pubkey, err := parsePubkey(string(body))
	if err != nil {
		return nil, err
	}
	return pubkey, nil
}

// parsePubkey parses the string returned by RStudio server
// The string is like this: 010001:DB1E3A8360F...
func parsePubkey(pubkey string) (*rsa.PublicKey, error) {
	s := strings.Split(pubkey, ":")
	if len(s) != 2 {
		return nil, fmt.Errorf("The format of the pubkey is wrong: %s", pubkey)
	}
	publicExponent, err := strconv.ParseInt(s[0], 16, 0)
	if err != nil {
		return nil, err
	}
	modulus := new(big.Int)
	_, success := modulus.SetString(s[1], 16)
	if !success {
		return nil, fmt.Errorf("Failed to parse modulus: %s", s[1])
	}
	return &rsa.PublicKey{N: modulus, E: int(publicExponent)}, nil
}

func login(username, password string, pubkey *rsa.PublicKey) (string, error) {
	form := url.Values{}
	form.Add("persist", "0")
	form.Add("appUri", "")
	form.Add("clientPath", "")

	v, err := rsa.EncryptPKCS1v15(rand.Reader, pubkey, []byte(username+"\n"+password))
	if err != nil {
		return "", err
	}
	form.Add("v", string(v))

	req, err := http.NewRequest("POST", rStudioLoginURL, strings.NewReader(form.Encode()))
	if err != nil {
		return "", err
	}

	req.Header.Set("User-Agent", userAgent)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	jar, _ := cookiejar.New(nil)
	client := http.Client{Jar: jar}

	resp, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	setCookieHeader := resp.Header.Get("Set-Cookie")
	if resp.StatusCode != 302 || setCookieHeader == "" {
		fmt.Printf("%#v", resp.Request)
		fmt.Printf("%#v", resp)
		fmt.Printf("%#v", jar)
		return "", fmt.Errorf("Failed to login!")
	}

	return setCookieHeader, nil
}
<commit_msg>add messages<commit_after>package main

import (
	"crypto/rand"
	"crypto/rsa"
	"fmt"
	"io/ioutil"
	"math/big"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"strconv"
	"strings"
)

const (
	rStudioPubKeyURL = "http://localhost:8787/auth-public-key"
	rStudioLoginURL  = "http://localhost:8787/auth-do-sign-in"
	userAgent        = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0"
)

func getPubkey() (*rsa.PublicKey, error) {
	req, err := http.NewRequest("GET", rStudioPubKeyURL, nil)
	if err != nil {
		return nil, err
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("Failed to get pubkey from %s", rStudioPubKeyURL)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	pubkey, err := parsePubkey(string(body))
	if err != nil {
		return nil, err
	}
	return pubkey, nil
}

// parsePubkey parses the string returned by RStudio server
// The string is like this: 010001:DB1E3A8360F...
func parsePubkey(pubkey string) (*rsa.PublicKey, error) {
	s := strings.Split(pubkey, ":")
	if len(s) != 2 {
		return nil, fmt.Errorf("The format of the pubkey is wrong: %s", pubkey)
	}
	publicExponent, err := strconv.ParseInt(s[0], 16, 0)
	if err != nil {
		return nil, err
	}
	modulus := new(big.Int)
	_, success := modulus.SetString(s[1], 16)
	if !success {
		return nil, fmt.Errorf("Failed to parse modulus: %s", s[1])
	}
	return &rsa.PublicKey{N: modulus, E: int(publicExponent)}, nil
}

func login(username, password string, pubkey *rsa.PublicKey) (string, error) {
	form := url.Values{}
	form.Add("persist", "0")
	form.Add("appUri", "")
	form.Add("clientPath", "")

	v, err := rsa.EncryptPKCS1v15(rand.Reader, pubkey, []byte(username+"\n"+password))
	if err != nil {
		return "", err
	}
	form.Add("v", string(v))

	fmt.Printf("username: %s, password: %s", username, password)

	req, err := http.NewRequest("POST", rStudioLoginURL, strings.NewReader(form.Encode()))
	if err != nil {
		return "", err
	}

	req.Header.Set("User-Agent", userAgent)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	jar, _ := cookiejar.New(nil)
	client := http.Client{Jar: jar}

	fmt.Printf("Attempting to login with parameters: %#v", form)

	resp, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	setCookieHeader := resp.Header.Get("Set-Cookie")
	if resp.StatusCode != 302 || setCookieHeader == "" {
		fmt.Printf("Requst: %#v\n", resp.Request)
		fmt.Printf("Response: %#v\n", resp)
		fmt.Printf("Cookies: %#v\n", jar)
		return "", fmt.Errorf("Failed to login!")
	}

	return setCookieHeader, nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2014-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

// Returns a bitmask of possible Bishop moves from the given square.
func (p *Position) bishopMoves(square int) Bitmask {
	return p.bishopMovesAt(square, p.board)
}

// Returns a bitmask of possible Rook moves from the given square.
func (p *Position) rookMoves(square int) Bitmask {
	return p.rookMovesAt(square, p.board)
}

// Returns a bitmask of possible Bishop moves from the given square wherees
// other pieces on the board are represented by the explicit parameter.
func (p *Position) bishopMovesAt(square int, board Bitmask) Bitmask {
	magic := ((bishopMagic[square].mask & board) * bishopMagic[square].magic) >> 55
	return bishopMagicMoves[square][magic]
}

// Returns a bitmask of possible Rook moves from the given square wherees other
// pieces on the board are represented by the explicit parameter.
func (p *Position) rookMovesAt(square int, board Bitmask) Bitmask {
	magic := ((rookMagic[square].mask & board) * rookMagic[square].magic) >> 52
	return rookMagicMoves[square][magic]
}

func (p *Position) targets(square int) Bitmask {
	return p.targetsFor(square, p.pieces[square])
}

func (p *Position) targetsFor(square int, piece Piece) (bitmask Bitmask) {
	switch kind, color := piece.kind(), piece.color(); kind {
	case Pawn:
		// Start with one square push, then try the second square.
		empty := ^p.board
		if color == White {
			bitmask |= (bit[square] << 8) & empty
			bitmask |= (bitmask << 8) & empty & maskRank[3]
		} else {
			bitmask |= (bit[square] >> 8) & empty
			bitmask |= (bitmask >> 8) & empty & maskRank[4]
		}
		bitmask |= pawnMoves[color][square] & p.outposts[color^1]

		// If the last move set the en-passant square and it is diagonally adjacent
		// to the current pawn, then add en-passant to the pawn's attack targets.
		if p.enpassant != 0 && maskPawn[color][p.enpassant].on(square) {
			bitmask |= bit[p.enpassant]
		}
	case Knight:
		bitmask = knightMoves[square] & ^p.outposts[color]
	case Bishop:
		bitmask = p.bishopMoves(square) & ^p.outposts[color]
	case Rook:
		bitmask = p.rookMoves(square) & ^p.outposts[color]
	case Queen:
		bitmask = (p.bishopMoves(square) | p.rookMoves(square)) & ^p.outposts[color]
	case King:
		bitmask = kingMoves[square] & ^p.outposts[color]
	}
	return
}

func (p *Position) attacks(square int) Bitmask {
	return p.attacksFor(square, p.pieces[square])
}

func (p *Position) attacksFor(square int, piece Piece) (bitmask Bitmask) {
	switch kind, color := piece.kind(), piece.color(); kind {
	case Pawn:
		return pawnMoves[color][square]
	case Knight:
		return knightMoves[square]
	case Bishop:
		return p.bishopMoves(square)
	case Rook:
		return p.rookMoves(square)
	case Queen:
		return p.bishopMoves(square) | p.rookMoves(square)
	case King:
		return kingMoves[square]
	}
	return
}

func (p *Position) xrayAttacks(square int) Bitmask {
	return p.xrayAttacksFor(square, p.pieces[square])
}

func (p *Position) xrayAttacksFor(square int, piece Piece) (bitmask Bitmask) {
	switch kind, color := piece.kind(), piece.color(); kind {
	case Bishop:
		board := p.board ^ p.outposts[queen(color)]
		return p.bishopMovesAt(square, board)
	case Rook:
		board := p.board ^ p.outposts[rook(color)] ^ p.outposts[queen(color)]
		return p.rookMovesAt(square, board)
	}
	return p.attacksFor(square, piece)
}

func (p *Position) allAttacks(color uint8) (bitmask Bitmask) {
	bitmask = p.pawnAttacks(color) | p.knightAttacks(color) | p.kingAttacks(color)

	outposts := p.outposts[bishop(color)] | p.outposts[queen(color)]
	for outposts != 0 {
		bitmask |= p.bishopMoves(outposts.pop())
	}

	outposts = p.outposts[rook(color)] | p.outposts[queen(color)]
	for outposts != 0 {
		bitmask |= p.rookMoves(outposts.pop())
	}
	return
}

// Returns a bitmask of pieces that attack given square. The resulting bitmask
// only counts pieces of requested color.
//
// This method is used in static exchange evaluation so instead of using current
// board bitmask (p.board) we pass the one that gets continuously updated during
// the evaluation.
func (p *Position) attackers(color uint8, square int, board Bitmask) Bitmask {
	attackers := knightMoves[square] & p.outposts[knight(color)]
	attackers |= maskPawn[color][square] & p.outposts[pawn(color)]
	attackers |= kingMoves[square] & p.outposts[king(color)]
	attackers |= p.rookMovesAt(square, board) & (p.outposts[rook(color)] | p.outposts[queen(color)])
	attackers |= p.bishopMovesAt(square, board) & (p.outposts[bishop(color)] | p.outposts[queen(color)])

	return attackers
}

func (p *Position) isAttacked(color uint8, square int) bool {
	return (knightMoves[square] & p.outposts[knight(color)]) != 0 ||
	       (maskPawn[color][square] & p.outposts[pawn(color)]) != 0 ||
	       (kingMoves[square] & p.outposts[king(color)]) != 0 ||
	       (p.rookMoves(square) & (p.outposts[rook(color)] | p.outposts[queen(color)])) != 0 ||
	       (p.bishopMoves(square) & (p.outposts[bishop(color)] | p.outposts[queen(color)])) != 0
}

func (p *Position) pawnAttacks(color uint8) (bitmask Bitmask) {
	if color == White {
		bitmask = (p.outposts[Pawn] & ^maskFile[0]) << 7
		bitmask |= (p.outposts[Pawn] & ^maskFile[7]) << 9
	} else {
		bitmask = (p.outposts[BlackPawn] & ^maskFile[0]) >> 9
		bitmask |= (p.outposts[BlackPawn] & ^maskFile[7]) >> 7
	}
	return
}

func (p *Position) knightAttacks(color uint8) (bitmask Bitmask) {
	outposts := p.outposts[knight(color)]
	for outposts != 0 {
		bitmask |= knightMoves[outposts.pop()]
	}
	return
}

func (p *Position) bishopAttacks(color uint8) (bitmask Bitmask) {
	outposts := p.outposts[bishop(color)]
	for outposts != 0 {
		bitmask |= p.bishopMoves(outposts.pop())
	}
	return
}

func (p *Position) rookAttacks(color uint8) (bitmask Bitmask) {
	outposts := p.outposts[rook(color)]
	for outposts != 0 {
		bitmask |= p.rookMoves(outposts.pop())
	}
	return
}

func (p *Position) queenAttacks(color uint8) (bitmask Bitmask) {
	outposts := p.outposts[queen(color)]
	for outposts != 0 {
		square := outposts.pop()
		bitmask |= p.rookMoves(square) | p.bishopMoves(square)
	}
	return
}

func (p *Position) kingAttacks(color uint8) Bitmask {
	return kingMoves[p.king[color]]
}

func (p *Position) strongestPiece(color uint8, targets Bitmask) Piece {
	if targets & p.outposts[queen(color)] != 0 {
		return queen(color)
	}
	if targets & p.outposts[rook(color)] != 0 {
		return rook(color)
	}
	if targets & p.outposts[bishop(color)] != 0 {
		return bishop(color)
	}
	if targets & p.outposts[knight(color)] != 0 {
		return knight(color)
	}
	if targets & p.outposts[pawn(color)] != 0 {
		return pawn(color)
	}
	return Piece(0)
}
<commit_msg>Minor refactoring<commit_after>// Copyright (c) 2014-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

// Returns a bitmask of possible Bishop moves from the given square.
func (p *Position) bishopMoves(square int) Bitmask {
	return p.bishopMovesAt(square, p.board)
}

// Returns a bitmask of possible Rook moves from the given square.
func (p *Position) rookMoves(square int) Bitmask {
	return p.rookMovesAt(square, p.board)
}

// Returns a bitmask of possible Bishop moves from the given square wherees
// other pieces on the board are represented by the explicit parameter.
func (p *Position) bishopMovesAt(square int, board Bitmask) Bitmask {
	magic := ((bishopMagic[square].mask & board) * bishopMagic[square].magic) >> 55
	return bishopMagicMoves[square][magic]
}

// Returns a bitmask of possible Rook moves from the given square wherees other
// pieces on the board are represented by the explicit parameter.
func (p *Position) rookMovesAt(square int, board Bitmask) Bitmask {
	magic := ((rookMagic[square].mask & board) * rookMagic[square].magic) >> 52
	return rookMagicMoves[square][magic]
}

func (p *Position) targets(square int) Bitmask {
	return p.targetsFor(square, p.pieces[square])
}

func (p *Position) targetsFor(square int, piece Piece) (bitmask Bitmask) {
	color := piece.color()
	if piece.isPawn() {
		// Start with one square push, then try the second square.
		empty := ^p.board
		if color == White {
			bitmask |= (bit[square] << 8) & empty
			bitmask |= (bitmask << 8) & empty & maskRank[3]
		} else {
			bitmask |= (bit[square] >> 8) & empty
			bitmask |= (bitmask >> 8) & empty & maskRank[4]
		}
		bitmask |= pawnMoves[color][square] & p.outposts[color^1]

		// If the last move set the en-passant square and it is diagonally adjacent
		// to the current pawn, then add en-passant to the pawn's attack targets.
		if p.enpassant != 0 && maskPawn[color][p.enpassant].on(square) {
			bitmask |= bit[p.enpassant]
		}
	} else {
		bitmask = p.attacksFor(square, piece) & ^p.outposts[color]
	}
	return
}

func (p *Position) attacks(square int) Bitmask {
	return p.attacksFor(square, p.pieces[square])
}

func (p *Position) attacksFor(square int, piece Piece) (bitmask Bitmask) {
	switch kind, color := piece.kind(), piece.color(); kind {
	case Pawn:
		return pawnMoves[color][square]
	case Knight:
		return knightMoves[square]
	case Bishop:
		return p.bishopMoves(square)
	case Rook:
		return p.rookMoves(square)
	case Queen:
		return p.bishopMoves(square) | p.rookMoves(square)
	case King:
		return kingMoves[square]
	}
	return
}

func (p *Position) xrayAttacks(square int) Bitmask {
	return p.xrayAttacksFor(square, p.pieces[square])
}

func (p *Position) xrayAttacksFor(square int, piece Piece) (bitmask Bitmask) {
	switch kind, color := piece.kind(), piece.color(); kind {
	case Bishop:
		board := p.board ^ p.outposts[queen(color)]
		return p.bishopMovesAt(square, board)
	case Rook:
		board := p.board ^ p.outposts[rook(color)] ^ p.outposts[queen(color)]
		return p.rookMovesAt(square, board)
	}
	return p.attacksFor(square, piece)
}

func (p *Position) allAttacks(color uint8) (bitmask Bitmask) {
	bitmask = p.pawnAttacks(color) | p.knightAttacks(color) | p.kingAttacks(color)

	outposts := p.outposts[bishop(color)] | p.outposts[queen(color)]
	for outposts != 0 {
		bitmask |= p.bishopMoves(outposts.pop())
	}

	outposts = p.outposts[rook(color)] | p.outposts[queen(color)]
	for outposts != 0 {
		bitmask |= p.rookMoves(outposts.pop())
	}
	return
}

// Returns a bitmask of pieces that attack given square. The resulting bitmask
// only counts pieces of requested color.
//
// This method is used in static exchange evaluation so instead of using current
// board bitmask (p.board) we pass the one that gets continuously updated during
// the evaluation.
func (p *Position) attackers(color uint8, square int, board Bitmask) (attackers Bitmask) {
	attackers  = knightMoves[square] & p.outposts[knight(color)]
	attackers |= maskPawn[color][square] & p.outposts[pawn(color)]
	attackers |= kingMoves[square] & p.outposts[king(color)]
	attackers |= p.rookMovesAt(square, board) & (p.outposts[rook(color)] | p.outposts[queen(color)])
	attackers |= p.bishopMovesAt(square, board) & (p.outposts[bishop(color)] | p.outposts[queen(color)])
	return
}

func (p *Position) isAttacked(color uint8, square int) bool {
	return (knightMoves[square] & p.outposts[knight(color)]) != 0 ||
	       (maskPawn[color][square] & p.outposts[pawn(color)]) != 0 ||
	       (kingMoves[square] & p.outposts[king(color)]) != 0 ||
	       (p.rookMoves(square) & (p.outposts[rook(color)] | p.outposts[queen(color)])) != 0 ||
	       (p.bishopMoves(square) & (p.outposts[bishop(color)] | p.outposts[queen(color)])) != 0
}

func (p *Position) pawnAttacks(color uint8) (bitmask Bitmask) {
	if color == White {
		bitmask = (p.outposts[Pawn] & ^maskFile[0]) << 7
		bitmask |= (p.outposts[Pawn] & ^maskFile[7]) << 9
	} else {
		bitmask = (p.outposts[BlackPawn] & ^maskFile[0]) >> 9
		bitmask |= (p.outposts[BlackPawn] & ^maskFile[7]) >> 7
	}
	return
}

func (p *Position) knightAttacks(color uint8) (bitmask Bitmask) {
	outposts := p.outposts[knight(color)]
	for outposts != 0 {
		bitmask |= knightMoves[outposts.pop()]
	}
	return
}

func (p *Position) bishopAttacks(color uint8) (bitmask Bitmask) {
	outposts := p.outposts[bishop(color)]
	for outposts != 0 {
		bitmask |= p.bishopMoves(outposts.pop())
	}
	return
}

func (p *Position) rookAttacks(color uint8) (bitmask Bitmask) {
	outposts := p.outposts[rook(color)]
	for outposts != 0 {
		bitmask |= p.rookMoves(outposts.pop())
	}
	return
}

func (p *Position) queenAttacks(color uint8) (bitmask Bitmask) {
	outposts := p.outposts[queen(color)]
	for outposts != 0 {
		square := outposts.pop()
		bitmask |= p.rookMoves(square) | p.bishopMoves(square)
	}
	return
}

func (p *Position) kingAttacks(color uint8) Bitmask {
	return kingMoves[p.king[color]]
}

func (p *Position) strongestPiece(color uint8, targets Bitmask) Piece {
	if targets & p.outposts[queen(color)] != 0 {
		return queen(color)
	}
	if targets & p.outposts[rook(color)] != 0 {
		return rook(color)
	}
	if targets & p.outposts[bishop(color)] != 0 {
		return bishop(color)
	}
	if targets & p.outposts[knight(color)] != 0 {
		return knight(color)
	}
	if targets & p.outposts[pawn(color)] != 0 {
		return pawn(color)
	}
	return Piece(0)
}
<|endoftext|>


<commit_before>// Copyright 2015 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 power64asm

import (
	"fmt"
	"strings"
)

// plan9Syntax returns the Go assembler syntax for the instruction.
// The syntax was originally defined by Plan 9.
// The pc is the program counter of the first instruction, used for expanding
// PC-relative addresses into absolute ones.
// The symname function queries the symbol table for the program
// being disassembled. It returns the name and base address of the symbol
// containing the target, if any; otherwise it returns "", 0.
func plan9Syntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string {
	if symname == nil {
		symname = func(uint64) (string, uint64) { return "", 0 }
	}
	if inst.Op == 0 {
		return "?"
	}
	var args []string
	for i, a := range inst.Args[:] {
		if a == nil {
			break
		}
		if s := plan9Arg(&inst, i, pc, a, symname); s != "" {
			args = append(args, s)
		}
	}
	var op string
	op = plan9OpMap[inst.Op]
	if op == "" {
		op = strings.ToUpper(inst.Op.String())
	}
	// laid out the instruction
	switch inst.Op {
	default: // dst, sA, sB, ...
		if len(args) == 0 {
			return op
		} else if len(args) == 1 {
			return fmt.Sprintf("%s %s", op, args[0])
		}
		args = append(args, args[0])
		return op + " " + strings.Join(args[1:], ", ")
	// store instructions always have the memory operand at the end, no need to reorder
	case STB, STBU, STBX, STBUX,
		STH, STHU, STHX, STHUX,
		STW, STWU, STWX, STWUX,
		STD, STDU, STDX, STDUX,
		STQ,
		STHBRX, STWBRX:
		return op + " " + strings.Join(args, ", ")
	// BC instructions needs additional handling
	case BC:
		return op + " " + strings.Join(args, ", ")
	}
	panic("unreachable")
}

// plan9Arg formats arg (which is the argIndex's arg in inst) according to Plan 9 rules.
// NOTE: because Plan9Syntax is the only caller of this func, and it receives a copy
//       of inst, it's ok to modify inst.Args here.
func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64) (string, uint64)) string {
	// special cases for load/store instructions
	if _, ok := arg.(Offset); ok {
		if argIndex+1 == len(inst.Args) || inst.Args[argIndex+1] == nil {
			panic(fmt.Errorf("wrong table: offset not followed by register"))
		}
	}
	switch arg := arg.(type) {
	case Reg:
		if isLoadStoreOp(inst.Op) && argIndex == 1 && arg == R0 {
			return "0"
		}
		if arg == R30 {
			return "g"
		}
		return strings.ToUpper(arg.String())
	case CondReg:
		if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") {
			return "" // don't show cr0 for cmp instructions
		} else if arg >= CR0 {
			return fmt.Sprintf("CR%d", int(arg-CR0))
		}
		bit := [4]string{"LT", "GT", "EQ", "SO"}[(arg-Cond0LT)%4]
		if arg <= Cond0SO {
			return bit
		}
		return fmt.Sprintf("4*CR%d+%s", int(arg-Cond0LT)/4, bit)
	case Imm:
		return fmt.Sprintf("$%d", arg)
	case SpReg:
		switch arg {
		case 8:
			return "LR"
		}
		return fmt.Sprintf("SPR(%d)", int(arg))
	case PCRel:
		addr := pc + uint64(int64(arg))
		if s, base := symname(addr); s != "" && base == addr {
			return fmt.Sprintf("%s(SB)", s)
		}
		return fmt.Sprintf("%#x", addr)
	case Label:
		return fmt.Sprintf("%#x", int(arg))
	case Offset:
		reg := inst.Args[argIndex+1].(Reg)
		removeArg(inst, argIndex+1)
		if reg == R0 {
			return fmt.Sprintf("%d(0)", int(arg))
		}
		return fmt.Sprintf("%d(R%d)", int(arg), reg-R0)
	}
	return fmt.Sprintf("???(%v)", arg)
}

var plan9OpMap = map[Op]string{
	LBZ: "MOVBZ", STB: "MOVB",
	LBZU: "MOVBZU", STBU: "MOVBU", // TODO(minux): indexed forms are not handled
	LHZ: "MOVHZ", LHA: "MOVH", STH: "MOVH",
	LHZU: "MOVHZU", STHU: "MOVHU",
	LWZ: "MOVWZ", LWA: "MOVW", STW: "MOVW",
	LWZU: "MOVWZU", STWU: "MOVWU",
	LD: "MOVD", STD: "MOVD",
	LDU: "MOVDU", STDU: "MOVDU",
	MTSPR: "MOV", MFSPR: "MOV", // the width is ambiguous for SPRs
	B:     "BR",
	CMPLD: "CMPU", CMPLW: "CMPWU",
	CMPD: "CMP", CMPW: "CMPW",
}
<commit_msg>power64asm: even more plan 9 syntax special cases<commit_after>// Copyright 2015 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 power64asm

import (
	"fmt"
	"strings"
)

// plan9Syntax returns the Go assembler syntax for the instruction.
// The syntax was originally defined by Plan 9.
// The pc is the program counter of the first instruction, used for expanding
// PC-relative addresses into absolute ones.
// The symname function queries the symbol table for the program
// being disassembled. It returns the name and base address of the symbol
// containing the target, if any; otherwise it returns "", 0.
func plan9Syntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string {
	if symname == nil {
		symname = func(uint64) (string, uint64) { return "", 0 }
	}
	if inst.Op == 0 {
		return "?"
	}
	var args []string
	for i, a := range inst.Args[:] {
		if a == nil {
			break
		}
		if s := plan9Arg(&inst, i, pc, a, symname); s != "" {
			args = append(args, s)
		}
	}
	var op string
	op = plan9OpMap[inst.Op]
	if op == "" {
		op = strings.ToUpper(inst.Op.String())
	}
	// laid out the instruction
	switch inst.Op {
	default: // dst, sA, sB, ...
		if len(args) == 0 {
			return op
		} else if len(args) == 1 {
			return fmt.Sprintf("%s %s", op, args[0])
		}
		args = append(args, args[0])
		return op + " " + strings.Join(args[1:], ", ")
	// store instructions always have the memory operand at the end, no need to reorder
	case STB, STBU, STBX, STBUX,
		STH, STHU, STHX, STHUX,
		STW, STWU, STWX, STWUX,
		STD, STDU, STDX, STDUX,
		STQ,
		STHBRX, STWBRX:
		return op + " " + strings.Join(args, ", ")
	// branch instructions needs additional handling
	case BCLR:
		if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
			return "RET"
		}
		return op + " " + strings.Join(args, ", ")
	case BC:
		if int(inst.Args[0].(Imm))&0x1c == 12 { // jump on cond bit set
			return fmt.Sprintf("B%s %s", args[1], args[2])
		} else if int(inst.Args[0].(Imm))&0x1c == 4 && revCondMap[args[1]] != "" { // jump on cond bit not set
			return fmt.Sprintf("B%s %s", revCondMap[args[1]], args[2])
		}
	case BCCTR:
		if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
			return "BR (CTR)"
		}
		return op + " " + strings.Join(args, ", ")
	case BCCTRL:
		if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
			return "BL (CTR)"
		}
		return op + " " + strings.Join(args, ", ")
	case BCA, BCL, BCLA, BCLRL, BCTAR, BCTARL:
		return op + " " + strings.Join(args, ", ")
	}
	panic("unreachable")
}

// plan9Arg formats arg (which is the argIndex's arg in inst) according to Plan 9 rules.
// NOTE: because Plan9Syntax is the only caller of this func, and it receives a copy
//       of inst, it's ok to modify inst.Args here.
func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64) (string, uint64)) string {
	// special cases for load/store instructions
	if _, ok := arg.(Offset); ok {
		if argIndex+1 == len(inst.Args) || inst.Args[argIndex+1] == nil {
			panic(fmt.Errorf("wrong table: offset not followed by register"))
		}
	}
	switch arg := arg.(type) {
	case Reg:
		if isLoadStoreOp(inst.Op) && argIndex == 1 && arg == R0 {
			return "0"
		}
		if arg == R30 {
			return "g"
		}
		return strings.ToUpper(arg.String())
	case CondReg:
		if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") {
			return "" // don't show cr0 for cmp instructions
		} else if arg >= CR0 {
			return fmt.Sprintf("CR%d", int(arg-CR0))
		}
		bit := [4]string{"LT", "GT", "EQ", "SO"}[(arg-Cond0LT)%4]
		if arg <= Cond0SO {
			return bit
		}
		return fmt.Sprintf("4*CR%d+%s", int(arg-Cond0LT)/4, bit)
	case Imm:
		return fmt.Sprintf("$%d", arg)
	case SpReg:
		switch arg {
		case 8:
			return "LR"
		case 9:
			return "CTR"
		}
		return fmt.Sprintf("SPR(%d)", int(arg))
	case PCRel:
		addr := pc + uint64(int64(arg))
		if s, base := symname(addr); s != "" && base == addr {
			return fmt.Sprintf("%s(SB)", s)
		}
		return fmt.Sprintf("%#x", addr)
	case Label:
		return fmt.Sprintf("%#x", int(arg))
	case Offset:
		reg := inst.Args[argIndex+1].(Reg)
		removeArg(inst, argIndex+1)
		if reg == R0 {
			return fmt.Sprintf("%d(0)", int(arg))
		}
		return fmt.Sprintf("%d(R%d)", int(arg), reg-R0)
	}
	return fmt.Sprintf("???(%v)", arg)
}

// revCondMap maps a conditional register bit to its inverse, if possible.
var revCondMap = map[string]string{
	"LT": "GE", "GT": "LE", "EQ": "NE",
}

// plan9OpMap maps an Op to its Plan 9 mnemonics, if different than its GNU mnemonics.
var plan9OpMap = map[Op]string{
	LBZ: "MOVBZ", STB: "MOVB",
	LBZU: "MOVBZU", STBU: "MOVBU", // TODO(minux): indexed forms are not handled
	LHZ: "MOVHZ", LHA: "MOVH", STH: "MOVH",
	LHZU: "MOVHZU", STHU: "MOVHU",
	LWZ: "MOVWZ", LWA: "MOVW", STW: "MOVW",
	LWZU: "MOVWZU", STWU: "MOVWU",
	LD: "MOVD", STD: "MOVD",
	LDU: "MOVDU", STDU: "MOVDU",
	MTSPR: "MOV", MFSPR: "MOV", // the width is ambiguous for SPRs
	B:     "BR",
	CMPLD: "CMPU", CMPLW: "CMPWU",
	CMPD: "CMP", CMPW: "CMPW",
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/flynn/flynn-host/client"
	"github.com/flynn/flynn-host/sampi"
	"github.com/flynn/flynn-host/types"
	"github.com/flynn/go-discoverd"
	"github.com/flynn/go-dockerclient"
	rpc "github.com/flynn/rpcplus/comborpc"
	"github.com/technoweenie/grohl"
)

func main() {
	externalAddr := flag.String("external", "", "external IP of host")
	configFile := flag.String("config", "", "configuration file")
	manifestFile := flag.String("manifest", "", "manifest file")
	hostID := flag.String("id", os.Getenv("HOST"), "host id")
	flag.Parse()
	grohl.AddContext("app", "lorne")
	grohl.Log(grohl.Data{"at": "start"})
	g := grohl.NewContext(grohl.Data{"fn": "main"})

	dockerc, err := docker.NewClient("unix:///var/run/docker.sock")
	if err != nil {
		log.Fatal(err)
	}

	state := NewState()
	ports := make(chan int)

	go allocatePorts(ports, 55000, 65535)
	go serveHTTP(&Host{state: state, docker: dockerc}, &attachHandler{state: state, docker: dockerc})
	go streamEvents(dockerc, state)

	processor := &jobProcessor{
		externalAddr: *externalAddr,
		docker:       dockerc,
		state:        state,
		discoverd:    os.Getenv("DISCOVERD"),
	}

	runner := &manifestRunner{
		env:        parseEnviron(),
		externalIP: *externalAddr,
		ports:      ports,
		processor:  processor,
		docker:     dockerc,
	}

	var disc *discoverd.Client
	if *manifestFile != "" {
		f, err := os.Open(*manifestFile)
		if err != nil {
			log.Fatal(err)
		}
		services, err := runner.runManifest(f)
		if err != nil {
			log.Fatal(err)
		}
		f.Close()

		if d, ok := services["discoverd"]; ok {
			processor.discoverd = fmt.Sprintf("%s:%d", d.InternalIP, d.TCPPorts[0])
			disc, err = discoverd.NewClientUsingAddress(processor.discoverd)
			if err != nil {
				log.Fatal(err)
			}
		}
	}

	if processor.discoverd == "" && *externalAddr != "" {
		processor.discoverd = *externalAddr + ":1111"
	}
	// HACK: use env as global for discoverd connection in sampic
	os.Setenv("DISCOVERD", processor.discoverd)
	if disc == nil {
		disc, err = discoverd.NewClientUsingAddress(processor.discoverd)
		if err != nil {
			log.Fatal(err)
		}
	}
	sampiStandby, err := disc.RegisterAndStandby("flynn-host", *externalAddr+":1113", map[string]string{"id": *hostID})
	if err != nil {
		log.Fatal(err)
	}
	go func() {
		<-sampiStandby
		rpc.Register(sampi.NewCluster(sampi.NewState()))
	}()

	cluster, err := client.New()
	if err != nil {
		log.Fatal(err)
	}
	g.Log(grohl.Data{"at": "sampi_connected"})

	events := make(chan host.Event)
	state.AddListener("all", events)
	go syncScheduler(cluster, events)

	var h *host.Host
	if *configFile != "" {
		h, err = openConfig(*configFile)
		if err != nil {
			log.Fatal(err)
		}
	} else {
		h = &host.Host{Resources: make(map[string]host.ResourceValue)}
	}
	if _, ok := h.Resources["memory"]; !ok {
		h.Resources["memory"] = host.ResourceValue{Value: 1024}
	}
	h.ID = *hostID

	jobs := make(chan *host.Job)
	cluster.ConnectHost(h, jobs)
	g.Log(grohl.Data{"at": "host_registered"})
	processor.Process(ports, jobs)
}

type jobProcessor struct {
	externalAddr string
	discoverd    string
	docker       interface {
		CreateContainer(*docker.Config) (*docker.Container, error)
		PullImage(docker.PullImageOptions, io.Writer) error
		StartContainer(string, *docker.HostConfig) error
	}
	state *State
}

func (p *jobProcessor) Process(ports <-chan int, jobs chan *host.Job) {
	for job := range jobs {
		p.processJob(ports, job)
	}
}

func (p *jobProcessor) processJob(ports <-chan int, job *host.Job) (*docker.Container, error) {
	g := grohl.NewContext(grohl.Data{"fn": "process_job", "job.id": job.ID})
	g.Log(grohl.Data{"at": "start", "job.image": job.Config.Image, "job.cmd": job.Config.Cmd, "job.entrypoint": job.Config.Entrypoint})

	var hostConfig *docker.HostConfig
	for i := 0; i < job.TCPPorts; i++ {
		port := strconv.Itoa(<-ports)
		if i == 0 {
			job.Config.Env = append(job.Config.Env, "PORT="+port)
		}
		job.Config.Env = append(job.Config.Env, fmt.Sprintf("PORT_%d=%s", i, port))
		if job.Config.ExposedPorts == nil {
			job.Config.ExposedPorts = make(map[string]struct{}, job.TCPPorts)
		}
		job.Config.ExposedPorts[port+"/tcp"] = struct{}{}
		if hostConfig == nil {
			hostConfig = &docker.HostConfig{
				PortBindings:    make(map[string][]docker.PortBinding, job.TCPPorts),
				PublishAllPorts: true,
			}
		}
		hostConfig.PortBindings[port+"/tcp"] = []docker.PortBinding{{HostPort: port}}
	}
	if p.externalAddr != "" {
		job.Config.Env = appendUnique(job.Config.Env, "EXTERNAL_IP="+p.externalAddr, "SD_HOST="+p.externalAddr, "DISCOVERD="+p.discoverd)
	}
	p.state.AddJob(job)
	g.Log(grohl.Data{"at": "create_container"})
	container, err := p.docker.CreateContainer(job.Config)
	if err == docker.ErrNoSuchImage {
		g.Log(grohl.Data{"at": "pull_image"})
		err = p.docker.PullImage(docker.PullImageOptions{Repository: job.Config.Image}, os.Stdout)
		if err != nil {
			g.Log(grohl.Data{"at": "pull_image", "status": "error", "err": err})
			p.state.SetStatusFailed(job.ID, err)
			return nil, err
		}
		container, err = p.docker.CreateContainer(job.Config)
	}
	if err != nil {
		g.Log(grohl.Data{"at": "create_container", "status": "error", "err": err})
		p.state.SetStatusFailed(job.ID, err)
		return nil, err
	}
	p.state.SetContainerID(job.ID, container.ID)
	p.state.WaitAttach(job.ID)
	g.Log(grohl.Data{"at": "start_container"})
	if err := p.docker.StartContainer(container.ID, hostConfig); err != nil {
		g.Log(grohl.Data{"at": "start_container", "status": "error", "err": err})
		p.state.SetStatusFailed(job.ID, err)
		return nil, err
	}
	p.state.SetStatusRunning(job.ID)
	g.Log(grohl.Data{"at": "finish"})
	return container, nil
}

func appendUnique(s []string, vars ...string) []string {
outer:
	for _, v := range vars {
		for _, existing := range s {
			if strings.HasPrefix(existing, strings.SplitN(v, "=", 2)[0]+"=") {
				continue outer
			}
		}
		s = append(s, v)
	}
	return s
}

type sampiSyncClient interface {
	RemoveJobs([]string) error
}

func syncScheduler(scheduler sampiSyncClient, events <-chan host.Event) {
	for event := range events {
		if event.Event != "stop" {
			continue
		}
		grohl.Log(grohl.Data{"fn": "scheduler_event", "at": "remove_job", "job.id": event.JobID})
		if err := scheduler.RemoveJobs([]string{event.JobID}); err != nil {
			grohl.Log(grohl.Data{"fn": "scheduler_event", "at": "remove_job", "status": "error", "err": err, "job.id": event.JobID})
			// TODO: try to reconnect?
		}
	}
}

type dockerStreamClient interface {
	Events() (*docker.EventStream, error)
	InspectContainer(string) (*docker.Container, error)
}

func streamEvents(client dockerStreamClient, state *State) {
	stream, err := client.Events()
	if err != nil {
		log.Fatal(err)
	}
	for event := range stream.Events {
		if event.Status != "die" {
			continue
		}
		container, err := client.InspectContainer(event.ID)
		if err != nil {
			log.Println("inspect container", event.ID, "error:", err)
			// TODO: set job status anyway?
			continue
		}
		state.SetStatusDone(event.ID, container.State.ExitCode)
	}
}

// TODO: fix this, horribly broken

func allocatePorts(ports chan<- int, startPort, endPort int) {
	for i := startPort; i < endPort; i++ {
		ports <- i
	}
	// TODO: handle wrap-around
}
<commit_msg>host: Log ConnectHost errors<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/flynn/flynn-host/client"
	"github.com/flynn/flynn-host/sampi"
	"github.com/flynn/flynn-host/types"
	"github.com/flynn/go-discoverd"
	"github.com/flynn/go-dockerclient"
	rpc "github.com/flynn/rpcplus/comborpc"
	"github.com/technoweenie/grohl"
)

func main() {
	externalAddr := flag.String("external", "", "external IP of host")
	configFile := flag.String("config", "", "configuration file")
	manifestFile := flag.String("manifest", "", "manifest file")
	hostID := flag.String("id", os.Getenv("HOST"), "host id")
	flag.Parse()
	grohl.AddContext("app", "lorne")
	grohl.Log(grohl.Data{"at": "start"})
	g := grohl.NewContext(grohl.Data{"fn": "main"})

	dockerc, err := docker.NewClient("unix:///var/run/docker.sock")
	if err != nil {
		log.Fatal(err)
	}

	state := NewState()
	ports := make(chan int)

	go allocatePorts(ports, 55000, 65535)
	go serveHTTP(&Host{state: state, docker: dockerc}, &attachHandler{state: state, docker: dockerc})
	go streamEvents(dockerc, state)

	processor := &jobProcessor{
		externalAddr: *externalAddr,
		docker:       dockerc,
		state:        state,
		discoverd:    os.Getenv("DISCOVERD"),
	}

	runner := &manifestRunner{
		env:        parseEnviron(),
		externalIP: *externalAddr,
		ports:      ports,
		processor:  processor,
		docker:     dockerc,
	}

	var disc *discoverd.Client
	if *manifestFile != "" {
		f, err := os.Open(*manifestFile)
		if err != nil {
			log.Fatal(err)
		}
		services, err := runner.runManifest(f)
		if err != nil {
			log.Fatal(err)
		}
		f.Close()

		if d, ok := services["discoverd"]; ok {
			processor.discoverd = fmt.Sprintf("%s:%d", d.InternalIP, d.TCPPorts[0])
			disc, err = discoverd.NewClientUsingAddress(processor.discoverd)
			if err != nil {
				log.Fatal(err)
			}
		}
	}

	if processor.discoverd == "" && *externalAddr != "" {
		processor.discoverd = *externalAddr + ":1111"
	}
	// HACK: use env as global for discoverd connection in sampic
	os.Setenv("DISCOVERD", processor.discoverd)
	if disc == nil {
		disc, err = discoverd.NewClientUsingAddress(processor.discoverd)
		if err != nil {
			log.Fatal(err)
		}
	}
	sampiStandby, err := disc.RegisterAndStandby("flynn-host", *externalAddr+":1113", map[string]string{"id": *hostID})
	if err != nil {
		log.Fatal(err)
	}
	go func() {
		<-sampiStandby
		rpc.Register(sampi.NewCluster(sampi.NewState()))
	}()

	cluster, err := client.New()
	if err != nil {
		log.Fatal(err)
	}
	g.Log(grohl.Data{"at": "sampi_connected"})

	events := make(chan host.Event)
	state.AddListener("all", events)
	go syncScheduler(cluster, events)

	var h *host.Host
	if *configFile != "" {
		h, err = openConfig(*configFile)
		if err != nil {
			log.Fatal(err)
		}
	} else {
		h = &host.Host{Resources: make(map[string]host.ResourceValue)}
	}
	if _, ok := h.Resources["memory"]; !ok {
		h.Resources["memory"] = host.ResourceValue{Value: 1024}
	}
	h.ID = *hostID

	jobs := make(chan *host.Job)
	hostErr := cluster.ConnectHost(h, jobs)
	g.Log(grohl.Data{"at": "host_registered"})
	processor.Process(ports, jobs)
	log.Fatal(*hostErr)
}

type jobProcessor struct {
	externalAddr string
	discoverd    string
	docker       interface {
		CreateContainer(*docker.Config) (*docker.Container, error)
		PullImage(docker.PullImageOptions, io.Writer) error
		StartContainer(string, *docker.HostConfig) error
	}
	state *State
}

func (p *jobProcessor) Process(ports <-chan int, jobs chan *host.Job) {
	for job := range jobs {
		p.processJob(ports, job)
	}
}

func (p *jobProcessor) processJob(ports <-chan int, job *host.Job) (*docker.Container, error) {
	g := grohl.NewContext(grohl.Data{"fn": "process_job", "job.id": job.ID})
	g.Log(grohl.Data{"at": "start", "job.image": job.Config.Image, "job.cmd": job.Config.Cmd, "job.entrypoint": job.Config.Entrypoint})

	var hostConfig *docker.HostConfig
	for i := 0; i < job.TCPPorts; i++ {
		port := strconv.Itoa(<-ports)
		if i == 0 {
			job.Config.Env = append(job.Config.Env, "PORT="+port)
		}
		job.Config.Env = append(job.Config.Env, fmt.Sprintf("PORT_%d=%s", i, port))
		if job.Config.ExposedPorts == nil {
			job.Config.ExposedPorts = make(map[string]struct{}, job.TCPPorts)
		}
		job.Config.ExposedPorts[port+"/tcp"] = struct{}{}
		if hostConfig == nil {
			hostConfig = &docker.HostConfig{
				PortBindings:    make(map[string][]docker.PortBinding, job.TCPPorts),
				PublishAllPorts: true,
			}
		}
		hostConfig.PortBindings[port+"/tcp"] = []docker.PortBinding{{HostPort: port}}
	}
	if p.externalAddr != "" {
		job.Config.Env = appendUnique(job.Config.Env, "EXTERNAL_IP="+p.externalAddr, "SD_HOST="+p.externalAddr, "DISCOVERD="+p.discoverd)
	}
	p.state.AddJob(job)
	g.Log(grohl.Data{"at": "create_container"})
	container, err := p.docker.CreateContainer(job.Config)
	if err == docker.ErrNoSuchImage {
		g.Log(grohl.Data{"at": "pull_image"})
		err = p.docker.PullImage(docker.PullImageOptions{Repository: job.Config.Image}, os.Stdout)
		if err != nil {
			g.Log(grohl.Data{"at": "pull_image", "status": "error", "err": err})
			p.state.SetStatusFailed(job.ID, err)
			return nil, err
		}
		container, err = p.docker.CreateContainer(job.Config)
	}
	if err != nil {
		g.Log(grohl.Data{"at": "create_container", "status": "error", "err": err})
		p.state.SetStatusFailed(job.ID, err)
		return nil, err
	}
	p.state.SetContainerID(job.ID, container.ID)
	p.state.WaitAttach(job.ID)
	g.Log(grohl.Data{"at": "start_container"})
	if err := p.docker.StartContainer(container.ID, hostConfig); err != nil {
		g.Log(grohl.Data{"at": "start_container", "status": "error", "err": err})
		p.state.SetStatusFailed(job.ID, err)
		return nil, err
	}
	p.state.SetStatusRunning(job.ID)
	g.Log(grohl.Data{"at": "finish"})
	return container, nil
}

func appendUnique(s []string, vars ...string) []string {
outer:
	for _, v := range vars {
		for _, existing := range s {
			if strings.HasPrefix(existing, strings.SplitN(v, "=", 2)[0]+"=") {
				continue outer
			}
		}
		s = append(s, v)
	}
	return s
}

type sampiSyncClient interface {
	RemoveJobs([]string) error
}

func syncScheduler(scheduler sampiSyncClient, events <-chan host.Event) {
	for event := range events {
		if event.Event != "stop" {
			continue
		}
		grohl.Log(grohl.Data{"fn": "scheduler_event", "at": "remove_job", "job.id": event.JobID})
		if err := scheduler.RemoveJobs([]string{event.JobID}); err != nil {
			grohl.Log(grohl.Data{"fn": "scheduler_event", "at": "remove_job", "status": "error", "err": err, "job.id": event.JobID})
			// TODO: try to reconnect?
		}
	}
}

type dockerStreamClient interface {
	Events() (*docker.EventStream, error)
	InspectContainer(string) (*docker.Container, error)
}

func streamEvents(client dockerStreamClient, state *State) {
	stream, err := client.Events()
	if err != nil {
		log.Fatal(err)
	}
	for event := range stream.Events {
		if event.Status != "die" {
			continue
		}
		container, err := client.InspectContainer(event.ID)
		if err != nil {
			log.Println("inspect container", event.ID, "error:", err)
			// TODO: set job status anyway?
			continue
		}
		state.SetStatusDone(event.ID, container.State.ExitCode)
	}
}

// TODO: fix this, horribly broken

func allocatePorts(ports chan<- int, startPort, endPort int) {
	for i := startPort; i < endPort; i++ {
		ports <- i
	}
	// TODO: handle wrap-around
}
<|endoftext|>


<commit_before>// package threedsecure provides the /3d_secure APIs
package threedsecure

import (
	"strconv"

	"github.com/stripe/stripe-go"
)

type Client struct {
	B   stripe.Backend
	Key string
}

func New(params *stripe.ThreeDSecureParams) (*stripe.ThreeDSecure, error) {
	return getC().New(params)
}

func (c Client) New(params *stripe.ThreeDSecureParams) (*stripe.ThreeDSecure, error) {
	body := &stripe.RequestValues{}
	body.Add("amount", strconv.FormatUint(params.Amount, 10))
	body.Add("currency", string(params.Currency))
	body.Add("card", params.Card)
	body.Add("customer", params.Customer)
	body.Add("return_url", params.ReturnURL)

	params.AppendTo(body)

	if len(params.Customer) > 0 {
		body.Add("customer", params.Customer)
	}

	tds := &stripe.ThreeDSecure{}
	err := c.B.Call("POST", "/3d_secure", c.Key, body, &params.Params, tds)
	return tds, err
}

func getC() Client {
	return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key}
}
<commit_msg>remove unconditional customer param<commit_after>// package threedsecure provides the /3d_secure APIs
package threedsecure

import (
	"strconv"

	"github.com/stripe/stripe-go"
)

type Client struct {
	B   stripe.Backend
	Key string
}

func New(params *stripe.ThreeDSecureParams) (*stripe.ThreeDSecure, error) {
	return getC().New(params)
}

func (c Client) New(params *stripe.ThreeDSecureParams) (*stripe.ThreeDSecure, error) {
	body := &stripe.RequestValues{}
	body.Add("amount", strconv.FormatUint(params.Amount, 10))
	body.Add("currency", string(params.Currency))
	body.Add("card", params.Card)
	body.Add("return_url", params.ReturnURL)

	params.AppendTo(body)

	if len(params.Customer) > 0 {
		body.Add("customer", params.Customer)
	}

	tds := &stripe.ThreeDSecure{}
	err := c.B.Call("POST", "/3d_secure", c.Key, body, &params.Params, tds)
	return tds, err
}

func getC() Client {
	return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key}
}
<|endoftext|>


<commit_before>// Copyright 2016 Vladimir Osintsev <osintsev@gmail.com>
//
// This program 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.
//
// This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
// See the COPYING file in the main directory for details.

package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"github.com/osminogin/tornote"
)

var (
	addr    = flag.String("addr", ":8000", "The address to bind to")
	secret  = flag.String("secret", "", "Secret key")
	db      = flag.String("db", "./db.sqlite3", "Path to sqlite3 database")
	version = flag.Bool("version", false, "Print server version")
)

var GitCommit string

func main() {
	flag.Parse()

	if *version {
		fmt.Printf("Version: git%s\n", GitCommit)
		os.Exit(0)
	}

	server := &tornote.Server{Host: *addr}

	// We already have some encrypted notes?
	if _, err := os.Stat(*db); err == nil && *secret == "" {
		log.Fatal("You must specify secret key if db file exist")
	}

	// Connecting to database
	if err := server.OpenDB(*db); err != nil {
		log.Fatal(err)
	}
	defer server.DB.Close()

	// XXX: Init templates (from there or inside tornote package)

	// Starting
	server.Run()
}
<commit_msg>Remove secret from server-side<commit_after>// Copyright 2016 Vladimir Osintsev <osintsev@gmail.com>
//
// This program 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.
//
// This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
// See the COPYING file in the main directory for details.

package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"github.com/osminogin/tornote"
)

var (
	addr    = flag.String("addr", ":8000", "The address to bind to")
	db      = flag.String("db", "./db.sqlite3", "Path to sqlite3 database")
	version = flag.Bool("version", false, "Print server version")
)

var GitCommit string

func main() {
	flag.Parse()

	if *version {
		fmt.Printf("Version: git%s\n", GitCommit)
		os.Exit(0)
	}

	server := &tornote.Server{Host: *addr}

	// We already have some encrypted notes?
	if _, err := os.Stat(*db); err == nil && *secret == "" {
		log.Fatal("You must specify secret key if db file exist")
	}

	// Connecting to database
	if err := server.OpenDB(*db); err != nil {
		log.Fatal(err)
	}
	defer server.DB.Close()

	// Starting
	server.Run()
}
<|endoftext|>


<commit_before>package endpoints

import (
	"fmt"
	"net"
	"os"

	lxd "github.com/lxc/lxd/client"
	"github.com/lxc/lxd/shared"
	"github.com/lxc/lxd/shared/logger"
)

// Bind to the given unix socket path.
func socketUnixListen(path string) (net.Listener, error) {
	addr, err := net.ResolveUnixAddr("unix", path)
	if err != nil {
		return nil, fmt.Errorf("cannot resolve socket address: %v", err)
	}

	listener, err := net.ListenUnix("unix", addr)
	if err != nil {
		return nil, fmt.Errorf("cannot bind socket: %v", err)
	}

	return listener, err

}

// CheckAlreadyRunning checks if the socket at the given path is already
// bound to a running LXD process, and return an error if so.
//
// FIXME: We should probably rather just try a regular unix socket
//        connection without using the client. However this is the way
//        this logic has historically behaved, so let's keep it like it
//        was.
func CheckAlreadyRunning(path string) error {
	// If there's no socket file at all, there's nothing to do.
	if !shared.PathExists(path) {
		return nil
	}

	_, err := lxd.ConnectLXDUnix(path, nil)

	// If the connection succeeded it means there's another LXD running.
	if err == nil {
		return fmt.Errorf("LXD is already running")
	}

	return nil
}

// Remove any stale socket file at the given path.
func socketUnixRemoveStale(path string) error {
	// If there's no socket file at all, there's nothing to do.
	if !shared.PathExists(path) {
		return nil
	}

	logger.Debugf("Detected stale unix socket, deleting")
	err := os.Remove(path)
	if err != nil {
		return fmt.Errorf("could not delete stale local socket: %v", err)
	}

	return nil
}

// Change the file mode of the given unix socket file,
func socketUnixSetPermissions(path string, mode os.FileMode) error {
	err := os.Chmod(path, mode)
	if err != nil {
		return fmt.Errorf("cannot set permissions on local socket: %v", err)
	}
	return nil
}

// Change the ownership of the given unix socket file,
func socketUnixSetOwnership(path string, group string) error {
	var gid int
	var err error

	if group != "" {
		gid, err = shared.GroupId(group)
		if err != nil {
			return fmt.Errorf("cannot get group ID of '%s': %v", group, err)
		}
	} else {
		gid = os.Getgid()
	}

	err = os.Chown(path, os.Getuid(), gid)
	if err != nil {
		return fmt.Errorf("cannot change ownership on local socket: %v", err)

	}

	return nil
}
<commit_msg>lxd: Fix socket activated startup<commit_after>package endpoints

import (
	"fmt"
	"net"
	"os"
	"strconv"

	"github.com/lxc/lxd/client"
	"github.com/lxc/lxd/shared"
	"github.com/lxc/lxd/shared/logger"
)

// Bind to the given unix socket path.
func socketUnixListen(path string) (net.Listener, error) {
	addr, err := net.ResolveUnixAddr("unix", path)
	if err != nil {
		return nil, fmt.Errorf("cannot resolve socket address: %v", err)
	}

	listener, err := net.ListenUnix("unix", addr)
	if err != nil {
		return nil, fmt.Errorf("cannot bind socket: %v", err)
	}

	return listener, err

}

// CheckAlreadyRunning checks if the socket at the given path is already
// bound to a running LXD process, and return an error if so.
//
// FIXME: We should probably rather just try a regular unix socket
//        connection without using the client. However this is the way
//        this logic has historically behaved, so let's keep it like it
//        was.
func CheckAlreadyRunning(path string) error {
	// If socket activated, nothing to do
	pid, err := strconv.Atoi(os.Getenv("LISTEN_PID"))
	if err == nil {
		if pid == os.Getpid() {
			return nil
		}
	}

	// If there's no socket file at all, there's nothing to do.
	if !shared.PathExists(path) {
		return nil
	}

	_, err = lxd.ConnectLXDUnix(path, nil)

	// If the connection succeeded it means there's another LXD running.
	if err == nil {
		return fmt.Errorf("LXD is already running")
	}

	return nil
}

// Remove any stale socket file at the given path.
func socketUnixRemoveStale(path string) error {
	// If there's no socket file at all, there's nothing to do.
	if !shared.PathExists(path) {
		return nil
	}

	logger.Debugf("Detected stale unix socket, deleting")
	err := os.Remove(path)
	if err != nil {
		return fmt.Errorf("could not delete stale local socket: %v", err)
	}

	return nil
}

// Change the file mode of the given unix socket file,
func socketUnixSetPermissions(path string, mode os.FileMode) error {
	err := os.Chmod(path, mode)
	if err != nil {
		return fmt.Errorf("cannot set permissions on local socket: %v", err)
	}
	return nil
}

// Change the ownership of the given unix socket file,
func socketUnixSetOwnership(path string, group string) error {
	var gid int
	var err error

	if group != "" {
		gid, err = shared.GroupId(group)
		if err != nil {
			return fmt.Errorf("cannot get group ID of '%s': %v", group, err)
		}
	} else {
		gid = os.Getgid()
	}

	err = os.Chown(path, os.Getuid(), gid)
	if err != nil {
		return fmt.Errorf("cannot change ownership on local socket: %v", err)

	}

	return nil
}
<|endoftext|>


<commit_before>package mailserver

import (
	"airdispat.ch/identity"
	"airdispat.ch/message"
	"airdispat.ch/routing"
	"airdispat.ch/server"
	"airdispat.ch/wire"
	"errors"
	"github.com/robfig/revel"
	"net"
	"os"
)

var ServerLocation string

func getServerLocation() string {
	s, _ := os.Hostname()
	ips, _ := net.LookupHost(s)
	return ips[0] + ":2048"
}

func Init() {
	def := getServerLocation()
	ServerLocation = revel.Config.StringDefault("server.location", def)
}

func SendAlert(r routing.Router, msgName string, from *identity.Identity, to string) error {
	addr, err := r.LookupAlias(to)
	if err != nil {
		return err
	}

	msgDescription := server.CreateMessageDescription(msgName, ServerLocation, from.Address, addr)
	err = message.SignAndSend(msgDescription, from, addr)
	if err != nil {
		return err
	}
	return nil
}

func DownloadMessage(r routing.Router, msgName string, from *identity.Identity, to string, toServer string) (*message.Mail, error) {
	addr, err := r.LookupAlias(to)
	if err != nil {
		return nil, err
	}
	addr.Location = toServer

	txMsg := server.CreateTransferMessage(msgName, from.Address, addr)
	bytes, typ, h, err := message.SendMessageAndReceive(txMsg, from, addr)
	if err != nil {
		return nil, err
	}

	if typ != wire.MailCode {
		return nil, errors.New("Wrong message type.")
	}

	return message.CreateMailFromBytes(bytes, h)
}

func DownloadPublicMail(r routing.Router, since uint64, from *identity.Identity, to string) (*server.MessageList, error) {
	addr, err := r.LookupAlias(to)
	if err != nil {
		return nil, err
	}

	txMsg := server.CreateTransferMessageList(since, from.Address, addr)
	bytes, typ, h, err := message.SendMessageAndReceive(txMsg, from, addr)
	if err != nil {
		return nil, err
	}

	if typ != wire.MessageListCode {
		return nil, errors.New("Wrong message type.")
	}

	return server.CreateMessageListFromBytes(bytes, h)
}
<commit_msg>Added Convenience Methods to Mailserver<commit_after>package mailserver

import (
	"airdispat.ch/identity"
	"airdispat.ch/message"
	"airdispat.ch/routing"
	"airdispat.ch/server"
	"airdispat.ch/wire"
	"errors"
	"github.com/airdispatch/dpl"
	"github.com/robfig/revel"
	"melange/app/models"
	"net"
	"os"
)

var ServerLocation string

func getServerLocation() string {
	s, _ := os.Hostname()
	ips, _ := net.LookupHost(s)
	return ips[0] + ":2048"
}

func Init() {
	def := getServerLocation()
	ServerLocation = revel.Config.StringDefault("server.location", def)
}

func Messages(r routing.Router,
	db models.Selectable,
	from *identity.Identity,
	fromUser *models.User,
	public bool, private bool, since int64) ([]dpl.Message, error) {

	var out []dpl.Message
	var err error

	if public {
		var s []*models.UserSubscription
		_, err := db.Select(&s, "select * from dispatch_subscription where userid = $1", fromUser.UserId)
		if err != nil {
			return nil, err
		}

		for _, v := range s {
			msg, err := DownloadPublicMail(r, uint64(since), from, v.Address) // from, to)
			if err != nil {
				return nil, err
			}
			for _, txn := range msg.Content {
				rmsg, err := DownloadMessage(r, txn.Name, nil, v.Address, txn.Location)
				if err != nil {
					return nil, err
				}
				out = append(out, &PluginMail{rmsg})
			}
		}
	}

	if private {
		var ale []*models.Alert
		_, err = db.Select(&ale, "select * from dispatch_alerts where \"to\" = $1 and timestamp > $2", from.Address.String(), since)
		if err != nil {
			return nil, err
		}
		for _, v := range ale {
			msg, err := v.DownloadMessageFromAlert(db, r)
			if err != nil {
				return nil, err
			}
			out = append(out, &PluginMail{msg})
		}
	}

	return out, nil
}

func SendAlert(r routing.Router, msgName string, from *identity.Identity, to string) error {
	addr, err := r.LookupAlias(to)
	if err != nil {
		return err
	}

	msgDescription := server.CreateMessageDescription(msgName, ServerLocation, from.Address, addr)
	err = message.SignAndSend(msgDescription, from, addr)
	if err != nil {
		return err
	}
	return nil
}

func DownloadMessage(r routing.Router, msgName string, from *identity.Identity, to string, toServer string) (*message.Mail, error) {
	addr, err := r.LookupAlias(to)
	if err != nil {
		return nil, err
	}
	addr.Location = toServer

	txMsg := server.CreateTransferMessage(msgName, from.Address, addr)
	bytes, typ, h, err := message.SendMessageAndReceive(txMsg, from, addr)
	if err != nil {
		return nil, err
	}

	if typ != wire.MailCode {
		return nil, errors.New("Wrong message type.")
	}

	return message.CreateMailFromBytes(bytes, h)
}

func DownloadMessageList(r routing.Router, m *server.MessageList, from *identity.Identity, to string) ([]*message.Mail, error) {
	output := make([]*message.Mail, len(m.Content))
	for i, v := range m.Content {
		var err error
		output[i], err = DownloadMessage(r, v.Name, from, to, v.Location)
		if err != nil {
			return nil, err
		}
	}
	return output, nil
}

func DownloadPublicMail(r routing.Router, since uint64, from *identity.Identity, to string) (*server.MessageList, error) {
	addr, err := r.LookupAlias(to)
	if err != nil {
		return nil, err
	}

	txMsg := server.CreateTransferMessageList(since, from.Address, addr)
	bytes, typ, h, err := message.SendMessageAndReceive(txMsg, from, addr)
	if err != nil {
		return nil, err
	}

	if typ != wire.MessageListCode {
		return nil, errors.New("Wrong message type.")
	}

	return server.CreateMessageListFromBytes(bytes, h)
}
<|endoftext|>


<commit_before>package manifest

import (
	"testing"

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

// TestParseAllOff test the correct parsing of an example plan file.
func TestParseAllOff(t *testing.T) {
	plan, err := ParseFile("../testdata/all_off.yml")

	assert.NoError(t, err)
	assert.NotNil(t, plan)

	assert.Len(t, plan.Switches, 3)
	assert.Equal(t, false, plan.Switches[0].State)
	assert.Equal(t, false, plan.Switches[1].State)
	assert.Equal(t, false, plan.Switches[2].State)

	assert.Len(t, plan.Thermostats, 1)
	assert.Equal(t, "ThermoOne", plan.Thermostats[0].Name)
	assert.Equal(t, float64(15), plan.Thermostats[0].Temperature)
}

// TestParseAllOn test the correct parsing of an example plan file.
func TestParseAllOn(t *testing.T) {
	plan, err := ParseFile("../testdata/all_on.yml")

	assert.NoError(t, err)
	assert.NotNil(t, plan)

	assert.Len(t, plan.Switches, 3)
	assert.Len(t, plan.Thermostats, 1)

	assert.Equal(t, true, plan.Switches[0].State)
	assert.Equal(t, true, plan.Switches[1].State)
	assert.Equal(t, true, plan.Switches[2].State)
}

// TestParseNoFileFound test the error handling when a file does not exist.
func TestParseNoFileFound(t *testing.T) {
	_, err := ParseFile("/akfnsjnqgjbqg/klksnglneglkenw/ksdgnkengkl/sdgnslgnsdl")
	assert.Error(t, err)
}

type errReader struct {
}

// Read always fails.
func (e *errReader) Read(p []byte) (n int, err error) {
	return 0, errors.New("I always fail")
}

// TestParseNotReadable test the error handling when a Reader fails.
func TestParseNotReadable(t *testing.T) {
	_, err := Parse(&errReader{})
	assert.Error(t, err)
}
<commit_msg>lint: goimports<commit_after>package manifest

import (
	"errors"
	"testing"

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

// TestParseAllOff test the correct parsing of an example plan file.
func TestParseAllOff(t *testing.T) {
	plan, err := ParseFile("../testdata/all_off.yml")

	assert.NoError(t, err)
	assert.NotNil(t, plan)

	assert.Len(t, plan.Switches, 3)
	assert.Equal(t, false, plan.Switches[0].State)
	assert.Equal(t, false, plan.Switches[1].State)
	assert.Equal(t, false, plan.Switches[2].State)

	assert.Len(t, plan.Thermostats, 1)
	assert.Equal(t, "ThermoOne", plan.Thermostats[0].Name)
	assert.Equal(t, float64(15), plan.Thermostats[0].Temperature)
}

// TestParseAllOn test the correct parsing of an example plan file.
func TestParseAllOn(t *testing.T) {
	plan, err := ParseFile("../testdata/all_on.yml")

	assert.NoError(t, err)
	assert.NotNil(t, plan)

	assert.Len(t, plan.Switches, 3)
	assert.Len(t, plan.Thermostats, 1)

	assert.Equal(t, true, plan.Switches[0].State)
	assert.Equal(t, true, plan.Switches[1].State)
	assert.Equal(t, true, plan.Switches[2].State)
}

// TestParseNoFileFound test the error handling when a file does not exist.
func TestParseNoFileFound(t *testing.T) {
	_, err := ParseFile("/akfnsjnqgjbqg/klksnglneglkenw/ksdgnkengkl/sdgnslgnsdl")
	assert.Error(t, err)
}

type errReader struct {
}

// Read always fails.
func (e *errReader) Read(p []byte) (n int, err error) {
	return 0, errors.New("I always fail")
}

// TestParseNotReadable test the error handling when a Reader fails.
func TestParseNotReadable(t *testing.T) {
	_, err := Parse(&errReader{})
	assert.Error(t, err)
}
<|endoftext|>