<commit_before>package main

import (
	"github.com/toomore/gogrs/twse"
	"github.com/toomore/gogrs/utils"
)

type checkGroup interface {
	String() string
	CheckFunc(...*twse.Data) bool
}

type check01 struct{}

func (check01) String() string {
	return "MA 3 > 6 > 18"
}

func (check01) CheckFunc(b ...*twse.Data) bool {
	defer wg.Done()
	var d = b[0]
	var start = d.Len()
	if start == 0 {
		d.Get()
	}
	for {
		if d.Len() >= 18 {
			break
		}
		d.PlusData()
		if (d.Len() - start) == 0 {
			break
		}
		start = d.Len()
	}
	if d.Len() < 18 {
		return false
	}
	var ma3 = d.MA(3)
	if days, ok := utils.CountCountineFloat64(utils.DeltaFloat64(ma3)); !ok || days == 0 {
		return false
	}
	var ma6 = d.MA(6)
	if days, ok := utils.CountCountineFloat64(utils.DeltaFloat64(ma6)); !ok || days == 0 {
		return false
	}
	var ma18 = d.MA(18)
	if days, ok := utils.CountCountineFloat64(utils.DeltaFloat64(ma18)); !ok || days == 0 {
		return false
	}
	//log.Println(ma3[len(ma3)-1], ma6[len(ma6)-1], ma18[len(ma18)-1])
	if ma3[len(ma3)-1] > ma6[len(ma6)-1] && ma6[len(ma6)-1] > ma18[len(ma18)-1] {
		return true
	}
	return false
}

type check02 struct{}

func (check02) String() string {
	return "量大於前三天 K 線收紅"
}
func (check02) CheckFunc(b ...*twse.Data) bool {
	defer wg.Done()
	return utils.ThanSumPastUint64((*b[0]).GetVolumeList(), 3, true) && (*b[0]).IsRed()
}

type check03 struct{}

func (check03) String() string {
	return "量或價走平 45 天"
}

func (check03) CheckFunc(b ...*twse.Data) bool {
	defer wg.Done()
	if b[0].Len() < 45 {
		start := b[0].Len()
		for {
			b[0].PlusData()
			if b[0].Len() > 45 {
				break
			}
			if b[0].Len() == start {
				break
			}
			start = b[0].Len()
		}
		if b[0].Len() < 45 {
			return false
		}
	}
	var price = b[0].GetPriceList()
	var volume = b[0].GetVolumeList()
	return price[len(price)-1] > 10 &&
		(utils.SD(price[len(price)-46:]) < 0.25 ||
			utils.SDUint64(volume[len(volume)-46:]) < 0.25)
}

func init() {
	ckList.Add(checkGroup(check01{}))
	ckList.Add(checkGroup(check02{}))
	ckList.Add(checkGroup(check03{}))
}
<commit_msg>Add Mindata, prepareData.<commit_after>package main

import (
	"github.com/toomore/gogrs/twse"
	"github.com/toomore/gogrs/utils"
)

type checkGroup interface {
	String() string
	CheckFunc(...*twse.Data) bool
	Mindata() int
}

type check01 struct{}

func (check01) String() string {
	return "MA 3 > 6 > 18"
}

func (check01) Mindata() int {
	return 18
}

func (check01) CheckFunc(b ...*twse.Data) bool {
	defer wg.Done()
	var d = b[0]
	prepareCheck := prepareData(b...)
	if prepareCheck[0] != true {
		return false
	}
	var ma3 = d.MA(3)
	if days, ok := utils.CountCountineFloat64(utils.DeltaFloat64(ma3)); !ok || days == 0 {
		return false
	}
	var ma6 = d.MA(6)
	if days, ok := utils.CountCountineFloat64(utils.DeltaFloat64(ma6)); !ok || days == 0 {
		return false
	}
	var ma18 = d.MA(18)
	if days, ok := utils.CountCountineFloat64(utils.DeltaFloat64(ma18)); !ok || days == 0 {
		return false
	}
	//log.Println(ma3[len(ma3)-1], ma6[len(ma6)-1], ma18[len(ma18)-1])
	if ma3[len(ma3)-1] > ma6[len(ma6)-1] && ma6[len(ma6)-1] > ma18[len(ma18)-1] {
		return true
	}
	return false
}

type check02 struct{}

func (check02) String() string {
	return "量大於前三天 K 線收紅"
}

func (check02) Mindata() int {
	return 4
}

func (check02) CheckFunc(b ...*twse.Data) bool {
	defer wg.Done()
	return utils.ThanSumPastUint64((*b[0]).GetVolumeList(), 3, true) && (*b[0]).IsRed()
}

type check03 struct{}

func (check03) String() string {
	return "量或價走平 45 天"
}

func (check03) Mindata() int {
	return 45
}

func (check03) CheckFunc(b ...*twse.Data) bool {
	defer wg.Done()
	if !prepareData(b...)[0] {
		return false
	}
	var price = b[0].GetPriceList()
	var volume = b[0].GetVolumeList()
	return price[len(price)-1] > 10 &&
		(utils.SD(price[len(price)-46:]) < 0.25 ||
			utils.SDUint64(volume[len(volume)-46:]) < 0.25)
}

func prepareData(b ...*twse.Data) []bool {
	var result []bool
	for i, _ := range b {
		result = make([]bool, len(b))
		b[i].Get()
		if b[i].Len() < 45 {
			start := b[i].Len()
			for {
				b[i].PlusData()
				if b[i].Len() > 45 {
					result[i] = true
					break
				}
				if b[i].Len() == start {
					result[i] = false
					break
				}
				start = b[i].Len()
			}
			if b[i].Len() < 45 {
				result[i] = false
			}
		}
	}
	return result
}

func init() {
	ckList.Add(checkGroup(check01{}))
	ckList.Add(checkGroup(check02{}))
	ckList.Add(checkGroup(check03{}))
}
<|endoftext|>


<commit_before>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains tests for the copylock checker.

package testdata

import "sync"

func OkFunc(*sync.Mutex) {}
func BadFunc(sync.Mutex) {} // ERROR "BadFunc passes Lock by value: sync.Mutex"
func OkRet() *sync.Mutex {}
func BadRet() sync.Mutex {} // ERROR "BadRet returns Lock by value: sync.Mutex"

type EmbeddedRWMutex struct {
	sync.RWMutex
}

func (*EmbeddedRWMutex) OkMeth() {}
func (EmbeddedRWMutex) BadMeth() {} // ERROR "BadMeth passes Lock by value: testdata.EmbeddedRWMutex"
func OkFunc(e *EmbeddedRWMutex)  {}
func BadFunc(EmbeddedRWMutex)    {} // ERROR "BadFunc passes Lock by value: testdata.EmbeddedRWMutex"
func OkRet() *EmbeddedRWMutex    {}
func BadRet() EmbeddedRWMutex    {} // ERROR "BadRet returns Lock by value: testdata.EmbeddedRWMutex"

type FieldMutex struct {
	s sync.Mutex
}

func (*FieldMutex) OkMeth()   {}
func (FieldMutex) BadMeth()   {} // ERROR "BadMeth passes Lock by value: testdata.FieldMutex contains sync.Mutex"
func OkFunc(*FieldMutex)      {}
func BadFunc(FieldMutex, int) {} // ERROR "BadFunc passes Lock by value: testdata.FieldMutex contains sync.Mutex"

type L0 struct {
	L1
}

type L1 struct {
	l L2
}

type L2 struct {
	sync.Mutex
}

func (*L0) Ok() {}
func (L0) Bad() {} // ERROR "Bad passes Lock by value: testdata.L0 contains testdata.L1 contains testdata.L2"

type EmbeddedMutexPointer struct {
	s *sync.Mutex // safe to copy this pointer
}

func (*EmbeddedMutexPointer) Ok()      {}
func (EmbeddedMutexPointer) AlsoOk()   {}
func StillOk(EmbeddedMutexPointer)     {}
func LookinGood() EmbeddedMutexPointer {}

type EmbeddedLocker struct {
	sync.Locker // safe to copy interface values
}

func (*EmbeddedLocker) Ok()    {}
func (EmbeddedLocker) AlsoOk() {}

type CustomLock struct{}

func (*CustomLock) Lock()   {}
func (*CustomLock) Unlock() {}

func Ok(*CustomLock) {}
func Bad(CustomLock) {} // ERROR "Bad passes Lock by value: testdata.CustomLock"

// TODO: Unfortunate cases

// Non-ideal error message:
// Since we're looking for Lock methods, sync.Once's underlying
// sync.Mutex gets called out, but without any reference to the sync.Once.
type LocalOnce sync.Once

func (LocalOnce) Bad() {} // ERROR "Bad passes Lock by value: testdata.LocalOnce contains sync.Mutex"

// False negative:
// LocalMutex doesn't have a Lock method.
// Nevertheless, it is probably a bad idea to pass it by value.
type LocalMutex sync.Mutex

func (LocalMutex) Bad() {} // WANTED: An error here :(
<commit_msg>go.tools/cmd/vet: remove duplicate test file<commit_after><|endoftext|>


<commit_before>// Copyright 2016 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package downloader

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

	"github.com/juju/errors"
	"github.com/juju/utils"
)

// NewHTTPBlobOpener returns a blob opener func suitable for use with
// Download. The opener func uses an HTTP client that enforces the
// provided SSL hostname verification policy.
func NewHTTPBlobOpener(hostnameVerification utils.SSLHostnameVerification) func(*url.URL) (io.ReadCloser, error) {
	return func(url *url.URL) (io.ReadCloser, error) {
		// TODO(rog) make the download operation interruptible.
		client := utils.GetHTTPClient(hostnameVerification)
		resp, err := client.Get(url.String())
		if err != nil {
			return nil, err
		}
		if resp.StatusCode != http.StatusOK {
			resp.Body.Close()
			return nil, errors.Errorf("bad http response: %v", resp.Status)
		}
		return resp.Body, nil
	}
}

// NewSha256Verifier returns a verifier suitable for Request. The
// verifier checks the SHA-256 checksum of the file to ensure that it
// matches the one returned by the provided func.
func NewSha256Verifier(getExpected func() (string, error)) func(*os.File) error {
	return func(file *os.File) error {
		expected, err := getExpected()
		if err != nil {
			return errors.Trace(err)
		}

		actual, _, err := utils.ReadSHA256(file)
		if err != nil {
			return errors.Trace(err)
		}
		if actual != expected {
			err := errors.Errorf("expected sha256 %q, got %q", expected, actual)
			return errors.NewNotValid(err, "")
		}
		return nil
	}
}
<commit_msg>Clarify that resp.Body is always non-nil.<commit_after>// Copyright 2016 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package downloader

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

	"github.com/juju/errors"
	"github.com/juju/utils"
)

// NewHTTPBlobOpener returns a blob opener func suitable for use with
// Download. The opener func uses an HTTP client that enforces the
// provided SSL hostname verification policy.
func NewHTTPBlobOpener(hostnameVerification utils.SSLHostnameVerification) func(*url.URL) (io.ReadCloser, error) {
	return func(url *url.URL) (io.ReadCloser, error) {
		// TODO(rog) make the download operation interruptible.
		client := utils.GetHTTPClient(hostnameVerification)
		resp, err := client.Get(url.String())
		if err != nil {
			return nil, err
		}
		if resp.StatusCode != http.StatusOK {
			// resp.Body is always non-nil. (see https://golang.org/pkg/net/http/#Response)
			resp.Body.Close()
			return nil, errors.Errorf("bad http response: %v", resp.Status)
		}
		return resp.Body, nil
	}
}

