<commit_before>package godbg

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"regexp"
	"runtime"
	"strings"
)

// http://stackoverflow.com/a/23554672/6309 https://vividcortex.com/blog/2013/12/03/go-idiom-package-and-object/
// you design a type with methods as usual, and then you also place matching functions at the package level itself.
// These functions simply delegate to a default instance of the type that’s a private package-level variable, created in an init() function.

// Pdbg allows to print debug message with indent and function name added
type Pdbg struct {
	bout     *bytes.Buffer
	berr     *bytes.Buffer
	sout     *bufio.Writer
	serr     *bufio.Writer
	breaks   []string
	excludes []string
	skips    []string
}

// Out returns a writer for normal messages.
// By default, os.StdOut
func Out() io.Writer {
	return pdbg.Out()
}

// Out returns a writer for normal messages for a given pdbg instance.
// By default, os.StdOut
func (pdbg *Pdbg) Out() io.Writer {
	if pdbg.sout == nil {
		return os.Stdout
	}
	return pdbg.sout
}

// Err returns a writer for error messages.
// By default, os.StdErr
func Err() io.Writer {
	return pdbg.Err()
}

// Err returns a writer for error messages for a given pdbg instance.
// By default, os.StdErr
func (pdbg *Pdbg) Err() io.Writer {
	if pdbg.serr == nil {
		return os.Stderr
	}
	return pdbg.serr
}

// global pdbg used for printing
var pdbg = NewPdbg()

// Option set an option for a Pdbg
// http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis
type Option func(*Pdbg)

// SetBuffers is an option for replacing stdout and stderr by
// bytes buffers (in a bufio.Writer).
// If apdbg is nil, set for the global pdbg instance
func SetBuffers(apdbg *Pdbg) {
	if apdbg == nil {
		apdbg = pdbg
	}
	apdbg.bout = bytes.NewBuffer(nil)
	apdbg.sout = bufio.NewWriter(apdbg.bout)
	apdbg.berr = bytes.NewBuffer(nil)
	apdbg.serr = bufio.NewWriter(apdbg.berr)
}

// SetExcludes set excludes on a pdbg (nil for global pdbg)
func (pdbg *Pdbg) SetExcludes(excludes []string) {
	pdbg.excludes = excludes
}

// OptExcludes is an option to set excludes at the creation of a pdbg
func OptExcludes(excludes []string) Option {
	return func(apdbg *Pdbg) {
		apdbg.SetExcludes(excludes)
	}
}

// SetSkips set skips on a pdbg (nil for global pdbg)
func (pdbg *Pdbg) SetSkips(skips []string) {
	sk := []string{"/godbg.go'"}
	sk = append(sk, skips...)
	pdbg.skips = sk
}

// OptSkips is an option to set excludes at the creation of a pdbg
func OptSkips(skips []string) Option {
	return func(apdbg *Pdbg) {
		apdbg.SetSkips(skips)
	}
}

// NewPdbg creates a PDbg instance, with options
func NewPdbg(options ...Option) *Pdbg {
	newpdbg := &Pdbg{}
	for _, option := range options {
		option(newpdbg)
	}
	newpdbg.breaks = append(newpdbg.breaks, "smartystreets")
	//newpdbg.breaks = append(newpdbg.breaks, "(*Pdbg).Pdbgf")
	newpdbg.skips = append(newpdbg.skips, "/godbg.go'")
	return newpdbg
}

// ResetIOs reset the out and err buffer of global pdbg instance
func ResetIOs() {
	pdbg.ResetIOs()
}

// ResetIOs reset the out and err buffer
// (unless they were the default stdout and stderr,
// in which case it does nothing)
func (pdbg *Pdbg) ResetIOs() {
	if pdbg.sout != nil {
		pdbg.bout = bytes.NewBuffer(nil)
		pdbg.sout.Reset(pdbg.bout)
		pdbg.berr = bytes.NewBuffer(nil)
		pdbg.serr.Reset(pdbg.berr)
	}
}

// OutString returns the string for out messages for the global pdbg instance.
// It flushes the out buffer.
// If out is set to os.Stdout, returns an empty string
func OutString() string {
	return pdbg.OutString()
}

// OutString returns the string for out messages for a given pdbg instance.
// It flushes the out buffer.
// If out is set to os.Stdout, returns an empty string
func (pdbg *Pdbg) OutString() string {
	if pdbg.sout == nil {
		return ""
	}
	pdbg.sout.Flush()
	return pdbg.bout.String()
}

// ErrString returns the string for error messages for the global pdbg instance.
// It flushes the err buffer.
// If err is set to os.StdErr, returns an empty string
func ErrString() string {
	return pdbg.ErrString()
}

// ErrString returns the string for error messages for a given pdbg instance.
// It flushes the err buffer.
// If err is set to os.StdErr, returns an empty string
func (pdbg *Pdbg) ErrString() string {
	if pdbg.serr == nil {
		return ""
	}
	pdbg.serr.Flush()
	return pdbg.berr.String()
}

func (pdbg *Pdbg) pdbgExcluded(dbg string) bool {
	for _, e := range pdbg.excludes {
		if strings.Contains(dbg, e) {
			// fmt.Printf("EXCLUDE over '%v' including '%v'\n", dbg, e) // DBG
			return true
		}
	}
	return false
}

func (pdbg *Pdbg) pdbgBreak(dbg string) bool {
	for _, b := range pdbg.breaks {
		if strings.Contains(dbg, b) {
			// fmt.Printf("BREAK over '%v' including '%v'\n", dbg, b) // DBG
			return true
		}
	}
	return false
}

func (pdbg *Pdbg) pdbgSkip(dbg string) (bool, int) {
	depthToAdd := 0
	for i, s := range pdbg.skips {
		if strings.Contains(dbg, s) {
			if i > 0 {
				depthToAdd = 1
			}
			// fmt.Printf("SKIP over '%v' including '%v'\n", dbg, s) // DBG
			return true, depthToAdd
		}
	}
	return false, depthToAdd
}

// Pdbgf uses global Pdbg variable for printing strings, with indent and function name
func Pdbgf(format string, args ...interface{}) string {
	return pdbg.Pdbgf(format, args...)
}

type caller func(skip int) (pc uintptr, file string, line int, ok bool)

var mycaller = runtime.Caller

// Pdbgf uses custom Pdbg variable for printing strings, with indent and function name
func (pdbg *Pdbg) Pdbgf(format string, args ...interface{}) string {
	msg := fmt.Sprintf(format+"\n", args...)
	msg = strings.TrimSpace(msg)

	pmsg := ""
	depth := 0
	nbskip := 0
	nbInitialSkips := 0
	first := true
	addOneForSkip := 0
	// fmt.Printf("~~~~~~~~~~~~~~~~~~~~~~\n") // DBG
	for ok := true; ok; {
		pc, file, line, ok := mycaller(depth)
		if !ok {
			break
		}
		fname := runtime.FuncForPC(pc).Name()
		fline := fmt.Sprintf("Name of function: '%v': '%+x' (line %v): file '%v'\n", fname, fname, line, file)
		// fmt.Println(fline) // DBG
		if pdbg.pdbgExcluded(fline) {
			depth = depth + 1
			if first {
				return ""
			}
			continue
		}
		if pdbg.pdbgBreak(fline) {
			break
		}
		if isSkipped, depthToAdd := pdbg.pdbgSkip(fline); isSkipped {
			depth = depth + 1
			nbskip = nbskip + 1
			addOneForSkip = addOneForSkip + depthToAdd
			continue
		}
		fnamerx1 := regexp.MustCompile(`.*\.func[^a-zA-Z0-9]`)
		fname = fnamerx1.ReplaceAllString(fname, "func.")
		fnamerx2 := regexp.MustCompile(`.*/`)
		fname = fnamerx2.ReplaceAllString(fname, "")
		if !strings.HasPrefix(fname, "func.") {
			fnamerx3 := regexp.MustCompile(`^.*?\.`)
			// fmt.Printf("fname before: '%v'", fname)
			fname = fnamerx3.ReplaceAllString(fname, "")
			// fmt.Printf(" => fname after: '%v'\n", fname)
			fnamerx4 := regexp.MustCompile(`[\(\)]`)
			fname = fnamerx4.ReplaceAllString(fname, "")
		}
		dbg := fname + ":" + fmt.Sprintf("%d", line)
		if first {
			// fmt.Printf(" => nbskip '%v'; addOneForSkip '%v'\n", nbskip, addOneForSkip) // DBG
			nbInitialSkips = nbskip - addOneForSkip
			pmsg = "[" + dbg + "]"
		} else {
			pmsg = pmsg + " (" + dbg + ")"
		}
		first = false
		depth = depth + 1
	}
	finalDepth := depth
	depth = finalDepth - nbInitialSkips - 1

	spaces := ""
	if depth >= 0 {
		spaces = strings.Repeat(" ", depth*2)
	}
	// fmt.Printf("spaces '%s', finalDepth '%d', depth '%d', nbInitialSkips '%d', addOneForSkip='%d'\n", spaces, finalDepth, depth, nbInitialSkips, addOneForSkip) // DBG
	res := pmsg
	if pmsg != "" {
		pmsg = spaces + pmsg + "\n"
	}
	msg = pmsg + spaces + "  " + msg + "\n"
	// fmt.Printf("==> MSG '%v'\n", msg) // DBG
	fmt.Fprint(pdbg.Err(), fmt.Sprint(msg))
	return res
}

var r = regexp.MustCompile(`:\d+[\)\]]`)
var r2 = regexp.MustCompile(`func\.\d+[\)\]]`)

// ShouldEqualNL is a custom goconvey assertion to ignore differences
// with func id and lines: `[globalPdbgExcludeTest:16] (func.019:167)` would
// be equal to [globalPdbgExcludeTest] (func)
// (see https://github.com/smartystreets/goconvey/wiki/Custom-Assertions)
func ShouldEqualNL(actual interface{}, expected ...interface{}) string {
	a := actual.(string)
	e := expected[0].(string)
	a = r.ReplaceAllStringFunc(a, func(s string) string { return s[len(s)-1:] })
	e = r.ReplaceAllStringFunc(e, func(s string) string { return s[len(s)-1:] })
	a = r2.ReplaceAllStringFunc(a, func(s string) string { return "func" + s[len(s)-1:] })
	e = r2.ReplaceAllStringFunc(e, func(s string) string { return "func" + s[len(s)-1:] })
	if a == e {
		return ""
	}
	return fmt.Sprintf("Extected: '%s'\nActual:   '%s'\n(Should be equal even with different lines and function ids)", e, a)
}
<commit_msg>WIP: goal is to replace os.Stdout and os.Stderr<commit_after>package godbg

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"regexp"
	"runtime"
	"strings"
)

// http://stackoverflow.com/a/23554672/6309 https://vividcortex.com/blog/2013/12/03/go-idiom-package-and-object/
// you design a type with methods as usual, and then you also place matching functions at the package level itself.
// These functions simply delegate to a default instance of the type that’s a private package-level variable, created in an init() function.

// Pdbg allows to print debug message with indent and function name added
type Pdbg struct {
	bout     *bytes.Buffer
	berr     *bytes.Buffer
	sout     *bufio.Writer
	serr     *bufio.Writer
	breaks   []string
	excludes []string
	skips    []string
	global   bool
}

// Out returns a writer for normal messages.
// By default, os.StdOut
func Out() io.Writer {
	return pdbg.Out()
}

// Out returns a writer for normal messages for a given pdbg instance.
// By default, os.StdOut
func (pdbg *Pdbg) Out() io.Writer {
	if pdbg.sout == nil {
		return os.Stdout
	}
	return pdbg.sout
}

// Err returns a writer for error messages.
// By default, os.StdErr
func Err() io.Writer {
	return pdbg.Err()
}

// Err returns a writer for error messages for a given pdbg instance.
// By default, os.StdErr
func (pdbg *Pdbg) Err() io.Writer {
	if pdbg.serr == nil {
		return os.Stderr
	}
	return pdbg.serr
}

// global pdbg used for printing
var pdbg *Pdbg

func init() {
	pdbg = NewPdbg()
	pdbg.global = true
}

// Option set an option for a Pdbg
// http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis
type Option func(*Pdbg)

