<commit_before>package rule

import (
	"context"
	"github.com/goharbor/harbor/src/controller/immutable"
	"github.com/goharbor/harbor/src/lib/q"
	iselector "github.com/goharbor/harbor/src/lib/selector"
	"github.com/goharbor/harbor/src/lib/selector/selectors/index"
	"github.com/goharbor/harbor/src/pkg/immutable/match"
	"github.com/goharbor/harbor/src/pkg/immutable/model"
)

// Matcher ...
type Matcher struct {
	rules []*model.Metadata
}

// Match ...
func (rm *Matcher) Match(ctx context.Context, pid int64, c iselector.Candidate) (bool, error) {
	if err := rm.getImmutableRules(ctx, pid); err != nil {
		return false, err
	}

	cands := []*iselector.Candidate{&c}
	for _, r := range rm.rules {
		if r.Disabled {
			continue
		}

		// match repositories according to the repository selectors
		var repositoryCandidates []*iselector.Candidate
		repositorySelectors := r.ScopeSelectors["repository"]
		if len(repositorySelectors) < 1 {
			continue
		}
		repositorySelector := repositorySelectors[0]
		selector, err := index.Get(repositorySelector.Kind, repositorySelector.Decoration,
			repositorySelector.Pattern, "")
		if err != nil {
			return false, err
		}
		repositoryCandidates, err = selector.Select(cands)
		if err != nil {
			return false, err
		}
		if len(repositoryCandidates) == 0 {
			continue
		}

		// match tag according to the tag selectors
		var tagCandidates []*iselector.Candidate
		tagSelectors := r.TagSelectors
		if len(tagSelectors) < 0 {
			continue
		}
		tagSelector := r.TagSelectors[0]
		selector, err = index.Get(tagSelector.Kind, tagSelector.Decoration,
			tagSelector.Pattern, "")
		if err != nil {
			return false, err
		}
		tagCandidates, err = selector.Select(cands)
		if err != nil {
			return false, err
		}
		if len(tagCandidates) == 0 {
			continue
		}

		return true, nil
	}
	return false, nil
}

func (rm *Matcher) getImmutableRules(ctx context.Context, pid int64) error {
	rules, err := immutable.Ctr.ListImmutableRules(ctx, q.New(q.KeyWords{"ProjectID": pid}))
	if err != nil {
		return err
	}
	rm.rules = rules
	return nil
}

// NewRuleMatcher ...
func NewRuleMatcher() match.ImmutableTagMatcher {
	return &Matcher{}
}
<commit_msg>fixes immutable rule issue (#14849)<commit_after>package rule

import (
	"context"
	"github.com/goharbor/harbor/src/controller/immutable"
	"github.com/goharbor/harbor/src/lib/q"
	iselector "github.com/goharbor/harbor/src/lib/selector"
	"github.com/goharbor/harbor/src/lib/selector/selectors/index"
	"github.com/goharbor/harbor/src/pkg/immutable/match"
	"github.com/goharbor/harbor/src/pkg/immutable/model"
)

// Matcher ...
type Matcher struct {
	rules []*model.Metadata
}

// Match ...
func (rm *Matcher) Match(ctx context.Context, pid int64, c iselector.Candidate) (bool, error) {
	if err := rm.getImmutableRules(ctx, pid); err != nil {
		return false, err
	}

	cands := []*iselector.Candidate{&c}
	for _, r := range rm.rules {
		if r.Disabled {
			continue
		}

		// match repositories according to the repository selectors
		var repositoryCandidates []*iselector.Candidate
		repositorySelectors := r.ScopeSelectors["repository"]
		if len(repositorySelectors) < 1 {
			continue
		}
		repositorySelector := repositorySelectors[0]
		selector, err := index.Get(repositorySelector.Kind, repositorySelector.Decoration,
			repositorySelector.Pattern, "")
		if err != nil {
			return false, err
		}
		repositoryCandidates, err = selector.Select(cands)
		if err != nil {
			return false, err
		}
		if len(repositoryCandidates) == 0 {
			continue
		}

		// match tag according to the tag selectors
		var tagCandidates []*iselector.Candidate
		tagSelectors := r.TagSelectors
		if len(tagSelectors) < 1 {
			continue
		}
		tagSelector := r.TagSelectors[0]
		selector, err = index.Get(tagSelector.Kind, tagSelector.Decoration,
			tagSelector.Pattern, "")
		if err != nil {
			return false, err
		}
		tagCandidates, err = selector.Select(cands)
		if err != nil {
			return false, err
		}
		if len(tagCandidates) == 0 {
			continue
		}

		return true, nil
	}
	return false, nil
}

func (rm *Matcher) getImmutableRules(ctx context.Context, pid int64) error {
	rules, err := immutable.Ctr.ListImmutableRules(ctx, q.New(q.KeyWords{"ProjectID": pid}))
	if err != nil {
		return err
	}
	rm.rules = rules
	return nil
}

// NewRuleMatcher ...
func NewRuleMatcher() match.ImmutableTagMatcher {
	return &Matcher{}
}
<|endoftext|>


<commit_before>// Copyright 2016 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 (
	"runtime/internal/sys"
	"unsafe"
)

type sigctxt struct {
	info *siginfo
	ctxt unsafe.Pointer
}

func (c *sigctxt) regs() *mcontext {
	return (*mcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext))
}

func (c *sigctxt) r1() uint64  { return uint64(c.regs().gregs[_REG_G1]) }
func (c *sigctxt) r2() uint64  { return uint64(c.regs().gregs[_REG_G2]) }
func (c *sigctxt) r3() uint64  { return uint64(c.regs().gregs[_REG_G3]) }
func (c *sigctxt) r4() uint64  { return uint64(c.regs().gregs[_REG_G4]) }
func (c *sigctxt) r5() uint64  { return uint64(c.regs().gregs[_REG_G5]) }
func (c *sigctxt) r6() uint64  { return uint64(c.regs().gregs[_REG_G6]) }
func (c *sigctxt) r7() uint64  { return uint64(c.regs().gregs[_REG_G7]) }
func (c *sigctxt) r8() uint64  { return uint64(c.regs().gregs[_REG_O0]) }
func (c *sigctxt) r9() uint64  { return uint64(c.regs().gregs[_REG_O1]) }
func (c *sigctxt) r10() uint64 { return uint64(c.regs().gregs[_REG_O2]) }
func (c *sigctxt) r11() uint64 { return uint64(c.regs().gregs[_REG_O3]) }
func (c *sigctxt) r12() uint64 { return uint64(c.regs().gregs[_REG_O4]) }
func (c *sigctxt) r13() uint64 { return uint64(c.regs().gregs[_REG_O5]) }

func (c *sigctxt) sp() uint64 { return uint64(c.regs().gregs[_REG_O6]) + sys.StackBias }
func (c *sigctxt) lr() uint64 { return uint64(c.regs().gregs[_REG_O7]) }

func (c *sigctxt) r16() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[0])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 0*8)))
}

func (c *sigctxt) r17() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[1])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 1*8)))
}

func (c *sigctxt) r18() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[2])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 2*8)))
}

func (c *sigctxt) r19() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[3])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 3*8)))
}

func (c *sigctxt) r20() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[4])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 4*8)))
}

func (c *sigctxt) r21() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[5])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 5*8)))
}

func (c *sigctxt) r22() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[6])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 6*8)))
}

func (c *sigctxt) r23() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[7])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 7*8)))
}

func (c *sigctxt) r24() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[0])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 8*8)))
}

func (c *sigctxt) r25() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[1])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 9*8)))
}

func (c *sigctxt) r26() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[2])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 10*8)))
}

func (c *sigctxt) r27() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[3])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 11*8)))
}

func (c *sigctxt) r28() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[4])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 12*8)))
}

func (c *sigctxt) r29() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[5])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 13*8)))
}

func (c *sigctxt) fp() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[6] + sys.StackBias)
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 14*8))) + sys.StackBias
}

func (c *sigctxt) r31() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[7])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 15*8)))
}

func (c *sigctxt) pc() uint64     { return uint64(c.regs().gregs[_REG_PC]) }
func (c *sigctxt) tstate() uint64 { return uint64(c.regs().gregs[_REG_CCR]) }

func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
func (c *sigctxt) fault() uint64   { return *(*uint64)(unsafe.Pointer(&c.info.__data[0])) }

func (c *sigctxt) set_r3(x uint64) { c.regs().gregs[_REG_G3] = int64(x) }

func (c *sigctxt) set_pc(x uint64) { c.regs().gregs[_REG_PC] = int64(x) }
func (c *sigctxt) set_sp(x uint64) { c.regs().gregs[_REG_O6] = int64(x - sys.StackBias) }
func (c *sigctxt) set_lr(x uint64) { c.regs().gregs[_REG_O7] = int64(x) }

func (c *sigctxt) set_fp(x uint64) {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		c.regs().gwins.wbuf[cwp].in[6] = int64(x-sys.StackBias)
	}
	*(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 14*8))) = x - sys.StackBias
}

func (c *sigctxt) set_r31(x uint64) {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		c.regs().gwins.wbuf[cwp].in[7] = int64(x)
	}
	*(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 15*8))) = x
}

func (c *sigctxt) set_sigcode(x uint64) { c.info.si_code = int32(x) }
func (c *sigctxt) set_sigaddr(x uint64) {
	*(*uintptr)(unsafe.Pointer(&c.info.__data[0])) = uintptr(x)
}
<commit_msg>runtime: add npc getters/setters<commit_after>// Copyright 2016 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 (
	"runtime/internal/sys"
	"unsafe"
)

type sigctxt struct {
	info *siginfo
	ctxt unsafe.Pointer
}

func (c *sigctxt) regs() *mcontext {
	return (*mcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext))
}

func (c *sigctxt) r1() uint64  { return uint64(c.regs().gregs[_REG_G1]) }
func (c *sigctxt) r2() uint64  { return uint64(c.regs().gregs[_REG_G2]) }
func (c *sigctxt) r3() uint64  { return uint64(c.regs().gregs[_REG_G3]) }
func (c *sigctxt) r4() uint64  { return uint64(c.regs().gregs[_REG_G4]) }
func (c *sigctxt) r5() uint64  { return uint64(c.regs().gregs[_REG_G5]) }
func (c *sigctxt) r6() uint64  { return uint64(c.regs().gregs[_REG_G6]) }
func (c *sigctxt) r7() uint64  { return uint64(c.regs().gregs[_REG_G7]) }
func (c *sigctxt) r8() uint64  { return uint64(c.regs().gregs[_REG_O0]) }
func (c *sigctxt) r9() uint64  { return uint64(c.regs().gregs[_REG_O1]) }
func (c *sigctxt) r10() uint64 { return uint64(c.regs().gregs[_REG_O2]) }
func (c *sigctxt) r11() uint64 { return uint64(c.regs().gregs[_REG_O3]) }
func (c *sigctxt) r12() uint64 { return uint64(c.regs().gregs[_REG_O4]) }
func (c *sigctxt) r13() uint64 { return uint64(c.regs().gregs[_REG_O5]) }

func (c *sigctxt) sp() uint64 { return uint64(c.regs().gregs[_REG_O6]) + sys.StackBias }
func (c *sigctxt) lr() uint64 { return uint64(c.regs().gregs[_REG_O7]) }

func (c *sigctxt) r16() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[0])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 0*8)))
}

func (c *sigctxt) r17() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[1])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 1*8)))
}

func (c *sigctxt) r18() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[2])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 2*8)))
}

func (c *sigctxt) r19() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[3])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 3*8)))
}

func (c *sigctxt) r20() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[4])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 4*8)))
}

func (c *sigctxt) r21() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[5])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 5*8)))
}

func (c *sigctxt) r22() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[6])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 6*8)))
}

func (c *sigctxt) r23() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].local[7])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 7*8)))
}

func (c *sigctxt) r24() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[0])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 8*8)))
}