// NewSha256Verifier returns a verifier suitable for Request. The
// verifier checks the SHA-256 checksum of the file to ensure that it
// matches the one returned by the provided func.
func NewSha256Verifier(getExpected func() (string, error)) func(*os.File) error {
	return func(file *os.File) error {
		expected, err := getExpected()
		if err != nil {
			return errors.Trace(err)
		}

		actual, _, err := utils.ReadSHA256(file)
		if err != nil {
			return errors.Trace(err)
		}
		if actual != expected {
			err := errors.Errorf("expected sha256 %q, got %q", expected, actual)
			return errors.NewNotValid(err, "")
		}
		return nil
	}
}
<|endoftext|>


<commit_before>// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime

import (
	"internal/abi"
	"internal/goarch"
	"unsafe"
)

// May run during STW, so write barriers are not allowed.
//
//go:nowritebarrierrec
func sighandler(_ureg *ureg, note *byte, gp *g) int {
	_g_ := getg()
	var t sigTabT
	var docrash bool
	var sig int
	var flags int
	var level int32

	c := &sigctxt{_ureg}
	notestr := gostringnocopy(note)

	// The kernel will never pass us a nil note or ureg so we probably
	// made a mistake somewhere in sigtramp.
	if _ureg == nil || note == nil {
		print("sighandler: ureg ", _ureg, " note ", note, "\n")
		goto Throw
	}
	// Check that the note is no more than ERRMAX bytes (including
	// the trailing NUL). We should never receive a longer note.
	if len(notestr) > _ERRMAX-1 {
		print("sighandler: note is longer than ERRMAX\n")
		goto Throw
	}
	if isAbortPC(c.pc()) {
		// Never turn abort into a panic.
		goto Throw
	}
	// See if the note matches one of the patterns in sigtab.
	// Notes that do not match any pattern can be handled at a higher
	// level by the program but will otherwise be ignored.
	flags = _SigNotify
	for sig, t = range sigtable {
		if hasPrefix(notestr, t.name) {
			flags = t.flags
			break
		}
	}
	if flags&_SigPanic != 0 && gp.throwsplit {
		// We can't safely sigpanic because it may grow the
		// stack. Abort in the signal handler instead.
		flags = (flags &^ _SigPanic) | _SigThrow
	}
	if flags&_SigGoExit != 0 {
		exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix.
	}
	if flags&_SigPanic != 0 {
		// Copy the error string from sigtramp's stack into m->notesig so
		// we can reliably access it from the panic routines.
		memmove(unsafe.Pointer(_g_.m.notesig), unsafe.Pointer(note), uintptr(len(notestr)+1))
		gp.sig = uint32(sig)
		gp.sigpc = c.pc()

		pc := c.pc()
		sp := c.sp()

		// If we don't recognize the PC as code
		// but we do recognize the top pointer on the stack as code,
		// then assume this was a call to non-code and treat like
		// pc == 0, to make unwinding show the context.
		if pc != 0 && !findfunc(pc).valid() && findfunc(*(*uintptr)(unsafe.Pointer(sp))).valid() {
			pc = 0
		}

		// IF LR exists, sigpanictramp must save it to the stack
		// before entry to sigpanic so that panics in leaf
		// functions are correctly handled. This will smash
		// the stack frame but we're not going back there
		// anyway.
		if usesLR {
			c.savelr(c.lr())
		}

		// If PC == 0, probably panicked because of a call to a nil func.
		// Not faking that as the return address will make the trace look like a call
		// to sigpanic instead. (Otherwise the trace will end at
		// sigpanic and we won't get to see who faulted).
		if pc != 0 {
			if usesLR {
				c.setlr(pc)
			} else {
				sp -= goarch.PtrSize
				*(*uintptr)(unsafe.Pointer(sp)) = pc
				c.setsp(sp)
			}
		}
		if usesLR {
			c.setpc(abi.FuncPCABI0(sigpanictramp))
		} else {
			c.setpc(abi.FuncPCABI0(sigpanic0))
		}
		return _NCONT
	}
	if flags&_SigNotify != 0 {
		if ignoredNote(note) {
			return _NCONT
		}
		if sendNote(note) {
			return _NCONT
		}
	}
	if flags&_SigKill != 0 {
		goto Exit
	}
	if flags&_SigThrow == 0 {
		return _NCONT
	}
Throw:
	_g_.m.throwing = throwTypeRuntime
	_g_.m.caughtsig.set(gp)
	startpanic_m()
	print(notestr, "\n")
	print("PC=", hex(c.pc()), "\n")
	print("\n")
	level, _, docrash = gotraceback()
	if level > 0 {
		goroutineheader(gp)
		tracebacktrap(c.pc(), c.sp(), c.lr(), gp)
		tracebackothers(gp)
		print("\n")
		dumpregs(_ureg)
	}
	if docrash {
		crash()
	}
Exit:
	goexitsall(note)
	exits(note)
	return _NDFLT // not reached
}

func sigenable(sig uint32) {
}

func sigdisable(sig uint32) {
}

func sigignore(sig uint32) {
}

func setProcessCPUProfiler(hz int32) {
}

func setThreadCPUProfiler(hz int32) {
	// TODO: Enable profiling interrupts.
	getg().m.profilehz = hz
}

// gsignalStack is unused on Plan 9.
type gsignalStack struct{}
<commit_msg>runtime: tricky replacements of _g_ in os3_plan9.go<commit_after>// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime

import (
	"internal/abi"
	"internal/goarch"
	"unsafe"
)

// May run during STW, so write barriers are not allowed.
//
//go:nowritebarrierrec
func sighandler(_ureg *ureg, note *byte, gp *g) int {
	gsignal := getg()
	mp := gsignal.m

	var t sigTabT
	var docrash bool
	var sig int
	var flags int
	var level int32

	c := &sigctxt{_ureg}
	notestr := gostringnocopy(note)

	// The kernel will never pass us a nil note or ureg so we probably
	// made a mistake somewhere in sigtramp.
	if _ureg == nil || note == nil {
		print("sighandler: ureg ", _ureg, " note ", note, "\n")
		goto Throw
	}
	// Check that the note is no more than ERRMAX bytes (including
	// the trailing NUL). We should never receive a longer note.
	if len(notestr) > _ERRMAX-1 {
		print("sighandler: note is longer than ERRMAX\n")
		goto Throw
	}
	if isAbortPC(c.pc()) {
		// Never turn abort into a panic.
		goto Throw
	}
	// See if the note matches one of the patterns in sigtab.
	// Notes that do not match any pattern can be handled at a higher
	// level by the program but will otherwise be ignored.
	flags = _SigNotify
	for sig, t = range sigtable {
		if hasPrefix(notestr, t.name) {
			flags = t.flags
			break
		}
	}
	if flags&_SigPanic != 0 && gp.throwsplit {
		// We can't safely sigpanic because it may grow the
		// stack. Abort in the signal handler instead.
		flags = (flags &^ _SigPanic) | _SigThrow
	}
	if flags&_SigGoExit != 0 {
		exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix.
	}
	if flags&_SigPanic != 0 {
		// Copy the error string from sigtramp's stack into m->notesig so
		// we can reliably access it from the panic routines.
		memmove(unsafe.Pointer(mp.notesig), unsafe.Pointer(note), uintptr(len(notestr)+1))
		gp.sig = uint32(sig)
		gp.sigpc = c.pc()

		pc := c.pc()
		sp := c.sp()

		// If we don't recognize the PC as code
		// but we do recognize the top pointer on the stack as code,
		// then assume this was a call to non-code and treat like
		// pc == 0, to make unwinding show the context.
		if pc != 0 && !findfunc(pc).valid() && findfunc(*(*uintptr)(unsafe.Pointer(sp))).valid() {
			pc = 0
		}

		// IF LR exists, sigpanictramp must save it to the stack
		// before entry to sigpanic so that panics in leaf
		// functions are correctly handled. This will smash
		// the stack frame but we're not going back there
		// anyway.
		if usesLR {
			c.savelr(c.lr())
		}

		// If PC == 0, probably panicked because of a call to a nil func.
		// Not faking that as the return address will make the trace look like a call
		// to sigpanic instead. (Otherwise the trace will end at
		// sigpanic and we won't get to see who faulted).
		if pc != 0 {
			if usesLR {
				c.setlr(pc)
			} else {
				sp -= goarch.PtrSize
				*(*uintptr)(unsafe.Pointer(sp)) = pc
				c.setsp(sp)
			}
		}
		if usesLR {
			c.setpc(abi.FuncPCABI0(sigpanictramp))
		} else {
			c.setpc(abi.FuncPCABI0(sigpanic0))
		}
		return _NCONT
	}
	if flags&_SigNotify != 0 {
		if ignoredNote(note) {
			return _NCONT
		}
		if sendNote(note) {
			return _NCONT
		}
	}
	if flags&_SigKill != 0 {
		goto Exit
	}
	if flags&_SigThrow == 0 {
		return _NCONT
	}
Throw:
	mp.throwing = throwTypeRuntime
	mp.caughtsig.set(gp)
	startpanic_m()
	print(notestr, "\n")
	print("PC=", hex(c.pc()), "\n")
	print("\n")
	level, _, docrash = gotraceback()
	if level > 0 {
		goroutineheader(gp)
		tracebacktrap(c.pc(), c.sp(), c.lr(), gp)
		tracebackothers(gp)
		print("\n")
		dumpregs(_ureg)
	}
	if docrash {
		crash()
	}
Exit:
	goexitsall(note)
	exits(note)
	return _NDFLT // not reached
}

func sigenable(sig uint32) {
}

func sigdisable(sig uint32) {
}

func sigignore(sig uint32) {
}

func setProcessCPUProfiler(hz int32) {
}

func setThreadCPUProfiler(hz int32) {
	// TODO: Enable profiling interrupts.
	getg().m.profilehz = hz
}

// gsignalStack is unused on Plan 9.
type gsignalStack struct{}
<|endoftext|>


<commit_before>// Copyright (c) 2018 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package codegen

import (
	"bytes"
	"encoding/gob"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"text/template"

	"github.com/golang/mock/mockgen/model"
	"github.com/pkg/errors"
)

type reflectData struct {
	PathAliasMap  map[string]string
	PathSymbolMap map[string]string
}

// ReflectInterface uses reflection to obtain interface information for each path symbol pair in the pathSympolMap
// projRoot is the root dir where mockgen is installed as a vendor package
func ReflectInterface(projRoot string, pathSymbolMap map[string]string) (map[string]*model.Package, error) {
	// We use TempDir instead of TempFile so we can control the filename.
	tmpDir, err := ioutil.TempDir(projRoot, "gomock_reflect_")
	if err != nil {
		return nil, err
	}
	defer func() { _ = os.RemoveAll(tmpDir) }()

	const progSource = "prog.go"
	var progBinary = "prog.bin"
	if runtime.GOOS == "windows" {
		// Windows won't execute a program unless it has a ".exe" suffix.
		progBinary += ".exe"
	}

	// Generate program
	paths := make(map[string]bool, len(pathSymbolMap))
	for p := range pathSymbolMap {
		paths[p] = true
	}
	data := reflectData{
		PathAliasMap:  uniqueAlias(paths),
		PathSymbolMap: pathSymbolMap,
	}
	var program bytes.Buffer
	if err := reflectProgram.Execute(&program, &data); err != nil {
		return nil, err
	}

	if err := ioutil.WriteFile(filepath.Join(tmpDir, progSource), program.Bytes(), 0600); err != nil {
		return nil, err
	}

	// Build it
	var buildStdout, buildStderr bytes.Buffer
	build := exec.Command("go", "build", "-o", progBinary, progSource)
	build.Dir = tmpDir
	build.Stdout = &buildStdout
	build.Stderr = &buildStderr
	if err := build.Run(); err != nil {
		return nil, errors.Wrap(err, buildStderr.String())
	}
	progPath := filepath.Join(tmpDir, progBinary)

	// Run it
	var stdout, stderr bytes.Buffer
	cmd := exec.Command(progPath)
	cmd.Dir = projRoot
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		return nil, errors.Wrap(err, stderr.String())
	}

	var pkgs map[string]*model.Package
	if err := gob.NewDecoder(&stdout).Decode(&pkgs); err != nil {
		return nil, err
	}
	return pkgs, nil
}

