<commit_before>//
// DISCLAIMER
//
// Copyright 2017 ArangoDB GmbH, Cologne, Germany
//
// 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.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Author Ewout Prangsma
//

package driver

// ArangoError is a Go error with arangodb specific error information.
type ArangoError struct {
	HasError     bool   `json:"error"`
	Code         int    `json:"code"`
	ErrorNum     int    `json:"errorNum"`
	ErrorMessage string `json:"errorMessage"`
}

// Error returns the error message of an ArangoError.
func (ae ArangoError) Error() string {
	return ae.ErrorMessage
}

// newArangoError creates a new ArangoError with given values.
func newArangoError(code, errorNum int, errorMessage string) error {
	return ArangoError{
		HasError:     true,
		Code:         code,
		ErrorNum:     errorNum,
		ErrorMessage: errorMessage,
	}
}

// IsArangoErrorWithCode returns true when the given error is an ArangoError and its Code field is equal to the given code.
func IsArangoErrorWithCode(err error, code int) bool {
	ae, ok := Cause(err).(ArangoError)
	return ok && ae.Code == code
}

// IsInvalidRequest returns true if the given error is an ArangoError with code 400, indicating an invalid request.
func IsInvalidRequest(err error) bool {
	return IsArangoErrorWithCode(err, 400)
}

// IsUnauthorized returns true if the given error is an ArangoError with code 401, indicating an unauthorized request.
func IsUnauthorized(err error) bool {
	return IsArangoErrorWithCode(err, 401)
}

// IsNotFound returns true if the given error is an ArangoError with code 404, indicating a object not found.
func IsNotFound(err error) bool {
	return IsArangoErrorWithCode(err, 404)
}

// IsConflict returns true if the given error is an ArangoError with code 409, indicating a conflict.
func IsConflict(err error) bool {
	return IsArangoErrorWithCode(err, 409)
}

// IsPreconditionFailed returns true if the given error is an ArangoError with code 412, indicating a failed precondition.
func IsPreconditionFailed(err error) bool {
	return IsArangoErrorWithCode(err, 412)
}

// InvalidArgumentError is returned when a go function argument is invalid.
type InvalidArgumentError struct {
	Message string
}

// Error implements the error interface for InvalidArgumentError.
func (e InvalidArgumentError) Error() string {
	return e.Message
}

// IsInvalidArgument returns true if the given error in an InvalidArgumentError.
func IsInvalidArgument(err error) bool {
	_, ok := Cause(err).(InvalidArgumentError)
	return ok
}

var (
	// WithStack is called on every return of an error to add stacktrace information to the error.
	// When setting this function, also set the Cause function.
	// The interface of this function is compatible with functions in github.com/pkg/errors.
	WithStack = func(err error) error { return err }
	// Cause is used to get the root cause of the given error.
	// The interface of this function is compatible with functions in github.com/pkg/errors.
	Cause = func(err error) error { return err }
)

// ErrorSlice is a slice of errors
type ErrorSlice []error

// FirstNonNil returns the first error in the slice that is not nil.
// If all errors in the slice are nil, nil is returned.
func (l ErrorSlice) FirstNonNil() error {
	for _, e := range l {
		if e != nil {
			return e
		}
	}
	return nil
}
<commit_msg>Added ErrorNum tests since `code` is not always included<commit_after>//
// DISCLAIMER
//
// Copyright 2017 ArangoDB GmbH, Cologne, Germany
//
// 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.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Author Ewout Prangsma
//

package driver

// ArangoError is a Go error with arangodb specific error information.
type ArangoError struct {
	HasError     bool   `json:"error"`
	Code         int    `json:"code"`
	ErrorNum     int    `json:"errorNum"`
	ErrorMessage string `json:"errorMessage"`
}

// Error returns the error message of an ArangoError.
func (ae ArangoError) Error() string {
	return ae.ErrorMessage
}

// newArangoError creates a new ArangoError with given values.
func newArangoError(code, errorNum int, errorMessage string) error {
	return ArangoError{
		HasError:     true,
		Code:         code,
		ErrorNum:     errorNum,
		ErrorMessage: errorMessage,
	}
}

// IsArangoErrorWithCode returns true when the given error is an ArangoError and its Code field is equal to the given code.
func IsArangoErrorWithCode(err error, code int) bool {
	ae, ok := Cause(err).(ArangoError)
	return ok && ae.Code == code
}

// IsArangoErrorWithErrorNum returns true when the given error is an ArangoError and its ErrorNum field is equal to one of the given numbers.
func IsArangoErrorWithErrorNum(err error, errorNum ...int) bool {
	ae, ok := Cause(err).(ArangoError)
	if !ok {
		return false
	}
	for _, x := range errorNum {
		if ae.ErrorNum == x {
			return true
		}
	}
	return false
}

// IsInvalidRequest returns true if the given error is an ArangoError with code 400, indicating an invalid request.
func IsInvalidRequest(err error) bool {
	return IsArangoErrorWithCode(err, 400)
}

// IsUnauthorized returns true if the given error is an ArangoError with code 401, indicating an unauthorized request.
func IsUnauthorized(err error) bool {
	return IsArangoErrorWithCode(err, 401)
}

// IsNotFound returns true if the given error is an ArangoError with code 404, indicating a object not found.
func IsNotFound(err error) bool {
	return IsArangoErrorWithCode(err, 404) || IsArangoErrorWithErrorNum(err, 1202, 1203)
}

// IsConflict returns true if the given error is an ArangoError with code 409, indicating a conflict.
func IsConflict(err error) bool {
	return IsArangoErrorWithCode(err, 409)
}

// IsPreconditionFailed returns true if the given error is an ArangoError with code 412, indicating a failed precondition.
func IsPreconditionFailed(err error) bool {
	return IsArangoErrorWithCode(err, 412) || IsArangoErrorWithErrorNum(err, 1200, 1210)
}

// InvalidArgumentError is returned when a go function argument is invalid.
type InvalidArgumentError struct {
	Message string
}

// Error implements the error interface for InvalidArgumentError.
func (e InvalidArgumentError) Error() string {
	return e.Message
}

// IsInvalidArgument returns true if the given error in an InvalidArgumentError.
func IsInvalidArgument(err error) bool {
	_, ok := Cause(err).(InvalidArgumentError)
	return ok
}

var (
	// WithStack is called on every return of an error to add stacktrace information to the error.
	// When setting this function, also set the Cause function.
	// The interface of this function is compatible with functions in github.com/pkg/errors.
	WithStack = func(err error) error { return err }
	// Cause is used to get the root cause of the given error.
	// The interface of this function is compatible with functions in github.com/pkg/errors.
	Cause = func(err error) error { return err }
)

// ErrorSlice is a slice of errors
type ErrorSlice []error