func (c *sigctxt) r25() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[1])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 9*8)))
}

func (c *sigctxt) r26() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[2])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 10*8)))
}

func (c *sigctxt) r27() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[3])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 11*8)))
}

func (c *sigctxt) r28() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[4])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 12*8)))
}

func (c *sigctxt) r29() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[5])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 13*8)))
}

func (c *sigctxt) fp() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[6] + sys.StackBias)
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 14*8))) + sys.StackBias
}

func (c *sigctxt) r31() uint64 {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		return uint64(c.regs().gwins.wbuf[cwp].in[7])
	}
	return *(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 15*8)))
}

func (c *sigctxt) pc() uint64     { return uint64(c.regs().gregs[_REG_PC]) }
func (c *sigctxt) npc() uint64     { return uint64(c.regs().gregs[_REG_nPC]) }
func (c *sigctxt) tstate() uint64 { return uint64(c.regs().gregs[_REG_CCR]) }

func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
func (c *sigctxt) fault() uint64   { return *(*uint64)(unsafe.Pointer(&c.info.__data[0])) }

func (c *sigctxt) set_r3(x uint64) { c.regs().gregs[_REG_G3] = int64(x) }

func (c *sigctxt) set_pc(x uint64) { c.regs().gregs[_REG_PC] = int64(x) }
func (c *sigctxt) set_npc(x uint64) { c.regs().gregs[_REG_nPC] = int64(x) }
func (c *sigctxt) set_sp(x uint64) { c.regs().gregs[_REG_O6] = int64(x - sys.StackBias) }
func (c *sigctxt) set_lr(x uint64) { c.regs().gregs[_REG_O7] = int64(x) }

func (c *sigctxt) set_fp(x uint64) {
	if c.regs().gwins != nil {
		cwp := int(c.regs().gregs[_REG_CCR] & 0x1f)
		c.regs().gwins.wbuf[cwp].in[6] = int64(x-sys.StackBias)
	}
	*(*uint64)(unsafe.Pointer((uintptr)(c.regs().gregs[_REG_O6] + sys.StackBias + 14*8))) = x - sys.StackBias
}

func (c *sigctxt) set_sigcode(x uint64) { c.info.si_code = int32(x) }
func (c *sigctxt) set_sigaddr(x uint64) {
	*(*uintptr)(unsafe.Pointer(&c.info.__data[0])) = uintptr(x)
}
<|endoftext|>


<commit_before>package steps