// This program reflects on an interface value, and prints the
// gob encoding of a model.Package to standard output.
// JSON doesn't work because of the model.Type interface.
var reflectProgram = template.Must(template.New("program").Parse(`
{{$pathAliasMap := .PathAliasMap}}
{{$pathSymbolMap := .PathSymbolMap}}
package main

import (
	"encoding/gob"
	"fmt"
	"os"
	"reflect"

	"github.com/golang/mock/mockgen/model"

	{{range $importPath, $alias := $pathAliasMap}}
	{{$alias}} "{{$importPath}}"
	{{end}}
)

func main() {
	its := []struct{
		path, sym string
		typ 	  reflect.Type
	}{
		{{range $importPath, $symbol := $pathSymbolMap}}
		{"{{$importPath}}", "{{$symbol}}", reflect.TypeOf((*{{index $pathAliasMap $importPath}}.{{$symbol}})(nil)).Elem()},
		{{end}}
	}

	pkgs := make(map[string]*model.Package, {{len $pathSymbolMap}})
	{{range $importPath, $symbol := $pathSymbolMap}}
	pkgs["{{$importPath}}"] = &model.Package{
		Name: "{{index $pathAliasMap $importPath}}",
	}
	{{end}}

	stderr := os.Stderr
	for _, it := range its {
		intf, err := model.InterfaceFromInterfaceType(it.typ)
		if err != nil {
			fmt.Fprintf(stderr, "Reflection: %v\n", err)
			os.Exit(1)
		}
		intf.Name = it.sym
		pkgs[it.path].Interfaces = []*model.Interface{intf}
	}
	if err := gob.NewEncoder(os.Stdout).Encode(pkgs); err != nil {
		fmt.Fprintf(stderr, "gob encode: %v\n", err)
		os.Exit(1)
	}
}
`))
<commit_msg>When generating temporary go program for mockgen, use cwd rather than GOPATH<commit_after>// Copyright (c) 2018 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package codegen

import (
	"bytes"
	"encoding/gob"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"text/template"

	"github.com/golang/mock/mockgen/model"
	"github.com/pkg/errors"
)

type reflectData struct {
	PathAliasMap  map[string]string
	PathSymbolMap map[string]string
}

// ReflectInterface uses reflection to obtain interface information for each path symbol pair in the pathSympolMap
// projRoot is the root dir where mockgen is installed as a vendor package
func ReflectInterface(projRoot string, pathSymbolMap map[string]string) (map[string]*model.Package, error) {
	// We use TempDir instead of TempFile so we can control the filename.
	tmpDir, err := ioutil.TempDir("./", "gomock_reflect_")
	if err != nil {
		return nil, err
	}
	defer func() { _ = os.RemoveAll(tmpDir) }()

	const progSource = "prog.go"
	var progBinary = "prog.bin"
	if runtime.GOOS == "windows" {
		// Windows won't execute a program unless it has a ".exe" suffix.
		progBinary += ".exe"
	}

	// Generate program
	paths := make(map[string]bool, len(pathSymbolMap))
	for p := range pathSymbolMap {
		paths[p] = true
	}
	data := reflectData{
		PathAliasMap:  uniqueAlias(paths),
		PathSymbolMap: pathSymbolMap,
	}
	var program bytes.Buffer
	if err := reflectProgram.Execute(&program, &data); err != nil {
		return nil, err
	}

	if err := ioutil.WriteFile(filepath.Join(tmpDir, progSource), program.Bytes(), 0600); err != nil {
		return nil, err
	}

	// Build it
	var buildStdout, buildStderr bytes.Buffer
	build := exec.Command("go", "build", "-o", progBinary, progSource)
	build.Dir = tmpDir
	build.Stdout = &buildStdout
	build.Stderr = &buildStderr
	if err := build.Run(); err != nil {
		return nil, errors.Wrap(err, buildStderr.String())
	}
	progPath := filepath.Join(tmpDir, progBinary)

	// Run it
	var stdout, stderr bytes.Buffer
	cmd := exec.Command(progPath)
	cmd.Dir = projRoot
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		return nil, errors.Wrap(err, stderr.String())
	}

	var pkgs map[string]*model.Package
	if err := gob.NewDecoder(&stdout).Decode(&pkgs); err != nil {
		return nil, err
	}
	return pkgs, nil
}

// This program reflects on an interface value, and prints the
// gob encoding of a model.Package to standard output.
// JSON doesn't work because of the model.Type interface.
var reflectProgram = template.Must(template.New("program").Parse(`
{{$pathAliasMap := .PathAliasMap}}
{{$pathSymbolMap := .PathSymbolMap}}
package main

import (
	"encoding/gob"
	"fmt"
	"os"
	"reflect"

	"github.com/golang/mock/mockgen/model"

	{{range $importPath, $alias := $pathAliasMap}}
	{{$alias}} "{{$importPath}}"
	{{end}}
)

func main() {
	its := []struct{
		path, sym string
		typ 	  reflect.Type
	}{
		{{range $importPath, $symbol := $pathSymbolMap}}
		{"{{$importPath}}", "{{$symbol}}", reflect.TypeOf((*{{index $pathAliasMap $importPath}}.{{$symbol}})(nil)).Elem()},
		{{end}}
	}

	pkgs := make(map[string]*model.Package, {{len $pathSymbolMap}})
	{{range $importPath, $symbol := $pathSymbolMap}}
	pkgs["{{$importPath}}"] = &model.Package{
		Name: "{{index $pathAliasMap $importPath}}",
	}
	{{end}}

	stderr := os.Stderr
	for _, it := range its {
		intf, err := model.InterfaceFromInterfaceType(it.typ)
		if err != nil {
			fmt.Fprintf(stderr, "Reflection: %v\n", err)
			os.Exit(1)
		}
		intf.Name = it.sym
		pkgs[it.path].Interfaces = []*model.Interface{intf}
	}
	if err := gob.NewEncoder(os.Stdout).Encode(pkgs); err != nil {
		fmt.Fprintf(stderr, "gob encode: %v\n", err)
		os.Exit(1)
	}
}
`))
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. 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 metadata provides access to Google Compute Engine (GCE)
// metadata and API service accounts.
//
// This package is a wrapper around the GCE metadata service,
// as documented at https://developers.google.com/compute/docs/metadata.
package metadata

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"strings"
	"sync"
	"time"
)

type cachedValue struct {
	k    string
	trim bool
	mu   sync.Mutex
	v    string
}

var (
	projID  = &cachedValue{k: "project/project-id", trim: true}
	projNum = &cachedValue{k: "project/numeric-project-id", trim: true}
	instID  = &cachedValue{k: "instance/id", trim: true}
)

var metaClient = &http.Client{
	Transport: &http.Transport{
		Dial: (&net.Dialer{
			Timeout:   750 * time.Millisecond,
			KeepAlive: 30 * time.Second,
		}).Dial,
		ResponseHeaderTimeout: 750 * time.Millisecond,
	},
}

// Get returns a value from the metadata service.
// The suffix is appended to "http://metadata/computeMetadata/v1/".
func Get(suffix string) (string, error) {
	// Using 169.254.169.254 instead of "metadata" here because Go
	// binaries built with the "netgo" tag and without cgo won't
	// know the search suffix for "metadata" is
	// ".google.internal", and this IP address is documented as
	// being stable anyway.
	url := "http://169.254.169.254/computeMetadata/v1/" + suffix
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Metadata-Flavor", "Google")
	res, err := metaClient.Do(req)
	if err != nil {
		return "", err
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		return "", fmt.Errorf("status code %d trying to fetch %s", res.StatusCode, url)
	}
	all, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return "", err
	}
	return string(all), nil
}

func getTrimmed(suffix string) (s string, err error) {
	s, err = Get(suffix)
	s = strings.TrimSpace(s)
	return
}

func (c *cachedValue) get() (v string, err error) {
	defer c.mu.Unlock()
	c.mu.Lock()
	if c.v != "" {
		return c.v, nil
	}
	if c.trim {
		v, err = getTrimmed(c.k)
	} else {
		v, err = Get(c.k)
	}
	if err == nil {
		c.v = v
	}
	return
}

var onGCE struct {
	sync.Mutex
	set bool
	v   bool
}

// OnGCE reports whether this process is running on Google Compute Engine.
func OnGCE() bool {
	defer onGCE.Unlock()
	onGCE.Lock()
	if onGCE.set {
		return onGCE.v
	}
	onGCE.set = true

	res, err := metaClient.Get("http://metadata.google.internal")
	if err != nil {
		return false
	}
	onGCE.v = res.Header.Get("Metadata-Flavor") == "Google"
	return onGCE.v
}

// ProjectID returns the current instance's project ID string.
func ProjectID() (string, error) { return projID.get() }

// NumericProjectID returns the current instance's numeric project ID.
func NumericProjectID() (string, error) { return projNum.get() }

// InternalIP returns the instance's primary internal IP address.
func InternalIP() (string, error) {
	return getTrimmed("instance/network-interfaces/0/ip")
}

// ExternalIP returns the instance's primary external (public) IP address.
func ExternalIP() (string, error) {
	return getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip")
}

// Hostname returns the instance's hostname. This will probably be of
// the form "INSTANCENAME.c.PROJECT.internal" but that isn't
// guaranteed.
//
// TODO: what is this defined to be? Docs say "The host name of the
// instance."
func Hostname() (string, error) {
	return getTrimmed("network-interfaces/0/ip")
}

// InstanceTags returns the list of user-defined instance tags,
// assigned when initially creating a GCE instance.
func InstanceTags() ([]string, error) {
	var s []string
	j, err := Get("instance/tags")
	if err != nil {
		return nil, err
	}
	if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil {
		return nil, err
	}
	return s, nil
}

// InstanceID returns the current VM's numeric instance ID.
func InstanceID() (string, error) {
	return instID.get()
}

// InstanceAttributes returns the list of user-defined attributes,
// assigned when initially creating a GCE VM instance. The value of an
// attribute can be obtained with InstanceAttributeValue.
func InstanceAttributes() ([]string, error) { return lines("instance/attributes/") }

// ProjectAttributes returns the list of user-defined attributes
// applying to the project as a whole, not just this VM.  The value of
// an attribute can be obtained with ProjectAttributeValue.
func ProjectAttributes() ([]string, error) { return lines("project/attributes/") }

func lines(suffix string) ([]string, error) {
	j, err := Get(suffix)
	if err != nil {
		return nil, err
	}
	s := strings.Split(strings.TrimSpace(j), "\n")
	for i := range s {
		s[i] = strings.TrimSpace(s[i])
	}
	return s, nil
}

// InstanceAttributeValue returns the value of the provided VM
// instance attribute.
func InstanceAttributeValue(attr string) (string, error) {
	return Get("instance/attributes/" + attr)
}