// FirstNonNil returns the first error in the slice that is not nil.
// If all errors in the slice are nil, nil is returned.
func (l ErrorSlice) FirstNonNil() error {
	for _, e := range l {
		if e != nil {
			return e
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"text/template"
	"time"
)

// blocked/direct form related code is no longer used, but still keep it for a
// while

var errPageRawTmpl = `<!DOCTYPE html>

	 <title>COW Proxy</title>

{{.H1}}

		{{.Msg}}
		{{.Form}}

		Generated by COW at {{.T}}

`

var blockedFormRawTmpl = `

		Refresh to retry or add {{.Domain}} to
		<form action="http://{{.ProxyAddr}}/blocked" method="get">
		<input type="hidden" name="host" value={{.Host}}>
		blocked sites
		<input type="submit" name="submit" value="blocked">
		</form>
`

var directFormRawTmpl = `<form action="http://{{.ProxyAddr}}/direct" method="get">
		<input type="hidden" name="host" value={{.Host}}>
		direct accessible sites
		<input type="submit" name="submit" value="direct">
		</form>
`

// Do not end with "\r\n" so we can add more header later
var headRawTmpl = "HTTP/1.1 {{.CodeReason}}\r\n" +
	"Connection: keep-alive\r\n" +
	"Cache-Control: no-cache\r\n" +
	"Pragma: no-cache\r\n" +
	"Content-Type: text/html\r\n" +
	"Content-Length: {{.Length}}\r\n"

var errPageTmpl, headTmpl, blockedFormTmpl, directFormTmpl *template.Template

func init() {
	var err error
	if headTmpl, err = template.New("errorHead").Parse(headRawTmpl); err != nil {
		fmt.Println("Internal error on generating error head template")
		os.Exit(1)
	}
	if errPageTmpl, err = template.New("errorPage").Parse(errPageRawTmpl); err != nil {
		fmt.Println("Internal error on generating error page template")
		os.Exit(1)
	}
	if blockedFormTmpl, err = template.New("blockedForm").Parse(blockedFormRawTmpl); err != nil {
		fmt.Println("Internal error on generating blocked form template")
		os.Exit(1)
	}
	if directFormTmpl, err = template.New("directForm").Parse(directFormRawTmpl); err != nil {
		fmt.Println("Internal error on generating direct form template")
		os.Exit(1)
	}
}

func genErrorPage(h1, msg, form string) (string, error) {
	var err error
	data := struct {
		H1   string
		Msg  string
		Form string
		T    string
	}{
		h1,
		msg,
		form,
		time.Now().Format(time.ANSIC),
	}

	buf := new(bytes.Buffer)
	err = errPageTmpl.Execute(buf, data)
	return buf.String(), err
}

func sendPageGeneric(w io.Writer, codeReason, h1, msg, form, addHeader string) {
	page, err := genErrorPage(h1, msg, form)
	if err != nil {
		errl.Println("Error generating error page:", err)
		return
	}

	data := struct {
		CodeReason string
		Length     int
	}{
		codeReason,
		len(page),
	}
	buf := new(bytes.Buffer)
	if err := headTmpl.Execute(buf, data); err != nil {
		errl.Println("Error generating error page header:", err)
		return
	}

	buf.WriteString(addHeader)
	buf.WriteString("\r\n")
	buf.WriteString(page)
	w.Write(buf.Bytes())
}

func sendErrorPage(w io.Writer, codeReason, h1, msg string) {
	sendPageGeneric(w, codeReason, "[Error] "+h1, msg, "", "")
}

func sendRedirectPage(w io.Writer, location string) {
	sendPageGeneric(w, "302 Found", "Domain added to blocked list", "Redirect to "+location,
		"", fmt.Sprintf("Location: %s\r\n", location))
}

func sendBlockedErrorPage(c *clientConn, codeReason, h1, msg string, r *Request) {
	// If host is IP or in always DS, we can't add it to blocked or direct domain list. Just
	// return ordinary error page.
	if r.URL.HostIsIP() || siteStat.AlwaysDirect(r.URL) {
		sendErrorPage(c, codeReason, h1, msg)
		return
	}

	data := struct {
		ProxyAddr string
		Host      string
		Domain    string
	}{
		c.proxy.addr,
		r.URL.Host,
		r.URL.Domain,
	}
	buf := new(bytes.Buffer)
	if err := blockedFormTmpl.Execute(buf, data); err != nil {
		errl.Println("Error generating blocked form:", err)
		panic("Error generating blocked form")
	}
	if err := directFormTmpl.Execute(buf, data); err != nil {
		errl.Println("Error generating direct form:", err)
		panic("Error generating direct form")
	}
	sendPageGeneric(c, codeReason, "[Error] "+h1, msg, buf.String(), "")
}
<commit_msg>Remove blocked error page and related code in error.go<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"text/template"
	"time"
)

var errPageRawTmpl = `<!DOCTYPE html>

	 <title>COW Proxy</title>

{{.H1}}

		{{.Msg}}
		{{.Form}}

		Generated by COW at {{.T}}

`

// Do not end with "\r\n" so we can add more header later
var headRawTmpl = "HTTP/1.1 {{.CodeReason}}\r\n" +
	"Connection: keep-alive\r\n" +
	"Cache-Control: no-cache\r\n" +
	"Pragma: no-cache\r\n" +
	"Content-Type: text/html\r\n" +
	"Content-Length: {{.Length}}\r\n"

var errPageTmpl, headTmpl, blockedFormTmpl, directFormTmpl *template.Template

func init() {
	var err error
	if headTmpl, err = template.New("errorHead").Parse(headRawTmpl); err != nil {
		fmt.Println("Internal error on generating error head template")
		os.Exit(1)
	}
	if errPageTmpl, err = template.New("errorPage").Parse(errPageRawTmpl); err != nil {
		fmt.Println("Internal error on generating error page template")
		os.Exit(1)
	}
}

func genErrorPage(h1, msg, form string) (string, error) {
	var err error
	data := struct {
		H1   string
		Msg  string
		Form string
		T    string
	}{
		h1,
		msg,
		form,
		time.Now().Format(time.ANSIC),
	}

	buf := new(bytes.Buffer)
	err = errPageTmpl.Execute(buf, data)
	return buf.String(), err
}

func sendPageGeneric(w io.Writer, codeReason, h1, msg, form, addHeader string) {
	page, err := genErrorPage(h1, msg, form)
	if err != nil {
		errl.Println("Error generating error page:", err)
		return
	}

	data := struct {
		CodeReason string
		Length     int
	}{
		codeReason,
		len(page),
	}
	buf := new(bytes.Buffer)
	if err := headTmpl.Execute(buf, data); err != nil {
		errl.Println("Error generating error page header:", err)
		return
	}

	buf.WriteString(addHeader)
	buf.WriteString("\r\n")
	buf.WriteString(page)
	w.Write(buf.Bytes())
}

func sendErrorPage(w io.Writer, codeReason, h1, msg string) {
	sendPageGeneric(w, codeReason, "[Error] "+h1, msg, "", "")
}
<|endoftext|>


<commit_before>package main

import (
    zmq "github.com/alecthomas/gozmq"
    "log"
    "github.com/howeyc/fsnotify"
    "os"
)

func main() {
    // Create and bind socket
    context, _ := zmq.NewContext()
    socket, _ := context.NewSocket(zmq.PUB)
    defer context.Close()
    defer socket.Close()
    socket.Bind("tcp://*:5556")
    socket.Bind("ipc://weather.ipc")

    // Open file and seek to end
    FILE := "testfile"
    log_file, err := os.Open(FILE)

    if err != nil {
        println(err)
    }

    stat, _ := os.Stat(FILE)
    size := stat.Size()

    log_file.Seek(0, 2)

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

    watcher, err := fsnotify.NewWatcher()

    done := make(chan bool)

    println("watching")
    // Process events
    go func() {
        for {
            ev := <-watcher.Event
            if (ev.IsModify()) {
                println("asdfasd")
                // Create a buffer for reading the new data
                stat, _ = os.Stat(FILE)
                new_size := stat.Size()
                bytes := make([]byte, new_size - size)

                if (new_size - size > 0) {
                    _, err := log_file.Read(bytes)

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

                    err = socket.Send(bytes, 0)

                    if err != nil {
                       log.Fatal(err)
                    }
                }
                size = new_size
            }
        }
    }()

    err = watcher.Watch("testfile")
    if err != nil {
        log.Fatal(err)
    }

    <-done

    watcher.Close()
}
<commit_msg>works for any specified file woosh<commit_after>package main

import (
    zmq "github.com/alecthomas/gozmq"
    "log"
    "github.com/howeyc/fsnotify"
    "os"
)

func main() {
    // Create and bind socket
    context, _ := zmq.NewContext()
    socket, _ := context.NewSocket(zmq.PUB)
    defer context.Close()
    defer socket.Close()
    socket.Bind("tcp://*:5556")
    socket.Bind("ipc://weather.ipc")

    // Open file and seek to end
    FILE := "/var/log/system.log"
    log_file, err := os.Open(FILE)

    if err != nil {
        println(err)
    }

    stat, _ := os.Stat(FILE)
    size := stat.Size()

    log_file.Seek(0, 2)

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

    watcher, err := fsnotify.NewWatcher()

    done := make(chan bool)

    println("Watching file for changes...")
    // Process events
    go func() {
        for {
            ev := <-watcher.Event
            if (ev.IsModify()) {

                // Create a buffer for reading the new data
                stat, _ = os.Stat(FILE)
                new_size := stat.Size()
                bytes := make([]byte, new_size - size)

                if (new_size - size > 0) {
                    _, err := log_file.Read(bytes)

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

                    err = socket.Send(bytes, 0)

                    if err != nil {
                       log.Fatal(err)
                    }
                }
                size = new_size
            }
        }
    }()

    err = watcher.Watch(FILE)
    if err != nil {
        log.Fatal(err)
    }

    <-done

    watcher.Close()
}
<|endoftext|>


<commit_before>package main

import "os"

type FileEvent struct {
  Source *string `json:"source,omitempty"`
  Offset int64 `json:"offset,omitempty"`
  Line uint64 `json:"line,omitempty"`
  Text *string `json:"text,omitempty"`
  Fields *map[string]string

  fileinfo *os.FileInfo
}

type FileState struct {
  Source *string `json:"source,omitempty"`
  Offset int64 `json:"offset,omitempty"`
  Inode uint64 `json:"inode,omitempty"`
  Device uint64 `json:"device,omitempty"`
}
<commit_msg>fixed Device to match data type for Dev size on Darwin<commit_after>package main

import "os"

type FileEvent struct {
  Source *string `json:"source,omitempty"`
  Offset int64 `json:"offset,omitempty"`
  Line uint64 `json:"line,omitempty"`
  Text *string `json:"text,omitempty"`
  Fields *map[string]string

  fileinfo *os.FileInfo
}

type FileState struct {
  Source *string `json:"source,omitempty"`
  Offset int64 `json:"offset,omitempty"`
  Inode uint64 `json:"inode,omitempty"`
  Device int32 `json:"device,omitempty"`
}
<|endoftext|>


<commit_before>package missinggo

import "sync"

type Event struct {
	mu     sync.Mutex
	ch     chan struct{}
	closed bool
}

func (me *Event) lazyInit() {
	if me.ch == nil {
		me.ch = make(chan struct{})
	}
}

func (me *Event) C() <-chan struct{} {
	me.mu.Lock()
	defer me.mu.Unlock()
	me.lazyInit()
	return me.ch
}

func (me *Event) Clear() {
	me.mu.Lock()
	defer me.mu.Unlock()
	me.lazyInit()
	if !me.closed {
		return
	}
	me.ch = make(chan struct{})
	me.closed = false
}

func (me *Event) Set() (first bool) {
	me.mu.Lock()
	defer me.mu.Unlock()
	me.lazyInit()
	if me.closed {
		return false
	}
	close(me.ch)
	me.closed = true
	return true
}

func (me *Event) IsSet() bool {
	me.mu.Lock()
	defer me.mu.Unlock()
	select {
	case <-me.ch:
		return true
	default:
		return false
	}
}

func (me *Event) Wait() {
	<-me.C()
}
<commit_msg>Avoid defers in Event<commit_after>package missinggo

import "sync"

type Event struct {
	mu     sync.Mutex
	ch     chan struct{}
	closed bool
}

func (me *Event) lazyInit() {
	if me.ch == nil {
		me.ch = make(chan struct{})
	}
}

func (me *Event) C() <-chan struct{} {
	me.mu.Lock()
	me.lazyInit()
	ch := me.ch
	me.mu.Unlock()
	return ch
}

func (me *Event) Clear() {
	me.mu.Lock()
	defer me.mu.Unlock()
	me.lazyInit()
	if !me.closed {
		return
	}
	me.ch = make(chan struct{})
	me.closed = false
}

func (me *Event) Set() (first bool) {
	me.mu.Lock()
	defer me.mu.Unlock()
	me.lazyInit()
	if me.closed {
		return false
	}
	close(me.ch)
	me.closed = true
	return true
}

func (me *Event) IsSet() bool {
	me.mu.Lock()
	ch := me.ch
	me.mu.Unlock()
	select {
	case <-ch:
		return true
	default:
		return false
	}
}

func (me *Event) Wait() {
	<-me.C()
}
<|endoftext|>


<commit_before>package main

import "os"

type FileEvent struct {
  Source *string `json:"source,omitempty"`
  Offset uint64 `json:"offset,omitempty"`
  Line uint64 `json:"line,omitempty"`
  Text *string `json:"text,omitempty"`
  Fields *map[string]string

  fileinfo *os.FileInfo
}

type FileState struct {
  Source *string `json:"source,omitempty"`
  Offset uint64 `json:"offset,omitempty"`
  Inode uint64 `json:"inode,omitempty"`
  Device uint64 `json:"device,omitempty"`
}
<commit_msg>- use int64 (offsets can be negative in seek calls)<commit_after>package main

import "os"

type FileEvent struct {
  Source *string `json:"source,omitempty"`
  Offset int64 `json:"offset,omitempty"`
  Line uint64 `json:"line,omitempty"`
  Text *string `json:"text,omitempty"`
  Fields *map[string]string

  fileinfo *os.FileInfo
}

type FileState struct {
  Source *string `json:"source,omitempty"`
  Offset int64 `json:"offset,omitempty"`
  Inode uint64 `json:"inode,omitempty"`
  Device uint64 `json:"device,omitempty"`
}
<|endoftext|>


<commit_before>package cl11

import (
	"unsafe"

	clw "github.com/rdwilliamson/clw11"
)

type Event struct {
	id           clw.Event
	Context      *Context
	CommandType  CommandType
	CommandQueue *CommandQueue
}

// Device counter times in nanoseconds.
type EventProfilingInfo struct {
	Queued int64
	Submit int64
	Start  int64
	End    int64
}

func (c *Context) CreateUserEvent() (*Event, error) {

	event, err := clw.CreateUserEvent(c.id)
	if err != nil {
		return nil, err
	}

	return &Event{id: event, Context: c, CommandType: CommandUser}, nil
}

type CommandType int

const (
	CommandNDRangeKernel        = CommandType(clw.CommandNdrangeKernel)
	CommandTask                 = CommandType(clw.CommandTask)
	CommandNativeKernel         = CommandType(clw.CommandNativeKernel)
	CommandReadBuffer           = CommandType(clw.CommandReadBuffer)
	CommandWriteBuffer          = CommandType(clw.CommandWriteBuffer)
	CommandCopyBuffer           = CommandType(clw.CommandCopyBuffer)
	CommandReadImage            = CommandType(clw.CommandReadImage)
	CommandWriteImage           = CommandType(clw.CommandWriteImage)
	CommandCopyImage            = CommandType(clw.CommandCopyImage)
	CommandCopyImageToBuffer    = CommandType(clw.CommandCopyImageToBuffer)
	CommandCopyBufferToImage    = CommandType(clw.CommandCopyBufferToImage)
	CommandMapBuffer            = CommandType(clw.CommandMapBuffer)
	CommandMapImage             = CommandType(clw.CommandMapImage)
	CommandUnmapMemoryObject    = CommandType(clw.CommandUnmapMemoryObject)
	CommandMarker               = CommandType(clw.CommandMarker)
	CommandAcquireGlObjects     = CommandType(clw.CommandAcquireGlObjects)
	CommandReleaseGlObjects     = CommandType(clw.CommandReleaseGlObjects)
	CommandReadBufferRectangle  = CommandType(clw.CommandReadBufferRectangle)
	CommandWriteBufferRectangle = CommandType(clw.CommandWriteBufferRectangle)
	CommandCopyBufferRectangle  = CommandType(clw.CommandCopyBufferRectangle)
	CommandUser                 = CommandType(clw.CommandUser)
)

var commandTypeMap = map[CommandType]string{
	CommandNDRangeKernel:        "ND range kernel",
	CommandTask:                 "task",
	CommandNativeKernel:         "native kernel",
	CommandReadBuffer:           "read buffer",
	CommandWriteBuffer:          "write buffer",
	CommandCopyBuffer:           "copy buffer",
	CommandReadImage:            "read image",
	CommandWriteImage:           "write image",
	CommandCopyImage:            "copy image",
	CommandCopyImageToBuffer:    "copy image to buffer",
	CommandCopyBufferToImage:    "copy buffer to image",
	CommandMapBuffer:            "map buffer",
	CommandMapImage:             "map image",
	CommandUnmapMemoryObject:    "unmap memory object",
	CommandMarker:               "marker",
	CommandAcquireGlObjects:     "acquire GL objects",
	CommandReleaseGlObjects:     "release GL objects",
	CommandReadBufferRectangle:  "read buffer rectangle",
	CommandWriteBufferRectangle: "write buffer rectangle",
	CommandCopyBufferRectangle:  "copy buffer rectangle",
	CommandUser:                 "user",
}

func (ct CommandType) String() string {
	return commandTypeMap[ct]
}

type CommandExecutionStatus int

const (
	Complete  = CommandExecutionStatus(clw.Complete)
	Running   = CommandExecutionStatus(clw.Running)
	Submitted = CommandExecutionStatus(clw.Submitted)
	Queued    = CommandExecutionStatus(clw.Queued)
)

func (ces CommandExecutionStatus) String() string {
	switch ces {
	case Complete:
		return "complete"
	case Running:
		return "running"
	case Submitted:
		return "submitted"
	case Queued:
		return "queued"
	}
	return ""
}

// Returns the events status, an error that caused the event to terminate, or an
// error that occurred trying to retrieve the event status.
func (e *Event) Status() (CommandExecutionStatus, error, error) {

	var status clw.CommandExecutionStatus
	err := clw.GetEventInfo(e.id, clw.EventCommandExecutionStatus, clw.Size(unsafe.Sizeof(status)),
		unsafe.Pointer(&status), nil)
	if err != nil {
		return 0, nil, err
	}

	if status < 0 {
		return 0, clw.CodeToError(clw.Int(status)), nil
	}

	return CommandExecutionStatus(status), nil, nil
}

func (e *Event) ProfilingInfo() (*EventProfilingInfo, error) {

	var queued clw.Ulong
	err := clw.GetEventProfilingInfo(e.id, clw.ProfilingCommandQueued, clw.Size(unsafe.Sizeof(queued)),
		unsafe.Pointer(&queued), nil)
	if err != nil {
		return nil, err
	}

	var submit clw.Ulong
	err = clw.GetEventProfilingInfo(e.id, clw.ProfilingCommandSubmit, clw.Size(unsafe.Sizeof(submit)),
		unsafe.Pointer(&submit), nil)
	if err != nil {
		return nil, err
	}

	var start clw.Ulong
	err = clw.GetEventProfilingInfo(e.id, clw.ProfilingCommandStart, clw.Size(unsafe.Sizeof(start)),
		unsafe.Pointer(&start), nil)
	if err != nil {
		return nil, err
	}

	var end clw.Ulong
	err = clw.GetEventProfilingInfo(e.id, clw.ProfilingCommandEnd, clw.Size(unsafe.Sizeof(end)),
		unsafe.Pointer(&end), nil)
	if err != nil {
		return nil, err
	}

	return &EventProfilingInfo{int64(queued), int64(submit), int64(start), int64(end)}, nil
}
<commit_msg>Moved profiling info into event.<commit_after>package cl11

import (
	"unsafe"

	clw "github.com/rdwilliamson/clw11"
)

type Event struct {
	id           clw.Event
	Context      *Context
	CommandType  CommandType
	CommandQueue *CommandQueue

	Queued int64
	Submit int64
	Start  int64
	End    int64
}

func (c *Context) CreateUserEvent() (*Event, error) {

	event, err := clw.CreateUserEvent(c.id)
	if err != nil {
		return nil, err
	}

	return &Event{id: event, Context: c, CommandType: CommandUser}, nil
}

type CommandType int

const (
	CommandNDRangeKernel        = CommandType(clw.CommandNdrangeKernel)
	CommandTask                 = CommandType(clw.CommandTask)
	CommandNativeKernel         = CommandType(clw.CommandNativeKernel)
	CommandReadBuffer           = CommandType(clw.CommandReadBuffer)
	CommandWriteBuffer          = CommandType(clw.CommandWriteBuffer)
	CommandCopyBuffer           = CommandType(clw.CommandCopyBuffer)
	CommandReadImage            = CommandType(clw.CommandReadImage)
	CommandWriteImage           = CommandType(clw.CommandWriteImage)
	CommandCopyImage            = CommandType(clw.CommandCopyImage)
	CommandCopyImageToBuffer    = CommandType(clw.CommandCopyImageToBuffer)
	CommandCopyBufferToImage    = CommandType(clw.CommandCopyBufferToImage)
	CommandMapBuffer            = CommandType(clw.CommandMapBuffer)
	CommandMapImage             = CommandType(clw.CommandMapImage)
	CommandUnmapMemoryObject    = CommandType(clw.CommandUnmapMemoryObject)
	CommandMarker               = CommandType(clw.CommandMarker)
	CommandAcquireGlObjects     = CommandType(clw.CommandAcquireGlObjects)
	CommandReleaseGlObjects     = CommandType(clw.CommandReleaseGlObjects)
	CommandReadBufferRectangle  = CommandType(clw.CommandReadBufferRectangle)
	CommandWriteBufferRectangle = CommandType(clw.CommandWriteBufferRectangle)
	CommandCopyBufferRectangle  = CommandType(clw.CommandCopyBufferRectangle)
	CommandUser                 = CommandType(clw.CommandUser)
)

var commandTypeMap = map[CommandType]string{
	CommandNDRangeKernel:        "ND range kernel",
	CommandTask:                 "task",
	CommandNativeKernel:         "native kernel",
	CommandReadBuffer:           "read buffer",
	CommandWriteBuffer:          "write buffer",
	CommandCopyBuffer:           "copy buffer",
	CommandReadImage:            "read image",
	CommandWriteImage:           "write image",
	CommandCopyImage:            "copy image",
	CommandCopyImageToBuffer:    "copy image to buffer",
	CommandCopyBufferToImage:    "copy buffer to image",
	CommandMapBuffer:            "map buffer",
	CommandMapImage:             "map image",
	CommandUnmapMemoryObject:    "unmap memory object",
	CommandMarker:               "marker",
	CommandAcquireGlObjects:     "acquire GL objects",
	CommandReleaseGlObjects:     "release GL objects",
	CommandReadBufferRectangle:  "read buffer rectangle",
	CommandWriteBufferRectangle: "write buffer rectangle",
	CommandCopyBufferRectangle:  "copy buffer rectangle",
	CommandUser:                 "user",
}

func (ct CommandType) String() string {
	return commandTypeMap[ct]
}

type CommandExecutionStatus int

const (
	Complete  = CommandExecutionStatus(clw.Complete)
	Running   = CommandExecutionStatus(clw.Running)
	Submitted = CommandExecutionStatus(clw.Submitted)
	Queued    = CommandExecutionStatus(clw.Queued)
)

func (ces CommandExecutionStatus) String() string {
	switch ces {
	case Complete:
		return "complete"
	case Running:
		return "running"
	case Submitted:
		return "submitted"
	case Queued:
		return "queued"
	}
	return ""
}

// Returns the events status, an error that caused the event to terminate, or an
// error that occurred trying to retrieve the event status.
func (e *Event) Status() (CommandExecutionStatus, error, error) {

	var status clw.CommandExecutionStatus
	err := clw.GetEventInfo(e.id, clw.EventCommandExecutionStatus, clw.Size(unsafe.Sizeof(status)),
		unsafe.Pointer(&status), nil)
	if err != nil {
		return 0, nil, err
	}

	if status < 0 {
		return 0, clw.CodeToError(clw.Int(status)), nil
	}

	return CommandExecutionStatus(status), nil, nil
}

func (e *Event) GetProfilingInfo() error {

	var value clw.Ulong
	err := clw.GetEventProfilingInfo(e.id, clw.ProfilingCommandQueued, clw.Size(unsafe.Sizeof(value)),
		unsafe.Pointer(&value), nil)
	if err != nil {
		return err
	}
	e.Queued = int64(value)

	err = clw.GetEventProfilingInfo(e.id, clw.ProfilingCommandSubmit, clw.Size(unsafe.Sizeof(value)),
		unsafe.Pointer(&value), nil)
	if err != nil {
		return err
	}
	e.Submit = int64(value)

	err = clw.GetEventProfilingInfo(e.id, clw.ProfilingCommandStart, clw.Size(unsafe.Sizeof(value)),
		unsafe.Pointer(&value), nil)
	if err != nil {
		return err
	}
	e.Start = int64(value)

	err = clw.GetEventProfilingInfo(e.id, clw.ProfilingCommandEnd, clw.Size(unsafe.Sizeof(value)),
		unsafe.Pointer(&value), nil)
	if err != nil {
		return err
	}
	e.End = int64(value)

	return nil
}
<|endoftext|>


<commit_before>// Package httpcache provides facilities for caching HTTP responses and
// hypermedia for REST resources.  The saved responses respect HTTP caching
// policies.  Hypermedia shouldn't change, so is stored for as long as possible.
package httpcache

import (
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"github.com/lostisland/go-sawyer"
	"net/http"
)

// RequestKey builds a unique string key for a net/http Request.
func RequestKey(r *http.Request) string {
	return r.Header.Get(keyHeader) + keySep + r.URL.String()
}

func RequestSha(r *http.Request) string {
	key := RequestKey(r)
	sum := sha256.New().Sum([]byte(key))
	return hex.EncodeToString(sum)
}

func ResponseError(err error) *sawyer.Response {
	return sawyer.ResponseError(err)
}

var NoResponseError = errors.New("No Response")

const (
	keySep    = ":"
	keyHeader = "Accept"
)
<commit_msg>unused helper<commit_after>// Package httpcache provides facilities for caching HTTP responses and
// hypermedia for REST resources.  The saved responses respect HTTP caching
// policies.  Hypermedia shouldn't change, so is stored for as long as possible.
package httpcache

import (
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"net/http"
)

// RequestKey builds a unique string key for a net/http Request.
func RequestKey(r *http.Request) string {
	return r.Header.Get(keyHeader) + keySep + r.URL.String()
}

func RequestSha(r *http.Request) string {
	key := RequestKey(r)
	sum := sha256.New().Sum([]byte(key))
	return hex.EncodeToString(sum)
}

var NoResponseError = errors.New("No Response")

const (
	keySep    = ":"
	keyHeader = "Accept"
)
<|endoftext|>


<commit_before>package transporter

import (
	"database/sql"
	"errors"
	"log"
	"sort"
	"strconv"

	"github.com/wawandco/transporter/Godeps/_workspace/src/gopkg.in/yaml.v1"
	"github.com/wawandco/transporter/managers"

	"github.com/wawandco/transporter/Godeps/_workspace/src/github.com/apaganobeleno/pq"
	"github.com/wawandco/transporter/Godeps/_workspace/src/github.com/go-sql-driver/mysql"
)

func init() {
	log.Println(sql.Drivers())
	if !driverRegistered("postgres") {
		sql.Register("postgres", &pq.Driver{})
	}

	if !driverRegistered("mysql") {
		sql.Register("mysql", &mysql.MySQLDriver{})
	}
}

var migrations []Migration
var manager managers.DatabaseManager
var databaseManagers = map[string]managers.DatabaseManager{
	"postgres": &managers.PostgreSQLManager{},
	"mysql":    &managers.MySQLManager{},
}

const (
	// MigrationsTable is the Db table where we will store migrations
	MigrationsTable = "transporter_migrations"
)

// Add function adds a migration to the migrations array
// So Transporter verifies if the migration is already completed or runs
// the desired migration as needed.
//
// Register checks if migration attempted to be registered id is unique.
func Add(m Migration) {
	migrations = append(migrations, m)
}

// MigrationsTableExists returns true if the table for the migrations already exists.
func MigrationsTableExists(db *sql.DB) bool {
	query := manager.AllMigrationsQuery(MigrationsTable)
	_, err := db.Query(query)
	return err == nil
}

//RunAllMigrationsUp runs pending migrations and stores migration on the migrations table.
func RunAllMigrationsUp(db *sql.DB) {

	//1. Migrations table exists? -> Create if needed
	if !MigrationsTableExists(db) {
		CreateMigrationsTable(db)
	}

	sort.Sort(ByIdentifier(migrations))

	version := DatabaseVersion(db)
	if len(migrations) > 0 && version == migrations[len(migrations)-1].GetID() {
		log.Println("| No migrations to run, DB is on latest version. (" + version + ")")
		return
	}

	var err error
	for _, migration := range migrations {
		// Check if migration is on the database already
		if migration.Pending(db) {
			err = RunMigrationUp(db, &migration)

			if err != nil {
				log.Println("| Could not complete your migration (" + migration.GetID() + "), please check your SQL.")
				log.Println("| " + err.Error())
				break
			}
		}
	}

	version = DatabaseVersion(db)
	if err == nil && version != "" {
		log.Println("| Done, new database version is " + version)
	}
}

// RunMigrationUp runs a single migration up and if success it saves the
// Migration identifier on the migrations table.
func RunMigrationUp(db *sql.DB, m *Migration) error {
	tx, err := dbTransaction(db)
	if err != nil {
		return errors.New("Could not open a db transaction.")
	}

	if m.Up != nil {
		m.Up(tx)
		migerr := tx.err
		err = tx.Commit()

		if err != nil || migerr != nil {
			return migerr
		}

		query := manager.AddMigrationQuery(MigrationsTable, m.GetID())
		_, err = db.Exec(query)
		return nil
	}

	return errors.New("Migration doesnt have Up function defined.")
}

// RunMigrationDown Runs one migration down and if successful it removes the migration from
// the migrations table.
func RunMigrationDown(db *sql.DB, m *Migration) error {
	tx, err := dbTransaction(db)
	if err != nil {
		return errors.New("Could not begin a transaction.")
	}

	if m.Down != nil {
		m.Down(tx)
		migerr := tx.err
		err = tx.Commit()

		if err != nil || migerr != nil {
			return migerr
		}
		query := manager.DeleteMigrationQuery(MigrationsTable, m.GetID())
		_, err = db.Exec(query)
		return nil
	}

	return errors.New("Migration (" + m.GetID() + ") doesn't have Down function defined.")
}

//RunOneMigrationDown Run down last migration that have completed.
func RunOneMigrationDown(db *sql.DB) {
	if !MigrationsTableExists(db) {
		CreateMigrationsTable(db)
	}

	sort.Sort(ByIdentifier(migrations))
	identifier := DatabaseVersion(db)
	id, err := strconv.Atoi(identifier)

	if err != nil {
		log.Println("Sorry, there is no migration to run back")
	}

	for _, mig := range migrations {
		if mig.Identifier-int64(id) == 0 {
			log.Println("| Running " + mig.GetID() + " back")
			err := RunMigrationDown(db, &mig)
			if err == nil {
				version := DatabaseVersion(db)
				if version != "" {
					log.Println("| Done, new database version is " + version)
				} else {
					log.Println("| Done, All existing migrations down.")
				}
			} else {
				log.Println("| Could not rollback your migration (" + mig.GetID() + "), please check your SQL.")
				log.Println("| " + err.Error())
			}
			break
		}
	}

}

//DatabaseVersion returns the latest database version.
func DatabaseVersion(db *sql.DB) string {
	query := manager.LastMigrationQuery(MigrationsTable)
	rows, _ := db.Query(query)
	var identifier string
	for rows.Next() {
		rows.Scan(&identifier)
		break
	}

	return identifier
}

//SetManager allows external entities like testing to set the driver as needed.
func SetManager(man managers.DatabaseManager) {
	manager = man
}

//DBConnection Returns a DB connection from the yml config file
func DBConnection(ymlFile []byte, environment string) (*sql.DB, error) {
	var connData map[string]map[string]string
	err := yaml.Unmarshal([]byte(ymlFile), &connData)

	if err != nil {
		return nil, err
	}

	if connData[environment] == nil {
		err = errors.New("Environment [" + environment + "] does not exist in your config.yml")
		return nil, err
	}

	manager = databaseManagers[connData[environment]["driver"]]
	return sql.Open(connData[environment]["driver"], connData[environment]["url"])
}

func dbTransaction(db *sql.DB) (*Tx, error) {
	sqlTx, err := db.Begin()
	if err != nil {
		log.Println("| Error, could not initialize transaction")
	}

	tx := &Tx{
		Tx:      sqlTx,
		Manager: manager,
		err:     nil,
	}

	return tx, err
}
<commit_msg>[testing]<commit_after>package transporter

import (
	"database/sql"
	"errors"
	"log"
	"sort"
	"strconv"

	"github.com/wawandco/transporter/Godeps/_workspace/src/gopkg.in/yaml.v1"
	"github.com/wawandco/transporter/managers"

	"github.com/wawandco/transporter/Godeps/_workspace/src/github.com/apaganobeleno/pq"
	"github.com/wawandco/transporter/Godeps/_workspace/src/github.com/go-sql-driver/mysql"
)

func init() {
	log.Println(sql.Drivers())
	log.Println(!driverRegistered("postgres"))
	log.Println(!driverRegistered("mysql"))

	if !driverRegistered("postgres") {
		sql.Register("postgres", &pq.Driver{})
	}

	if !driverRegistered("mysql") {
		sql.Register("mysql", &mysql.MySQLDriver{})
	}
}

var migrations []Migration
var manager managers.DatabaseManager
var databaseManagers = map[string]managers.DatabaseManager{
	"postgres": &managers.PostgreSQLManager{},
	"mysql":    &managers.MySQLManager{},
}

const (
	// MigrationsTable is the Db table where we will store migrations
	MigrationsTable = "transporter_migrations"
)

// Add function adds a migration to the migrations array
// So Transporter verifies if the migration is already completed or runs
// the desired migration as needed.
//
// Register checks if migration attempted to be registered id is unique.
func Add(m Migration) {
	migrations = append(migrations, m)
}

// MigrationsTableExists returns true if the table for the migrations already exists.
func MigrationsTableExists(db *sql.DB) bool {
	query := manager.AllMigrationsQuery(MigrationsTable)
	_, err := db.Query(query)
	return err == nil
}

//RunAllMigrationsUp runs pending migrations and stores migration on the migrations table.
func RunAllMigrationsUp(db *sql.DB) {

	//1. Migrations table exists? -> Create if needed
	if !MigrationsTableExists(db) {
		CreateMigrationsTable(db)
	}

	sort.Sort(ByIdentifier(migrations))

	version := DatabaseVersion(db)
	if len(migrations) > 0 && version == migrations[len(migrations)-1].GetID() {
		log.Println("| No migrations to run, DB is on latest version. (" + version + ")")
		return
	}

	var err error
	for _, migration := range migrations {
		// Check if migration is on the database already
		if migration.Pending(db) {
			err = RunMigrationUp(db, &migration)

			if err != nil {
				log.Println("| Could not complete your migration (" + migration.GetID() + "), please check your SQL.")
				log.Println("| " + err.Error())
				break
			}
		}
	}

	version = DatabaseVersion(db)
	if err == nil && version != "" {
		log.Println("| Done, new database version is " + version)
	}
}

// RunMigrationUp runs a single migration up and if success it saves the
// Migration identifier on the migrations table.
func RunMigrationUp(db *sql.DB, m *Migration) error {
	tx, err := dbTransaction(db)
	if err != nil {
		return errors.New("Could not open a db transaction.")
	}

	if m.Up != nil {
		m.Up(tx)
		migerr := tx.err
		err = tx.Commit()

		if err != nil || migerr != nil {
			return migerr
		}

		query := manager.AddMigrationQuery(MigrationsTable, m.GetID())
		_, err = db.Exec(query)
		return nil
	}

	return errors.New("Migration doesnt have Up function defined.")
}

// RunMigrationDown Runs one migration down and if successful it removes the migration from
// the migrations table.
func RunMigrationDown(db *sql.DB, m *Migration) error {
	tx, err := dbTransaction(db)
	if err != nil {
		return errors.New("Could not begin a transaction.")
	}

	if m.Down != nil {
		m.Down(tx)
		migerr := tx.err
		err = tx.Commit()

		if err != nil || migerr != nil {
			return migerr
		}
		query := manager.DeleteMigrationQuery(MigrationsTable, m.GetID())
		_, err = db.Exec(query)
		return nil
	}

	return errors.New("Migration (" + m.GetID() + ") doesn't have Down function defined.")
}

//RunOneMigrationDown Run down last migration that have completed.
func RunOneMigrationDown(db *sql.DB) {
	if !MigrationsTableExists(db) {
		CreateMigrationsTable(db)
	}

	sort.Sort(ByIdentifier(migrations))
	identifier := DatabaseVersion(db)
	id, err := strconv.Atoi(identifier)

	if err != nil {
		log.Println("Sorry, there is no migration to run back")
	}

	for _, mig := range migrations {
		if mig.Identifier-int64(id) == 0 {
			log.Println("| Running " + mig.GetID() + " back")
			err := RunMigrationDown(db, &mig)
			if err == nil {
				version := DatabaseVersion(db)
				if version != "" {
					log.Println("| Done, new database version is " + version)
				} else {
					log.Println("| Done, All existing migrations down.")
				}
			} else {
				log.Println("| Could not rollback your migration (" + mig.GetID() + "), please check your SQL.")
				log.Println("| " + err.Error())
			}
			break
		}
	}

}

//DatabaseVersion returns the latest database version.
func DatabaseVersion(db *sql.DB) string {
	query := manager.LastMigrationQuery(MigrationsTable)
	rows, _ := db.Query(query)
	var identifier string
	for rows.Next() {
		rows.Scan(&identifier)
		break
	}

	return identifier
}

//SetManager allows external entities like testing to set the driver as needed.
func SetManager(man managers.DatabaseManager) {
	manager = man
}

//DBConnection Returns a DB connection from the yml config file
func DBConnection(ymlFile []byte, environment string) (*sql.DB, error) {
	var connData map[string]map[string]string
	err := yaml.Unmarshal([]byte(ymlFile), &connData)

	if err != nil {
		return nil, err
	}

	if connData[environment] == nil {
		err = errors.New("Environment [" + environment + "] does not exist in your config.yml")
		return nil, err
	}

	manager = databaseManagers[connData[environment]["driver"]]
	return sql.Open(connData[environment]["driver"], connData[environment]["url"])
}

func dbTransaction(db *sql.DB) (*Tx, error) {
	sqlTx, err := db.Begin()
	if err != nil {
		log.Println("| Error, could not initialize transaction")
	}

	tx := &Tx{
		Tx:      sqlTx,
		Manager: manager,
		err:     nil,
	}

	return tx, err
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.

package httpreplay

import (
	"bufio"
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"os"
	"sync"
	"time"
)

// Mode represents recording/playback mode
type Mode int

// Recorder states
const (
	ModeRecording Mode = iota
	ModeReplaying
	ModeDisabled
)

// Transformer converts a request and a saved interaction into a result.  The Interaction is passed by value to suggest that it should not be modified.
type Transformer func(*Request, Interaction, *Response)

type jsonObj map[string]interface{}
type jsonArr []jsonObj
type jsonStr string

func defaultTransformer(req *Request, i Interaction, res *Response) {
}

type roundTripperProxy struct {
	recorder *Recorder
	chained  http.RoundTripper
}

func (rtp *roundTripperProxy) RoundTrip(r *http.Request) (*http.Response, error) {
	return rtp.recorder.RoundTrip(r, rtp.chained)
}

func (rtp *roundTripperProxy) CancelRequest(r *http.Request) {
	rtp.recorder.CancelRequest(r, rtp.chained)
}

// Recorder represents a type used to record and replay
// client and server interactions
type Recorder struct {
	// Operating mode of the recorder
	mode Mode

	// Scenario used by the recorder
	scenario *Scenario

	// transformer is used to adjust responses to match changes in requests
	transformer Transformer

	// count is for debug logging -- how many requests have been matched
	count int
}

// HookTransport makes a new transport and chains the one passed in with it, returning the new one
func (r *Recorder) HookTransport(client *http.Client) error {
	if r == nil {
		return errors.New("The test case missing calling SetScenerio() ")
	}
	if _, ok := client.Transport.(*roundTripperProxy); !ok {
		proxy := roundTripperProxy{
			recorder: r,
			chained:  client.Transport,
		}
		client.Transport = &proxy
	}
	return nil
}

// SetTransformer can be used to override the default (no-op) transformer
func (r *Recorder) SetTransformer(t Transformer) {
	r.transformer = t
}

var mut sync.RWMutex

func (r *Recorder) invokeTransformer(req *http.Request) (*Interaction, *Response, error) {
	mut.Lock()
	defer mut.Unlock()
	if err := req.ParseForm(); err != nil {
		debugLogf("\t-> Returning error from invokeTransformer: %v", err)
		//return nil, nil, err
	}

	reqBody := make([]byte, req.ContentLength)
	if _, err := io.ReadFull(req.Body, reqBody); err != nil {
		debugLogf("\t-> Returning error from invokeTransformer: %v", err)
		return nil, nil, err
	}

	var bodyParsed interface{}
	if len(reqBody) != 0 {
		bodyParsed, _ = unmarshal(reqBody)
	}

	request := Request{
		Body:       string(reqBody),
		BodyParsed: bodyParsed,
		Form:       req.PostForm,
		Headers:    req.Header,
		URL:        req.URL.String(),
		Method:     req.Method,
	}

	i, err := r.scenario.GetInteraction(request)
	if err != nil {
		if err.Error() == "Requested interaction not found" {
			debugLogf("\t-> Convert full path of request to find Interaction:")
			i, err = r.scenario.GetInteractionWithFullPath(request)
			if err != nil {
				debugLogf("\t-> Returning error from invokeTransformer: %v", err)
				return nil, nil, err
			}
		}
	}
	i.Request.BodyParsed, _ = unmarshal([]byte(i.Request.Body))
	i.Response.BodyParsed, _ = unmarshal([]byte(i.Response.Body))
	debugLogf("\t=> => Request %d matched interaction %d", r.count, i.Index)
	r.count++

	res := i.Response
	response := Response{
		Body:     res.Body,
		Headers:  res.Headers,
		Status:   res.Status,
		Code:     res.Code,
		Duration: res.Duration,
	}

	if len(res.Body) > 0 {
		if bodyParsed, err := unmarshal([]byte(res.Body)); err == nil {
			response.BodyParsed = bodyParsed
		}
	}

	r.transformer(&request, *i, &response)

	// Pick up changes from response.BodyParsed and put them into
	// response.Body to send back to the ultimate requestor.
	if response.BodyParsed != nil {
		resBody, err := json.Marshal(response.BodyParsed)
		if err != nil {
			debugLogf("\t-> Returning error from invokeTransformer: %v", err)
			return nil, nil, err
		}
		response.Body = string(resBody)
	}

	return i, &response, nil
}

func (r *Recorder) recordInteraction(req *http.Request, realTransport http.RoundTripper) (*Interaction, *Response, error) {
	// Copy the original request, so we can read the form values
	reqBytes, err := httputil.DumpRequestOut(req, true)
	if err != nil {
		debugLogf("-=-=-=- Error from httputil.DumpRequestOut: %v", err)
		return nil, nil, err
	}

	reqBuffer := bytes.NewBuffer(reqBytes)
	copiedReq, err := http.ReadRequest(bufio.NewReader(reqBuffer))
	if err != nil {
		debugLogf("-=-=-=- Error from http.ReadRequest: %v", err)
		return nil, nil, err
	}

	err = copiedReq.ParseForm()
	if err != nil {
		debugLogf("-=-=-=- Error from copiedReq.ParseForm: %v", err)
		return nil, nil, err
	}

	reqBody := &bytes.Buffer{}
	if req.Body != nil {
		// Record the request body so we can add it to the scenario
		req.Body = ioutil.NopCloser(io.TeeReader(req.Body, reqBody))
	}

	// Perform client request to its original
	// destination and record interactions
	resp, err := realTransport.RoundTrip(req)
	if err != nil {
		debugLogf("-=-=-=- Error from realTransport.RoundTrip: %v", err)
		return nil, nil, err
	}

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		debugLogf("-=-=-=- Error from ioutil.ReadAll: %v", err)
		return nil, nil, err
	}

	// Add interaction to scenario
	interaction := &Interaction{
		Request: Request{
			Body:    reqBody.String(),
			Form:    copiedReq.PostForm,
			Headers: req.Header,
			URL:     req.URL.String(),
			Method:  req.Method,
		},
		Response: Response{
			Body:    string(respBody),
			Headers: resp.Header,
			Status:  resp.Status,
			Code:    resp.StatusCode,
		},
	}
	r.scenario.AddInteraction(interaction)

	return interaction, &interaction.Response, nil
}

func (r *Recorder) requestHandler(req *http.Request, realTransport http.RoundTripper) (*Interaction, *Response, error) {
	// Return interaction from scenario if in replay mode
	if r.mode == ModeReplaying {
		return r.invokeTransformer(req)
	}
	return r.recordInteraction(req, realTransport)
}

func InstallRecorderForRecodReplay(client *http.Client, recorder *Recorder) (HTTPRecordingClient, error) {
	err := recorder.HookTransport(client)
	if err != nil {
		debugLogf("Fail install Recorder: %v", err)
		return nil, err
	}
	return client, nil
}

// unmarshal seems like it should not be necessary, but sometimes json.Unmarshal will choose a type of map[interface{}]interface{} which will not downcast into a map[string]interface{}.
func unmarshal(body []byte) (interface{}, error) {
	var bodyParsed interface{}

	var decode = func(result interface{}) error {
		jsonDecoder := json.NewDecoder(bytes.NewReader(body))
		jsonDecoder.UseNumber()
		return jsonDecoder.Decode(result)
	}

	if 0 < len(body) {
		var bodyObjParsed jsonObj
		//if err := json.Unmarshal(body, &bodyObjParsed); err == nil {
		if err := decode(&bodyObjParsed); err == nil {
			bodyParsed = bodyObjParsed
		} else {
			var bodyArrParsed jsonArr
			//if err := json.Unmarshal(body, &bodyArrParsed); err == nil {
			if err := decode(&bodyArrParsed); err == nil {
				bodyParsed = bodyArrParsed
			} else {
				var bodyStrParsed jsonStr
				//if err := json.Unmarshal(body, &bodyStrParsed); err == nil {
				if err := decode(&bodyStrParsed); err == nil {
					bodyParsed = bodyStrParsed
				} else {
					return nil, err
				}
			}
		}
	}
	return bodyParsed, nil
}

// NewRecorder creates a new recorder
func NewRecorder(scenarioName string) (*Recorder, error) {
	// Default mode is "replay" if file exists
	return NewRecorderAsMode(scenarioName, ModeReplaying)
}

// NewRecorderAsMode creates a new recorder in the specified mode
func NewRecorderAsMode(scenarioName string, mode Mode) (*Recorder, error) {
	var s *Scenario
	var err error

	if mode != ModeDisabled {
		// Depending on whether the scenario file exists or not we
		// either create a new empty scenario or load from file
		if mode == ModeRecording {
			// Create new scenario and enter in recording mode
			s = NewScenario(scenarioName)
		} else {
			// Load scenario from file and enter replay mode
			s, err = Load(scenarioName)
			if err != nil {
				return nil, err
			}
			mode = ModeReplaying
		}
	}

	r := &Recorder{
		mode:        mode,
		scenario:    s,
		transformer: defaultTransformer,
	}

	return r, nil
}

// Stop is used to stop the recorder and save any recorded interactions
func (r *Recorder) Stop() error {
	if r.mode == ModeRecording {
		if err := r.scenario.Save(); err != nil {
			return err
		}
	}

	return nil
}

// RoundTrip implements the http.RoundTripper interface
func (r *Recorder) RoundTrip(req *http.Request, realTransport http.RoundTripper) (*http.Response, error) {
	if r.mode == ModeDisabled {
		response, err := realTransport.RoundTrip(req)
		if err != nil {
			return response, err
		}
	}
	// Pass scenario and mode to handler, so that interactions can be
	// retrieved or recorded depending on the current recorder mode
	interaction, resp, err := r.requestHandler(req, realTransport)

	if err != nil {
		debugLogf("-==-==-==- Error return from RoundTrip: %v", err)
		return nil, err
	}

	select {
	case <-req.Context().Done():
		debugLogf("-==-==-==- Error return from RoundTrip: %v", req.Context().Err())
		return nil, req.Context().Err()
	default:
		buf := bytes.NewBuffer([]byte(resp.Body))
		// apply the duration defined in the interaction
		if false && resp.Duration != "" {
			d, err := time.ParseDuration(interaction.Duration)
			if err != nil {
				debugLogf("-==-==-==- Error return from RoundTrip: %v", err)
				return nil, err
			}
			// block for the configured 'duration' to simulate the network latency and server processing time.
			if _, ok := os.LookupEnv("TF_VAR_SLOW_REPLAY"); ok {
				<-time.After(d)
			}
		}

		theResp := http.Response{
			Status:        resp.Status,
			StatusCode:    resp.Code,
			Proto:         "HTTP/1.0",
			ProtoMajor:    1,
			ProtoMinor:    0,
			Request:       req,
			Header:        resp.Headers,
			Close:         true,
			ContentLength: int64(buf.Len()),
			Body:          ioutil.NopCloser(buf),
		}
		return &theResp, nil
	}
}

// CancelRequest implements the github.com/coreos/etcd/client.CancelableTransport interface
func (r *Recorder) CancelRequest(req *http.Request, realTransport http.RoundTripper) {
	type cancelableTransport interface {
		CancelRequest(req *http.Request)
	}
	if ct, ok := realTransport.(cancelableTransport); ok {
		ct.CancelRequest(req)
	}
}

// SetMatcher sets a function to match requests against recorded HTTP interactions.
func (r *Recorder) SetMatcher(matcher Matcher) {
	if r.scenario != nil {
		r.scenario.Matcher = matcher
	}
}
<commit_msg>TER-1300: remove Authorization from the header<commit_after>// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.

package httpreplay

import (
	"bufio"
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"os"
	"sync"
	"time"
)

// Mode represents recording/playback mode
type Mode int

// Recorder states
const (
	ModeRecording Mode = iota
	ModeReplaying
	ModeDisabled
)

// Transformer converts a request and a saved interaction into a result.  The Interaction is passed by value to suggest that it should not be modified.
type Transformer func(*Request, Interaction, *Response)

type jsonObj map[string]interface{}
type jsonArr []jsonObj
type jsonStr string

func defaultTransformer(req *Request, i Interaction, res *Response) {
}

type roundTripperProxy struct {
	recorder *Recorder
	chained  http.RoundTripper
}

func (rtp *roundTripperProxy) RoundTrip(r *http.Request) (*http.Response, error) {
	return rtp.recorder.RoundTrip(r, rtp.chained)
}

func (rtp *roundTripperProxy) CancelRequest(r *http.Request) {
	rtp.recorder.CancelRequest(r, rtp.chained)
}

// Recorder represents a type used to record and replay
// client and server interactions
type Recorder struct {
	// Operating mode of the recorder
	mode Mode

	// Scenario used by the recorder
	scenario *Scenario

	// transformer is used to adjust responses to match changes in requests
	transformer Transformer

	// count is for debug logging -- how many requests have been matched
	count int
}

// HookTransport makes a new transport and chains the one passed in with it, returning the new one
func (r *Recorder) HookTransport(client *http.Client) error {
	if r == nil {
		return errors.New("The test case missing calling SetScenerio() ")
	}
	if _, ok := client.Transport.(*roundTripperProxy); !ok {
		proxy := roundTripperProxy{
			recorder: r,
			chained:  client.Transport,
		}
		client.Transport = &proxy
	}
	return nil
}

// SetTransformer can be used to override the default (no-op) transformer
func (r *Recorder) SetTransformer(t Transformer) {
	r.transformer = t
}

var mut sync.RWMutex

func (r *Recorder) invokeTransformer(req *http.Request) (*Interaction, *Response, error) {
	mut.Lock()
	defer mut.Unlock()
	if err := req.ParseForm(); err != nil {
		debugLogf("\t-> Returning error from invokeTransformer: %v", err)
		//return nil, nil, err
	}

	reqBody := make([]byte, req.ContentLength)
	if _, err := io.ReadFull(req.Body, reqBody); err != nil {
		debugLogf("\t-> Returning error from invokeTransformer: %v", err)
		return nil, nil, err
	}

	var bodyParsed interface{}
	if len(reqBody) != 0 {
		bodyParsed, _ = unmarshal(reqBody)
	}

	request := Request{
		Body:       string(reqBody),
		BodyParsed: bodyParsed,
		Form:       req.PostForm,
		Headers:    req.Header,
		URL:        req.URL.String(),
		Method:     req.Method,
	}

	i, err := r.scenario.GetInteraction(request)
	if err != nil {
		if err.Error() == "Requested interaction not found" {
			debugLogf("\t-> Convert full path of request to find Interaction:")
			i, err = r.scenario.GetInteractionWithFullPath(request)
			if err != nil {
				debugLogf("\t-> Returning error from invokeTransformer: %v", err)
				return nil, nil, err
			}
		}
	}
	i.Request.BodyParsed, _ = unmarshal([]byte(i.Request.Body))
	i.Response.BodyParsed, _ = unmarshal([]byte(i.Response.Body))
	debugLogf("\t=> => Request %d matched interaction %d", r.count, i.Index)
	r.count++

	res := i.Response
	response := Response{
		Body:     res.Body,
		Headers:  res.Headers,
		Status:   res.Status,
		Code:     res.Code,
		Duration: res.Duration,
	}

	if len(res.Body) > 0 {
		if bodyParsed, err := unmarshal([]byte(res.Body)); err == nil {
			response.BodyParsed = bodyParsed
		}
	}

	r.transformer(&request, *i, &response)

	// Pick up changes from response.BodyParsed and put them into
	// response.Body to send back to the ultimate requestor.
	if response.BodyParsed != nil {
		resBody, err := json.Marshal(response.BodyParsed)
		if err != nil {
			debugLogf("\t-> Returning error from invokeTransformer: %v", err)
			return nil, nil, err
		}
		response.Body = string(resBody)
	}

	return i, &response, nil
}

func (r *Recorder) recordInteraction(req *http.Request, realTransport http.RoundTripper) (*Interaction, *Response, error) {
	// Copy the original request, so we can read the form values
	reqBytes, err := httputil.DumpRequestOut(req, true)
	if err != nil {
		debugLogf("-=-=-=- Error from httputil.DumpRequestOut: %v", err)
		return nil, nil, err
	}

	reqBuffer := bytes.NewBuffer(reqBytes)
	copiedReq, err := http.ReadRequest(bufio.NewReader(reqBuffer))
	if err != nil {
		debugLogf("-=-=-=- Error from http.ReadRequest: %v", err)
		return nil, nil, err
	}

	err = copiedReq.ParseForm()
	if err != nil {
		debugLogf("-=-=-=- Error from copiedReq.ParseForm: %v", err)
		return nil, nil, err
	}

	reqBody := &bytes.Buffer{}
	if req.Body != nil {
		// Record the request body so we can add it to the scenario
		req.Body = ioutil.NopCloser(io.TeeReader(req.Body, reqBody))
	}

	// Perform client request to its original
	// destination and record interactions
	resp, err := realTransport.RoundTrip(req)
	if err != nil {
		debugLogf("-=-=-=- Error from realTransport.RoundTrip: %v", err)
		return nil, nil, err
	}

	req.Header.Del("Authorization")
	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		debugLogf("-=-=-=- Error from ioutil.ReadAll: %v", err)
		return nil, nil, err
	}

	// Add interaction to scenario
	interaction := &Interaction{
		Request: Request{
			Body:    reqBody.String(),
			Form:    copiedReq.PostForm,
			Headers: req.Header,
			URL:     req.URL.String(),
			Method:  req.Method,
		},
		Response: Response{
			Body:    string(respBody),
			Headers: resp.Header,
			Status:  resp.Status,
			Code:    resp.StatusCode,
		},
	}
	r.scenario.AddInteraction(interaction)

	return interaction, &interaction.Response, nil
}