// SetBuffers is an option for replacing stdout and stderr by
// bytes buffers (in a bufio.Writer).
// If apdbg is nil, set for the global pdbg instance
func SetBuffers(apdbg *Pdbg) {
	if apdbg == nil {
		apdbg = pdbg
	}
	// http://stackoverflow.com/questions/10473800/in-go-how-do-i-capture-stdout-of-a-function-into-a-string
	apdbg.bout = bytes.NewBuffer(nil)
	apdbg.sout = bufio.NewWriter(apdbg.bout)
	apdbg.berr = bytes.NewBuffer(nil)
	apdbg.serr = bufio.NewWriter(apdbg.berr)
	if apdbg.global {
		os.Stdout = Out()
		os.Stderr = Err()
	}
}

// SetExcludes set excludes on a pdbg (nil for global pdbg)
func (pdbg *Pdbg) SetExcludes(excludes []string) {
	pdbg.excludes = excludes
}

// OptExcludes is an option to set excludes at the creation of a pdbg
func OptExcludes(excludes []string) Option {
	return func(apdbg *Pdbg) {
		apdbg.SetExcludes(excludes)
	}
}

// SetSkips set skips on a pdbg (nil for global pdbg)
func (pdbg *Pdbg) SetSkips(skips []string) {
	sk := []string{"/godbg.go'"}
	sk = append(sk, skips...)
	pdbg.skips = sk
}

// OptSkips is an option to set excludes at the creation of a pdbg
func OptSkips(skips []string) Option {
	return func(apdbg *Pdbg) {
		apdbg.SetSkips(skips)
	}
}

// NewPdbg creates a PDbg instance, with options
func NewPdbg(options ...Option) *Pdbg {
	newpdbg := &Pdbg{}
	for _, option := range options {
		option(newpdbg)
	}
	newpdbg.breaks = append(newpdbg.breaks, "smartystreets")
	//newpdbg.breaks = append(newpdbg.breaks, "(*Pdbg).Pdbgf")
	newpdbg.skips = append(newpdbg.skips, "/godbg.go'")
	return newpdbg
}

// ResetIOs reset the out and err buffer of global pdbg instance
func ResetIOs() {
	pdbg.ResetIOs()
}

// ResetIOs reset the out and err buffer
// (unless they were the default stdout and stderr,
// in which case it does nothing)
func (pdbg *Pdbg) ResetIOs() {
	if pdbg.sout != nil {
		pdbg.bout = bytes.NewBuffer(nil)
		pdbg.sout.Reset(pdbg.bout)
		pdbg.berr = bytes.NewBuffer(nil)
		pdbg.serr.Reset(pdbg.berr)
	}
}

// OutString returns the string for out messages for the global pdbg instance.
// It flushes the out buffer.
// If out is set to os.Stdout, returns an empty string
func OutString() string {
	return pdbg.OutString()
}

// OutString returns the string for out messages for a given pdbg instance.
// It flushes the out buffer.
// If out is set to os.Stdout, returns an empty string
func (pdbg *Pdbg) OutString() string {
	if pdbg.sout == nil {
		return ""
	}
	pdbg.sout.Flush()
	return pdbg.bout.String()
}

// ErrString returns the string for error messages for the global pdbg instance.
// It flushes the err buffer.
// If err is set to os.StdErr, returns an empty string
func ErrString() string {
	return pdbg.ErrString()
}

// ErrString returns the string for error messages for a given pdbg instance.
// It flushes the err buffer.
// If err is set to os.StdErr, returns an empty string
func (pdbg *Pdbg) ErrString() string {
	if pdbg.serr == nil {
		return ""
	}
	pdbg.serr.Flush()
	return pdbg.berr.String()
}

func (pdbg *Pdbg) pdbgExcluded(dbg string) bool {
	for _, e := range pdbg.excludes {
		if strings.Contains(dbg, e) {
			// fmt.Printf("EXCLUDE over '%v' including '%v'\n", dbg, e) // DBG
			return true
		}
	}
	return false
}

func (pdbg *Pdbg) pdbgBreak(dbg string) bool {
	for _, b := range pdbg.breaks {
		if strings.Contains(dbg, b) {
			// fmt.Printf("BREAK over '%v' including '%v'\n", dbg, b) // DBG
			return true
		}
	}
	return false
}

func (pdbg *Pdbg) pdbgSkip(dbg string) (bool, int) {
	depthToAdd := 0
	for i, s := range pdbg.skips {
		if strings.Contains(dbg, s) {
			if i > 0 {
				depthToAdd = 1
			}
			// fmt.Printf("SKIP over '%v' including '%v'\n", dbg, s) // DBG
			return true, depthToAdd
		}
	}
	return false, depthToAdd
}

// Pdbgf uses global Pdbg variable for printing strings, with indent and function name
func Pdbgf(format string, args ...interface{}) string {
	return pdbg.Pdbgf(format, args...)
}

type caller func(skip int) (pc uintptr, file string, line int, ok bool)

var mycaller = runtime.Caller

// Pdbgf uses custom Pdbg variable for printing strings, with indent and function name
func (pdbg *Pdbg) Pdbgf(format string, args ...interface{}) string {
	msg := fmt.Sprintf(format+"\n", args...)
	msg = strings.TrimSpace(msg)

	pmsg := ""
	depth := 0
	nbskip := 0
	nbInitialSkips := 0
	first := true
	addOneForSkip := 0
	// fmt.Printf("~~~~~~~~~~~~~~~~~~~~~~\n") // DBG
	for ok := true; ok; {
		pc, file, line, ok := mycaller(depth)
		if !ok {
			break
		}
		fname := runtime.FuncForPC(pc).Name()
		fline := fmt.Sprintf("Name of function: '%v': '%+x' (line %v): file '%v'\n", fname, fname, line, file)
		// fmt.Println(fline) // DBG
		if pdbg.pdbgExcluded(fline) {
			depth = depth + 1
			if first {
				return ""
			}
			continue
		}
		if pdbg.pdbgBreak(fline) {
			break
		}
		if isSkipped, depthToAdd := pdbg.pdbgSkip(fline); isSkipped {
			depth = depth + 1
			nbskip = nbskip + 1
			addOneForSkip = addOneForSkip + depthToAdd
			continue
		}
		fnamerx1 := regexp.MustCompile(`.*\.func[^a-zA-Z0-9]`)
		fname = fnamerx1.ReplaceAllString(fname, "func.")
		fnamerx2 := regexp.MustCompile(`.*/`)
		fname = fnamerx2.ReplaceAllString(fname, "")
		if !strings.HasPrefix(fname, "func.") {
			fnamerx3 := regexp.MustCompile(`^.*?\.`)
			// fmt.Printf("fname before: '%v'", fname)
			fname = fnamerx3.ReplaceAllString(fname, "")
			// fmt.Printf(" => fname after: '%v'\n", fname)
			fnamerx4 := regexp.MustCompile(`[\(\)]`)
			fname = fnamerx4.ReplaceAllString(fname, "")
		}
		dbg := fname + ":" + fmt.Sprintf("%d", line)
		if first {
			// fmt.Printf(" => nbskip '%v'; addOneForSkip '%v'\n", nbskip, addOneForSkip) // DBG
			nbInitialSkips = nbskip - addOneForSkip
			pmsg = "[" + dbg + "]"
		} else {
			pmsg = pmsg + " (" + dbg + ")"
		}
		first = false
		depth = depth + 1
	}
	finalDepth := depth
	depth = finalDepth - nbInitialSkips - 1

	spaces := ""
	if depth >= 0 {
		spaces = strings.Repeat(" ", depth*2)
	}
	// fmt.Printf("spaces '%s', finalDepth '%d', depth '%d', nbInitialSkips '%d', addOneForSkip='%d'\n", spaces, finalDepth, depth, nbInitialSkips, addOneForSkip) // DBG
	res := pmsg
	if pmsg != "" {
		pmsg = spaces + pmsg + "\n"
	}
	msg = pmsg + spaces + "  " + msg + "\n"
	// fmt.Printf("==> MSG '%v'\n", msg) // DBG
	fmt.Fprint(pdbg.Err(), fmt.Sprint(msg))
	return res
}

var r = regexp.MustCompile(`:\d+[\)\]]`)
var r2 = regexp.MustCompile(`func\.\d+[\)\]]`)

// ShouldEqualNL is a custom goconvey assertion to ignore differences
// with func id and lines: `[globalPdbgExcludeTest:16] (func.019:167)` would
// be equal to [globalPdbgExcludeTest] (func)
// (see https://github.com/smartystreets/goconvey/wiki/Custom-Assertions)
func ShouldEqualNL(actual interface{}, expected ...interface{}) string {
	a := actual.(string)
	e := expected[0].(string)
	a = r.ReplaceAllStringFunc(a, func(s string) string { return s[len(s)-1:] })
	e = r.ReplaceAllStringFunc(e, func(s string) string { return s[len(s)-1:] })
	a = r2.ReplaceAllStringFunc(a, func(s string) string { return "func" + s[len(s)-1:] })
	e = r2.ReplaceAllStringFunc(e, func(s string) string { return "func" + s[len(s)-1:] })
	if a == e {
		return ""
	}
	return fmt.Sprintf("Extected: '%s'\nActual:   '%s'\n(Should be equal even with different lines and function ids)", e, a)
}
<|endoftext|>


<commit_before>package goson

import (
    "encoding/json"
    "strings"
    "errors"
    "strconv"
    "go/types"
)

/**
 * Created by tuxer on 9/6/17.
 */

type JsonObject struct {
    dataMap map[string]interface{}
}

func (j *JsonObject) ToBytes() []byte {
    data, e := json.Marshal(j.dataMap)
    if e != nil {
        return nil
    }
    return data
}

func (j *JsonObject) ToString() *string {
    data := j.ToBytes()
    str := ``
    if data != nil  {
        str = string(data)
    } else {
        return nil
    }
    return &str
}

func (j *JsonObject) GetJsonArray(path string) []JsonObject    {
    obj := j.get(path)

    values, ok := obj.([]interface{})

    if !ok  {
        return nil
    }
    var arrJson []JsonObject
    for _, value := range values   {
        mapValue, ok := value.(map[string]interface{})
        if ok   {
            jo := JsonObject{dataMap: mapValue}
            arrJson = append(arrJson, jo)
        }
    }
    return arrJson
}
func (j *JsonObject) GetJsonObject(path string) *JsonObject    {
    obj := j.get(path)

    v, ok := obj.(map[string]interface{})
    if ok   {
        jo := JsonObject{ dataMap: v }
        return &jo
    }
    return nil
}

func (j *JsonObject) GetInt(path string) *int {
    obj := j.get(path)

    switch obj.(type) {
    case float64:
        float, _ := obj.(float64)
        val := int(float)
        return &val
    case string:
        str, _ := obj.(string)
        val, e := strconv.Atoi(str)
        if e != nil {
            return nil
        }
        return &val
    default:
        return nil
    }
}
func (j *JsonObject) GetBoolean(path string) *bool {
    obj := j.get(path)
    b, ok := obj.(bool)
    if ok   {
        return &b
    } else {
        return nil
    }
}

func (j *JsonObject) GetString(path string) *string {
    obj := j.get(path)

    switch obj.(type) {
    case string:
        str, _ := obj.(string)
        return &str
    case float64:
        float, _ := obj.(float64)
        str := strconv.FormatFloat(float, 'f', -1, 64)
        return &str
    default:
        return nil
    }
}

func (j *JsonObject) Put(path string, value interface{}) *JsonObject    {
    j.PutE(path, value)
    return j
}
func (j *JsonObject) PutE(path string, value interface{}) error   {
    ptr, ok := value.(types.Pointer)
    if ok   {
        value = ptr.Elem()
    }

    arrays, ok := value.([]JsonObject)
    if ok   {
        arrayMap := []map[string]interface{}{}
        for _, jo := range arrays {
            arrayMap = append(arrayMap, jo.dataMap)
        }
        value = arrayMap
    }
    _, ok = value.(*JsonObject)
    if ok   {
        value = value.(*JsonObject).dataMap
    }
    _, ok = value.(JsonObject)
    if ok   {
        value = value.(JsonObject).dataMap
    }

    if j.dataMap == nil  {
        j.dataMap = make(map[string]interface{})
    }

    rootMap := j.dataMap
    currentMap := rootMap

    splittedPath := strings.Split(path, `.`)
    for index, pathItem := range splittedPath   {
        if index < len(splittedPath) - 1    {
            _, ok := currentMap[pathItem]
            if !ok   {
                currentMap[pathItem] = make(map[string]interface{})
            }
            currentMap, ok = currentMap[pathItem].(map[string]interface{})
            if !ok  {
                return errors.New(pathItem + `is not a json object`)
            }
        } else {
            currentMap[pathItem] = value
        }
    }
    j.dataMap = rootMap
    return nil
}

