<commit_before>// Copyright 2014, Hǎiliàng Wáng. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gccxml

import (
	"bufio"
	"io"
	"regexp"
	"sort"
	"strings"
)

var (
	reMacro = regexp.MustCompile(`#define (\S+) (.*)`)
)

type Macro struct {
	Name string
	Body string
}

type Macros []Macro

func DecodeMacros(r io.Reader) (ms Macros, err error) {
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		m := reMacro.FindStringSubmatch(scanner.Text())
		if len(m) == 3 {
			ms = append(ms, Macro{m[1], strings.TrimSpace(m[2])})
		}
	}
	err = scanner.Err()
	sort.Sort(ms)
	return
}

func (m Macro) HasPrefix(prefix string) bool {
	return strings.HasPrefix(m.Name, prefix)
}

func (m Macro) NoArg() bool {
	return !strings.Contains(m.Name, "(")
}

func (m Macro) IsString() bool {
	return len(m.Body) >= 2 && m.Body[0] == '"' && m.Body[len(m.Body)-1] == '"'
}

func (m Macro) ContainsNum() bool {
	for _, c := range m.Body {
		if c >= '0' && c <= '9' {
			return true
		}
	}
	return false
}

func (m Macro) ContainsOthers(ms Macros) bool {
	for _, o := range ms {
		if strings.Contains(m.Body, o.Name) {
			return true
		}
	}
	return false
}

func (ms Macros) Constants(prefix string) (fms Macros) {
	for _, m := range ms {
		if m.HasPrefix(prefix) &&
			m.NoArg() &&
			(m.IsString() || m.ContainsNum() || m.ContainsOthers(ms)) {
			fms = append(fms, m)
		}
	}
	return
}

func (s Macros) Len() int {
	return len(s)
}

func (s Macros) Less(i, j int) bool {
	return s[i].Name < s[j].Name
}

func (s Macros) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}
<commit_msg>use regular expression instead of prefix.<commit_after>// Copyright 2014, Hǎiliàng Wáng. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gccxml

import (
	"bufio"
	"io"
	"regexp"
	"sort"
	"strings"
)

var (
	reMacro = regexp.MustCompile(`#define (\S+) (.*)`)
)

type Macro struct {
	Name string
	Body string
}

type Macros []Macro

func DecodeMacros(r io.Reader) (ms Macros, err error) {
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		m := reMacro.FindStringSubmatch(scanner.Text())
		if len(m) == 3 {
			ms = append(ms, Macro{m[1], strings.TrimSpace(m[2])})
		}
	}
	err = scanner.Err()
	sort.Sort(ms)
	return
}

func (m Macro) NoArg() bool {
	return !strings.Contains(m.Name, "(")
}

func (m Macro) IsString() bool {
	return len(m.Body) >= 2 && m.Body[0] == '"' && m.Body[len(m.Body)-1] == '"'
}

func (m Macro) ContainsNum() bool {
	for _, c := range m.Body {
		if c >= '0' && c <= '9' {
			return true
		}
	}
	return false
}

func (m Macro) ContainsOthers(ms Macros) bool {
	for _, o := range ms {
		if strings.Contains(m.Body, o.Name) {
			return true
		}
	}
	return false
}

func (ms Macros) Constants(pat string) (fms Macros) {
	re := regexp.MustCompile(pat)
	for _, m := range ms {
		if re.MatchString(m.Name) &&
			m.NoArg() &&
			(m.IsString() || m.ContainsNum() || m.ContainsOthers(ms)) {
			fms = append(fms, m)
		}
	}
	return
}

func (s Macros) Len() int {
	return len(s)
}

func (s Macros) Less(i, j int) bool {
	return s[i].Name < s[j].Name
}

func (s Macros) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}
<|endoftext|>


<commit_before>package types

import (
	"testing"
	"time"

	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
	"github.com/stretchr/testify/require"
	testconstants "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/constants"
	"github.com/zigbee-alliance/distributed-compliance-ledger/testutil/sample"
	"github.com/zigbee-alliance/distributed-compliance-ledger/utils/validator"
)

func TestMsgCertifyModel_ValidateBasic(t *testing.T) {
	negative_tests := []struct {
		name string
		msg  MsgCertifyModel
		err  error
	}{
		{
			name: "invalid address",
			msg: MsgCertifyModel{
				Signer:                "invalid_address",
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
			},
			err: sdkerrors.ErrInvalidAddress,
		},
		{
			name: "vid is 0",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Vid:                   0,
				Pid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
			},
			err: validator.ErrFieldLowerBoundViolated,
		},
		{
			name: "vid < 0",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Vid:                   -1,
				Pid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
			},
			err: validator.ErrFieldLowerBoundViolated,
		},
		{
			name: "vid > 65535",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Vid:                   65536,
				Pid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
			},
			err: validator.ErrFieldUpperBoundViolated,
		},
		{
			name: "pid is 0",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Pid:                   0,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
			},
			err: validator.ErrFieldLowerBoundViolated,
		},
		{
			name: "pid < 0",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Pid:                   -1,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
			},
			err: validator.ErrFieldLowerBoundViolated,
		},
		{
			name: "pid > 65535",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Pid:                   65536,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
			},
			err: validator.ErrFieldUpperBoundViolated,
		},
		{
			name: "cd version number  > 65535",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				CDVersionNumber:       65536,
				Pid:                   1,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
			},
			err: validator.ErrFieldUpperBoundViolated,
		},
	}

	positive_tests := []struct {
		name string
		msg  MsgCertifyModel
	}{
		{
			name: "valid address",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				SoftwareVersionString: testconstants.SoftwareVersionString,
				Pid:                   1,
				Vid:                   1,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
			},
		},
	}

	for _, tt := range negative_tests {
		t.Run(tt.name, func(t *testing.T) {
			err := tt.msg.ValidateBasic()
			require.Error(t, err)
			require.ErrorIs(t, err, tt.err)
		})
	}

	for _, tt := range positive_tests {
		t.Run(tt.name, func(t *testing.T) {
			err := tt.msg.ValidateBasic()
			require.NoError(t, err)
		})
	}
}
<commit_msg>certify model tests updated<commit_after>package types

import (
	"testing"
	"time"

	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
	"github.com/stretchr/testify/require"
	testconstants "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/constants"
	"github.com/zigbee-alliance/distributed-compliance-ledger/testutil/sample"
	"github.com/zigbee-alliance/distributed-compliance-ledger/utils/validator"
)