func (r *Recorder) requestHandler(req *http.Request, realTransport http.RoundTripper) (*Interaction, *Response, error) {
	// Return interaction from scenario if in replay mode
	if r.mode == ModeReplaying {
		return r.invokeTransformer(req)
	}
	return r.recordInteraction(req, realTransport)
}

func InstallRecorderForRecodReplay(client *http.Client, recorder *Recorder) (HTTPRecordingClient, error) {
	err := recorder.HookTransport(client)
	if err != nil {
		debugLogf("Fail install Recorder: %v", err)
		return nil, err
	}
	return client, nil
}

// unmarshal seems like it should not be necessary, but sometimes json.Unmarshal will choose a type of map[interface{}]interface{} which will not downcast into a map[string]interface{}.
func unmarshal(body []byte) (interface{}, error) {
	var bodyParsed interface{}

	var decode = func(result interface{}) error {
		jsonDecoder := json.NewDecoder(bytes.NewReader(body))
		jsonDecoder.UseNumber()
		return jsonDecoder.Decode(result)
	}

	if 0 < len(body) {
		var bodyObjParsed jsonObj
		//if err := json.Unmarshal(body, &bodyObjParsed); err == nil {
		if err := decode(&bodyObjParsed); err == nil {
			bodyParsed = bodyObjParsed
		} else {
			var bodyArrParsed jsonArr
			//if err := json.Unmarshal(body, &bodyArrParsed); err == nil {
			if err := decode(&bodyArrParsed); err == nil {
				bodyParsed = bodyArrParsed
			} else {
				var bodyStrParsed jsonStr
				//if err := json.Unmarshal(body, &bodyStrParsed); err == nil {
				if err := decode(&bodyStrParsed); err == nil {
					bodyParsed = bodyStrParsed
				} else {
					return nil, err
				}
			}
		}
	}
	return bodyParsed, nil
}