func (j *JsonObject) get(path string) interface{} {
    splittedPath := strings.Split(path, `.`)

    var jsonMap interface{}
    jsonMap = j.dataMap
    var val interface{}
    for _, pathItem := range splittedPath   {
        if jsonMap == nil   {
            return nil
        }
        val = jsonMap.(map[string]interface{})[pathItem]

        switch val.(type) {
        case map[string]interface{}:
            jsonMap = val
        default:
            jsonMap = nil
        }
    }
    return val
}

func Parse(data []byte) *JsonObject    {
    jo := JsonObject{}
    json.Unmarshal(data, &jo.dataMap)
    return &jo
}<commit_msg>- add func to get datamap - add getFloat<commit_after>package goson

import (
    "encoding/json"
    "strings"
    "errors"
    "strconv"
    "go/types"
)

/**
 * Created by tuxer on 9/6/17.
 */

type JsonObject struct {
    dataMap map[string]interface{}
}

func (j *JsonObject) ToBytes() []byte {
    data, e := json.Marshal(j.dataMap)
    if e != nil {
        return nil
    }
    return data
}

func (j *JsonObject) ToString() *string {
    data := j.ToBytes()
    str := ``
    if data != nil  {
        str = string(data)
    } else {
        return nil
    }
    return &str
}

func (j *JsonObject) GetDataMap() map[string]interface{}   {
    return j.dataMap
}

func (j *JsonObject) GetJsonArray(path string) []JsonObject    {
    obj := j.get(path)

    values, ok := obj.([]interface{})

    if !ok  {
        return nil
    }
    var arrJson []JsonObject
    for _, value := range values   {
        mapValue, ok := value.(map[string]interface{})
        if ok   {
            jo := JsonObject{dataMap: mapValue}
            arrJson = append(arrJson, jo)
        }
    }
    return arrJson
}
func (j *JsonObject) GetJsonObject(path string) *JsonObject    {
    obj := j.get(path)

    v, ok := obj.(map[string]interface{})
    if ok   {
        jo := JsonObject{ dataMap: v }
        return &jo
    }
    return nil
}

func (j *JsonObject) GetFloat(path string) *float64 {
    obj := j.get(path)

    switch obj.(type) {
    case float64:
        float, _ := obj.(float64)
        return &float
    case string:
        str, _ := obj.(string)
        val, e := strconv.ParseFloat(str, 64)
        if e != nil {
            return nil
        }
        return &val
    default:
        return nil
    }
}

func (j *JsonObject) GetInt(path string) *int {
    obj := j.get(path)

    switch obj.(type) {
    case float64:
        float, _ := obj.(float64)
        val := int(float)
        return &val
    case string:
        str, _ := obj.(string)
        val, e := strconv.Atoi(str)
        if e != nil {
            return nil
        }
        return &val
    default:
        return nil
    }
}
func (j *JsonObject) GetBoolean(path string) *bool {
    obj := j.get(path)
    b, ok := obj.(bool)
    if ok   {
        return &b
    } else {
        return nil
    }
}

func (j *JsonObject) GetString(path string) *string {
    obj := j.get(path)

    switch obj.(type) {
    case string:
        str, _ := obj.(string)
        return &str
    case float64:
        float, _ := obj.(float64)
        str := strconv.FormatFloat(float, 'f', -1, 64)
        return &str
    default:
        return nil
    }
}

func (j *JsonObject) Put(path string, value interface{}) *JsonObject    {
    j.PutE(path, value)
    return j
}
func (j *JsonObject) PutE(path string, value interface{}) error   {
    ptr, ok := value.(types.Pointer)
    if ok   {
        value = ptr.Elem()
    }

    arrays, ok := value.([]JsonObject)
    if ok   {
        arrayMap := []map[string]interface{}{}
        for _, jo := range arrays {
            arrayMap = append(arrayMap, jo.dataMap)
        }
        value = arrayMap
    }
    _, ok = value.(*JsonObject)
    if ok   {
        value = value.(*JsonObject).dataMap
    }
    _, ok = value.(JsonObject)
    if ok   {
        value = value.(JsonObject).dataMap
    }

    if j.dataMap == nil  {
        j.dataMap = make(map[string]interface{})
    }

    rootMap := j.dataMap
    currentMap := rootMap

    splittedPath := strings.Split(path, `.`)
    for index, pathItem := range splittedPath   {
        if index < len(splittedPath) - 1    {
            _, ok := currentMap[pathItem]
            if !ok   {
                currentMap[pathItem] = make(map[string]interface{})
            }
            currentMap, ok = currentMap[pathItem].(map[string]interface{})
            if !ok  {
                return errors.New(pathItem + `is not a json object`)
            }
        } else {
            currentMap[pathItem] = value
        }
    }
    j.dataMap = rootMap
    return nil
}

func (j *JsonObject) get(path string) interface{} {
    splittedPath := strings.Split(path, `.`)

    var jsonMap interface{}
    jsonMap = j.dataMap
    var val interface{}
    for _, pathItem := range splittedPath   {
        if jsonMap == nil   {
            return nil
        }
        val = jsonMap.(map[string]interface{})[pathItem]

        switch val.(type) {
        case map[string]interface{}:
            jsonMap = val
        default:
            jsonMap = nil
        }
    }
    return val
}

func Parse(data []byte) *JsonObject    {
    jo := JsonObject{}
    json.Unmarshal(data, &jo.dataMap)
    return &jo
}<|endoftext|>


<commit_before>// Package gossp provides support for speech signal processing.
package gossp

import (
	"math"
)

// DivideFrames returns overlapping divided frames.
func DivideFrames(input []float64, frameLen, frameShift int) [][]float64 {
	numFrames := int(float64(len(input)-frameLen)/float64(frameShift)) + 1
	frames := make([][]float64, numFrames)
	for i := 0; i < numFrames; i++ {
		frames[i] = input[i*frameShift : i*frameShift+frameLen]
	}
	return frames
}

// SplitSpectrum splits complex spectrum X(k) to amplitude |X(k)|
// and angle(X(k))
func SplitSpectrum(spec []complex128) ([]float64, []float64) {
	amp := make([]float64, len(spec))
	phase := make([]float64, len(spec))
	for i, val := range spec {
		amp[i] = cmplx.Abs(val)
		phase[i] = math.Atan2(imag(val), real(val))
	}

	return amp, phase
}

// SplitSpectrogram returns SpilitSpectrum for each time frame.
func SplitSpectrogram(spectrogram [][]complex128) ([][]float64, [][]float64) {
	numFrames, numFreqBins := len(spectrogram), len(spectrogram[0])
	amp := create2DSlice(numFrames, numFreqBins)
	phase := create2DSlice(numFrames, numFreqBins)

	for i := 0; i < numFrames; i++ {
		amp[i], phase[i] = SplitSpectrum(spectrogram[i])
	}

	return amp, phase
}

func create2DSlice(rows, cols int) [][]float64 {
	s := make([][]float64, rows)
	for i := range s {
		s[i] = make([]float64, cols)
	}
	return s
}

// ReconstructSpectrum returns complex spectrum from amplitude
// and phase spectrum.
// angle(X(k)) and |X(k)| -> X(k)
func ReconstructSpectrum(amp, phase []float64) []complex128 {
	spec := make([]complex128, len(amp))
	for i := range amp {
		spec[i] = complex(amp[i], 0.0) * cmplx.Exp(complex(0.0, phase[i]))
	}
	return spec
}

// ReconstructSpectrogram returns complex spectrogram from amplitude
// phase spectrogram.
func ReconstructSpectrogram(amplitudeSpectrogram,
	phaseSpectrogram [][]float64) [][]complex128 {
	spectrogram := make([][]complex128, len(amplitudeSpectrogram))
	for i := range amplitudeSpectrogram {
		a, p := amplitudeSpectrogram[i], phaseSpectrogram[i]
		spectrogram[i] = ReconstructSpectrum(a, p)
	}
	return spectrogram
}

// ToReal performs a real sequence from a complex sequence.
func ToReal(x []complex128) []float64 {
	y := make([]float64, len(x))
	for i, val := range x {
		y[i] = real(val)
	}
	return y
}

// Angle returns angle of complex number in radian.
func Angle(z complex128) float64 {
	return math.Atan2(imag(z), real(z))
}

// UnWrap returns unwraped phase given a phase spectrum.
func UnWrap(phase []float64) []float64 {
	unwraped := make([]float64, len(phase))

	unwraped[0] = phase[0]
	for i := 1; i < len(phase); i++ {
		diff := phase[i] - phase[i-1]
		switch {
		case diff > math.Pi:
			unwraped[i] = phase[i] - 2*math.Pi
		case diff < -math.Pi:
			unwraped[i] = phase[i] + 2*math.Pi
		default:
			unwraped[i] = phase[i]
		}
	}

	return unwraped
}

// Matlab
func HistC(x, edges []float64) []int {
	index := make([]int, len(edges))

	count := 1

	previousIndex := 0
	for i, val := range edges {
		previousIndex = i
		index[i] = 1
		if val >= x[0] {
			break
		}
	}

	for i := previousIndex; i < len(edges); i++ {
		if edges[i] < x[count] {
			index[i] = count
		} else {
			index[i] = count
			i--
			count++
		}

		previousIndex = i
		if count == len(x) {
			break
		}
	}
	count--

	for i := previousIndex + 1; i < len(edges); i++ {
		index[i] = count
	}

	return index
}

// Matlab
func Interp1(x, y, xi []float64) []float64 {
	yi := make([]float64, len(xi))

	h := make([]float64, len(x)-1)
	p := make([]float64, len(xi))
	s := make([]float64, len(xi))

	for i := 0; i < len(x)-1; i++ {
		h[i] = x[i+1] - x[i]
	}

	for i := 0; i < len(x); i++ {
		p[i] = float64(i)
	}

	k := HistC(x, xi)

	for i := range xi {
		s[i] = (xi[i] - x[k[i]-1]) / h[k[i]-1]
	}

	for i := range xi {
		yi[i] = y[k[i]-1] + s[i]*(y[k[i]]-y[k[i]-1])
	}

	return yi
}

// Symmetrize returns symmetrized vector given a input vector.
func Symmetrize(x []float64) []float64 {
	N := len(x)
	y := make([]float64, (N-1)*2)

	y[0] = x[0]
	for i := 1; i < N; i++ {
		y[i] = x[i]
		y[len(y)-i] = x[i]
	}

	return y
}

// Hz2Mel converts frequency in hz to mel.
func Hz2Mel(freq float64) float64 {
	return 1127.01048 * math.Log(freq/700.0+1.0)
}

// Mel2Hz converts frequency in mel to hz.
func Mel2Hz(mel float64) float64 {
	return 700.0 * (math.Exp(mel/1127.01048) - 1.0)
}
<commit_msg>Add import "math/cmplx"<commit_after>// Package gossp provides support for speech signal processing.
package gossp

import (
	"math"
	"math/cmplx"
)

// DivideFrames returns overlapping divided frames.
func DivideFrames(input []float64, frameLen, frameShift int) [][]float64 {
	numFrames := int(float64(len(input)-frameLen)/float64(frameShift)) + 1
	frames := make([][]float64, numFrames)
	for i := 0; i < numFrames; i++ {
		frames[i] = input[i*frameShift : i*frameShift+frameLen]
	}
	return frames
}

// SplitSpectrum splits complex spectrum X(k) to amplitude |X(k)|
// and angle(X(k))
func SplitSpectrum(spec []complex128) ([]float64, []float64) {
	amp := make([]float64, len(spec))
	phase := make([]float64, len(spec))
	for i, val := range spec {
		amp[i] = cmplx.Abs(val)
		phase[i] = math.Atan2(imag(val), real(val))
	}

	return amp, phase
}

// SplitSpectrogram returns SpilitSpectrum for each time frame.
func SplitSpectrogram(spectrogram [][]complex128) ([][]float64, [][]float64) {
	numFrames, numFreqBins := len(spectrogram), len(spectrogram[0])
	amp := create2DSlice(numFrames, numFreqBins)
	phase := create2DSlice(numFrames, numFreqBins)

	for i := 0; i < numFrames; i++ {
		amp[i], phase[i] = SplitSpectrum(spectrogram[i])
	}

	return amp, phase
}