import (
	"errors"
	"fmt"
	"log"
	"time"

	deployapi "github.com/openshift/origin/pkg/deploy/api"
	deployutil "github.com/openshift/origin/pkg/deploy/util"

	kapi "k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"

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

// registers all deployment related steps
func init() {
	RegisterSteps(func(c *Context) {

		c.Then(`^I should not have a deploymentconfig "(.+?)"$`, func(dcName string) {
			found, err := c.DeploymentConfigExists(dcName)
			if err != nil {
				c.Fail("Failed to check for Deployment Config '%s' existance: %v", dcName, err)
				return
			}

			if found {
				c.Fail("Deployment Config %s should not exists", dcName)
				return
			}
		})

		c.Then(`^I should have a deploymentconfig "(.+?)"$`, func(dcName string) {
			dc, err := c.GetDeploymentConfig(dcName)
			if err != nil {
				c.Fail("Failed to get Deployment Config '%s': %v", dcName, err)
				return
			}

			assert.Equal(c.T, dcName, dc.Name)
		})

		c.Given(`^I have a deploymentconfig "(.+?)"$`, func(dcName string) {
			dc, err := c.GetDeploymentConfig(dcName)
			if err != nil {
				c.Fail("Failed to get Deployment Config '%s': %v", dcName, err)
				return
			}

			assert.Equal(c.T, dcName, dc.Name)
		})

		c.When(`^the deploymentconfig "(.+?)" has at least (\d+) deployments?$`, func(dcName string, requiredDeployments int) {
			dc, err := c.GetDeploymentConfig(dcName)
			if err != nil {
				c.Fail("Failed to get Deployment Config '%s': %v", dcName, err)
				return
			}

			if !(dc.LatestVersion >= requiredDeployments) {
				log.Printf("DC latest version is %d. TODO => trigger a new deployment", dc.LatestVersion)
			}
		})

		c.Then(`^the latest deployment of "(.+?)" should succeed in less than "(.+?)"$`, func(dcName string, timeout string) {
			timeoutDuration, err := time.ParseDuration(timeout)
			if err != nil {
				c.Fail("Failed to parse duration '%s': %v", timeout, err)
				return
			}

			dc, err := c.GetDeploymentConfig(dcName)
			if err != nil {
				c.Fail("Failed to get Deployment Config '%s': %v", dcName, err)
				return
			}

			latestDeploymentName := fmt.Sprintf("%s-%d", dc.Name, dc.LatestVersion)

			success, err := c.IsDeploymentComplete(latestDeploymentName, timeoutDuration)
			if err != nil {
				c.Fail("Failed to check status of the deployment '%s': %v", latestDeploymentName, err)
				return
			}

			if !success {
				c.Fail("Deployment '%s' was not successful!", latestDeploymentName)
				return
			}
		})

		c.When(`^I have a successful deployment of "(.+?)"$`, func(dcName string) {
			rcList, err := c.GetReplicationControllers(deployutil.ConfigSelector(dcName))
			if err != nil {
				c.Fail("Failed to get Deployment Config '%s': %v", dcName, err)
				return
			}

			var successfulDeployment bool
			for _, rc := range rcList.Items {
				if status, ok := rc.Annotations[deployapi.DeploymentStatusAnnotation]; ok {
					switch status {
					case string(deployapi.DeploymentStatusComplete):
						successfulDeployment = true
					default:
					}
				}
			}

			if !successfulDeployment {
				c.Fail("No successful deployment for '%s'", dcName)
				return
			}
		})

		c.When(`^I delete the deploymentconfig "(.+?)"$`, func(dcName string) {
			if err := c.DeleteDeploymentConfig(dcName); err != nil {
				c.Fail("Failed to delete deployment config %s", dcName)
			}
		})

	})
}

// DeploymentConfigExists checks if a DeploymentConfig with the given name exists.
func (c *Context) DeploymentConfigExists(dcName string) (bool, error) {
	client, _, err := c.Clients()
	if err != nil {
		return false, err
	}

	namespace, err := c.Namespace()
	if err != nil {
		return false, err
	}

	dcList, err := client.DeploymentConfigs(namespace).List(labels.Everything(), fields.Everything())
	if err != nil {
		return false, err
	}

	for _, dc := range dcList.Items {
		if dc.Name == dcName {
			return true, nil
		}
	}
	return false, nil
}

// GetDeploymentConfig gets the DeploymentConfig with the given name, or returns an error
func (c *Context) GetDeploymentConfig(dcName string) (*deployapi.DeploymentConfig, error) {
	client, _, err := c.Clients()
	if err != nil {
		return nil, err
	}

	namespace, err := c.Namespace()
	if err != nil {
		return nil, err
	}

	dc, err := client.DeploymentConfigs(namespace).Get(dcName)
	if err != nil {
		return nil, err
	}

	return dc, nil
}

// GetReplicationControllers gets a ReplicationControllerList from the given label selector, or returns an error
func (c *Context) GetReplicationControllers(labelSelector labels.Selector) (*kapi.ReplicationControllerList, error) {
	_, kclient, err := c.Clients()
	if err != nil {
		return nil, err
	}

	namespace, err := c.Namespace()
	if err != nil {
		return nil, err
	}

	rcList, err := kclient.ReplicationControllers(namespace).List(labelSelector)
	if err != nil {
		return nil, err
	}

	return rcList, nil
}

// DeleteDeploymentConfig deletes the DeploymentConfig with the given name, or returns an error
func (c *Context) DeleteDeploymentConfig(dcName string) error {
	client, _, err := c.Clients()
	if err != nil {
		return err
	}

	namespace, err := c.Namespace()
	if err != nil {
		return err
	}

	if err = client.DeploymentConfigs(namespace).Delete(dcName); err != nil {
		return err
	}

	return nil
}

// IsDeploymentComplete checks if the deployment with the given name is complete.
//
// If the deployment is still running, it will wait for the given timeout duration.
//
// It returns true if the deployment completed, or false if it failed.
func (c *Context) IsDeploymentComplete(deploymentName string, timeout time.Duration) (bool, error) {
	_, kclient, err := c.Clients()
	if err != nil {
		return false, err
	}

	namespace, err := c.Namespace()
	if err != nil {
		return false, err
	}

	startTime := time.Now()

	// TODO use Watch instead of manually polling
	for time.Now().Sub(startTime) < timeout {
		var rc *kapi.ReplicationController

		err = c.ExecWithExponentialBackoff(func() error {
			var err error
			rc, err = kclient.ReplicationControllers(namespace).Get(deploymentName)
			return err
		})
		if err != nil {
			return false, err
		}

		if status, ok := rc.Annotations[deployapi.DeploymentStatusAnnotation]; ok {
			switch status {
			case string(deployapi.DeploymentStatusNew), string(deployapi.DeploymentStatusPending), string(deployapi.DeploymentStatusRunning):
				time.Sleep(5 * time.Second)
			case string(deployapi.DeploymentStatusComplete):
				return true, nil
			case string(deployapi.DeploymentStatusFailed):
				return false, nil
			default:
				return false, errors.New(fmt.Sprintf("Unknown status %v", status))
			}
		}
	}

	return false, nil
}
<commit_msg>fail when the DC does not have the required number of deployments<commit_after>package steps

import (
	"errors"
	"fmt"
	"time"

	deployapi "github.com/openshift/origin/pkg/deploy/api"
	deployutil "github.com/openshift/origin/pkg/deploy/util"

	kapi "k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"

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

// registers all deployment related steps
func init() {
	RegisterSteps(func(c *Context) {

		c.Then(`^I should not have a deploymentconfig "(.+?)"$`, func(dcName string) {
			found, err := c.DeploymentConfigExists(dcName)
			if err != nil {
				c.Fail("Failed to check for Deployment Config '%s' existance: %v", dcName, err)
				return
			}

			if found {
				c.Fail("Deployment Config %s should not exists", dcName)
				return
			}
		})

		c.Then(`^I should have a deploymentconfig "(.+?)"$`, func(dcName string) {
			dc, err := c.GetDeploymentConfig(dcName)
			if err != nil {
				c.Fail("Failed to get Deployment Config '%s': %v", dcName, err)
				return
			}

			assert.Equal(c.T, dcName, dc.Name)
		})

		c.Given(`^I have a deploymentconfig "(.+?)"$`, func(dcName string) {
			dc, err := c.GetDeploymentConfig(dcName)
			if err != nil {
				c.Fail("Failed to get Deployment Config '%s': %v", dcName, err)
				return
			}

			assert.Equal(c.T, dcName, dc.Name)
		})

		c.When(`^the deploymentconfig "(.+?)" has at least (\d+) deployments?$`, func(dcName string, requiredDeployments int) {
			dc, err := c.GetDeploymentConfig(dcName)
			if err != nil {
				c.Fail("Failed to get Deployment Config '%s': %v", dcName, err)
				return
			}

			if dc.LatestVersion < requiredDeployments {
				c.Fail("The Deployment Config '%s' has only %v deployments, instead of the %v deployments required", dcName, dc.LatestVersion, requiredDeployments)
				return
			}
		})

		c.Then(`^the latest deployment of "(.+?)" should succeed in less than "(.+?)"$`, func(dcName string, timeout string) {
			timeoutDuration, err := time.ParseDuration(timeout)
			if err != nil {
				c.Fail("Failed to parse duration '%s': %v", timeout, err)
				return
			}

			dc, err := c.GetDeploymentConfig(dcName)
			if err != nil {
				c.Fail("Failed to get Deployment Config '%s': %v", dcName, err)
				return
			}

			latestDeploymentName := fmt.Sprintf("%s-%d", dc.Name, dc.LatestVersion)

			success, err := c.IsDeploymentComplete(latestDeploymentName, timeoutDuration)
			if err != nil {
				c.Fail("Failed to check status of the deployment '%s': %v", latestDeploymentName, err)
				return
			}

			if !success {
				c.Fail("Deployment '%s' was not successful!", latestDeploymentName)
				return
			}
		})

		c.When(`^I have a successful deployment of "(.+?)"$`, func(dcName string) {
			rcList, err := c.GetReplicationControllers(deployutil.ConfigSelector(dcName))
			if err != nil {
				c.Fail("Failed to get Deployment Config '%s': %v", dcName, err)
				return
			}

			var successfulDeployment bool
			for _, rc := range rcList.Items {
				if status, ok := rc.Annotations[deployapi.DeploymentStatusAnnotation]; ok {
					switch status {
					case string(deployapi.DeploymentStatusComplete):
						successfulDeployment = true
					default:
					}
				}
			}

			if !successfulDeployment {
				c.Fail("No successful deployment for '%s'", dcName)
				return
			}
		})

		c.When(`^I delete the deploymentconfig "(.+?)"$`, func(dcName string) {
			if err := c.DeleteDeploymentConfig(dcName); err != nil {
				c.Fail("Failed to delete deployment config %s", dcName)
			}
		})

	})
}

// DeploymentConfigExists checks if a DeploymentConfig with the given name exists.
func (c *Context) DeploymentConfigExists(dcName string) (bool, error) {
	client, _, err := c.Clients()
	if err != nil {
		return false, err
	}

	namespace, err := c.Namespace()
	if err != nil {
		return false, err
	}

	dcList, err := client.DeploymentConfigs(namespace).List(labels.Everything(), fields.Everything())
	if err != nil {
		return false, err
	}

	for _, dc := range dcList.Items {
		if dc.Name == dcName {
			return true, nil
		}
	}
	return false, nil
}

// GetDeploymentConfig gets the DeploymentConfig with the given name, or returns an error
func (c *Context) GetDeploymentConfig(dcName string) (*deployapi.DeploymentConfig, error) {
	client, _, err := c.Clients()
	if err != nil {
		return nil, err
	}

	namespace, err := c.Namespace()
	if err != nil {
		return nil, err
	}

	dc, err := client.DeploymentConfigs(namespace).Get(dcName)
	if err != nil {
		return nil, err
	}

	return dc, nil
}

// GetReplicationControllers gets a ReplicationControllerList from the given label selector, or returns an error
func (c *Context) GetReplicationControllers(labelSelector labels.Selector) (*kapi.ReplicationControllerList, error) {
	_, kclient, err := c.Clients()
	if err != nil {
		return nil, err
	}

	namespace, err := c.Namespace()
	if err != nil {
		return nil, err
	}

	rcList, err := kclient.ReplicationControllers(namespace).List(labelSelector)
	if err != nil {
		return nil, err
	}

	return rcList, nil
}

// DeleteDeploymentConfig deletes the DeploymentConfig with the given name, or returns an error
func (c *Context) DeleteDeploymentConfig(dcName string) error {
	client, _, err := c.Clients()
	if err != nil {
		return err
	}

	namespace, err := c.Namespace()
	if err != nil {
		return err
	}

	if err = client.DeploymentConfigs(namespace).Delete(dcName); err != nil {
		return err
	}

	return nil
}

// IsDeploymentComplete checks if the deployment with the given name is complete.
//
// If the deployment is still running, it will wait for the given timeout duration.
//
// It returns true if the deployment completed, or false if it failed.
func (c *Context) IsDeploymentComplete(deploymentName string, timeout time.Duration) (bool, error) {
	_, kclient, err := c.Clients()
	if err != nil {
		return false, err
	}

	namespace, err := c.Namespace()
	if err != nil {
		return false, err
	}

	startTime := time.Now()

	// TODO use Watch instead of manually polling
	for time.Now().Sub(startTime) < timeout {
		var rc *kapi.ReplicationController

		err = c.ExecWithExponentialBackoff(func() error {
			var err error
			rc, err = kclient.ReplicationControllers(namespace).Get(deploymentName)
			return err
		})
		if err != nil {
			return false, err
		}

		if status, ok := rc.Annotations[deployapi.DeploymentStatusAnnotation]; ok {
			switch status {
			case string(deployapi.DeploymentStatusNew), string(deployapi.DeploymentStatusPending), string(deployapi.DeploymentStatusRunning):
				time.Sleep(5 * time.Second)
			case string(deployapi.DeploymentStatusComplete):
				return true, nil
			case string(deployapi.DeploymentStatusFailed):
				return false, nil
			default:
				return false, errors.New(fmt.Sprintf("Unknown status %v", status))
			}
		}
	}

	return false, nil
}
<|endoftext|>


<commit_before>package cafs

import (
	"bytes"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"sync"

	"github.com/tchaik/tchaik/store"
)

// Index is an interface which contains methods for implementing
// a content addressable file system.
type Index interface {
	// Get returns the real path for the given filename, with true if and only
	// if the path exists in the index.
	Get(path string) (string, bool)

	// AddContent adds the path to the index, and returns the path to the file
	// and whether the path/content already exists.
	Add(path string, hash string) bool

	// Exists returns true of the hash is in the index.
	Exists(hash string) bool
}

type index struct {
	sync.RWMutex

	files map[string]string // path -> sha1
	index map[string]bool   // {sha1}
	root  string
}

func NewIndex() *index {
	return &index{
		files: make(map[string]string),
		index: make(map[string]bool),
	}
}

func (i *index) MarshalJSON() ([]byte, error) {
	i.RLock()
	defer i.RUnlock()

	exp := struct {
		Files map[string]string
	}{
		Files: i.files,
	}
	return json.Marshal(exp)
}

func (i *index) UnmarshalJSON(b []byte) error {
	i.Lock()
	defer i.Unlock()

	var exp struct {
		Files map[string]string
	}
	err := json.Unmarshal(b, &exp)
	if err != nil {
		return err
	}

	i.files = make(map[string]string)
	i.index = make(map[string]bool)
	for k, v := range exp.Files {
		i.index[v] = true
		i.files[k] = v
	}
	return nil
}

// Get implements Index.
func (i *index) Get(path string) (string, bool) {
	i.RLock()
	defer i.RUnlock()

	x, ok := i.files[path]
	return x, ok
}

// Add implements Index.
func (i *index) Add(path, hash string) bool {
	i.Lock()
	defer i.Unlock()

	i.files[path] = hash
	if !i.index[hash] {
		i.index[hash] = true
		return false
	}
	return true
}

// Exists implements Index.
func (i *index) Exists(hash string) bool {
	i.RLock()
	defer i.RUnlock()

	return i.index[hash]
}

// Add the path+data to the index.
func AddContent(idx Index, path string, content []byte) (string, bool) {
	if x, ok := idx.Get(path); ok {
		return x, true
	}
	s := fmt.Sprintf("%x", sha1.Sum(content))
	return s, idx.Add(path, s)
}

// FileSystem is a type which defines a content addressable filesystem.
type FileSystem struct {
	idx Index

	fs store.RWFileSystem
}

// Open the file with the given path.  Uses the internal index to identify
// which file to open.  NB: Stat on the returned file will refer to the
// internal file.
func (s *FileSystem) Open(path string) (http.File, error) {
	realPath, ok := s.idx.Get(path)
	if !ok {
		return nil, fmt.Errorf("no such file: %v", path)
	}
	return s.open(realPath)
}

// Wait implements RWFileSystem.
func (s *FileSystem) Wait() error { return nil }

func (s *FileSystem) open(path string) (http.File, error) {
	return s.fs.Open(path)
}

func (s *FileSystem) create(path string) (io.WriteCloser, error) {
	return s.fs.Create(path)
}

type file struct {
	bytes.Buffer

	fs   *FileSystem
	path string
}

// Close acts as a signal that all the information has been written to
// the underlying buffer, and the file can be written to the RWFileSystem.
func (a *file) Close() error {
	_, ok := a.fs.idx.Get(a.path)
	if ok {
		return fmt.Errorf("file already exists: %v", a.path)
	}

	path, ok := AddContent(a.fs.idx, a.path, a.Bytes())
	if !ok {
		fmt.Println("creating", path)
		f, err := a.fs.create(path)
		if err != nil {
			return fmt.Errorf("error creating file: %v", err)
		}
		defer f.Close()
		_, err = io.Copy(f, a)
		if err != nil {
			return fmt.Errorf("error copying data into file '%v': %v", path, err)
		}
	}
	err := a.fs.writeIndex()
	if err != nil {
		return err
	}
	return nil
}

// Create a new file with path. We buffer the contents written to the io.WriteCloser
// so that the content can be hashed and then written to the underlying RWFileSystem.
func (s *FileSystem) Create(path string) (io.WriteCloser, error) {
	_, ok := s.idx.Get(path)
	if ok {
		return nil, fmt.Errorf("file already exists for '%v'", path)
	}

	return &file{
		Buffer: bytes.Buffer{},
		path:   path,
		fs:     s,
	}, nil
}

// initIndex initialises the cafs index.
func (s *FileSystem) initIndex() error {
	f, err := s.open(".idx")
	if err != nil {
		// FIXME: Improve this
		// Can't guarantee that we will get an IsNotExist(err) here
		return nil
	}
	defer f.Close()

	b, err := ioutil.ReadAll(f)
	if err != nil {
		return fmt.Errorf("error reading index: %v", err)
	}
	err = json.Unmarshal(b, s.idx)
	if err != nil {
		return fmt.Errorf("error decoding index: %v", err)
	}
	fmt.Printf("Index initialised: %d files (%d paths)", len(s.idx.(*index).index), len(s.idx.(*index).files))
	return nil
}

func (s *FileSystem) writeIndex() error {
	f, err := s.fs.Create(".idx")
	if err != nil {
		return fmt.Errorf("error creating index: %v", err)
	}
	defer f.Close()

	b, err := json.Marshal(s.idx)
	if err != nil {
		return fmt.Errorf("error encoding index: %v", err)
	}

	_, err = f.Write(b)
	if err != nil {
		return fmt.Errorf("error writing index: %v", err)
	}
	return nil
}

// New creates a new content addressable RWFileSystem.
func New(fs store.RWFileSystem) (*FileSystem, error) {
	s := &FileSystem{
		idx: NewIndex(),
		fs:  fs,
	}
	err := s.initIndex()
	if err != nil {
		return nil, err
	}
	return s, nil
}
<commit_msg>Refactor content addressable index writeIndex -> persist.<commit_after>package cafs

import (
	"bytes"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"sync"

	"github.com/tchaik/tchaik/store"
)

// Index is an interface which contains methods for implementing
// a content addressable file system.
type Index interface {
	// Get returns the real path for the given filename, with true if and only
	// if the path exists in the index.
	Get(path string) (string, bool)

	// AddContent adds the path to the index, and returns the path to the file
	// and whether the path/content already exists.
	Add(path string, hash string) bool

	// Exists returns true of the hash is in the index.
	Exists(hash string) bool
}

type index struct {
	sync.RWMutex

	files map[string]string // path -> sha1
	index map[string]bool   // {sha1}
	root  string
}

func NewIndex() *index {
	return &index{
		files: make(map[string]string),
		index: make(map[string]bool),
	}
}

func (i *index) MarshalJSON() ([]byte, error) {
	i.RLock()
	defer i.RUnlock()

	exp := struct {
		Files map[string]string
	}{
		Files: i.files,
	}
	return json.Marshal(exp)
}

func (i *index) UnmarshalJSON(b []byte) error {
	i.Lock()
	defer i.Unlock()

	var exp struct {
		Files map[string]string
	}
	err := json.Unmarshal(b, &exp)
	if err != nil {
		return err
	}

	i.files = make(map[string]string)
	i.index = make(map[string]bool)
	for k, v := range exp.Files {
		i.index[v] = true
		i.files[k] = v
	}
	return nil
}

// Get implements Index.
func (i *index) Get(path string) (string, bool) {
	i.RLock()
	defer i.RUnlock()

	x, ok := i.files[path]
	return x, ok
}

// Add implements Index.
func (i *index) Add(path, hash string) bool {
	i.Lock()
	defer i.Unlock()

	i.files[path] = hash
	if !i.index[hash] {
		i.index[hash] = true
		return false
	}
	return true
}

// Exists implements Index.
func (i *index) Exists(hash string) bool {
	i.RLock()
	defer i.RUnlock()

	return i.index[hash]
}

// Add the path+data to the index.
func AddContent(idx Index, path string, content []byte) (string, bool) {
	if x, ok := idx.Get(path); ok {
		return x, true
	}
	s := fmt.Sprintf("%x", sha1.Sum(content))
	return s, idx.Add(path, s)
}

// FileSystem is a type which defines a content addressable filesystem.
type FileSystem struct {
	idx Index

	fs store.RWFileSystem
}

// Open the file with the given path.  Uses the internal index to identify
// which file to open.  NB: Stat on the returned file will refer to the
// internal file.
func (s *FileSystem) Open(path string) (http.File, error) {
	realPath, ok := s.idx.Get(path)
	if !ok {
		return nil, fmt.Errorf("no such file: %v", path)
	}
	return s.open(realPath)
}

// Wait implements RWFileSystem.
func (s *FileSystem) Wait() error { return nil }

func (s *FileSystem) open(path string) (http.File, error) {
	return s.fs.Open(path)
}

func (s *FileSystem) create(path string) (io.WriteCloser, error) {
	return s.fs.Create(path)
}

type file struct {
	bytes.Buffer

	fs   *FileSystem
	path string
}

// Close acts as a signal that all the information has been written to
// the underlying buffer, and the file can be written to the RWFileSystem.
func (a *file) Close() error {
	_, ok := a.fs.idx.Get(a.path)
	if ok {
		return fmt.Errorf("file already exists: %v", a.path)
	}

	path, ok := AddContent(a.fs.idx, a.path, a.Bytes())
	if !ok {
		fmt.Println("creating", path)
		f, err := a.fs.create(path)
		if err != nil {
			return fmt.Errorf("error creating file: %v", err)
		}
		defer f.Close()
		_, err = io.Copy(f, a)
		if err != nil {
			return fmt.Errorf("error copying data into file '%v': %v", path, err)
		}
	}
	err := a.fs.persist()
	if err != nil {
		return err
	}
	return nil
}

// Create a new file with path. We buffer the contents written to the io.WriteCloser
// so that the content can be hashed and then written to the underlying RWFileSystem.
func (s *FileSystem) Create(path string) (io.WriteCloser, error) {
	_, ok := s.idx.Get(path)
	if ok {
		return nil, fmt.Errorf("file already exists for '%v'", path)
	}

	return &file{
		Buffer: bytes.Buffer{},
		path:   path,
		fs:     s,
	}, nil
}

// initIndex initialises the cafs index.
func (s *FileSystem) initIndex() error {
	f, err := s.open(".idx")
	if err != nil {
		// FIXME: Improve this
		// Can't guarantee that we will get an IsNotExist(err) here
		return nil
	}
	defer f.Close()

	b, err := ioutil.ReadAll(f)
	if err != nil {
		return fmt.Errorf("error reading index: %v", err)
	}
	err = json.Unmarshal(b, s.idx)
	if err != nil {
		return fmt.Errorf("error decoding index: %v", err)
	}
	fmt.Printf("Index initialised: %d files (%d paths)", len(s.idx.(*index).index), len(s.idx.(*index).files))
	return nil
}

func (s *FileSystem) persist() error {
	f, err := s.fs.Create(".idx")
	if err != nil {
		return fmt.Errorf("error creating index: %v", err)
	}
	defer f.Close()

	b, err := json.Marshal(s.idx)
	if err != nil {
		return fmt.Errorf("error encoding index: %v", err)
	}

	_, err = f.Write(b)
	if err != nil {
		return fmt.Errorf("error writing index: %v", err)
	}
	return nil
}

// New creates a new content addressable RWFileSystem.
func New(fs store.RWFileSystem) (*FileSystem, error) {
	s := &FileSystem{
		idx: NewIndex(),
		fs:  fs,
	}
	err := s.initIndex()
	if err != nil {
		return nil, err
	}
	return s, nil
}
<|endoftext|>


<commit_before>package strava

import (
	"log"
	"time"

	stravalib "github.com/svdberg/syncmysport-runkeeper/Godeps/_workspace/src/github.com/strava/go.strava"
	dm "github.com/svdberg/syncmysport-runkeeper/datamodel"
)

func ConvertToActivity(stravaActivity *stravalib.ActivityDetailed, timeStream *stravalib.StreamSet, gpsTrack *stravalib.StreamSet, hrTrack *stravalib.StreamSet, altTrack *stravalib.StreamSet) *dm.Activity {
	stvActivity := dm.CreateActivity()
	stvActivity.StartTime = int(stravaActivity.StartDate.Unix()) //UTC date
	log.Printf("STV Local date: %s, start date: %s, unix: %d", stravaActivity.StartDateLocal, stravaActivity.StartDate, stravaActivity.StartDate.Unix())
	stvActivity.Duration = stravaActivity.ElapsedTime
	stvActivity.Name = stravaActivity.Name
	stvActivity.Calories = stravaActivity.Calories
	stvActivity.Distance = stravaActivity.Distance
	stvActivity.AverageHeartRate = int(stravaActivity.AverageHeartrate)
	loc, err := time.LoadLocation(stravaActivity.TimeZone)
	if err != nil {
		timeInTZ := time.Time(stravaActivity.StartDate).In(loc)
		_, offsetInSeconds := timeInTZ.Zone()
		stvActivity.UtcOffSet = offsetInSeconds / 60 / 60
	} else {
		log.Printf("Warning: reading location from strava Activity failed with: %s", err)
	}

	if stravaActivity.Type.String() == "Run" {
		stvActivity.Type = "Running"
	} else if stravaActivity.Type.String() == "Ride" || stravaActivity.Type.String() == "EBikeRide" || stravaActivity.Type.String() == "VirtualRide" {
		stvActivity.Type = "Cycling"
	} else if stravaActivity.Type.String() == "Swim" {
		stvActivity.Type = "Swimming"
	} else {
		//I don't know, call it Activity
		stvActivity.Type = "Activity"
	}

	if gpsTrack != nil && gpsTrack.Location != nil && timeStream != nil {
		stvActivity.GPS = convertGPSTrack(gpsTrack, timeStream, altTrack)
	}
	if hrTrack != nil && hrTrack.HeartRate != nil && timeStream != nil {
		stvActivity.HeartRate = convertHeartRateTrack(hrTrack, timeStream)
	}
	return stvActivity
}

func convertGPSTrack(sourceStream *stravalib.StreamSet, timeStream *stravalib.StreamSet, elevationStream *stravalib.StreamSet) []dm.GPS {
	//merge the time stream + the location stream
	merged := mergeTimeAndLocation(timeStream.Time, sourceStream.Location, elevationStream.Elevation)

	result := make([]dm.GPS, len(sourceStream.Location.Data))
	for index, gpsTime := range merged {
		alt := 0.0
		result[index] = dm.GPS{float64(gpsTime.Time), alt, gpsTime.Long, gpsTime.Lat}
	}
	return result
}

type GPSTime struct {
	Time int
	Lat  float64
	Long float64
	Alt  float64
}

func mergeTimeAndLocation(timeStream *stravalib.IntegerStream, locStream *stravalib.LocationStream, altStream *stravalib.DecimalStream) []GPSTime {
	merged := make([]GPSTime, len(timeStream.Data))
	for i, t := range timeStream.Data {
		latLong := locStream.Data[i]
		alt := altStream.Data[i]
		merged[i] = GPSTime{t, latLong[0], latLong[1], alt}
	}
	return merged
}

func convertHeartRateTrack(sourceStream *stravalib.StreamSet, timeStream *stravalib.StreamSet) []dm.HeartRate {
	result := make([]dm.HeartRate, len(sourceStream.HeartRate.Data))
	for index, hr := range sourceStream.HeartRate.Data {
		hrTime := timeStream.Time.Data[index]
		result[index] = dm.HeartRate{float64(hrTime), hr}
	}
	return result
}
<commit_msg>Now with actual setting of the value<commit_after>package strava

import (
	"log"
	"time"

	stravalib "github.com/svdberg/syncmysport-runkeeper/Godeps/_workspace/src/github.com/strava/go.strava"
	dm "github.com/svdberg/syncmysport-runkeeper/datamodel"
)

func ConvertToActivity(stravaActivity *stravalib.ActivityDetailed, timeStream *stravalib.StreamSet, gpsTrack *stravalib.StreamSet, hrTrack *stravalib.StreamSet, altTrack *stravalib.StreamSet) *dm.Activity {
	stvActivity := dm.CreateActivity()
	stvActivity.StartTime = int(stravaActivity.StartDate.Unix()) //UTC date
	log.Printf("STV Local date: %s, start date: %s, unix: %d", stravaActivity.StartDateLocal, stravaActivity.StartDate, stravaActivity.StartDate.Unix())
	stvActivity.Duration = stravaActivity.ElapsedTime
	stvActivity.Name = stravaActivity.Name
	stvActivity.Calories = stravaActivity.Calories
	stvActivity.Distance = stravaActivity.Distance
	stvActivity.AverageHeartRate = int(stravaActivity.AverageHeartrate)
	loc, err := time.LoadLocation(stravaActivity.TimeZone)
	if err != nil {
		timeInTZ := time.Time(stravaActivity.StartDate).In(loc)
		_, offsetInSeconds := timeInTZ.Zone()
		stvActivity.UtcOffSet = offsetInSeconds / 60 / 60
	} else {
		log.Printf("Warning: reading location from strava Activity failed with: %s", err)
	}

	if stravaActivity.Type.String() == "Run" {
		stvActivity.Type = "Running"
	} else if stravaActivity.Type.String() == "Ride" || stravaActivity.Type.String() == "EBikeRide" || stravaActivity.Type.String() == "VirtualRide" {
		stvActivity.Type = "Cycling"
	} else if stravaActivity.Type.String() == "Swim" {
		stvActivity.Type = "Swimming"
	} else {
		//I don't know, call it Activity
		stvActivity.Type = "Activity"
	}

	if gpsTrack != nil && gpsTrack.Location != nil && timeStream != nil {
		stvActivity.GPS = convertGPSTrack(gpsTrack, timeStream, altTrack)
	}
	if hrTrack != nil && hrTrack.HeartRate != nil && timeStream != nil {
		stvActivity.HeartRate = convertHeartRateTrack(hrTrack, timeStream)
	}
	return stvActivity
}

func convertGPSTrack(sourceStream *stravalib.StreamSet, timeStream *stravalib.StreamSet, elevationStream *stravalib.StreamSet) []dm.GPS {
	//merge the time stream + the location stream
	merged := mergeTimeAndLocation(timeStream.Time, sourceStream.Location, elevationStream.Elevation)

	result := make([]dm.GPS, len(sourceStream.Location.Data))
	for index, gpsTime := range merged {
		result[index] = dm.GPS{float64(gpsTime.Time), gpsTime.Alt, gpsTime.Long, gpsTime.Lat}
	}
	return result
}

type GPSTime struct {
	Time int
	Lat  float64
	Long float64
	Alt  float64
}

func mergeTimeAndLocation(timeStream *stravalib.IntegerStream, locStream *stravalib.LocationStream, altStream *stravalib.DecimalStream) []GPSTime {
	merged := make([]GPSTime, len(timeStream.Data))
	for i, t := range timeStream.Data {
		latLong := locStream.Data[i]
		alt := altStream.Data[i]
		merged[i] = GPSTime{t, latLong[0], latLong[1], alt}
	}
	return merged
}

func convertHeartRateTrack(sourceStream *stravalib.StreamSet, timeStream *stravalib.StreamSet) []dm.HeartRate {
	result := make([]dm.HeartRate, len(sourceStream.HeartRate.Data))
	for index, hr := range sourceStream.HeartRate.Data {
		hrTime := timeStream.Time.Data[index]
		result[index] = dm.HeartRate{float64(hrTime), hr}
	}
	return result
}
<|endoftext|>


<commit_before>package main

import (
	"log"

	"github.com/upfluence/sensu-client-go/Godeps/_workspace/src/github.com/upfluence/sensu-go/sensu/transport/rabbitmq"
	"github.com/upfluence/sensu-client-go/sensu"
)

func main() {
	cfg, err := sensu.NewConfigFromFlagSet(sensu.ExtractFlags())

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

	t := rabbitmq.NewRabbitMQTransport(cfg.RabbitMQURI())
	client := sensu.NewClient(t, cfg)

	client.Start()
}
<commit_msg>Update demo client<commit_after>package main

import (
	"log"

	"github.com/upfluence/sensu-client-go/Godeps/_workspace/src/github.com/upfluence/sensu-go/sensu/transport/rabbitmq"
	"github.com/upfluence/sensu-client-go/sensu"
)

func main() {
	cfg, err := sensu.NewConfigFromFlagSet(sensu.ExtractFlags())

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

	t, _ := rabbitmq.NewRabbitMQTransport(cfg.RabbitMQURI())
	client := sensu.NewClient(t, cfg)

	client.Start()
}
<|endoftext|>


<commit_before>package aurora

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gorilla/securecookie"
	"github.com/gorilla/sessions"
)

var (
	maxAge  = 30
	sPath   = "/"
	cName   = "youngWarlock"
	sBucket = "sessions"
	secret  = []byte("my-secret")
	testURL = "http://www.example.com"
)

func TestSession_New(t *testing.T) {
	store, req := sessSetup(t)
	testNewSess(store, req, t)
}

func TestSession_Save(t *testing.T) {
	store, req := sessSetup(t)
	testNewSess(store, req, t)
	testSaveSess(store, req, t, "user", "gernest")
}

func TestSess_Get(t *testing.T) {
	opts := &sessions.Options{MaxAge: maxAge, Path: sPath}
	store, req := sessSetup(t)
	s := testSaveSess(store, req, t, "user", "gernest")
	c, err := securecookie.EncodeMulti(s.Name(), s.ID, securecookie.CodecsFromPairs(secret)...)
	if err != nil {
		t.Error(err)
	}
	newCookie := sessions.NewCookie(s.Name(), c, opts)
	req.AddCookie(newCookie)
	s, err = store.New(req, cName)
	if err != nil {
		t.Error(err)
	}
	if s.IsNew {
		t.Errorf("Expected  false, actual %v", s.IsNew)
	}
	ss, err := store.Get(req, cName)
	if err != nil {
		t.Error(err)
	}
	if ss.IsNew {
		t.Errorf("Expected  false, actual %v", ss.IsNew)
	}
	if ss.Values["user"] != "gernest" {
		t.Errorf("Expected gernest, actual %s", ss.Values["user"])
	}
}
func TestSess_Delete(t *testing.T) {
	store, req := sessSetup(t)
	s := testSaveSess(store, req, t, "user", "gernest")
	w := httptest.NewRecorder()
	err := store.Delete(req, w, s)
	if err != nil {
		t.Error(err)
	}
}

func sessSetup(t *testing.T) (*Session, *http.Request) {
	opts := &sessions.Options{MaxAge: maxAge, Path: sPath}
	store := NewSessStore(testDb, sBucket, 10, opts, secret)
	req, err := http.NewRequest("GET", testURL, nil)
	if err != nil {
		t.Error(err)
	}
	return store, req
}

func testNewSess(ss *Session, req *http.Request, t *testing.T) *sessions.Session {
	s, err := ss.New(req, cName)
	if err == nil {
		if !s.IsNew {
			t.Errorf("Expected true actual %v", s.IsNew)
		}
		t.Errorf("Expected \"http: named cookie not present\" actual nil")
	}
	return s
}
func testSaveSess(ss *Session, req *http.Request, t *testing.T, key, val string) *sessions.Session {
	s := testNewSess(ss, req, t)
	s.Values[key] = val
	w := httptest.NewRecorder()
	err := s.Save(req, w)
	if err != nil {
		t.Error(err)
	}
	return s
}
<commit_msg>refactor<commit_after>package aurora

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gorilla/securecookie"
	"github.com/gorilla/sessions"
)