// NewRecorder creates a new recorder
func NewRecorder(scenarioName string) (*Recorder, error) {
	// Default mode is "replay" if file exists
	return NewRecorderAsMode(scenarioName, ModeReplaying)
}

// NewRecorderAsMode creates a new recorder in the specified mode
func NewRecorderAsMode(scenarioName string, mode Mode) (*Recorder, error) {
	var s *Scenario
	var err error

	if mode != ModeDisabled {
		// Depending on whether the scenario file exists or not we
		// either create a new empty scenario or load from file
		if mode == ModeRecording {
			// Create new scenario and enter in recording mode
			s = NewScenario(scenarioName)
		} else {
			// Load scenario from file and enter replay mode
			s, err = Load(scenarioName)
			if err != nil {
				return nil, err
			}
			mode = ModeReplaying
		}
	}

	r := &Recorder{
		mode:        mode,
		scenario:    s,
		transformer: defaultTransformer,
	}

	return r, nil
}

// Stop is used to stop the recorder and save any recorded interactions
func (r *Recorder) Stop() error {
	if r.mode == ModeRecording {
		if err := r.scenario.Save(); err != nil {
			return err
		}
	}

	return nil
}

// RoundTrip implements the http.RoundTripper interface
func (r *Recorder) RoundTrip(req *http.Request, realTransport http.RoundTripper) (*http.Response, error) {
	if r.mode == ModeDisabled {
		response, err := realTransport.RoundTrip(req)
		if err != nil {
			return response, err
		}
	}
	// Pass scenario and mode to handler, so that interactions can be
	// retrieved or recorded depending on the current recorder mode
	interaction, resp, err := r.requestHandler(req, realTransport)

	if err != nil {
		debugLogf("-==-==-==- Error return from RoundTrip: %v", err)
		return nil, err
	}

	select {
	case <-req.Context().Done():
		debugLogf("-==-==-==- Error return from RoundTrip: %v", req.Context().Err())
		return nil, req.Context().Err()
	default:
		buf := bytes.NewBuffer([]byte(resp.Body))
		// apply the duration defined in the interaction
		if false && resp.Duration != "" {
			d, err := time.ParseDuration(interaction.Duration)
			if err != nil {
				debugLogf("-==-==-==- Error return from RoundTrip: %v", err)
				return nil, err
			}
			// block for the configured 'duration' to simulate the network latency and server processing time.
			if _, ok := os.LookupEnv("TF_VAR_SLOW_REPLAY"); ok {
				<-time.After(d)
			}
		}

		theResp := http.Response{
			Status:        resp.Status,
			StatusCode:    resp.Code,
			Proto:         "HTTP/1.0",
			ProtoMajor:    1,
			ProtoMinor:    0,
			Request:       req,
			Header:        resp.Headers,
			Close:         true,
			ContentLength: int64(buf.Len()),
			Body:          ioutil.NopCloser(buf),
		}
		return &theResp, nil
	}
}