func TestMsgCertifyModel_ValidateBasic(t *testing.T) {
	negative_tests := []struct {
		name string
		msg  MsgCertifyModel
		err  error
	}{
		{
			name: "invalid address",
			msg: MsgCertifyModel{
				Signer:                "invalid_address",
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       testconstants.SoftwareVersion,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
			err: sdkerrors.ErrInvalidAddress,
		},
		{
			name: "vid is 0",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Vid:                   0,
				Pid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       testconstants.SoftwareVersion,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
			err: validator.ErrFieldLowerBoundViolated,
		},
		{
			name: "vid < 0",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Vid:                   -1,
				Pid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       testconstants.SoftwareVersion,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
			err: validator.ErrFieldLowerBoundViolated,
		},
		{
			name: "vid > 65535",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Vid:                   65536,
				Pid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       testconstants.SoftwareVersion,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
			err: validator.ErrFieldUpperBoundViolated,
		},
		{
			name: "pid is 0",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Pid:                   0,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       testconstants.SoftwareVersion,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
			err: validator.ErrFieldLowerBoundViolated,
		},
		{
			name: "pid < 0",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Pid:                   -1,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       testconstants.SoftwareVersion,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
			err: validator.ErrFieldLowerBoundViolated,
		},
		{
			name: "pid > 65535",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Pid:                   65536,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       testconstants.SoftwareVersion,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
			err: validator.ErrFieldUpperBoundViolated,
		},
		{
			name: "cd version number > 65535",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				CDVersionNumber:       65536,
				Pid:                   1,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       testconstants.SoftwareVersion,
			},
			err: validator.ErrFieldUpperBoundViolated,
		},
		{
			name: "certification date not set",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Pid:                   1,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     "",
				CertificationType:     testconstants.CertificationType,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
			err: validator.ErrRequiredFieldMissing,
		},
		{
			name: "certification type not set",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Pid:                   1,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     "",
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
			err: validator.ErrRequiredFieldMissing,
		},
		{
			name: "certification date is not RFC3339",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				Pid:                   1,
				Vid:                   1,
				SoftwareVersionString: testconstants.SoftwareVersionString,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC1123),
				CertificationType:     testconstants.TestResult,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
			err: ErrInvalidTestDateFormat,
		},
	}

	positive_tests := []struct {
		name string
		msg  MsgCertifyModel
	}{
		{
			name: "valid certification model msg",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				SoftwareVersionString: testconstants.SoftwareVersionString,
				Pid:                   1,
				Vid:                   1,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       testconstants.SoftwareVersion,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
		},
		{
			name: "software version = 0",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				SoftwareVersionString: testconstants.SoftwareVersionString,
				Pid:                   1,
				Vid:                   1,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       0,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
		},
		{
			name: "cd version number = 0",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				SoftwareVersionString: testconstants.SoftwareVersionString,
				Pid:                   1,
				Vid:                   1,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     testconstants.CertificationType,
				SoftwareVersion:       1,
				CDVersionNumber:       0,
			},
		},
		{
			name: "certification type is zigbee",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				SoftwareVersionString: testconstants.SoftwareVersionString,
				Pid:                   1,
				Vid:                   1,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     "zigbee",
				SoftwareVersion:       testconstants.SoftwareVersion,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
		},
		{
			name: "certification type is matter",
			msg: MsgCertifyModel{
				Signer:                sample.AccAddress(),
				SoftwareVersionString: testconstants.SoftwareVersionString,
				Pid:                   1,
				Vid:                   1,
				CertificationDate:     testconstants.CertificationDate.Format(time.RFC3339),
				CertificationType:     "matter",
				SoftwareVersion:       testconstants.SoftwareVersion,
				CDVersionNumber:       uint32(testconstants.CdVersionNumber),
			},
		},
	}

	for _, tt := range negative_tests {
		t.Run(tt.name, func(t *testing.T) {
			err := tt.msg.ValidateBasic()
			require.Error(t, err)
			require.ErrorIs(t, err, tt.err)
		})
	}

	for _, tt := range positive_tests {
		t.Run(tt.name, func(t *testing.T) {
			err := tt.msg.ValidateBasic()
			require.NoError(t, err)
		})
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lease

import (
	"fmt"
	"io"
	"log"
	"sync"
)

// Create a ReadLease that never expires, unless voluntarily revoked or
// upgraded.
//
// The supplied function will be used to obtain the read lease contents, the
// first time and whenever the supplied file leaser decides to expire the
// temporary copy thus obtained. It must return the same contents every time,
// and the contents must be of the given size.
//
// This magic is not preserved after the lease is upgraded.
func NewAutoRefreshingReadLease(
	fl FileLeaser,
	size int64,
	f func() (io.ReadCloser, error)) (rl ReadLease) {
	rl = &autoRefreshingReadLease{
		leaser: fl,
		size:   size,
		f:      f,
	}

	return
}

type autoRefreshingReadLease struct {
	mu sync.Mutex

	/////////////////////////
	// Constant data
	/////////////////////////

	size int64

	/////////////////////////
	// Dependencies
	/////////////////////////

	leaser FileLeaser
	f      func() (io.ReadCloser, error)

	/////////////////////////
	// Mutable state
	/////////////////////////

	// Set to true when we've been revoked for good.
	//
	// GUARDED_BY(mu)
	revoked bool

	// The current wrapped lease, or nil if one has never been issued.
	//
	// GUARDED_BY(mu)
	wrapped ReadLease
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// Attempt to clean up after the supplied read/write lease.
func destroyReadWriteLease(rwl ReadWriteLease) {
	var err error
	defer func() {
		if err != nil {
			log.Printf("Error destroying read/write lease: %v", err)
		}
	}()

	// Downgrade to a read lease.
	rl, err := rwl.Downgrade()
	if err != nil {
		err = fmt.Errorf("Downgrade: %v", err)
		return
	}

	// Revoke the read lease.
	rl.Revoke()
}

// Set up a read/write lease and fill in our contents.
//
// REQUIRES: The caller has observed that rl.lease has expired.
//
// LOCKS_REQUIRED(rl.mu)
func (rl *autoRefreshingReadLease) getContents() (
	rwl ReadWriteLease, err error) {
	// Obtain some space to write the contents.
	rwl, err = rl.leaser.NewFile()
	if err != nil {
		err = fmt.Errorf("NewFile: %v", err)
		return
	}

	// Attempt to clean up if we exit early.
	defer func() {
		if err != nil {
			destroyReadWriteLease(rwl)
		}
	}()

	// Obtain the reader for our contents.
	rc, err := rl.f()
	if err != nil {
		err = fmt.Errorf("User function: %v", err)
		return
	}

	defer func() {
		closeErr := rc.Close()
		if closeErr != nil && err == nil {
			err = fmt.Errorf("Close: %v", closeErr)
		}
	}()

	// Copy into the read/write lease.
	copied, err := io.Copy(rwl, rc)
	if err != nil {
		err = fmt.Errorf("Copy: %v", err)
		return
	}

	// Did the user lie about the size?
	if copied != rl.Size() {
		err = fmt.Errorf("Copied %v bytes; expected %v", copied, rl.Size())
		return
	}

	return
}

// Downgrade and save the supplied read/write lease obtained with getContents
// for later use.
//
// LOCKS_REQUIRED(rl.mu)
func (rl *autoRefreshingReadLease) saveContents(rwl ReadWriteLease) {
	downgraded, err := rwl.Downgrade()
	if err != nil {
		log.Printf("Failed to downgrade write lease (%q); abandoning.", err.Error())
		return
	}

	rl.wrapped = downgraded
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

func (rl *autoRefreshingReadLease) Read(p []byte) (n int, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Special case: have we been permanently revoked?
	if rl.revoked {
		err = &RevokedError{}
		return
	}

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	n, err = rwl.Read(p)

	return
}

func (rl *autoRefreshingReadLease) Seek(
	offset int64,
	whence int) (off int64, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Special case: have we been permanently revoked?
	if rl.revoked {
		err = &RevokedError{}
		return
	}

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	off, err = rwl.Seek(offset, whence)

	return
}

func (rl *autoRefreshingReadLease) ReadAt(
	p []byte,
	off int64) (n int, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Special case: have we been permanently revoked?
	if rl.revoked {
		err = &RevokedError{}
		return
	}

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	n, err = rwl.ReadAt(p, off)

	return
}

func (rl *autoRefreshingReadLease) Size() (size int64) {
	size = rl.size
	return
}

func (rl *autoRefreshingReadLease) Revoked() (revoked bool) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	revoked = rl.revoked
	return
}

func (rl *autoRefreshingReadLease) Upgrade() (rwl ReadWriteLease, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Special case: have we been permanently revoked?
	if rl.revoked {
		err = &RevokedError{}
		return
	}

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Build the read/write lease anew.
	rwl, err = rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	return
}

func (rl *autoRefreshingReadLease) Revoke() {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	rl.revoked = true
	if rl.wrapped != nil {
		rl.wrapped.Revoke()
	}
}
<commit_msg>Fixed a bug.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lease

import (
	"fmt"
	"io"
	"log"
	"sync"
)

// Create a ReadLease that never expires, unless voluntarily revoked or
// upgraded.
//
// The supplied function will be used to obtain the read lease contents, the
// first time and whenever the supplied file leaser decides to expire the
// temporary copy thus obtained. It must return the same contents every time,
// and the contents must be of the given size.
//
// This magic is not preserved after the lease is upgraded.
func NewAutoRefreshingReadLease(
	fl FileLeaser,
	size int64,
	f func() (io.ReadCloser, error)) (rl ReadLease) {
	rl = &autoRefreshingReadLease{
		leaser: fl,
		size:   size,
		f:      f,
	}

	return
}

type autoRefreshingReadLease struct {
	mu sync.Mutex

	/////////////////////////
	// Constant data
	/////////////////////////

	size int64

	/////////////////////////
	// Dependencies
	/////////////////////////

	leaser FileLeaser
	f      func() (io.ReadCloser, error)

	/////////////////////////
	// Mutable state
	/////////////////////////

	// Set to true when we've been revoked for good.
	//
	// GUARDED_BY(mu)
	revoked bool

	// The current wrapped lease, or nil if one has never been issued.
	//
	// GUARDED_BY(mu)
	wrapped ReadLease
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// Attempt to clean up after the supplied read/write lease.
func destroyReadWriteLease(rwl ReadWriteLease) {
	var err error
	defer func() {
		if err != nil {
			log.Printf("Error destroying read/write lease: %v", err)
		}
	}()

	// Downgrade to a read lease.
	rl, err := rwl.Downgrade()
	if err != nil {
		err = fmt.Errorf("Downgrade: %v", err)
		return
	}

	// Revoke the read lease.
	rl.Revoke()
}

// Set up a read/write lease and fill in our contents.
//
// REQUIRES: The caller has observed that rl.lease has expired.
//
// LOCKS_REQUIRED(rl.mu)
func (rl *autoRefreshingReadLease) getContents() (
	rwl ReadWriteLease, err error) {
	// Obtain some space to write the contents.
	rwl, err = rl.leaser.NewFile()
	if err != nil {
		err = fmt.Errorf("NewFile: %v", err)
		return
	}

	// Attempt to clean up if we exit early.
	defer func() {
		if err != nil {
			destroyReadWriteLease(rwl)
		}
	}()

	// Obtain the reader for our contents.
	rc, err := rl.f()
	if err != nil {
		err = fmt.Errorf("User function: %v", err)
		return
	}

	defer func() {
		closeErr := rc.Close()
		if closeErr != nil && err == nil {
			err = fmt.Errorf("Close: %v", closeErr)
		}
	}()

	// Copy into the read/write lease.
	copied, err := io.Copy(rwl, rc)
	if err != nil {
		err = fmt.Errorf("Copy: %v", err)
		return
	}

	// Did the user lie about the size?
	if copied != rl.Size() {
		err = fmt.Errorf("Copied %v bytes; expected %v", copied, rl.Size())
		return
	}

	return
}

// Downgrade and save the supplied read/write lease obtained with getContents
// for later use.
//
// LOCKS_REQUIRED(rl.mu)
func (rl *autoRefreshingReadLease) saveContents(rwl ReadWriteLease) {
	downgraded, err := rwl.Downgrade()
	if err != nil {
		log.Printf("Failed to downgrade write lease (%q); abandoning.", err.Error())
		return
	}

	rl.wrapped = downgraded
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

func (rl *autoRefreshingReadLease) Read(p []byte) (n int, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Special case: have we been permanently revoked?
	if rl.revoked {
		err = &RevokedError{}
		return
	}

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	n, err = rwl.Read(p)

	return
}

func (rl *autoRefreshingReadLease) Seek(
	offset int64,
	whence int) (off int64, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Special case: have we been permanently revoked?
	if rl.revoked {
		err = &RevokedError{}
		return
	}

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	off, err = rwl.Seek(offset, whence)

	return
}

func (rl *autoRefreshingReadLease) ReadAt(
	p []byte,
	off int64) (n int, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Special case: have we been permanently revoked?
	if rl.revoked {
		err = &RevokedError{}
		return
	}

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	n, err = rwl.ReadAt(p, off)

	return
}

func (rl *autoRefreshingReadLease) Size() (size int64) {
	size = rl.size
	return
}

func (rl *autoRefreshingReadLease) Revoked() (revoked bool) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	revoked = rl.revoked
	return
}

func (rl *autoRefreshingReadLease) Upgrade() (rwl ReadWriteLease, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Special case: have we been permanently revoked?
	if rl.revoked {
		err = &RevokedError{}
		return
	}

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Build the read/write lease anew.
	rwl, err = rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	// We are now revoked.
	rl.revoked = true

	return
}

func (rl *autoRefreshingReadLease) Revoke() {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	rl.revoked = true
	if rl.wrapped != nil {
		rl.wrapped.Revoke()
	}
}
<|endoftext|>


<commit_before>package main

import (
    "log"
    "github.com/trendrr/cheshire-golang/cheshire"
    "github.com/trendrr/cheshire-golang/cheshire/impl/gocache"

)

type DummyFilter struct {
    filterName string
}
func (this *DummyFilter) Before(*cheshire.Txn) bool {
    log.Printf("BEFORE! (%s) \n", this.filterName)
    return true
}
func (this *DummyFilter) After(*cheshire.Response, *cheshire.Txn) {
    log.Printf("AFTER! (%s) \n", this.filterName)
}

func main() {
    log.Println(cheshire.RandString(32))
    cache := gocache.New(10, 10)
    //create a couple dummy filters
    cache.Set("blah", []byte("balh"), 10)
    //this one will get executed on every request.
    globalFilter := &DummyFilter{"global"}
    //this one will only get executed on ping requests.
    pingFilter := &DummyFilter{"ping"}

    bootstrap := cheshire.NewBootstrapFile("example_config.yaml")

    bootstrap.AddFilters(globalFilter, cheshire.NewSession(cache, 3600))

    log.Println("HERE:1")
    //a ping controller api controller.
    pinger := func(txn *cheshire.Txn) {
        // log.Printf("PING! %s", request.Strest.Params)
        response := cheshire.NewResponse(txn)
        response.Put("data", "PONG")
        // log.Printf("Sending REsponse: %s", response.TxnId())
        txn.Write(response)
    }
    //now register the api call
    cheshire.RegisterApi("/ping", "GET", pinger, pingFilter)
    log.Println("HERE:1")

    //an example html page
    four04 := func(txn *cheshire.Txn) {
        context := make(map[string]interface{})
        context["message"] = "this is a 404 page"
        cheshire.Render(txn, "/404.html", context)
    }
    cheshire.RegisterHtml("/404", "GET", four04)

    //an example redirect page
    redirect := func(txn *cheshire.Txn) {
        cheshire.Redirect(txn, "/ping")
    }
    cheshire.RegisterHtml("/redirect", "GET", redirect)

    //an example of session usage
    sess := func(txn *cheshire.Txn) {
        log.Println(txn.Session)
        txn.Session.Put("mymessage", "this is my message")
        context := make(map[string]interface{})
        cheshire.Render(txn, "/index.html", context)
    }
    cheshire.RegisterHtml("/", "GET", sess)

    log.Println("Starting")
    //starts listening on all configured interfaces
    bootstrap.Start()
}
<commit_msg>clean up example<commit_after>package main

import (
    "log"
    "github.com/trendrr/cheshire-golang/cheshire"
    "github.com/trendrr/cheshire-golang/cheshire/impl/gocache"

)

type DummyFilter struct {
    filterName string
}
func (this *DummyFilter) Before(*cheshire.Txn) bool {
    log.Printf("BEFORE! (%s) \n", this.filterName)
    return true
}
func (this *DummyFilter) After(*cheshire.Response, *cheshire.Txn) {
    log.Printf("AFTER! (%s) \n", this.filterName)
}

func main() {
    log.Println(cheshire.RandString(32))

    //this one will get executed on every request.
    globalFilter := &DummyFilter{"global"}
    //this one will only get executed on ping requests.
    pingFilter := &DummyFilter{"ping"}

    bootstrap := cheshire.NewBootstrapFile("example_config.yaml")

    //Setup our cache.  this uses the local cache
    //you will need
    //github.com/pmylund/go-cache
    cache := gocache.New(10, 10)
    bootstrap.AddFilters(globalFilter, cheshire.NewSession(cache, 3600))

    log.Println("HERE:1")
    //a ping controller api controller.
    pinger := func(txn *cheshire.Txn) {
        // log.Printf("PING! %s", request.Strest.Params)
        response := cheshire.NewResponse(txn)
        response.Put("data", "PONG")
        // log.Printf("Sending REsponse: %s", response.TxnId())
        txn.Write(response)
    }
    //now register the api call
    cheshire.RegisterApi("/ping", "GET", pinger, pingFilter)
    log.Println("HERE:1")

    //an example html page
    four04 := func(txn *cheshire.Txn) {
        context := make(map[string]interface{})
        context["message"] = "this is a 404 page"
        cheshire.Render(txn, "/404.html", context)
    }
    cheshire.RegisterHtml("/404", "GET", four04)

    //an example redirect page
    redirect := func(txn *cheshire.Txn) {
        cheshire.Redirect(txn, "/ping")
    }
    cheshire.RegisterHtml("/redirect", "GET", redirect)

    //an example of session usage
    sess := func(txn *cheshire.Txn) {
        log.Println(txn.Session)
        txn.Session.Put("mymessage", "this is my message")
        context := make(map[string]interface{})
        cheshire.Render(txn, "/index.html", context)
    }
    cheshire.RegisterHtml("/", "GET", sess)

    log.Println("Starting")
    //starts listening on all configured interfaces
    bootstrap.Start()
}
<|endoftext|>


<commit_before>package protobuf

import (
	"encoding/hex"
	"fmt"
	"log"
)

func Example_MarshalUnmarshal() {
	type Embedded struct {
		Field1 string
		Field2 uint64
	}
	type MyStruct struct {
		Field1 uint32
		Field2 *Embedded
	}

	var v = &MyStruct{
		Field1: uint32(42),
		Field2: &Embedded{
			Field1: "field1",
			Field2: uint64(43),
		},
	}

	data := make([]byte, Size(v))
	if _, err := Marshal(data, v); err != nil {
		log.Fatal("marshal: %v", err)
	}

	fmt.Println(hex.EncodeToString(data))

	var x = &MyStruct{}
	if err := Unmarshal(data, x); err != nil {
		log.Fatalf("unmarshal %v", err)
	}

	fmt.Printf("%d %s %d\n", x.Field1, x.Field2.Field1, x.Field2.Field2)

	// Output:
	// 082a120a0a066669656c6431102b
	// 42 field1 43
}

func Example_TagMarshalUnmarshal() {
	type Embedded struct {
		Field1 string `protobuf:"bytes,required"`
		Field2 uint64 `protobuf:"varint,optional"`
	}
	type MyStruct struct {
		Field1 uint32    `protobuf:"varint,required"`
		Field2 uint32    `protobuf:"fixed32,required"`
		Field3 *Embedded `protobuf:"bytes:required"`
	}

	var v = &MyStruct{
		Field1: uint32(42),
		Field2: uint32(43),
		Field3: &Embedded{
			Field1: "field1",
			Field2: uint64(44),
		},
	}

	data := make([]byte, Size(v))
	if _, err := Marshal(data, v); err != nil {
		log.Fatal("marshal: %v", err)
	}

	fmt.Println(hex.EncodeToString(data))

	var x = &MyStruct{}
	if err := Unmarshal(data, x); err != nil {
		log.Fatalf("unmarshal %v", err)
	}

	fmt.Printf("%d %d %s %d\n", x.Field1, x.Field2, x.Field3.Field1, x.Field3.Field2)

	// Output:
	// 082a152b0000001a0a0a066669656c6431102c
	// 42 43 field1 44
}
<commit_msg>1419779488<commit_after>package protobuf

import (
	"encoding/hex"
	"fmt"
	"log"
)

func ExampleMarshal() {
	type Embedded struct {
		Field1 string
		Field2 uint64
	}
	type MyStruct struct {
		Field1 uint32
		Field2 *Embedded
	}

	var v = &MyStruct{
		Field1: uint32(42),
		Field2: &Embedded{
			Field1: "field1",
			Field2: uint64(43),
		},
	}

	data := make([]byte, Size(v))
	if _, err := Marshal(data, v); err != nil {
		log.Fatal("marshal: %v", err)
	}

	fmt.Println(hex.EncodeToString(data))

	// Output:
	// 082a120a0a066669656c6431102b
}

func ExampleUnmarshal() {
	type Embedded struct {
		Field1 string
		Field2 uint64
	}
	type MyStruct struct {
		Field1 uint32
		Field2 *Embedded
	}

	data, err := hex.DecodeString("082a120a0a066669656c6431102b")
	if err != nil {
		log.Fatal(err)
	}

	var v = &MyStruct{}
	if err := Unmarshal(data, v); err != nil {
		log.Fatalf("unmarshal %v", err)
	}

	fmt.Printf("%d %s %d\n", v.Field1, v.Field2.Field1, v.Field2.Field2)

	// Output:
	// 42 field1 43
}

func ExampleMarshal_tag() {
	type Embedded struct {
		Field1 string `protobuf:"bytes,required"`
		Field2 uint64 `protobuf:"varint,optional"`
	}
	type MyStruct struct {
		Field1 uint32    `protobuf:"varint,required"`
		Field2 uint32    `protobuf:"fixed32,required"`
		Field3 *Embedded `protobuf:"bytes:required"`
	}

	var v = &MyStruct{
		Field1: uint32(42),
		Field2: uint32(43),
		Field3: &Embedded{
			Field1: "field1",
			Field2: uint64(44),
		},
	}

	data := make([]byte, Size(v))
	if _, err := Marshal(data, v); err != nil {
		log.Fatal("marshal: %v", err)
	}

	fmt.Println(hex.EncodeToString(data))

	// Output:
	// 082a152b0000001a0a0a066669656c6431102c
}
<|endoftext|>


<commit_before>package async_test

import (
	"fmt"
	"time"

	"github.com/egonelbre/async"
)

func ExampleAll() {
	fmt.Println("=== succeeding case ===")
	result := async.All(
		func() error {
			time.Sleep(100 * time.Millisecond)
			return nil
		},
		func() error {
			time.Sleep(200 * time.Millisecond)
			return nil
		},
	)

	select {
	case err := <-result.Error:
		fmt.Printf("Got an error: %v\n", err)
	case <-result.Done:
		fmt.Printf("Success\n")
	}

	fmt.Println("=== failing case ===")
	result = async.All(
		func() error {
			time.Sleep(100 * time.Millisecond)
			return nil
		},
		func() error {
			time.Sleep(200 * time.Millisecond)
			return fmt.Errorf("CRASH")
		},
	)

	select {
	case err := <-result.Error:
		fmt.Printf("Got an error: %v\n", err)
	case <-result.Done:
		fmt.Printf("Success\n")
	}

	fmt.Println("=== handling all errors ===")
	result = async.All(
		func() error {
			return fmt.Errorf("SPLASH")
		},
		func() error {
			return fmt.Errorf("CRASH")
		},
	)

	for err := range result.Error {
		fmt.Printf("Got an error: %v\n", err)
	}
}

func ExampleSpawn() {
	work := make(chan int, 3)
	done := make(chan int, 3)

	async.Spawn(3, func(id int) {
		for v := range work {
			done <- v * v
		}
	}, func() {
		close(done)
	})

	for i := 0; i < 5; i += 1 {
		work <- i
	}
	close(work)

	for r := range done {
		println(r)
	}
}
<commit_msg>Single function per example.<commit_after>package async_test

import (
	"fmt"
	"time"

	"github.com/egonelbre/async"
)

func ExampleAll_Success() {
	result := async.All(
		func() error {
			time.Sleep(100 * time.Millisecond)
			return nil
		},
		func() error {
			time.Sleep(200 * time.Millisecond)
			return nil
		},
	)

	select {
	case err := <-result.Error:
		fmt.Printf("Got an error: %v\n", err)
	case <-result.Done:
		fmt.Printf("Success\n")
	}
}

func ExampleAll_Failing() {
	result = async.All(
		func() error {
			time.Sleep(100 * time.Millisecond)
			return nil
		},
		func() error {
			time.Sleep(200 * time.Millisecond)
			return fmt.Errorf("CRASH")
		},
	)

	select {
	case err := <-result.Error:
		fmt.Printf("Got an error: %v\n", err)
	case <-result.Done:
		fmt.Printf("Success\n")
	}
}

func ExampleAll_HandleAllErrors() {
	result = async.All(
		func() error {
			return fmt.Errorf("SPLASH")
		},
		func() error {
			return fmt.Errorf("CRASH")
		},
	)

	for err := range result.Error {
		fmt.Printf("Got an error: %v\n", err)
	}
}

func ExampleSpawn() {
	work := make(chan int, 3)
	done := make(chan int, 3)

	async.Spawn(3, func(id int) {
		for v := range work {
			done <- v * v
		}
	}, func() {
		close(done)
	})

	for i := 0; i < 5; i += 1 {
		work <- i
	}
	close(work)

	for r := range done {
		println(r)
	}
}
<|endoftext|>


<commit_before>package sparse

import (
	"fmt"

	"gonum.org/v1/gonum/mat"
)

func Example() {
	// Construct a new DOK (Dictionary Of Keys) matrix
	dokMatrix := NewDOK(3, 2)

	// Populate it with some non-zero values
	dokMatrix.Set(0, 0, 5)
	dokMatrix.Set(2, 1, 7)

	// Demonstrate accessing values (could use mat.Formatted() to
	// pretty print but this demonstrates element access)
	m, n := dokMatrix.Dims()
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			fmt.Printf("%.0f", dokMatrix.At(i, j))
			if j < n-1 {
				fmt.Printf(" ")
			}
		}
		fmt.Printf("\n")
	}

	// Convert DOK matrix to mat.Dense just for fun
	// (not required for upcoming multiplication operation)
	denseMatrix := dokMatrix.ToDense()

	// Confirm the two matrices in different formats are equal
	// Using the mat.Equal function
	if !mat.Equal(dokMatrix, denseMatrix) {
		fmt.Println("DOK and converted Dense are not equal")
	}

	// Create a random 2x3 CSR (Compressed Sparse Row) matrix with
	// density of 0.5 (half the elements will be non-zero)
	csrMatrix := Random(CSRFormat, 2, 3, 0.5)

	// Create a new CSR (Compressed Sparse Row) matrix
	csrProduct := &CSR{}

	// Multiply the 2 matrices together and store the result in the
	// receiver
	csrProduct.Mul(csrMatrix, denseMatrix)

	// Output: 5 0
	//0 0
	//0 7
}
<commit_msg>changed declaration of CSR matrix in example<commit_after>package sparse

import (
	"fmt"

	"gonum.org/v1/gonum/mat"
)

func Example() {
	// Construct a new DOK (Dictionary Of Keys) matrix
	dokMatrix := NewDOK(3, 2)

	// Populate it with some non-zero values
	dokMatrix.Set(0, 0, 5)
	dokMatrix.Set(2, 1, 7)

	// Demonstrate accessing values (could use mat.Formatted() to
	// pretty print but this demonstrates element access)
	m, n := dokMatrix.Dims()
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			fmt.Printf("%.0f", dokMatrix.At(i, j))
			if j < n-1 {
				fmt.Printf(" ")
			}
		}
		fmt.Printf("\n")
	}

	// Convert DOK matrix to mat.Dense just for fun
	// (not required for upcoming multiplication operation)
	denseMatrix := dokMatrix.ToDense()

	// Confirm the two matrices in different formats are equal
	// Using the mat.Equal function
	if !mat.Equal(dokMatrix, denseMatrix) {
		fmt.Println("DOK and converted Dense are not equal")
	}

	// Create a random 2x3 CSR (Compressed Sparse Row) matrix with
	// density of 0.5 (half the elements will be non-zero)
	csrMatrix := Random(CSRFormat, 2, 3, 0.5)

	// Create a new CSR (Compressed Sparse Row) matrix
	var csrProduct CSR

	// Multiply the 2 matrices together and store the result in the
	// receiver
	csrProduct.Mul(csrMatrix, denseMatrix)

	// Output: 5 0
	//0 0
	//0 7
}
<|endoftext|>