// ProjectAttributeValue returns the value of the provided
// project attribute.
func ProjectAttributeValue(attr string) (string, error) {
	return Get("project/attributes/" + attr)
}

// Scopes returns the service account scopes for the given account.
// The account may be empty or the string "default" to use the instance's
// main account.
func Scopes(serviceAccount string) ([]string, error) {
	if serviceAccount == "" {
		serviceAccount = "default"
	}
	return lines("instance/service-accounts/" + serviceAccount + "/scopes")
}
<commit_msg>compute/metadata: Add comment about why OnGCE prefers to do DNS lookup.<commit_after>// Copyright 2014 Google Inc. 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 metadata provides access to Google Compute Engine (GCE)
// metadata and API service accounts.
//
// This package is a wrapper around the GCE metadata service,
// as documented at https://developers.google.com/compute/docs/metadata.
package metadata

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"strings"
	"sync"
	"time"
)

type cachedValue struct {
	k    string
	trim bool
	mu   sync.Mutex
	v    string
}

var (
	projID  = &cachedValue{k: "project/project-id", trim: true}
	projNum = &cachedValue{k: "project/numeric-project-id", trim: true}
	instID  = &cachedValue{k: "instance/id", trim: true}
)

var metaClient = &http.Client{
	Transport: &http.Transport{
		Dial: (&net.Dialer{
			Timeout:   750 * time.Millisecond,
			KeepAlive: 30 * time.Second,
		}).Dial,
		ResponseHeaderTimeout: 750 * time.Millisecond,
	},
}

// Get returns a value from the metadata service.
// The suffix is appended to "http://metadata/computeMetadata/v1/".
func Get(suffix string) (string, error) {
	// Using 169.254.169.254 instead of "metadata" here because Go
	// binaries built with the "netgo" tag and without cgo won't
	// know the search suffix for "metadata" is
	// ".google.internal", and this IP address is documented as
	// being stable anyway.
	url := "http://169.254.169.254/computeMetadata/v1/" + suffix
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Metadata-Flavor", "Google")
	res, err := metaClient.Do(req)
	if err != nil {
		return "", err
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		return "", fmt.Errorf("status code %d trying to fetch %s", res.StatusCode, url)
	}
	all, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return "", err
	}
	return string(all), nil
}

func getTrimmed(suffix string) (s string, err error) {
	s, err = Get(suffix)
	s = strings.TrimSpace(s)
	return
}

func (c *cachedValue) get() (v string, err error) {
	defer c.mu.Unlock()
	c.mu.Lock()
	if c.v != "" {
		return c.v, nil
	}
	if c.trim {
		v, err = getTrimmed(c.k)
	} else {
		v, err = Get(c.k)
	}
	if err == nil {
		c.v = v
	}
	return
}

var onGCE struct {
	sync.Mutex
	set bool
	v   bool
}

// OnGCE reports whether this process is running on Google Compute Engine.
func OnGCE() bool {
	defer onGCE.Unlock()
	onGCE.Lock()
	if onGCE.set {
		return onGCE.v
	}
	onGCE.set = true

	// We use the DNS name of the metadata service here instead of the IP address
	// because we expect that to fail faster in the not-on-GCE case.
	res, err := metaClient.Get("http://metadata.google.internal")
	if err != nil {
		return false
	}
	onGCE.v = res.Header.Get("Metadata-Flavor") == "Google"
	return onGCE.v
}

// ProjectID returns the current instance's project ID string.
func ProjectID() (string, error) { return projID.get() }

// NumericProjectID returns the current instance's numeric project ID.
func NumericProjectID() (string, error) { return projNum.get() }

// InternalIP returns the instance's primary internal IP address.
func InternalIP() (string, error) {
	return getTrimmed("instance/network-interfaces/0/ip")
}

// ExternalIP returns the instance's primary external (public) IP address.
func ExternalIP() (string, error) {
	return getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip")
}

// Hostname returns the instance's hostname. This will probably be of
// the form "INSTANCENAME.c.PROJECT.internal" but that isn't
// guaranteed.
//
// TODO: what is this defined to be? Docs say "The host name of the
// instance."
func Hostname() (string, error) {
	return getTrimmed("network-interfaces/0/ip")
}

// InstanceTags returns the list of user-defined instance tags,
// assigned when initially creating a GCE instance.
func InstanceTags() ([]string, error) {
	var s []string
	j, err := Get("instance/tags")
	if err != nil {
		return nil, err
	}
	if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil {
		return nil, err
	}
	return s, nil
}

// InstanceID returns the current VM's numeric instance ID.
func InstanceID() (string, error) {
	return instID.get()
}

// InstanceAttributes returns the list of user-defined attributes,
// assigned when initially creating a GCE VM instance. The value of an
// attribute can be obtained with InstanceAttributeValue.
func InstanceAttributes() ([]string, error) { return lines("instance/attributes/") }

// ProjectAttributes returns the list of user-defined attributes
// applying to the project as a whole, not just this VM.  The value of
// an attribute can be obtained with ProjectAttributeValue.
func ProjectAttributes() ([]string, error) { return lines("project/attributes/") }

func lines(suffix string) ([]string, error) {
	j, err := Get(suffix)
	if err != nil {
		return nil, err
	}
	s := strings.Split(strings.TrimSpace(j), "\n")
	for i := range s {
		s[i] = strings.TrimSpace(s[i])
	}
	return s, nil
}

// InstanceAttributeValue returns the value of the provided VM
// instance attribute.
func InstanceAttributeValue(attr string) (string, error) {
	return Get("instance/attributes/" + attr)
}

// ProjectAttributeValue returns the value of the provided
// project attribute.
func ProjectAttributeValue(attr string) (string, error) {
	return Get("project/attributes/" + attr)
}

// Scopes returns the service account scopes for the given account.
// The account may be empty or the string "default" to use the instance's
// main account.
func Scopes(serviceAccount string) ([]string, error) {
	if serviceAccount == "" {
		serviceAccount = "default"
	}
	return lines("instance/service-accounts/" + serviceAccount + "/scopes")
}
<|endoftext|>


<commit_before>package controllers

import (
	"net/http"
	"encoding/json"
	"github.com/wandi34/wallets-as-a-service/backend/common"
	"fmt"
	"github.com/blockcypher/gobcy"
	"github.com/wandi34/wallets-as-a-service/backend/data"
	"github.com/wandi34/wallets-as-a-service/backend/models"
	"gopkg.in/mgo.v2/bson"
	"strconv"
)

//var bcy = gobcy.API{"2aa27c3912c047f2baa7e932cfc453e7", "bcy", "test"}

func CreateTransaction(w http.ResponseWriter, r *http.Request) {
	var dataResource CreateTransactionResource
	// Decode the incoming Transaction json
	err := json.NewDecoder(r.Body).Decode(&dataResource)
	if err != nil {
		common.DisplayAppError(
			w,
			err,
			"Invalid body",
			500,
		)
		return
	}
	sourceAddress := dataResource.Data.SourceAddress
	targetAddress := dataResource.Data.TargetAddress
	amount, err := strconv.Atoi(dataResource.Data.Amount)
	//Post New TXSkeleton
	skel, err := bcy.NewTX(gobcy.TempNewTX(sourceAddress, targetAddress, amount), false)
	if err != nil {
		fmt.Println(err)
	}
	//Sign it locally
	context := NewContext()
	defer context.Close()
	col := context.DbCollection("accounts")
	repo := &data.AccountRepository{C: col}
	// Authenticate the login user
	result := models.Account{}
	err = repo.C.Find(bson.M{"wallet.address": "C85ZfUB6W1KfwX3WPB9avoM4wciTKdFVbP"}).One(&result)
	fmt.Println(len(skel.ToSign))
	err = skel.Sign([]string{result.Wallet.Private})
	if err != nil {
		fmt.Println(err)
	}
	//Send TXSkeleton
	skel, err = bcy.SendTX(skel)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("%+v\n", skel)
}
<commit_msg>Create transactions for specific user<commit_after>package controllers

import (
	"net/http"
	"encoding/json"
	"github.com/wandi34/wallets-as-a-service/backend/common"
	"fmt"
	"github.com/blockcypher/gobcy"
	"github.com/wandi34/wallets-as-a-service/backend/data"
	"github.com/wandi34/wallets-as-a-service/backend/models"
	"gopkg.in/mgo.v2/bson"
	"strconv"
)

//var bcy = gobcy.API{"2aa27c3912c047f2baa7e932cfc453e7", "bcy", "test"}

func CreateTransaction(w http.ResponseWriter, r *http.Request) {
	var dataResource CreateTransactionResource
	// Decode the incoming Transaction json
	err := json.NewDecoder(r.Body).Decode(&dataResource)
	if err != nil {
		common.DisplayAppError(
			w,
			err,
			"Invalid body",
			500,
		)
		return
	}
	sourceAddress := dataResource.Data.SourceAddress
	targetAddress := dataResource.Data.TargetAddress
	amount, err := strconv.Atoi(dataResource.Data.Amount)
	//Post New TXSkeleton
	skel, err := bcy.NewTX(gobcy.TempNewTX(sourceAddress, targetAddress, amount), false)
	if err != nil {
		fmt.Println(err)
	}
	//Sign it locally
	context := NewContext()
	defer context.Close()
	col := context.DbCollection("accounts")
	repo := &data.AccountRepository{C: col}
	// Authenticate the login user
	result := models.Account{}
	err = repo.C.Find(bson.M{"wallet.address": sourceAddress}).One(&result)
	fmt.Println(len(skel.ToSign))
	err = skel.Sign([]string{result.Wallet.Private})
	if err != nil {
		fmt.Println(err)
	}
	//Send TXSkeleton
	skel, err = bcy.SendTX(skel)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("%+v\n", skel)
}
<|endoftext|>


<commit_before>package cc_messages

const CF_ROUTER = "cf-router"

type Routes []Route

type Route struct {
	Port  uint16   `json:"port"`
	Hosts []string `json:"hosts"`
}
<commit_msg>Add receptor.RoutingInfo related constructors<commit_after>package cc_messages

import (
	"encoding/json"

	"github.com/cloudfoundry-incubator/receptor"
)

const CF_ROUTER = "cf-router"

type Routes []Route

type Route struct {
	Hostnames []string `json:"routes"`
	Port      uint16   `json:"port"`
}

type receptorRoute struct {
	Hostnames []string `json:"hostnames"`
	Port      uint16   `json:"port"`
}

func NewRoutingInfo(hostnames []string, port uint16) *receptor.RoutingInfo {
	routingData, err := json.Marshal([]receptorRoute{
		{Hostnames: hostnames, Port: port},
	})
	if err != nil {
		panic("unexpected failure to marshal route")
	}

	routingInfo := json.RawMessage(routingData)

	return &receptor.RoutingInfo{
		CF_ROUTER: &routingInfo,
	}
}

func RouteFromRoutingInfo(routingInfo *receptor.RoutingInfo) Route {
	route := Route{}
	if routingInfo != nil {
		if message, found := (*routingInfo)[CF_ROUTER]; found {
			receptorRoutes := []receptorRoute{}

			err := json.Unmarshal([]byte(*message), &receptorRoutes)
			if err != nil {
				panic("unexpected failure to marshal route")
			}

			if len(receptorRoutes) > 0 {
				route.Hostnames = receptorRoutes[0].Hostnames
				route.Port = receptorRoutes[0].Port
			}
		}
	}

	return route
}
<|endoftext|>


<commit_before>package cephfs