// CancelRequest implements the github.com/coreos/etcd/client.CancelableTransport interface
func (r *Recorder) CancelRequest(req *http.Request, realTransport http.RoundTripper) {
	type cancelableTransport interface {
		CancelRequest(req *http.Request)
	}
	if ct, ok := realTransport.(cancelableTransport); ok {
		ct.CancelRequest(req)
	}
}

// SetMatcher sets a function to match requests against recorded HTTP interactions.
func (r *Recorder) SetMatcher(matcher Matcher) {
	if r.scenario != nil {
		r.scenario.Matcher = matcher
	}
}
<|endoftext|>


<commit_before>package hueserver

import (
	"encoding/json"
	"net/http"
	"text/template"
	"time"

	"github.com/facebookgo/httpdown"
	"github.com/labstack/echo"
	"github.com/labstack/echo/engine/standard"
	"github.com/labstack/echo/middleware"
)

var setupTemplate = template.Must(template.New("setup").Parse(`<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
  <specVersion>
    <major>1</major>
    <minor>0</minor>
  </specVersion>
  <URLBase>http://{{.URLBase}}/</URLBase>
  <device>
    <deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>
    <friendlyName>{{.FriendlyName}}</friendlyName>
    <manufacturer>Royal Philips Electronics</manufacturer>
    <modelName>Philips hue bridge 2012</modelName>
    <modelNumber>929000226503</modelNumber>
    <UDN>uuid:{{.UUID}}</UDN>
  </device>
</root>`))

