<commit_before>/**
 * Copyright 2016 IBM Corp.
 *
 * 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 product

import (
	"fmt"

	"github.ibm.com/riethm/gopherlayer.git/datatypes"
	"github.ibm.com/riethm/gopherlayer.git/filter"
	"github.ibm.com/riethm/gopherlayer.git/services"
	"github.ibm.com/riethm/gopherlayer.git/session"
)

// Get a list of product item prices for a specific product package type and
// a specific set of price category code / product item capacity combinations.
// These combinations are passed as a map of integers (category code) mapped
// to strings (capacity)
// For example, these are the options to specify an upgrade to 8 cpus and 32
// GB or memory:
// {"guest_core": "8", "ram": "32"}
func GetProductPrices(
	sess *session.Session,
	packageType string,
	options map[string]string,
) ([]datatypes.Product_Item_Price, error) {

	service := services.GetProductPackageService(sess)

	// 1. Get package id
	packages, err := service.
		Mask("id,name,description,isActive,type[keyName]").
		Filter(
			filter.Build(
				filter.Path("type.keyName").Eq(packageType),
				filter.Path("description").NotContains("OUTLET"),
				filter.Path("name").NotContains("OUTLET"),
			),
		).
		Limit(1).
		GetAllObjects()
	if err != nil {
		return nil, err
	}

	if len(packages) == 0 {
		return nil, fmt.Errorf("No product packages found for %s", packageType)
	}

	// 2. Get product items for package id
	productItems, err := service.
		Id(*packages[0].Id).
		Mask("id,capacity,description,units,keyName,prices[id,categories[id,name,categoryCode]]").
		GetItems()
	if err != nil {
		return nil, err
	}

	// 3. Filter product items based on sets of category ids and capacity numbers
	prices := []datatypes.Product_Item_Price{}
	for _, productItem := range productItems {
		for _, category := range productItem.Prices[0].Categories {
			for k, v := range options {
				if productItem.Capacity != nil && *productItem.Capacity == v && *category.CategoryCode == k {
					prices = append(prices, productItem.Prices[0])
				}
			}
		}
	}

	return prices, nil
}
<commit_msg>Add consts for common category codes. Fix golint complaints<commit_after>/**
 * Copyright 2016 IBM Corp.
 *
 * 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 product

import (
	"fmt"

	"github.ibm.com/riethm/gopherlayer.git/datatypes"
	"github.ibm.com/riethm/gopherlayer.git/filter"
	"github.ibm.com/riethm/gopherlayer.git/services"
	"github.ibm.com/riethm/gopherlayer.git/session"
)

// CPUCategoryCode Category code for cpus
const CPUCategoryCode = "guest_core"

// MemoryCategoryCode Category code for Memory
const MemoryCategoryCode = "ram"

// NICSpeedCategoryCode Category code for NIC speed
const NICSpeedCategoryCode = "port_speed"

// GetProductPrices Get a list of product item prices for a specific product
// package type and a specific set of price category code / product item
// capacity combinations.
// These combinations are passed as a map of integers (category code) mapped
// to strings (capacity)
// For example, these are the options to specify an upgrade to 8 cpus and 32
// GB or memory:
// {"guest_core": "8", "ram": "32"}
func GetProductPrices(
	sess *session.Session,
	packageType string,
	options map[string]string,
) ([]datatypes.Product_Item_Price, error) {

	service := services.GetProductPackageService(sess)

	// 1. Get package id
	packages, err := service.
		Mask("id,name,description,isActive,type[keyName]").
		Filter(
			filter.Build(
				filter.Path("type.keyName").Eq(packageType),
				filter.Path("description").NotContains("OUTLET"),
				filter.Path("name").NotContains("OUTLET"),
			),
		).
		Limit(1).
		GetAllObjects()
	if err != nil {
		return nil, err
	}

	if len(packages) == 0 {
		return nil, fmt.Errorf("No product packages found for %s", packageType)
	}

	// 2. Get product items for package id
	productItems, err := service.
		Id(*packages[0].Id).
		Mask("id,capacity,description,units,keyName,prices[id,categories[id,name,categoryCode]]").
		GetItems()
	if err != nil {
		return nil, err
	}

	// 3. Filter product items based on sets of category ids and capacity numbers
	prices := []datatypes.Product_Item_Price{}
	for _, productItem := range productItems {
		for _, category := range productItem.Prices[0].Categories {
			for k, v := range options {
				if productItem.Capacity != nil && *productItem.Capacity == v && *category.CategoryCode == k {
					prices = append(prices, productItem.Prices[0])
				}
			}
		}
	}

	return prices, nil
}
<|endoftext|>


<commit_before>// Copyright 2018 The Wuffs Authors.
//
// 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
//
//    https://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.

// +build ignore

package main

// This program exercises the Go standard library's GIF decoder.
//
// Wuffs' C code doesn't depend on Go per se, but this program gives some
// performance data for specific Go GIF implementations. The equivalent Wuffs
// benchmarks (on the same test image) are run via:
//
// wuffs bench -mimic -focus=wuffs_gif_decode_1000k,mimic_gif_decode_1000k std/gif
//
// The "1000k" is because the test image (harvesters.gif) has approximately 1
// million pixels.
//
// The Wuffs benchmark reports megabytes per second. This program reports
// megapixels per second. The two concepts should be equivalent, since GIF
// images' pixel data are always 1 byte per pixel indices into a color palette.

import (
	"bytes"
	"fmt"
	"image"
	"image/gif"
	"io/ioutil"
	"os"
	"time"
)

// These constants are hard-coded to the harvesters.gif test image.
const WIDTH = 1165
const HEIGHT = 859
const BYTES_PER_PIXEL = 1 // Palette index.
const NUM_BYTES = WIDTH * HEIGHT * BYTES_PER_PIXEL
const FIRST_PIXEL = 0 // Top left pixel's palette index is 0x00.
const LAST_PIXEL = 1  // Bottom right pixel's palette index is 0x01.

func main() {
	if err := main1(); err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(1)
	}
}

func main1() error {
	src, err := ioutil.ReadFile("../../test/data/harvesters.gif")
	if err != nil {
		return err
	}

	start := time.Now()

	const REPS = 50
	for i := 0; i < REPS; i++ {
		decode(src)
	}

	elapsedNanos := time.Since(start)

	totalPixels := uint64(WIDTH * HEIGHT * REPS)
	kpPerS := totalPixels * 1000000 / uint64(elapsedNanos)

	fmt.Printf("Go      %3d.%03d megapixels/second\n", kpPerS/1000, kpPerS%1000)
	return nil
}

func decode(src []byte) {
	img, err := gif.Decode(bytes.NewReader(src))
	if err != nil {
		panic(err)
	}
	m := img.(*image.Paletted)
	if len(m.Pix) != NUM_BYTES {
		panic("wrong num_bytes")
	}

	// A hard-coded sanity check that we decoded the pixel data correctly.
	if (m.Pix[0] != FIRST_PIXEL) || (m.Pix[NUM_BYTES-1] != LAST_PIXEL) {
		panic("wrong dst pixels")
	}
}
<commit_msg>Have bench-go-gif process multiple images<commit_after>// Copyright 2018 The Wuffs Authors.
//
// 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
//
//    https://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.

// +build ignore

package main

// This program exercises the Go standard library's GIF decoder.
//
// Wuffs' C code doesn't depend on Go per se, but this program gives some
// performance data for specific Go GIF implementations. The equivalent Wuffs
// benchmarks (on the same test images) are run via:
//
// wuffs bench std/gif

import (
	"bytes"
	"fmt"
	"image"
	"image/draw"
	"image/gif"
	"io/ioutil"
	"os"
	"runtime"
	"strings"
	"time"
)

const (
	iterscale = 20
	reps      = 5
)

type testCase = struct {
	benchname     string
	filename      string
	itersUnscaled uint32
}

var testCases = []testCase{{
	benchname:     "go_gif_decode_1k_bw",
	filename:      "test/data/pjw-thumbnail.gif",
	itersUnscaled: 2000,
}, {
	benchname:     "go_gif_decode_1k_color",
	filename:      "test/data/hippopotamus.regular.gif",
	itersUnscaled: 1000,
}, {
	benchname:     "go_gif_decode_10k_bgra",
	filename:      "test/data/hat.gif",
	itersUnscaled: 100,
}, {
	benchname:     "go_gif_decode_10k_indexed",
	filename:      "test/data/hat.gif",
	itersUnscaled: 100,
}, {
	benchname:     "go_gif_decode_20k",
	filename:      "test/data/bricks-gray.gif",
	itersUnscaled: 50,
}, {
	benchname:     "go_gif_decode_100k_artificial",
	filename:      "test/data/hibiscus.primitive.gif",
	itersUnscaled: 15,
}, {
	benchname:     "go_gif_decode_100k_realistic",
	filename:      "test/data/hibiscus.regular.gif",
	itersUnscaled: 10,
}, {
	benchname:     "go_gif_decode_1000k",
	filename:      "test/data/harvesters.gif",
	itersUnscaled: 1,
}, {
	benchname:     "go_gif_decode_anim_screencap",
	filename:      "test/data/gifplayer-muybridge.gif",
	itersUnscaled: 1,
}}

func main() {
	if err := main1(); err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(1)
	}
}

func main1() error {
	fmt.Printf("# Go %s\n", runtime.Version())
	fmt.Printf("#\n")
	fmt.Printf("# The output format, including the \"Benchmark\" prefixes, is compatible with the\n")
	fmt.Printf("# https://godoc.org/golang.org/x/perf/cmd/benchstat tool. To install it, first\n")
	fmt.Printf("# install Go, then run \"go get golang.org/x/perf/cmd/benchstat\".\n")

	for i := -1; i < reps; i++ {
		for _, tc := range testCases {
			src, err := ioutil.ReadFile("../../" + tc.filename)
			if err != nil {
				return err
			}

			runtime.GC()

			start := time.Now()

			iters := uint64(tc.itersUnscaled) * iterscale
			bgra := strings.HasSuffix(tc.benchname, "_bgra")
			numBytes, err := decode(src, bgra)
			if err != nil {
				return err
			}
			for i := uint64(1); i < iters; i++ {
				decode(src, bgra)
			}

			elapsedNanos := time.Since(start)

			kbPerS := numBytes * uint64(iters) * 1000000 / uint64(elapsedNanos)

			if i < 0 {
				continue // Warm up rep.
			}

			fmt.Printf("Benchmark%-30s %8d %12d ns/op %8d.%03d MB/s\n",
				tc.benchname, iters, uint64(elapsedNanos)/iters, kbPerS/1000, kbPerS%1000)
		}
	}

	return nil
}

func decode(src []byte, bgra bool) (numBytes uint64, retErr error) {
	g, err := gif.DecodeAll(bytes.NewReader(src))
	if err != nil {
		return 0, err
	}

	for _, m := range g.Image {
		b := m.Bounds()
		n := uint64(b.Dx()) * uint64(b.Dy())

		// Go converts to RGBA (as that's what Go's image/draw standard library is
		// optimized for); Wuffs converts to BGRA. The difference isn't important,
		// as we just want measure how long it takes.
		if bgra {
			dst := image.NewRGBA(b)
			draw.Draw(dst, b, m, b.Min, draw.Src)
			n *= 4
		}

		numBytes += n
	}

	return numBytes, nil
}
<|endoftext|>


<commit_before>package cli

import (
	"errors"
	"flag"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
)

type Create struct{}

func NewCreate() *Create {
	return &Create{}
}

func (c Create) Definition() string {
	return "Creates a kite from kite skeleton"
}

func (c Create) Exec() error {
	flag.Parse()
	if len(flag.Args()) == 0 {
		return errors.New("You should give a kite name")
	}

	kiteName := flag.Arg(0)
	folder := kiteName + ".kite"

	err := os.Mkdir(folder, 0755)
	if os.IsExist(err) {
		return errors.New("Kite already exists")
	}
	if err != nil {
		return err
	}
	err = os.MkdirAll(filepath.Join(folder, "bin"), 0755)
	if err != nil {
		return err
	}
	err = os.MkdirAll(filepath.Join(folder, "resources"), 0755)
	if err != nil {
		return err
	}
	err = createManifest(folder)
	if err != nil {
		return err
	}
	err = createKite(folder, kiteName)
	if err != nil {
		return err
	}
	return nil
}

func createManifest(folder string) error {
	path := filepath.Join(folder, "manifest.json")
	return ioutil.WriteFile(path, []byte("buff\n"), 0755)
}

func createKite(folder, kiteName string) error {
	return cp(os.Getenv("HOME")+"/.kd/skel.go", filepath.Join(folder, kiteName+".go"))
}

func cp(src, dst string) error {
	s, err := os.Open(src)
	if err != nil {
		return err
	}
	defer s.Close()
	d, err := os.Create(dst)
	if err != nil {
		return err
	}
	if _, err := io.Copy(d, s); err != nil {
		d.Close()
		return err
	}
	return d.Close()
}
<commit_msg>create.go: env HOME usage cancelled<commit_after>package cli

import (
	"errors"
	"flag"
	"io"
	"io/ioutil"
	"os"
	"os/user"
	"path/filepath"
)

type Create struct{}

func NewCreate() *Create {
	return &Create{}
}

func (c Create) Definition() string {
	return "Creates a kite from kite skeleton"
}

func (c Create) Exec() error {
	flag.Parse()
	if len(flag.Args()) == 0 {
		return errors.New("You should give a kite name")
	}

	kiteName := flag.Arg(0)
	folder := kiteName + ".kite"

	err := os.Mkdir(folder, 0755)
	if os.IsExist(err) {
		return errors.New("Kite already exists")
	}
	if err != nil {
		return err
	}
	err = os.MkdirAll(filepath.Join(folder, "bin"), 0755)
	if err != nil {
		return err
	}
	err = os.MkdirAll(filepath.Join(folder, "resources"), 0755)
	if err != nil {
		return err
	}
	err = createManifest(folder)
	if err != nil {
		return err
	}
	err = createKite(folder, kiteName)
	if err != nil {
		return err
	}
	return nil
}

func createManifest(folder string) error {
	path := filepath.Join(folder, "manifest.json")
	return ioutil.WriteFile(path, []byte("buff\n"), 0755)
}

func createKite(folder, kiteName string) error {
	currUser, err := user.Current()
	if err != nil {
		return err
	}
	skelPath := filepath.Join(currUser.HomeDir, "/.kd/skel.go")
	kitePath := filepath.Join(folder, kiteName+".go")
	return cp(skelPath, kitePath)
}

func cp(src, dst string) error {
	s, err := os.Open(src)
	if err != nil {
		return err
	}
	defer s.Close()
	d, err := os.Create(dst)
	if err != nil {
		return err
	}
	if _, err := io.Copy(d, s); err != nil {
		d.Close()
		return err
	}
	return d.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"log"
	"strings"
)

type fileListing struct {
	Files map[string]interface{} `json:"files"`
	Dirs  map[string]interface{} `json:"dirs"`
	Path  string                 `json:"path"`
}

func listFiles(path string, includeMeta bool,
	depth int) (fileListing, error) {

	viewRes := struct {
		Rows []struct {
			Key   []string
			Value map[string]interface{}
		}
	}{}

	// use the requested path to build our view query parameters
	startKey := []string{}
	if path != "" {
		startKey = strings.Split(path, "/")
	}
	endKey := make([]string, len(startKey)+1, len(startKey)+1)
	copy(endKey, startKey)
	endKey[len(startKey)] = "ZZZZZZ" // FIXME use {} instead
	groupLevel := len(startKey) + depth

	// query the view
	err := couchbase.ViewCustom("cbfs", "file_browse",
		map[string]interface{}{
			"group_level": groupLevel,
			"start_key":   startKey,
			"end_key":     endKey,
		}, &viewRes)
	if err != nil {
		return fileListing{}, err
	}

	// use the view result to build a list of keys
	keys := make([]string, len(viewRes.Rows), len(viewRes.Rows))
	for i, r := range viewRes.Rows {
		keys[i] = strings.Join(r.Key, "/")
	}

	// do a multi-get on the all the keys returned
	bulkResult := couchbase.GetBulk(keys)

	// divide items up into files and directories
	files := map[string]interface{}{}
	dirs := map[string]interface{}{}
	for _, r := range viewRes.Rows {
		key := strings.Join(r.Key, "/")
		subkey := r.Key
		if len(r.Key) > depth {
			subkey = r.Key[len(r.Key)-depth:]
		}
		name := strings.Join(subkey, "/")
		res, ok := bulkResult[key]
		if ok == true {
			// this means we have a file
			rv := map[string]interface{}{}
			err := json.Unmarshal(res.Body, &rv)
			if err != nil {
				log.Printf("Error deserializing json, ignoring: %v", err)
			} else {
				if includeMeta {
					files[name] = rv
				} else {
					files[name] = map[string]interface{}{}
				}
			}
		} else {
			// no record in the multi-get metans this is a directory
			dirs[name] = map[string]interface{}{
				"descendants": r.Value["count"],
				"size":        int64(r.Value["sum"].(float64)),
				"smallest":    int64(r.Value["min"].(float64)),
				"largest":     int64(r.Value["max"].(float64)),
			}
		}
	}

	rv := fileListing{
		Path:  "/" + path,
		Dirs:  dirs,
		Files: files,
	}

	return rv, nil
}
<commit_msg>List should work with all the things.<commit_after>package main

import (
	"encoding/json"
	"log"
	"strings"
)

type fileListing struct {
	Files map[string]interface{} `json:"files"`
	Dirs  map[string]interface{} `json:"dirs"`
	Path  string                 `json:"path"`
}

func toStringJoin(in []interface{}, sep string) string {
	s := []string{}
	for _, a := range in {
		s = append(s, a.(string))
	}
	return strings.Join(s, sep)
}

func listFiles(path string, includeMeta bool,
	depth int) (fileListing, error) {

	viewRes := struct {
		Rows []struct {
			Key   []interface{}
			Value map[string]interface{}
		}
	}{}

	// use the requested path to build our view query parameters
	startKey := []interface{}{}
	if path != "" {
		for _, k := range strings.Split(path, "/") {
			startKey = append(startKey, k)
		}
	}
	endKey := make([]interface{}, len(startKey)+1, len(startKey)+1)
	copy(endKey, startKey)
	endMarker := json.RawMessage([]byte{'{', '}'})
	endKey[len(startKey)] = &endMarker
	groupLevel := len(startKey) + depth

	// query the view
	err := couchbase.ViewCustom("cbfs", "file_browse",
		map[string]interface{}{
			"group_level": groupLevel,
			"start_key":   startKey,
			"end_key":     endKey,
		}, &viewRes)
	if err != nil {
		return fileListing{}, err
	}

	// use the view result to build a list of keys
	keys := make([]string, len(viewRes.Rows), len(viewRes.Rows))
	for i, r := range viewRes.Rows {
		keys[i] = toStringJoin(r.Key, "/")
	}

	// do a multi-get on the all the keys returned
	bulkResult := couchbase.GetBulk(keys)

	// divide items up into files and directories
	files := map[string]interface{}{}
	dirs := map[string]interface{}{}
	for _, r := range viewRes.Rows {
		key := toStringJoin(r.Key, "/")
		subkey := r.Key
		if len(r.Key) > depth {
			subkey = r.Key[len(r.Key)-depth:]
		}
		name := toStringJoin(subkey, "/")
		res, ok := bulkResult[key]
		if ok == true {
			// this means we have a file
			rv := map[string]interface{}{}
			err := json.Unmarshal(res.Body, &rv)
			if err != nil {
				log.Printf("Error deserializing json, ignoring: %v", err)
			} else {
				if includeMeta {
					files[name] = rv
				} else {
					files[name] = map[string]interface{}{}
				}
			}
		} else {
			// no record in the multi-get metans this is a directory
			dirs[name] = map[string]interface{}{
				"descendants": r.Value["count"],
				"size":        int64(r.Value["sum"].(float64)),
				"smallest":    int64(r.Value["min"].(float64)),
				"largest":     int64(r.Value["max"].(float64)),
			}
		}
	}

	rv := fileListing{
		Path:  "/" + path,
		Dirs:  dirs,
		Files: files,
	}

	return rv, nil
}
<|endoftext|>


<commit_before>package images

import (
	"encoding/xml"
	"fmt"
	"github.com/megamsys/opennebula-go/api"
)

type ImageType string

const (
	LOCKED  = 4
	READY   = 1
	USED    = 2
	FAILURE = 5
)

const (
	OPERATING_SYSTEM = ImageType("OS")
	CD_ROM           = ImageType("CDROM")
	DATABLOCK        = ImageType("DATABLOCK")
)

type Images struct {
	Images []Image `xml:"IMAGE"`
	T      *api.Rpc
}

type Image struct {
	Id          int       `xml:"ID"`
	Uid         int       `xml:"UID"`
	Name        string    `xml:"NAME"`
	Type        ImageType `xml:"TYPE"`
	Size        int       `xml:"SIZE"`
	State       int       `xml:"STATE"`
	Path        string    `xml:"PATH"`
	Persistent  string    `xml:"PERSISTENT"`
	DatastoreID int       `xml:"DATASTORE_ID"`
	Datastore   string    `xml:"DATASTORE"`
	FsType      string    `xml:"FSTYPE"`
	RunningVMs  Vms       `xml:"VMS"`
	T           *api.Rpc
}

type Vms struct {
	Id []int `xml:"ID"`
}

func (v *Image) Create() (interface{}, error) {
	// qcow2 has some feature block so we use raw by default
	v.FsType = "raw"
	finalData, _ := xml.Marshal(v)
	data := string(finalData)
	args := []interface{}{v.T.Key, data, v.DatastoreID}
	return v.T.Call(api.ONE_IMAGE_CREATE, args)
}

func (v *Image) ByName() (*Image, error) {
	ims, err := v.List()
	if err != nil {
		return nil, err
	}
	for _, k := range ims.Images {
		if k.Name == v.Name {
			return &k, nil
		}
	}
	return nil, fmt.Errorf("ONE doesn't have any images name (%s)", v.Name)
}

func (v *Image) Delete() (interface{}, error) {
	args := []interface{}{v.T.Key, v.Id}
	return v.T.Call(api.ONE_IMAGE_SHOW, args)
}

func (v *Image) ChPersistent(state bool) (interface{}, error) {
	args := []interface{}{v.T.Key, v.Id, state}
	return v.T.Call(api.ONE_IMAGE_PERSISTENT, args)
}

func (v *Image) ChType(t ImageType) (interface{}, error) {
	args := []interface{}{v.T.Key, v.Id, string(t)}
	return v.T.Call(api.ONE_IMAGE_TYPECHANGE, args)
}

func (v *Image) Rename(new_name string) (interface{}, error) {
	args := []interface{}{v.T.Key, v.Id, new_name}
	return v.T.Call(api.ONE_IMAGE_RENAME, args)
}

func (v *Image) Enable(state string) (interface{}, error) {
	args := []interface{}{v.T.Key, v.Id, state}
	return v.T.Call(api.ONE_IMAGE_ENABLE, args)
}

func (v *Image) Show() (*Image, error) {
	args := []interface{}{v.T.Key, v.Id}
	res, err := v.T.Call(api.ONE_IMAGE_SHOW, args)
	if err != nil {
		return nil, err
	}
	xmlImage := &Image{}
	if err = xml.Unmarshal([]byte(res), xmlImage); err != nil {
		return nil, err
	}
	return xmlImage, err
}

func (v *Image) List() (*Images, error) {
	first := -1 // -1 for default smaller ID
	last := -1  //-1 for default last ID
	args := []interface{}{v.T.Key, -1, first, last}
	res, err := v.T.Call(api.ONE_IMAGE_LIST, args)
	if err != nil {
		return nil, err
	}
	xmlImages := &Images{}
	if err = xml.Unmarshal([]byte(res), xmlImages); err != nil {
		return nil, err
	}
	return xmlImages, err
}

func (v *Image) State_string() string {
	switch v.State {
	case LOCKED:
		return "locked"
	case READY:
		return "ready"
	case USED:
		return "used"
	case FAILURE:
		return "failure"
	default:
		return "unknown"
	}
}
<commit_msg>avoid keys in xml string<commit_after>package images

import (
	"encoding/xml"
	"fmt"
	"github.com/megamsys/opennebula-go/api"
)

type ImageType string

const (
	LOCKED  = 4
	READY   = 1
	USED    = 2
	FAILURE = 5
)

const (
	OPERATING_SYSTEM = ImageType("OS")
	CD_ROM           = ImageType("CDROM")
	DATABLOCK        = ImageType("DATABLOCK")
)

type Images struct {
	Images []Image `xml:"IMAGE"`
	T      *api.Rpc
}

type Image struct {
	Id          int       `xml:"ID"`
	Uid         int       `xml:"UID"`
	Name        string    `xml:"NAME"`
	Type        ImageType `xml:"TYPE"`
	Size        int       `xml:"SIZE"`
	State       int       `xml:"STATE"`
	Path        string    `xml:"PATH"`
	Persistent  string    `xml:"PERSISTENT"`
	DatastoreID int       `xml:"DATASTORE_ID"`
	Datastore   string    `xml:"DATASTORE"`
	FsType      string    `xml:"FSTYPE"`
	RunningVMs  Vms       `xml:"VMS"`
	T           *api.Rpc  `xml:"-"`
}

type Vms struct {
	Id []int `xml:"ID"`
}

func (v *Image) Create() (interface{}, error) {
	// qcow2 has some feature block so we use raw by default
	v.FsType = "raw"
	finalData, _ := xml.Marshal(v)
	data := string(finalData)
	args := []interface{}{v.T.Key, data, v.DatastoreID}
	return v.T.Call(api.ONE_IMAGE_CREATE, args)
}

func (v *Image) ByName() (*Image, error) {
	ims, err := v.List()
	if err != nil {
		return nil, err
	}
	for _, k := range ims.Images {
		if k.Name == v.Name {
			return &k, nil
		}
	}
	return nil, fmt.Errorf("ONE doesn't have any images name (%s)", v.Name)
}

func (v *Image) Delete() (interface{}, error) {
	args := []interface{}{v.T.Key, v.Id}
	return v.T.Call(api.ONE_IMAGE_SHOW, args)
}

func (v *Image) ChPersistent(state bool) (interface{}, error) {
	args := []interface{}{v.T.Key, v.Id, state}
	return v.T.Call(api.ONE_IMAGE_PERSISTENT, args)
}

func (v *Image) ChType(t ImageType) (interface{}, error) {
	args := []interface{}{v.T.Key, v.Id, string(t)}
	return v.T.Call(api.ONE_IMAGE_TYPECHANGE, args)
}

func (v *Image) Rename(new_name string) (interface{}, error) {
	args := []interface{}{v.T.Key, v.Id, new_name}
	return v.T.Call(api.ONE_IMAGE_RENAME, args)
}

func (v *Image) Enable(state string) (interface{}, error) {
	args := []interface{}{v.T.Key, v.Id, state}
	return v.T.Call(api.ONE_IMAGE_ENABLE, args)
}

func (v *Image) Show() (*Image, error) {
	args := []interface{}{v.T.Key, v.Id}
	res, err := v.T.Call(api.ONE_IMAGE_SHOW, args)
	if err != nil {
		return nil, err
	}
	xmlImage := &Image{}
	if err = xml.Unmarshal([]byte(res), xmlImage); err != nil {
		return nil, err
	}
	return xmlImage, err
}

func (v *Image) List() (*Images, error) {
	first := -1 // -1 for default smaller ID
	last := -1  //-1 for default last ID
	args := []interface{}{v.T.Key, -1, first, last}
	res, err := v.T.Call(api.ONE_IMAGE_LIST, args)
	if err != nil {
		return nil, err
	}
	xmlImages := &Images{}
	if err = xml.Unmarshal([]byte(res), xmlImages); err != nil {
		return nil, err
	}
	return xmlImages, err
}

func (v *Image) State_string() string {
	switch v.State {
	case LOCKED:
		return "locked"
	case READY:
		return "ready"
	case USED:
		return "used"
	case FAILURE:
		return "failure"
	default:
		return "unknown"
	}
}
<|endoftext|>


<commit_before>package push

import (
	"time"

	"code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("push with disk flag", func() {
	var (
		appName string
	)

	BeforeEach(func() {
		appName = helpers.NewAppName()
	})

	Context("when the -k flag is provided with application disk", func() {
		It("creates the app with the specified disk", func() {
			helpers.WithHelloWorldApp(func(dir string) {
				session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir},
					PushCommandName, appName,
					"-k", "70M",
				)
				Eventually(session).Should(Exit(0))
			})

			time.Sleep(5 * time.Second)
			session := helpers.CF("app", appName)
			Eventually(session).Should(Say(`name:\s+%s`, appName))
			Eventually(session).Should(Say(`last uploaded:\s+%s`, helpers.ReadableDateTimeRegex))
			Eventually(session).Should(Say(`\s+state\s+since\s+cpu\s+memory\s+disk`))
			Eventually(session).Should(Say(`#0\s+running\s+\d{4}-[01]\d-[0-3]\dT[0-2][0-9]:[0-5]\d:[0-5]\dZ.+of.+of 70M`))
			Eventually(session).Should(Exit(0))
		})
	})
})
<commit_msg>Fixed push command test for -k flag<commit_after>package push

import (
	"code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("push with disk flag", func() {
	var (
		appName string
	)

	BeforeEach(func() {
		appName = helpers.NewAppName()
	})

	Context("when the -k flag is provided with application disk", func() {
		It("creates the app with the specified disk", func() {
			helpers.WithHelloWorldApp(func(dir string) {
				session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir},
					PushCommandName, appName,
					"-k", "70M",
				)
				Eventually(session).Should(Exit(0))
			})

			helpers.WaitForAppDiskToTakeEffect(appName, 0, 0, false, "70M")

			session := helpers.CF("app", appName)
			Eventually(session).Should(Exit(0))
			Expect(session).To(Say(`name:\s+%s`, appName))
			Expect(session).To(Say(`last uploaded:\s+%s`, helpers.ReadableDateTimeRegex))
			Expect(session).To(Say(`\s+state\s+since\s+cpu\s+memory\s+disk`))
			Expect(session).To(Say(`#0\s+running\s+\d{4}-[01]\d-[0-3]\dT[0-2][0-9]:[0-5]\d:[0-5]\dZ.+of.+of 70M`))
		})
	})
})
<|endoftext|>


<commit_before>package quicproxy

import (
	"net"
	"sync"
	"sync/atomic"
	"time"

	"github.com/lucas-clemente/quic-go/internal/protocol"
	"github.com/lucas-clemente/quic-go/internal/utils"
)

// Connection is a UDP connection
type connection struct {
	ClientAddr *net.UDPAddr // Address of the client
	ServerConn *net.UDPConn // UDP connection to server

	incomingPacketCounter uint64
	outgoingPacketCounter uint64
}

// Direction is the direction a packet is sent.
type Direction int

const (
	// DirectionIncoming is the direction from the client to the server.
	DirectionIncoming Direction = iota
	// DirectionOutgoing is the direction from the server to the client.
	DirectionOutgoing
	// DirectionBoth is both incoming and outgoing
	DirectionBoth
)

func (d Direction) String() string {
	switch d {
	case DirectionIncoming:
		return "incoming"
	case DirectionOutgoing:
		return "outgoing"
	case DirectionBoth:
		return "both"
	default:
		panic("unknown direction")
	}
}

func (d Direction) Is(dir Direction) bool {
	if d == DirectionBoth || dir == DirectionBoth {
		return true
	}
	return d == dir
}

// DropCallback is a callback that determines which packet gets dropped.
type DropCallback func(dir Direction, packetCount uint64) bool

// NoDropper doesn't drop packets.
var NoDropper DropCallback = func(Direction, uint64) bool {
	return false
}

// DelayCallback is a callback that determines how much delay to apply to a packet.
type DelayCallback func(dir Direction, packetCount uint64) time.Duration

// NoDelay doesn't apply a delay.
var NoDelay DelayCallback = func(Direction, uint64) time.Duration {
	return 0
}

// Opts are proxy options.
type Opts struct {
	// The address this proxy proxies packets to.
	RemoteAddr string
	// DropPacket determines whether a packet gets dropped.
	DropPacket DropCallback
	// DelayPacket determines how long a packet gets delayed. This allows
	// simulating a connection with non-zero RTTs.
	// Note that the RTT is the sum of the delay for the incoming and the outgoing packet.
	DelayPacket DelayCallback
}

// QuicProxy is a QUIC proxy that can drop and delay packets.
type QuicProxy struct {
	mutex sync.Mutex

	version protocol.VersionNumber

	conn       *net.UDPConn
	serverAddr *net.UDPAddr

	dropPacket  DropCallback
	delayPacket DelayCallback

	// Mapping from client addresses (as host:port) to connection
	clientDict map[string]*connection
}

// NewQuicProxy creates a new UDP proxy
func NewQuicProxy(local string, version protocol.VersionNumber, opts *Opts) (*QuicProxy, error) {
	if opts == nil {
		opts = &Opts{}
	}
	laddr, err := net.ResolveUDPAddr("udp", local)
	if err != nil {
		return nil, err
	}
	conn, err := net.ListenUDP("udp", laddr)
	if err != nil {
		return nil, err
	}
	raddr, err := net.ResolveUDPAddr("udp", opts.RemoteAddr)
	if err != nil {
		return nil, err
	}

	packetDropper := NoDropper
	if opts.DropPacket != nil {
		packetDropper = opts.DropPacket
	}

	packetDelayer := NoDelay
	if opts.DelayPacket != nil {
		packetDelayer = opts.DelayPacket
	}

	p := QuicProxy{
		clientDict:  make(map[string]*connection),
		conn:        conn,
		serverAddr:  raddr,
		dropPacket:  packetDropper,
		delayPacket: packetDelayer,
		version:     version,
	}

	utils.Debugf("Starting UDP Proxy %s <-> %s", conn.LocalAddr(), raddr)
	go p.runProxy()
	return &p, nil
}

// Close stops the UDP Proxy
func (p *QuicProxy) Close() error {
	p.mutex.Lock()
	defer p.mutex.Unlock()
	for _, c := range p.clientDict {
		if err := c.ServerConn.Close(); err != nil {
			return err
		}
	}
	return p.conn.Close()
}

// LocalAddr is the address the proxy is listening on.
func (p *QuicProxy) LocalAddr() net.Addr {
	return p.conn.LocalAddr()
}

// LocalPort is the UDP port number the proxy is listening on.
func (p *QuicProxy) LocalPort() int {
	return p.conn.LocalAddr().(*net.UDPAddr).Port
}

func (p *QuicProxy) newConnection(cliAddr *net.UDPAddr) (*connection, error) {
	srvudp, err := net.DialUDP("udp", nil, p.serverAddr)
	if err != nil {
		return nil, err
	}
	return &connection{
		ClientAddr: cliAddr,
		ServerConn: srvudp,
	}, nil
}

// runProxy listens on the proxy address and handles incoming packets.
func (p *QuicProxy) runProxy() error {
	for {
		buffer := make([]byte, protocol.MaxReceivePacketSize)
		n, cliaddr, err := p.conn.ReadFromUDP(buffer)
		if err != nil {
			return err
		}
		raw := buffer[0:n]

		saddr := cliaddr.String()
		p.mutex.Lock()
		conn, ok := p.clientDict[saddr]

		if !ok {
			conn, err = p.newConnection(cliaddr)
			if err != nil {
				p.mutex.Unlock()
				return err
			}
			p.clientDict[saddr] = conn
			go p.runConnection(conn)
		}
		p.mutex.Unlock()

		packetCount := atomic.AddUint64(&conn.incomingPacketCounter, 1)

		if p.dropPacket(DirectionIncoming, packetCount) {
			if utils.Debug() {
				utils.Debugf("dropping incoming packet %d (%d bytes)", packetCount, n)
			}
			continue
		}

		// Send the packet to the server
		delay := p.delayPacket(DirectionIncoming, packetCount)
		if delay != 0 {
			if utils.Debug() {
				utils.Debugf("delaying incoming packet %d (%d bytes) to %s by %s", packetCount, n, conn.ServerConn.RemoteAddr(), delay)
			}
			time.AfterFunc(delay, func() {
				// TODO: handle error
				_, _ = conn.ServerConn.Write(raw)
			})
		} else {
			if utils.Debug() {
				utils.Debugf("forwarding incoming packet %d (%d bytes) to %s", packetCount, n, conn.ServerConn.RemoteAddr())
			}
			if _, err := conn.ServerConn.Write(raw); err != nil {
				return err
			}
		}
	}
}

// runConnection handles packets from server to a single client
func (p *QuicProxy) runConnection(conn *connection) error {
	for {
		buffer := make([]byte, protocol.MaxReceivePacketSize)
		n, err := conn.ServerConn.Read(buffer)
		if err != nil {
			return err
		}
		raw := buffer[0:n]

		packetCount := atomic.AddUint64(&conn.outgoingPacketCounter, 1)

		if p.dropPacket(DirectionOutgoing, packetCount) {
			if utils.Debug() {
				utils.Debugf("dropping outgoing packet %d (%d bytes)", packetCount, n)
			}
			continue
		}
		utils.Debugf("forwarding outgoing packet %d (%d bytes) to %s", packetCount, n, conn.ClientAddr)

		delay := p.delayPacket(DirectionOutgoing, packetCount)
		if delay != 0 {
			if utils.Debug() {
				utils.Debugf("delaying outgoing packet %d (%d bytes) to %s by %s", packetCount, n, conn.ClientAddr, delay)
			}
			time.AfterFunc(delay, func() {
				// TODO: handle error
				_, _ = p.conn.WriteToUDP(raw, conn.ClientAddr)
			})
		} else {
			if utils.Debug() {
				utils.Debugf("forwarding outgoing packet %d (%d bytes) to %s", packetCount, n, conn.ClientAddr)
			}
			if _, err := p.conn.WriteToUDP(raw, conn.ClientAddr); err != nil {
				return err
			}
		}
	}
}
<commit_msg>remove duplicate log statement in the proxy<commit_after>package quicproxy

import (
	"net"
	"sync"
	"sync/atomic"
	"time"

	"github.com/lucas-clemente/quic-go/internal/protocol"
	"github.com/lucas-clemente/quic-go/internal/utils"
)

// Connection is a UDP connection
type connection struct {
	ClientAddr *net.UDPAddr // Address of the client
	ServerConn *net.UDPConn // UDP connection to server

	incomingPacketCounter uint64
	outgoingPacketCounter uint64
}

// Direction is the direction a packet is sent.
type Direction int

const (
	// DirectionIncoming is the direction from the client to the server.
	DirectionIncoming Direction = iota
	// DirectionOutgoing is the direction from the server to the client.
	DirectionOutgoing
	// DirectionBoth is both incoming and outgoing
	DirectionBoth
)

func (d Direction) String() string {
	switch d {
	case DirectionIncoming:
		return "incoming"
	case DirectionOutgoing:
		return "outgoing"
	case DirectionBoth:
		return "both"
	default:
		panic("unknown direction")
	}
}

func (d Direction) Is(dir Direction) bool {
	if d == DirectionBoth || dir == DirectionBoth {
		return true
	}
	return d == dir
}

// DropCallback is a callback that determines which packet gets dropped.
type DropCallback func(dir Direction, packetCount uint64) bool

// NoDropper doesn't drop packets.
var NoDropper DropCallback = func(Direction, uint64) bool {
	return false
}

// DelayCallback is a callback that determines how much delay to apply to a packet.
type DelayCallback func(dir Direction, packetCount uint64) time.Duration

// NoDelay doesn't apply a delay.
var NoDelay DelayCallback = func(Direction, uint64) time.Duration {
	return 0
}

// Opts are proxy options.
type Opts struct {
	// The address this proxy proxies packets to.
	RemoteAddr string
	// DropPacket determines whether a packet gets dropped.
	DropPacket DropCallback
	// DelayPacket determines how long a packet gets delayed. This allows
	// simulating a connection with non-zero RTTs.
	// Note that the RTT is the sum of the delay for the incoming and the outgoing packet.
	DelayPacket DelayCallback
}

// QuicProxy is a QUIC proxy that can drop and delay packets.
type QuicProxy struct {
	mutex sync.Mutex

	version protocol.VersionNumber

	conn       *net.UDPConn
	serverAddr *net.UDPAddr

	dropPacket  DropCallback
	delayPacket DelayCallback

	// Mapping from client addresses (as host:port) to connection
	clientDict map[string]*connection
}

// NewQuicProxy creates a new UDP proxy
func NewQuicProxy(local string, version protocol.VersionNumber, opts *Opts) (*QuicProxy, error) {
	if opts == nil {
		opts = &Opts{}
	}
	laddr, err := net.ResolveUDPAddr("udp", local)
	if err != nil {
		return nil, err
	}
	conn, err := net.ListenUDP("udp", laddr)
	if err != nil {
		return nil, err
	}
	raddr, err := net.ResolveUDPAddr("udp", opts.RemoteAddr)
	if err != nil {
		return nil, err
	}

	packetDropper := NoDropper
	if opts.DropPacket != nil {
		packetDropper = opts.DropPacket
	}

	packetDelayer := NoDelay
	if opts.DelayPacket != nil {
		packetDelayer = opts.DelayPacket
	}

	p := QuicProxy{
		clientDict:  make(map[string]*connection),
		conn:        conn,
		serverAddr:  raddr,
		dropPacket:  packetDropper,
		delayPacket: packetDelayer,
		version:     version,
	}

	utils.Debugf("Starting UDP Proxy %s <-> %s", conn.LocalAddr(), raddr)
	go p.runProxy()
	return &p, nil
}

// Close stops the UDP Proxy
func (p *QuicProxy) Close() error {
	p.mutex.Lock()
	defer p.mutex.Unlock()
	for _, c := range p.clientDict {
		if err := c.ServerConn.Close(); err != nil {
			return err
		}
	}
	return p.conn.Close()
}

// LocalAddr is the address the proxy is listening on.
func (p *QuicProxy) LocalAddr() net.Addr {
	return p.conn.LocalAddr()
}

// LocalPort is the UDP port number the proxy is listening on.
func (p *QuicProxy) LocalPort() int {
	return p.conn.LocalAddr().(*net.UDPAddr).Port
}

func (p *QuicProxy) newConnection(cliAddr *net.UDPAddr) (*connection, error) {
	srvudp, err := net.DialUDP("udp", nil, p.serverAddr)
	if err != nil {
		return nil, err
	}
	return &connection{
		ClientAddr: cliAddr,
		ServerConn: srvudp,
	}, nil
}

// runProxy listens on the proxy address and handles incoming packets.
func (p *QuicProxy) runProxy() error {
	for {
		buffer := make([]byte, protocol.MaxReceivePacketSize)
		n, cliaddr, err := p.conn.ReadFromUDP(buffer)
		if err != nil {
			return err
		}
		raw := buffer[0:n]

		saddr := cliaddr.String()
		p.mutex.Lock()
		conn, ok := p.clientDict[saddr]

		if !ok {
			conn, err = p.newConnection(cliaddr)
			if err != nil {
				p.mutex.Unlock()
				return err
			}
			p.clientDict[saddr] = conn
			go p.runConnection(conn)
		}
		p.mutex.Unlock()

		packetCount := atomic.AddUint64(&conn.incomingPacketCounter, 1)

		if p.dropPacket(DirectionIncoming, packetCount) {
			if utils.Debug() {
				utils.Debugf("dropping incoming packet %d (%d bytes)", packetCount, n)
			}
			continue
		}

		// Send the packet to the server
		delay := p.delayPacket(DirectionIncoming, packetCount)
		if delay != 0 {
			if utils.Debug() {
				utils.Debugf("delaying incoming packet %d (%d bytes) to %s by %s", packetCount, n, conn.ServerConn.RemoteAddr(), delay)
			}
			time.AfterFunc(delay, func() {
				// TODO: handle error
				_, _ = conn.ServerConn.Write(raw)
			})
		} else {
			if utils.Debug() {
				utils.Debugf("forwarding incoming packet %d (%d bytes) to %s", packetCount, n, conn.ServerConn.RemoteAddr())
			}
			if _, err := conn.ServerConn.Write(raw); err != nil {
				return err
			}
		}
	}
}

// runConnection handles packets from server to a single client
func (p *QuicProxy) runConnection(conn *connection) error {
	for {
		buffer := make([]byte, protocol.MaxReceivePacketSize)
		n, err := conn.ServerConn.Read(buffer)
		if err != nil {
			return err
		}
		raw := buffer[0:n]

		packetCount := atomic.AddUint64(&conn.outgoingPacketCounter, 1)

		if p.dropPacket(DirectionOutgoing, packetCount) {
			if utils.Debug() {
				utils.Debugf("dropping outgoing packet %d (%d bytes)", packetCount, n)
			}
			continue
		}

		delay := p.delayPacket(DirectionOutgoing, packetCount)
		if delay != 0 {
			if utils.Debug() {
				utils.Debugf("delaying outgoing packet %d (%d bytes) to %s by %s", packetCount, n, conn.ClientAddr, delay)
			}
			time.AfterFunc(delay, func() {
				// TODO: handle error
				_, _ = p.conn.WriteToUDP(raw, conn.ClientAddr)
			})
		} else {
			if utils.Debug() {
				utils.Debugf("forwarding outgoing packet %d (%d bytes) to %s", packetCount, n, conn.ClientAddr)
			}
			if _, err := p.conn.WriteToUDP(raw, conn.ClientAddr); err != nil {
				return err
			}
		}
	}
}
<|endoftext|>


<commit_before>/*
Package lmdb provides bindings to the lmdb C API.  The package bindings are
fairly low level and are designed to provide a minimal interface that prevents
misuse up to a reasonable extent.  In general the C documentation should be
used as reference.

	http://symas.com/mdb/doc/group__mdb.html

Experimental

This package is experimental and the API is in flux while core development is
being done and the spartan but volumnous LMDB docs are being completly
deciphered.

Transactions

Readonly transactions in LMDB operate on a snapshot of the database at the time
the transaction began.  The number of simultaneously active read transaction is
bounded and configured when the environment is initialized.

LMDB allows only one read-write transaction to be active at a time.  Attempts
to create write transactions will block until no others write transactions are
active.

LMDB allows read-write transactions to have subtransactions which may be
aborted and rolled back without aborting their parent.  Transactions must not
be used while they have an active subtransaction.

Errors

The errors returned by the package API will with few exceptions have type Errno
or syscall.Errno.  The only errors of type Errno returned are those defined in
lmdb.h, those which have constants defined in this package.  Other errno values
like EINVAL will by of type syscall.Errno.
*/
package lmdb