import (
	"fmt"
	"os"
	"syscall"
	"testing"
	"time"

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

var (
	CephMountTest = "/tmp/ceph/mds/mnt/"
)

func TestCreateMount(t *testing.T) {
	mount := fsConnect(t)
	mount, err := CreateMount()
	assert.NoError(t, err)
	assert.NotNil(t, mount)
}

func fsConnect(t *testing.T) *MountInfo {
	mount, err := CreateMount()
	require.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	require.NoError(t, err)

	timeout := time.After(time.Second * 5)
	ch := make(chan error)
	go func(mount *MountInfo) {
		ch <- mount.Mount()
	}(mount)
	select {
	case err = <-ch:
	case <-timeout:
		err = fmt.Errorf("timed out waiting for connect")
	}
	require.NoError(t, err)
	return mount
}

func TestMountRoot(t *testing.T) {
	fsConnect(t)
}

func TestSyncFs(t *testing.T) {
	mount := fsConnect(t)

	err := mount.SyncFs()
	assert.NoError(t, err)
}

func TestChangeDir(t *testing.T) {
	mount := fsConnect(t)

	dir1 := mount.CurrentDir()
	assert.NotNil(t, dir1)

	err := mount.MakeDir("/asdf", 0755)
	assert.NoError(t, err)

	err = mount.ChangeDir("/asdf")
	assert.NoError(t, err)

	dir2 := mount.CurrentDir()
	assert.NotNil(t, dir2)

	assert.NotEqual(t, dir1, dir2)
	assert.Equal(t, dir1, "/")
	assert.Equal(t, dir2, "/asdf")
}

func TestRemoveDir(t *testing.T) {
	dirname := "one"
	mount := fsConnect(t)

	err := mount.MakeDir(dirname, 0755)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	_, err = os.Stat(CephMountTest + dirname)
	assert.NoError(t, err)

	err = mount.RemoveDir(dirname)
	assert.NoError(t, err)

	_, err = os.Stat(CephMountTest + dirname)
	assert.EqualError(t, err,
		fmt.Sprintf("stat %s: no such file or directory", CephMountTest+dirname))
}

func TestUnmountMount(t *testing.T) {
	t.Run("neverMounted", func(t *testing.T) {
		mount, err := CreateMount()
		require.NoError(t, err)
		require.NotNil(t, mount)
		assert.False(t, mount.IsMounted())
	})
	t.Run("mountUnmount", func(t *testing.T) {
		mount := fsConnect(t)
		assert.True(t, mount.IsMounted())

		err := mount.Unmount()
		assert.NoError(t, err)
		assert.False(t, mount.IsMounted())
	})
}

func TestReleaseMount(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.Release()
	assert.NoError(t, err)
}

func TestChmodDir(t *testing.T) {
	dirname := "two"
	var stats_before uint32 = 0755
	var stats_after uint32 = 0700
	mount := fsConnect(t)

	err := mount.MakeDir(dirname, stats_before)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	stats, err := os.Stat(CephMountTest + dirname)
	require.NoError(t, err)

	assert.Equal(t, uint32(stats.Mode().Perm()), stats_before)

	err = mount.Chmod(dirname, stats_after)
	assert.NoError(t, err)

	stats, err = os.Stat(CephMountTest + dirname)
	assert.Equal(t, uint32(stats.Mode().Perm()), stats_after)
}

// Not cross-platform, go's os does not specifiy Sys return type
func TestChown(t *testing.T) {
	dirname := "three"
	// dockerfile creates bob user account
	var bob uint32 = 1010
	var root uint32

	mount := fsConnect(t)

	err := mount.MakeDir(dirname, 0755)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	stats, err := os.Stat(CephMountTest + dirname)
	require.NoError(t, err)

	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Uid), root)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Gid), root)

	err = mount.Chown(dirname, bob, bob)
	assert.NoError(t, err)

	stats, err = os.Stat(CephMountTest + dirname)
	assert.NoError(t, err)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Uid), bob)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Gid), bob)

}

func TestCephFSError(t *testing.T) {
	err := getError(0)
	assert.NoError(t, err)

	err = getError(-5) // IO error
	assert.Error(t, err)
	assert.Equal(t, err.Error(), "cephfs: ret=5, Input/output error")

	err = getError(345) // no such errno
	assert.Error(t, err)
	assert.Equal(t, err.Error(), "cephfs: ret=345")
}
<commit_msg>cephfs: test creating a cephfs mount from a rados Conn<commit_after>package cephfs

import (
	"fmt"
	"os"
	"syscall"
	"testing"
	"time"

	"github.com/ceph/go-ceph/rados"

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

var (
	CephMountTest = "/tmp/ceph/mds/mnt/"
)

func TestCreateMount(t *testing.T) {
	mount := fsConnect(t)
	mount, err := CreateMount()
	assert.NoError(t, err)
	assert.NotNil(t, mount)
}

func fsConnect(t *testing.T) *MountInfo {
	mount, err := CreateMount()
	require.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	require.NoError(t, err)

	timeout := time.After(time.Second * 5)
	ch := make(chan error)
	go func(mount *MountInfo) {
		ch <- mount.Mount()
	}(mount)
	select {
	case err = <-ch:
	case <-timeout:
		err = fmt.Errorf("timed out waiting for connect")
	}
	require.NoError(t, err)
	return mount
}

func TestMountRoot(t *testing.T) {
	fsConnect(t)
}

func TestSyncFs(t *testing.T) {
	mount := fsConnect(t)

	err := mount.SyncFs()
	assert.NoError(t, err)
}

func TestChangeDir(t *testing.T) {
	mount := fsConnect(t)

	dir1 := mount.CurrentDir()
	assert.NotNil(t, dir1)

	err := mount.MakeDir("/asdf", 0755)
	assert.NoError(t, err)

	err = mount.ChangeDir("/asdf")
	assert.NoError(t, err)

	dir2 := mount.CurrentDir()
	assert.NotNil(t, dir2)

	assert.NotEqual(t, dir1, dir2)
	assert.Equal(t, dir1, "/")
	assert.Equal(t, dir2, "/asdf")
}

func TestRemoveDir(t *testing.T) {
	dirname := "one"
	mount := fsConnect(t)

	err := mount.MakeDir(dirname, 0755)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	_, err = os.Stat(CephMountTest + dirname)
	assert.NoError(t, err)

	err = mount.RemoveDir(dirname)
	assert.NoError(t, err)

	_, err = os.Stat(CephMountTest + dirname)
	assert.EqualError(t, err,
		fmt.Sprintf("stat %s: no such file or directory", CephMountTest+dirname))
}

func TestUnmountMount(t *testing.T) {
	t.Run("neverMounted", func(t *testing.T) {
		mount, err := CreateMount()
		require.NoError(t, err)
		require.NotNil(t, mount)
		assert.False(t, mount.IsMounted())
	})
	t.Run("mountUnmount", func(t *testing.T) {
		mount := fsConnect(t)
		assert.True(t, mount.IsMounted())

		err := mount.Unmount()
		assert.NoError(t, err)
		assert.False(t, mount.IsMounted())
	})
}

func TestReleaseMount(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.Release()
	assert.NoError(t, err)
}

func TestChmodDir(t *testing.T) {
	dirname := "two"
	var stats_before uint32 = 0755
	var stats_after uint32 = 0700
	mount := fsConnect(t)

	err := mount.MakeDir(dirname, stats_before)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	stats, err := os.Stat(CephMountTest + dirname)
	require.NoError(t, err)

	assert.Equal(t, uint32(stats.Mode().Perm()), stats_before)

	err = mount.Chmod(dirname, stats_after)
	assert.NoError(t, err)

	stats, err = os.Stat(CephMountTest + dirname)
	assert.Equal(t, uint32(stats.Mode().Perm()), stats_after)
}

// Not cross-platform, go's os does not specifiy Sys return type
func TestChown(t *testing.T) {
	dirname := "three"
	// dockerfile creates bob user account
	var bob uint32 = 1010
	var root uint32

	mount := fsConnect(t)

	err := mount.MakeDir(dirname, 0755)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	stats, err := os.Stat(CephMountTest + dirname)
	require.NoError(t, err)

	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Uid), root)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Gid), root)

	err = mount.Chown(dirname, bob, bob)
	assert.NoError(t, err)

	stats, err = os.Stat(CephMountTest + dirname)
	assert.NoError(t, err)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Uid), bob)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Gid), bob)

}

func TestCephFSError(t *testing.T) {
	err := getError(0)
	assert.NoError(t, err)

	err = getError(-5) // IO error
	assert.Error(t, err)
	assert.Equal(t, err.Error(), "cephfs: ret=5, Input/output error")

	err = getError(345) // no such errno
	assert.Error(t, err)
	assert.Equal(t, err.Error(), "cephfs: ret=345")
}

func radosConnect(t *testing.T) *rados.Conn {
	conn, err := rados.NewConn()
	require.NoError(t, err)
	err = conn.ReadDefaultConfigFile()
	require.NoError(t, err)

	timeout := time.After(time.Second * 5)
	ch := make(chan error)
	go func(conn *rados.Conn) {
		ch <- conn.Connect()
	}(conn)
	select {
	case err = <-ch:
	case <-timeout:
		err = fmt.Errorf("timed out waiting for connect")
	}
	require.NoError(t, err)
	return conn
}

func TestCreateFromRados(t *testing.T) {
	conn := radosConnect(t)
	mount, err := CreateFromRados(conn)
	assert.NoError(t, err)
	assert.NotNil(t, mount)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"reflect"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/cloudfoundry-community/go-cfenv"
)

const (
	key   = "test-key"
	value = "test-value"
)

var creds map[string]interface{}