var (
	maxAge  = 30
	sPath   = "/"
	cName   = "youngWarlock"
	sBucket = "sessions"
	secret  = []byte("my-secret")
	testURL = "http://www.example.com"
)

func TestSession_New(t *testing.T) {
	store, req := sessSetup(t)
	testNewSess(store, req, t)
}

func TestSession_Save(t *testing.T) {
	store, req := sessSetup(t)
	testNewSess(store, req, t)
	testSaveSess(store, req, t, "user", "gernest")
}

func TestSess_Get(t *testing.T) {
	opts := &sessions.Options{MaxAge: maxAge, Path: sPath}
	store, req := sessSetup(t)
	s := testSaveSess(store, req, t, "user", "gernest")
	c, err := securecookie.EncodeMulti(s.Name(), s.ID, securecookie.CodecsFromPairs(secret)...)
	if err != nil {
		t.Error(err)
	}
	newCookie := sessions.NewCookie(s.Name(), c, opts)
	req.AddCookie(newCookie)
	s, err = store.New(req, cName)
	if err != nil {
		t.Error(err)
	}
	if s.IsNew {
		t.Errorf("Expected  false, actual %v", s.IsNew)
	}
	ss, err := store.Get(req, cName)
	if err != nil {
		t.Error(err)
	}
	if ss.IsNew {
		t.Errorf("Expected  false, actual %v", ss.IsNew)
	}
	if ss.Values["user"] != "gernest" {
		t.Errorf("Expected gernest, actual %s", ss.Values["user"])
	}
}
func TestSess_Delete(t *testing.T) {
	store, req := sessSetup(t)
	s := testSaveSess(store, req, t, "user", "gernest")
	defer testDb.DeleteDatabase()
	w := httptest.NewRecorder()
	err := store.Delete(req, w, s)
	if err != nil {
		t.Error(err)
	}
}