/*
#cgo CFLAGS: -pthread -W -Wall -Wno-unused-parameter -Wbad-function-cast -O2 -g
#cgo freebsd CFLAGS: -DMDB_DSYNC=O_SYNC
#cgo openbsd CFLAGS: -DMDB_DSYNC=O_SYNC
#cgo netbsd CFLAGS: -DMDB_DSYNC=O_SYNC

#include "lmdb.h"
*/
import "C"

import (
	"fmt"
	"syscall"
)

// Errno represents the class of error defined by LMDB.  The only values of
// type Errno returned by the API are those declared as constants in this
// package.  Other errors resulting from non-zero errno values will be of type
// syscall.Errno.
type Errno C.int

// minimum and maximum values produced for the Errno type. syscall.Errnos of
// other values may still be produced.
const minErrno, maxErrno C.int = C.MDB_KEYEXIST, C.MDB_LAST_ERRCODE

func (e Errno) Error() string {
	s := C.GoString(C.mdb_strerror(C.int(e)))
	if s == "" {
		return fmt.Sprint("mdb errno:", int(e))
	}
	return s
}

// _errno is for use by tests that can't import C
func _errno(ret int) error {
	return errno(C.int(ret))
}

// errno transforms an integer returned by the LMDB C API into an error value,
// which may be nil.
func errno(ret C.int) error {
	if ret == C.MDB_SUCCESS {
		return nil
	}
	if minErrno <= ret && ret <= maxErrno {
		return Errno(ret)
	}
	return syscall.Errno(ret)
}