func main() {
	env, _ := cfenv.Current()
	services, _ := env.Services.WithLabel(os.Getenv("SERVICE_NAME"))
	if len(services) != 1 {
		log.Fatalf("Expected one service instance; got %d", len(services))
	}
	creds = services[0].Credentials

	http.HandleFunc("/", handler)
	http.ListenAndServe(":"+os.Getenv("PORT"), nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
	config := &aws.Config{
		Region: aws.String(creds["region"].(string)),
		Credentials: credentials.NewStaticCredentials(
			creds["access_key_id"].(string),
			creds["secret_access_key"].(string),
			"",
		),
	}

	sess, err := session.NewSession(config)
	if err != nil {
		log.Println(err.Error())
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	svc := s3.New(sess)

	bucket := creds["bucket"].(string)
	additionalBuckets := []string{}
	for _, additionalBucket := range creds["additional_buckets"].([]interface{}) {
		additionalBuckets = append(additionalBuckets, additionalBucket.(string))
	}

	if os.Getenv("ADDITIONAL_INSTANCE_NAME") != "" {
		if len(additionalBuckets) != 1 {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
	}

	buckets := append(additionalBuckets, bucket)

	for _, bucket := range buckets {
		if err := testBucket(bucket, svc); err != nil {
			log.Println(err.Error())
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
	}

	w.WriteHeader(http.StatusOK)
}

func testBucket(bucket string, svc *s3.S3) error {
	// Test put object
	if _, err := svc.PutObject(&s3.PutObjectInput{
		Body:   strings.NewReader(value),
		Bucket: aws.String(creds["bucket"].(string)),
		Key:    aws.String(key),
	}); err != nil {
		return err
	}

	// Test get object
	result, err := svc.GetObject(&s3.GetObjectInput{
		Bucket: aws.String(creds["bucket"].(string)),
		Key:    aws.String(key),
	})
	if err != nil {
		return err
	}

	// Test object contents
	body, err := ioutil.ReadAll(result.Body)
	if err != nil {
		return err
	}
	if string(body) != value {
		return fmt.Errorf("Got value %s; expected %s", string(body), value)
	}

	// Test public access
	resp, _ := http.Get(
		fmt.Sprintf(
			"https://s3-%s.amazonaws.com/%s/%s",
			creds["region"].(string),
			creds["bucket"].(string),
			key,
		),
	)
	expectedCode := http.StatusForbidden
	if os.Getenv("IS_PUBLIC") == "true" {
		expectedCode = http.StatusOK
	}
	if resp.StatusCode != expectedCode {
		return fmt.Errorf("expected code %d; got %d", expectedCode, resp.StatusCode)
	}

	// Test delete object
	if _, err = svc.DeleteObject(&s3.DeleteObjectInput{
		Bucket: aws.String(creds["bucket"].(string)),
		Key:    aws.String(key),
	}); err != nil {
		return err
	}

	// Leave object in bucket
	if _, err := svc.PutObject(&s3.PutObjectInput{
		Body:   strings.NewReader(value),
		Bucket: aws.String(creds["bucket"].(string)),
		Key:    aws.String(key),
	}); err != nil {
		return err
	}

	expectedEncryption := os.Getenv("ENCRYPTION")
	if expectedEncryption != "" {
		var expectedConfig s3.ServerSideEncryptionConfiguration
		if err := json.Unmarshal([]byte(expectedEncryption), &expectedConfig); err != nil {
			return err
		}
		encryptionOutput, err := svc.GetBucketEncryption(&s3.GetBucketEncryptionInput{
			Bucket: aws.String(creds["bucket"].(string)),
		})
		if err != nil {
			return err
		}
		if !reflect.DeepEqual(expectedConfig, *encryptionOutput.ServerSideEncryptionConfiguration) {
			return fmt.Errorf("expected encryption config %+v; got %+v", expectedConfig, encryptionOutput.ServerSideEncryptionConfiguration)
		}
	}

	return nil
}
<commit_msg>Removed code that leaves a file in bucket.<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"reflect"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/cloudfoundry-community/go-cfenv"
)

const (
	key   = "test-key"
	value = "test-value"
)

var creds map[string]interface{}

func main() {
	env, _ := cfenv.Current()
	services, _ := env.Services.WithLabel(os.Getenv("SERVICE_NAME"))
	if len(services) != 1 {
		log.Fatalf("Expected one service instance; got %d", len(services))
	}
	creds = services[0].Credentials

	http.HandleFunc("/", handler)
	http.ListenAndServe(":"+os.Getenv("PORT"), nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
	config := &aws.Config{
		Region: aws.String(creds["region"].(string)),
		Credentials: credentials.NewStaticCredentials(
			creds["access_key_id"].(string),
			creds["secret_access_key"].(string),
			"",
		),
	}

	sess, err := session.NewSession(config)
	if err != nil {
		log.Println(err.Error())
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	svc := s3.New(sess)

	bucket := creds["bucket"].(string)
	additionalBuckets := []string{}
	for _, additionalBucket := range creds["additional_buckets"].([]interface{}) {
		additionalBuckets = append(additionalBuckets, additionalBucket.(string))
	}

	if os.Getenv("ADDITIONAL_INSTANCE_NAME") != "" {
		if len(additionalBuckets) != 1 {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
	}

	buckets := append(additionalBuckets, bucket)

	for _, bucket := range buckets {
		if err := testBucket(bucket, svc); err != nil {
			log.Println(err.Error())
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
	}

	w.WriteHeader(http.StatusOK)
}

func testBucket(bucket string, svc *s3.S3) error {
	// Test put object
	if _, err := svc.PutObject(&s3.PutObjectInput{
		Body:   strings.NewReader(value),
		Bucket: aws.String(creds["bucket"].(string)),
		Key:    aws.String(key),
	}); err != nil {
		return err
	}

	// Test get object
	result, err := svc.GetObject(&s3.GetObjectInput{
		Bucket: aws.String(creds["bucket"].(string)),
		Key:    aws.String(key),
	})
	if err != nil {
		return err
	}

	// Test object contents
	body, err := ioutil.ReadAll(result.Body)
	if err != nil {
		return err
	}
	if string(body) != value {
		return fmt.Errorf("Got value %s; expected %s", string(body), value)
	}

	// Test public access
	resp, _ := http.Get(
		fmt.Sprintf(
			"https://s3-%s.amazonaws.com/%s/%s",
			creds["region"].(string),
			creds["bucket"].(string),
			key,
		),
	)
	expectedCode := http.StatusForbidden
	if os.Getenv("IS_PUBLIC") == "true" {
		expectedCode = http.StatusOK
	}
	if resp.StatusCode != expectedCode {
		return fmt.Errorf("expected code %d; got %d", expectedCode, resp.StatusCode)
	}

	// Test delete object
	if _, err = svc.DeleteObject(&s3.DeleteObjectInput{
		Bucket: aws.String(creds["bucket"].(string)),
		Key:    aws.String(key),
	}); err != nil {
		return err
	}

	expectedEncryption := os.Getenv("ENCRYPTION")
	if expectedEncryption != "" {
		var expectedConfig s3.ServerSideEncryptionConfiguration
		if err := json.Unmarshal([]byte(expectedEncryption), &expectedConfig); err != nil {
			return err
		}
		encryptionOutput, err := svc.GetBucketEncryption(&s3.GetBucketEncryptionInput{
			Bucket: aws.String(creds["bucket"].(string)),
		})
		if err != nil {
			return err
		}
		if !reflect.DeepEqual(expectedConfig, *encryptionOutput.ServerSideEncryptionConfiguration) {
			return fmt.Errorf("expected encryption config %+v; got %+v", expectedConfig, encryptionOutput.ServerSideEncryptionConfiguration)
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package cli

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"path"
	"time"

	"github.com/alecthomas/kingpin"
	"github.com/prometheus/alertmanager/cli/format"
	"github.com/prometheus/alertmanager/types"
)

type getResponse struct {
	Status    string        `json:"status"`
	Data      types.Silence `json:"data,omitempty"`
	ErrorType string        `json:"errorType,omitempty"`
	Error     string        `json:"error,omitempty"`
}

var (
	updateCmd       = silenceCmd.Command("update", "Update silences")
	updateExpires   = updateCmd.Flag("expires", "Duration of silence").Short('e').Duration()
	updateExpiresOn = updateCmd.Flag("expire-on", "Expire at a certain time (Overwrites expires) RFC3339 format 2006-01-02T15:04:05Z07:00").Time(time.RFC3339)
	updateComment   = updateCmd.Flag("comment", "A comment to help describe the silence").Short('c').String()
	updateIds       = updateCmd.Arg("update-ids", "Silence IDs to update").Strings()
)

func init() {
	updateCmd.Action(update)
	longHelpText["silence update"] = `Extend or update existing silence in Alertmanager.`
}

func update(element *kingpin.ParseElement, ctx *kingpin.ParseContext) error {
	if len(*updateIds) < 1 {
		return fmt.Errorf("no silence IDs specified")
	}

	alertmanagerUrl := GetAlertmanagerURL("/api/v1/silence")
	var updatedSilences []types.Silence
	for _, silenceId := range *updateIds {
		silence, err := getSilenceById(silenceId, alertmanagerUrl)
		if err != nil {
			return err
		}
		silence, err = updateSilence(silence)
		if err != nil {
			return err
		}
		updatedSilences = append(updatedSilences, *silence)
	}

	if *silenceQuiet {
		for _, silence := range updatedSilences {
			fmt.Println(silence.ID)
		}
	} else {
		formatter, found := format.Formatters[*output]
		if !found {
			return fmt.Errorf("unknown output formatter")
		}
		formatter.FormatSilences(updatedSilences)
	}
	return nil
}

// This takes an url.URL and not a pointer as we will modify it for our API call.
func getSilenceById(silenceId string, baseUrl url.URL) (*types.Silence, error) {
	baseUrl.Path = path.Join(baseUrl.Path, silenceId)
	res, err := http.Get(baseUrl.String())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, fmt.Errorf("couldn't read response body: %v", err)
	}

	if res.StatusCode == 404 {
		return nil, fmt.Errorf("no silence found with id: %v", silenceId)
	}
	if res.StatusCode != 200 {
		return nil, fmt.Errorf("received %d response from Alertmanager: %v", res.StatusCode, body)
	}

	var response getResponse
	err = json.Unmarshal(body, &response)
	return &response.Data, nil
}

func updateSilence(silence *types.Silence) (*types.Silence, error) {
	if *updateExpires != 0 {
		silence.EndsAt = time.Now().UTC().Add(*updateExpires)
	}

	// expire-on will override expires value if both are specified
	if !(*updateExpiresOn).IsZero() {
		silence.EndsAt = *updateExpiresOn
	}

	if *comment != "" {
		silence.Comment = *comment
	}

	// addSilence can also be used to update an existing silence
	_, err := addSilence(silence)
	if err != nil {
		return nil, err
	}
	return silence, nil
}
<commit_msg>Fix updating silence comments (#1189)<commit_after>package cli

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"path"
	"time"

	"github.com/alecthomas/kingpin"
	"github.com/prometheus/alertmanager/cli/format"
	"github.com/prometheus/alertmanager/types"
)

type getResponse struct {
	Status    string        `json:"status"`
	Data      types.Silence `json:"data,omitempty"`
	ErrorType string        `json:"errorType,omitempty"`
	Error     string        `json:"error,omitempty"`
}

var (
	updateCmd       = silenceCmd.Command("update", "Update silences")
	updateExpires   = updateCmd.Flag("expires", "Duration of silence").Short('e').Duration()
	updateExpiresOn = updateCmd.Flag("expire-on", "Expire at a certain time (Overwrites expires) RFC3339 format 2006-01-02T15:04:05Z07:00").Time(time.RFC3339)
	updateComment   = updateCmd.Flag("comment", "A comment to help describe the silence").Short('c').String()
	updateIds       = updateCmd.Arg("update-ids", "Silence IDs to update").Strings()
)

func init() {
	updateCmd.Action(update)
	longHelpText["silence update"] = `Extend or update existing silence in Alertmanager.`
}

func update(element *kingpin.ParseElement, ctx *kingpin.ParseContext) error {
	if len(*updateIds) < 1 {
		return fmt.Errorf("no silence IDs specified")
	}

	alertmanagerUrl := GetAlertmanagerURL("/api/v1/silence")
	var updatedSilences []types.Silence
	for _, silenceId := range *updateIds {
		silence, err := getSilenceById(silenceId, alertmanagerUrl)
		if err != nil {
			return err
		}
		silence, err = updateSilence(silence)
		if err != nil {
			return err
		}
		updatedSilences = append(updatedSilences, *silence)
	}

	if *silenceQuiet {
		for _, silence := range updatedSilences {
			fmt.Println(silence.ID)
		}
	} else {
		formatter, found := format.Formatters[*output]
		if !found {
			return fmt.Errorf("unknown output formatter")
		}
		formatter.FormatSilences(updatedSilences)
	}
	return nil
}

// This takes an url.URL and not a pointer as we will modify it for our API call.
func getSilenceById(silenceId string, baseUrl url.URL) (*types.Silence, error) {
	baseUrl.Path = path.Join(baseUrl.Path, silenceId)
	res, err := http.Get(baseUrl.String())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, fmt.Errorf("couldn't read response body: %v", err)
	}

	if res.StatusCode == 404 {
		return nil, fmt.Errorf("no silence found with id: %v", silenceId)
	}
	if res.StatusCode != 200 {
		return nil, fmt.Errorf("received %d response from Alertmanager: %v", res.StatusCode, body)
	}

	var response getResponse
	err = json.Unmarshal(body, &response)
	return &response.Data, nil
}

func updateSilence(silence *types.Silence) (*types.Silence, error) {
	if *updateExpires != 0 {
		silence.EndsAt = time.Now().UTC().Add(*updateExpires)
	}

	// expire-on will override expires value if both are specified
	if !(*updateExpiresOn).IsZero() {
		silence.EndsAt = *updateExpiresOn
	}

	if *updateComment != "" {
		silence.Comment = *updateComment
	}

	// addSilence can also be used to update an existing silence
	_, err := addSilence(silence)
	if err != nil {
		return nil, err
	}
	return silence, nil
}
<|endoftext|>


<commit_before>package responder

import (
	"github.com/stretchr/goweb"
	"github.com/stretchr/goweb/context"
	"net/http"
)

// The standard API response object
type standardResponse struct {
	S int         `json:"status"`
	D interface{} `json:"data"`
	E []string    `json:"error"`
}

// The standard API response object
type paginatedResponse struct {
	S      int         `json:"status"`
	D      interface{} `json:"data"`
	E      []string    `json:"error"`
	Limit  int         `json:"limit"`
	Offset int         `json:"offset"`
	Count  int         `json:"total_count"`
}

func RespondOK(ctx context.Context) error {
	addResponseHeaders(ctx)
	response := new(standardResponse)
	response.S = http.StatusOK
	response.D = nil
	response.E = nil
	return goweb.API.WriteResponseObject(ctx, http.StatusOK, response)
}

func WriteResponseObject(ctx context.Context, status int, responseObject interface{}) error {
	addResponseHeaders(ctx)
	return goweb.API.WriteResponseObject(ctx, status, responseObject)
}

func RespondWithData(ctx context.Context, data interface{}) error {
	addResponseHeaders(ctx)
	response := new(standardResponse)
	response.S = http.StatusOK
	response.D = data
	response.E = nil
	return goweb.API.WriteResponseObject(ctx, http.StatusOK, response)
}

func RespondWithError(ctx context.Context, status int, err string) error {
	addResponseHeaders(ctx)
	response := new(standardResponse)
	response.S = status
	response.D = nil
	response.E = append(response.E, err)
	return goweb.API.WriteResponseObject(ctx, http.StatusOK, response)
}

func RespondWithPaginatedData(ctx context.Context, data interface{}, limit, offset, count int) error {
	addResponseHeaders(ctx)
	response := new(paginatedResponse)
	response.S = http.StatusOK
	response.D = data
	response.E = nil
	response.Limit = limit
	response.Offset = offset
	response.Count = count

	return goweb.API.WriteResponseObject(ctx, http.StatusOK, response)
}

func addResponseHeaders(ctx context.Context) {
	ctx.HttpResponseWriter().Header().Set("Connection", "close")
	ctx.HttpResponseWriter().Header().Set("Access-Control-Allow-Headers", "Authorization")
	ctx.HttpResponseWriter().Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS")
	ctx.HttpResponseWriter().Header().Set("Access-Control-Allow-Origin", "*")
	ctx.HttpResponseWriter().Header().Set("Content-Type", "application/json")
}
<commit_msg>Explicitly setting JSON codec as only response type.<commit_after>package responder

import (
	"github.com/stretchr/codecs/services"
	"github.com/stretchr/goweb"
	"github.com/stretchr/goweb/context"
	"net/http"
)

// The standard API response object
type standardResponse struct {
	S int         `json:"status"`
	D interface{} `json:"data"`
	E []string    `json:"error"`
}

// The standard API response object
type paginatedResponse struct {
	S      int         `json:"status"`
	D      interface{} `json:"data"`
	E      []string    `json:"error"`
	Limit  int         `json:"limit"`
	Offset int         `json:"offset"`
	Count  int         `json:"total_count"`
}

func RespondOK(ctx context.Context) error {
	addResponseHeaders(ctx)
	response := new(standardResponse)
	response.S = http.StatusOK
	response.D = nil
	response.E = nil
	goweb.API.SetCodecService(getJsonCodec())
	return goweb.API.WriteResponseObject(ctx, http.StatusOK, response)
}

func WriteResponseObject(ctx context.Context, status int, responseObject interface{}) error {
	addResponseHeaders(ctx)
	goweb.API.SetCodecService(getJsonCodec())
	return goweb.API.WriteResponseObject(ctx, status, responseObject)
}

func RespondWithData(ctx context.Context, data interface{}) error {
	addResponseHeaders(ctx)
	response := new(standardResponse)
	response.S = http.StatusOK
	response.D = data
	response.E = nil
	goweb.API.SetCodecService(getJsonCodec())
	return goweb.API.WriteResponseObject(ctx, http.StatusOK, response)
}

func RespondWithError(ctx context.Context, status int, err string) error {
	addResponseHeaders(ctx)
	response := new(standardResponse)
	response.S = status
	response.D = nil
	response.E = append(response.E, err)
	goweb.API.SetCodecService(getJsonCodec())
	return goweb.API.WriteResponseObject(ctx, http.StatusOK, response)
}

func RespondWithPaginatedData(ctx context.Context, data interface{}, limit, offset, count int) error {
	addResponseHeaders(ctx)
	response := new(paginatedResponse)
	response.S = http.StatusOK
	response.D = data
	response.E = nil
	response.Limit = limit
	response.Offset = offset
	response.Count = count
	goweb.API.SetCodecService(getJsonCodec())
	return goweb.API.WriteResponseObject(ctx, http.StatusOK, response)
}

func addResponseHeaders(ctx context.Context) {
	ctx.HttpResponseWriter().Header().Set("Connection", "close")
	ctx.HttpResponseWriter().Header().Set("Access-Control-Allow-Headers", "Authorization")
	ctx.HttpResponseWriter().Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS")
	ctx.HttpResponseWriter().Header().Set("Access-Control-Allow-Origin", "*")
}

func getJsonCodec() services.CodecService {
	codecService := services.NewWebCodecService()
	myCodecService := new(services.WebCodecService)
	codec, _ := codecService.GetCodec("application/json")
	myCodecService.AddCodec(codec)
	return myCodecService
}
<|endoftext|>


<commit_before>package virtualbox

import (
	"fmt"
	"github.com/mitchellh/multistep"
	"github.com/mitchellh/packer/packer"
	"log"
	"strings"
	"time"
	"unicode"
	"unicode/utf8"
)

const KeyLeftShift uint32 = 0xFFE1

type bootCommandTemplateData struct {
	HTTPIP   string
	HTTPPort uint
	Name     string
}

// This step "types" the boot command into the VM over VNC.
//
// Uses:
//   config *config
//   driver Driver
//   http_port int
//   ui     packer.Ui
//   vmName string
//
// Produces:
//   <nothing>
type stepTypeBootCommand struct{}

func (s *stepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction {
	config := state.Get("config").(*config)
	driver := state.Get("driver").(Driver)
	httpPort := state.Get("http_port").(uint)
	ui := state.Get("ui").(packer.Ui)
	vmName := state.Get("vmName").(string)

	tplData := &bootCommandTemplateData{
		"10.0.2.2",
		httpPort,
		config.VMName,
	}

	ui.Say("Typing the boot command...")
	for _, command := range config.BootCommand {
		command, err := config.tpl.Process(command, tplData)
		if err != nil {
			err := fmt.Errorf("Error preparing boot command: %s", err)
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}

		for _, code := range scancodes(command) {
			if code == "wait" {
				time.Sleep(1 * time.Second)
				continue
			}

			if code == "wait5" {
				time.Sleep(5 * time.Second)
				continue
			}

			if code == "wait10" {
				time.Sleep(10 * time.Second)
				continue
			}

			// Since typing is sometimes so slow, we check for an interrupt
			// in between each character.
			if _, ok := state.GetOk(multistep.StateCancelled); ok {
				return multistep.ActionHalt
			}

			if err := driver.VBoxManage("controlvm", vmName, "keyboardputscancode", code); err != nil {
				err := fmt.Errorf("Error sending boot command: %s", err)
				state.Put("error", err)
				ui.Error(err.Error())
				return multistep.ActionHalt
			}
		}
	}

	return multistep.ActionContinue
}

func (*stepTypeBootCommand) Cleanup(multistep.StateBag) {}

func scancodes(message string) []string {
	special := make(map[string][]string)
	special["<bs>"] = []string{"ff", "08"}
	special["<del>"] = []string{"ff", "ff"}
	special["<enter>"] = []string{"1c", "9c"}
	special["<esc>"] = []string{"01", "81"}
	special["<f1>"] = []string{"ff", "be"}
	special["<f2>"] = []string{"ff", "bf"}
	special["<f3>"] = []string{"ff", "c0"}
	special["<f4>"] = []string{"ff", "c1"}
	special["<f5>"] = []string{"ff", "c2"}
	special["<f6>"] = []string{"ff", "c3"}
	special["<f7>"] = []string{"ff", "c4"}
	special["<f8>"] = []string{"ff", "c5"}
	special["<f9>"] = []string{"ff", "c6"}
	special["<f10>"] = []string{"ff", "c7"}
	special["<f11>"] = []string{"ff", "c8"}
	special["<f12>"] = []string{"ff", "c9"}
	special["<return>"] = []string{"1c", "9c"}
	special["<tab>"] = []string{"0f", "8f"}

	shiftedChars := "~!@#$%^&*()_+{}|:\"<>?"

	// Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
	scancodeIndex := make(map[string]uint)
	scancodeIndex["1234567890-="] = 0x02
	scancodeIndex["!@#$%^&*()_+"] = 0x02
	scancodeIndex["qwertyuiop[]"] = 0x10
	scancodeIndex["QWERTYUIOP{}"] = 0x10
	scancodeIndex["asdfghjkl;'`"] = 0x1e
	scancodeIndex[`ASDFGHJKL:"~`] = 0x1e
	scancodeIndex[`\zxcvbnm,./`] = 0x2b
	scancodeIndex["|ZXCVBNM<>?"] = 0x2b
	scancodeIndex[" "] = 0x39

	scancodeMap := make(map[rune]uint)
	for chars, start := range scancodeIndex {
		var i uint = 0
		for len(chars) > 0 {
			r, size := utf8.DecodeRuneInString(chars)
			chars = chars[size:]
			scancodeMap[r] = start + i
			i += 1
		}
	}

	result := make([]string, 0, len(message)*2)
	for len(message) > 0 {
		var scancode []string

		if strings.HasPrefix(message, "<wait>") {
			log.Printf("Special code <wait> found, will sleep 1 second at this point.")
			scancode = []string{"wait"}
			message = message[len("<wait>"):]
		}

		if strings.HasPrefix(message, "<wait5>") {
			log.Printf("Special code <wait5> found, will sleep 5 seconds at this point.")
			scancode = []string{"wait5"}
			message = message[len("<wait5>"):]
		}

		if strings.HasPrefix(message, "<wait10>") {
			log.Printf("Special code <wait10> found, will sleep 10 seconds at this point.")
			scancode = []string{"wait10"}
			message = message[len("<wait10>"):]
		}

		if scancode == nil {
			for specialCode, specialValue := range special {
				if strings.HasPrefix(message, specialCode) {
					log.Printf("Special code '%s' found, replacing with: %s", specialCode, specialValue)
					scancode = specialValue
					message = message[len(specialCode):]
					break
				}
			}
		}

		if scancode == nil {
			r, size := utf8.DecodeRuneInString(message)
			message = message[size:]
			scancodeInt := scancodeMap[r]
			keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r)

			scancode = make([]string, 0, 4)
			if keyShift {
				scancode = append(scancode, "2a")
			}

			scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt))

			if keyShift {
				scancode = append(scancode, "aa")
			}

			scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt+0x80))
			log.Printf("Sending char '%c', code '%v', shift %v", r, scancode, keyShift)
		}

		result = append(result, scancode...)
	}

	return result
}
<commit_msg>Fix VirtualBox scancodes<commit_after>package virtualbox

import (
	"fmt"
	"github.com/mitchellh/multistep"
	"github.com/mitchellh/packer/packer"
	"log"
	"strings"
	"time"
	"unicode"
	"unicode/utf8"
)

const KeyLeftShift uint32 = 0xFFE1

type bootCommandTemplateData struct {
	HTTPIP   string
	HTTPPort uint
	Name     string
}

// This step "types" the boot command into the VM over VNC.
//
// Uses:
//   config *config
//   driver Driver
//   http_port int
//   ui     packer.Ui
//   vmName string
//
// Produces:
//   <nothing>
type stepTypeBootCommand struct{}

func (s *stepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction {
	config := state.Get("config").(*config)
	driver := state.Get("driver").(Driver)
	httpPort := state.Get("http_port").(uint)
	ui := state.Get("ui").(packer.Ui)
	vmName := state.Get("vmName").(string)

	tplData := &bootCommandTemplateData{
		"10.0.2.2",
		httpPort,
		config.VMName,
	}

	ui.Say("Typing the boot command...")
	for _, command := range config.BootCommand {
		command, err := config.tpl.Process(command, tplData)
		if err != nil {
			err := fmt.Errorf("Error preparing boot command: %s", err)
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}

		for _, code := range scancodes(command) {
			if code == "wait" {
				time.Sleep(1 * time.Second)
				continue
			}

			if code == "wait5" {
				time.Sleep(5 * time.Second)
				continue
			}

			if code == "wait10" {
				time.Sleep(10 * time.Second)
				continue
			}

			// Since typing is sometimes so slow, we check for an interrupt
			// in between each character.
			if _, ok := state.GetOk(multistep.StateCancelled); ok {
				return multistep.ActionHalt
			}

			if err := driver.VBoxManage("controlvm", vmName, "keyboardputscancode", code); err != nil {
				err := fmt.Errorf("Error sending boot command: %s", err)
				state.Put("error", err)
				ui.Error(err.Error())
				return multistep.ActionHalt
			}
		}
	}

	return multistep.ActionContinue
}

func (*stepTypeBootCommand) Cleanup(multistep.StateBag) {}

func scancodes(message string) []string {
	// Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
  //
  // Scancodes represent raw keyboard output and are fed to the VM by the
  // VBoxManage controlvm keyboardputscancode program.
  //
  // Scancodes are recorded here in pairs. The first entry represents
  // the key press and the second entry represents the key release and is
  // derived from the first by the addition of 0x81.
	special := make(map[string][]string)
	special["<bs>"] = []string{"0e", "8e"}
	special["<del>"] = []string{"53", "d3"}
	special["<enter>"] = []string{"1c", "9c"}
	special["<esc>"] = []string{"01", "81"}
	special["<f1>"] = []string{"3b", "bb"}
	special["<f2>"] = []string{"3c", "bc"}
	special["<f3>"] = []string{"3d", "bd"}
	special["<f4>"] = []string{"3e", "be"}
	special["<f5>"] = []string{"3f", "bf"}
	special["<f6>"] = []string{"40", "c0"}
	special["<f7>"] = []string{"41", "c1"}
	special["<f8>"] = []string{"42", "c2"}
	special["<f9>"] = []string{"43", "c3"}
	special["<f10>"] = []string{"44", "c4"}
	special["<return>"] = []string{"1c", "9c"}
	special["<tab>"] = []string{"0f", "8f"}

	shiftedChars := "~!@#$%^&*()_+{}|:\"<>?"

	scancodeIndex := make(map[string]uint)
	scancodeIndex["1234567890-="] = 0x02
	scancodeIndex["!@#$%^&*()_+"] = 0x02
	scancodeIndex["qwertyuiop[]"] = 0x10
	scancodeIndex["QWERTYUIOP{}"] = 0x10
	scancodeIndex["asdfghjkl;'`"] = 0x1e
	scancodeIndex[`ASDFGHJKL:"~`] = 0x1e
	scancodeIndex[`\zxcvbnm,./`] = 0x2b
	scancodeIndex["|ZXCVBNM<>?"] = 0x2b
	scancodeIndex[" "] = 0x39

	scancodeMap := make(map[rune]uint)
	for chars, start := range scancodeIndex {
		var i uint = 0
		for len(chars) > 0 {
			r, size := utf8.DecodeRuneInString(chars)
			chars = chars[size:]
			scancodeMap[r] = start + i
			i += 1
		}
	}

	result := make([]string, 0, len(message)*2)
	for len(message) > 0 {
		var scancode []string

		if strings.HasPrefix(message, "<wait>") {
			log.Printf("Special code <wait> found, will sleep 1 second at this point.")
			scancode = []string{"wait"}
			message = message[len("<wait>"):]
		}

		if strings.HasPrefix(message, "<wait5>") {
			log.Printf("Special code <wait5> found, will sleep 5 seconds at this point.")
			scancode = []string{"wait5"}
			message = message[len("<wait5>"):]
		}

		if strings.HasPrefix(message, "<wait10>") {
			log.Printf("Special code <wait10> found, will sleep 10 seconds at this point.")
			scancode = []string{"wait10"}
			message = message[len("<wait10>"):]
		}

		if scancode == nil {
			for specialCode, specialValue := range special {
				if strings.HasPrefix(message, specialCode) {
					log.Printf("Special code '%s' found, replacing with: %s", specialCode, specialValue)
					scancode = specialValue
					message = message[len(specialCode):]
					break
				}
			}
		}

		if scancode == nil {
			r, size := utf8.DecodeRuneInString(message)
			message = message[size:]
			scancodeInt := scancodeMap[r]
			keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r)

			scancode = make([]string, 0, 4)
			if keyShift {
				scancode = append(scancode, "2a")
			}

			scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt))

			if keyShift {
				scancode = append(scancode, "aa")
			}

			scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt+0x80))
			log.Printf("Sending char '%c', code '%v', shift %v", r, scancode, keyShift)
		}

		result = append(result, scancode...)
	}

	return result
}
<|endoftext|>