func sessSetup(t *testing.T) (*Session, *http.Request) {
	opts := &sessions.Options{MaxAge: maxAge, Path: sPath}
	store := NewSessStore(testDb, sBucket, 10, opts, secret)
	req, err := http.NewRequest("GET", testURL, nil)
	if err != nil {
		t.Error(err)
	}
	return store, req
}

func testNewSess(ss *Session, req *http.Request, t *testing.T) *sessions.Session {
	s, err := ss.New(req, cName)
	if err == nil {
		if !s.IsNew {
			t.Errorf("Expected true actual %v", s.IsNew)
		}
		t.Errorf("Expected \"http: named cookie not present\" actual nil")
	}
	return s
}
func testSaveSess(ss *Session, req *http.Request, t *testing.T, key, val string) *sessions.Session {
	s := testNewSess(ss, req, t)
	s.Values[key] = val
	w := httptest.NewRecorder()
	err := s.Save(req, w)
	if err != nil {
		t.Error(err)
	}
	return s
}
<|endoftext|>


<commit_before>package smux

import (
	"fmt"
	"io"
	"log"
	"net"
	"sync"
	"testing"
	"time"
)

func init() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	ln, err := net.Listen("tcp", "127.0.0.1:19999")
	if err != nil {
		// handle error
		panic(err)
	}
	go func() {
		for {
			conn, err := ln.Accept()
			if err != nil {
				// handle error
			}
			go handleConnection(conn)
		}
	}()
}

func handleConnection(conn net.Conn) {
	session, _ := Server(conn, nil)
	for {
		if stream, err := session.AcceptStream(); err == nil {
			go func(s io.ReadWriteCloser) {
				buf := make([]byte, 65536)
				for {
					n, err := s.Read(buf)
					if err != nil {
						return
					}
					s.Write(buf[:n])
				}
			}(stream)
		} else {
			log.Println(err)
			return
		}
	}
}

func TestEcho(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	stream, _ := session.OpenStream()
	const N = 100
	buf := make([]byte, 10)
	var sent string
	var received string
	for i := 0; i < N; i++ {
		msg := fmt.Sprintf("hello%v", i)
		stream.Write([]byte(msg))
		sent += msg
		if n, err := stream.Read(buf); err != nil {
			t.Fatal(err)
		} else {
			received += string(buf[:n])
		}
	}
	if sent != received {
		t.Fatal("data mimatch")
	}
	session.Close()
}

func TestSpeed(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	stream, _ := session.OpenStream()

	start := time.Now()
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		buf := make([]byte, 1024*1024)
		nrecv := 0
		for {
			n, err := stream.Read(buf)
			if err != nil {
				t.Fatal(err)
				break
			} else {
				nrecv += n
				if nrecv == 4096*4096 {
					break
				}
			}
		}
		println("total recv:", nrecv)
		stream.Close()
		fmt.Println("time for 16MB rtt", time.Now().Sub(start))
		wg.Done()
	}()
	msg := make([]byte, 8192)
	for i := 0; i < 2048; i++ {
		stream.Write(msg)
	}
	wg.Wait()
	session.Close()
}

func TestParallel(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)

	par := 1000
	messages := 100
	var wg sync.WaitGroup
	wg.Add(par)
	for i := 0; i < par; i++ {
		stream, _ := session.OpenStream()
		go func(s *Stream) {
			buf := make([]byte, 20)
			for j := 0; j < messages; j++ {
				msg := fmt.Sprintf("hello%v", j)
				s.Write([]byte(msg))
				if _, err := s.Read(buf); err != nil {
					break
				}
			}
			s.Close()
			wg.Done()
		}(stream)
	}
	t.Log("created", session.NumStreams(), "streams")
	wg.Wait()
	session.Close()
}

func TestCloseThenOpen(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	session.Close()
	if _, err := session.OpenStream(); err == nil {
		t.Fatal("opened after close")
	}
}

func TestTinyReadBuffer(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	stream, _ := session.OpenStream()
	const N = 100
	tinybuf := make([]byte, 6)
	var sent string
	var received string
	for i := 0; i < N; i++ {
		msg := fmt.Sprintf("hello%v", i)
		sent += msg
		nsent, err := stream.Write([]byte(msg))
		if err != nil {
			t.Fatal("cannot write")
		}
		nrecv := 0
		for nrecv < nsent {
			if n, err := stream.Read(tinybuf); err == nil {
				nrecv += n
				received += string(tinybuf[:n])
			} else {
				t.Fatal("cannot read with tiny buffer")
			}
		}
	}

	if sent != received {
		t.Fatal("data mimatch")
	}
	session.Close()
}

func TestIsClose(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	session.Close()
	if session.IsClosed() != true {
		t.Fatal("still open after close")
	}
}

func TestKeepAliveTimeout(t *testing.T) {
	ln, err := net.Listen("tcp", "127.0.0.1:29999")
	if err != nil {
		// handle error
		panic(err)
	}
	go func() {
		ln.Accept()
	}()

	cli, err := net.Dial("tcp", "127.0.0.1:29999")
	if err != nil {
		t.Fatal(err)
	}

	config := DefaultConfig()
	config.KeepAliveInterval = 1
	config.KeepAliveTimeout = 2
	session, _ := Client(cli, config)
	<-time.After(3 * time.Second)
	if session.IsClosed() != true {
		t.Fatal("keepalive-timeout failed")
	}
}