// The set of error codes defined by LMDB are typed constants.
const (
	ErrKeyExist        Errno = C.MDB_KEYEXIST
	ErrNotFound        Errno = C.MDB_NOTFOUND
	ErrPageNotFound    Errno = C.MDB_PAGE_NOTFOUND
	ErrCorrupted       Errno = C.MDB_CORRUPTED
	ErrPanic           Errno = C.MDB_PANIC
	ErrVersionMismatch Errno = C.MDB_VERSION_MISMATCH
	ErrInvalid         Errno = C.MDB_INVALID
	ErrMapFull         Errno = C.MDB_MAP_FULL
	ErrDBsFull         Errno = C.MDB_DBS_FULL
	ErrReadersFull     Errno = C.MDB_READERS_FULL
	ErrTLSFull         Errno = C.MDB_TLS_FULL
	ErrTxnFull         Errno = C.MDB_TXN_FULL
	ErrCursorFull      Errno = C.MDB_CURSOR_FULL
	ErrPageFull        Errno = C.MDB_PAGE_FULL
	ErrMapResized      Errno = C.MDB_MAP_RESIZED
	ErrIncompatibile   Errno = C.MDB_INCOMPATIBLE
)

// Version returns a string representation of the LMDB version.
//
// See mdb_version.
func Version() string {
	var major, minor, patch *C.int
	ver_str := C.mdb_version(major, minor, patch)
	return C.GoString(ver_str)
}