<commit_before>package httpcaddyfile

import (
	"reflect"
	"sort"
	"testing"
)

func TestHostsFromKeys(t *testing.T) {
	for i, tc := range []struct {
		keys             []Address
		expectNormalMode []string
		expectLoggerMode []string
	}{
		{
			[]Address{
				Address{Original: "foo", Host: "foo"},
			},
			[]string{"foo"},
			[]string{"foo"},
		},
		{
			[]Address{
				Address{Original: "foo", Host: "foo"},
				Address{Original: "bar", Host: "bar"},
			},
			[]string{"bar", "foo"},
			[]string{"bar", "foo"},
		},
		{
			[]Address{
				Address{Original: ":2015", Port: "2015"},
			},
			[]string{}, []string{},
		},
		{
			[]Address{
				Address{Original: ":443", Port: "443"},
			},
			[]string{}, []string{},
		},
		{
			[]Address{
				Address{Original: "foo", Host: "foo"},
				Address{Original: ":2015", Port: "2015"},
			},
			[]string{}, []string{"foo"},
		},
		{
			[]Address{
				Address{Original: "example.com:2015", Host: "example.com", Port: "2015"},
			},
			[]string{"example.com"},
			[]string{"example.com:2015"},
		},
		{
			[]Address{
				Address{Original: "example.com:80", Host: "example.com", Port: "80"},
			},
			[]string{"example.com"},
			[]string{"example.com"},
		},
		{
			[]Address{
				Address{Original: "https://:2015/foo", Scheme: "https", Port: "2015", Path: "/foo"},
			},
			[]string{},
			[]string{},
		},
		{
			[]Address{
				Address{Original: "https://example.com:2015/foo", Scheme: "https", Host: "example.com", Port: "2015", Path: "/foo"},
			},
			[]string{"example.com"},
			[]string{"example.com:2015"},
		},
	} {
		sb := serverBlock{keys: tc.keys}

		// test in normal mode
		actual := sb.hostsFromKeys(false)
		sort.Strings(actual)
		if !reflect.DeepEqual(tc.expectNormalMode, actual) {
			t.Errorf("Test %d (loggerMode=false): Expected: %v Actual: %v", i, tc.expectNormalMode, actual)
		}

		// test in logger mode
		actual = sb.hostsFromKeys(true)
		sort.Strings(actual)
		if !reflect.DeepEqual(tc.expectLoggerMode, actual) {
			t.Errorf("Test %d (loggerMode=true): Expected: %v Actual: %v", i, tc.expectLoggerMode, actual)
		}
	}
}
<commit_msg>tests: Clean up redundant type declarations<commit_after>package httpcaddyfile