func TestServerEcho(t *testing.T) {
	ln, err := net.Listen("tcp", "127.0.0.1:39999")
	if err != nil {
		// handle error
		panic(err)
	}
	go func() {
		if conn, err := ln.Accept(); err == nil {
			session, _ := Server(conn, nil)
			if stream, err := session.OpenStream(); err == nil {
				const N = 100
				buf := make([]byte, 10)
				for i := 0; i < N; i++ {
					msg := fmt.Sprintf("hello%v", i)
					stream.Write([]byte(msg))
					if n, err := stream.Read(buf); err != nil {
						t.Fatal(err)
					} else if string(buf[:n]) != msg {
						t.Fatal(err)
					}
				}
				stream.Close()
			} else {
				t.Fatal(err)
			}
		} else {
			t.Fatal(err)
		}
	}()

	cli, err := net.Dial("tcp", "127.0.0.1:39999")
	if err != nil {
		t.Fatal(err)
	}
	if session, err := Client(cli, nil); err == nil {
		if stream, err := session.AcceptStream(); err == nil {
			buf := make([]byte, 65536)
			for {
				n, err := stream.Read(buf)
				if err != nil {
					break
				}
				stream.Write(buf[:n])
			}
		} else {
			t.Fatal(err)
		}
	} else {
		t.Fatal(err)
	}
}

func TestSendWithoutRecv(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	stream, _ := session.OpenStream()
	const N = 100
	for i := 0; i < N; i++ {
		msg := fmt.Sprintf("hello%v", i)
		stream.Write([]byte(msg))
	}
	session.Close()
}

func BenchmarkAcceptClose(b *testing.B) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		b.Fatal(err)
	}
	session, _ := Client(cli, nil)
	for i := 0; i < b.N; i++ {
		if stream, err := session.OpenStream(); err == nil {
			stream.Close()
		} else {
			b.Fatal(err)
		}
	}
}
<commit_msg>upd test<commit_after>package smux

import (
	"fmt"
	"io"
	"log"
	"net"
	"sync"
	"testing"
	"time"
)

func init() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	ln, err := net.Listen("tcp", "127.0.0.1:19999")
	if err != nil {
		// handle error
		panic(err)
	}
	go func() {
		for {
			conn, err := ln.Accept()
			if err != nil {
				// handle error
			}
			go handleConnection(conn)
		}
	}()
}

func handleConnection(conn net.Conn) {
	session, _ := Server(conn, nil)
	for {
		if stream, err := session.AcceptStream(); err == nil {
			go func(s io.ReadWriteCloser) {
				buf := make([]byte, 65536)
				for {
					n, err := s.Read(buf)
					if err != nil {
						return
					}
					s.Write(buf[:n])
				}
			}(stream)
		} else {
			log.Println(err)
			return
		}
	}
}

func TestEcho(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	stream, _ := session.OpenStream()
	const N = 100
	buf := make([]byte, 10)
	var sent string
	var received string
	for i := 0; i < N; i++ {
		msg := fmt.Sprintf("hello%v", i)
		stream.Write([]byte(msg))
		sent += msg
		if n, err := stream.Read(buf); err != nil {
			t.Fatal(err)
		} else {
			received += string(buf[:n])
		}
	}
	if sent != received {
		t.Fatal("data mimatch")
	}
	session.Close()
}

func TestSpeed(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	stream, _ := session.OpenStream()

	start := time.Now()
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		buf := make([]byte, 1024*1024)
		nrecv := 0
		for {
			n, err := stream.Read(buf)
			if err != nil {
				t.Fatal(err)
				break
			} else {
				nrecv += n
				if nrecv == 4096*4096 {
					break
				}
			}
		}
		println("total recv:", nrecv)
		stream.Close()
		fmt.Println("time for 16MB rtt", time.Now().Sub(start))
		wg.Done()
	}()
	msg := make([]byte, 8192)
	for i := 0; i < 2048; i++ {
		stream.Write(msg)
	}
	wg.Wait()
	session.Close()
}

func TestParallel(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)

	par := 1000
	messages := 100
	var wg sync.WaitGroup
	wg.Add(par)
	for i := 0; i < par; i++ {
		stream, _ := session.OpenStream()
		go func(s *Stream) {
			buf := make([]byte, 20)
			for j := 0; j < messages; j++ {
				msg := fmt.Sprintf("hello%v", j)
				s.Write([]byte(msg))
				if _, err := s.Read(buf); err != nil {
					break
				}
			}
			s.Close()
			wg.Done()
		}(stream)
	}
	t.Log("created", session.NumStreams(), "streams")
	wg.Wait()
	session.Close()
}

func TestCloseThenOpen(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	session.Close()
	if _, err := session.OpenStream(); err == nil {
		t.Fatal("opened after close")
	}
}

func TestTinyReadBuffer(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	stream, _ := session.OpenStream()
	const N = 100
	tinybuf := make([]byte, 6)
	var sent string
	var received string
	for i := 0; i < N; i++ {
		msg := fmt.Sprintf("hello%v", i)
		sent += msg
		nsent, err := stream.Write([]byte(msg))
		if err != nil {
			t.Fatal("cannot write")
		}
		nrecv := 0
		for nrecv < nsent {
			if n, err := stream.Read(tinybuf); err == nil {
				nrecv += n
				received += string(tinybuf[:n])
			} else {
				t.Fatal("cannot read with tiny buffer")
			}
		}
	}

	if sent != received {
		t.Fatal("data mimatch")
	}
	session.Close()
}

func TestIsClose(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	session.Close()
	if session.IsClosed() != true {
		t.Fatal("still open after close")
	}
}

func TestKeepAliveTimeout(t *testing.T) {
	ln, err := net.Listen("tcp", "127.0.0.1:29999")
	if err != nil {
		// handle error
		panic(err)
	}
	go func() {
		ln.Accept()
	}()

	cli, err := net.Dial("tcp", "127.0.0.1:29999")
	if err != nil {
		t.Fatal(err)
	}

	config := DefaultConfig()
	config.KeepAliveInterval = 1
	config.KeepAliveTimeout = 2
	session, _ := Client(cli, config)
	<-time.After(3 * time.Second)
	if session.IsClosed() != true {
		t.Fatal("keepalive-timeout failed")
	}
}

func TestServerEcho(t *testing.T) {
	ln, err := net.Listen("tcp", "127.0.0.1:39999")
	if err != nil {
		// handle error
		panic(err)
	}
	go func() {
		if conn, err := ln.Accept(); err == nil {
			session, _ := Server(conn, nil)
			if stream, err := session.OpenStream(); err == nil {
				const N = 100
				buf := make([]byte, 10)
				for i := 0; i < N; i++ {
					msg := fmt.Sprintf("hello%v", i)
					stream.Write([]byte(msg))
					if n, err := stream.Read(buf); err != nil {
						t.Fatal(err)
					} else if string(buf[:n]) != msg {
						t.Fatal(err)
					}
				}
				stream.Close()
			} else {
				t.Fatal(err)
			}
		} else {
			t.Fatal(err)
		}
	}()

	cli, err := net.Dial("tcp", "127.0.0.1:39999")
	if err != nil {
		t.Fatal(err)
	}
	if session, err := Client(cli, nil); err == nil {
		if stream, err := session.AcceptStream(); err == nil {
			buf := make([]byte, 65536)
			for {
				n, err := stream.Read(buf)
				if err != nil {
					break
				}
				stream.Write(buf[:n])
			}
		} else {
			t.Fatal(err)
		}
	} else {
		t.Fatal(err)
	}
}

func TestSendWithoutRecv(t *testing.T) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		t.Fatal(err)
	}
	session, _ := Client(cli, nil)
	stream, _ := session.OpenStream()
	const N = 100
	for i := 0; i < N; i++ {
		msg := fmt.Sprintf("hello%v", i)
		stream.Write([]byte(msg))
	}
	buf := make([]byte, 1024)
	if _, err := stream.Read(buf); err != nil {
		t.Fatal(err)
	}
	session.Close()
}

func BenchmarkAcceptClose(b *testing.B) {
	cli, err := net.Dial("tcp", "127.0.0.1:19999")
	if err != nil {
		b.Fatal(err)
	}
	session, _ := Client(cli, nil)
	for i := 0; i < b.N; i++ {
		if stream, err := session.OpenStream(); err == nil {
			stream.Close()
		} else {
			b.Fatal(err)
		}
	}
}
<|endoftext|>


<commit_before>package stripe

import (
	"encoding/json"
)

// SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow indicates the type of 3D Secure authentication performed.
type SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow string

// List of values that SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow can take.
const (
	SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlowChallenge    SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow = "challenge"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlowFrictionless SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow = "frictionless"
)

// SetupAttemptPaymentMethodDetailsCardThreeDSecureResult indicates the outcome of 3D Secure authentication.
type SetupAttemptPaymentMethodDetailsCardThreeDSecureResult string

// List of values that SetupAttemptPaymentMethodDetailsCardThreeDSecureResult can take.
const (
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultAttemptAcknowledged SetupAttemptPaymentMethodDetailsCardThreeDSecureResult = "attempt_acknowledged"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultAuthenticated       SetupAttemptPaymentMethodDetailsCardThreeDSecureResult = "authenticated"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultFailed              SetupAttemptPaymentMethodDetailsCardThreeDSecureResult = "failed"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultNotSupported        SetupAttemptPaymentMethodDetailsCardThreeDSecureResult = "not_supported"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultProcessingError     SetupAttemptPaymentMethodDetailsCardThreeDSecureResult = "processing_error"
)

// SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason represents dditional information about why 3D Secure succeeded or failed
type SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason string

// List of values that SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason can take.
const (
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonAbandoned           SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "abandoned"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonBypassed            SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "bypassed"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonCanceled            SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "canceled"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonCardNotEnrolled     SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "card_not_enrolled"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonNetworkNotSupported SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "network_not_supported"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonProtocolError       SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "protocol_error"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonRejected            SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "rejected"
)

// SetupAttemptPaymentMethodDetailsType is the type of the payment method associated with the setup attempt's payment method details.
type SetupAttemptPaymentMethodDetailsType string

// List of values that SetupAttemptPaymentMethodDetailsType can take.
const (
	SetupAttemptPaymentMethodDetailsTypeCard SetupAttemptPaymentMethodDetailsType = "card"
)

// SetupAttemptUsage is the list of allowed values for usage.
type SetupAttemptUsage string

// List of values that SetupAttemptUsage can take.
const (
	SetupAttemptUsageOffSession SetupAttemptUsage = "off_session"
	SetupAttemptUsageOnSession  SetupAttemptUsage = "on_session"
)

// SetupAttemptStatus is the list of allowed values for the setup attempt's status.
type SetupAttemptStatus string

// List of values that SetupAttemptStatus can take.
const (
	SetupAttemptStatusAbandoned            SetupAttemptStatus = "abandoned"
	SetupAttemptStatusFailed               SetupAttemptStatus = "failed"
	SetupAttemptStatusProcessing           SetupAttemptStatus = "processing"
	SetupAttemptStatusRequiresAction       SetupAttemptStatus = "requires_action"
	SetupAttemptStatusRequiresConfirmation SetupAttemptStatus = "requires_confirmation"
	SetupAttemptStatusSucceeded            SetupAttemptStatus = "succeeded"
)

// SetupAttemptListParams is the set of parameters that can be used when listing setup attempts.
type SetupAttemptListParams struct {
	ListParams   `form:"*"`
	Created      *int64            `form:"created"`
	CreatedRange *RangeQueryParams `form:"created"`
	SetupIntent  *string           `form:"setup_intent"`
}