type LightState struct {
	On        bool      `json:"on"`
	Bri       int       `json:"bri"`
	Hue       int       `json:"hue"`
	Sat       int       `json:"sat"`
	Effect    string    `json:"effect"`
	Ct        int       `json:"ct"`
	Alert     string    `json:"alert"`
	Colormode string    `json:"colormode"`
	Reachable bool      `json:"reachable"`
	XY        []float64 `json:"xy"`
}

type LightStateChange struct {
	On             *bool   `json:"on,omitempty"`
	Bri            *int    `json:"bri,omitempty"`
	Hue            *int    `json:"hue,omitempty"`
	Sat            *int    `json:"sat,omitempty"`
	Effect         *string `json:"effect,omitempty"`
	Ct             *int    `json:"ct,omitempty"`
	Alert          *string `json:"alert,omitempty"`
	Colormode      *string `json:"colormode,omitempty"`
	TransitionTime int     `json:"transitiontime,omitempty"`
}

type LightStateChangeResponse []struct {
	Success map[string]interface{} `json:"success,omitempty"`
}

type Light struct {
	State            LightState `json:"state"`
	Type             string     `json:"type"`
	Name             string     `json:"name"`
	ModelID          string     `json:"modelid"`
	ManufacturerName string     `json:"manufacturername"`
	UniqueID         string     `json:"uniqueid"`
	SwVersion        string     `json:"swversion"`
	PointSymbol      struct {
		One   string `json:"1"`
		Two   string `json:"2"`
		Three string `json:"3"`
		Four  string `json:"4"`
		Five  string `json:"5"`
		Six   string `json:"6"`
		Seven string `json:"7"`
		Eight string `json:"8"`
	} `json:"pointsymbol"`
}

type LightList map[string]Light

type Server struct {
	mux           *echo.Echo
	UUID          string
	FriendlyName  string
	URLBase       string
	GetLights     func() LightList
	GetLight      func(id string) Light
	SetLightState func(id string, state LightStateChange) LightStateChangeResponse
}

func (server *Server) Start(port string) error {
	hd := &httpdown.HTTP{
		StopTimeout: 8 * time.Second,
		KillTimeout: 2 * time.Second,
	}

	httpSrv := standard.New(port)
	httpSrv.SetHandler(server.mux)
	httpSrv.TLSConfig = nil
	return httpdown.ListenAndServe(httpSrv.Server, hd)
}

func (server *Server) serveSetupXML(c echo.Context) error {
	return setupTemplate.Execute(c.Response().Writer(), server)
}

func (server *Server) getLights(c echo.Context) error {
	return c.JSON(http.StatusOK, server.GetLights())
}

func (server *Server) getLight(c echo.Context) error {
	return c.JSON(http.StatusOK, server.GetLight(c.Param("lightId")))
}

func (server *Server) setLightState(c echo.Context) error {
	decoder := json.NewDecoder(c.Request().Body())
	state := &LightStateChange{}
	if err := decoder.Decode(state); err != nil {
		return err
	}
	lightID := c.Param("lightId")
	stateChangeResponse := server.SetLightState(lightID, *state)

	return c.JSON(http.StatusOK, stateChangeResponse)
}

func NewServer(uuid, urlBase, friendlyName string, getLights func() LightList, getLight func(id string) Light, setLightState func(id string, state LightStateChange) LightStateChangeResponse) (srv *Server) {
	srv = &Server{
		mux:           echo.New(),
		UUID:          uuid,
		FriendlyName:  friendlyName,
		URLBase:       urlBase,
		GetLights:     getLights,
		GetLight:      getLight,
		SetLightState: setLightState,
	}

	srv.mux.Use(middleware.Logger())
	srv.mux.Get("/upnp/setup.xml", srv.serveSetupXML)
	srv.mux.GET("/api/:userId", srv.getLights)
	srv.mux.GET("/api/:userId/lights", srv.getLights)
	srv.mux.PUT("/api/:userId/lights/:lightId/state", srv.setLightState)
	srv.mux.GET("/api/:userId/lights/:lightId", srv.getLight)

	return
}
<commit_msg>Make work with latest deps<commit_after>package hueserver

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

	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
)

var setupTemplate = template.Must(template.New("setup").Parse(`<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
  <specVersion>
    <major>1</major>
    <minor>0</minor>
  </specVersion>
  <URLBase>http://{{.URLBase}}/</URLBase>
  <device>
    <deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>
    <friendlyName>{{.FriendlyName}}</friendlyName>
    <manufacturer>Royal Philips Electronics</manufacturer>
    <modelName>Philips hue bridge 2012</modelName>
    <modelNumber>929000226503</modelNumber>
    <UDN>uuid:{{.UUID}}</UDN>
  </device>
</root>`))

type LightState struct {
	On        bool      `json:"on"`
	Bri       int       `json:"bri"`
	Hue       int       `json:"hue"`
	Sat       int       `json:"sat"`
	Effect    string    `json:"effect"`
	Ct        int       `json:"ct"`
	Alert     string    `json:"alert"`
	Colormode string    `json:"colormode"`
	Reachable bool      `json:"reachable"`
	XY        []float64 `json:"xy"`
}

type LightStateChange struct {
	On             *bool   `json:"on,omitempty"`
	Bri            *int    `json:"bri,omitempty"`
	Hue            *int    `json:"hue,omitempty"`
	Sat            *int    `json:"sat,omitempty"`
	Effect         *string `json:"effect,omitempty"`
	Ct             *int    `json:"ct,omitempty"`
	Alert          *string `json:"alert,omitempty"`
	Colormode      *string `json:"colormode,omitempty"`
	TransitionTime int     `json:"transitiontime,omitempty"`
}

type LightStateChangeResponse []struct {
	Success map[string]interface{} `json:"success,omitempty"`
}

type Light struct {
	State            LightState `json:"state"`
	Type             string     `json:"type"`
	Name             string     `json:"name"`
	ModelID          string     `json:"modelid"`
	ManufacturerName string     `json:"manufacturername"`
	UniqueID         string     `json:"uniqueid"`
	SwVersion        string     `json:"swversion"`
	PointSymbol      struct {
		One   string `json:"1"`
		Two   string `json:"2"`
		Three string `json:"3"`
		Four  string `json:"4"`
		Five  string `json:"5"`
		Six   string `json:"6"`
		Seven string `json:"7"`
		Eight string `json:"8"`
	} `json:"pointsymbol"`
}

type LightList map[string]Light

type Server struct {
	mux           *echo.Echo
	UUID          string
	FriendlyName  string
	URLBase       string
	GetLights     func() LightList
	GetLight      func(id string) Light
	SetLightState func(id string, state LightStateChange) LightStateChangeResponse
}

func (server *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	server.mux.ServeHTTP(w, r)
}

func (server *Server) Start(port string) error {
	return http.ListenAndServe(port, server)
}

func (server *Server) serveSetupXML(c echo.Context) error {
	return setupTemplate.Execute(c.Response().Writer(), server)
}

func (server *Server) getLights(c echo.Context) error {
	return c.JSON(http.StatusOK, server.GetLights())
}

func (server *Server) getLight(c echo.Context) error {
	return c.JSON(http.StatusOK, server.GetLight(c.Param("lightId")))
}