func create2DSlice(rows, cols int) [][]float64 {
	s := make([][]float64, rows)
	for i := range s {
		s[i] = make([]float64, cols)
	}
	return s
}

// ReconstructSpectrum returns complex spectrum from amplitude
// and phase spectrum.
// angle(X(k)) and |X(k)| -> X(k)
func ReconstructSpectrum(amp, phase []float64) []complex128 {
	spec := make([]complex128, len(amp))
	for i := range amp {
		spec[i] = complex(amp[i], 0.0) * cmplx.Exp(complex(0.0, phase[i]))
	}
	return spec
}

// ReconstructSpectrogram returns complex spectrogram from amplitude
// phase spectrogram.
func ReconstructSpectrogram(amplitudeSpectrogram,
	phaseSpectrogram [][]float64) [][]complex128 {
	spectrogram := make([][]complex128, len(amplitudeSpectrogram))
	for i := range amplitudeSpectrogram {
		a, p := amplitudeSpectrogram[i], phaseSpectrogram[i]
		spectrogram[i] = ReconstructSpectrum(a, p)
	}
	return spectrogram
}

// ToReal performs a real sequence from a complex sequence.
func ToReal(x []complex128) []float64 {
	y := make([]float64, len(x))
	for i, val := range x {
		y[i] = real(val)
	}
	return y
}

// Angle returns angle of complex number in radian.
func Angle(z complex128) float64 {
	return math.Atan2(imag(z), real(z))
}

// UnWrap returns unwraped phase given a phase spectrum.
func UnWrap(phase []float64) []float64 {
	unwraped := make([]float64, len(phase))

	unwraped[0] = phase[0]
	for i := 1; i < len(phase); i++ {
		diff := phase[i] - phase[i-1]
		switch {
		case diff > math.Pi:
			unwraped[i] = phase[i] - 2*math.Pi
		case diff < -math.Pi:
			unwraped[i] = phase[i] + 2*math.Pi
		default:
			unwraped[i] = phase[i]
		}
	}

	return unwraped
}

// Matlab
func HistC(x, edges []float64) []int {
	index := make([]int, len(edges))

	count := 1

	previousIndex := 0
	for i, val := range edges {
		previousIndex = i
		index[i] = 1
		if val >= x[0] {
			break
		}
	}

	for i := previousIndex; i < len(edges); i++ {
		if edges[i] < x[count] {
			index[i] = count
		} else {
			index[i] = count
			i--
			count++
		}

		previousIndex = i
		if count == len(x) {
			break
		}
	}
	count--

	for i := previousIndex + 1; i < len(edges); i++ {
		index[i] = count
	}

	return index
}

// Matlab
func Interp1(x, y, xi []float64) []float64 {
	yi := make([]float64, len(xi))

	h := make([]float64, len(x)-1)
	p := make([]float64, len(xi))
	s := make([]float64, len(xi))

	for i := 0; i < len(x)-1; i++ {
		h[i] = x[i+1] - x[i]
	}

	for i := 0; i < len(x); i++ {
		p[i] = float64(i)
	}

	k := HistC(x, xi)

	for i := range xi {
		s[i] = (xi[i] - x[k[i]-1]) / h[k[i]-1]
	}

	for i := range xi {
		yi[i] = y[k[i]-1] + s[i]*(y[k[i]]-y[k[i]-1])
	}

	return yi
}

// Symmetrize returns symmetrized vector given a input vector.
func Symmetrize(x []float64) []float64 {
	N := len(x)
	y := make([]float64, (N-1)*2)

	y[0] = x[0]
	for i := 1; i < N; i++ {
		y[i] = x[i]
		y[len(y)-i] = x[i]
	}

	return y
}

// Hz2Mel converts frequency in hz to mel.
func Hz2Mel(freq float64) float64 {
	return 1127.01048 * math.Log(freq/700.0+1.0)
}

// Mel2Hz converts frequency in mel to hz.
func Mel2Hz(mel float64) float64 {
	return 700.0 * (math.Exp(mel/1127.01048) - 1.0)
}
<|endoftext|>


<commit_before>package metrics

import (
	"bytes"
	"io"
	"net"
	"net/http"
	"os"

	"github.com/koding/kite"
)

// Publisher sends DD events to agent.
type Publisher struct {
	conn            io.WriteCloser
	metricsEndpoint string
}

// NewPublisherWithConn creates new Publisher for sending the incoming events to
// DataDog agent.
func NewPublisherWithConn(conn io.WriteCloser, metricsEndpoint string) *Publisher {
	return &Publisher{
		conn:            conn,
		metricsEndpoint: metricsEndpoint,
	}
}

// NewPublisher creates a new publisher with default DD agent address.
func NewPublisher(metricsEndpoint string) (*Publisher, error) {
	udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8125")
	if err != nil {
		return nil, err
	}

	conn, err := net.DialUDP("udp", nil, udpAddr)
	if err != nil {
		return nil, err
	}

	return NewPublisherWithConn(conn, metricsEndpoint), nil
}

// PublishRequest represents a request type for "metrics.publish" kloud's
// kite method.
type PublishRequest struct {
	Data GzippedPayload `json:"data"`
}

// Pattern returns the endpoint name for kite.
func (Publisher) Pattern() string {
	return "metrics.publish"
}

// Publish is a kite.Handler for "metrics.publish" kite method.
func (p *Publisher) Publish(r *kite.Request) (interface{}, error) {
	var req PublishRequest
	if err := r.Args.One().Unmarshal(&req); err != nil {
		return nil, err
	}

	for _, data := range req.Data {
		_, err := p.conn.Write(data)
		if err == nil {
			continue
		}

		if errP, ok := err.(*net.OpError); ok {
			if _, ok := errP.Err.(*os.SyscallError); ok {
				continue
			}
		}

		return nil, err
	}

	go func() {
		if _, err := http.Post(p.metricsEndpoint, "application/json", bytes.NewReader(r.Args.Raw)); err != nil {
			r.LocalKite.Log.Error("Err while publishing metrics: %s", err)
		}
	}()

	return nil, nil
}

// Close closes the underlying connection.
func (p *Publisher) Close() error {
	return p.conn.Close()
}
<commit_msg>kloud/metrics: add contextual cancellation to http<commit_after>package metrics

import (
	"bytes"
	"context"
	"io"
	"net"
	"os"
	"time"

	"golang.org/x/net/context/ctxhttp"

	"github.com/koding/kite"
)

// Publisher sends DD events to agent.
type Publisher struct {
	conn            io.WriteCloser
	metricsEndpoint string
}

// NewPublisherWithConn creates new Publisher for sending the incoming events to
// DataDog agent.
func NewPublisherWithConn(conn io.WriteCloser, metricsEndpoint string) *Publisher {
	return &Publisher{
		conn:            conn,
		metricsEndpoint: metricsEndpoint,
	}
}

// NewPublisher creates a new publisher with default DD agent address.
func NewPublisher(metricsEndpoint string) (*Publisher, error) {
	udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8125")
	if err != nil {
		return nil, err
	}

	conn, err := net.DialUDP("udp", nil, udpAddr)
	if err != nil {
		return nil, err
	}

	return NewPublisherWithConn(conn, metricsEndpoint), nil
}

// PublishRequest represents a request type for "metrics.publish" kloud's
// kite method.
type PublishRequest struct {
	Data GzippedPayload `json:"data"`
}

// Pattern returns the endpoint name for kite.
func (Publisher) Pattern() string {
	return "metrics.publish"
}

// Publish is a kite.Handler for "metrics.publish" kite method.
func (p *Publisher) Publish(r *kite.Request) (interface{}, error) {
	var req PublishRequest
	if err := r.Args.One().Unmarshal(&req); err != nil {
		return nil, err
	}

	for _, data := range req.Data {
		_, err := p.conn.Write(data)
		if err == nil {
			continue
		}

		if errP, ok := err.(*net.OpError); ok {
			if _, ok := errP.Err.(*os.SyscallError); ok {
				continue
			}
		}

		return nil, err
	}

	go func() {
		ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
		defer cancel()
		if _, err := ctxhttp.Post(ctx, nil, p.metricsEndpoint, "application/json", bytes.NewReader(r.Args.Raw)); err != nil {
			r.LocalKite.Log.Error("Err while publishing metrics: %s", err)
		}
	}()

	return nil, nil
}

// Close closes the underlying connection.
func (p *Publisher) Close() error {
	return p.conn.Close()
}
<|endoftext|>


<commit_before>package status

import (
	"fmt"
	"koding/klient/kiteerrortypes"
	"koding/klient/remote/machine"
	"koding/klient/util"
	"net/http"
	"time"

	"github.com/koding/kite"
	"github.com/koding/logging"
)

const (
	tokenExpiredMessage     = "token is expired"
	tokenNotValidYetMessage = "token is not valid yet"
)

var (
	defaultHTTPClient = &http.Client{
		Timeout: 4 * time.Second,
	}
)

// Used to check the status of a remote machine / kite.
type MachineGetter interface {
	GetMachinesWithoutCache() (machine.Machines, error)
	GetMachine(string) (*machine.Machine, error)
}

// Status deals with checking the status of remote kites, kontrol, and etc.
// Implementing the core logic of Klient's remote.status method.
type Status struct {
	Log logging.Logger

	// Used to fetch machines from a remote.
	MachineGetter MachineGetter

	// Used to curl the machines directly, outside of kite protocol.
	HTTPClient *http.Client
}

func NewStatus(log logging.Logger, mg MachineGetter) *Status {
	return &Status{
		Log:           log.New("status"),
		MachineGetter: mg,
		HTTPClient:    defaultHTTPClient,
	}
}

// handleKiteErr handles a kite transport error, filtering out common connection
// related errors. If the given error is *not* a kiteErr, the normal error is
// returned.
//
// If nil is given as an arg, nil is returned.
func (s *Status) handleKiteErr(err error) error {
	// By checking for nil, we allow usage of this func like:
	// handleKIteErr(Dial()), if desired.
	if err == nil {
		return nil
	}

	kErr, ok := err.(*kite.Error)

	// If we fail to cast the kite error, this is a normal error type. We currently
	// have no cases to handle for that, so return it.
	if !ok {
		return err
	}

	// Authentication errors come from the kite lib, so parse the messages to return
	// easy to decpiher types.
	if kErr.Type == kiteerrortypes.AuthenticationError {
		switch kErr.Message {
		case tokenExpiredMessage:
			return util.NewKiteError(kiteerrortypes.AuthErrTokenIsExpired, err)
		case tokenNotValidYetMessage:
			return util.NewKiteError(kiteerrortypes.AuthErrTokenIsNotValidYet, err)
		}
	}

	// If we get here, the kite error type is not handled. Return the original
	// error.
	return err
}

// KontrolStatus checks the status of our connection to kontrol, returning
// ok or no.
//
// TODO: IMPORTANT: Use a less costly method to determine if Kontrol is connected.
// An ideal method would simply be `ping`, but Kontrol does not currently implement
// ping.
func (s *Status) KontrolStatus() error {
	if _, err := s.MachineGetter.GetMachinesWithoutCache(); err != nil {
		return fmt.Errorf("Unable to get kontrol connection. err:%s", err)
	}

	return nil
}

// MachineStatus dials the given machine name, pings it, and returns ok or not.
// Custom type errors for any problems encountered.
func (s *Status) MachineStatus(name string) error {
	machine, err := s.MachineGetter.GetMachine(name)
	if err != nil {
		return err
	}

	// Try and ping it directly via http. This lets us
	if _, err := s.HTTPClient.Get(fmt.Sprintf("http://%s:56789/kite", machine.IP)); err != nil {
		return util.KiteErrorf(
			kiteerrortypes.MachineUnreachable,
			"Machine unreachable. host:%s, err:%s",
			machine.IP, err,
		)
	}

	if err := machine.Dial(); err != nil {
		return s.handleKiteErr(err)
	}

	if err := machine.Ping(); err != nil {
		return s.handleKiteErr(err)
	}

	return nil
}
<commit_msg>docstring: Fixed typo<commit_after>package status

import (
	"fmt"
	"koding/klient/kiteerrortypes"
	"koding/klient/remote/machine"
	"koding/klient/util"
	"net/http"
	"time"

	"github.com/koding/kite"
	"github.com/koding/logging"
)

const (
	tokenExpiredMessage     = "token is expired"
	tokenNotValidYetMessage = "token is not valid yet"
)