func cbool(b bool) C.int {
	if b {
		return 1
	}
	return 0
}
<commit_msg>godoc: more about transactions<commit_after>/*
Package lmdb provides bindings to the lmdb C API.  The package bindings are
fairly low level and are designed to provide a minimal interface that prevents
misuse to a reasonable extent.  When in doubt refer to the C documentation as a
reference.

	http://symas.com/mdb/doc/group__mdb.html

Experimental

This package is experimental and the API is in flux while core development is
being done and the spartan but volumnous LMDB docs are being completly
deciphered.

Transactions

Readonly transactions in LMDB operate on a snapshot of the database at the time
the transaction began.  The number of simultaneously active read transaction is
bounded and configured when the environment is initialized.

LMDB allows only one read-write transaction to be active at a time.  Attempts
to create write transactions will block until no other write transactions are
active.

LMDB allows read-write transactions to have subtransactions which may be
aborted and rolled back without aborting their parent.  Transactions cannot be
used while they have an active subtransaction.

The lmdb package supplies managed, and unmanaged transaction types. Managed
transactions which do not require explicit calling of Abort()/Commit() are
provided through Env methods Update(), View(), and RunTxn(). Unmanaged readonly
transactions created with the method BeginView() and unmanaged readwrite
transactions with BeginUpdate().

Errors

The errors returned by the package API will with few exceptions have type Errno
or syscall.Errno.  The only errors of type Errno returned are those defined in
lmdb.h, those which have constants defined in this package.  Other errno values
like EINVAL will by of type syscall.Errno.
*/
package lmdb