<commit_before>package hll

import (
	"crypto/sha1"
	"encoding/binary"
	"fmt"
	"strconv"
)

func Example() {
	const (
		p           = 14 // Max memory usage is 2^p bytes
		pPrime      = 25 // Setting this is a bit more complicated, Google recommends 25.
		numToInsert = 1000000
	)

	// You can use any hash function that you want. Here we use SHA1 then extract 8 bytes as uint64.
	hashU64 := func(s string) uint64 {
		sha1Hash := sha1.Sum([]byte(s))
		return binary.LittleEndian.Uint64(sha1Hash[0:8])
	}

	hll := NewHll(p, pPrime)

	// For this example, our inputs will just be strings, e.g. "1", "2"
	for i := 0; i < numToInsert; i++ {
		inputString := strconv.Itoa(i)

		// To use HLL, you hash your item, convert the hash to uint64, and pass it to Add().
		hll.Add(hashU64(inputString))
	}

	// Duplicates do not affect the cardinality. The following loop has no effect.
	for i := 0; i < 10000; i++ {
		hll.Add(hashU64("1"))
	}

	// We inserted 1M unique elements, the cardinality should be roughly 1M.
	fmt.Printf("%d\n", hll.Cardinality())
	// Output: 989546
}
<commit_msg>Correct memory bound in comment in example<commit_after>package hll