var (
	defaultHTTPClient = &http.Client{
		Timeout: 4 * time.Second,
	}
)

// Used to check the status of a remote machine / kite.
type MachineGetter interface {
	GetMachinesWithoutCache() (machine.Machines, error)
	GetMachine(string) (*machine.Machine, error)
}

// Status deals with checking the status of remote kites, kontrol, and etc.
// Implementing the core logic of Klient's remote.status method.
type Status struct {
	Log logging.Logger

	// Used to fetch machines from a remote.
	MachineGetter MachineGetter

	// Used to curl the machines directly, outside of kite protocol.
	HTTPClient *http.Client
}

func NewStatus(log logging.Logger, mg MachineGetter) *Status {
	return &Status{
		Log:           log.New("status"),
		MachineGetter: mg,
		HTTPClient:    defaultHTTPClient,
	}
}

// handleKiteErr handles a kite transport error, filtering out common connection
// related errors. If the given error is *not* a kiteErr, the normal error is
// returned.
//
// If nil is given as an arg, nil is returned.
func (s *Status) handleKiteErr(err error) error {
	// By checking for nil, we allow usage of this func like:
	// handleKiteErr(Dial()), if desired.
	if err == nil {
		return nil
	}

	kErr, ok := err.(*kite.Error)

	// If we fail to cast the kite error, this is a normal error type. We currently
	// have no cases to handle for that, so return it.
	if !ok {
		return err
	}

	// Authentication errors come from the kite lib, so parse the messages to return
	// easy to decpiher types.
	if kErr.Type == kiteerrortypes.AuthenticationError {
		switch kErr.Message {
		case tokenExpiredMessage:
			return util.NewKiteError(kiteerrortypes.AuthErrTokenIsExpired, err)
		case tokenNotValidYetMessage:
			return util.NewKiteError(kiteerrortypes.AuthErrTokenIsNotValidYet, err)
		}
	}

	// If we get here, the kite error type is not handled. Return the original
	// error.
	return err
}

// KontrolStatus checks the status of our connection to kontrol, returning
// ok or no.
//
// TODO: IMPORTANT: Use a less costly method to determine if Kontrol is connected.
// An ideal method would simply be `ping`, but Kontrol does not currently implement
// ping.
func (s *Status) KontrolStatus() error {
	if _, err := s.MachineGetter.GetMachinesWithoutCache(); err != nil {
		return fmt.Errorf("Unable to get kontrol connection. err:%s", err)
	}

	return nil
}

// MachineStatus dials the given machine name, pings it, and returns ok or not.
// Custom type errors for any problems encountered.
func (s *Status) MachineStatus(name string) error {
	machine, err := s.MachineGetter.GetMachine(name)
	if err != nil {
		return err
	}

	// Try and ping it directly via http. This lets us
	if _, err := s.HTTPClient.Get(fmt.Sprintf("http://%s:56789/kite", machine.IP)); err != nil {
		return util.KiteErrorf(
			kiteerrortypes.MachineUnreachable,
			"Machine unreachable. host:%s, err:%s",
			machine.IP, err,
		)
	}

	if err := machine.Dial(); err != nil {
		return s.handleKiteErr(err)
	}

	if err := machine.Ping(); err != nil {
		return s.handleKiteErr(err)
	}

	return nil
}
<|endoftext|>


<commit_before>package graphs

import (
	"fmt"
	"sort"
)

// A Vertex can be just anything.
type Vertex interface{}

// An Edge connects two vertices with a cost.
type Edge struct {
	Start Vertex
	End   Vertex
	Cost  float64
}

// A Halfedge is an edge where just the end vertex is
// stored. The start vertex is inferred from the context.
type Halfedge struct {
	End  Vertex
	Cost float64
}

// A Graph is defined by its vertices and edges stored as
// an adjacency set.
type Graph struct {
	Adjacency map[Vertex]*Set
	Vertices  *Set
	Directed  bool
}

// NewGraph creates a new empty graph.
func NewGraph() *Graph {
	return &Graph{
		Adjacency: map[Vertex]*Set{},
		Vertices:  NewSet(),
		Directed:  false,
	}
}

// NewDigraph creates a new empty directed graph.
func NewDigraph() *Graph {
	graph := NewGraph()
	graph.Directed = true
	return graph
}

// AddVertex adds the given vertex to the graph.
func (g *Graph) AddVertex(v Vertex) {
	g.Vertices.Add(v)
}

// AddEdge adds an edge to the graph. The edge connects
// vertex v1 and vertex v2 with cost c.
func (g *Graph) AddEdge(v1, v2 Vertex, c float64) {
	g.Vertices.Add(v1)
	g.Vertices.Add(v2)

	if _, exists := g.Adjacency[v1]; !exists {
		g.Adjacency[v1] = NewSet()
	}

	g.Adjacency[v1].Add(Halfedge{
		End:  v2,
		Cost: c,
	})

	if !g.Directed {
		if _, exists := g.Adjacency[v2]; !exists {
			g.Adjacency[v2] = NewSet()
		}

		g.Adjacency[v2].Add(Halfedge{
			End:  v1,
			Cost: c,
		})
	}
}

// Dump prints all edges with their cost to stdout.
func (g *Graph) Dump() {
	for v, s := range g.Adjacency {
		s.Each(func(e interface{}, stop *bool) {
			he := e.(Halfedge)
			fmt.Printf("(%v,%v,%f)\n", v, he.End, he.Cost)
		})
	}
}

// NVertices returns the number of vertices.
func (g *Graph) NVertices() int {
	return g.Vertices.Len()
}

// NEdges returns the number of edges.
func (g *Graph) NEdges() int {
	n := 0

	for _, v := range g.Adjacency {
		n += v.Len()
	}

	// Don’t count a-b and b-a edges for undirected graphs
	// as two separate edges.
	if !g.Directed {
		n /= 2
	}

	return n
}

// Equals returns whether the graph is equal to the given graph.
// Two graphs are equal of their adjacency is equal.
func (g *Graph) Equals(g2 *Graph) bool {
	// Two graphs with differnet vertices aren’t equal.
	if !g.Vertices.Equals(g2.Vertices) {
		return false
	}

	// Some for number of edges.
	if g.NEdges() != g2.NEdges() {
		return false
	}

	// Check if the adjacency for each vertex is equal
	// for both graphs.
	a1 := g.Adjacency
	a2 := g2.Adjacency

	for k, v := range a1 {
		if !v.Equals(a2[k]) {
			return false
		}
	}

	return true
}

// VerticesIter returns a channel where all vertices
// are sent to.
func (g *Graph) VerticesIter() chan Vertex {
	ch := make(chan Vertex)
	go func() {
		for e := range g.Vertices.Iter() {
			ch <- e.(Vertex)
		}
		close(ch)
	}()
	return ch
}

// SortedEdges is an array of edges that can be sorted
// by their cost.
type SortedEdges []Edge

func (se SortedEdges) Len() int {
	return len(se)
}

func (se SortedEdges) Less(i, j int) bool {
	return se[i].Cost < se[j].Cost
}

func (se SortedEdges) Swap(i, j int) {
	se[i], se[j] = se[j], se[i]
}

// SortedEdges returns an array of edges sorted by their cost.
func (g *Graph) SortedEdges() SortedEdges {
	set := NewSet()

	for v, s := range g.Adjacency {
		s.Each(func(e interface{}, stop *bool) {
			he := e.(Halfedge)
			set.Add(Edge{
				Start: v,
				End:   he.End,
				Cost:  he.Cost,
			})
		})
	}

	edges := make(SortedEdges, set.Len())
	set.Each(func(e interface{}, stop *bool) {
		edges = append(edges, e.(Edge))
	})

	sort.Sort(&edges)
	return edges
}

// EdgesIter returns a channel with all edges of the graph.
func (g *Graph) EdgesIter() chan Edge {
	ch := make(chan Edge)
	go func() {
		for v, s := range g.Adjacency {
			for x := range s.Iter() {
				he := x.(Halfedge)
				ch <- Edge{v, he.End, he.Cost}
			}
		}
		close(ch)
	}()
	return ch
}

// HalfedgesIter returns a channel with all halfedges for
// the given start vertex.
func (g *Graph) HalfedgesIter(v Vertex) chan Halfedge {
	ch := make(chan Halfedge)
	go func() {
		if s, exists := g.Adjacency[v]; exists {
			for x := range s.Iter() {
				he := x.(Halfedge)
				ch <- he
			}
		}
		close(ch)
	}()
	return ch
}
<commit_msg>Use even more iterators<commit_after>package graphs

import (
	"fmt"
	"sort"
)

// A Vertex can be just anything.
type Vertex interface{}

// An Edge connects two vertices with a cost.
type Edge struct {
	Start Vertex
	End   Vertex
	Cost  float64
}

// A Halfedge is an edge where just the end vertex is
// stored. The start vertex is inferred from the context.
type Halfedge struct {
	End  Vertex
	Cost float64
}

// A Graph is defined by its vertices and edges stored as
// an adjacency set.
type Graph struct {
	Adjacency map[Vertex]*Set
	Vertices  *Set
	Directed  bool
}

// NewGraph creates a new empty graph.
func NewGraph() *Graph {
	return &Graph{
		Adjacency: map[Vertex]*Set{},
		Vertices:  NewSet(),
		Directed:  false,
	}
}

// NewDigraph creates a new empty directed graph.
func NewDigraph() *Graph {
	graph := NewGraph()
	graph.Directed = true
	return graph
}

// AddVertex adds the given vertex to the graph.
func (g *Graph) AddVertex(v Vertex) {
	g.Vertices.Add(v)
}

// AddEdge adds an edge to the graph. The edge connects
// vertex v1 and vertex v2 with cost c.
func (g *Graph) AddEdge(v1, v2 Vertex, c float64) {
	g.Vertices.Add(v1)
	g.Vertices.Add(v2)

	if _, exists := g.Adjacency[v1]; !exists {
		g.Adjacency[v1] = NewSet()
	}

	g.Adjacency[v1].Add(Halfedge{
		End:  v2,
		Cost: c,
	})

	if !g.Directed {
		if _, exists := g.Adjacency[v2]; !exists {
			g.Adjacency[v2] = NewSet()
		}

		g.Adjacency[v2].Add(Halfedge{
			End:  v1,
			Cost: c,
		})
	}
}

// Dump prints all edges with their cost to stdout.
func (g *Graph) Dump() {
	for e := range g.EdgesIter() {
		fmt.Printf("(%v,%v,%f)\n", e.Start, e.End, e.Cost)
	}
}

// NVertices returns the number of vertices.
func (g *Graph) NVertices() int {
	return g.Vertices.Len()
}

// NEdges returns the number of edges.
func (g *Graph) NEdges() int {
	n := 0

	for _, v := range g.Adjacency {
		n += v.Len()
	}

	// Don’t count a-b and b-a edges for undirected graphs
	// as two separate edges.
	if !g.Directed {
		n /= 2
	}

	return n
}

// Equals returns whether the graph is equal to the given graph.
// Two graphs are equal of their adjacency is equal.
func (g *Graph) Equals(g2 *Graph) bool {
	// Two graphs with differnet vertices aren’t equal.
	if !g.Vertices.Equals(g2.Vertices) {
		return false
	}

	// Some for number of edges.
	if g.NEdges() != g2.NEdges() {
		return false
	}

	// Check if the adjacency for each vertex is equal
	// for both graphs.
	a1 := g.Adjacency
	a2 := g2.Adjacency

	for k, v := range a1 {
		if !v.Equals(a2[k]) {
			return false
		}
	}

	return true
}

// VerticesIter returns a channel where all vertices
// are sent to.
func (g *Graph) VerticesIter() chan Vertex {
	ch := make(chan Vertex)
	go func() {
		for e := range g.Vertices.Iter() {
			ch <- e.(Vertex)
		}
		close(ch)
	}()
	return ch
}

// SortedEdges is an array of edges that can be sorted
// by their cost.
type SortedEdges []Edge

func (se SortedEdges) Len() int {
	return len(se)
}

func (se SortedEdges) Less(i, j int) bool {
	return se[i].Cost < se[j].Cost
}

func (se SortedEdges) Swap(i, j int) {
	se[i], se[j] = se[j], se[i]
}