// SetupAttemptPaymentMethodDetailsCardThreeDSecure represents details about 3DS associated with the setup attempt's payment method.
type SetupAttemptPaymentMethodDetailsCardThreeDSecure struct {
	AuthenticationFlow SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow `json:"authentication_flow"`
	Result             SetupAttemptPaymentMethodDetailsCardThreeDSecureResult             `json:"result"`
	ResultReason       SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason       `json:"result_reason"`
	Version            string                                                             `json:"version"`
}

// SetupAttemptPaymentMethodDetailsBancontact represents details about the Bancontact PaymentMethod.
type SetupAttemptPaymentMethodDetailsBancontact struct {
	BankCode                  string         `json:"bank_code"`
	BankName                  string         `json:"bank_name"`
	Bic                       string         `json:"bic"`
	GeneratedSepaDebit        *PaymentMethod `json:"generated_sepa_debit"`
	GeneratedSepaDebitMandate *Mandate       `json:"generated_sepa_debit_mandate"`
	IbanLast4                 string         `json:"iban_last4"`
	PreferredLanguage         string         `json:"preferred_language"`
	VerifiedName              string         `json:"verified_name"`
}

// SetupAttemptPaymentMethodDetailsCard represents details about the Card PaymentMethod.
type SetupAttemptPaymentMethodDetailsCard struct {
	ThreeDSecure *SetupAttemptPaymentMethodDetailsCardThreeDSecure `json:"three_d_secure"`
}

// SetupAttemptPaymentMethodDetailsBancontact represents details about the Bancontact PaymentMethod.
type SetupAttemptPaymentMethodDetailsIdeal struct {
	Bank                      string         `json:"bank"`
	Bic                       string         `json:"bic"`
	GeneratedSepaDebit        *PaymentMethod `json:"generated_sepa_debit"`
	GeneratedSepaDebitMandate *Mandate       `json:"generated_sepa_debit_mandate"`
	IbanLast4                 string         `json:"iban_last4"`
	VerifiedName              string         `json:"verified_name"`
}

// SetupAttemptPaymentMethodDetailsBancontact represents details about the Bancontact PaymentMethod.
type SetupAttemptPaymentMethodDetailsSofort struct {
	BankCode                  string         `json:"bank_code"`
	BankName                  string         `json:"bank_name"`
	Bic                       string         `json:"bic"`
	GeneratedSepaDebit        *PaymentMethod `json:"generated_sepa_debit"`
	GeneratedSepaDebitMandate *Mandate       `json:"generated_sepa_debit_mandate"`
	IbanLast4                 string         `json:"iban_last4"`
	PreferredLanguage         string         `json:"preferred_language"`
	VerifiedName              string         `json:"verified_name"`
}

// SetupAttemptPaymentMethodDetails represents the details about the PaymentMethod associated with the setup attempt.
type SetupAttemptPaymentMethodDetails struct {
	Bancontact *SetupAttemptPaymentMethodDetailsBancontact `json:"bancontact"`
	Card       *SetupAttemptPaymentMethodDetailsCard       `json:"card"`
	Ideal      *SetupAttemptPaymentMethodDetailsIdeal      `json:"ideal"`
	Sofort     *SetupAttemptPaymentMethodDetailsSofort     `json:"sofort"`
	Type       SetupAttemptPaymentMethodDetailsType        `json:"type"`
}

// SetupAttempt is the resource representing a Stripe setup attempt.
type SetupAttempt struct {
	APIResource
	Application          *Application                      `json:"application"`
	Created              int64                             `json:"created"`
	Customer             *Customer                         `json:"customer"`
	ID                   string                            `json:"id"`
	Livemode             bool                              `json:"livemode"`
	Object               string                            `json:"object"`
	OnBehalfOf           *Account                          `json:"on_behalf_of"`
	PaymentMethod        *PaymentMethod                    `json:"payment_method"`
	PaymentMethodDetails *SetupAttemptPaymentMethodDetails `json:"payment_method_details"`
	SetupError           *Error                            `json:"setup_error"`
	Status               SetupAttemptStatus                `json:"status"`
	Usage                SetupAttemptUsage                 `json:"usage"`
}

// SetupAttemptList is a list of setup attempts as retrieved from a list endpoint.
type SetupAttemptList struct {
	APIResource
	ListMeta
	Data []*SetupAttempt `json:"data"`
}

// UnmarshalJSON handles deserialization of a SetupAttempt.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (p *SetupAttempt) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		p.ID = id
		return nil
	}

	type setupAttempt SetupAttempt
	var v setupAttempt
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*p = SetupAttempt(v)
	return nil
}
<commit_msg>Fix bad comments to make the linter happy<commit_after>package stripe

import (
	"encoding/json"
)

// SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow indicates the type of 3D Secure authentication performed.
type SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow string

// List of values that SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow can take.
const (
	SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlowChallenge    SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow = "challenge"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlowFrictionless SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow = "frictionless"
)

// SetupAttemptPaymentMethodDetailsCardThreeDSecureResult indicates the outcome of 3D Secure authentication.
type SetupAttemptPaymentMethodDetailsCardThreeDSecureResult string

// List of values that SetupAttemptPaymentMethodDetailsCardThreeDSecureResult can take.
const (
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultAttemptAcknowledged SetupAttemptPaymentMethodDetailsCardThreeDSecureResult = "attempt_acknowledged"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultAuthenticated       SetupAttemptPaymentMethodDetailsCardThreeDSecureResult = "authenticated"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultFailed              SetupAttemptPaymentMethodDetailsCardThreeDSecureResult = "failed"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultNotSupported        SetupAttemptPaymentMethodDetailsCardThreeDSecureResult = "not_supported"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultProcessingError     SetupAttemptPaymentMethodDetailsCardThreeDSecureResult = "processing_error"
)

// SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason represents dditional information about why 3D Secure succeeded or failed
type SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason string

// List of values that SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason can take.
const (
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonAbandoned           SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "abandoned"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonBypassed            SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "bypassed"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonCanceled            SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "canceled"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonCardNotEnrolled     SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "card_not_enrolled"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonNetworkNotSupported SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "network_not_supported"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonProtocolError       SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "protocol_error"
	SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReasonRejected            SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason = "rejected"
)

// SetupAttemptPaymentMethodDetailsType is the type of the payment method associated with the setup attempt's payment method details.
type SetupAttemptPaymentMethodDetailsType string

// List of values that SetupAttemptPaymentMethodDetailsType can take.
const (
	SetupAttemptPaymentMethodDetailsTypeCard SetupAttemptPaymentMethodDetailsType = "card"
)

// SetupAttemptUsage is the list of allowed values for usage.
type SetupAttemptUsage string

// List of values that SetupAttemptUsage can take.
const (
	SetupAttemptUsageOffSession SetupAttemptUsage = "off_session"
	SetupAttemptUsageOnSession  SetupAttemptUsage = "on_session"
)

// SetupAttemptStatus is the list of allowed values for the setup attempt's status.
type SetupAttemptStatus string

// List of values that SetupAttemptStatus can take.
const (
	SetupAttemptStatusAbandoned            SetupAttemptStatus = "abandoned"
	SetupAttemptStatusFailed               SetupAttemptStatus = "failed"
	SetupAttemptStatusProcessing           SetupAttemptStatus = "processing"
	SetupAttemptStatusRequiresAction       SetupAttemptStatus = "requires_action"
	SetupAttemptStatusRequiresConfirmation SetupAttemptStatus = "requires_confirmation"
	SetupAttemptStatusSucceeded            SetupAttemptStatus = "succeeded"
)

// SetupAttemptListParams is the set of parameters that can be used when listing setup attempts.
type SetupAttemptListParams struct {
	ListParams   `form:"*"`
	Created      *int64            `form:"created"`
	CreatedRange *RangeQueryParams `form:"created"`
	SetupIntent  *string           `form:"setup_intent"`
}

// SetupAttemptPaymentMethodDetailsCardThreeDSecure represents details about 3DS associated with the setup attempt's payment method.
type SetupAttemptPaymentMethodDetailsCardThreeDSecure struct {
	AuthenticationFlow SetupAttemptPaymentMethodDetailsCardThreeDSecureAuthenticationFlow `json:"authentication_flow"`
	Result             SetupAttemptPaymentMethodDetailsCardThreeDSecureResult             `json:"result"`
	ResultReason       SetupAttemptPaymentMethodDetailsCardThreeDSecureResultReason       `json:"result_reason"`
	Version            string                                                             `json:"version"`
}

// SetupAttemptPaymentMethodDetailsBancontact represents details about the Bancontact PaymentMethod.
type SetupAttemptPaymentMethodDetailsBancontact struct {
	BankCode                  string         `json:"bank_code"`
	BankName                  string         `json:"bank_name"`
	Bic                       string         `json:"bic"`
	GeneratedSepaDebit        *PaymentMethod `json:"generated_sepa_debit"`
	GeneratedSepaDebitMandate *Mandate       `json:"generated_sepa_debit_mandate"`
	IbanLast4                 string         `json:"iban_last4"`
	PreferredLanguage         string         `json:"preferred_language"`
	VerifiedName              string         `json:"verified_name"`
}

// SetupAttemptPaymentMethodDetailsCard represents details about the Card PaymentMethod.
type SetupAttemptPaymentMethodDetailsCard struct {
	ThreeDSecure *SetupAttemptPaymentMethodDetailsCardThreeDSecure `json:"three_d_secure"`
}

// SetupAttemptPaymentMethodDetailsIdeal represents details about the Bancontact PaymentMethod.
type SetupAttemptPaymentMethodDetailsIdeal struct {
	Bank                      string         `json:"bank"`
	Bic                       string         `json:"bic"`
	GeneratedSepaDebit        *PaymentMethod `json:"generated_sepa_debit"`
	GeneratedSepaDebitMandate *Mandate       `json:"generated_sepa_debit_mandate"`
	IbanLast4                 string         `json:"iban_last4"`
	VerifiedName              string         `json:"verified_name"`
}

// SetupAttemptPaymentMethodDetailsSofort represents details about the Bancontact PaymentMethod.
type SetupAttemptPaymentMethodDetailsSofort struct {
	BankCode                  string         `json:"bank_code"`
	BankName                  string         `json:"bank_name"`
	Bic                       string         `json:"bic"`
	GeneratedSepaDebit        *PaymentMethod `json:"generated_sepa_debit"`
	GeneratedSepaDebitMandate *Mandate       `json:"generated_sepa_debit_mandate"`
	IbanLast4                 string         `json:"iban_last4"`
	PreferredLanguage         string         `json:"preferred_language"`
	VerifiedName              string         `json:"verified_name"`
}

// SetupAttemptPaymentMethodDetails represents the details about the PaymentMethod associated with the setup attempt.
type SetupAttemptPaymentMethodDetails struct {
	Bancontact *SetupAttemptPaymentMethodDetailsBancontact `json:"bancontact"`
	Card       *SetupAttemptPaymentMethodDetailsCard       `json:"card"`
	Ideal      *SetupAttemptPaymentMethodDetailsIdeal      `json:"ideal"`
	Sofort     *SetupAttemptPaymentMethodDetailsSofort     `json:"sofort"`
	Type       SetupAttemptPaymentMethodDetailsType        `json:"type"`
}

// SetupAttempt is the resource representing a Stripe setup attempt.
type SetupAttempt struct {
	APIResource
	Application          *Application                      `json:"application"`
	Created              int64                             `json:"created"`
	Customer             *Customer                         `json:"customer"`
	ID                   string                            `json:"id"`
	Livemode             bool                              `json:"livemode"`
	Object               string                            `json:"object"`
	OnBehalfOf           *Account                          `json:"on_behalf_of"`
	PaymentMethod        *PaymentMethod                    `json:"payment_method"`
	PaymentMethodDetails *SetupAttemptPaymentMethodDetails `json:"payment_method_details"`
	SetupError           *Error                            `json:"setup_error"`
	Status               SetupAttemptStatus                `json:"status"`
	Usage                SetupAttemptUsage                 `json:"usage"`
}