import (
	"crypto/sha1"
	"encoding/binary"
	"fmt"
	"strconv"
)

func Example() {
	const (
		p           = 14 // Max memory usage is 0.75 * 2^p bytes
		pPrime      = 25 // Setting this is a bit more complicated, Google recommends 25.
		numToInsert = 1000000
	)

	// You can use any hash function that you want. Here we use SHA1 then extract 8 bytes as uint64.
	hashU64 := func(s string) uint64 {
		sha1Hash := sha1.Sum([]byte(s))
		return binary.LittleEndian.Uint64(sha1Hash[0:8])
	}

	hll := NewHll(p, pPrime)

	// For this example, our inputs will just be strings, e.g. "1", "2"
	for i := 0; i < numToInsert; i++ {
		inputString := strconv.Itoa(i)

		// To use HLL, you hash your item, convert the hash to uint64, and pass it to Add().
		hll.Add(hashU64(inputString))
	}

	// Duplicates do not affect the cardinality. The following loop has no effect.
	for i := 0; i < 10000; i++ {
		hll.Add(hashU64("1"))
	}

	// We inserted 1M unique elements, the cardinality should be roughly 1M.
	fmt.Printf("%d\n", hll.Cardinality())
	// Output: 989546
}
<|endoftext|>


<commit_before>// Copyright 2016 Swen Gorschewski. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package kallisto_test

import "gitlab.com/swen/kallisto"