func (server *Server) setLightState(c echo.Context) error {
	defer c.Request().Body.Close()
	decoder := json.NewDecoder(c.Request().Body)
	state := &LightStateChange{}
	if err := decoder.Decode(state); err != nil {
		return err
	}
	lightID := c.Param("lightId")
	stateChangeResponse := server.SetLightState(lightID, *state)

	return c.JSON(http.StatusOK, stateChangeResponse)
}

func NewServer(uuid, urlBase, friendlyName string, getLights func() LightList, getLight func(id string) Light, setLightState func(id string, state LightStateChange) LightStateChangeResponse) (srv *Server) {
	srv = &Server{
		mux:           echo.New(),
		UUID:          uuid,
		FriendlyName:  friendlyName,
		URLBase:       urlBase,
		GetLights:     getLights,
		GetLight:      getLight,
		SetLightState: setLightState,
	}

	srv.mux.Use(middleware.Logger())
	srv.mux.GET("/upnp/setup.xml", srv.serveSetupXML)
	srv.mux.GET("/api/:userId", srv.getLights)
	srv.mux.GET("/api/:userId/lights", srv.getLights)
	srv.mux.PUT("/api/:userId/lights/:lightId/state", srv.setLightState)
	srv.mux.GET("/api/:userId/lights/:lightId", srv.getLight)

	return
}
<|endoftext|>


<commit_before>package endly

import (
	"fmt"
	"github.com/viant/toolbox"
	"github.com/viant/toolbox/url"
	"path"
	"strings"
)

//DaemonServiceID represents system daemon service
const DaemonServiceID = "daemon"

const (
	serviceTypeError = iota
	serviceTypeInitDaemon
	serviceTypeLaunchCtl
	serviceTypeStdService
	serviceTypeSystemctl
)

type daemonService struct {
	*AbstractService
}

func (s *daemonService) Run(context *Context, request interface{}) *ServiceResponse {
	startEvent := s.Begin(context, request, Pairs("request", request))
	var response = &ServiceResponse{Status: "ok"}
	defer s.End(context)(startEvent, Pairs("response", response))
	var err error
	switch actualRequest := request.(type) {
	case *DaemonStartRequest:
		response.Response, err = s.startService(context, actualRequest)
		if err != nil {
			response.Error = fmt.Sprintf("Failed to start service: %v, %v", actualRequest.Service, err)
		}
	case *DaemonStopRequest:
		response.Response, err = s.stopService(context, actualRequest)
		if err != nil {
			response.Error = fmt.Sprintf("Failed to stop service: %v, %v", actualRequest.Service, err)
		}
	case *DaemonStatusRequest:
		response.Response, err = s.checkService(context, actualRequest)
		if err != nil {
			response.Error = fmt.Sprintf("Failed to check status service: %v, %v", actualRequest.Service, err)
		}
	}
	if response.Error != "" {
		response.Status = "err"
	}
	return response
}

func (s *daemonService) NewRequest(action string) (interface{}, error) {
	switch action {
	case "status":
		return &DaemonStatusRequest{}, nil
	case "start":
		return &DaemonStartRequest{}, nil
	case "stop":
		return &DaemonStopRequest{}, nil
	}
	return s.AbstractService.NewRequest(action)
}

func (s *daemonService) determineServiceType(context *Context, service, exclusion string, target *url.Resource) (int, string, error) {
	if exclusion != "" {
		exclusion = " | grep -v " + exclusion
	}
	commandResult, err := context.Execute(target, &ManagedCommand{
		Executions: []*Execution{
			{
				Command: fmt.Sprintf("ls /Library/LaunchDaemons/ | grep %v %v", service, exclusion),
			},
		},
	})
	if err != nil {
		return 0, "", err
	}
	if !CheckNoSuchFileOrDirectory(commandResult.Stdout()) {
		file := strings.TrimSpace(commandResult.Stdout())
		if len(file) > 0 {
			servicePath := path.Join("/Library/LaunchDaemons/", file)
			return serviceTypeLaunchCtl, servicePath, nil
		}
		return serviceTypeLaunchCtl, "", nil

	}

	commandResult, err = context.ExecuteAsSuperUser(target, &ManagedCommand{
		Options: &ExecutionOptions{
			Terminators: []string{"(END)"},
		},
		Executions: []*Execution{
			{
				Command: "service " + service + " status",
			},
			{
				Secure:      "",
				MatchOutput: "(END)", //quite multiline mode
				Command:     "Q",
			},
		},
	})

	if err != nil {
		return 0, "", err
	}
	if !CheckCommandNotFound(commandResult.Stdout()) {
		return serviceTypeStdService, service, nil
	}
	commandResult, err = context.ExecuteAsSuperUser(target, &ManagedCommand{
		Executions: []*Execution{
			{
				Command: "systemctl status " + service,
			},
		},
	})
	if err != nil {
		return 0, "", err
	}

	if !CheckCommandNotFound(commandResult.Stdout()) {
		return serviceTypeSystemctl, service, nil
	}

	return serviceTypeError, "", nil
}

func extractServiceInfo(state map[string]string, info *DaemonInfo) {
	if pid, ok := state["pid"]; ok {
		info.Pid = toolbox.AsInt(pid)
	}
	if state, ok := state["state"]; ok {
		if strings.Contains(state, "inactive") {
			state = "not running"
		} else if strings.Contains(state, "active") {
			state = "running"
		}
		info.State = state
	}
	if path, ok := state["path"]; ok {
		info.Path = path
	}
}

func (s *daemonService) checkService(context *Context, request *DaemonStatusRequest) (*DaemonInfo, error) {

	if request.Service == "" {
		return nil, fmt.Errorf("Service was empty")
	}
	serviceType, serviceInit, err := s.determineServiceType(context, request.Service, request.Exclusion, request.Target)
	if err != nil {
		return nil, err
	}

	target, err := context.ExpandResource(request.Target)
	if err != nil {
		return nil, err
	}

	var result = &DaemonInfo{
		Service: request.Service,
		Type:    serviceType,
		Init:    serviceInit,
	}
	command := ""

	if serviceInit == "" && serviceType == serviceTypeLaunchCtl {
		return result, nil
	}

	switch serviceType {
	case serviceTypeError:
		return nil, fmt.Errorf("Unknown daemon service type")
	case serviceTypeLaunchCtl:

		exclusion := request.Exclusion
		if exclusion != "" {
			exclusion = " | grep -v " + exclusion
		}

		commandResult, err := context.ExecuteAsSuperUser(target, &ManagedCommand{
			Executions: []*Execution{
				{
					Command: fmt.Sprintf("launchctl list | grep %v %v", request.Service, exclusion),
					Extraction: DataExtractions{
						{
							Key:     "pid",
							RegExpr: "(\\d+)[^\\d]+",
						},
					},
					Error: []string{"Unrecognized"},
				},
				{
					Command: "launchctl procinfo $pid",
					Extraction: DataExtractions{
						{
							Key:     "path",
							RegExpr: "program path[\\s|\\t]+=[\\s|\\t]+([^\\s]+)",
						},
						{
							Key:     "state",
							RegExpr: "[\\s|\\t]+state[\\s|\\t]+=[\\s|\\t]+([^s]+)",
						},
					},
					Error: []string{"Unrecognized"},
				},
			},
		})
		if err != nil {
			return nil, err
		}

		extractServiceInfo(commandResult.Extracted, result)
		return result, nil

	case serviceTypeSystemctl:
		command = fmt.Sprintf("systemctl status %v ", serviceInit)
	case serviceTypeStdService:
		command = fmt.Sprintf("service %v status", serviceInit)
	case serviceTypeInitDaemon:
		command = fmt.Sprintf("%v status", serviceInit)
	}

	commandResult, err := context.ExecuteAsSuperUser(target, &ManagedCommand{
		Options: &ExecutionOptions{
			Terminators: []string{"(END)"},
		},
		Executions: []*Execution{

			{
				Command: command,
				Extraction: DataExtractions{
					{
						Key:     "pid",
						RegExpr: "[^└]+└─(\\d+).+",
					},
					{
						Key:     "pid",
						RegExpr: " Main PID: (\\d+).+",
					},
					{
						Key:     "state",
						RegExpr: "[\\s|\\t]+Active:\\s+(\\S+)",
					},
					{
						Key:     "path",
						RegExpr: "[^└]+└─\\d+[\\s\\t].(.+)",
					},
				},
			},
			{
				Secure:      "",
				MatchOutput: "(END)", //quite multiline mode
				Command:     "Q",
			},
		},
	})
	if err != nil {
		return nil, err
	}

	extractServiceInfo(commandResult.Extracted, result)
	return result, nil

}

func (s *daemonService) stopService(context *Context, request *DaemonStopRequest) (*DaemonInfo, error) {
	serviceInfo, err := s.checkService(context, &DaemonStatusRequest{
		Target:    request.Target,
		Service:   request.Service,
		Exclusion: request.Exclusion,
	})
	if err != nil {
		return nil, err
	}
	if !serviceInfo.IsActive() {
		return serviceInfo, nil
	}
	target, err := context.ExpandResource(request.Target)
	if err != nil {
		return nil, err
	}
	command := ""
	switch serviceInfo.Type {
	case serviceTypeError:
		return nil, fmt.Errorf("Unknown daemon service type")
	case serviceTypeLaunchCtl:
		command = fmt.Sprintf("launchctl unload -F %v", serviceInfo.Init)
	case serviceTypeSystemctl:
		command = fmt.Sprintf("systemctl stop %v ", serviceInfo.Init)
	case serviceTypeStdService:
		command = fmt.Sprintf("service %v stop", serviceInfo.Init)
	case serviceTypeInitDaemon:
		command = fmt.Sprintf("%v stop", serviceInfo.Init)
	}

	commandResult, err := context.ExecuteAsSuperUser(target, &ManagedCommand{
		Executions: []*Execution{
			{
				Command: command,
			},
		},
	})
	if CheckCommandNotFound(commandResult.Stdout()) {
		return nil, fmt.Errorf("%v", commandResult.Stdout)
	}
	return s.checkService(context, &DaemonStatusRequest{
		Target:    request.Target,
		Service:   request.Service,
		Exclusion: request.Exclusion,
	})
}

func (s *daemonService) startService(context *Context, request *DaemonStartRequest) (*DaemonInfo, error) {
	serviceInfo, err := s.checkService(context, &DaemonStatusRequest{
		Target:    request.Target,
		Service:   request.Service,
		Exclusion: request.Exclusion,
	})
	if err != nil {
		return nil, err
	}
	if serviceInfo.IsActive() {
		return serviceInfo, nil
	}
	target, err := context.ExpandResource(request.Target)
	if err != nil {
		return nil, err
	}
	command := ""
	switch serviceInfo.Type {
	case serviceTypeError:
		return nil, fmt.Errorf("Unknown daemon service type")
	case serviceTypeLaunchCtl:
		command = fmt.Sprintf("launchctl load -F %v", serviceInfo.Init)
	case serviceTypeSystemctl:
		command = fmt.Sprintf("systemctl start %v ", serviceInfo.Init)
	case serviceTypeStdService:
		command = fmt.Sprintf("service %v start", serviceInfo.Init)
	case serviceTypeInitDaemon:
		command = fmt.Sprintf("%v start", serviceInfo.Init)
	}

	commandResult, err := context.ExecuteAsSuperUser(target, &ManagedCommand{
		Executions: []*Execution{
			{
				Command: command,
			},
		},
	})
	if CheckCommandNotFound(commandResult.Stdout()) {
		return nil, fmt.Errorf("%v", commandResult.Stdout)
	}
	return s.checkService(context, &DaemonStatusRequest{
		Target:    request.Target,
		Service:   request.Service,
		Exclusion: request.Exclusion,
	})
}

//NewDaemonService creates a new system service.
func NewDaemonService() Service {
	var result = &daemonService{
		AbstractService: NewAbstractService(DaemonServiceID),
	}
	result.AbstractService.Service = result
	return result
}
<commit_msg>patched deamon state detection on osx<commit_after>package endly

import (
	"fmt"
	"github.com/viant/toolbox"
	"github.com/viant/toolbox/url"
	"path"
	"strings"
	"github.com/lunixbochs/vtclean"
)

//DaemonServiceID represents system daemon service
const DaemonServiceID = "daemon"

const (
	serviceTypeError = iota
	serviceTypeInitDaemon
	serviceTypeLaunchCtl
	serviceTypeStdService
	serviceTypeSystemctl
)

type daemonService struct {
	*AbstractService
}

func (s *daemonService) Run(context *Context, request interface{}) *ServiceResponse {
	startEvent := s.Begin(context, request, Pairs("request", request))
	var response = &ServiceResponse{Status: "ok"}
	defer s.End(context)(startEvent, Pairs("response", response))
	var err error
	switch actualRequest := request.(type) {
	case *DaemonStartRequest:
		response.Response, err = s.startService(context, actualRequest)
		if err != nil {
			response.Error = fmt.Sprintf("Failed to start service: %v, %v", actualRequest.Service, err)
		}
	case *DaemonStopRequest:
		response.Response, err = s.stopService(context, actualRequest)
		if err != nil {
			response.Error = fmt.Sprintf("Failed to stop service: %v, %v", actualRequest.Service, err)
		}
	case *DaemonStatusRequest:
		response.Response, err = s.checkService(context, actualRequest)
		if err != nil {
			response.Error = fmt.Sprintf("Failed to check status service: %v, %v", actualRequest.Service, err)
		}
	}
	if response.Error != "" {
		response.Status = "err"
	}
	return response
}