/*
#cgo CFLAGS: -pthread -W -Wall -Wno-unused-parameter -Wbad-function-cast -O2 -g
#cgo freebsd CFLAGS: -DMDB_DSYNC=O_SYNC
#cgo openbsd CFLAGS: -DMDB_DSYNC=O_SYNC
#cgo netbsd CFLAGS: -DMDB_DSYNC=O_SYNC

#include "lmdb.h"
*/
import "C"

import (
	"fmt"
	"syscall"
)

// Errno represents the class of error defined by LMDB.  The only values of
// type Errno returned by the API are those declared as constants in this
// package.  Other errors resulting from non-zero errno values will be of type
// syscall.Errno.
type Errno C.int

// minimum and maximum values produced for the Errno type. syscall.Errnos of
// other values may still be produced.
const minErrno, maxErrno C.int = C.MDB_KEYEXIST, C.MDB_LAST_ERRCODE

func (e Errno) Error() string {
	s := C.GoString(C.mdb_strerror(C.int(e)))
	if s == "" {
		return fmt.Sprint("mdb errno:", int(e))
	}
	return s
}

// _errno is for use by tests that can't import C
func _errno(ret int) error {
	return errno(C.int(ret))
}

// errno transforms an integer returned by the LMDB C API into an error value,
// which may be nil.
func errno(ret C.int) error {
	if ret == C.MDB_SUCCESS {
		return nil
	}
	if minErrno <= ret && ret <= maxErrno {
		return Errno(ret)
	}
	return syscall.Errno(ret)
}

// The set of error codes defined by LMDB are typed constants.
const (
	ErrKeyExist        Errno = C.MDB_KEYEXIST
	ErrNotFound        Errno = C.MDB_NOTFOUND
	ErrPageNotFound    Errno = C.MDB_PAGE_NOTFOUND
	ErrCorrupted       Errno = C.MDB_CORRUPTED
	ErrPanic           Errno = C.MDB_PANIC
	ErrVersionMismatch Errno = C.MDB_VERSION_MISMATCH
	ErrInvalid         Errno = C.MDB_INVALID
	ErrMapFull         Errno = C.MDB_MAP_FULL
	ErrDBsFull         Errno = C.MDB_DBS_FULL
	ErrReadersFull     Errno = C.MDB_READERS_FULL
	ErrTLSFull         Errno = C.MDB_TLS_FULL
	ErrTxnFull         Errno = C.MDB_TXN_FULL
	ErrCursorFull      Errno = C.MDB_CURSOR_FULL
	ErrPageFull        Errno = C.MDB_PAGE_FULL
	ErrMapResized      Errno = C.MDB_MAP_RESIZED
	ErrIncompatibile   Errno = C.MDB_INCOMPATIBLE
)

// Version returns a string representation of the LMDB version.
//
// See mdb_version.
func Version() string {
	var major, minor, patch *C.int
	ver_str := C.mdb_version(major, minor, patch)
	return C.GoString(ver_str)
}

func cbool(b bool) C.int {
	if b {
		return 1
	}
	return 0
}
<|endoftext|>


<commit_before>package getproviders

import (
	"fmt"
	"regexp"
	"strings"

	svchost "github.com/hashicorp/terraform-svchost"

	"github.com/hashicorp/terraform/addrs"
)

// MultiSource is a Source that wraps a series of other sources and combines
// their sets of available providers and provider versions.
//
// A MultiSource consists of a sequence of selectors that each specify an
// underlying source to query and a set of matching patterns to decide which
// providers can be retrieved from which sources. If multiple selectors find
// a given provider version then the earliest one in the sequence takes
// priority for deciding the package metadata for the provider.
//
// For underlying sources that make network requests, consider wrapping each
// one in a MemoizeSource so that availability information retrieved in
// AvailableVersions can be reused in PackageMeta.
type MultiSource []MultiSourceSelector

var _ Source = MultiSource(nil)

// AvailableVersions retrieves all of the versions of the given provider
// that are available across all of the underlying selectors, while respecting
// each selector's matching patterns.
func (s MultiSource) AvailableVersions(provider addrs.Provider) (VersionList, error) {
	// TODO: Implement
	panic("MultiSource.AvailableVersions not yet implemented")
}

// PackageMeta retrieves the package metadata for the given provider from the
// first selector that indicates support for it.
func (s MultiSource) PackageMeta(provider addrs.Provider, version Version, target Platform) (PackageMeta, error) {
	// TODO: Implement
	panic("MultiSource.PackageMeta not yet implemented")
}

// MultiSourceSelector is an element of the source selection configuration on
// MultiSource. A MultiSource has zero or more of these to configure which
// underlying sources it should consult for a given provider.
type MultiSourceSelector struct {
	// Source is the underlying source that this selector applies to.
	Source Source

	// Include and Exclude are sets of provider matching patterns that
	// together define which providers are eligible to be potentially
	// installed from the corresponding Source.
	Include, Exclude MultiSourceMatchingPatterns
}

// MultiSourceMatchingPatterns is a set of patterns that together define a
// set of providers by matching on the segments of the provider FQNs.
//
// The Provider address values in a MultiSourceMatchingPatterns are special in
// that any of Hostname, Namespace, or Type can be getproviders.Wildcard
// to indicate that any concrete value is permitted for that segment.
type MultiSourceMatchingPatterns []addrs.Provider

// ParseMultiSourceMatchingPatterns parses a slice of strings containing the
// string form of provider matching patterns and, if all the given strings
// are valid, returns the corresponding MultiSourceMatchingPatterns value.
func ParseMultiSourceMatchingPatterns(strs []string) (MultiSourceMatchingPatterns, error) {
	if len(strs) == 0 {
		return nil, nil
	}

	ret := make(MultiSourceMatchingPatterns, len(strs))
	for i, str := range strs {
		parts := strings.Split(str, "/")
		if len(parts) < 2 || len(parts) > 3 {
			return nil, fmt.Errorf("invalid provider matching pattern %q: must have either two or three slash-separated segments", str)
		}
		host := defaultRegistryHost
		explicitHost := len(parts) == 3
		if explicitHost {
			givenHost := parts[0]
			if givenHost == "*" {
				host = svchost.Hostname(Wildcard)
			} else {
				normalHost, err := svchost.ForComparison(givenHost)
				if err != nil {
					return nil, fmt.Errorf("invalid hostname in provider matching pattern %q: %s", str, err)
				}

				// The remaining code below deals only with the namespace/type portions.
				host = normalHost
			}

			parts = parts[1:]
		}

		if !validProviderNamePattern.MatchString(parts[1]) {
			return nil, fmt.Errorf("invalid provider type %q in provider matching pattern %q: must either be the wildcard * or a provider type name", parts[1], str)
		}
		if !validProviderNamePattern.MatchString(parts[0]) {
			return nil, fmt.Errorf("invalid registry namespace %q in provider matching pattern %q: must either be the wildcard * or a literal namespace", parts[1], str)
		}

		ret[i] = addrs.Provider{
			Hostname:  host,
			Namespace: parts[0],
			Type:      parts[1],
		}

		if ret[i].Hostname == svchost.Hostname(Wildcard) && !(ret[i].Namespace == Wildcard && ret[i].Type == Wildcard) {
			return nil, fmt.Errorf("invalid provider matching pattern %q: hostname can be a wildcard only if both namespace and provider type are also wildcards", str)
		}
		if ret[i].Namespace == Wildcard && ret[i].Type != Wildcard {
			return nil, fmt.Errorf("invalid provider matching pattern %q: namespace can be a wildcard only if the provider type is also a wildcard", str)
		}
	}
	return ret, nil
}

// CanHandleProvider returns true if and only if the given provider address
// is both included by the selector's include patterns and _not_ excluded
// by its exclude patterns.
//
// The absense of any include patterns is treated the same as a pattern
// that matches all addresses. Exclusions take priority over inclusions.
func (s MultiSourceSelector) CanHandleProvider(addr addrs.Provider) bool {
	switch {
	case s.Exclude.MatchesProvider(addr):
		return false
	case len(s.Include) > 0:
		return s.Include.MatchesProvider(addr)
	default:
		return true
	}
}

// MatchesProvider tests whether the receiving matching patterns match with
// the given concrete provider address.
func (ps MultiSourceMatchingPatterns) MatchesProvider(addr addrs.Provider) bool {
	for _, pattern := range ps {
		hostMatch := (pattern.Hostname == svchost.Hostname(Wildcard) || pattern.Hostname == addr.Hostname)
		namespaceMatch := (pattern.Namespace == Wildcard || pattern.Namespace == addr.Namespace)
		typeMatch := (pattern.Type == Wildcard || pattern.Type == addr.Type)
		if hostMatch && namespaceMatch && typeMatch {
			return true
		}
	}
	return false
}

// Wildcard is a string value representing a wildcard element in the Include
// and Exclude patterns used with MultiSource. It is not valid to use Wildcard
// anywhere else.
const Wildcard string = "*"

// We'll read the default registry host from over in the addrs package, to
// avoid duplicating it. A "default" provider uses the default registry host
// by definition.
var defaultRegistryHost = addrs.NewDefaultProvider("placeholder").Hostname

var validProviderNamePattern = regexp.MustCompile("^[a-zA-Z0-9_-]+|\\*$")
<commit_msg>internal/getproviders: Exit early if MultiSource has no sources<commit_after>package getproviders

import (
	"fmt"
	"regexp"
	"strings"

	svchost "github.com/hashicorp/terraform-svchost"

	"github.com/hashicorp/terraform/addrs"
)

// MultiSource is a Source that wraps a series of other sources and combines
// their sets of available providers and provider versions.
//
// A MultiSource consists of a sequence of selectors that each specify an
// underlying source to query and a set of matching patterns to decide which
// providers can be retrieved from which sources. If multiple selectors find
// a given provider version then the earliest one in the sequence takes
// priority for deciding the package metadata for the provider.
//
// For underlying sources that make network requests, consider wrapping each
// one in a MemoizeSource so that availability information retrieved in
// AvailableVersions can be reused in PackageMeta.
type MultiSource []MultiSourceSelector

var _ Source = MultiSource(nil)

// AvailableVersions retrieves all of the versions of the given provider
// that are available across all of the underlying selectors, while respecting
// each selector's matching patterns.
func (s MultiSource) AvailableVersions(provider addrs.Provider) (VersionList, error) {
	if len(s) == 0 { // Easy case: there can be no available versions
		return nil, nil
	}

	// TODO: Implement
	panic("MultiSource.AvailableVersions not yet implemented")
}