func ExampleSimpleServer() {
	// create a kallisto mux
	k := kallisto.New()

	// register a route for a HTTP GET request
	// the first parameter represents the request url,
	// the second parameter is an internal name for the route,
	// and the last parameter is a controller function that will be called
	// if a request for this route comes in.
	k.GET("/", "index", func(ctx *kallisto.Context, res *kallisto.Response) {
		res.Text("Hello world!")
	})

	// starts a webserver listening for requests to localhost on port 8080
	k.ListenAndServe("localhost:8080")
}
<commit_msg>fixed function name<commit_after>// Copyright 2016 Swen Gorschewski. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package kallisto_test

import "github.com/swengorschewski/kallisto"

func Example() {
	// create a kallisto mux
	k := kallisto.New()

	// register a route for a HTTP GET request
	// the first parameter represents the request url,
	// the second parameter is an internal name for the route,
	// and the last parameter is a controller function that will be called
	// if a request for this route comes in.
	k.GET("/", "index", func(ctx *kallisto.Context, res *kallisto.Response) {
		res.Text("Hello world!")
	})

	// starts a webserver listening for requests to localhost on port 8080
	k.ListenAndServe("localhost:8080")
}
<|endoftext|>


<commit_before>package geohash_test

import (
	"fmt"

	"github.com/mmcloughlin/geohash"
)

func ExampleEncode() {
	fmt.Println(geohash.Encode(48.858, 2.294))
	// Output: u09tunq6qp66
}
<commit_msg>More examples for encode functions<commit_after>package geohash_test

import (
	"fmt"

	"github.com/mmcloughlin/geohash"
)

func ExampleEncode() {
	fmt.Println(geohash.Encode(48.858, 2.294))
	// Output: u09tunq6qp66
}

func ExampleEncodeInt() {
	fmt.Printf("%016x\n", geohash.EncodeInt(48.858, 2.294))
	// Output: d0139d52c6b54c69
}

func ExampleEncodeIntWithPrecision() {
	fmt.Printf("%08x\n", geohash.EncodeIntWithPrecision(48.858, 2.294, 32))
	// Output: d0139d52
}

func ExampleEncodeWithPrecision() {
	fmt.Println(geohash.EncodeWithPrecision(48.858, 2.294, 5))
	// Output: u09tu
}
<|endoftext|>


<commit_before>package shttp_test

import (
	"log"
	"net/http"

	"github.com/apriendeau/shttp"
)

func ExampleWrite() {
	handler := func(w http.ResponseWriter, r *http.Request) {
		body := make(map[string]string)
		if err := shttp.Read(r, &body); err != nil {
			if err := shttp.Error(w, r, err, 422); err != nil {
				log.Panic(err)
			}
		}

		message := struct {
			Message  string            `json:"message"`
			Received map[string]string `json:"received"`
		}{"I received your information.", body}

		if err := shttp.Write(w, r, message, 200); err != nil {
			log.Panic(err)
		}
	}
	mux := http.NewServeMux()
	mux.HandleFunc("/post", handler)
	if err := http.ListenAndServe(":8000", mux); err != nil {
		log.Panic(err)
	}
}
<commit_msg>adds example to godoc<commit_after>package shttp_test

import (
	"log"
	"net/http"

	"github.com/apriendeau/shttp"
)

func ExampleReadAndWrite() {
	handler := func(w http.ResponseWriter, r *http.Request) {
		body := make(map[string]string)
		if err := shttp.Read(r, &body); err != nil {
			if err := shttp.Error(w, r, err, 422); err != nil {
				log.Panic(err)
			}
		}

		message := struct {
			Message  string            `json:"message"`
			Received map[string]string `json:"received"`
		}{"I received your information.", body}

		if err := shttp.Write(w, r, message, 200); err != nil {
			log.Panic(err)
		}
	}
	mux := http.NewServeMux()
	mux.HandleFunc("/post", handler)
	if err := http.ListenAndServe(":8000", mux); err != nil {
		log.Panic(err)
	}
}
<|endoftext|>


<commit_before>/*Package eventual is a simple event dispatcher for golang base on channels.
The goal is to pass data arond, without depending to any package except for this
one.

There is some definition :

- Mandatory means publish is not finished unless all subscribers receive the message,
in this case, the receiver must always read the channel. TODO : a way to unsub
- Exclusive means there is only and only one receiver for a topic is available

    package main

    import "github.com/fzerorubigd/eventual"

    func main() {
        e := &eventual.Eventual{}
        // Create a no mandatory, no exclusive topic
        t ,_ := e.Register("the.topic.name", false, false)
        c1 := t.Sub()

        // In any other part of code, even in another package you can create
        // an exactly same topic with exactly same parameter
        t ,_ := e.Register("the.topic.name", false, false)
        t.Pub(SomeIEventStructure{}) // No there is a data in c1, but if there is no reader the data is lost
    }

## TODO

- Support for buffer size (aka pre fetch)

- Support for reply back

*/
package eventual

import (
	"fmt"
	"sync"
)

// IEvent is an interface to handle one instance of an event in system.
// each IEvent must contain the topic and data that passed to this event
type IEvent interface {
	// Data is the event data that publisherdecide the type of it
	Data() interface{}
}

// Publisher is an interface for publishing event in a system
type Publisher interface {
	// Pub is for publishing an event. it's panic prof
	Pub(IEvent)
}

// Subscriber is an interface to handle subscribers
type Subscriber interface {
	// Sub is for getting an channel to read the events from it.
	// if the event is exclusive, and there is a subscriber, then
	// it panic.
	Sub() <-chan IEvent
}

// Event is the actual event, must register to get one of this.
type Event interface {
	Publisher
	Subscriber

	// GetTopic return the current topic
	GetTopic() string
	// IsMandatory return if this event is mandatory or not , mandatory means
	IsMandatory() bool
	// IsExclusive return if this event is exclusive and there is only one subscriber
	// is allowed
	IsExclusive() bool
	// // GetTimeout return the timeout for this even. if the timeout is equal or less
	// // than zero, there is no wait, if not the event wait this duration for the
	// // subscriber to pick.
	// GetTimeout() time.Duration
}

// Eventual is an event bus
type Eventual interface {
	Register(topic string, mandatory, exclusive bool) (Event, error)
}

type eventInstance struct {
	topic     string
	mandatory bool
	exclusive bool
	subs      []chan IEvent

	lock sync.Mutex
}

type eventualInstance struct {
	list map[string]Event
	lock sync.Mutex
}

func (e *eventInstance) Pub(ei IEvent) {
	wg := sync.WaitGroup{}
	wg.Add(len(e.subs))
	for i := range e.subs {
		go func(c chan IEvent) {
			defer wg.Done()
			if e.mandatory {
				c <- ei
			} else {
				select {
				case c <- ei:
				default:
				}
			}
		}(e.subs[i])
	}
	// In mandatory, its blocked until all data are recieved
	wg.Wait()
}

// Sub implementation of the Subscriber interface
func (e *eventInstance) Sub() <-chan IEvent {
	e.lock.Lock()
	defer e.lock.Unlock()

	if e.IsExclusive() && len(e.subs) > 0 {
		panic(fmt.Errorf("this is a exclusive event, and there is already a subscriber available"))
	}
	res := make(chan IEvent)
	e.subs = append(e.subs, res)

	return res
}

func (e *eventInstance) IsMandatory() bool {
	return e.mandatory
}

func (e *eventInstance) IsExclusive() bool {
	return e.exclusive
}

func (e *eventInstance) GetTopic() string {
	return e.topic
}

// Register and event in system, the topic is the event topic, mandatory means
// if the event is hanged until the subscriber gets it. exclusive means the event
// can only and only one subscriber.
// The parameters must be exactly same when calling this several times for a topic
// unless yo get an error.
func (e *eventualInstance) Register(topic string, mandatory, exclusive bool) (Event, error) {
	e.lock.Lock()
	defer e.lock.Unlock()
	event, ok := e.list[topic]
	if ok {
		if event.IsMandatory() != mandatory || event.IsExclusive() != exclusive {
			err := fmt.Errorf(
				"the topic mandatory is %t exclusive is %t, requested topic is respectively %t and %t",
				event.IsMandatory(),
				event.IsExclusive(),
				mandatory,
				exclusive,
			)
			return nil, err
		}
	} else {
		event = &eventInstance{topic, mandatory, exclusive, nil, sync.Mutex{}}
		e.list[topic] = event
	}

	return event, nil
}

// New return an eventual structure
func New() Eventual {
	return &eventualInstance{make(map[string]Event), sync.Mutex{}}
}
<commit_msg>finally no race (I hope)<commit_after>/*Package eventual is a simple event dispatcher for golang base on channels.
The goal is to pass data arond, without depending to any package except for this
one.

There is some definition :

- Mandatory means publish is not finished unless all subscribers receive the message,
in this case, the receiver must always read the channel. TODO : a way to unsub
- Exclusive means there is only and only one receiver for a topic is available

    package main

    import "github.com/fzerorubigd/eventual"

    func main() {
        e := &eventual.Eventual{}
        // Create a no mandatory, no exclusive topic
        t ,_ := e.Register("the.topic.name", false, false)
        c1 := t.Sub()

        // In any other part of code, even in another package you can create
        // an exactly same topic with exactly same parameter
        t ,_ := e.Register("the.topic.name", false, false)
        t.Pub(SomeIEventStructure{}) // No there is a data in c1, but if there is no reader the data is lost
    }

## TODO

- Support for buffer size (aka pre fetch)

- Support for reply back

*/
package eventual

import (
	"fmt"
	"sync"
)

// IEvent is an interface to handle one instance of an event in system.
// each IEvent must contain the topic and data that passed to this event
type IEvent interface {
	// Data is the event data that publisherdecide the type of it
	Data() interface{}
}

// Publisher is an interface for publishing event in a system
type Publisher interface {
	// Pub is for publishing an event. it's panic prof
	Pub(IEvent)
}

// Subscriber is an interface to handle subscribers
type Subscriber interface {
	// Sub is for getting an channel to read the events from it.
	// if the event is exclusive, and there is a subscriber, then
	// it panic.
	Sub() <-chan IEvent
}