// SortedEdges returns an array of edges sorted by their cost.
func (g *Graph) SortedEdges() SortedEdges {
	set := NewSet()

	for v := range g.Adjacency {
		for he := range g.HalfedgesIter(v) {
			set.Add(Edge{
				Start: v,
				End:   he.End,
				Cost:  he.Cost,
			})
		}
	}

	edges := make(SortedEdges, set.Len())
	for e := range set.Iter() {
		edges = append(edges, e.(Edge))
	}

	sort.Sort(&edges)
	return edges
}

// EdgesIter returns a channel with all edges of the graph.
func (g *Graph) EdgesIter() chan Edge {
	ch := make(chan Edge)
	go func() {
		for v, s := range g.Adjacency {
			for x := range s.Iter() {
				he := x.(Halfedge)
				ch <- Edge{v, he.End, he.Cost}
			}
		}
		close(ch)
	}()
	return ch
}

// HalfedgesIter returns a channel with all halfedges for
// the given start vertex.
func (g *Graph) HalfedgesIter(v Vertex) chan Halfedge {
	ch := make(chan Halfedge)
	go func() {
		if s, exists := g.Adjacency[v]; exists {
			for x := range s.Iter() {
				he := x.(Halfedge)
				ch <- he
			}
		}
		close(ch)
	}()
	return ch
}
<|endoftext|>


<commit_before>// gogl provides a framework for representing and working with graphs.
package gogl

type Vertex interface{}

type Graph interface {
	EachVertex(f func(vertex Vertex))
	EachEdge(f func(source Vertex, target Vertex))
	EachAdjacent(vertex Vertex, f func(adjacent Vertex))
	HasVertex(vertex Vertex) bool
	GetSubgraph([]Vertex) Graph
}

type MutableGraph interface {
	Graph
	AddVertex(v interface{}) bool
	RemoveVertex(v interface{}) bool
}

type DirectedGraph interface {
	Graph
	Transpose() DirectedGraph
	IsAcyclic() bool
	GetCycles() [][]interface{}
}

type MutableDirectedGraph interface {
	MutableGraph
	DirectedGraph
	addDirectedEdge(source interface{}, target interface{}) bool
	removeDirectedEdge(source interface{}, target interface{}) bool
}

type Edge interface {
	Tail() Vertex
	Head() Vertex
}
<commit_msg>Introduce bitfield describing edge capabilities.<commit_after>// gogl provides a framework for representing and working with graphs.
package gogl

// Constants defining graph capabilities and behaviors.
const (
  E_DIRECTED, EM_DIRECTED = 1 << iota, 1 << iota - 1
  E_UNDIRECTED, EM_UNDIRECTED
  E_WEIGHTED, EM_WEIGHTED
  E_TYPED, EM_TYPED
  E_SIGNED, EM_SIGNED
  E_LOOPS, EM_LOOPS
  E_MULTIGRAPH, EM_MULTIGRAPH
)

type Vertex interface{}

type Graph interface {
	EachVertex(f func(vertex Vertex))
	EachEdge(f func(source Vertex, target Vertex))
	EachAdjacent(vertex Vertex, f func(adjacent Vertex))
	HasVertex(vertex Vertex) bool
	GetSubgraph([]Vertex) Graph
}

type MutableGraph interface {
	Graph
	AddVertex(v interface{}) bool
	RemoveVertex(v interface{}) bool
}

type DirectedGraph interface {
	Graph
	Transpose() DirectedGraph
	IsAcyclic() bool
	GetCycles() [][]interface{}
}

type MutableDirectedGraph interface {
	MutableGraph
	DirectedGraph
	addDirectedEdge(source interface{}, target interface{}) bool
	removeDirectedEdge(source interface{}, target interface{}) bool
}

type Edge interface {
	Tail() Vertex
	Head() Vertex
}
<|endoftext|>


<commit_before>package saml

import "github.com/RobotsAndPencils/go-saml/util"

// ServiceProviderSettings provides settings to configure server acting as a SAML Service Provider.
// Expect only one IDP per SP in this configuration. If you need to configure multipe IDPs for an SP
// then configure multiple instances of this module
type ServiceProviderSettings struct {
	PublicCertPath              string
	PrivateKeyPath              string
	IDPSSOURL                   string
	IDPSSODescriptorURL         string
	IDPPublicCertPath           string
	AssertionConsumerServiceURL string
	SPSignRequest               bool

	hasInit       bool
	publicCert    string
	privateKey    string
	iDPPublicCert string
}

type IdentityProviderSettings struct {
}

func (s *ServiceProviderSettings) setHasInit() {
	s.hasInit = true
}

func (s *ServiceProviderSettings) Init() (err error) {
	if s.hasInit {
		return nil
	}
	defer s.setHasInit()
	if s.SPSignRequest {
		s.publicCert, err = util.LoadCertificate(s.PublicCertPath)
		if err != nil {
			panic(err)
		}

		s.privateKey, err = util.LoadCertificate(s.PrivateKeyPath)
		if err != nil {
			panic(err)
		}
	}

	s.iDPPublicCert, err = util.LoadCertificate(s.IDPPublicCertPath)
	if err != nil {
		panic(err)
	}

	return nil
}

func (s *ServiceProviderSettings) PublicCert() string {
	if !s.hasInit {
		panic("Must call ServiceProviderSettings.Init() first")
	}
	return s.publicCert
}

func (s *ServiceProviderSettings) PrivateKey() string {
	if !s.hasInit {
		panic("Must call ServiceProviderSettings.Init() first")
	}
	return s.privateKey
}

func (s *ServiceProviderSettings) IDPPublicCert() string {
	if !s.hasInit {
		panic("Must call ServiceProviderSettings.Init() first")
	}
	return s.iDPPublicCert
}
<commit_msg>fix regression. defer usage was wrong<commit_after>package saml

import (
	"log"

	"github.com/RobotsAndPencils/go-saml/util"
)

// ServiceProviderSettings provides settings to configure server acting as a SAML Service Provider.
// Expect only one IDP per SP in this configuration. If you need to configure multipe IDPs for an SP
// then configure multiple instances of this module
type ServiceProviderSettings struct {
	PublicCertPath              string
	PrivateKeyPath              string
	IDPSSOURL                   string
	IDPSSODescriptorURL         string
	IDPPublicCertPath           string
	AssertionConsumerServiceURL string
	SPSignRequest               bool

	hasInit       bool
	publicCert    string
	privateKey    string
	iDPPublicCert string
}

type IdentityProviderSettings struct {
}

func (s *ServiceProviderSettings) setHasInit() {
}

func (s *ServiceProviderSettings) Init() (err error) {
	if s.hasInit {
		log.Println("already initialized")
		return nil
	}
	if s.SPSignRequest {
		s.publicCert, err = util.LoadCertificate(s.PublicCertPath)
		if err != nil {
			log.Println("error loading public certificate: ", err)
			s.hasInit = false
			panic(err)
		}

		s.privateKey, err = util.LoadCertificate(s.PrivateKeyPath)
		if err != nil {
			log.Println("error loading private certificate: ", err)
			s.hasInit = false
			panic(err)
		}
	}

	s.iDPPublicCert, err = util.LoadCertificate(s.IDPPublicCertPath)
	if err != nil {
		log.Println("error loading idp public certificate: ", err)
		s.hasInit = false
		panic(err)
	} else {
		if s.iDPPublicCert != "" {
			s.hasInit = true
		} else {
			log.Println("idp public cert empty")
		}
	}
	return nil
}

func (s *ServiceProviderSettings) PublicCert() string {
	if !s.hasInit {
		panic("Must call ServiceProviderSettings.Init() first")
	}
	return s.publicCert
}

func (s *ServiceProviderSettings) PrivateKey() string {
	if !s.hasInit {
		panic("Must call ServiceProviderSettings.Init() first")
	}
	return s.privateKey
}

func (s *ServiceProviderSettings) IDPPublicCert() string {
	if !s.hasInit {
		panic("Must call ServiceProviderSettings.Init() first")
	}
	return s.iDPPublicCert
}
<|endoftext|>


<commit_before>package sqrl

import (
	"github.com/kalaspuffar/base64url"
	"time"
	"math/rand"
	"crypto/aes"
	"crypto/cipher"
	"encoding/binary"
	"fmt"
	"net"
)

type Nonce struct {
	global_counter uint32
	aesKeyBlock cipher.Block
}

func NewNonce() *Nonce {
	nonce := new(Nonce)
	nonce.global_counter = 0
	/*
		Create AES key for nut encryption
	*/
	rand.Seed(time.Now().Unix())
	aesKey := make([]byte, 16)
	binary.LittleEndian.PutUint32(aesKey[0:4], rand.Uint32())
	binary.LittleEndian.PutUint32(aesKey[4:8], rand.Uint32())
	binary.LittleEndian.PutUint32(aesKey[8:12], rand.Uint32())
	binary.LittleEndian.PutUint32(aesKey[12:16], rand.Uint32())
	aesKeyBlockRet, err := aes.NewCipher(aesKey)
	nonce.aesKeyBlock = aesKeyBlockRet
	if(err != nil) {
		fmt.Println(err)
	}

	return nonce
}

/*
	Generate a 32 bytes (128 bits) nonce from ipv4 address, timestamp, counter and random as
	suggested in SQRL documentation (https://www.grc.com/sqrl/server.htm)
	Encode this with AES key generated at server start and return
*/
func (r *Nonce) Generate(remoteAddr string) string {
	/*
		Prepare nut (128 bits)
	*/
	nut := make([]byte, 16)

	/*
		Prepare ipv4 address (32 bits)
	*/
	ipAddr := []byte(net.ParseIP(remoteAddr))
	ipv4Addr := ipAddr[len(ipAddr)-4:]
	copy(nut[0:4], ipv4Addr);

	/*
		Prepare unix timestamp (32 bits)
	*/
	binary.LittleEndian.PutUint32(nut[4:8], uint32(time.Now().Unix()))

	/*
		Prepare a global counter (32 bits)
	*/
	r.global_counter++
	binary.LittleEndian.PutUint32(nut[8:12], r.global_counter)

	/*
		Prepare a random uint32 (32 bits)
	*/
	rand.Seed(time.Now().Unix())
	binary.LittleEndian.PutUint32(nut[12:16], rand.Uint32())

	/*
		Encrypt nut with AES key and return base64url encoded string.
	 */
	encryptedNut := make([]byte, 16)
	r.aesKeyBlock.Encrypt(encryptedNut, nut)
	return base64url.Encode(encryptedNut)
}<commit_msg>Fix to nonce generation to handle remoteAddr strings with ipv6 format. Eg. [::1]:58000<commit_after>package sqrl

import (
	"github.com/kalaspuffar/base64url"
	"time"
	"math/rand"
	"crypto/aes"
	"crypto/cipher"
	"encoding/binary"
	"fmt"
	"net"
	"strings"
)

type Nonce struct {
	global_counter uint32
	aesKeyBlock cipher.Block
}

func NewNonce() *Nonce {
	nonce := new(Nonce)
	nonce.global_counter = 0
	/*
		Create AES key for nut encryption
	*/
	rand.Seed(time.Now().Unix())
	aesKey := make([]byte, 16)
	binary.LittleEndian.PutUint32(aesKey[0:4], rand.Uint32())
	binary.LittleEndian.PutUint32(aesKey[4:8], rand.Uint32())
	binary.LittleEndian.PutUint32(aesKey[8:12], rand.Uint32())
	binary.LittleEndian.PutUint32(aesKey[12:16], rand.Uint32())
	aesKeyBlockRet, err := aes.NewCipher(aesKey)
	nonce.aesKeyBlock = aesKeyBlockRet
	if err != nil {
		fmt.Println(err)
	}

	return nonce
}

/*
	Generate a 32 bytes (128 bits) nonce from ipv4 address, timestamp, counter and random as
	suggested in SQRL documentation (https://www.grc.com/sqrl/server.htm)
	Encode this with AES key generated at server start and return
*/
func (r *Nonce) Generate(remoteAddr string) string {
	/*
		Prepare nut (128 bits)
	*/
	nut := make([]byte, 16)

	/*
		Prepare ipv4 address (32 bits)
	*/
	if strings.Contains(remoteAddr, "]") {
		remoteAddr = strings.Split(remoteAddr, "]")[0]
		remoteAddr = strings.Replace(remoteAddr, "[", "", -1)
	} else {
		remoteAddr = strings.Split(remoteAddr, ":")[0]
	}
	ipAddr := []byte(net.ParseIP(remoteAddr))
	ipv4Addr := ipAddr[len(ipAddr)-4:]
	copy(nut[0:4], ipv4Addr);

	/*
		Prepare unix timestamp (32 bits)
	*/
	binary.LittleEndian.PutUint32(nut[4:8], uint32(time.Now().Unix()))

	/*
		Prepare a global counter (32 bits)
	*/
	r.global_counter++
	binary.LittleEndian.PutUint32(nut[8:12], r.global_counter)

	/*
		Prepare a random uint32 (32 bits)
	*/
	rand.Seed(time.Now().Unix())
	binary.LittleEndian.PutUint32(nut[12:16], rand.Uint32())

	/*
		Encrypt nut with AES key and return base64url encoded string.
	 */
	encryptedNut := make([]byte, 16)
	r.aesKeyBlock.Encrypt(encryptedNut, nut)
	return base64url.Encode(encryptedNut)
}<|endoftext|>