// PackageMeta retrieves the package metadata for the given provider from the
// first selector that indicates support for it.
func (s MultiSource) PackageMeta(provider addrs.Provider, version Version, target Platform) (PackageMeta, error) {
	if len(s) == 0 { // Easy case: no providers exist at all
		return PackageMeta{}, ErrProviderNotKnown{provider}
	}

	// TODO: Implement
	panic("MultiSource.PackageMeta not yet implemented")
}

// MultiSourceSelector is an element of the source selection configuration on
// MultiSource. A MultiSource has zero or more of these to configure which
// underlying sources it should consult for a given provider.
type MultiSourceSelector struct {
	// Source is the underlying source that this selector applies to.
	Source Source

	// Include and Exclude are sets of provider matching patterns that
	// together define which providers are eligible to be potentially
	// installed from the corresponding Source.
	Include, Exclude MultiSourceMatchingPatterns
}

// MultiSourceMatchingPatterns is a set of patterns that together define a
// set of providers by matching on the segments of the provider FQNs.
//
// The Provider address values in a MultiSourceMatchingPatterns are special in
// that any of Hostname, Namespace, or Type can be getproviders.Wildcard
// to indicate that any concrete value is permitted for that segment.
type MultiSourceMatchingPatterns []addrs.Provider

// ParseMultiSourceMatchingPatterns parses a slice of strings containing the
// string form of provider matching patterns and, if all the given strings
// are valid, returns the corresponding MultiSourceMatchingPatterns value.
func ParseMultiSourceMatchingPatterns(strs []string) (MultiSourceMatchingPatterns, error) {
	if len(strs) == 0 {
		return nil, nil
	}

	ret := make(MultiSourceMatchingPatterns, len(strs))
	for i, str := range strs {
		parts := strings.Split(str, "/")
		if len(parts) < 2 || len(parts) > 3 {
			return nil, fmt.Errorf("invalid provider matching pattern %q: must have either two or three slash-separated segments", str)
		}
		host := defaultRegistryHost
		explicitHost := len(parts) == 3
		if explicitHost {
			givenHost := parts[0]
			if givenHost == "*" {
				host = svchost.Hostname(Wildcard)
			} else {
				normalHost, err := svchost.ForComparison(givenHost)
				if err != nil {
					return nil, fmt.Errorf("invalid hostname in provider matching pattern %q: %s", str, err)
				}

				// The remaining code below deals only with the namespace/type portions.
				host = normalHost
			}

			parts = parts[1:]
		}

		if !validProviderNamePattern.MatchString(parts[1]) {
			return nil, fmt.Errorf("invalid provider type %q in provider matching pattern %q: must either be the wildcard * or a provider type name", parts[1], str)
		}
		if !validProviderNamePattern.MatchString(parts[0]) {
			return nil, fmt.Errorf("invalid registry namespace %q in provider matching pattern %q: must either be the wildcard * or a literal namespace", parts[1], str)
		}

		ret[i] = addrs.Provider{
			Hostname:  host,
			Namespace: parts[0],
			Type:      parts[1],
		}

		if ret[i].Hostname == svchost.Hostname(Wildcard) && !(ret[i].Namespace == Wildcard && ret[i].Type == Wildcard) {
			return nil, fmt.Errorf("invalid provider matching pattern %q: hostname can be a wildcard only if both namespace and provider type are also wildcards", str)
		}
		if ret[i].Namespace == Wildcard && ret[i].Type != Wildcard {
			return nil, fmt.Errorf("invalid provider matching pattern %q: namespace can be a wildcard only if the provider type is also a wildcard", str)
		}
	}
	return ret, nil
}

// CanHandleProvider returns true if and only if the given provider address
// is both included by the selector's include patterns and _not_ excluded
// by its exclude patterns.
//
// The absense of any include patterns is treated the same as a pattern
// that matches all addresses. Exclusions take priority over inclusions.
func (s MultiSourceSelector) CanHandleProvider(addr addrs.Provider) bool {
	switch {
	case s.Exclude.MatchesProvider(addr):
		return false
	case len(s.Include) > 0:
		return s.Include.MatchesProvider(addr)
	default:
		return true
	}
}

// MatchesProvider tests whether the receiving matching patterns match with
// the given concrete provider address.
func (ps MultiSourceMatchingPatterns) MatchesProvider(addr addrs.Provider) bool {
	for _, pattern := range ps {
		hostMatch := (pattern.Hostname == svchost.Hostname(Wildcard) || pattern.Hostname == addr.Hostname)
		namespaceMatch := (pattern.Namespace == Wildcard || pattern.Namespace == addr.Namespace)
		typeMatch := (pattern.Type == Wildcard || pattern.Type == addr.Type)
		if hostMatch && namespaceMatch && typeMatch {
			return true
		}
	}
	return false
}

// Wildcard is a string value representing a wildcard element in the Include
// and Exclude patterns used with MultiSource. It is not valid to use Wildcard
// anywhere else.
const Wildcard string = "*"

// We'll read the default registry host from over in the addrs package, to
// avoid duplicating it. A "default" provider uses the default registry host
// by definition.
var defaultRegistryHost = addrs.NewDefaultProvider("placeholder").Hostname

var validProviderNamePattern = regexp.MustCompile("^[a-zA-Z0-9_-]+|\\*$")
<|endoftext|>


<commit_before>package repository

import (
	"context"
	"runtime"
	"sync"

	"github.com/restic/restic/internal/debug"
	"github.com/restic/restic/internal/restic"
	"golang.org/x/sync/errgroup"
)

// ForAllIndexes loads all index files in parallel and calls the given callback.
// It is guaranteed that the function is not run concurrently. If the callback
// returns an error, this function is cancelled and also returns that error.
func ForAllIndexes(ctx context.Context, repo restic.Repository,
	fn func(id restic.ID, index *Index, oldFormat bool, err error) error) error {

	debug.Log("Start")

	type FileInfo struct {
		restic.ID
		Size int64
	}

	var m sync.Mutex

	// track spawned goroutines using wg, create a new context which is
	// cancelled as soon as an error occurs.
	wg, ctx := errgroup.WithContext(ctx)

	ch := make(chan FileInfo)
	// send list of index files through ch, which is closed afterwards
	wg.Go(func() error {
		defer close(ch)
		return repo.List(ctx, restic.IndexFile, func(id restic.ID, size int64) error {
			select {
			case <-ctx.Done():
				return ctx.Err()
			case ch <- FileInfo{id, size}:
			}
			return nil
		})
	})

	// a worker receives an index ID from ch, loads the index, and sends it to indexCh
	worker := func() error {
		var buf []byte
		for fi := range ch {
			debug.Log("worker got file %v", fi.ID.Str())
			var err error
			var idx *Index
			oldFormat := false

			buf, err = repo.LoadUnpacked(ctx, restic.IndexFile, fi.ID, buf[:0])
			if err == nil {
				idx, oldFormat, err = DecodeIndex(buf, fi.ID)
			}

			m.Lock()
			err = fn(fi.ID, idx, oldFormat, err)
			m.Unlock()
			if err != nil {
				return err
			}
		}
		return nil
	}

	// decoding an index can take quite some time such that this can be both CPU- or IO-bound
	// as the whole index is kept in memory anyways, a few workers too much don't matter
	workerCount := int(repo.Connections()) + runtime.GOMAXPROCS(0)
	// run workers on ch
	for i := 0; i < workerCount; i++ {
		wg.Go(worker)
	}

	return wg.Wait()
}
<commit_msg>repository: Reduce buffer reallocations in ForAllIndexes<commit_after>package repository

import (
	"context"
	"runtime"
	"sync"

	"github.com/restic/restic/internal/debug"
	"github.com/restic/restic/internal/restic"
	"golang.org/x/sync/errgroup"
)

// ForAllIndexes loads all index files in parallel and calls the given callback.
// It is guaranteed that the function is not run concurrently. If the callback
// returns an error, this function is cancelled and also returns that error.
func ForAllIndexes(ctx context.Context, repo restic.Repository,
	fn func(id restic.ID, index *Index, oldFormat bool, err error) error) error {

	debug.Log("Start")

	type FileInfo struct {
		restic.ID
		Size int64
	}

	var m sync.Mutex

	// track spawned goroutines using wg, create a new context which is
	// cancelled as soon as an error occurs.
	wg, ctx := errgroup.WithContext(ctx)

	ch := make(chan FileInfo)
	// send list of index files through ch, which is closed afterwards
	wg.Go(func() error {
		defer close(ch)
		return repo.List(ctx, restic.IndexFile, func(id restic.ID, size int64) error {
			select {
			case <-ctx.Done():
				return ctx.Err()
			case ch <- FileInfo{id, size}:
			}
			return nil
		})
	})

	// a worker receives an index ID from ch, loads the index, and sends it to indexCh
	worker := func() error {
		var buf []byte
		for fi := range ch {
			debug.Log("worker got file %v", fi.ID.Str())
			var err error
			var idx *Index
			oldFormat := false

			if cap(buf) < int(fi.Size) {
				// overallocate a bit
				buf = make([]byte, fi.Size+128*1024)
			}
			buf, err = repo.LoadUnpacked(ctx, restic.IndexFile, fi.ID, buf[:0])
			if err == nil {
				idx, oldFormat, err = DecodeIndex(buf, fi.ID)
			}

			m.Lock()
			err = fn(fi.ID, idx, oldFormat, err)
			m.Unlock()
			if err != nil {
				return err
			}
		}
		return nil
	}

	// decoding an index can take quite some time such that this can be both CPU- or IO-bound
	// as the whole index is kept in memory anyways, a few workers too much don't matter
	workerCount := int(repo.Connections()) + runtime.GOMAXPROCS(0)
	// run workers on ch
	for i := 0; i < workerCount; i++ {
		wg.Go(worker)
	}

	return wg.Wait()
}
<|endoftext|>


<commit_before>// Copyright 2016 The Upspin 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 tree // import "upspin.io/dir/server/tree"

// This file implements block reading and writing.

import (
	"upspin.io/bind"
	"upspin.io/errors"
	"upspin.io/path"
	"upspin.io/upspin"
)

// store stores a node to the StoreServer. It does not reset the dirty bit.
// Children of n, if any, must not be dirty.
func (t *Tree) store(n *node) error {
	// Get our store server.
	storeServer, err := bind.StoreServer(t.config, t.config.StoreEndpoint())
	if err != nil {
		return err
	}

	// Use our preferred packing
	packer := t.packer

	// Can't pack a non-dir entry. Something went bad if we got here.
	if !n.entry.IsDir() {
		err := errors.E(errors.Internal, errors.Str("can't pack non-dir entry"))
		return err
	}

	// Prepare the dirEntry
	n.entry.Blocks = nil // if any blocks existed, their references are lost as we're packing dirEntry again.
	n.entry.Packing = t.config.Packing()
	n.entry.Time = upspin.Now()
	n.entry.Writer = t.config.UserName()
	// Sequence number is already up-to-date (see setNodeDirtyAt).

	// Start packing.
	bp, err := packer.Pack(t.config, &n.entry)
	if err != nil {
		return errors.E(err)
	}

	// Pack and store child nodes, keeping blocks at ~BlockSize.
	var data []byte
	for _, kid := range n.kids {
		// TODO: also check whether there are any Blocks with empty locations that are non-empty dirs or files.
		if kid.dirty {
			// We should write nodes from the bottom up, so this should never happen.
			return errors.E(kid.entry.Name, errors.Internal, errors.Str("kid node is dirty"))
		}
		block, err := kid.entry.Marshal()
		if err != nil {
			return errors.E(err)
		}

		// Don't let blocks grow too much (but we never split a large DirEntry in the middle).
		if len(data) > 0 && len(data)+len(block) > upspin.BlockSize {
			// Flush now.
			err = storeBlock(storeServer, bp, data)
			if err != nil {
				return errors.E(err)
			}
			data = data[:0]
		}
		data = append(data, block...)
	}
	// Put remaining data.
	if len(data) > 0 {
		err = storeBlock(storeServer, bp, data)
		if err != nil {
			return errors.E(err)
		}
	}
	err = bp.Close()
	if err != nil {
		return errors.E(err)
	}
	return nil
}