// Event is the actual event, must register to get one of this.
type Event interface {
	Publisher
	Subscriber

	// GetTopic return the current topic
	GetTopic() string
	// IsMandatory return if this event is mandatory or not , mandatory means
	IsMandatory() bool
	// IsExclusive return if this event is exclusive and there is only one subscriber
	// is allowed
	IsExclusive() bool
	// // GetTimeout return the timeout for this even. if the timeout is equal or less
	// // than zero, there is no wait, if not the event wait this duration for the
	// // subscriber to pick.
	// GetTimeout() time.Duration
}

// Eventual is an event bus
type Eventual interface {
	Register(topic string, mandatory, exclusive bool) (Event, error)
}

type eventInstance struct {
	topic     string
	mandatory bool
	exclusive bool
	subs      []chan IEvent

	lock *sync.RWMutex
}

type eventualInstance struct {
	list map[string]Event
	lock *sync.Mutex
}

func (e *eventInstance) Pub(ei IEvent) {
	if e.mandatory {
		e.pubMandatory(ei)
	} else {
		e.pubNormal(ei)
	}
}

func (e *eventInstance) pubMandatory(ei IEvent) {
	wg := sync.WaitGroup{}

	wg.Add(len(e.subs))
	for i := range e.subs {
		go func(c chan IEvent) {
			e.lock.RLock()
			defer e.lock.RUnlock()
			defer wg.Done()
			c <- ei
		}(e.subs[i])
	}
	// In mandatory, its blocked until all data are recieved
	wg.Wait()
}

func (e *eventInstance) pubNormal(ei IEvent) {
	e.lock.RLock()
	defer e.lock.RUnlock()

	for i := range e.subs {
		select {
		case e.subs[i] <- ei:
		default:
		}
	}
}

// Sub implementation of the Subscriber interface
func (e *eventInstance) Sub() <-chan IEvent {
	e.lock.Lock()
	defer e.lock.Unlock()

	if e.IsExclusive() && len(e.subs) > 0 {
		panic(fmt.Errorf("this is a exclusive event, and there is already a subscriber available"))
	}
	res := make(chan IEvent)
	e.subs = append(e.subs, res)

	return res
}

func (e *eventInstance) IsMandatory() bool {
	return e.mandatory
}

func (e *eventInstance) IsExclusive() bool {
	return e.exclusive
}

func (e *eventInstance) GetTopic() string {
	return e.topic
}

// Register and event in system, the topic is the event topic, mandatory means
// if the event is hanged until the subscriber gets it. exclusive means the event
// can only and only one subscriber.
// The parameters must be exactly same when calling this several times for a topic
// unless yo get an error.
func (e *eventualInstance) Register(topic string, mandatory, exclusive bool) (Event, error) {
	e.lock.Lock()
	defer e.lock.Unlock()

	event, ok := e.list[topic]
	if ok {
		if event.IsMandatory() != mandatory || event.IsExclusive() != exclusive {
			err := fmt.Errorf(
				"the topic mandatory is %t exclusive is %t, requested topic is respectively %t and %t",
				event.IsMandatory(),
				event.IsExclusive(),
				mandatory,
				exclusive,
			)
			return nil, err
		}
	} else {
		event = &eventInstance{topic, mandatory, exclusive, nil, &sync.RWMutex{}}
		e.list[topic] = event
	}

	return event, nil
}

// New return an eventual structure
func New() Eventual {
	return &eventualInstance{make(map[string]Event), &sync.Mutex{}}
}
<|endoftext|>


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

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

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

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

package kubectl

import (
	"fmt"
	"strconv"
	"time"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/errors"
	"k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/apis/batch"
	"k8s.io/kubernetes/pkg/apis/extensions"
	client "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/util/wait"
)

// Scaler provides an interface for resources that can be scaled.
type Scaler interface {
	// Scale scales the named resource after checking preconditions. It optionally
	// retries in the event of resource version mismatch (if retry is not nil),
	// and optionally waits until the status of the resource matches newSize (if wait is not nil)
	Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, wait *RetryParams) error
	// ScaleSimple does a simple one-shot attempt at scaling - not useful on it's own, but
	// a necessary building block for Scale
	ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error
}

func ScalerFor(kind unversioned.GroupKind, c client.Interface) (Scaler, error) {
	switch kind {
	case api.Kind("ReplicationController"):
		return &ReplicationControllerScaler{c}, nil
	case extensions.Kind("ReplicaSet"):
		return &ReplicaSetScaler{c.Extensions()}, nil
	case extensions.Kind("Job"), batch.Kind("Job"):
		return &JobScaler{c.Batch()}, nil // Either kind of job can be scaled with Batch interface.
	case extensions.Kind("Deployment"):
		return &DeploymentScaler{c.Extensions()}, nil
	}
	return nil, fmt.Errorf("no scaler has been implemented for %q", kind)
}

// ScalePrecondition describes a condition that must be true for the scale to take place
// If CurrentSize == -1, it is ignored.
// If CurrentResourceVersion is the empty string, it is ignored.
// Otherwise they must equal the values in the resource for it to be valid.
type ScalePrecondition struct {
	Size            int
	ResourceVersion string
}

// A PreconditionError is returned when a resource fails to match
// the scale preconditions passed to kubectl.
type PreconditionError struct {
	Precondition  string
	ExpectedValue string
	ActualValue   string
}

func (pe PreconditionError) Error() string {
	return fmt.Sprintf("Expected %s to be %s, was %s", pe.Precondition, pe.ExpectedValue, pe.ActualValue)
}

type ScaleErrorType int

const (
	ScaleGetFailure ScaleErrorType = iota
	ScaleUpdateFailure
	ScaleUpdateConflictFailure
)

// A ScaleError is returned when a scale request passes
// preconditions but fails to actually scale the controller.
type ScaleError struct {
	FailureType     ScaleErrorType
	ResourceVersion string
	ActualError     error
}

func (c ScaleError) Error() string {
	return fmt.Sprintf(
		"Scaling the resource failed with: %v; Current resource version %s",
		c.ActualError, c.ResourceVersion)
}

// RetryParams encapsulates the retry parameters used by kubectl's scaler.
type RetryParams struct {
	Interval, Timeout time.Duration
}

func NewRetryParams(interval, timeout time.Duration) *RetryParams {
	return &RetryParams{interval, timeout}
}

// ScaleCondition is a closure around Scale that facilitates retries via util.wait
func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name string, count uint) wait.ConditionFunc {
	return func() (bool, error) {
		err := r.ScaleSimple(namespace, name, precondition, count)
		switch e, _ := err.(ScaleError); err.(type) {
		case nil:
			return true, nil
		case ScaleError:
			// Retry only on update conflicts.
			if e.FailureType == ScaleUpdateConflictFailure {
				return false, nil
			}
		}
		return false, err
	}
}

// ValidateReplicationController ensures that the preconditions match.  Returns nil if they are valid, an error otherwise
func (precondition *ScalePrecondition) ValidateReplicationController(controller *api.ReplicationController) error {
	if precondition.Size != -1 && int(controller.Spec.Replicas) != precondition.Size {
		return PreconditionError{"replicas", strconv.Itoa(precondition.Size), strconv.Itoa(int(controller.Spec.Replicas))}
	}
	if len(precondition.ResourceVersion) != 0 && controller.ResourceVersion != precondition.ResourceVersion {
		return PreconditionError{"resource version", precondition.ResourceVersion, controller.ResourceVersion}
	}
	return nil
}

type ReplicationControllerScaler struct {
	c client.Interface
}

func (scaler *ReplicationControllerScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error {
	controller, err := scaler.c.ReplicationControllers(namespace).Get(name)
	if err != nil {
		return ScaleError{ScaleGetFailure, "Unknown", err}
	}
	if preconditions != nil {
		if err := preconditions.ValidateReplicationController(controller); err != nil {
			return err
		}
	}
	controller.Spec.Replicas = int32(newSize)
	if _, err := scaler.c.ReplicationControllers(namespace).Update(controller); err != nil {
		if errors.IsConflict(err) {
			return ScaleError{ScaleUpdateConflictFailure, controller.ResourceVersion, err}
		}
		return ScaleError{ScaleUpdateFailure, controller.ResourceVersion, err}
	}
	return nil
}

// Scale updates a ReplicationController to a new size, with optional precondition check (if preconditions is not nil),
// optional retries (if retry is not nil), and then optionally waits for it's replica count to reach the new value
// (if wait is not nil).
func (scaler *ReplicationControllerScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
	if preconditions == nil {
		preconditions = &ScalePrecondition{-1, ""}
	}
	if retry == nil {
		// Make it try only once, immediately
		retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
	}
	cond := ScaleCondition(scaler, preconditions, namespace, name, newSize)
	if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
		return err
	}
	if waitForReplicas != nil {
		rc, err := scaler.c.ReplicationControllers(namespace).Get(name)
		if err != nil {
			return err
		}
		return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
			client.ControllerHasDesiredReplicas(scaler.c, rc))
	}
	return nil
}

// ValidateReplicaSet ensures that the preconditions match.  Returns nil if they are valid, an error otherwise
func (precondition *ScalePrecondition) ValidateReplicaSet(replicaSet *extensions.ReplicaSet) error {
	if precondition.Size != -1 && int(replicaSet.Spec.Replicas) != precondition.Size {
		return PreconditionError{"replicas", strconv.Itoa(precondition.Size), strconv.Itoa(int(replicaSet.Spec.Replicas))}
	}
	if len(precondition.ResourceVersion) != 0 && replicaSet.ResourceVersion != precondition.ResourceVersion {
		return PreconditionError{"resource version", precondition.ResourceVersion, replicaSet.ResourceVersion}
	}
	return nil
}