<commit_before>package qpid

import (
	"math"
	"time"
)

// Location of where something is
type Location int

// TODO: Need other location constants, think more here
const (
	_ Location = iota
	Food
	Top
	Bottom
	Outside
	Inside
)

// Temp is a temperature in Celcius
type Temp int

// C returns the temperature in Celcius
func (t *Temp) C() int {
	return t
}

// F returns the temperature in Fahrenheit
func (t *Temp) F() int {
	return math.Floor(t*9/5) + 32
}

// A Grill represents the cooking chamber of a BBQ cooker.
// It can contain one or more Sensors which report the current
// temperature.
type Grill struct {
	GrillSensors  []Sensor
	MeatSensors   []Sensor
	FoodMonitors  []Monitor
	GrillMonitors []Monitor
	Reporter      GrillReporter
}

// A Probe measures a temperature at a unique location.
type Probe struct {
	ID          int // Unique ID
	Location    Location
	Description string
	Temperature Temp // Current Temperature
}

// GrillStatus reports the temperatures of the Grill and Food probes at
// a point in time
type GrillStatus struct {
	Time              time.Time
	GrillTemperatures []Probe
	FoodTemperatures  []Probe
}

// Sensor is the interface to retrieve the current temperature
// of a probe
type Sensor interface {
	Temperature() (Temp, error)
	Location() Location
	Description() string
}

// Sourcer provides a string representing the source of an Alert
type Sourcer interface {
	Source() string
}

// An Alert is triggered when a Threshold is reached.
type Alert struct {
	Time    time.Time
	Message string
	Source  Sourcer
}

// A Thresholder watches a probe for high and low values,
// firing an Alert on the channel returned by Alerts()
type Thresholder interface {
	HighThreshold(Temp) error
	LowThreshold(Temp) error
	Alerts() chan<- Alert
}

// A Targeter sets the desired temperature for a device.
type Targeter interface {
	// Target sets the desired temperature, returns current and/or error
	Target(int) (int, error)
	// Setpoint() returns the currently set desired temperature
	Setpoint() (int, error)
}

type Monitor interface {
	Targeter
	Thresholder
}

// A CookController manages the cook.  A new cook is started by
// calling Run()
type CookController interface {
	FoodMonitors() []Monitor
	GrillMonitor() Monitor
	Run() error
}

// GrillReporter outputs metrics from a Grill
type GrillReporter interface {
	Status() (GrillStatus, error)
}
<commit_msg>and another<commit_after>package qpid

import (
	"math"
	"time"
)

// Location of where something is
type Location int

// TODO: Need other location constants, think more here
const (
	_ Location = iota
	Food
	Top
	Bottom
	Outside
	Inside
)

// Temp is a temperature in Celcius
type Temp int

// C returns the temperature in Celcius
func (t *Temp) C() int {
	return t
}

// F returns the temperature in Fahrenheit
func (t *Temp) F() int {
	return math.Floor(t*9/5) + 32
}

// A Grill represents the cooking chamber of a BBQ cooker.
// It can contain one or more Sensors which report the current
// temperature.
type Grill struct {
	GrillSensors  []Sensor
	MeatSensors   []Sensor
	FoodMonitors  []Monitor
	GrillMonitors []Monitor
	Reporter      GrillReporter
}

// A Probe measures a temperature at a unique location.
type Probe struct {
	ID          int // Unique ID
	Location    Location
	Description string
	Temperature Temp // Current Temperature
}

// GrillStatus reports the temperatures of the Grill and Food probes at
// a point in time
type GrillStatus struct {
	Time              time.Time
	GrillTemperatures []Probe
	FoodTemperatures  []Probe
}

// Sensor is the interface to retrieve the current temperature
// of a probe
type Sensor interface {
	Temperature() (Temp, error)
	Location() Location
	Description() string
}

// Sourcer provides a string representing the source of an Alert
type Sourcer interface {
	Source() string
}

// An Alert is triggered when a Threshold is reached.
type Alert struct {
	Time    time.Time
	Message string
	Source  Sourcer
}

// A Thresholder watches a probe for high and low values,
// firing an Alert on the channel returned by Alerts()
type Thresholder interface {
	HighThreshold(Temp) error
	LowThreshold(Temp) error
	Alerts() chan<- Alert
}

// A Targeter sets the desired temperature for a device.
type Targeter interface {
	// Target sets the desired temperature, returns current and/or error
	Target(Temp) (Temp, error)
	// Setpoint() returns the currently set desired temperature
	Setpoint() (Temp, error)
}

type Monitor interface {
	Targeter
	Thresholder
}

// A CookController manages the cook.  A new cook is started by
// calling Run()
type CookController interface {
	FoodMonitors() []Monitor
	GrillMonitor() Monitor
	Run() error
}

// GrillReporter outputs metrics from a Grill
type GrillReporter interface {
	Status() (GrillStatus, error)
}
<|endoftext|>


<commit_before>package migo

import (
	"database/sql"
	"fmt"

	"github.com/pkg/errors"
)

const (
	offFKCheck = "SET FOREIGN_KEY_CHECKS = 0"
	onFKCheck  = "SET FOREIGN_KEY_CHECKS = 1"
)

func GetDSN(dbpath, env string) (string, error) {
	dbconf, err := NewDb(dbpath, env)
	if err != nil {
		return "", errors.Wrap(err, "Parse db configue")
	}
	sqlconf := NewSql(*dbconf)
	return sqlconf.DbConf.FormatDSN(), nil
}

func GetInsertQuery(table string, data interface{}) (string, error) {
	q := fmt.Sprintf("INSERT INTO %s ", table)

	l, ok := data.(map[string]interface{})
	if !ok {
		return q, errors.Wrapf(ErrInvalidTable, "%+v", data)
	}
	var key, val string
	for k, v := range l {
		key += fmt.Sprintf("%s, ", k)
		switch v := v.(type) {
		default:
			val += fmt.Sprintf("'%v', ", v)
		case string:
			val += fmt.Sprintf("'%s', ", v)
		}
	}
	q += fmt.Sprintf("(%s) VALUES (%s)", key[0:len(key)-2], val[0:len(val)-2])
	return q, nil
}

func GetInsertQueries(path string) ([]string, error) {
	y, err := ParseYAML(path)
	if err != nil {
		return nil, errors.Wrap(err, "Parse YAML")
	}

	qs := []string{offFKCheck}
	for table, data := range y {
		datalist, ok := data.([]interface{})
		if !ok {
			return nil, errors.Wrapf(ErrInvalidTable, "%+v", data)
		}
		for _, d := range datalist {
			q, err := GetInsertQuery(table, d)
			if err != nil {
				return nil, errors.Wrap(err, "Query build failed")
			}
			qs = append(qs, q)
		}
	}
	qs = append(qs, onFKCheck)
	return qs, nil
}

func GetDeleteQueries(path string) ([]string, error) {
	y, err := ParseYAML(path)
	if err != nil {
		return nil, errors.Wrap(err, "Parse YAML")
	}

	qs := []string{offFKCheck}
	for table, _ := range y {
		qs = append(qs, fmt.Sprintf("TRUNCATE TABLE %s", table))
	}
	qs = append(qs, onFKCheck)
	return qs, nil
}

func Exec(qs []string, dsn string) error {
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		return errors.Wrap(err, "Create db connection")
	}
	defer db.Close()

	for _, q := range qs {
		_, err := db.Exec(q)
		if err != nil {
			return errors.Wrapf(err, "Query execute error: %s", q)
		}
	}
	return nil
}

func InsertRecords(path, dsn string) error {
	qs, err := GetInsertQueries(path)
	if err != nil {
		return err
	}
	if err := Exec(qs, dsn); err != nil {
		return errors.Wrap(err, "insert records")
	}
	return nil
}

func DropRecords(path, dsn string) error {
	qs, err := GetDeleteQueries(path)
	if err != nil {
		return err
	}
	if err := Exec(qs, dsn); err != nil {
		return errors.Wrap(err, "truncate records")
	}
	return nil
}

func Seed(path, dbpath, env string) error {
	dsn, err := GetDSN(dbpath, env)
	if err != nil {
		return err
	}

	if err := InsertRecords(path, dsn); err != nil {
		return err
	}

	return nil

}
<commit_msg>delete path params<commit_after>package migo

import (
	"database/sql"
	"fmt"

	"github.com/pkg/errors"
)

const (
	offFKCheck = "SET FOREIGN_KEY_CHECKS = 0"
	onFKCheck  = "SET FOREIGN_KEY_CHECKS = 1"
)

func GetDSN(dbpath, env string) (string, error) {
	dbconf, err := NewDb(dbpath, env)
	if err != nil {
		return "", errors.Wrap(err, "Parse db configue")
	}
	sqlconf := NewSql(*dbconf)
	return sqlconf.DbConf.FormatDSN(), nil
}

func GetInsertQuery(table string, data interface{}) (string, error) {
	q := fmt.Sprintf("INSERT INTO %s ", table)

	l, ok := data.(map[string]interface{})
	if !ok {
		return q, errors.Wrapf(ErrInvalidTable, "%+v", data)
	}
	var key, val string
	for k, v := range l {
		key += fmt.Sprintf("%s, ", k)
		switch v := v.(type) {
		default:
			val += fmt.Sprintf("'%v', ", v)
		case string:
			val += fmt.Sprintf("'%s', ", v)
		}
	}
	q += fmt.Sprintf("(%s) VALUES (%s)", key[0:len(key)-2], val[0:len(val)-2])
	return q, nil
}

func GetInsertQueries(y map[string]interface{}) ([]string, error) {
	qs := []string{offFKCheck}
	for table, data := range y {
		datalist, ok := data.([]interface{})
		if !ok {
			return nil, errors.Wrapf(ErrInvalidTable, "%+v", data)
		}
		for _, d := range datalist {
			q, err := GetInsertQuery(table, d)
			if err != nil {
				return nil, errors.Wrap(err, "Query build failed")
			}
			qs = append(qs, q)
		}
	}
	qs = append(qs, onFKCheck)
	return qs, nil
}

func GetDeleteQueries(y map[string]interface{}) ([]string, error) {

	qs := []string{offFKCheck}
	for table, _ := range y {
		qs = append(qs, fmt.Sprintf("TRUNCATE TABLE %s", table))
	}
	qs = append(qs, onFKCheck)
	return qs, nil
}

func Exec(qs []string, dsn string) error {
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		return errors.Wrap(err, "Create db connection")
	}
	defer db.Close()

	for _, q := range qs {
		_, err := db.Exec(q)
		if err != nil {
			return errors.Wrapf(err, "Query execute error: %s", q)
		}
	}
	return nil
}

func InsertRecords(y map[string]interface{}, dsn string) error {
	qs, err := GetInsertQueries(y)
	if err != nil {
		return err
	}
	if err := Exec(qs, dsn); err != nil {
		return errors.Wrap(err, "insert records")
	}
	return nil
}

func DropRecords(y map[string]interface{}, dsn string) error {
	qs, err := GetDeleteQueries(y)
	if err != nil {
		return err
	}
	if err := Exec(qs, dsn); err != nil {
		return errors.Wrap(err, "truncate records")
	}
	return nil
}

func Seed(path, dbpath, env string) error {
	dsn, err := GetDSN(dbpath, env)
	if err != nil {
		return err
	}

	y, err := ParseYAML(path)
	if err != nil {
		return err
	}

	if err := InsertRecords(y, dsn); err != nil {
		return err
	}

	return nil

}
<|endoftext|>


<commit_before><commit_msg>set timeout<commit_after><|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package integration

import (
	"context"
	"flag"
	"fmt"
	"math"
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
	"testing"
	"time"

	"k8s.io/minikube/pkg/minikube/constants"
	"k8s.io/minikube/pkg/minikube/detect"
)