func (s *daemonService) NewRequest(action string) (interface{}, error) {
	switch action {
	case "status":
		return &DaemonStatusRequest{}, nil
	case "start":
		return &DaemonStartRequest{}, nil
	case "stop":
		return &DaemonStopRequest{}, nil
	}
	return s.AbstractService.NewRequest(action)
}

func (s *daemonService) determineServiceType(context *Context, service, exclusion string, target *url.Resource) (int, string, error) {
	if exclusion != "" {
		exclusion = " | grep -v " + exclusion
	}
	commandResult, err := context.Execute(target, &ManagedCommand{
		Executions: []*Execution{
			{
				Command: fmt.Sprintf("ls /Library/LaunchDaemons/ | grep %v %v", service, exclusion),
			},
		},
	})
	if err != nil {
		return 0, "", err
	}
	if !CheckNoSuchFileOrDirectory(commandResult.Stdout()) {
		file := strings.TrimSpace(commandResult.Stdout())
		if len(file) > 0 {
			servicePath := path.Join("/Library/LaunchDaemons/", file)
			return serviceTypeLaunchCtl, servicePath, nil
		}
		return serviceTypeLaunchCtl, "", nil

	}

	commandResult, err = context.ExecuteAsSuperUser(target, &ManagedCommand{
		Options: &ExecutionOptions{
			Terminators: []string{"(END)"},
		},
		Executions: []*Execution{
			{
				Command: "service " + service + " status",
			},
			{
				Secure:      "",
				MatchOutput: "(END)", //quite multiline mode
				Command:     "Q",
			},
		},
	})

	if err != nil {
		return 0, "", err
	}
	if !CheckCommandNotFound(commandResult.Stdout()) {
		return serviceTypeStdService, service, nil
	}
	commandResult, err = context.ExecuteAsSuperUser(target, &ManagedCommand{
		Executions: []*Execution{
			{
				Command: "systemctl status " + service,
			},
		},
	})
	if err != nil {
		return 0, "", err
	}

	if !CheckCommandNotFound(commandResult.Stdout()) {
		return serviceTypeSystemctl, service, nil
	}

	return serviceTypeError, "", nil
}

func extractServiceInfo(state map[string]string, info *DaemonInfo) {
	if pid, ok := state["pid"]; ok {
		info.Pid = toolbox.AsInt(pid)
	}
	if value, ok := state["state"]; ok {
		state := vtclean.Clean(value, false)
		if strings.Contains(state, "inactive") {
			state = "not running"
		} else if strings.Contains(state, "active")   {
			state = "running"
		}
		info.State = state
	}
	if path, ok := state["path"]; ok {
		info.Path = path
	}
}

func (s *daemonService) checkService(context *Context, request *DaemonStatusRequest) (*DaemonInfo, error) {

	if request.Service == "" {
		return nil, fmt.Errorf("Service was empty")
	}
	serviceType, serviceInit, err := s.determineServiceType(context, request.Service, request.Exclusion, request.Target)
	if err != nil {
		return nil, err
	}

	target, err := context.ExpandResource(request.Target)
	if err != nil {
		return nil, err
	}

	var result = &DaemonInfo{
		Service: request.Service,
		Type:    serviceType,
		Init:    serviceInit,
	}
	command := ""

	if serviceInit == "" && serviceType == serviceTypeLaunchCtl {
		return result, nil
	}

	switch serviceType {
	case serviceTypeError:
		return nil, fmt.Errorf("Unknown daemon service type")
	case serviceTypeLaunchCtl:

		exclusion := request.Exclusion
		if exclusion != "" {
			exclusion = " | grep -v " + exclusion
		}

		commandResult, err := context.ExecuteAsSuperUser(target, &ManagedCommand{
			Executions: []*Execution{
				{
					Command: fmt.Sprintf("launchctl list | grep %v %v", request.Service, exclusion),
					Extraction: DataExtractions{
						{
							Key:     "pid",
							RegExpr: "(\\d+)[^\\d]+",
						},
					},
					Error: []string{"Unrecognized"},
				},
				{
					Command: "launchctl procinfo $pid",
					Extraction: DataExtractions{
						{
							Key:     "path",
							RegExpr: "program path[\\s|\\t]+=[\\s|\\t]+([^\\s]+)",
						},
						{
							Key:     "state",
							RegExpr: "state = (running)",
						},

					},
					Error: []string{"Unrecognized"},
				},
			},
		})
		if err != nil {
			return nil, err
		}

		extractServiceInfo(commandResult.Extracted, result)
		return result, nil

	case serviceTypeSystemctl:
		command = fmt.Sprintf("systemctl status %v ", serviceInit)
	case serviceTypeStdService:
		command = fmt.Sprintf("service %v status", serviceInit)
	case serviceTypeInitDaemon:
		command = fmt.Sprintf("%v status", serviceInit)
	}

	commandResult, err := context.ExecuteAsSuperUser(target, &ManagedCommand{
		Options: &ExecutionOptions{
			Terminators: []string{"(END)"},
		},
		Executions: []*Execution{

			{
				Command: command,
				Extraction: DataExtractions{
					{
						Key:     "pid",
						RegExpr: "[^└]+└─(\\d+).+",
					},
					{
						Key:     "pid",
						RegExpr: " Main PID: (\\d+).+",
					},
					{
						Key:     "state",
						RegExpr: "[\\s|\\t]+Active:\\s+(\\S+)",
					},
					{
						Key:     "path",
						RegExpr: "[^└]+└─\\d+[\\s\\t].(.+)",
					},
				},
			},
			{
				Secure:      "",
				MatchOutput: "(END)", //quite multiline mode
				Command:     "Q",
			},
		},
	})
	if err != nil {
		return nil, err
	}

	extractServiceInfo(commandResult.Extracted, result)
	return result, nil

}

func (s *daemonService) stopService(context *Context, request *DaemonStopRequest) (*DaemonInfo, error) {
	serviceInfo, err := s.checkService(context, &DaemonStatusRequest{
		Target:    request.Target,
		Service:   request.Service,
		Exclusion: request.Exclusion,
	})
	if err != nil {
		return nil, err
	}
	if !serviceInfo.IsActive() {
		return serviceInfo, nil
	}
	target, err := context.ExpandResource(request.Target)
	if err != nil {
		return nil, err
	}
	command := ""
	switch serviceInfo.Type {
	case serviceTypeError:
		return nil, fmt.Errorf("Unknown daemon service type")
	case serviceTypeLaunchCtl:
		command = fmt.Sprintf("launchctl unload -F %v", serviceInfo.Init)
	case serviceTypeSystemctl:
		command = fmt.Sprintf("systemctl stop %v ", serviceInfo.Init)
	case serviceTypeStdService:
		command = fmt.Sprintf("service %v stop", serviceInfo.Init)
	case serviceTypeInitDaemon:
		command = fmt.Sprintf("%v stop", serviceInfo.Init)
	}

	commandResult, err := context.ExecuteAsSuperUser(target, &ManagedCommand{
		Executions: []*Execution{
			{
				Command: command,
			},
		},
	})
	if CheckCommandNotFound(commandResult.Stdout()) {
		return nil, fmt.Errorf("%v", commandResult.Stdout)
	}
	return s.checkService(context, &DaemonStatusRequest{
		Target:    request.Target,
		Service:   request.Service,
		Exclusion: request.Exclusion,
	})
}

func (s *daemonService) startService(context *Context, request *DaemonStartRequest) (*DaemonInfo, error) {
	serviceInfo, err := s.checkService(context, &DaemonStatusRequest{
		Target:    request.Target,
		Service:   request.Service,
		Exclusion: request.Exclusion,
	})
	if err != nil {
		return nil, err
	}
	if serviceInfo.IsActive() {
		return serviceInfo, nil
	}
	target, err := context.ExpandResource(request.Target)
	if err != nil {
		return nil, err
	}
	command := ""
	switch serviceInfo.Type {
	case serviceTypeError:
		return nil, fmt.Errorf("Unknown daemon service type")
	case serviceTypeLaunchCtl:
		command = fmt.Sprintf("launchctl load -F %v", serviceInfo.Init)
	case serviceTypeSystemctl:
		command = fmt.Sprintf("systemctl start %v ", serviceInfo.Init)
	case serviceTypeStdService:
		command = fmt.Sprintf("service %v start", serviceInfo.Init)
	case serviceTypeInitDaemon:
		command = fmt.Sprintf("%v start", serviceInfo.Init)
	}

	commandResult, err := context.ExecuteAsSuperUser(target, &ManagedCommand{
		Executions: []*Execution{
			{
				Command: command,
			},
		},
	})
	if CheckCommandNotFound(commandResult.Stdout()) {
		return nil, fmt.Errorf("%v", commandResult.Stdout)
	}
	return s.checkService(context, &DaemonStatusRequest{
		Target:    request.Target,
		Service:   request.Service,
		Exclusion: request.Exclusion,
	})
}

//NewDaemonService creates a new system service.
func NewDaemonService() Service {
	var result = &daemonService{
		AbstractService: NewAbstractService(DaemonServiceID),
	}
	result.AbstractService.Service = result
	return result
}
<|endoftext|>


<commit_before>package logzalgo

import (
	"bytes"
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/kortschak/zalgo"
)

// New corrupts a default logrus logger, making it much better at logging stuff.
func New() *logrus.Logger {
	thatThing := logrus.New()
	thatThing.Formatter = NewZalgoFormatterrrrrr()
	return thatThing
}

// ZalgoFormatter, just look at it, don't touch it.
type ZalgoFormatter struct {
	victim *logrus.TextFormatter
	pain   *bytes.Buffer
	z      *zalgo.Corrupter
}

// NewZalgoFormatterrrrrr gives you a new Zalgo formatterrrrrr...!
func NewZalgoFormatterrrrrr() *ZalgoFormatter {
	pain := bytes.NewBuffer(nil)
	z := zalgo.NewCorrupter(pain)

	z.Zalgo = func(n int, z *zalgo.Corrupter) {
		z.Up += 0.1
		z.Middle += complex(0.01, 0.01)
		z.Down += complex(real(z.Down)*0.1, 0)
	}

	return &ZalgoFormatter{
		victim: &logrus.TextFormatter{},
		pain:   pain,
		z:      z,
	}
}

// Format Formats Stuff™.
func (zal *ZalgoFormatter) Format(entry *logrus.Entry) ([]byte, error) {
	zal.pain.Reset()

	zal.z.Up = complex(0, 0.2)
	zal.z.Middle = complex(0, 0.2)
	zal.z.Down = complex(0.001, 0.3)

	victimsWish := entry.Data["msg"].(string)

	_, _ = fmt.Fprint(zal.z, victimsWish)

	victimsReality := zal.pain.String()

	entry.Data["msg"] = victimsReality
	return zal.victim.Format(entry)
}
<commit_msg>Zalgo has no mercy, no rune will be spared.<commit_after>package logzalgo

import (
	"bytes"
	"fmt"

	"github.com/Sirupsen/logrus"
	"github.com/kortschak/zalgo"
)

// New corrupts a default logrus logger, making it much better at logging stuff.
func New() *logrus.Logger {
	thatThing := logrus.New()
	thatThing.Formatter = NewZalgoFormatterrrrrr()
	return thatThing
}

// ZalgoFormatter, just look at it, don't touch it.
type ZalgoFormatter struct {
	victim *logrus.TextFormatter
	pain   *bytes.Buffer
	z      *zalgo.Corrupter
}

// NewZalgoFormatterrrrrr gives you a new Zalgo formatterrrrrr...!
func NewZalgoFormatterrrrrr() *ZalgoFormatter {
	pain := bytes.NewBuffer(nil)
	z := zalgo.NewCorrupter(pain)

	z.Zalgo = func(n int, r rune, z *zalgo.Corrupter) bool {
		z.Up += 0.1
		z.Middle += complex(0.01, 0.01)
		z.Down += complex(real(z.Down)*0.1, 0)
		return false
	}

	return &ZalgoFormatter{
		victim: &logrus.TextFormatter{},
		pain:   pain,
		z:      z,
	}
}

// Format Formats Stuff™.
func (zal *ZalgoFormatter) Format(entry *logrus.Entry) ([]byte, error) {
	zal.pain.Reset()

	zal.z.Up = complex(0, 0.2)
	zal.z.Middle = complex(0, 0.2)
	zal.z.Down = complex(0.001, 0.3)

	victimsWish := entry.Data["msg"].(string)

	_, _ = fmt.Fprint(zal.z, victimsWish)

	victimsReality := zal.pain.String()

	entry.Data["msg"] = victimsReality
	return zal.victim.Format(entry)
}
<|endoftext|>