// SetupAttemptList is a list of setup attempts as retrieved from a list endpoint.
type SetupAttemptList struct {
	APIResource
	ListMeta
	Data []*SetupAttempt `json:"data"`
}

// UnmarshalJSON handles deserialization of a SetupAttempt.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (p *SetupAttempt) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		p.ID = id
		return nil
	}

	type setupAttempt SetupAttempt
	var v setupAttempt
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*p = SetupAttempt(v)
	return nil
}
<|endoftext|>


<commit_before>// Licensed under GPL-2.0
package main

import (
	"flag"
	"fmt"
	"html"
	"io"
	"io/ioutil"
	"log"
	"mime"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
)

/*
#cgo LDFLAGS: -lcap
#include <sys/capability.h>
#include <errno.h>

static int dropAllCaps(void) {
    cap_t state;

    state = cap_init();
    if (!state) {
        cap_free(state);
    }

    if (cap_clear(state) < 0) {
        cap_free(state);
        return errno;
    }

    if (cap_set_proc(state) == -1) {
        cap_free(state);
        return errno;
    }

    cap_free(state);
    return 0;
}
*/
import "C"

var requestLog *log.Logger
var allowUploads *bool

func dropAllCaps() (err error) {
	errno := C.dropAllCaps()
	if errno != 0 {
		return syscall.Errno(errno)
	}
	return
}

func reqHandler(w http.ResponseWriter, r *http.Request) {
	if !*allowUploads && r.Method == "POST" {
		http.Error(w, "Uploads not allowed", http.StatusForbidden)
		log.Println("Uploads not allowed")
		return
	}

	cwd, _ := os.Getwd()
	filePath := filepath.Join(cwd, r.URL.Path)
	if strings.HasPrefix(filePath, cwd) == false {
		log.Println("Trying to access dir outside of cwd")
		return
	}

	statInfo, statErr := os.Stat(filePath)
	if statErr != nil {
		http.NotFound(w, r)
		log.Println(statErr)
		return
	}

	requestLog.Println(r.RemoteAddr, fmt.Sprintf("\"%s %s %s\"", r.Method, r.URL, r.Proto))
	if r.Method == "GET" && statInfo.IsDir() {
		files, readErr := ioutil.ReadDir(filePath)
		if readErr != nil {
			http.Error(w, "Directory read error", http.StatusInternalServerError)
			log.Println(readErr)
			return
		}

		w.Header().Set("Content-Type", "text/html")
		dirlistTitle := fmt.Sprintf("Directory listing for %s", r.URL.Path)

		fmt.Fprintf(w, "<!DOCTYPE html>\n"+
			"\n"+
			"\n"+
			"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"+
			fmt.Sprintf("<title>%s</title>\n", dirlistTitle)+
			"\n\n"+
			fmt.Sprintf("
%s
\n", dirlistTitle))
		if *allowUploads {
			fmt.Fprintf(w, fmt.Sprintf("<form action=\"%s\" method=\"post\" enctype=\"multipart/form-data\">\n", r.URL.Path)+
				"Upload file: \n"+
				"<input type=\"file\" name=\"file\">\n"+
				"<input type=\"submit\" value=\"Submit\" />\n</form>\n")
		}
		fmt.Fprintf(w, "
\n
\n")

		listFmt := "
\n..\n
\n"
		fmt.Fprintf(w, listFmt, filepath.Dir(r.URL.Path))
		for _, f := range files {
			fFull := html.EscapeString(filepath.Join(r.URL.Path, f.Name()))
			fmt.Fprintf(w, "
\n%s\n
\n", fFull, f.Name())
		}

		fmt.Fprintf(w, "
\n
\n\n")

	} else if r.Method == "GET" {
		mimeType := mime.TypeByExtension(filepath.Ext(filePath))
		if mimeType == "" {
			mimeType = "application/octet-stream"
		}
		w.Header().Set("Content-Type", mimeType)
		w.Header().Set("Content-Length", strconv.FormatInt(statInfo.Size(), 10))

		file, err := os.Open(filePath)
		if err != nil {
			log.Println(err)
			return
		}
		defer file.Close()

		_, err = io.Copy(w, file)
		if err != nil {
			log.Println(err)
			return
		}

	} else if r.Method == "POST" {
		if !statInfo.IsDir() {
			http.Error(w, "Cannot upload to non-directory file", http.StatusForbidden)
			log.Println("Cannot upload to non-directory file")
			return
		}

		err := r.ParseMultipartForm(15485760)
		if err != nil {
			log.Println(err)
			return
		}
		formFile, handler, err := r.FormFile("file")
		if err != nil {
			fmt.Println(err)
			return
		}
		defer formFile.Close()

		outFilePath := filepath.Join(filePath, handler.Filename)
		if _, err := os.Stat(outFilePath); err == nil {
			http.Error(w, "File already exists", http.StatusForbidden)
			log.Println("File already exists")
			return
		}
		f, err := os.OpenFile(outFilePath, os.O_WRONLY|os.O_CREATE, 0666)
		if err != nil {
			http.Error(w, "Cannot write file", http.StatusForbidden)
			fmt.Println(err)
			return
		}
		defer f.Close()

		_, err = io.Copy(f, formFile)
		if err != nil {
			log.Println(err)
			return
		}
		http.Redirect(w, r, r.URL.Path, 302)
	} else {
		http.Error(w, "Unhandled request", http.StatusBadRequest)
	}
}

func main() {
	requestLog = log.New(os.Stdout,
		"REQ: ",
		log.Ldate|log.Ltime)

	err := syscall.Chroot(".")
	if err != nil {
		panic(err)
	}
	err = dropAllCaps()
	if err != nil {
		panic(err)
	}

	allowUploads = flag.Bool("allow-uploads", false, "Allow uploading of files")
	listenPort := flag.Int("port", 8000, "Listen on port (default 8000)")
	flag.Parse()

	http.HandleFunc("/", reqHandler)
	fmt.Println("Listening on port", *listenPort)
	err = http.ListenAndServe(fmt.Sprintf(":%d", *listenPort), nil)
	if err != nil {
		panic(err)
	}
}
<commit_msg>Handle all errors (including defered)<commit_after>// Licensed under GPL-2.0
package main

import (
	"flag"
	"fmt"
	"html"
	"io"
	"io/ioutil"
	"log"
	"mime"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
)

/*
#cgo LDFLAGS: -lcap
#include <sys/capability.h>
#include <errno.h>

static int dropAllCaps(void) {
    cap_t state;

    state = cap_init();
    if (!state) {
        cap_free(state);
    }

    if (cap_clear(state) < 0) {
        cap_free(state);
        return errno;
    }

    if (cap_set_proc(state) == -1) {
        cap_free(state);
        return errno;
    }

    cap_free(state);
    return 0;
}
*/
import "C"

var requestLog *log.Logger
var allowUploads *bool

func dropAllCaps() (err error) {
	errno := C.dropAllCaps()
	if errno != 0 {
		return syscall.Errno(errno)
	}
	return
}

func reqHandler(w http.ResponseWriter, r *http.Request) {
	if !*allowUploads && r.Method == "POST" {
		http.Error(w, "Uploads not allowed", http.StatusForbidden)
		log.Println("Uploads not allowed")
		return
	}

	cwd, _ := os.Getwd()
	filePath := filepath.Join(cwd, r.URL.Path)
	if strings.HasPrefix(filePath, cwd) == false {
		log.Println("Trying to access dir outside of cwd")
		return
	}

	statInfo, statErr := os.Stat(filePath)
	if statErr != nil {
		http.NotFound(w, r)
		log.Println(statErr)
		return
	}

	requestLog.Println(r.RemoteAddr, fmt.Sprintf("\"%s %s %s\"", r.Method, r.URL, r.Proto))
	if r.Method == "GET" && statInfo.IsDir() {
		files, readErr := ioutil.ReadDir(filePath)
		if readErr != nil {
			http.Error(w, "Directory read error", http.StatusInternalServerError)
			log.Println(readErr)
			return
		}

		w.Header().Set("Content-Type", "text/html")
		dirlistTitle := fmt.Sprintf("Directory listing for %s", r.URL.Path)

		fmt.Fprintf(w, "<!DOCTYPE html>\n"+
			"\n"+
			"\n"+
			"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"+
			fmt.Sprintf("<title>%s</title>\n", dirlistTitle)+
			"\n\n"+
			fmt.Sprintf("
%s
\n", dirlistTitle))
		if *allowUploads {
			fmt.Fprintf(w, fmt.Sprintf("<form action=\"%s\" method=\"post\" enctype=\"multipart/form-data\">\n", r.URL.Path)+
				"Upload file: \n"+
				"<input type=\"file\" name=\"file\">\n"+
				"<input type=\"submit\" value=\"Submit\" />\n</form>\n")
		}
		fmt.Fprintf(w, "
\n
\n")

		listFmt := "
\n..\n
\n"
		fmt.Fprintf(w, listFmt, filepath.Dir(r.URL.Path))
		for _, f := range files {
			fFull := html.EscapeString(filepath.Join(r.URL.Path, f.Name()))
			fmt.Fprintf(w, "
\n%s\n
\n", fFull, f.Name())
		}

		fmt.Fprintf(w, "
\n
\n\n")

	} else if r.Method == "GET" {
		mimeType := mime.TypeByExtension(filepath.Ext(filePath))
		if mimeType == "" {
			mimeType = "application/octet-stream"
		}
		w.Header().Set("Content-Type", mimeType)
		w.Header().Set("Content-Length", strconv.FormatInt(statInfo.Size(), 10))

		file, err := os.Open(filePath)
		if err != nil {
			log.Println(err)
			return
		}
		defer func() {
			err := file.Close()
			if err != nil {
				panic(err)
			}
		}()

		_, err = io.Copy(w, file)
		if err != nil {
			log.Println(err)
			return
		}

	} else if r.Method == "POST" {
		if !statInfo.IsDir() {
			http.Error(w, "Cannot upload to non-directory file", http.StatusForbidden)
			log.Println("Cannot upload to non-directory file")
			return
		}

		err := r.ParseMultipartForm(15485760)
		if err != nil {
			log.Println(err)
			return
		}
		formFile, handler, err := r.FormFile("file")
		if err != nil {
			fmt.Println(err)
			return
		}
		defer func() {
			err := formFile.Close()
			if err != nil {
				panic(err)
			}
		}()

		outFilePath := filepath.Join(filePath, handler.Filename)
		if _, err := os.Stat(outFilePath); err == nil {
			http.Error(w, "File already exists", http.StatusForbidden)
			log.Println("File already exists")
			return
		}
		f, err := os.OpenFile(outFilePath, os.O_WRONLY|os.O_CREATE, 0666)
		if err != nil {
			http.Error(w, "Cannot write file", http.StatusForbidden)
			fmt.Println(err)
			return
		}
		defer func() {
			err := f.Close()
			if err != nil {
				panic(err)
			}
		}()

		_, err = io.Copy(f, formFile)
		if err != nil {
			log.Println(err)
			return
		}
		http.Redirect(w, r, r.URL.Path, 302)
	} else {
		http.Error(w, "Unhandled request", http.StatusBadRequest)
	}
}

func main() {
	requestLog = log.New(os.Stdout,
		"REQ: ",
		log.Ldate|log.Ltime)

	err := syscall.Chroot(".")
	if err != nil {
		panic(err)
	}
	err = dropAllCaps()
	if err != nil {
		panic(err)
	}

	allowUploads = flag.Bool("allow-uploads", false, "Allow uploading of files")
	listenPort := flag.Int("port", 8000, "Listen on port (default 8000)")
	flag.Parse()

	http.HandleFunc("/", reqHandler)
	fmt.Println("Listening on port", *listenPort)
	err = http.ListenAndServe(fmt.Sprintf(":%d", *listenPort), nil)
	if err != nil {
		panic(err)
	}
}
<|endoftext|>