import (
	"reflect"
	"sort"
	"testing"
)

func TestHostsFromKeys(t *testing.T) {
	for i, tc := range []struct {
		keys             []Address
		expectNormalMode []string
		expectLoggerMode []string
	}{
		{
			[]Address{
				{Original: "foo", Host: "foo"},
			},
			[]string{"foo"},
			[]string{"foo"},
		},
		{
			[]Address{
				{Original: "foo", Host: "foo"},
				{Original: "bar", Host: "bar"},
			},
			[]string{"bar", "foo"},
			[]string{"bar", "foo"},
		},
		{
			[]Address{
				{Original: ":2015", Port: "2015"},
			},
			[]string{}, []string{},
		},
		{
			[]Address{
				{Original: ":443", Port: "443"},
			},
			[]string{}, []string{},
		},
		{
			[]Address{
				{Original: "foo", Host: "foo"},
				{Original: ":2015", Port: "2015"},
			},
			[]string{}, []string{"foo"},
		},
		{
			[]Address{
				{Original: "example.com:2015", Host: "example.com", Port: "2015"},
			},
			[]string{"example.com"},
			[]string{"example.com:2015"},
		},
		{
			[]Address{
				{Original: "example.com:80", Host: "example.com", Port: "80"},
			},
			[]string{"example.com"},
			[]string{"example.com"},
		},
		{
			[]Address{
				{Original: "https://:2015/foo", Scheme: "https", Port: "2015", Path: "/foo"},
			},
			[]string{},
			[]string{},
		},
		{
			[]Address{
				{Original: "https://example.com:2015/foo", Scheme: "https", Host: "example.com", Port: "2015", Path: "/foo"},
			},
			[]string{"example.com"},
			[]string{"example.com:2015"},
		},
	} {
		sb := serverBlock{keys: tc.keys}

		// test in normal mode
		actual := sb.hostsFromKeys(false)
		sort.Strings(actual)
		if !reflect.DeepEqual(tc.expectNormalMode, actual) {
			t.Errorf("Test %d (loggerMode=false): Expected: %v Actual: %v", i, tc.expectNormalMode, actual)
		}

		// test in logger mode
		actual = sb.hostsFromKeys(true)
		sort.Strings(actual)
		if !reflect.DeepEqual(tc.expectLoggerMode, actual) {
			t.Errorf("Test %d (loggerMode=true): Expected: %v Actual: %v", i, tc.expectLoggerMode, actual)
		}
	}
}
<|endoftext|>