// storeBlock stores a single block of data to the StoreServer as part of a block packing operation.
func storeBlock(store upspin.StoreServer, bp upspin.BlockPacker, data []byte) error {
	cipher, err := bp.Pack(data)
	if err != nil {
		return err
	}
	refdata, err := store.Put(cipher)
	if err != nil {
		return err
	}
	loc := upspin.Location{
		Endpoint:  store.Endpoint(),
		Reference: refdata.Reference,
	}
	bp.SetLocation(loc)
	return nil
}

// loadKidsFromBlock unmarshals a block of packed dirEntries into a node.
func loadKidsFromBlock(n *node, block []byte) error {
	if n.kids == nil {
		n.kids = make(map[string]*node)
	}
	if n.dirty {
		err := errors.E(errors.Internal, n.entry.Name,
			errors.Str("trying to load a block from storage when the node is dirty"))
		return err
	}
	nodePath, err := path.Parse(n.entry.Name)
	if err != nil {
		return err
	}
	if len(n.kids) > 0 {
		// This means we're trying to load an existing DirEntry onto
		// a directory that has content already. To allow it, we would
		// need to check for name collisions. Disallow for now.
		err := errors.E(errors.Invalid, nodePath.Path(), errors.Str("cannot hide existing contents of path with new block"))
		return err
	}
	if n.entry.Name == "" {
		err := errors.E(errors.Internal, errors.Str("empty entry name"))
		return err
	}
	// Load children for this node.
	elemPos := nodePath.NElem()
	for len(block) > 0 {
		var entry upspin.DirEntry
		remaining, err := entry.Unmarshal(block)
		if err != nil {
			return errors.E(err)
		}
		block = remaining

		// Process this entry.
		p, err := path.Parse(entry.Name)
		if err != nil {
			return errors.E(err)
		}
		// elem is the next pathwise element to load. Normally, it's the
		// next element in entryPath. But if it's a directory that
		// doesn't conform with the parent name, we allow it, to support
		// snapshots and other types of "redirected" directories. But we
		// must patch it according to this tree's perspective.
		var elem string
		if p.Drop(1).Equal(nodePath) {
			elem = p.Elem(elemPos)
		} else {
			// If the block being loaded is not a prefix of the
			// parent, then it's a "redirection" such as a snapshot
			// entry.
			elem = p.Elem(p.NElem() - 1) // ok, never root.
			// Patch the entry's Name, so it belongs to this tree.
			entry.Name = path.Join(nodePath.Path(), elem)
		}
		if _, exists := n.kids[elem]; exists {
			// Trying to re-add an existing child. Something is amiss.
			err := errors.E(errors.Internal, n.entry.Name,
				errors.Str("re-adding an existing element in the Tree"))
			return err
		}
		n.kids[elem] = &node{
			entry: entry,
		}
	}
	return nil
}
<commit_msg>dir/server/tree: add more error checking<commit_after>// Copyright 2016 The Upspin 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 tree // import "upspin.io/dir/server/tree"

// This file implements block reading and writing.

import (
	"upspin.io/bind"
	"upspin.io/errors"
	"upspin.io/path"
	"upspin.io/upspin"
)

// store stores a node to the StoreServer. It does not reset the dirty bit.
// Children of n, if any, must not be dirty.
func (t *Tree) store(n *node) error {
	// Get our store server.
	storeServer, err := bind.StoreServer(t.config, t.config.StoreEndpoint())
	if err != nil {
		return err
	}

	// Use our preferred packing
	packer := t.packer

	// Can't pack a non-dir entry. Something went bad if we got here.
	if !n.entry.IsDir() {
		err := errors.E(errors.Internal, errors.Str("can't pack non-dir entry"))
		return err
	}

	// Prepare the dirEntry
	n.entry.Blocks = nil // if any blocks existed, their references are lost as we're packing dirEntry again.
	n.entry.Packing = t.config.Packing()
	n.entry.Time = upspin.Now()
	n.entry.Writer = t.config.UserName()
	// Sequence number is already up-to-date (see setNodeDirtyAt).

	// Start packing.
	bp, err := packer.Pack(t.config, &n.entry)
	if err != nil {
		return errors.E(err)
	}

	// Pack and store child nodes, keeping blocks at ~BlockSize.
	var data []byte
	for _, kid := range n.kids {
		if kid.dirty {
			// We should write nodes from the bottom up, so this should never happen.
			return errors.E(kid.entry.Name, errors.Internal, errors.Str("kid node is dirty"))
		}
		// Check whether there are any empty Blocks or locations that
		// are non-empty dirs or files.
		if len(kid.kids) != 0 {
			for _, b := range kid.entry.Blocks {
				if len(b.Location.Reference) == 0 || b.Size == 0 {
					return errors.E(kid.entry.Name, errors.Internal, errors.Str("empty directory block when there exist kid blocks"))
				}
			}
		}
		block, err := kid.entry.Marshal()
		if err != nil {
			return errors.E(err)
		}

		// Don't let blocks grow too much (but we never split a large DirEntry in the middle).
		if len(data) > 0 && len(data)+len(block) > upspin.BlockSize {
			// Flush now.
			err = storeBlock(storeServer, bp, data)
			if err != nil {
				return errors.E(err)
			}
			data = data[:0]
		}
		data = append(data, block...)
	}
	// Put remaining data.
	if len(data) > 0 {
		err = storeBlock(storeServer, bp, data)
		if err != nil {
			return errors.E(err)
		}
	}
	err = bp.Close()
	if err != nil {
		return errors.E(err)
	}
	return nil
}

// storeBlock stores a single block of data to the StoreServer as part of a block packing operation.
func storeBlock(store upspin.StoreServer, bp upspin.BlockPacker, data []byte) error {
	cipher, err := bp.Pack(data)
	if err != nil {
		return err
	}
	refdata, err := store.Put(cipher)
	if err != nil {
		return err
	}
	loc := upspin.Location{
		Endpoint:  store.Endpoint(),
		Reference: refdata.Reference,
	}
	bp.SetLocation(loc)
	return nil
}