// General configuration: used to set the VM Driver
var startArgs = flag.String("minikube-start-args", "", "Arguments to pass to minikube start")

// Flags for faster local integration testing
var forceProfile = flag.String("profile", "", "force tests to run against a particular profile")
var cleanup = flag.Bool("cleanup", true, "cleanup failed test run")
var enableGvisor = flag.Bool("gvisor", false, "run gvisor integration test (slow)")
var postMortemLogs = flag.Bool("postmortem-logs", true, "show logs after a failed test run")
var timeOutMultiplier = flag.Float64("timeout-multiplier", 1, "multiply the timeout for the tests")

// Paths to files - normally set for CI
var binaryPath = flag.String("binary", "../../out/minikube", "path to minikube binary")
var testdataDir = flag.String("testdata-dir", "testdata", "the directory relative to test/integration where the testdata lives")

// Node names are consistent, let's store these for easy access later
const (
	SecondNodeName = "m02"
	ThirdNodeName  = "m03"
)

// TestMain is the test main
func TestMain(m *testing.M) {
	flag.Parse()
	setMaxParallelism()

	start := time.Now()
	code := m.Run()
	fmt.Printf("Tests completed in %s (result code %d)\n", time.Since(start), code)
	os.Exit(code)
}

func TestMainNoArgs(t *testing.T) {
	rr, err := Run(t, exec.CommandContext(context.Background(), Target()))
	if err != nil {
		t.Fatalf("failed running minikube with no args %q: %v", rr.Command(), err)
	}
}

// setMaxParallelism caps the max parallelism. Go assumes 1 core per test, whereas minikube needs 2 cores per test.
func setMaxParallelism() {

	flagVal := flag.Lookup("test.parallel").Value.String()
	requested, err := strconv.Atoi(flagVal)
	if err != nil {
		fmt.Fprintf(os.Stderr, "unable to parse --test.parallel value: %q\n", flagVal)
		return
	}

	maxp := runtime.GOMAXPROCS(0)

	// Do not ignore what the user has explicitly set
	if requested != maxp {
		fmt.Fprintf(os.Stderr, "--test-parallel=%d was set via flags (system has %d cores)\n", requested, maxp)
		return
	}

	if maxp == 2 {
		fmt.Fprintf(os.Stderr, "Found %d cores, will not round down core count.\n", maxp)
		return
	}

	// Each "minikube start" consumes up to 2 cores, though the average usage is somewhat lower
	limit := int(math.Floor(float64(maxp) / 1.75))

	// Windows and MacOS tests were failing from timeouts due to too much parallelism
	if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
		limit /= 2
	}

	fmt.Fprintf(os.Stderr, "Found %d cores, limiting parallelism with --test.parallel=%d\n", maxp, limit)
	if err := flag.Set("test.parallel", strconv.Itoa(limit)); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to set test.parallel: %v\n", err)
	}
	runtime.GOMAXPROCS(limit)
}

// StartArgs returns the arguments normally used for starting minikube
func StartArgs() []string {
	return strings.Split(*startArgs, " ")
}

// Target returns where the minikube binary can be found
func Target() string {
	return *binaryPath
}

// NoneDriver returns whether or not this test is using the none driver
func NoneDriver() bool {
	return strings.Contains(*startArgs, "--driver=none") || strings.Contains(*startArgs, "--vm-driver=none")
}

// HyperVDriver returns whether or not this test is using the Hyper-V driver
func HyperVDriver() bool {
	return strings.Contains(*startArgs, "--driver=hyperv") || strings.Contains(*startArgs, "--vm-driver=hyperv")
}

// VirtualboxDriver returns whether or not this test is using the VirtualBox driver
func VirtualboxDriver() bool {
	return strings.Contains(*startArgs, "--driver=virtualbox") || strings.Contains(*startArgs, "--vm-driver=virtualbox")
}

// DockerDriver returns whether or not this test is using the docker or podman driver
func DockerDriver() bool {
	return strings.Contains(*startArgs, "--driver=docker") || strings.Contains(*startArgs, "--vm-driver=docker")
}

// PodmanDriver returns whether or not this test is using the docker or podman driver
func PodmanDriver() bool {
	return strings.Contains(*startArgs, "--vm-driver=podman") || strings.Contains(*startArgs, "driver=podman")
}

// KicDriver returns whether or not this test is using the docker or podman driver
func KicDriver() bool {
	return DockerDriver() || PodmanDriver()
}

// ContainerRuntime returns the name of a specific container runtime if it was specified
func ContainerRuntime() string {
	flag := "--container-runtime="
	for _, s := range StartArgs() {
		if strings.HasPrefix(s, flag) {
			return strings.TrimPrefix(s, flag)
		}
	}
	return constants.DefaultContainerRuntime
}

// GithubActionRunner returns true if running inside a github action runner
func GithubActionRunner() bool {
	// based on https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables
	return os.Getenv("GITHUB_ACTIONS") == "true"
}

// arm64Platform returns true if running on arm64/* platform
func arm64Platform() bool {
	return runtime.GOARCH == "arm64"
}

// NeedsPortForward returns access to endpoints with this driver needs port forwarding
// (Docker on non-Linux platforms requires ports to be forwarded to 127.0.0.1)
func NeedsPortForward() bool {
	return KicDriver() && (runtime.GOOS == "windows" || runtime.GOOS == "darwin") || detect.IsMicrosoftWSL()
}

// CanCleanup returns if cleanup is allowed
func CanCleanup() bool {
	return *cleanup
}

// Minutes will return timeout in minutes based on how slow the machine is
func Minutes(n int) time.Duration {
	return time.Duration(*timeOutMultiplier) * time.Duration(n) * time.Minute
}

// Seconds will return timeout in minutes based on how slow the machine is
func Seconds(n int) time.Duration {
	return time.Duration(*timeOutMultiplier) * time.Duration(n) * time.Second
}

// TestingKicBaseImage will return true if the integraiton test is running against a passed --base-image flag
func TestingKicBaseImage() bool {
	return strings.Contains(*startArgs, "base-image")
}
<commit_msg>hardcode to 2<commit_after>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package integration

import (
	"context"
	"flag"
	"fmt"
	"math"
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
	"testing"
	"time"

	"k8s.io/minikube/pkg/minikube/constants"
	"k8s.io/minikube/pkg/minikube/detect"
)

// General configuration: used to set the VM Driver
var startArgs = flag.String("minikube-start-args", "", "Arguments to pass to minikube start")

// Flags for faster local integration testing
var forceProfile = flag.String("profile", "", "force tests to run against a particular profile")
var cleanup = flag.Bool("cleanup", true, "cleanup failed test run")
var enableGvisor = flag.Bool("gvisor", false, "run gvisor integration test (slow)")
var postMortemLogs = flag.Bool("postmortem-logs", true, "show logs after a failed test run")
var timeOutMultiplier = flag.Float64("timeout-multiplier", 1, "multiply the timeout for the tests")

// Paths to files - normally set for CI
var binaryPath = flag.String("binary", "../../out/minikube", "path to minikube binary")
var testdataDir = flag.String("testdata-dir", "testdata", "the directory relative to test/integration where the testdata lives")

// Node names are consistent, let's store these for easy access later
const (
	SecondNodeName = "m02"
	ThirdNodeName  = "m03"
)

// TestMain is the test main
func TestMain(m *testing.M) {
	flag.Parse()
	setMaxParallelism()

	start := time.Now()
	code := m.Run()
	fmt.Printf("Tests completed in %s (result code %d)\n", time.Since(start), code)
	os.Exit(code)
}

func TestMainNoArgs(t *testing.T) {
	rr, err := Run(t, exec.CommandContext(context.Background(), Target()))
	if err != nil {
		t.Fatalf("failed running minikube with no args %q: %v", rr.Command(), err)
	}
}

// setMaxParallelism caps the max parallelism. Go assumes 1 core per test, whereas minikube needs 2 cores per test.
func setMaxParallelism() {

	flagVal := flag.Lookup("test.parallel").Value.String()
	requested, err := strconv.Atoi(flagVal)
	if err != nil {
		fmt.Fprintf(os.Stderr, "unable to parse --test.parallel value: %q\n", flagVal)
		return
	}

	maxp := runtime.GOMAXPROCS(0)

	// Do not ignore what the user has explicitly set
	if requested != maxp {
		fmt.Fprintf(os.Stderr, "--test-parallel=%d was set via flags (system has %d cores)\n", requested, maxp)
		return
	}

	if maxp == 2 {
		fmt.Fprintf(os.Stderr, "Found %d cores, will not round down core count.\n", maxp)
		return
	}

	// Each "minikube start" consumes up to 2 cores, though the average usage is somewhat lower
	limit := int(math.Floor(float64(maxp) / 1.75))

	// Windows and MacOS tests were failing from timeouts due to too much parallelism
	if runtime.GOOS == "windows" {
		limit /= 2
	}

	// Hardcode limit to 2 for macOS
	if runtime.GOOS == "darwin" {
		limit = 2
	}

	fmt.Fprintf(os.Stderr, "Found %d cores, limiting parallelism with --test.parallel=%d\n", maxp, limit)
	if err := flag.Set("test.parallel", strconv.Itoa(limit)); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to set test.parallel: %v\n", err)
	}
	runtime.GOMAXPROCS(limit)
}

// StartArgs returns the arguments normally used for starting minikube
func StartArgs() []string {
	return strings.Split(*startArgs, " ")
}

// Target returns where the minikube binary can be found
func Target() string {
	return *binaryPath
}

// NoneDriver returns whether or not this test is using the none driver
func NoneDriver() bool {
	return strings.Contains(*startArgs, "--driver=none") || strings.Contains(*startArgs, "--vm-driver=none")
}

// HyperVDriver returns whether or not this test is using the Hyper-V driver
func HyperVDriver() bool {
	return strings.Contains(*startArgs, "--driver=hyperv") || strings.Contains(*startArgs, "--vm-driver=hyperv")
}

// VirtualboxDriver returns whether or not this test is using the VirtualBox driver
func VirtualboxDriver() bool {
	return strings.Contains(*startArgs, "--driver=virtualbox") || strings.Contains(*startArgs, "--vm-driver=virtualbox")
}

// DockerDriver returns whether or not this test is using the docker or podman driver
func DockerDriver() bool {
	return strings.Contains(*startArgs, "--driver=docker") || strings.Contains(*startArgs, "--vm-driver=docker")
}

// PodmanDriver returns whether or not this test is using the docker or podman driver
func PodmanDriver() bool {
	return strings.Contains(*startArgs, "--vm-driver=podman") || strings.Contains(*startArgs, "driver=podman")
}

// KicDriver returns whether or not this test is using the docker or podman driver
func KicDriver() bool {
	return DockerDriver() || PodmanDriver()
}

// ContainerRuntime returns the name of a specific container runtime if it was specified
func ContainerRuntime() string {
	flag := "--container-runtime="
	for _, s := range StartArgs() {
		if strings.HasPrefix(s, flag) {
			return strings.TrimPrefix(s, flag)
		}
	}
	return constants.DefaultContainerRuntime
}

// GithubActionRunner returns true if running inside a github action runner
func GithubActionRunner() bool {
	// based on https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables
	return os.Getenv("GITHUB_ACTIONS") == "true"
}

// arm64Platform returns true if running on arm64/* platform
func arm64Platform() bool {
	return runtime.GOARCH == "arm64"
}

// NeedsPortForward returns access to endpoints with this driver needs port forwarding
// (Docker on non-Linux platforms requires ports to be forwarded to 127.0.0.1)
func NeedsPortForward() bool {
	return KicDriver() && (runtime.GOOS == "windows" || runtime.GOOS == "darwin") || detect.IsMicrosoftWSL()
}

// CanCleanup returns if cleanup is allowed
func CanCleanup() bool {
	return *cleanup
}

// Minutes will return timeout in minutes based on how slow the machine is
func Minutes(n int) time.Duration {
	return time.Duration(*timeOutMultiplier) * time.Duration(n) * time.Minute
}

// Seconds will return timeout in minutes based on how slow the machine is
func Seconds(n int) time.Duration {
	return time.Duration(*timeOutMultiplier) * time.Duration(n) * time.Second
}

// TestingKicBaseImage will return true if the integraiton test is running against a passed --base-image flag
func TestingKicBaseImage() bool {
	return strings.Contains(*startArgs, "base-image")
}
<|endoftext|>