type ReplicaSetScaler struct {
	c client.ExtensionsInterface
}

func (scaler *ReplicaSetScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error {
	rs, err := scaler.c.ReplicaSets(namespace).Get(name)
	if err != nil {
		return ScaleError{ScaleGetFailure, "Unknown", err}
	}
	if preconditions != nil {
		if err := preconditions.ValidateReplicaSet(rs); err != nil {
			return err
		}
	}
	rs.Spec.Replicas = int32(newSize)
	if _, err := scaler.c.ReplicaSets(namespace).Update(rs); err != nil {
		if errors.IsConflict(err) {
			return ScaleError{ScaleUpdateConflictFailure, rs.ResourceVersion, err}
		}
		return ScaleError{ScaleUpdateFailure, rs.ResourceVersion, err}
	}
	return nil
}

// Scale updates a ReplicaSet to a new size, with optional precondition check (if preconditions is
// not nil), optional retries (if retry is not nil), and then optionally waits for it's replica
// count to reach the new value (if wait is not nil).
func (scaler *ReplicaSetScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
	if preconditions == nil {
		preconditions = &ScalePrecondition{-1, ""}
	}
	if retry == nil {
		// Make it try only once, immediately
		retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
	}
	cond := ScaleCondition(scaler, preconditions, namespace, name, newSize)
	if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
		return err
	}
	if waitForReplicas != nil {
		rs, err := scaler.c.ReplicaSets(namespace).Get(name)
		if err != nil {
			return err
		}
		return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
			client.ReplicaSetHasDesiredReplicas(scaler.c, rs))
	}
	return nil
}

// ValidateJob ensures that the preconditions match.  Returns nil if they are valid, an error otherwise.
func (precondition *ScalePrecondition) ValidateJob(job *batch.Job) error {
	if precondition.Size != -1 && job.Spec.Parallelism == nil {
		return PreconditionError{"parallelism", strconv.Itoa(precondition.Size), "nil"}
	}
	if precondition.Size != -1 && int(*job.Spec.Parallelism) != precondition.Size {
		return PreconditionError{"parallelism", strconv.Itoa(precondition.Size), strconv.Itoa(int(*job.Spec.Parallelism))}
	}
	if len(precondition.ResourceVersion) != 0 && job.ResourceVersion != precondition.ResourceVersion {
		return PreconditionError{"resource version", precondition.ResourceVersion, job.ResourceVersion}
	}
	return nil
}

type JobScaler struct {
	c client.BatchInterface
}

// ScaleSimple is responsible for updating job's parallelism.
func (scaler *JobScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error {
	job, err := scaler.c.Jobs(namespace).Get(name)
	if err != nil {
		return ScaleError{ScaleGetFailure, "Unknown", err}
	}
	if preconditions != nil {
		if err := preconditions.ValidateJob(job); err != nil {
			return err
		}
	}
	parallelism := int32(newSize)
	job.Spec.Parallelism = &parallelism
	if _, err := scaler.c.Jobs(namespace).Update(job); err != nil {
		if errors.IsConflict(err) {
			return ScaleError{ScaleUpdateConflictFailure, job.ResourceVersion, err}
		}
		return ScaleError{ScaleUpdateFailure, job.ResourceVersion, err}
	}
	return nil
}

// Scale updates a Job to a new size, with optional precondition check (if preconditions is not nil),
// optional retries (if retry is not nil), and then optionally waits for parallelism to reach desired
// number, which can be less than requested based on job's current progress.
func (scaler *JobScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
	if preconditions == nil {
		preconditions = &ScalePrecondition{-1, ""}
	}
	if retry == nil {
		// Make it try only once, immediately
		retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
	}
	cond := ScaleCondition(scaler, preconditions, namespace, name, newSize)
	if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
		return err
	}
	if waitForReplicas != nil {
		job, err := scaler.c.Jobs(namespace).Get(name)
		if err != nil {
			return err
		}
		return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
			client.JobHasDesiredParallelism(scaler.c, job))
	}
	return nil
}

// ValidateDeployment ensures that the preconditions match.  Returns nil if they are valid, an error otherwise.
func (precondition *ScalePrecondition) ValidateDeployment(deployment *extensions.Deployment) error {
	if precondition.Size != -1 && int(deployment.Spec.Replicas) != precondition.Size {
		return PreconditionError{"replicas", strconv.Itoa(precondition.Size), strconv.Itoa(int(deployment.Spec.Replicas))}
	}
	if len(precondition.ResourceVersion) != 0 && deployment.ResourceVersion != precondition.ResourceVersion {
		return PreconditionError{"resource version", precondition.ResourceVersion, deployment.ResourceVersion}
	}
	return nil
}

type DeploymentScaler struct {
	c client.ExtensionsInterface
}

// ScaleSimple is responsible for updating a deployment's desired replicas count.
func (scaler *DeploymentScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error {
	deployment, err := scaler.c.Deployments(namespace).Get(name)
	if err != nil {
		return ScaleError{ScaleGetFailure, "Unknown", err}
	}
	if preconditions != nil {
		if err := preconditions.ValidateDeployment(deployment); err != nil {
			return err
		}
	}

	// TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528).
	// For now I'm falling back to regular Deployment update operation.
	deployment.Spec.Replicas = int32(newSize)
	if _, err := scaler.c.Deployments(namespace).Update(deployment); err != nil {
		if errors.IsConflict(err) {
			return ScaleError{ScaleUpdateConflictFailure, deployment.ResourceVersion, err}
		}
		return ScaleError{ScaleUpdateFailure, deployment.ResourceVersion, err}
	}
	return nil
}

// Scale updates a deployment to a new size, with optional precondition check (if preconditions is not nil),
// optional retries (if retry is not nil), and then optionally waits for the status to reach desired count.
func (scaler *DeploymentScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
	if preconditions == nil {
		preconditions = &ScalePrecondition{-1, ""}
	}
	if retry == nil {
		// Make it try only once, immediately
		retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
	}
	cond := ScaleCondition(scaler, preconditions, namespace, name, newSize)
	if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
		return err
	}
	if waitForReplicas != nil {
		deployment, err := scaler.c.Deployments(namespace).Get(name)
		if err != nil {
			return err
		}
		return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
			client.DeploymentHasDesiredReplicas(scaler.c, deployment))
	}
	return nil
}
<commit_msg>UPSTREAM: 27048: kubectl: return more meaningful timeout errors<commit_after>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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

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

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

package kubectl

import (
	"fmt"
	"strconv"
	"time"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/errors"
	"k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/apis/batch"
	"k8s.io/kubernetes/pkg/apis/extensions"
	client "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/util/wait"
)

// Scaler provides an interface for resources that can be scaled.
type Scaler interface {
	// Scale scales the named resource after checking preconditions. It optionally
	// retries in the event of resource version mismatch (if retry is not nil),
	// and optionally waits until the status of the resource matches newSize (if wait is not nil)
	Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, wait *RetryParams) error
	// ScaleSimple does a simple one-shot attempt at scaling - not useful on it's own, but
	// a necessary building block for Scale
	ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error
}

func ScalerFor(kind unversioned.GroupKind, c client.Interface) (Scaler, error) {
	switch kind {
	case api.Kind("ReplicationController"):
		return &ReplicationControllerScaler{c}, nil
	case extensions.Kind("ReplicaSet"):
		return &ReplicaSetScaler{c.Extensions()}, nil
	case extensions.Kind("Job"), batch.Kind("Job"):
		return &JobScaler{c.Batch()}, nil // Either kind of job can be scaled with Batch interface.
	case extensions.Kind("Deployment"):
		return &DeploymentScaler{c.Extensions()}, nil
	}
	return nil, fmt.Errorf("no scaler has been implemented for %q", kind)
}

// ScalePrecondition describes a condition that must be true for the scale to take place
// If CurrentSize == -1, it is ignored.
// If CurrentResourceVersion is the empty string, it is ignored.
// Otherwise they must equal the values in the resource for it to be valid.
type ScalePrecondition struct {
	Size            int
	ResourceVersion string
}

// A PreconditionError is returned when a resource fails to match
// the scale preconditions passed to kubectl.
type PreconditionError struct {
	Precondition  string
	ExpectedValue string
	ActualValue   string
}

func (pe PreconditionError) Error() string {
	return fmt.Sprintf("Expected %s to be %s, was %s", pe.Precondition, pe.ExpectedValue, pe.ActualValue)
}

type ScaleErrorType int

const (
	ScaleGetFailure ScaleErrorType = iota
	ScaleUpdateFailure
	ScaleUpdateConflictFailure
)

// A ScaleError is returned when a scale request passes
// preconditions but fails to actually scale the controller.
type ScaleError struct {
	FailureType     ScaleErrorType
	ResourceVersion string
	ActualError     error
}

func (c ScaleError) Error() string {
	return fmt.Sprintf(
		"Scaling the resource failed with: %v; Current resource version %s",
		c.ActualError, c.ResourceVersion)
}

// RetryParams encapsulates the retry parameters used by kubectl's scaler.
type RetryParams struct {
	Interval, Timeout time.Duration
}

func NewRetryParams(interval, timeout time.Duration) *RetryParams {
	return &RetryParams{interval, timeout}
}

// ScaleCondition is a closure around Scale that facilitates retries via util.wait
func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name string, count uint) wait.ConditionFunc {
	return func() (bool, error) {
		err := r.ScaleSimple(namespace, name, precondition, count)
		switch e, _ := err.(ScaleError); err.(type) {
		case nil:
			return true, nil
		case ScaleError:
			// Retry only on update conflicts.
			if e.FailureType == ScaleUpdateConflictFailure {
				return false, nil
			}
		}
		return false, err
	}
}