// loadKidsFromBlock unmarshals a block of packed dirEntries into a node.
func loadKidsFromBlock(n *node, block []byte) error {
	if n.kids == nil {
		n.kids = make(map[string]*node)
	}
	if n.dirty {
		err := errors.E(errors.Internal, n.entry.Name,
			errors.Str("trying to load a block from storage when the node is dirty"))
		return err
	}
	nodePath, err := path.Parse(n.entry.Name)
	if err != nil {
		return err
	}
	if len(n.kids) > 0 {
		// This means we're trying to load an existing DirEntry onto
		// a directory that has content already. To allow it, we would
		// need to check for name collisions. Disallow for now.
		err := errors.E(errors.Invalid, nodePath.Path(), errors.Str("cannot hide existing contents of path with new block"))
		return err
	}
	if n.entry.Name == "" {
		err := errors.E(errors.Internal, errors.Str("empty entry name"))
		return err
	}
	// Load children for this node.
	elemPos := nodePath.NElem()
	for len(block) > 0 {
		var entry upspin.DirEntry
		remaining, err := entry.Unmarshal(block)
		if err != nil {
			return errors.E(err)
		}
		block = remaining

		// Process this entry.
		p, err := path.Parse(entry.Name)
		if err != nil {
			return errors.E(err)
		}
		// elem is the next pathwise element to load. Normally, it's the
		// next element in entryPath. But if it's a directory that
		// doesn't conform with the parent name, we allow it, to support
		// snapshots and other types of "redirected" directories. But we
		// must patch it according to this tree's perspective.
		var elem string
		if p.Drop(1).Equal(nodePath) {
			elem = p.Elem(elemPos)
		} else {
			// If the block being loaded is not a prefix of the
			// parent, then it's a "redirection" such as a snapshot
			// entry.
			elem = p.Elem(p.NElem() - 1) // ok, never root.
			// Patch the entry's Name, so it belongs to this tree.
			entry.Name = path.Join(nodePath.Path(), elem)
		}
		if _, exists := n.kids[elem]; exists {
			// Trying to re-add an existing child. Something is amiss.
			err := errors.E(errors.Internal, n.entry.Name,
				errors.Str("re-adding an existing element in the Tree"))
			return err
		}
		n.kids[elem] = &node{
			entry: entry,
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"

	"github.com/boltdb/bolt"
	"github.com/gorilla/mux"
)

func main() {
	r := mux.NewRouter()
	apiR := r.PathPrefix("/api/").Subrouter()

	db, err := bolt.Open("records.bolt", 0600, &bolt.Options{Timeout: 1})
	if err != nil {
		log.Fatalf("Failed to open bolt database, err: %s", err)
	}

	gprdb, err := NewPreRegBoltDb(db)
	if err != nil {
		log.Fatalf("Failed to get group preregistration database started, err %s", err)
	}

	ces := NewConfirmationEmailService("registration.cubjamboree.ca", "no-reply@cubjamboree.ca", "info@cubjamboree.ca", NewLocalMailder("localhost:25"), gprdb)

	NewGroupPreRegistrationHandler(apiR, gprdb, ces)

	http.Handle("/api/", r)
	http.Handle("/", http.FileServer(http.Dir("../app")))
	panic(http.ListenAndServe(":8080", nil))
}
<commit_msg>Use full email server address.<commit_after>package main

import (
	"log"
	"net/http"

	"github.com/boltdb/bolt"
	"github.com/gorilla/mux"
)

func main() {
	r := mux.NewRouter()
	apiR := r.PathPrefix("/api/").Subrouter()

	db, err := bolt.Open("records.bolt", 0600, &bolt.Options{Timeout: 1})
	if err != nil {
		log.Fatalf("Failed to open bolt database, err: %s", err)
	}

	gprdb, err := NewPreRegBoltDb(db)
	if err != nil {
		log.Fatalf("Failed to get group preregistration database started, err %s", err)
	}

	ces := NewConfirmationEmailService("registration.cubjamboree.ca", "no-reply@cubjamboree.ca", "info@cubjamboree.ca", NewLocalMailder("smtp.mjdsystems.ca:25"), gprdb)

	NewGroupPreRegistrationHandler(apiR, gprdb, ces)

	http.Handle("/api/", r)
	http.Handle("/", http.FileServer(http.Dir("../app")))
	panic(http.ListenAndServe(":8080", nil))
}
<|endoftext|>


<commit_before>package backendpool

import (
	"testing"

	pb_resolvers "github.com/mwitkow/kedge/_protogen/kedge/config/common/resolvers"
	pb "github.com/mwitkow/kedge/_protogen/kedge/config/grpc/backends"
	"github.com/sirupsen/logrus"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestDynamic_Operations(t *testing.T) {
	d := NewDynamic(logrus.New())
	d.backendFactory = func(config *pb.Backend) (*backend, error) {
		return &backend{config: config}, nil
	}
	assert.Len(t, d.Configs(), 0, "at first there needs to be nothing")
	err := d.AddOrUpdate(
		&pb.Backend{
			Name: "foobar", DisableConntracking: true, Resolver: &pb.Backend_K8S{
				K8S: &pb_resolvers.K8SResolver{
					DnsPortName: "some:port",
				},
			},
		},
		false,
	)
	require.NoError(t, err)
	assert.True(t, changed)

	changed, err = d.AddOrUpdate(&pb.Backend{Name: "carbar", DisableConntracking: true}, false)
	require.NoError(t, err)
	assert.True(t, changed)

	assert.Len(t, d.Configs(), 2, "we should have two")
	oldCarBar := d.backends["carbar"]
	changed, err = d.AddOrUpdate(&pb.Backend{Name: "carbar"}, false)
	require.NoError(t, err)
	assert.True(t, changed)
	assert.True(t, oldCarBar.closed, "oldCarBar should enter closed state")
	assert.Len(t, d.Configs(), 2, "we should still two")

	// Add totally the same one.
	changed, err = d.AddOrUpdate(
		&pb.Backend{
			Name: "foobar", DisableConntracking: true, Resolver: &pb.Backend_K8S{
				K8S: &pb_resolvers.K8SResolver{
					DnsPortName: "some:port",
				},
			},
		},
		false,
	)
	require.NoError(t, err)
	assert.False(t, changed, "We tried to update totally the same backend, it should not change.")

	assert.Error(t, d.Remove("nonexisting"), "removing a non existing backend should return error")
	assert.NoError(t, d.Remove("foobar"), "removing a non existing backend should return error")
	assert.Len(t, d.Configs(), 1, "we now should have two")
}
<commit_msg>Fixed test.<commit_after>package backendpool

import (
	"testing"

	pb_resolvers "github.com/mwitkow/kedge/_protogen/kedge/config/common/resolvers"
	pb "github.com/mwitkow/kedge/_protogen/kedge/config/grpc/backends"
	"github.com/sirupsen/logrus"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestDynamic_Operations(t *testing.T) {
	d := NewDynamic(logrus.New())
	d.backendFactory = func(config *pb.Backend) (*backend, error) {
		return &backend{config: config}, nil
	}
	assert.Len(t, d.Configs(), 0, "at first there needs to be nothing")
	changed, err := d.AddOrUpdate(
		&pb.Backend{
			Name: "foobar", DisableConntracking: true, Resolver: &pb.Backend_K8S{
				K8S: &pb_resolvers.K8SResolver{
					DnsPortName: "some:port",
				},
			},
		},
		false,
	)
	require.NoError(t, err)
	assert.True(t, changed)

	changed, err = d.AddOrUpdate(&pb.Backend{Name: "carbar", DisableConntracking: true}, false)
	require.NoError(t, err)
	assert.True(t, changed)

	assert.Len(t, d.Configs(), 2, "we should have two")
	oldCarBar := d.backends["carbar"]
	changed, err = d.AddOrUpdate(&pb.Backend{Name: "carbar"}, false)
	require.NoError(t, err)
	assert.True(t, changed)
	assert.True(t, oldCarBar.closed, "oldCarBar should enter closed state")
	assert.Len(t, d.Configs(), 2, "we should still two")

	// Add totally the same one.
	changed, err = d.AddOrUpdate(
		&pb.Backend{
			Name: "foobar", DisableConntracking: true, Resolver: &pb.Backend_K8S{
				K8S: &pb_resolvers.K8SResolver{
					DnsPortName: "some:port",
				},
			},
		},
		false,
	)
	require.NoError(t, err)
	assert.False(t, changed, "We tried to update totally the same backend, it should not change.")

	assert.Error(t, d.Remove("nonexisting"), "removing a non existing backend should return error")
	assert.NoError(t, d.Remove("foobar"), "removing a non existing backend should return error")
	assert.Len(t, d.Configs(), 1, "we now should have two")
}
<|endoftext|>


<commit_before><commit_msg>Wrote a function to generate unique session tokens<commit_after><|endoftext|>


<commit_before>// OpenSimplex-Go refuses to compile for Windows,386

// +build !386

package render

import (
	"image"
	"image/color"
	"math/rand"
	"time"
)

// NewNoiseBox returns a box of noise
func NewNoiseBox(w, h int) *Sprite {
	return NewSeededNoiseBox(w, h, time.Now().Unix())
}

// NewSeededNoiseBox returns a box of noise seeded at a specific value
// this previously used a complex noise function, but this refused to
// run on windows 32bit and was overkill, so it now uses math/rand
func NewSeededNoiseBox(w, h int, seed int64) *Sprite {
	rect := image.Rect(0, 0, w, h)
	rgba := image.NewRGBA(rect)

	for x := 0; x < w; x++ {
		for y := 0; y < h; y++ {
			v := uint8(rand.Intn(256))
			rgba.Set(x, y, color.RGBA{v, v, v, 255})
		}
	}

	return NewSprite(0, 0, rgba)
}

// NewNoiseSequence returns a sequence of noise boxes
func NewNoiseSequence(w, h, frames int, fps float64) *Sequence {
	mods := make([]Modifiable, frames)
	for i := 0; i < frames; i++ {
		mods[i] = NewSeededNoiseBox(w, h, time.Now().Unix()*int64(i))
	}
	return NewSequence(mods, fps)
}
<commit_msg>Respecting input seed in noise box<commit_after>// OpenSimplex-Go refuses to compile for Windows,386

// +build !386

package render

import (
	"image"
	"image/color"
	"math/rand"
	"time"
)

// NewNoiseBox returns a box of noise
func NewNoiseBox(w, h int) *Sprite {
	return NewSeededNoiseBox(w, h, time.Now().Unix())
}

// NewSeededNoiseBox returns a box of noise seeded at a specific value
// this previously used a complex noise function, but this refused to
// run on windows 32bit and was overkill, so it now uses math/rand
func NewSeededNoiseBox(w, h int, seed int64) *Sprite {
	rect := image.Rect(0, 0, w, h)
	rgba := image.NewRGBA(rect)
	rng := rand.New(rand.NewSource(seed))

	for x := 0; x < w; x++ {
		for y := 0; y < h; y++ {
			v := uint8(rng.Intn(256))
			rgba.Set(x, y, color.RGBA{v, v, v, 255})
		}
	}

	return NewSprite(0, 0, rgba)
}

// NewNoiseSequence returns a sequence of noise boxes
func NewNoiseSequence(w, h, frames int, fps float64) *Sequence {
	mods := make([]Modifiable, frames)
	for i := 0; i < frames; i++ {
		mods[i] = NewSeededNoiseBox(w, h, time.Now().Unix()*int64(i))
	}
	return NewSequence(mods, fps)
}
<|endoftext|>


<commit_before>package render

import "net/http"

type Redirect struct {
	Code     int
	Location string
	Request  *http.Request
}

func (r *Redirect) Render(w http.ResponseWriter) error {
	writeContentType(w, jsonContentType)
	http.Redirect(w, r.Request, r.Location, r.Code)
	return nil
}
<commit_msg>remove unused code<commit_after>package render

import "net/http"

type Redirect struct {
	Code     int
	Location string
	Request  *http.Request
}

func (r *Redirect) Render(w http.ResponseWriter) error {
	http.Redirect(w, r.Request, r.Location, r.Code)
	return nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

package model

import (
	"strings"
	"testing"
)

func TestTeamJson(t *testing.T) {
	o := Team{Id: NewId(), DisplayName: NewId()}
	json := o.ToJson()
	ro := TeamFromJson(strings.NewReader(json))

	if o.Id != ro.Id {
		t.Fatal("Ids do not match")
	}
}

func TestTeamIsValid(t *testing.T) {
	o := Team{}

	if err := o.IsValid(true); err == nil {
		t.Fatal("should be invalid")
	}

	o.Id = NewId()
	if err := o.IsValid(true); err == nil {
		t.Fatal("should be invalid")
	}

	o.CreateAt = GetMillis()
	if err := o.IsValid(); err == nil {
		t.Fatal("should be invalid")
	}

	o.UpdateAt = GetMillis()
	if err := o.IsValid(); err == nil {
		t.Fatal("should be invalid")
	}

	o.Email = strings.Repeat("01234567890", 20)
	if err := o.IsValid(); err == nil {
		t.Fatal("should be invalid")
	}

	o.Email = "corey@hulen.com"
	o.DisplayName = strings.Repeat("01234567890", 20)
	if err := o.IsValid(); err == nil {
		t.Fatal("should be invalid")
	}

	o.DisplayName = "1234"
	o.Name = "ZZZZZZZ"
	if err := o.IsValid(true); err == nil {
		t.Fatal("should be invalid")
	}

	o.Name = "zzzzz"
	o.Type = TEAM_OPEN
	if err := o.IsValid(true); err != nil {
		t.Fatal(err)
	}
}

func TestTeamPreSave(t *testing.T) {
	o := Team{DisplayName: "test"}
	o.PreSave()
	o.Etag()
}

func TestTeamPreUpdate(t *testing.T) {
	o := Team{DisplayName: "test"}
	o.PreUpdate()
}

var domains = []struct {
	value    string
	expected bool
}{
	{"spin-punch", true},
	{"-spin-punch", false},
	{"spin-punch-", false},
	{"spin_punch", false},
	{"a", false},
	{"aa", false},
	{"aaa", false},
	{"aaa-999b", true},
	{"b00b", true},
	{"b))b", false},
	{"test", true},
}

func TestValidTeamName(t *testing.T) {
	for _, v := range domains {
		if IsValidTeamName(v.value) != v.expected {
			t.Errorf("expect %v as %v", v.value, v.expected)
		}
	}
}

var tReservedDomains = []struct {
	value    string
	expected bool
}{
	{"test-hello", true},
	{"test", true},
	{"admin", true},
	{"Admin-punch", true},
	{"spin-punch-admin", false},
}

func TestReservedTeamName(t *testing.T) {
	for _, v := range tReservedDomains {
		if IsReservedTeamName(v.value) != v.expected {
			t.Errorf("expect %v as %v", v.value, v.expected)
		}
	}
}

func TestCleanTeamName(t *testing.T) {
	if CleanTeamName("Jimbo's Team") != "jimbos-team" {
		t.Fatal("didn't clean name properly")
	}
	if len(CleanTeamName("Test")) != 26 {
		t.Fatal("didn't clean name properly")
	}
	if CleanTeamName("Team Really cool") != "really-cool" {
		t.Fatal("didn't clean name properly")
	}
	if CleanTeamName("super-duper-guys") != "super-duper-guys" {
		t.Fatal("didn't clean name properly")
	}
}
<commit_msg>Fixing unit tests<commit_after>// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

package model

import (
	"strings"
	"testing"
)

func TestTeamJson(t *testing.T) {
	o := Team{Id: NewId(), DisplayName: NewId()}
	json := o.ToJson()
	ro := TeamFromJson(strings.NewReader(json))

	if o.Id != ro.Id {
		t.Fatal("Ids do not match")
	}
}

func TestTeamIsValid(t *testing.T) {
	o := Team{}

	if err := o.IsValid(true); err == nil {
		t.Fatal("should be invalid")
	}

	o.Id = NewId()
	if err := o.IsValid(true); err == nil {
		t.Fatal("should be invalid")
	}

	o.CreateAt = GetMillis()
	if err := o.IsValid(true); err == nil {
		t.Fatal("should be invalid")
	}

	o.UpdateAt = GetMillis()
	if err := o.IsValid(true); err == nil {
		t.Fatal("should be invalid")
	}

	o.Email = strings.Repeat("01234567890", 20)
	if err := o.IsValid(true); err == nil {
		t.Fatal("should be invalid")
	}

	o.Email = "corey@hulen.com"
	o.DisplayName = strings.Repeat("01234567890", 20)
	if err := o.IsValid(true); err == nil {
		t.Fatal("should be invalid")
	}

	o.DisplayName = "1234"
	o.Name = "ZZZZZZZ"
	if err := o.IsValid(true); err == nil {
		t.Fatal("should be invalid")
	}

	o.Name = "zzzzz"
	o.Type = TEAM_OPEN
	if err := o.IsValid(true); err != nil {
		t.Fatal(err)
	}
}

func TestTeamPreSave(t *testing.T) {
	o := Team{DisplayName: "test"}
	o.PreSave()
	o.Etag()
}

func TestTeamPreUpdate(t *testing.T) {
	o := Team{DisplayName: "test"}
	o.PreUpdate()
}

var domains = []struct {
	value    string
	expected bool
}{
	{"spin-punch", true},
	{"-spin-punch", false},
	{"spin-punch-", false},
	{"spin_punch", false},
	{"a", false},
	{"aa", false},
	{"aaa", false},
	{"aaa-999b", true},
	{"b00b", true},
	{"b))b", false},
	{"test", true},
}

func TestValidTeamName(t *testing.T) {
	for _, v := range domains {
		if IsValidTeamName(v.value) != v.expected {
			t.Errorf("expect %v as %v", v.value, v.expected)
		}
	}
}

var tReservedDomains = []struct {
	value    string
	expected bool
}{
	{"test-hello", true},
	{"test", true},
	{"admin", true},
	{"Admin-punch", true},
	{"spin-punch-admin", false},
}

func TestReservedTeamName(t *testing.T) {
	for _, v := range tReservedDomains {
		if IsReservedTeamName(v.value) != v.expected {
			t.Errorf("expect %v as %v", v.value, v.expected)
		}
	}
}

func TestCleanTeamName(t *testing.T) {
	if CleanTeamName("Jimbo's Team") != "jimbos-team" {
		t.Fatal("didn't clean name properly")
	}
	if len(CleanTeamName("Test")) != 26 {
		t.Fatal("didn't clean name properly")
	}
	if CleanTeamName("Team Really cool") != "really-cool" {
		t.Fatal("didn't clean name properly")
	}
	if CleanTeamName("super-duper-guys") != "super-duper-guys" {
		t.Fatal("didn't clean name properly")
	}
}
<|endoftext|>