// ValidateReplicationController ensures that the preconditions match.  Returns nil if they are valid, an error otherwise
func (precondition *ScalePrecondition) ValidateReplicationController(controller *api.ReplicationController) error {
	if precondition.Size != -1 && int(controller.Spec.Replicas) != precondition.Size {
		return PreconditionError{"replicas", strconv.Itoa(precondition.Size), strconv.Itoa(int(controller.Spec.Replicas))}
	}
	if len(precondition.ResourceVersion) != 0 && controller.ResourceVersion != precondition.ResourceVersion {
		return PreconditionError{"resource version", precondition.ResourceVersion, controller.ResourceVersion}
	}
	return nil
}

type ReplicationControllerScaler struct {
	c client.Interface
}

func (scaler *ReplicationControllerScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error {
	controller, err := scaler.c.ReplicationControllers(namespace).Get(name)
	if err != nil {
		return ScaleError{ScaleGetFailure, "Unknown", err}
	}
	if preconditions != nil {
		if err := preconditions.ValidateReplicationController(controller); err != nil {
			return err
		}
	}
	controller.Spec.Replicas = int32(newSize)
	if _, err := scaler.c.ReplicationControllers(namespace).Update(controller); err != nil {
		if errors.IsConflict(err) {
			return ScaleError{ScaleUpdateConflictFailure, controller.ResourceVersion, err}
		}
		return ScaleError{ScaleUpdateFailure, controller.ResourceVersion, err}
	}
	return nil
}

// Scale updates a ReplicationController to a new size, with optional precondition check (if preconditions is not nil),
// optional retries (if retry is not nil), and then optionally waits for it's replica count to reach the new value
// (if wait is not nil).
func (scaler *ReplicationControllerScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
	if preconditions == nil {
		preconditions = &ScalePrecondition{-1, ""}
	}
	if retry == nil {
		// Make it try only once, immediately
		retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
	}
	cond := ScaleCondition(scaler, preconditions, namespace, name, newSize)
	if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
		return err
	}
	if waitForReplicas != nil {
		rc, err := scaler.c.ReplicationControllers(namespace).Get(name)
		if err != nil {
			return err
		}
		err = wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, client.ControllerHasDesiredReplicas(scaler.c, rc))
		if err == wait.ErrWaitTimeout {
			return fmt.Errorf("timed out waiting for %q to be synced", name)
		}
		return err
	}
	return nil
}

// ValidateReplicaSet ensures that the preconditions match.  Returns nil if they are valid, an error otherwise
func (precondition *ScalePrecondition) ValidateReplicaSet(replicaSet *extensions.ReplicaSet) error {
	if precondition.Size != -1 && int(replicaSet.Spec.Replicas) != precondition.Size {
		return PreconditionError{"replicas", strconv.Itoa(precondition.Size), strconv.Itoa(int(replicaSet.Spec.Replicas))}
	}
	if len(precondition.ResourceVersion) != 0 && replicaSet.ResourceVersion != precondition.ResourceVersion {
		return PreconditionError{"resource version", precondition.ResourceVersion, replicaSet.ResourceVersion}
	}
	return nil
}

type ReplicaSetScaler struct {
	c client.ExtensionsInterface
}

func (scaler *ReplicaSetScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error {
	rs, err := scaler.c.ReplicaSets(namespace).Get(name)
	if err != nil {
		return ScaleError{ScaleGetFailure, "Unknown", err}
	}
	if preconditions != nil {
		if err := preconditions.ValidateReplicaSet(rs); err != nil {
			return err
		}
	}
	rs.Spec.Replicas = int32(newSize)
	if _, err := scaler.c.ReplicaSets(namespace).Update(rs); err != nil {
		if errors.IsConflict(err) {
			return ScaleError{ScaleUpdateConflictFailure, rs.ResourceVersion, err}
		}
		return ScaleError{ScaleUpdateFailure, rs.ResourceVersion, err}
	}
	return nil
}

// Scale updates a ReplicaSet to a new size, with optional precondition check (if preconditions is
// not nil), optional retries (if retry is not nil), and then optionally waits for it's replica
// count to reach the new value (if wait is not nil).
func (scaler *ReplicaSetScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
	if preconditions == nil {
		preconditions = &ScalePrecondition{-1, ""}
	}
	if retry == nil {
		// Make it try only once, immediately
		retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
	}
	cond := ScaleCondition(scaler, preconditions, namespace, name, newSize)
	if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
		return err
	}
	if waitForReplicas != nil {
		rs, err := scaler.c.ReplicaSets(namespace).Get(name)
		if err != nil {
			return err
		}
		err = wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, client.ReplicaSetHasDesiredReplicas(scaler.c, rs))
		if err == wait.ErrWaitTimeout {
			return fmt.Errorf("timed out waiting for %q to be synced", name)
		}
		return err
	}
	return nil
}

// ValidateJob ensures that the preconditions match.  Returns nil if they are valid, an error otherwise.
func (precondition *ScalePrecondition) ValidateJob(job *batch.Job) error {
	if precondition.Size != -1 && job.Spec.Parallelism == nil {
		return PreconditionError{"parallelism", strconv.Itoa(precondition.Size), "nil"}
	}
	if precondition.Size != -1 && int(*job.Spec.Parallelism) != precondition.Size {
		return PreconditionError{"parallelism", strconv.Itoa(precondition.Size), strconv.Itoa(int(*job.Spec.Parallelism))}
	}
	if len(precondition.ResourceVersion) != 0 && job.ResourceVersion != precondition.ResourceVersion {
		return PreconditionError{"resource version", precondition.ResourceVersion, job.ResourceVersion}
	}
	return nil
}

type JobScaler struct {
	c client.BatchInterface
}

// ScaleSimple is responsible for updating job's parallelism.
func (scaler *JobScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error {
	job, err := scaler.c.Jobs(namespace).Get(name)
	if err != nil {
		return ScaleError{ScaleGetFailure, "Unknown", err}
	}
	if preconditions != nil {
		if err := preconditions.ValidateJob(job); err != nil {
			return err
		}
	}
	parallelism := int32(newSize)
	job.Spec.Parallelism = &parallelism
	if _, err := scaler.c.Jobs(namespace).Update(job); err != nil {
		if errors.IsConflict(err) {
			return ScaleError{ScaleUpdateConflictFailure, job.ResourceVersion, err}
		}
		return ScaleError{ScaleUpdateFailure, job.ResourceVersion, err}
	}
	return nil
}

// Scale updates a Job to a new size, with optional precondition check (if preconditions is not nil),
// optional retries (if retry is not nil), and then optionally waits for parallelism to reach desired
// number, which can be less than requested based on job's current progress.
func (scaler *JobScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
	if preconditions == nil {
		preconditions = &ScalePrecondition{-1, ""}
	}
	if retry == nil {
		// Make it try only once, immediately
		retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
	}
	cond := ScaleCondition(scaler, preconditions, namespace, name, newSize)
	if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
		return err
	}
	if waitForReplicas != nil {
		job, err := scaler.c.Jobs(namespace).Get(name)
		if err != nil {
			return err
		}
		err = wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, client.JobHasDesiredParallelism(scaler.c, job))
		if err == wait.ErrWaitTimeout {
			return fmt.Errorf("timed out waiting for %q to be synced", name)
		}
		return err
	}
	return nil
}

// ValidateDeployment ensures that the preconditions match.  Returns nil if they are valid, an error otherwise.
func (precondition *ScalePrecondition) ValidateDeployment(deployment *extensions.Deployment) error {
	if precondition.Size != -1 && int(deployment.Spec.Replicas) != precondition.Size {
		return PreconditionError{"replicas", strconv.Itoa(precondition.Size), strconv.Itoa(int(deployment.Spec.Replicas))}
	}
	if len(precondition.ResourceVersion) != 0 && deployment.ResourceVersion != precondition.ResourceVersion {
		return PreconditionError{"resource version", precondition.ResourceVersion, deployment.ResourceVersion}
	}
	return nil
}

type DeploymentScaler struct {
	c client.ExtensionsInterface
}

// ScaleSimple is responsible for updating a deployment's desired replicas count.
func (scaler *DeploymentScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error {
	deployment, err := scaler.c.Deployments(namespace).Get(name)
	if err != nil {
		return ScaleError{ScaleGetFailure, "Unknown", err}
	}
	if preconditions != nil {
		if err := preconditions.ValidateDeployment(deployment); err != nil {
			return err
		}
	}

	// TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528).
	// For now I'm falling back to regular Deployment update operation.
	deployment.Spec.Replicas = int32(newSize)
	if _, err := scaler.c.Deployments(namespace).Update(deployment); err != nil {
		if errors.IsConflict(err) {
			return ScaleError{ScaleUpdateConflictFailure, deployment.ResourceVersion, err}
		}
		return ScaleError{ScaleUpdateFailure, deployment.ResourceVersion, err}
	}
	return nil
}

// Scale updates a deployment to a new size, with optional precondition check (if preconditions is not nil),
// optional retries (if retry is not nil), and then optionally waits for the status to reach desired count.
func (scaler *DeploymentScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
	if preconditions == nil {
		preconditions = &ScalePrecondition{-1, ""}
	}
	if retry == nil {
		// Make it try only once, immediately
		retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
	}
	cond := ScaleCondition(scaler, preconditions, namespace, name, newSize)
	if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
		return err
	}
	if waitForReplicas != nil {
		deployment, err := scaler.c.Deployments(namespace).Get(name)
		if err != nil {
			return err
		}
		err = wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, client.DeploymentHasDesiredReplicas(scaler.c, deployment))
		if err == wait.ErrWaitTimeout {
			return fmt.Errorf("timed out waiting for %q to be synced", name)
		}
		return err
	}
	return nil
}
<|endoftext|>