<commit_before>package libphonenumber

// TODO(ttacon): do we need to worry about load factor?

var CountryCodeToRegion = map[int][]string{
	1: []string{
		"US", "AG", "AI", "AS", "BB", "BM", "BS", "CA", "DM", "DO",
		"GD", "GU", "JM", "KN", "KY", "LC", "MP", "MS", "PR", "SX",
		"TC", "TT", "VC", "VG", "VI",
	},
	7:   []string{"RU", "KZ"},
	20:  []string{"EG"},
	27:  []string{"ZA"},
	30:  []string{"GR"},
	31:  []string{"NL"},
	32:  []string{"BE"},
	33:  []string{"FR"},
	34:  []string{"ES"},
	36:  []string{"HU"},
	39:  []string{"IT"},
	40:  []string{"RO"},
	41:  []string{"CH"},
	43:  []string{"AT"},
	44:  []string{"GB", "GG", "IM", "JE"},
	45:  []string{"DK"},
	46:  []string{"SE"},
	47:  []string{"NO", "SJ"},
	48:  []string{"PL"},
	49:  []string{"DE"},
	51:  []string{"PE"},
	52:  []string{"MX"},
	53:  []string{"CU"},
	54:  []string{"AR"},
	55:  []string{"BR"},
	56:  []string{"CL"},
	57:  []string{"CO"},
	58:  []string{"VE"},
	60:  []string{"MY"},
	61:  []string{"AU", "CC", "CX"},
	62:  []string{"ID"},
	63:  []string{"PH"},
	64:  []string{"NZ"},
	65:  []string{"SG"},
	66:  []string{"TH"},
	81:  []string{"JP"},
	82:  []string{"KR"},
	84:  []string{"VN"},
	86:  []string{"CN"},
	90:  []string{"TR"},
	91:  []string{"IN"},
	92:  []string{"PK"},
	93:  []string{"AF"},
	94:  []string{"LK"},
	95:  []string{"MM"},
	98:  []string{"IR"},
	211: []string{"SS"},
	212: []string{"MA", "EH"},
	213: []string{"DZ"},
	216: []string{"TN"},
	218: []string{"LY"},
	220: []string{"GM"},
	221: []string{"SN"},
	222: []string{"MR"},
	223: []string{"ML"},
	224: []string{"GN"},
	225: []string{"CI"},
	226: []string{"BF"},
	227: []string{"NE"},
	228: []string{"TG"},
	229: []string{"BJ"},
	230: []string{"MU"},
	231: []string{"LR"},
	232: []string{"SL"},
	233: []string{"GH"},
	234: []string{"NG"},
	235: []string{"TD"},
	236: []string{"CF"},
	237: []string{"CM"},
	238: []string{"CV"},
	239: []string{"ST"},
	240: []string{"GQ"},
	241: []string{"GA"},
	242: []string{"CG"},
	243: []string{"CD"},
	244: []string{"AO"},
	245: []string{"GW"},
	246: []string{"IO"},
	247: []string{"AC"},
	248: []string{"SC"},
	249: []string{"SD"},
	250: []string{"RW"},
	251: []string{"ET"},
	252: []string{"SO"},
	253: []string{"DJ"},
	254: []string{"KE"},
	255: []string{"TZ"},
	256: []string{"UG"},
	257: []string{"BI"},
	258: []string{"MZ"},
	260: []string{"ZM"},
	261: []string{"MG"},
	262: []string{"RE", "YT"},
	263: []string{"ZW"},
	264: []string{"NA"},
	265: []string{"MW"},
	266: []string{"LS"},
	267: []string{"BW"},
	268: []string{"SZ"},
	269: []string{"KM"},
	290: []string{"SH", "TA"},
	291: []string{"ER"},
	297: []string{"AW"},
	298: []string{"FO"},
	299: []string{"GL"},
	350: []string{"GI"},
	351: []string{"PT"},
	352: []string{"LU"},
	353: []string{"IE"},
	354: []string{"IS"},
	355: []string{"AL"},
	356: []string{"MT"},
	357: []string{"CY"},
	358: []string{"FI", "AX"},
	359: []string{"BG"},
	370: []string{"LT"},
	371: []string{"LV"},
	372: []string{"EE"},
	373: []string{"MD"},
	374: []string{"AM"},
	375: []string{"BY"},
	376: []string{"AD"},
	377: []string{"MC"},
	378: []string{"SM"},
	379: []string{"VA"},
	380: []string{"UA"},
	381: []string{"RS"},
	382: []string{"ME"},
	385: []string{"HR"},
	386: []string{"SI"},
	387: []string{"BA"},
	389: []string{"MK"},
	420: []string{"CZ"},
	421: []string{"SK"},
	423: []string{"LI"},
	500: []string{"FK"},
	501: []string{"BZ"},
	502: []string{"GT"},
	503: []string{"SV"},
	504: []string{"HN"},
	505: []string{"NI"},
	506: []string{"CR"},
	507: []string{"PA"},
	508: []string{"PM"},
	509: []string{"HT"},
	590: []string{"GP", "BL", "MF"},
	591: []string{"BO"},
	592: []string{"GY"},
	593: []string{"EC"},
	594: []string{"GF"},
	595: []string{"PY"},
	596: []string{"MQ"},
	597: []string{"SR"},
	598: []string{"UY"},
	599: []string{"CW", "BQ"},
	670: []string{"TL"},
	672: []string{"NF"},
	673: []string{"BN"},
	674: []string{"NR"},
	675: []string{"PG"},
	676: []string{"TO"},
	677: []string{"SB"},
	678: []string{"VU"},
	679: []string{"FJ"},
	680: []string{"PW"},
	681: []string{"WF"},
	682: []string{"CK"},
	683: []string{"NU"},
	685: []string{"WS"},
	686: []string{"KI"},
	687: []string{"NC"},
	688: []string{"TV"},
	689: []string{"PF"},
	690: []string{"TK"},
	691: []string{"FM"},
	692: []string{"MH"},
	800: []string{"001"},
	808: []string{"001"},
	850: []string{"KP"},
	852: []string{"HK"},
	853: []string{"MO"},
	855: []string{"KH"},
	856: []string{"LA"},
	870: []string{"001"},
	878: []string{"001"},
	880: []string{"BD"},
	881: []string{"001"},
	882: []string{"001"},
	883: []string{"001"},
	886: []string{"TW"},
	888: []string{"001"},
	960: []string{"MV"},
	961: []string{"LB"},
	962: []string{"JO"},
	963: []string{"SY"},
	964: []string{"IQ"},
	965: []string{"KW"},
	966: []string{"SA"},
	967: []string{"YE"},
	968: []string{"OM"},
	970: []string{"PS"},
	971: []string{"AE"},
	972: []string{"IL"},
	973: []string{"BH"},
	974: []string{"QA"},
	975: []string{"BT"},
	976: []string{"MN"},
	977: []string{"NP"},
	979: []string{"001"},
	992: []string{"TJ"},
	993: []string{"TM"},
	994: []string{"AZ"},
	995: []string{"GE"},
	996: []string{"KG"},
	998: []string{"UZ"},
}
<commit_msg>added Kosovo to CountryCodeToRegion map<commit_after>package libphonenumber

// TODO(ttacon): do we need to worry about load factor?

var CountryCodeToRegion = map[int][]string{
	1: []string{
		"US", "AG", "AI", "AS", "BB", "BM", "BS", "CA", "DM", "DO",
		"GD", "GU", "JM", "KN", "KY", "LC", "MP", "MS", "PR", "SX",
		"TC", "TT", "VC", "VG", "VI",
	},
	7:   []string{"RU", "KZ"},
	20:  []string{"EG"},
	27:  []string{"ZA"},
	30:  []string{"GR"},
	31:  []string{"NL"},
	32:  []string{"BE"},
	33:  []string{"FR"},
	34:  []string{"ES"},
	36:  []string{"HU"},
	39:  []string{"IT"},
	40:  []string{"RO"},
	41:  []string{"CH"},
	43:  []string{"AT"},
	44:  []string{"GB", "GG", "IM", "JE"},
	45:  []string{"DK"},
	46:  []string{"SE"},
	47:  []string{"NO", "SJ"},
	48:  []string{"PL"},
	49:  []string{"DE"},
	51:  []string{"PE"},
	52:  []string{"MX"},
	53:  []string{"CU"},
	54:  []string{"AR"},
	55:  []string{"BR"},
	56:  []string{"CL"},
	57:  []string{"CO"},
	58:  []string{"VE"},
	60:  []string{"MY"},
	61:  []string{"AU", "CC", "CX"},
	62:  []string{"ID"},
	63:  []string{"PH"},
	64:  []string{"NZ"},
	65:  []string{"SG"},
	66:  []string{"TH"},
	81:  []string{"JP"},
	82:  []string{"KR"},
	84:  []string{"VN"},
	86:  []string{"CN"},
	90:  []string{"TR"},
	91:  []string{"IN"},
	92:  []string{"PK"},
	93:  []string{"AF"},
	94:  []string{"LK"},
	95:  []string{"MM"},
	98:  []string{"IR"},
	211: []string{"SS"},
	212: []string{"MA", "EH"},
	213: []string{"DZ"},
	216: []string{"TN"},
	218: []string{"LY"},
	220: []string{"GM"},
	221: []string{"SN"},
	222: []string{"MR"},
	223: []string{"ML"},
	224: []string{"GN"},
	225: []string{"CI"},
	226: []string{"BF"},
	227: []string{"NE"},
	228: []string{"TG"},
	229: []string{"BJ"},
	230: []string{"MU"},
	231: []string{"LR"},
	232: []string{"SL"},
	233: []string{"GH"},
	234: []string{"NG"},
	235: []string{"TD"},
	236: []string{"CF"},
	237: []string{"CM"},
	238: []string{"CV"},
	239: []string{"ST"},
	240: []string{"GQ"},
	241: []string{"GA"},
	242: []string{"CG"},
	243: []string{"CD"},
	244: []string{"AO"},
	245: []string{"GW"},
	246: []string{"IO"},
	247: []string{"AC"},
	248: []string{"SC"},
	249: []string{"SD"},
	250: []string{"RW"},
	251: []string{"ET"},
	252: []string{"SO"},
	253: []string{"DJ"},
	254: []string{"KE"},
	255: []string{"TZ"},
	256: []string{"UG"},
	257: []string{"BI"},
	258: []string{"MZ"},
	260: []string{"ZM"},
	261: []string{"MG"},
	262: []string{"RE", "YT"},
	263: []string{"ZW"},
	264: []string{"NA"},
	265: []string{"MW"},
	266: []string{"LS"},
	267: []string{"BW"},
	268: []string{"SZ"},
	269: []string{"KM"},
	290: []string{"SH", "TA"},
	291: []string{"ER"},
	297: []string{"AW"},
	298: []string{"FO"},
	299: []string{"GL"},
	350: []string{"GI"},
	351: []string{"PT"},
	352: []string{"LU"},
	353: []string{"IE"},
	354: []string{"IS"},
	355: []string{"AL"},
	356: []string{"MT"},
	357: []string{"CY"},
	358: []string{"FI", "AX"},
	359: []string{"BG"},
	370: []string{"LT"},
	371: []string{"LV"},
	372: []string{"EE"},
	373: []string{"MD"},
	374: []string{"AM"},
	375: []string{"BY"},
	376: []string{"AD"},
	377: []string{"MC"},
	378: []string{"SM"},
	379: []string{"VA"},
	380: []string{"UA"},
	381: []string{"RS"},
	382: []string{"ME"},
	383: []string{"XK"},
	385: []string{"HR"},
	386: []string{"SI"},
	387: []string{"BA"},
	389: []string{"MK"},
	420: []string{"CZ"},
	421: []string{"SK"},
	423: []string{"LI"},
	500: []string{"FK"},
	501: []string{"BZ"},
	502: []string{"GT"},
	503: []string{"SV"},
	504: []string{"HN"},
	505: []string{"NI"},
	506: []string{"CR"},
	507: []string{"PA"},
	508: []string{"PM"},
	509: []string{"HT"},
	590: []string{"GP", "BL", "MF"},
	591: []string{"BO"},
	592: []string{"GY"},
	593: []string{"EC"},
	594: []string{"GF"},
	595: []string{"PY"},
	596: []string{"MQ"},
	597: []string{"SR"},
	598: []string{"UY"},
	599: []string{"CW", "BQ"},
	670: []string{"TL"},
	672: []string{"NF"},
	673: []string{"BN"},
	674: []string{"NR"},
	675: []string{"PG"},
	676: []string{"TO"},
	677: []string{"SB"},
	678: []string{"VU"},
	679: []string{"FJ"},
	680: []string{"PW"},
	681: []string{"WF"},
	682: []string{"CK"},
	683: []string{"NU"},
	685: []string{"WS"},
	686: []string{"KI"},
	687: []string{"NC"},
	688: []string{"TV"},
	689: []string{"PF"},
	690: []string{"TK"},
	691: []string{"FM"},
	692: []string{"MH"},
	800: []string{"001"},
	808: []string{"001"},
	850: []string{"KP"},
	852: []string{"HK"},
	853: []string{"MO"},
	855: []string{"KH"},
	856: []string{"LA"},
	870: []string{"001"},
	878: []string{"001"},
	880: []string{"BD"},
	881: []string{"001"},
	882: []string{"001"},
	883: []string{"001"},
	886: []string{"TW"},
	888: []string{"001"},
	960: []string{"MV"},
	961: []string{"LB"},
	962: []string{"JO"},
	963: []string{"SY"},
	964: []string{"IQ"},
	965: []string{"KW"},
	966: []string{"SA"},
	967: []string{"YE"},
	968: []string{"OM"},
	970: []string{"PS"},
	971: []string{"AE"},
	972: []string{"IL"},
	973: []string{"BH"},
	974: []string{"QA"},
	975: []string{"BT"},
	976: []string{"MN"},
	977: []string{"NP"},
	979: []string{"001"},
	992: []string{"TJ"},
	993: []string{"TM"},
	994: []string{"AZ"},
	995: []string{"GE"},
	996: []string{"KG"},
	998: []string{"UZ"},
}
<|endoftext|>


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

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"time"
)

type obj map[string]interface{}

// dash runs the given method and command on the dashboard.
// If args is non-nil it is encoded as the URL query string.
// If req is non-nil it is JSON-encoded and passed as the body of the HTTP POST.
// If resp is non-nil the server's response is decoded into the value pointed
// to by resp (resp must be a pointer).
func dash(meth, cmd string, args url.Values, req, resp interface{}) error {
	var r *http.Response
	var err error
	if *verbose {
		log.Println("dash", meth, cmd, args, req)
	}
	cmd = "http://" + *dashboard + "/" + cmd
	if len(args) > 0 {
		cmd += "?" + args.Encode()
	}
	switch meth {
	case "GET":
		if req != nil {
			log.Panicf("%s to %s with req", meth, cmd)
		}
		r, err = http.Get(cmd)
	case "POST":
		var body io.Reader
		if req != nil {
			b, err := json.Marshal(req)
			if err != nil {
				return err
			}
			body = bytes.NewBuffer(b)
		}
		r, err = http.Post(cmd, "text/json", body)
	default:
		log.Panicf("%s: invalid method %q", cmd, meth)
		panic("invalid method: " + meth)
	}
	if err != nil {
		return err
	}

	defer r.Body.Close()
	body := new(bytes.Buffer)
	if _, err := body.ReadFrom(r.Body); err != nil {
		return err
	}

	// Read JSON-encoded Response into provided resp
	// and return an error if present.
	var result = struct {
		Response interface{}
		Error    string
	}{
		// Put the provided resp in here as it can be a pointer to
		// some value we should unmarshal into.
		Response: resp,
	}
	if err = json.Unmarshal(body.Bytes(), &result); err != nil {
		log.Printf("json unmarshal %#q: %s\n", body.Bytes(), err)
		return err
	}
	if result.Error != "" {
		return errors.New(result.Error)
	}

	return nil
}

// todo returns the next hash to build.
func (b *Builder) todo(kind, pkg, goHash string) (rev string, err error) {
	args := url.Values{
		"kind":        {kind},
		"builder":     {b.name},
		"packagePath": {pkg},
		"goHash":      {goHash},
	}
	var resp *struct {
		Kind string
		Data struct {
			Hash string
		}
	}
	if err = dash("GET", "todo", args, nil, &resp); err != nil {
		return "", err
	}
	if resp == nil {
		return "", nil
	}
	if kind != resp.Kind {
		return "", fmt.Errorf("expecting Kind %q, got %q", kind, resp.Kind)
	}
	return resp.Data.Hash, nil
}

// recordResult sends build results to the dashboard
func (b *Builder) recordResult(ok bool, pkg, hash, goHash, buildLog string, runTime time.Duration) error {
	req := obj{
		"Builder":     b.name,
		"PackagePath": pkg,
		"Hash":        hash,
		"GoHash":      goHash,
		"OK":          ok,
		"Log":         buildLog,
		"RunTime":     runTime,
	}
	args := url.Values{"key": {b.key}, "builder": {b.name}}
	return dash("POST", "result", args, req, nil)
}

func postCommit(key, pkg string, l *HgLog) error {
	t, err := time.Parse(time.RFC3339, l.Date)
	if err != nil {
		return fmt.Errorf("parsing %q: %v", l.Date, t)
	}
	return dash("POST", "commit", url.Values{"key": {key}}, obj{
		"PackagePath": pkg,
		"Hash":        l.Hash,
		"ParentHash":  l.Parent,
		"Time":        t.Format(time.RFC3339),
		"User":        l.Author,
		"Desc":        l.Desc,
	}, nil)
}

func dashboardCommit(pkg, hash string) bool {
	err := dash("GET", "commit", url.Values{
		"packagePath": {pkg},
		"hash":        {hash},
	}, nil, nil)
	return err == nil
}

func dashboardPackages(kind string) []string {
	args := url.Values{"kind": []string{kind}}
	var resp []struct {
		Path string
	}
	if err := dash("GET", "packages", args, nil, &resp); err != nil {
		log.Println("dashboardPackages:", err)
		return nil
	}
	var pkgs []string
	for _, r := range resp {
		pkgs = append(pkgs, r.Path)
	}
	return pkgs
}
<commit_msg>misc/dashboard/builder: check http status before processing response<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"time"
)

type obj map[string]interface{}

// dash runs the given method and command on the dashboard.
// If args is non-nil it is encoded as the URL query string.
// If req is non-nil it is JSON-encoded and passed as the body of the HTTP POST.
// If resp is non-nil the server's response is decoded into the value pointed
// to by resp (resp must be a pointer).
func dash(meth, cmd string, args url.Values, req, resp interface{}) error {
	var r *http.Response
	var err error
	if *verbose {
		log.Println("dash", meth, cmd, args, req)
	}
	cmd = "http://" + *dashboard + "/" + cmd
	if len(args) > 0 {
		cmd += "?" + args.Encode()
	}
	switch meth {
	case "GET":
		if req != nil {
			log.Panicf("%s to %s with req", meth, cmd)
		}
		r, err = http.Get(cmd)
	case "POST":
		var body io.Reader
		if req != nil {
			b, err := json.Marshal(req)
			if err != nil {
				return err
			}
			body = bytes.NewBuffer(b)
		}
		r, err = http.Post(cmd, "text/json", body)
	default:
		log.Panicf("%s: invalid method %q", cmd, meth)
		panic("invalid method: " + meth)
	}
	if err != nil {
		return err
	}
	defer r.Body.Close()
	if r.StatusCode != http.StatusOK {
		return fmt.Errorf("bad http response: %v", r.Status)
	}
	body := new(bytes.Buffer)
	if _, err := body.ReadFrom(r.Body); err != nil {
		return err
	}

	// Read JSON-encoded Response into provided resp
	// and return an error if present.
	var result = struct {
		Response interface{}
		Error    string
	}{
		// Put the provided resp in here as it can be a pointer to
		// some value we should unmarshal into.
		Response: resp,
	}
	if err = json.Unmarshal(body.Bytes(), &result); err != nil {
		log.Printf("json unmarshal %#q: %s\n", body.Bytes(), err)
		return err
	}
	if result.Error != "" {
		return errors.New(result.Error)
	}

	return nil
}

// todo returns the next hash to build.
func (b *Builder) todo(kind, pkg, goHash string) (rev string, err error) {
	args := url.Values{
		"kind":        {kind},
		"builder":     {b.name},
		"packagePath": {pkg},
		"goHash":      {goHash},
	}
	var resp *struct {
		Kind string
		Data struct {
			Hash string
		}
	}
	if err = dash("GET", "todo", args, nil, &resp); err != nil {
		return "", err
	}
	if resp == nil {
		return "", nil
	}
	if kind != resp.Kind {
		return "", fmt.Errorf("expecting Kind %q, got %q", kind, resp.Kind)
	}
	return resp.Data.Hash, nil
}

// recordResult sends build results to the dashboard
func (b *Builder) recordResult(ok bool, pkg, hash, goHash, buildLog string, runTime time.Duration) error {
	req := obj{
		"Builder":     b.name,
		"PackagePath": pkg,
		"Hash":        hash,
		"GoHash":      goHash,
		"OK":          ok,
		"Log":         buildLog,
		"RunTime":     runTime,
	}
	args := url.Values{"key": {b.key}, "builder": {b.name}}
	return dash("POST", "result", args, req, nil)
}

func postCommit(key, pkg string, l *HgLog) error {
	t, err := time.Parse(time.RFC3339, l.Date)
	if err != nil {
		return fmt.Errorf("parsing %q: %v", l.Date, t)
	}
	return dash("POST", "commit", url.Values{"key": {key}}, obj{
		"PackagePath": pkg,
		"Hash":        l.Hash,
		"ParentHash":  l.Parent,
		"Time":        t.Format(time.RFC3339),
		"User":        l.Author,
		"Desc":        l.Desc,
	}, nil)
}

func dashboardCommit(pkg, hash string) bool {
	err := dash("GET", "commit", url.Values{
		"packagePath": {pkg},
		"hash":        {hash},
	}, nil, nil)
	return err == nil
}

func dashboardPackages(kind string) []string {
	args := url.Values{"kind": []string{kind}}
	var resp []struct {
		Path string
	}
	if err := dash("GET", "packages", args, nil, &resp); err != nil {
		log.Println("dashboardPackages:", err)
		return nil
	}
	var pkgs []string
	for _, r := range resp {
		pkgs = append(pkgs, r.Path)
	}
	return pkgs
}
<|endoftext|>


<commit_before>package stripe

import (
	"encoding/json"
)

// CustomerTaxInfoType is the type of tax info associated with a customer.
type CustomerTaxInfoType string

// List of values that CustomerTaxInfoType can take.
const (
	CustomerTaxInfoTypeVAT CustomerTaxInfoType = "vat"
)

// CustomerTaxInfoVerificationStatus is the type of tax info associated with a customer.
type CustomerTaxInfoVerificationStatus string

// List of values that CustomerTaxInfoType can take.
const (
	CustomerTaxInfoVerificationStatusPending    CustomerTaxInfoVerificationStatus = "pending"
	CustomerTaxInfoVerificationStatusUnverified CustomerTaxInfoVerificationStatus = "unverified"
	CustomerTaxInfoVerificationStatusVerified   CustomerTaxInfoVerificationStatus = "verified"
)

// CustomerParams is the set of parameters that can be used when creating or updating a customer.
// For more details see https://stripe.com/docs/api#create_customer and https://stripe.com/docs/api#update_customer.
type CustomerParams struct {
	Params          `form:"*"`
	AccountBalance  *int64                         `form:"account_balance"`
	Coupon          *string                        `form:"coupon"`
	DefaultSource   *string                        `form:"default_source"`
	Description     *string                        `form:"description"`
	Email           *string                        `form:"email"`
	InvoicePrefix   *string                        `form:"invoice_prefix"`
	InvoiceSettings *CustomerInvoiceSettingsParams `form:"invoice_settings"`
	Plan            *string                        `form:"plan"`
	Quantity        *int64                         `form:"quantity"`
	Shipping        *CustomerShippingDetailsParams `form:"shipping"`
	Source          *SourceParams                  `form:"*"` // SourceParams has custom encoding so brought to top level with "*"
	TaxInfo         *CustomerTaxInfoParams         `form:"tax_info"`
	TaxPercent      *float64                       `form:"tax_percent"`
	Token           *string                        `form:"-"` // This doesn't seem to be used?
	TrialEnd        *int64                         `form:"trial_end"`
}

// CustomerInvoiceCustomFieldParams represents the parameters associated with one custom field on
// the customer's invoices.
type CustomerInvoiceCustomFieldParams struct {
	Name  *string `form:"name"`
	Value *string `form:"value"`
}

// CustomerInvoiceSettingsParams is the structure containing the default settings for invoices
// associated with this customer.
type CustomerInvoiceSettingsParams struct {
	CustomFields         []*CustomerInvoiceCustomFieldParams `form:"custom_fields"`
	DefaultPaymentMethod *string                             `form:"default_payment_method"`
	Footer               *string                             `form:"footer"`
}

// CustomerShippingDetailsParams is the structure containing shipping information.
type CustomerShippingDetailsParams struct {
	Address *AddressParams `form:"address"`
	Name    *string        `form:"name"`
	Phone   *string        `form:"phone"`
}

// CustomerTaxInfoParams is the structure containing tax information for the customer.
type CustomerTaxInfoParams struct {
	TaxID *string `form:"tax_id"`
	Type  *string `form:"type"`
}

// SetSource adds valid sources to a CustomerParams object,
// returning an error for unsupported sources.
func (cp *CustomerParams) SetSource(sp interface{}) error {
	source, err := SourceParamsFor(sp)
	cp.Source = source
	return err
}

// CustomerListParams is the set of parameters that can be used when listing customers.
// For more details see https://stripe.com/docs/api#list_customers.
type CustomerListParams struct {
	ListParams   `form:"*"`
	Created      *int64            `form:"created"`
	CreatedRange *RangeQueryParams `form:"created"`
	Email        *string           `form:"email"`
}

// Customer is the resource representing a Stripe customer.
// For more details see https://stripe.com/docs/api#customers.
type Customer struct {
	AccountBalance      int64                        `json:"account_balance"`
	Created             int64                        `json:"created"`
	Currency            Currency                     `json:"currency"`
	DefaultSource       *PaymentSource               `json:"default_source"`
	Deleted             bool                         `json:"deleted"`
	Delinquent          bool                         `json:"delinquent"`
	Description         string                       `json:"description"`
	Discount            *Discount                    `json:"discount"`
	Email               string                       `json:"email"`
	ID                  string                       `json:"id"`
	InvoicePrefix       string                       `json:"invoice_prefix"`
	Livemode            bool                         `json:"livemode"`
	Metadata            map[string]string            `json:"metadata"`
	Shipping            *CustomerShippingDetails     `json:"shipping"`
	Sources             *SourceList                  `json:"sources"`
	Subscriptions       *SubscriptionList            `json:"subscriptions"`
	TaxInfo             *CustomerTaxInfo             `json:"tax_info"`
	TaxInfoVerification *CustomerTaxInfoVerification `json:"tax_info_verification"`
}

// CustomerInvoiceCustomField represents a custom field associated with the customer's invoices.
type CustomerInvoiceCustomField struct {
	Name  *string `form:"name"`
	Value *string `form:"value"`
}

// CustomerInvoiceSettings is the structure containing the default settings for invoices associated
// with this customer.
type CustomerInvoiceSettings struct {
	CustomFields         []*CustomerInvoiceCustomField `json:"custom_fields"`
	DefaultPaymentMethod *PaymentMethod                `json:"default_payment_method"`
	Footer               string                        `json:"footer"`
}

// CustomerList is a list of customers as retrieved from a list endpoint.
type CustomerList struct {
	ListMeta
	Data []*Customer `json:"data"`
}

// CustomerShippingDetails is the structure containing shipping information.
type CustomerShippingDetails struct {
	Address Address `json:"address"`
	Name    string  `json:"name"`
	Phone   string  `json:"phone"`
}

// CustomerTaxInfo is the structure containing tax information for the customer.
type CustomerTaxInfo struct {
	TaxID string              `json:"tax_id"`
	Type  CustomerTaxInfoType `json:"type"`
}

// CustomerTaxInfoVerification is the structure containing tax verification for the customer.
type CustomerTaxInfoVerification struct {
	Status       CustomerTaxInfoVerificationStatus `json:"status"`
	VerifiedName string                            `json:"verified_name"`
}

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

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

	*c = Customer(v)
	return nil
}
<commit_msg>Add support for passing a PaymentMethod id on Customer creation<commit_after>package stripe

import (
	"encoding/json"
)

// CustomerTaxInfoType is the type of tax info associated with a customer.
type CustomerTaxInfoType string

// List of values that CustomerTaxInfoType can take.
const (
	CustomerTaxInfoTypeVAT CustomerTaxInfoType = "vat"
)

// CustomerTaxInfoVerificationStatus is the type of tax info associated with a customer.
type CustomerTaxInfoVerificationStatus string

// List of values that CustomerTaxInfoType can take.
const (
	CustomerTaxInfoVerificationStatusPending    CustomerTaxInfoVerificationStatus = "pending"
	CustomerTaxInfoVerificationStatusUnverified CustomerTaxInfoVerificationStatus = "unverified"
	CustomerTaxInfoVerificationStatusVerified   CustomerTaxInfoVerificationStatus = "verified"
)

// CustomerParams is the set of parameters that can be used when creating or updating a customer.
// For more details see https://stripe.com/docs/api#create_customer and https://stripe.com/docs/api#update_customer.
type CustomerParams struct {
	Params          `form:"*"`
	AccountBalance  *int64                         `form:"account_balance"`
	Coupon          *string                        `form:"coupon"`
	DefaultSource   *string                        `form:"default_source"`
	Description     *string                        `form:"description"`
	Email           *string                        `form:"email"`
	InvoicePrefix   *string                        `form:"invoice_prefix"`
	InvoiceSettings *CustomerInvoiceSettingsParams `form:"invoice_settings"`
	PaymentMethod   *string                        `form:"payment_method"`
	Plan            *string                        `form:"plan"`
	Quantity        *int64                         `form:"quantity"`
	Shipping        *CustomerShippingDetailsParams `form:"shipping"`
	Source          *SourceParams                  `form:"*"` // SourceParams has custom encoding so brought to top level with "*"
	TaxInfo         *CustomerTaxInfoParams         `form:"tax_info"`
	TaxPercent      *float64                       `form:"tax_percent"`
	Token           *string                        `form:"-"` // This doesn't seem to be used?
	TrialEnd        *int64                         `form:"trial_end"`
}

// CustomerInvoiceCustomFieldParams represents the parameters associated with one custom field on
// the customer's invoices.
type CustomerInvoiceCustomFieldParams struct {
	Name  *string `form:"name"`
	Value *string `form:"value"`
}

// CustomerInvoiceSettingsParams is the structure containing the default settings for invoices
// associated with this customer.
type CustomerInvoiceSettingsParams struct {
	CustomFields         []*CustomerInvoiceCustomFieldParams `form:"custom_fields"`
	DefaultPaymentMethod *string                             `form:"default_payment_method"`
	Footer               *string                             `form:"footer"`
}

// CustomerShippingDetailsParams is the structure containing shipping information.
type CustomerShippingDetailsParams struct {
	Address *AddressParams `form:"address"`
	Name    *string        `form:"name"`
	Phone   *string        `form:"phone"`
}

// CustomerTaxInfoParams is the structure containing tax information for the customer.
type CustomerTaxInfoParams struct {
	TaxID *string `form:"tax_id"`
	Type  *string `form:"type"`
}

// SetSource adds valid sources to a CustomerParams object,
// returning an error for unsupported sources.
func (cp *CustomerParams) SetSource(sp interface{}) error {
	source, err := SourceParamsFor(sp)
	cp.Source = source
	return err
}

// CustomerListParams is the set of parameters that can be used when listing customers.
// For more details see https://stripe.com/docs/api#list_customers.
type CustomerListParams struct {
	ListParams   `form:"*"`
	Created      *int64            `form:"created"`
	CreatedRange *RangeQueryParams `form:"created"`
	Email        *string           `form:"email"`
}

// Customer is the resource representing a Stripe customer.
// For more details see https://stripe.com/docs/api#customers.
type Customer struct {
	AccountBalance      int64                        `json:"account_balance"`
	Created             int64                        `json:"created"`
	Currency            Currency                     `json:"currency"`
	DefaultSource       *PaymentSource               `json:"default_source"`
	Deleted             bool                         `json:"deleted"`
	Delinquent          bool                         `json:"delinquent"`
	Description         string                       `json:"description"`
	Discount            *Discount                    `json:"discount"`
	Email               string                       `json:"email"`
	ID                  string                       `json:"id"`
	InvoicePrefix       string                       `json:"invoice_prefix"`
	Livemode            bool                         `json:"livemode"`
	Metadata            map[string]string            `json:"metadata"`
	Shipping            *CustomerShippingDetails     `json:"shipping"`
	Sources             *SourceList                  `json:"sources"`
	Subscriptions       *SubscriptionList            `json:"subscriptions"`
	TaxInfo             *CustomerTaxInfo             `json:"tax_info"`
	TaxInfoVerification *CustomerTaxInfoVerification `json:"tax_info_verification"`
}

// CustomerInvoiceCustomField represents a custom field associated with the customer's invoices.
type CustomerInvoiceCustomField struct {
	Name  *string `form:"name"`
	Value *string `form:"value"`
}

// CustomerInvoiceSettings is the structure containing the default settings for invoices associated
// with this customer.
type CustomerInvoiceSettings struct {
	CustomFields         []*CustomerInvoiceCustomField `json:"custom_fields"`
	DefaultPaymentMethod *PaymentMethod                `json:"default_payment_method"`
	Footer               string                        `json:"footer"`
}

// CustomerList is a list of customers as retrieved from a list endpoint.
type CustomerList struct {
	ListMeta
	Data []*Customer `json:"data"`
}

// CustomerShippingDetails is the structure containing shipping information.
type CustomerShippingDetails struct {
	Address Address `json:"address"`
	Name    string  `json:"name"`
	Phone   string  `json:"phone"`
}

// CustomerTaxInfo is the structure containing tax information for the customer.
type CustomerTaxInfo struct {
	TaxID string              `json:"tax_id"`
	Type  CustomerTaxInfoType `json:"type"`
}

// CustomerTaxInfoVerification is the structure containing tax verification for the customer.
type CustomerTaxInfoVerification struct {
	Status       CustomerTaxInfoVerificationStatus `json:"status"`
	VerifiedName string                            `json:"verified_name"`
}

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

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

	*c = Customer(v)
	return nil
}
<|endoftext|>


<commit_before>package proto

import (
	"fmt"
	"math"
)

const (
	maxParseBufSize = 10 * math.MaxUint16
)

func messageSizeError(size int) error {
	return fmt.Errorf("unreasonable message/block size %d (max:%d)", size, maxParseBufSize)
}

// allocParseBuf is used to allocate buffers used for parsing
func allocParseBuf(size int) ([]byte, error) {
	if size < 0 || size > maxParseBufSize {
		return nil, messageSizeError(size)
	}

	return make([]byte, size), nil
}
<commit_msg>set limit on buffersize equal MAX i32<commit_after>package proto

import (
	"fmt"
	"math"
)

const (
	maxParseBufSize = math.MaxInt32
)

func messageSizeError(size int) error {
	return fmt.Errorf("unreasonable message/block size %d (max:%d)", size, maxParseBufSize)
}

// allocParseBuf is used to allocate buffers used for parsing
func allocParseBuf(size int) ([]byte, error) {
	if size < 0 || size > maxParseBufSize {
		return nil, messageSizeError(size)
	}

	return make([]byte, size), nil
}
<|endoftext|>


<commit_before>package proxy

import (
	"crypto/tls"
	"errors"
	"io"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
	"time"

	"github.com/cloudfoundry/dropsonde"
	"github.com/cloudfoundry/gorouter/access_log"
	router_http "github.com/cloudfoundry/gorouter/common/http"
	"github.com/cloudfoundry/gorouter/common/secure"
	"github.com/cloudfoundry/gorouter/route"
	"github.com/cloudfoundry/gorouter/route_service"
	steno "github.com/cloudfoundry/gosteno"
	"github.com/cloudfoundry/gorouter/metrics"
)

const (
	VcapCookieId    = "__VCAP_ID__"
	StickyCookieKey = "JSESSIONID"
	maxRetries      = 3
)

var noEndpointsAvailable = errors.New("No endpoints available")

type LookupRegistry interface {
	Lookup(uri route.Uri) *route.Pool
}

type AfterRoundTrip func(rsp *http.Response, endpoint *route.Endpoint, err error)

type Proxy interface {
	ServeHTTP(responseWriter http.ResponseWriter, request *http.Request)
}

type ProxyArgs struct {
	EndpointTimeout     time.Duration
	Ip                  string
	TraceKey            string
	Registry            LookupRegistry
	Reporter            metrics.ProxyReporter
	AccessLogger        access_log.AccessLogger
	SecureCookies       bool
	TLSConfig           *tls.Config
	RouteServiceEnabled bool
	RouteServiceTimeout time.Duration
	Crypto              secure.Crypto
	CryptoPrev          secure.Crypto
	ExtraHeadersToLog   []string
}

type proxy struct {
	ip                 string
	traceKey           string
	logger             *steno.Logger
	registry           LookupRegistry
	reporter           metrics.ProxyReporter
	accessLogger       access_log.AccessLogger
	transport          *http.Transport
	secureCookies      bool
	routeServiceConfig *route_service.RouteServiceConfig
	ExtraHeadersToLog  []string
}

func NewProxy(args ProxyArgs) Proxy {
	routeServiceConfig := route_service.NewRouteServiceConfig(args.RouteServiceEnabled, args.RouteServiceTimeout, args.Crypto, args.CryptoPrev)

	p := &proxy{
		accessLogger: args.AccessLogger,
		traceKey:     args.TraceKey,
		ip:           args.Ip,
		logger:       steno.NewLogger("router.proxy"),
		registry:     args.Registry,
		reporter:     args.Reporter,
		transport: &http.Transport{
			Dial: func(network, addr string) (net.Conn, error) {
				conn, err := net.DialTimeout(network, addr, 5*time.Second)
				if err != nil {
					return conn, err
				}
				if args.EndpointTimeout > 0 {
					err = conn.SetDeadline(time.Now().Add(args.EndpointTimeout))
				}
				return conn, err
			},
			DisableKeepAlives:  true,
			DisableCompression: true,
			TLSClientConfig:    args.TLSConfig,
		},
		secureCookies:      args.SecureCookies,
		routeServiceConfig: routeServiceConfig,
		ExtraHeadersToLog:  args.ExtraHeadersToLog,
	}

	return p
}

func hostWithoutPort(req *http.Request) string {
	host := req.Host

	// Remove :<port>
	pos := strings.Index(host, ":")
	if pos >= 0 {
		host = host[0:pos]
	}

	return host
}

func (p *proxy) getStickySession(request *http.Request) string {
	// Try choosing a backend using sticky session
	if _, err := request.Cookie(StickyCookieKey); err == nil {
		if sticky, err := request.Cookie(VcapCookieId); err == nil {
			return sticky.Value
		}
	}
	return ""
}

func (p *proxy) lookup(request *http.Request) *route.Pool {
	uri := route.Uri(hostWithoutPort(request) + request.RequestURI)
	return p.registry.Lookup(uri)
}

func (p *proxy) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) {
	startedAt := time.Now()
	accessLog := access_log.AccessLogRecord{
		Request:           request,
		StartedAt:         startedAt,
		ExtraHeadersToLog: p.ExtraHeadersToLog,
	}

	requestBodyCounter := &countingReadCloser{delegate: request.Body}
	request.Body = requestBodyCounter

	proxyWriter := NewProxyResponseWriter(responseWriter)
	handler := NewRequestHandler(request, proxyWriter, p.reporter, &accessLog)

	defer func() {
		accessLog.RequestBytesReceived = requestBodyCounter.count
		p.accessLogger.Log(accessLog)
	}()

	if !isProtocolSupported(request) {
		handler.HandleUnsupportedProtocol()
		return
	}

	if isLoadBalancerHeartbeat(request) {
		handler.HandleHeartbeat()
		return
	}

	routePool := p.lookup(request)
	if routePool == nil {
		p.reporter.CaptureBadRequest(request)
		handler.HandleMissingRoute()
		return
	}

	stickyEndpointId := p.getStickySession(request)
	iter := &wrappedIterator{
		nested: routePool.Endpoints(stickyEndpointId),

		afterNext: func(endpoint *route.Endpoint) {
			if endpoint != nil {
				handler.Logger().Set("RouteEndpoint", endpoint.ToLogData())
				accessLog.RouteEndpoint = endpoint
				p.reporter.CaptureRoutingRequest(endpoint, request)
			}
		},
	}

	if isTcpUpgrade(request) {
		handler.HandleTcpRequest(iter)
		accessLog.FinishedAt = time.Now()
		return
	}

	if isWebSocketUpgrade(request) {
		handler.HandleWebSocketRequest(iter)
		accessLog.FinishedAt = time.Now()
		return
	}

	backend := true

	routeServiceUrl := routePool.RouteServiceUrl()
	// Attempted to use a route service when it is not supported
	if routeServiceUrl != "" && !p.routeServiceConfig.RouteServiceEnabled() {
		handler.HandleUnsupportedRouteService()
		return
	}

	var routeServiceArgs route_service.RouteServiceArgs
	if routeServiceUrl != "" {
		rsSignature := request.Header.Get(route_service.RouteServiceSignature)
		forwardedUrlRaw := "http" + "://" + request.Host + request.RequestURI
		if hasBeenToRouteService(routeServiceUrl, rsSignature) {
			// A request from a route service destined for a backend instances
			routeServiceArgs.UrlString = routeServiceUrl
			err := p.routeServiceConfig.ValidateSignature(&request.Header, forwardedUrlRaw)
			if err != nil {
				handler.HandleBadSignature(err)
				return
			}
		} else {
			var err error
			// should not hardcode http, will be addressed by #100982038
			routeServiceArgs, err = buildRouteServiceArgs(p.routeServiceConfig, routeServiceUrl, forwardedUrlRaw)
			backend = false
			if err != nil {
				handler.HandleRouteServiceFailure(err)
				return
			}
		}
	}

	after := func(rsp *http.Response, endpoint *route.Endpoint, err error) {
		accessLog.FirstByteAt = time.Now()
		if rsp != nil {
			accessLog.StatusCode = rsp.StatusCode
		}

		if p.traceKey != "" && request.Header.Get(router_http.VcapTraceHeader) == p.traceKey {
			setTraceHeaders(responseWriter, p.ip, endpoint.CanonicalAddr())
		}

		latency := time.Since(startedAt)

		p.reporter.CaptureRoutingResponse(endpoint, rsp, startedAt, latency)

		if err != nil {
			p.reporter.CaptureBadGateway(request)
			handler.HandleBadGateway(err)
			return
		}

		if endpoint.PrivateInstanceId != "" {
			setupStickySession(responseWriter, rsp, endpoint, stickyEndpointId, p.secureCookies, routePool.ContextPath())
		}
	}

	roundTripper := NewProxyRoundTripper(backend,
		dropsonde.InstrumentedRoundTripper(p.transport), iter, handler, after)

	newReverseProxy(roundTripper, request, routeServiceArgs, p.routeServiceConfig).ServeHTTP(proxyWriter, request)

	accessLog.FinishedAt = time.Now()
	accessLog.BodyBytesSent = proxyWriter.Size()
}

func newReverseProxy(proxyTransport http.RoundTripper, req *http.Request,
	routeServiceArgs route_service.RouteServiceArgs,
	routeServiceConfig *route_service.RouteServiceConfig) http.Handler {
	rproxy := &httputil.ReverseProxy{
		Director: func(request *http.Request) {
			SetupProxyRequest(req, request, routeServiceArgs, routeServiceConfig)
		},
		Transport:     proxyTransport,
		FlushInterval: 50 * time.Millisecond,
	}

	return rproxy
}

func SetupProxyRequest(source *http.Request, target *http.Request,
	routeServiceArgs route_service.RouteServiceArgs,
	routeServiceConfig *route_service.RouteServiceConfig) {
	target.URL.Scheme = "http"
	target.URL.Host = source.Host
	target.URL.Opaque = source.RequestURI
	target.URL.RawQuery = ""

	setRequestXRequestStart(source)
	setRequestXVcapRequestId(source, nil)

	sig := target.Header.Get(route_service.RouteServiceSignature)
	if forwardingToRouteService(routeServiceArgs.UrlString, sig) {
		// An endpoint has a route service and this request did not come from the service
		routeServiceConfig.SetupRouteServiceRequest(target, routeServiceArgs)
	} else if hasBeenToRouteService(routeServiceArgs.UrlString, sig) {
		// Remove the headers since the backend should not see it
		target.Header.Del(route_service.RouteServiceSignature)
		target.Header.Del(route_service.RouteServiceMetadata)
	}
}

func newRouteServiceEndpoint() *route.Endpoint {
	return &route.Endpoint{
		Tags: map[string]string{},
	}
}

type wrappedIterator struct {
	nested    route.EndpointIterator
	afterNext func(*route.Endpoint)
}

func (i *wrappedIterator) Next() *route.Endpoint {
	e := i.nested.Next()
	if i.afterNext != nil {
		i.afterNext(e)
	}
	return e
}

func (i *wrappedIterator) EndpointFailed() {
	i.nested.EndpointFailed()
}

func buildRouteServiceArgs(routeServiceConfig *route_service.RouteServiceConfig, routeServiceUrl, forwardedUrlRaw string) (route_service.RouteServiceArgs, error) {
	var routeServiceArgs route_service.RouteServiceArgs
	sig, metadata, err := routeServiceConfig.GenerateSignatureAndMetadata(forwardedUrlRaw)
	if err != nil {
		return routeServiceArgs, err
	}

	routeServiceArgs.UrlString = routeServiceUrl
	routeServiceArgs.Signature = sig
	routeServiceArgs.Metadata = metadata
	routeServiceArgs.ForwardedUrlRaw = forwardedUrlRaw

	rsURL, err := url.Parse(routeServiceUrl)
	if err != nil {
		return routeServiceArgs, err
	}
	routeServiceArgs.ParsedUrl = rsURL

	return routeServiceArgs, nil
}

func setupStickySession(responseWriter http.ResponseWriter, response *http.Response,
	endpoint *route.Endpoint,
	originalEndpointId string,
	secureCookies bool,
	path string) {

	maxAge := 0

	// did the endpoint change?
	sticky := originalEndpointId != "" && originalEndpointId != endpoint.PrivateInstanceId

	for _, v := range response.Cookies() {
		if v.Name == StickyCookieKey {
			sticky = true
			if v.MaxAge < 0 {
				maxAge = v.MaxAge
			}
			break
		}
	}

	if sticky {
		cookie := &http.Cookie{
			Name:     VcapCookieId,
			Value:    endpoint.PrivateInstanceId,
			Path:     path,
			MaxAge:   maxAge,
			HttpOnly: true,
			Secure:   secureCookies,
		}

		http.SetCookie(responseWriter, cookie)
	}
}

func forwardingToRouteService(rsUrl, sigHeader string) bool {
	return sigHeader == "" && rsUrl != ""
}

func hasBeenToRouteService(rsUrl, sigHeader string) bool {
	return sigHeader != "" && rsUrl != ""
}

func isProtocolSupported(request *http.Request) bool {
	return request.ProtoMajor == 1 && (request.ProtoMinor == 0 || request.ProtoMinor == 1)
}

func isLoadBalancerHeartbeat(request *http.Request) bool {
	return request.UserAgent() == "HTTP-Monitor/1.1"
}

func isWebSocketUpgrade(request *http.Request) bool {
	// websocket should be case insensitive per RFC6455 4.2.1
	return strings.ToLower(upgradeHeader(request)) == "websocket"
}

func isTcpUpgrade(request *http.Request) bool {
	return upgradeHeader(request) == "tcp"
}

func upgradeHeader(request *http.Request) string {
	// handle multiple Connection field-values, either in a comma-separated string or multiple field-headers
	for _, v := range request.Header[http.CanonicalHeaderKey("Connection")] {
		// upgrade should be case insensitive per RFC6455 4.2.1
		if strings.Contains(strings.ToLower(v), "upgrade") {
			return request.Header.Get("Upgrade")
		}
	}

	return ""
}

func setTraceHeaders(responseWriter http.ResponseWriter, routerIp, addr string) {
	responseWriter.Header().Set(router_http.VcapRouterHeader, routerIp)
	responseWriter.Header().Set(router_http.VcapBackendHeader, addr)
	responseWriter.Header().Set(router_http.CfRouteEndpointHeader, addr)
}

type countingReadCloser struct {
	delegate io.ReadCloser
	count    int
}

func (crc *countingReadCloser) Read(b []byte) (int, error) {
	n, err := crc.delegate.Read(b)
	crc.count += n
	return n, err
}

func (crc *countingReadCloser) Close() error {
	return crc.delegate.Close()
}
<commit_msg>Add atomic counter to remove data race condition on proxy gorouter<commit_after>package proxy

import (
	"crypto/tls"
	"errors"
	"io"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
	"sync/atomic"
	"time"

	"github.com/cloudfoundry/dropsonde"
	"github.com/cloudfoundry/gorouter/access_log"
	router_http "github.com/cloudfoundry/gorouter/common/http"
	"github.com/cloudfoundry/gorouter/common/secure"
	"github.com/cloudfoundry/gorouter/metrics"
	"github.com/cloudfoundry/gorouter/route"
	"github.com/cloudfoundry/gorouter/route_service"
	steno "github.com/cloudfoundry/gosteno"
)

const (
	VcapCookieId    = "__VCAP_ID__"
	StickyCookieKey = "JSESSIONID"
	maxRetries      = 3
)

var noEndpointsAvailable = errors.New("No endpoints available")

type LookupRegistry interface {
	Lookup(uri route.Uri) *route.Pool
}

type AfterRoundTrip func(rsp *http.Response, endpoint *route.Endpoint, err error)

type Proxy interface {
	ServeHTTP(responseWriter http.ResponseWriter, request *http.Request)
}

type ProxyArgs struct {
	EndpointTimeout     time.Duration
	Ip                  string
	TraceKey            string
	Registry            LookupRegistry
	Reporter            metrics.ProxyReporter
	AccessLogger        access_log.AccessLogger
	SecureCookies       bool
	TLSConfig           *tls.Config
	RouteServiceEnabled bool
	RouteServiceTimeout time.Duration
	Crypto              secure.Crypto
	CryptoPrev          secure.Crypto
	ExtraHeadersToLog   []string
}

type proxy struct {
	ip                 string
	traceKey           string
	logger             *steno.Logger
	registry           LookupRegistry
	reporter           metrics.ProxyReporter
	accessLogger       access_log.AccessLogger
	transport          *http.Transport
	secureCookies      bool
	routeServiceConfig *route_service.RouteServiceConfig
	ExtraHeadersToLog  []string
}

func NewProxy(args ProxyArgs) Proxy {
	routeServiceConfig := route_service.NewRouteServiceConfig(args.RouteServiceEnabled, args.RouteServiceTimeout, args.Crypto, args.CryptoPrev)

	p := &proxy{
		accessLogger: args.AccessLogger,
		traceKey:     args.TraceKey,
		ip:           args.Ip,
		logger:       steno.NewLogger("router.proxy"),
		registry:     args.Registry,
		reporter:     args.Reporter,
		transport: &http.Transport{
			Dial: func(network, addr string) (net.Conn, error) {
				conn, err := net.DialTimeout(network, addr, 5*time.Second)
				if err != nil {
					return conn, err
				}
				if args.EndpointTimeout > 0 {
					err = conn.SetDeadline(time.Now().Add(args.EndpointTimeout))
				}
				return conn, err
			},
			DisableKeepAlives:  true,
			DisableCompression: true,
			TLSClientConfig:    args.TLSConfig,
		},
		secureCookies:      args.SecureCookies,
		routeServiceConfig: routeServiceConfig,
		ExtraHeadersToLog:  args.ExtraHeadersToLog,
	}

	return p
}

func hostWithoutPort(req *http.Request) string {
	host := req.Host

	// Remove :<port>
	pos := strings.Index(host, ":")
	if pos >= 0 {
		host = host[0:pos]
	}

	return host
}

func (p *proxy) getStickySession(request *http.Request) string {
	// Try choosing a backend using sticky session
	if _, err := request.Cookie(StickyCookieKey); err == nil {
		if sticky, err := request.Cookie(VcapCookieId); err == nil {
			return sticky.Value
		}
	}
	return ""
}

func (p *proxy) lookup(request *http.Request) *route.Pool {
	uri := route.Uri(hostWithoutPort(request) + request.RequestURI)
	return p.registry.Lookup(uri)
}

func (p *proxy) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) {
	startedAt := time.Now()
	accessLog := access_log.AccessLogRecord{
		Request:           request,
		StartedAt:         startedAt,
		ExtraHeadersToLog: p.ExtraHeadersToLog,
	}

	requestBodyCounter := &countingReadCloser{delegate: request.Body}
	request.Body = requestBodyCounter

	proxyWriter := NewProxyResponseWriter(responseWriter)
	handler := NewRequestHandler(request, proxyWriter, p.reporter, &accessLog)

	defer func() {
		accessLog.RequestBytesReceived = requestBodyCounter.GetCount()
		p.accessLogger.Log(accessLog)
	}()

	if !isProtocolSupported(request) {
		handler.HandleUnsupportedProtocol()
		return
	}

	if isLoadBalancerHeartbeat(request) {
		handler.HandleHeartbeat()
		return
	}

	routePool := p.lookup(request)
	if routePool == nil {
		p.reporter.CaptureBadRequest(request)
		handler.HandleMissingRoute()
		return
	}

	stickyEndpointId := p.getStickySession(request)
	iter := &wrappedIterator{
		nested: routePool.Endpoints(stickyEndpointId),

		afterNext: func(endpoint *route.Endpoint) {
			if endpoint != nil {
				handler.Logger().Set("RouteEndpoint", endpoint.ToLogData())
				accessLog.RouteEndpoint = endpoint
				p.reporter.CaptureRoutingRequest(endpoint, request)
			}
		},
	}

	if isTcpUpgrade(request) {
		handler.HandleTcpRequest(iter)
		accessLog.FinishedAt = time.Now()
		return
	}

	if isWebSocketUpgrade(request) {
		handler.HandleWebSocketRequest(iter)
		accessLog.FinishedAt = time.Now()
		return
	}

	backend := true

	routeServiceUrl := routePool.RouteServiceUrl()
	// Attempted to use a route service when it is not supported
	if routeServiceUrl != "" && !p.routeServiceConfig.RouteServiceEnabled() {
		handler.HandleUnsupportedRouteService()
		return
	}

	var routeServiceArgs route_service.RouteServiceArgs
	if routeServiceUrl != "" {
		rsSignature := request.Header.Get(route_service.RouteServiceSignature)
		forwardedUrlRaw := "http" + "://" + request.Host + request.RequestURI
		if hasBeenToRouteService(routeServiceUrl, rsSignature) {
			// A request from a route service destined for a backend instances
			routeServiceArgs.UrlString = routeServiceUrl
			err := p.routeServiceConfig.ValidateSignature(&request.Header, forwardedUrlRaw)
			if err != nil {
				handler.HandleBadSignature(err)
				return
			}
		} else {
			var err error
			// should not hardcode http, will be addressed by #100982038
			routeServiceArgs, err = buildRouteServiceArgs(p.routeServiceConfig, routeServiceUrl, forwardedUrlRaw)
			backend = false
			if err != nil {
				handler.HandleRouteServiceFailure(err)
				return
			}
		}
	}

	after := func(rsp *http.Response, endpoint *route.Endpoint, err error) {
		accessLog.FirstByteAt = time.Now()
		if rsp != nil {
			accessLog.StatusCode = rsp.StatusCode
		}

		if p.traceKey != "" && request.Header.Get(router_http.VcapTraceHeader) == p.traceKey {
			setTraceHeaders(responseWriter, p.ip, endpoint.CanonicalAddr())
		}

		latency := time.Since(startedAt)

		p.reporter.CaptureRoutingResponse(endpoint, rsp, startedAt, latency)

		if err != nil {
			p.reporter.CaptureBadGateway(request)
			handler.HandleBadGateway(err)
			return
		}

		if endpoint.PrivateInstanceId != "" {
			setupStickySession(responseWriter, rsp, endpoint, stickyEndpointId, p.secureCookies, routePool.ContextPath())
		}
	}

	roundTripper := NewProxyRoundTripper(backend,
		dropsonde.InstrumentedRoundTripper(p.transport), iter, handler, after)

	newReverseProxy(roundTripper, request, routeServiceArgs, p.routeServiceConfig).ServeHTTP(proxyWriter, request)

	accessLog.FinishedAt = time.Now()
	accessLog.BodyBytesSent = proxyWriter.Size()
}

func newReverseProxy(proxyTransport http.RoundTripper, req *http.Request,
	routeServiceArgs route_service.RouteServiceArgs,
	routeServiceConfig *route_service.RouteServiceConfig) http.Handler {
	rproxy := &httputil.ReverseProxy{
		Director: func(request *http.Request) {
			SetupProxyRequest(req, request, routeServiceArgs, routeServiceConfig)
		},
		Transport:     proxyTransport,
		FlushInterval: 50 * time.Millisecond,
	}

	return rproxy
}

func SetupProxyRequest(source *http.Request, target *http.Request,
	routeServiceArgs route_service.RouteServiceArgs,
	routeServiceConfig *route_service.RouteServiceConfig) {
	target.URL.Scheme = "http"
	target.URL.Host = source.Host
	target.URL.Opaque = source.RequestURI
	target.URL.RawQuery = ""

	setRequestXRequestStart(source)
	setRequestXVcapRequestId(source, nil)

	sig := target.Header.Get(route_service.RouteServiceSignature)
	if forwardingToRouteService(routeServiceArgs.UrlString, sig) {
		// An endpoint has a route service and this request did not come from the service
		routeServiceConfig.SetupRouteServiceRequest(target, routeServiceArgs)
	} else if hasBeenToRouteService(routeServiceArgs.UrlString, sig) {
		// Remove the headers since the backend should not see it
		target.Header.Del(route_service.RouteServiceSignature)
		target.Header.Del(route_service.RouteServiceMetadata)
	}
}

func newRouteServiceEndpoint() *route.Endpoint {
	return &route.Endpoint{
		Tags: map[string]string{},
	}
}

type wrappedIterator struct {
	nested    route.EndpointIterator
	afterNext func(*route.Endpoint)
}

func (i *wrappedIterator) Next() *route.Endpoint {
	e := i.nested.Next()
	if i.afterNext != nil {
		i.afterNext(e)
	}
	return e
}

func (i *wrappedIterator) EndpointFailed() {
	i.nested.EndpointFailed()
}

func buildRouteServiceArgs(routeServiceConfig *route_service.RouteServiceConfig, routeServiceUrl, forwardedUrlRaw string) (route_service.RouteServiceArgs, error) {
	var routeServiceArgs route_service.RouteServiceArgs
	sig, metadata, err := routeServiceConfig.GenerateSignatureAndMetadata(forwardedUrlRaw)
	if err != nil {
		return routeServiceArgs, err
	}

	routeServiceArgs.UrlString = routeServiceUrl
	routeServiceArgs.Signature = sig
	routeServiceArgs.Metadata = metadata
	routeServiceArgs.ForwardedUrlRaw = forwardedUrlRaw

	rsURL, err := url.Parse(routeServiceUrl)
	if err != nil {
		return routeServiceArgs, err
	}
	routeServiceArgs.ParsedUrl = rsURL

	return routeServiceArgs, nil
}

func setupStickySession(responseWriter http.ResponseWriter, response *http.Response,
	endpoint *route.Endpoint,
	originalEndpointId string,
	secureCookies bool,
	path string) {

	maxAge := 0

	// did the endpoint change?
	sticky := originalEndpointId != "" && originalEndpointId != endpoint.PrivateInstanceId

	for _, v := range response.Cookies() {
		if v.Name == StickyCookieKey {
			sticky = true
			if v.MaxAge < 0 {
				maxAge = v.MaxAge
			}
			break
		}
	}

	if sticky {
		cookie := &http.Cookie{
			Name:     VcapCookieId,
			Value:    endpoint.PrivateInstanceId,
			Path:     path,
			MaxAge:   maxAge,
			HttpOnly: true,
			Secure:   secureCookies,
		}

		http.SetCookie(responseWriter, cookie)
	}
}

func forwardingToRouteService(rsUrl, sigHeader string) bool {
	return sigHeader == "" && rsUrl != ""
}

func hasBeenToRouteService(rsUrl, sigHeader string) bool {
	return sigHeader != "" && rsUrl != ""
}

func isProtocolSupported(request *http.Request) bool {
	return request.ProtoMajor == 1 && (request.ProtoMinor == 0 || request.ProtoMinor == 1)
}

func isLoadBalancerHeartbeat(request *http.Request) bool {
	return request.UserAgent() == "HTTP-Monitor/1.1"
}

func isWebSocketUpgrade(request *http.Request) bool {
	// websocket should be case insensitive per RFC6455 4.2.1
	return strings.ToLower(upgradeHeader(request)) == "websocket"
}

func isTcpUpgrade(request *http.Request) bool {
	return upgradeHeader(request) == "tcp"
}

func upgradeHeader(request *http.Request) string {
	// handle multiple Connection field-values, either in a comma-separated string or multiple field-headers
	for _, v := range request.Header[http.CanonicalHeaderKey("Connection")] {
		// upgrade should be case insensitive per RFC6455 4.2.1
		if strings.Contains(strings.ToLower(v), "upgrade") {
			return request.Header.Get("Upgrade")
		}
	}

	return ""
}

func setTraceHeaders(responseWriter http.ResponseWriter, routerIp, addr string) {
	responseWriter.Header().Set(router_http.VcapRouterHeader, routerIp)
	responseWriter.Header().Set(router_http.VcapBackendHeader, addr)
	responseWriter.Header().Set(router_http.CfRouteEndpointHeader, addr)
}

type countingReadCloser struct {
	delegate io.ReadCloser
	count    uint32
}

func (crc *countingReadCloser) Read(b []byte) (int, error) {
	n, err := crc.delegate.Read(b)
	atomic.AddUint32(&crc.count, uint32(n))
	return n, err
}

func (crc *countingReadCloser) GetCount() int {
	return int(atomic.LoadUint32(&crc.count))
}

func (crc *countingReadCloser) Close() error {
	return crc.delegate.Close()
}
<|endoftext|>


<commit_before>// Package proxy contains all proxies used by V2Ray.
package proxy

import (
	"context"

	"v2ray.com/core/app/dispatcher"
	"v2ray.com/core/common/net"
	"v2ray.com/core/transport/internet"
	"v2ray.com/core/transport/ray"
)

// An Inbound processes inbound connections.
type Inbound interface {
	Network() net.NetworkList

	Process(context.Context, net.Network, internet.Connection, dispatcher.Interface) error
}

// An Outbound process outbound connections.
type Outbound interface {
	Process(context.Context, ray.OutboundRay, Dialer) error
}

// Dialer is used by OutboundHandler for creating outbound connections.
type Dialer interface {
	Dial(ctx context.Context, destination net.Destination) (internet.Connection, error)
}
<commit_msg>update comments<commit_after>// Package proxy contains all proxies used by V2Ray.
package proxy

import (
	"context"

	"v2ray.com/core/app/dispatcher"
	"v2ray.com/core/common/net"
	"v2ray.com/core/transport/internet"
	"v2ray.com/core/transport/ray"
)

// An Inbound processes inbound connections.
type Inbound interface {
	// Network returns a list of network that this inbound supports. Connections with not-supported networks will not be passed into Process().
	Network() net.NetworkList

	// Process processes a connection of given network. If necessary, the Inbound can dispatch the connection to an Outbound.
	Process(context.Context, net.Network, internet.Connection, dispatcher.Interface) error
}

// An Outbound process outbound connections.
type Outbound interface {
	// Process processes the given connection. The given dialer may be used to dial a system outbound connection.
	Process(context.Context, ray.OutboundRay, Dialer) error
}

// Dialer is used by OutboundHandler for creating outbound connections.
type Dialer interface {
	// Dial dials a system connection to the given destination.
	Dial(ctx context.Context, destination net.Destination) (internet.Connection, error)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/rds"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSDBOptionGroup_basic(t *testing.T) {
	var v rds.OptionGroup

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSDBOptionGroupBasicConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					testAccCheckAWSDBOptionGroupAttributes(&v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", "option-group-test-terraform"),
				),
			},
		},
	})
}

func TestAccAWSDBOptionGroup_OptionSettings(t *testing.T) {
	var v rds.OptionGroup

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSDBOptionGroupOptionSettings,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", "option-group-test-terraform"),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.#", "1"),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.961211605.option_settings.129825347.value", "UTC"),
				),
			},
			resource.TestStep{
				Config: testAccAWSDBOptionGroupOptionSettings_update,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", "option-group-test-terraform"),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.#", "1"),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.2422743510.option_settings.1350509764.value", "US/Pacific"),
				),
			},
		},
	})
}

func TestAccAWSDBOptionGroup_sqlServerOptionsUpdate(t *testing.T) {
	var v rds.OptionGroup

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSDBOptionGroupSqlServerEEOptions,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", "option-group-test-terraform"),
				),
			},

			resource.TestStep{
				Config: testAccAWSDBOptionGroupSqlServerEEOptions_update,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", "option-group-test-terraform"),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.#", "1"),
				),
			},
		},
	})
}

func TestAccAWSDBOptionGroup_multipleOptions(t *testing.T) {
	var v rds.OptionGroup

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSDBOptionGroupMultipleOptions,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", "option-group-test-terraform"),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.#", "2"),
				),
			},
		},
	})
}

func testAccCheckAWSDBOptionGroupAttributes(v *rds.OptionGroup) resource.TestCheckFunc {
	return func(s *terraform.State) error {

		if *v.EngineName != "mysql" {
			return fmt.Errorf("bad engine_name: %#v", *v.EngineName)
		}

		if *v.MajorEngineVersion != "5.6" {
			return fmt.Errorf("bad major_engine_version: %#v", *v.MajorEngineVersion)
		}

		if *v.OptionGroupDescription != "Test option group for terraform" {
			return fmt.Errorf("bad option_group_description: %#v", *v.OptionGroupDescription)
		}

		return nil
	}
}

func TestResourceAWSDBOptionGroupName_validation(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			Value:    "testing123!",
			ErrCount: 1,
		},
		{
			Value:    "1testing123",
			ErrCount: 1,
		},
		{
			Value:    "testing--123",
			ErrCount: 1,
		},
		{
			Value:    "testing123-",
			ErrCount: 1,
		},
		{
			Value:    randomString(256),
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateDbOptionGroupName(tc.Value, "aws_db_option_group_name")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected the DB Option Group Name to trigger a validation error")
		}
	}
}

func testAccCheckAWSDBOptionGroupExists(n string, v *rds.OptionGroup) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No DB Option Group Name is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).rdsconn

		opts := rds.DescribeOptionGroupsInput{
			OptionGroupName: aws.String(rs.Primary.ID),
		}

		resp, err := conn.DescribeOptionGroups(&opts)

		if err != nil {
			return err
		}

		if len(resp.OptionGroupsList) != 1 ||
			*resp.OptionGroupsList[0].OptionGroupName != rs.Primary.ID {
			return fmt.Errorf("DB Option Group not found")
		}

		*v = *resp.OptionGroupsList[0]

		return nil
	}
}

func testAccCheckAWSDBOptionGroupDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).rdsconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_db_option_group" {
			continue
		}

		resp, err := conn.DescribeOptionGroups(
			&rds.DescribeOptionGroupsInput{
				OptionGroupName: aws.String(rs.Primary.ID),
			})

		if err == nil {
			if len(resp.OptionGroupsList) != 0 &&
				*resp.OptionGroupsList[0].OptionGroupName == rs.Primary.ID {
				return fmt.Errorf("DB Option Group still exists")
			}
		}

		// Verify the error
		newerr, ok := err.(awserr.Error)
		if !ok {
			return err
		}
		if newerr.Code() != "OptionGroupNotFoundFault" {
			return err
		}
	}

	return nil
}

const testAccAWSDBOptionGroupBasicConfig = `
resource "aws_db_option_group" "bar" {
  name                     = "option-group-test-terraform"
  option_group_description = "Test option group for terraform"
  engine_name              = "mysql"
  major_engine_version     = "5.6"
}
`

const testAccAWSDBOptionGroupOptionSettings = `
resource "aws_db_option_group" "bar" {
  name                     = "option-group-test-terraform"
  option_group_description = "Test option group for terraform"
  engine_name              = "oracle-ee"
  major_engine_version     = "11.2"

  option {
    option_name = "Timezone"
    option_settings {
      name = "TIME_ZONE"
      value = "UTC"
    }
  }
}
`

const testAccAWSDBOptionGroupOptionSettings_update = `
resource "aws_db_option_group" "bar" {
  name                     = "option-group-test-terraform"
  option_group_description = "Test option group for terraform"
  engine_name              = "oracle-ee"
  major_engine_version     = "11.2"

  option {
    option_name = "Timezone"
    option_settings {
      name = "TIME_ZONE"
      value = "US/Pacific"
    }
  }
}
`

const testAccAWSDBOptionGroupSqlServerEEOptions = `
resource "aws_db_option_group" "bar" {
  name                     = "option-group-test-terraform"
  option_group_description = "Test option group for terraform"
  engine_name              = "sqlserver-ee"
  major_engine_version     = "11.00"
}
`

const testAccAWSDBOptionGroupSqlServerEEOptions_update = `
resource "aws_db_option_group" "bar" {
  name                     = "option-group-test-terraform"
  option_group_description = "Test option group for terraform"
  engine_name              = "sqlserver-ee"
  major_engine_version     = "11.00"

  option {
    option_name = "Mirroring"
  }
}
`

const testAccAWSDBOptionGroupMultipleOptions = `
resource "aws_db_option_group" "bar" {
  name                     = "option-group-test-terraform"
  option_group_description = "Test option group for terraform"
  engine_name              = "oracle-se"
  major_engine_version     = "11.2"

  option {
    option_name = "STATSPACK"
  }

  option {
    option_name = "XMLDB"
  }
}
`
<commit_msg>provider/aws: Randomize DB Option Group Name to avoid name conflicts in Travis CI<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/rds"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSDBOptionGroup_basic(t *testing.T) {
	var v rds.OptionGroup
	rName := fmt.Sprintf("option-group-test-terraform-%s", acctest.RandString(5))

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSDBOptionGroupBasicConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					testAccCheckAWSDBOptionGroupAttributes(&v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", rName),
				),
			},
		},
	})
}

func TestAccAWSDBOptionGroup_OptionSettings(t *testing.T) {
	var v rds.OptionGroup
	rName := fmt.Sprintf("option-group-test-terraform-%s", acctest.RandString(5))

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSDBOptionGroupOptionSettings(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", rName),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.#", "1"),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.961211605.option_settings.129825347.value", "UTC"),
				),
			},
			resource.TestStep{
				Config: testAccAWSDBOptionGroupOptionSettings_update(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", rName),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.#", "1"),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.2422743510.option_settings.1350509764.value", "US/Pacific"),
				),
			},
		},
	})
}

func TestAccAWSDBOptionGroup_sqlServerOptionsUpdate(t *testing.T) {
	var v rds.OptionGroup
	rName := fmt.Sprintf("option-group-test-terraform-%s", acctest.RandString(5))

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSDBOptionGroupSqlServerEEOptions(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", rName),
				),
			},

			resource.TestStep{
				Config: testAccAWSDBOptionGroupSqlServerEEOptions_update(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", rName),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.#", "1"),
				),
			},
		},
	})
}

func TestAccAWSDBOptionGroup_multipleOptions(t *testing.T) {
	var v rds.OptionGroup
	rName := fmt.Sprintf("option-group-test-terraform-%s", acctest.RandString(5))

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSDBOptionGroupMultipleOptions(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBOptionGroupExists("aws_db_option_group.bar", &v),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "name", rName),
					resource.TestCheckResourceAttr(
						"aws_db_option_group.bar", "option.#", "2"),
				),
			},
		},
	})
}

func testAccCheckAWSDBOptionGroupAttributes(v *rds.OptionGroup) resource.TestCheckFunc {
	return func(s *terraform.State) error {

		if *v.EngineName != "mysql" {
			return fmt.Errorf("bad engine_name: %#v", *v.EngineName)
		}

		if *v.MajorEngineVersion != "5.6" {
			return fmt.Errorf("bad major_engine_version: %#v", *v.MajorEngineVersion)
		}

		if *v.OptionGroupDescription != "Test option group for terraform" {
			return fmt.Errorf("bad option_group_description: %#v", *v.OptionGroupDescription)
		}

		return nil
	}
}

func TestResourceAWSDBOptionGroupName_validation(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			Value:    "testing123!",
			ErrCount: 1,
		},
		{
			Value:    "1testing123",
			ErrCount: 1,
		},
		{
			Value:    "testing--123",
			ErrCount: 1,
		},
		{
			Value:    "testing123-",
			ErrCount: 1,
		},
		{
			Value:    randomString(256),
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateDbOptionGroupName(tc.Value, "aws_db_option_group_name")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected the DB Option Group Name to trigger a validation error")
		}
	}
}

func testAccCheckAWSDBOptionGroupExists(n string, v *rds.OptionGroup) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No DB Option Group Name is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).rdsconn

		opts := rds.DescribeOptionGroupsInput{
			OptionGroupName: aws.String(rs.Primary.ID),
		}

		resp, err := conn.DescribeOptionGroups(&opts)

		if err != nil {
			return err
		}

		if len(resp.OptionGroupsList) != 1 ||
			*resp.OptionGroupsList[0].OptionGroupName != rs.Primary.ID {
			return fmt.Errorf("DB Option Group not found")
		}

		*v = *resp.OptionGroupsList[0]

		return nil
	}
}

func testAccCheckAWSDBOptionGroupDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).rdsconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_db_option_group" {
			continue
		}

		resp, err := conn.DescribeOptionGroups(
			&rds.DescribeOptionGroupsInput{
				OptionGroupName: aws.String(rs.Primary.ID),
			})

		if err == nil {
			if len(resp.OptionGroupsList) != 0 &&
				*resp.OptionGroupsList[0].OptionGroupName == rs.Primary.ID {
				return fmt.Errorf("DB Option Group still exists")
			}
		}

		// Verify the error
		newerr, ok := err.(awserr.Error)
		if !ok {
			return err
		}
		if newerr.Code() != "OptionGroupNotFoundFault" {
			return err
		}
	}

	return nil
}

func testAccAWSDBOptionGroupBasicConfig(r string) string {
	return fmt.Sprintf(`
resource "aws_db_option_group" "bar" {
  name                     = "%s"
  option_group_description = "Test option group for terraform"
  engine_name              = "mysql"
  major_engine_version     = "5.6"
}
`, r)
}

func testAccAWSDBOptionGroupOptionSettings(r string) string {
	return fmt.Sprintf(`
resource "aws_db_option_group" "bar" {
  name                     = "%s"
  option_group_description = "Test option group for terraform"
  engine_name              = "oracle-ee"
  major_engine_version     = "11.2"

  option {
    option_name = "Timezone"
    option_settings {
      name = "TIME_ZONE"
      value = "UTC"
    }
  }
}
`, r)
}

func testAccAWSDBOptionGroupOptionSettings_update(r string) string {
	return fmt.Sprintf(`
resource "aws_db_option_group" "bar" {
  name                     = "%s"
  option_group_description = "Test option group for terraform"
  engine_name              = "oracle-ee"
  major_engine_version     = "11.2"

  option {
    option_name = "Timezone"
    option_settings {
      name = "TIME_ZONE"
      value = "US/Pacific"
    }
  }
}
`, r)
}

func testAccAWSDBOptionGroupSqlServerEEOptions(r string) string {
	return fmt.Sprintf(`
resource "aws_db_option_group" "bar" {
  name                     = "%s"
  option_group_description = "Test option group for terraform"
  engine_name              = "sqlserver-ee"
  major_engine_version     = "11.00"
}
`, r)
}

func testAccAWSDBOptionGroupSqlServerEEOptions_update(r string) string {
	return fmt.Sprintf(`
resource "aws_db_option_group" "bar" {
  name                     = "%s"
  option_group_description = "Test option group for terraform"
  engine_name              = "sqlserver-ee"
  major_engine_version     = "11.00"

  option {
    option_name = "Mirroring"
  }
}
`, r)
}

func testAccAWSDBOptionGroupMultipleOptions(r string) string {
	return fmt.Sprintf(`
resource "aws_db_option_group" "bar" {
  name                     = "%s"
  option_group_description = "Test option group for terraform"
  engine_name              = "oracle-se"
  major_engine_version     = "11.2"

  option {
    option_name = "STATSPACK"
  }

  option {
    option_name = "XMLDB"
  }
}
`, r)
}
<|endoftext|>


<commit_before>// Copyright 2015 Claudemiro Alves Feitosa Neto. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package gochip8

import (
	"testing"

	"github.com/bmizerany/assert"
)

// dumbSound - Only for testing purpuses
type dumbSound struct {
	BeepCalled bool
}

func (s *dumbSound) Beep() {
	(*s).BeepCalled = true
}

// newCpuAt creates a new cpu and write the ins to the pc memory location
// Only for testing purpuse
func newCpuAt(ins uint16) cpu {
	s := &dumbSound{}
	c := newCpu(s)
	c.memory.WriteWord(uint16(c.pc), ins)

	return c
}

func TestTimers(t *testing.T) {
	s := &dumbSound{}
	c := newCpu(s)

	// With Beep
	c.memory.WriteWord(uint16(c.pc), 0x0E0)

	c.dt = 1
	c.st = 1

	assert.Equal(t, s.BeepCalled, false)

	c.Step()

	assert.Equal(t, c.dt, byte(0))
	assert.Equal(t, c.st, byte(0))
	assert.Equal(t, s.BeepCalled, true)

	// No Beep
	c.memory.WriteWord(uint16(c.pc), 0x0E0)
	s.BeepCalled = false

	c.st = 2
	c.Step()

	assert.Equal(t, s.BeepCalled, false)
	assert.Equal(t, c.st, byte(1))
}

// 00E0 - CLS
func Test00E0(t *testing.T) {

	c := newCpuAt(0x00E0)
	c.gfx.SetPixel(0, 0)
	c.Step()

	for i := 0; i < 64; i++ {
		for j := 0; j < 32; j++ {
			assert.Equal(t, byte(COLOR_BLACK), byte(c.gfx.GetPixel(i, j)))
		}
	}
}

// 00EE - RET
func Test00EE(t *testing.T) {
	c := newCpuAt(0x00EE)

	c.stack.Push(pc(1))
	c.Step()

	assert.Equal(t, pc(1), c.pc)
}

// 1nnn - JP addr
func Test1000(t *testing.T) {
	c := newCpuAt(0x1FFF)
	c.Step()

	assert.Equal(t, pc(0x0FFF), c.pc)
}

// 2nnn - CALL addr
func Test2000(t *testing.T) {
	c := newCpuAt(0x2FFF)
	oldPC := c.pc + 2 // The increment happen before the Step

	c.Step()

	assert.Equal(t, oldPC, c.stack.Pop())
	assert.Equal(t, pc(0x0FFF), c.pc)
}

// 3xkk - SE Vx, byte
func Test3000Equal(t *testing.T) {
	c := newCpuAt(0x31FF)
	c.regs[1] = 0xFF

	oldPC := c.pc + 4
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 3xkk - SE Vx, byte
func Test3000NotEqual(t *testing.T) {
	c := newCpuAt(0x31FF)
	c.regs[1] = 0xAA

	oldPC := c.pc + 2
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 4xkk - SNE Vx, byte
func Test4000Equal(t *testing.T) {
	c := newCpuAt(0x41FF)
	c.regs[1] = 0xFF

	oldPC := c.pc + 2
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 4xkk - SNE Vx, byte
func Test4000NotEqual(t *testing.T) {
	c := newCpuAt(0x41FF)
	c.regs[1] = 0xAA

	oldPC := c.pc + 4
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 5xy0 - SE Vx, Vy
func Test5000Equal(t *testing.T) {
	c := newCpuAt(0x512F)
	c.regs[1] = 0xFF
	c.regs[2] = 0xFF

	oldPC := c.pc + 4
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 5xy0 - SE Vx, Vy
func Test5000NotEqual(t *testing.T) {
	c := newCpuAt(0x512F)
	c.regs[1] = 0xFF
	c.regs[2] = 0xAA

	oldPC := c.pc + 2
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 6xkk - LD Vx, byte
func Test6000(t *testing.T) {
	c := newCpuAt(0x61FF)
	c.Step()
	assert.Equal(t, c.regs[1], byte(0xFF))
}

// 7xkk - ADD Vx, byte
func Test7000(t *testing.T) {
	c := newCpuAt(0x7101)
	c.regs[1] = 1
	c.Step()
	assert.Equal(t, c.regs[1], byte(2))
}

// 8xy0 - LD Vx, Vy
func Test8xy0(t *testing.T) {
	c := newCpuAt(0x8120)
	c.regs[1] = 1
	c.regs[2] = 0
	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[2], byte(0))
	c.Step()
	assert.Equal(t, c.regs[1], byte(0))
	assert.Equal(t, c.regs[2], byte(0))
}

// 8xy1 - OR Vx, Vy
func Test8xy1(t *testing.T) {
	c := newCpuAt(0x8121)
	c.regs[1] = 1
	c.regs[2] = 2
	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[2], byte(2))
	c.Step()
	assert.Equal(t, c.regs[1], byte(1|2))
	assert.Equal(t, c.regs[2], byte(2))
}

// 8xy2 - OR Vx, Vy
func Test8xy2(t *testing.T) {
	c := newCpuAt(0x8122)
	c.regs[1] = 1
	c.regs[2] = 2
	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[2], byte(2))
	c.Step()
	assert.Equal(t, c.regs[1], byte(1&2))
	assert.Equal(t, c.regs[2], byte(2))
}

// 8xy3 - OR Vx, Vy
func Test8xy3(t *testing.T) {
	c := newCpuAt(0x8123)
	c.regs[1] = 1
	c.regs[2] = 2
	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[2], byte(2))
	c.Step()
	assert.Equal(t, c.regs[1], byte(1^2))
	assert.Equal(t, c.regs[2], byte(2))
}

// 8xy4 - ADD Vx, Vy
func Test8xy4Overflow(t *testing.T) {
	c := newCpuAt(0x8124)
	c.regs[1] = 0xFF
	c.regs[2] = 1

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(0))
	assert.Equal(t, c.regs[0xF], byte(1))
}

// 8xy4 - ADD Vx, Vy
func Test8xy4ONotverflow(t *testing.T) {
	c := newCpuAt(0x8124)
	c.regs[1] = 0xF0
	c.regs[2] = 1

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(0xF0+1))
	assert.Equal(t, c.regs[0xF], byte(0))
}

// 8xy5 - SUB Vx, Vy
func Test8xy5Greater(t *testing.T) {
	c := newCpuAt(0x8125)
	c.regs[1] = 2
	c.regs[2] = 1

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[0xF], byte(1))
}

// 8xy5 - SUB Vx, Vy
func Test8xy5NotGreater(t *testing.T) {
	c := newCpuAt(0x8125)
	c.regs[1] = 1
	c.regs[2] = 2

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(0xFF))
	assert.Equal(t, c.regs[0xF], byte(0))
}

// 8xy6 - SHR Vx {, Vy}
func Test8xy6(t *testing.T) {
	c := newCpuAt(0x8126)
	c.regs[1] = 1

	c.Step()

	assert.Equal(t, c.regs[0xF], byte(1&0x0001))
	assert.Equal(t, c.regs[1], byte(1/2))
}

// 8xy7 - SUBN Vx, Vy
func Test8xy7Greater(t *testing.T) {
	c := newCpuAt(0x8127)
	c.regs[1] = 1
	c.regs[2] = 2

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[0xF], byte(1))
}

// 8xy7 - SUBN Vx, Vy
func Test8xy7NotGreater(t *testing.T) {
	c := newCpuAt(0x8127)
	c.regs[1] = 2
	c.regs[2] = 1

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(0xFF))
	assert.Equal(t, c.regs[0xF], byte(0))
}

// 8xyE - SHL Vx {, Vy}
func Test8xyE(t *testing.T) {
	c := newCpuAt(0x812E)
	c.regs[1] = 1

	c.Step()

	assert.Equal(t, c.regs[0xF], byte(1&0x0001))
	assert.Equal(t, c.regs[1], byte(1*2))
}

// 9xy0 - SNE Vx, Vy
func Test9xy0NotEqual(t *testing.T) {
	c := newCpuAt(0x9120)
	c.regs[1] = 1
	c.regs[2] = 2

	oldPC := c.pc

	c.Step()

	assert.Equal(t, c.pc, oldPC+4)
}

// 9xy0 - SNE Vx, Vy
func Test9xy0Equal(t *testing.T) {
	c := newCpuAt(0x9120)
	c.regs[1] = 1
	c.regs[2] = 1

	oldPC := c.pc

	c.Step()

	assert.Equal(t, c.pc, oldPC+2)
}

// Annn - LD I, addr
func TestA000(t *testing.T) {
	c := newCpuAt(0xAFFF)

	c.Step()

	assert.Equal(t, c.i, uint16(0xFFF))
}
<commit_msg>Added Test for 0xB000<commit_after>// Copyright 2015 Claudemiro Alves Feitosa Neto. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package gochip8

import (
	"testing"

	"github.com/bmizerany/assert"
)

// dumbSound - Only for testing purpuses
type dumbSound struct {
	BeepCalled bool
}

func (s *dumbSound) Beep() {
	(*s).BeepCalled = true
}

// newCpuAt creates a new cpu and write the ins to the pc memory location
// Only for testing purpuse
func newCpuAt(ins uint16) cpu {
	s := &dumbSound{}
	c := newCpu(s)
	c.memory.WriteWord(uint16(c.pc), ins)

	return c
}

func TestTimers(t *testing.T) {
	s := &dumbSound{}
	c := newCpu(s)

	// With Beep
	c.memory.WriteWord(uint16(c.pc), 0x0E0)

	c.dt = 1
	c.st = 1

	assert.Equal(t, s.BeepCalled, false)

	c.Step()

	assert.Equal(t, c.dt, byte(0))
	assert.Equal(t, c.st, byte(0))
	assert.Equal(t, s.BeepCalled, true)

	// No Beep
	c.memory.WriteWord(uint16(c.pc), 0x0E0)
	s.BeepCalled = false

	c.st = 2
	c.Step()

	assert.Equal(t, s.BeepCalled, false)
	assert.Equal(t, c.st, byte(1))
}

// 00E0 - CLS
func Test00E0(t *testing.T) {

	c := newCpuAt(0x00E0)
	c.gfx.SetPixel(0, 0)
	c.Step()

	for i := 0; i < 64; i++ {
		for j := 0; j < 32; j++ {
			assert.Equal(t, byte(COLOR_BLACK), byte(c.gfx.GetPixel(i, j)))
		}
	}
}

// 00EE - RET
func Test00EE(t *testing.T) {
	c := newCpuAt(0x00EE)

	c.stack.Push(pc(1))
	c.Step()

	assert.Equal(t, pc(1), c.pc)
}

// 1nnn - JP addr
func Test1000(t *testing.T) {
	c := newCpuAt(0x1FFF)
	c.Step()

	assert.Equal(t, pc(0x0FFF), c.pc)
}

// 2nnn - CALL addr
func Test2000(t *testing.T) {
	c := newCpuAt(0x2FFF)
	oldPC := c.pc + 2 // The increment happen before the Step

	c.Step()

	assert.Equal(t, oldPC, c.stack.Pop())
	assert.Equal(t, pc(0x0FFF), c.pc)
}

// 3xkk - SE Vx, byte
func Test3000Equal(t *testing.T) {
	c := newCpuAt(0x31FF)
	c.regs[1] = 0xFF

	oldPC := c.pc + 4
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 3xkk - SE Vx, byte
func Test3000NotEqual(t *testing.T) {
	c := newCpuAt(0x31FF)
	c.regs[1] = 0xAA

	oldPC := c.pc + 2
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 4xkk - SNE Vx, byte
func Test4000Equal(t *testing.T) {
	c := newCpuAt(0x41FF)
	c.regs[1] = 0xFF

	oldPC := c.pc + 2
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 4xkk - SNE Vx, byte
func Test4000NotEqual(t *testing.T) {
	c := newCpuAt(0x41FF)
	c.regs[1] = 0xAA

	oldPC := c.pc + 4
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 5xy0 - SE Vx, Vy
func Test5000Equal(t *testing.T) {
	c := newCpuAt(0x512F)
	c.regs[1] = 0xFF
	c.regs[2] = 0xFF

	oldPC := c.pc + 4
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 5xy0 - SE Vx, Vy
func Test5000NotEqual(t *testing.T) {
	c := newCpuAt(0x512F)
	c.regs[1] = 0xFF
	c.regs[2] = 0xAA

	oldPC := c.pc + 2
	c.Step()

	assert.Equal(t, oldPC, c.pc)
}

// 6xkk - LD Vx, byte
func Test6000(t *testing.T) {
	c := newCpuAt(0x61FF)
	c.Step()
	assert.Equal(t, c.regs[1], byte(0xFF))
}

// 7xkk - ADD Vx, byte
func Test7000(t *testing.T) {
	c := newCpuAt(0x7101)
	c.regs[1] = 1
	c.Step()
	assert.Equal(t, c.regs[1], byte(2))
}

// 8xy0 - LD Vx, Vy
func Test8xy0(t *testing.T) {
	c := newCpuAt(0x8120)
	c.regs[1] = 1
	c.regs[2] = 0
	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[2], byte(0))
	c.Step()
	assert.Equal(t, c.regs[1], byte(0))
	assert.Equal(t, c.regs[2], byte(0))
}

// 8xy1 - OR Vx, Vy
func Test8xy1(t *testing.T) {
	c := newCpuAt(0x8121)
	c.regs[1] = 1
	c.regs[2] = 2
	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[2], byte(2))
	c.Step()
	assert.Equal(t, c.regs[1], byte(1|2))
	assert.Equal(t, c.regs[2], byte(2))
}

// 8xy2 - OR Vx, Vy
func Test8xy2(t *testing.T) {
	c := newCpuAt(0x8122)
	c.regs[1] = 1
	c.regs[2] = 2
	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[2], byte(2))
	c.Step()
	assert.Equal(t, c.regs[1], byte(1&2))
	assert.Equal(t, c.regs[2], byte(2))
}

// 8xy3 - OR Vx, Vy
func Test8xy3(t *testing.T) {
	c := newCpuAt(0x8123)
	c.regs[1] = 1
	c.regs[2] = 2
	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[2], byte(2))
	c.Step()
	assert.Equal(t, c.regs[1], byte(1^2))
	assert.Equal(t, c.regs[2], byte(2))
}

// 8xy4 - ADD Vx, Vy
func Test8xy4Overflow(t *testing.T) {
	c := newCpuAt(0x8124)
	c.regs[1] = 0xFF
	c.regs[2] = 1

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(0))
	assert.Equal(t, c.regs[0xF], byte(1))
}

// 8xy4 - ADD Vx, Vy
func Test8xy4ONotverflow(t *testing.T) {
	c := newCpuAt(0x8124)
	c.regs[1] = 0xF0
	c.regs[2] = 1

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(0xF0+1))
	assert.Equal(t, c.regs[0xF], byte(0))
}

// 8xy5 - SUB Vx, Vy
func Test8xy5Greater(t *testing.T) {
	c := newCpuAt(0x8125)
	c.regs[1] = 2
	c.regs[2] = 1

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[0xF], byte(1))
}

// 8xy5 - SUB Vx, Vy
func Test8xy5NotGreater(t *testing.T) {
	c := newCpuAt(0x8125)
	c.regs[1] = 1
	c.regs[2] = 2

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(0xFF))
	assert.Equal(t, c.regs[0xF], byte(0))
}

// 8xy6 - SHR Vx {, Vy}
func Test8xy6(t *testing.T) {
	c := newCpuAt(0x8126)
	c.regs[1] = 1

	c.Step()

	assert.Equal(t, c.regs[0xF], byte(1&0x0001))
	assert.Equal(t, c.regs[1], byte(1/2))
}

// 8xy7 - SUBN Vx, Vy
func Test8xy7Greater(t *testing.T) {
	c := newCpuAt(0x8127)
	c.regs[1] = 1
	c.regs[2] = 2

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(1))
	assert.Equal(t, c.regs[0xF], byte(1))
}

// 8xy7 - SUBN Vx, Vy
func Test8xy7NotGreater(t *testing.T) {
	c := newCpuAt(0x8127)
	c.regs[1] = 2
	c.regs[2] = 1

	assert.Equal(t, c.regs[0xF], byte(0))

	c.Step()

	assert.Equal(t, c.regs[1], byte(0xFF))
	assert.Equal(t, c.regs[0xF], byte(0))
}

// 8xyE - SHL Vx {, Vy}
func Test8xyE(t *testing.T) {
	c := newCpuAt(0x812E)
	c.regs[1] = 1

	c.Step()

	assert.Equal(t, c.regs[0xF], byte(1&0x0001))
	assert.Equal(t, c.regs[1], byte(1*2))
}

// 9xy0 - SNE Vx, Vy
func Test9xy0NotEqual(t *testing.T) {
	c := newCpuAt(0x9120)
	c.regs[1] = 1
	c.regs[2] = 2

	oldPC := c.pc

	c.Step()

	assert.Equal(t, c.pc, oldPC+4)
}

// 9xy0 - SNE Vx, Vy
func Test9xy0Equal(t *testing.T) {
	c := newCpuAt(0x9120)
	c.regs[1] = 1
	c.regs[2] = 1

	oldPC := c.pc

	c.Step()

	assert.Equal(t, c.pc, oldPC+2)
}

// Annn - LD I, addr
func TestA000(t *testing.T) {
	c := newCpuAt(0xAFFF)

	c.Step()

	assert.Equal(t, c.i, uint16(0xFFF))
}

// Bnnn - JP V0, addr
func TestB000(t *testing.T) {
	c := newCpuAt(0xBFFF)
	c.regs[0] = 1

	c.Step()

	assert.Equal(t, c.pc, pc(0xFFF+1))
}
<|endoftext|>


<commit_before>// Package bitmap provides a []bool/bitmap implementation with standardized
// iteration. Bitmaps are the equivalent of []bool, with improved compression
// for runs of similar values, and faster operations on ranges and the like.
package bitmap

import (
	"math"

	"github.com/RoaringBitmap/roaring"

	"github.com/anacrolix/missinggo/iter"
)

const MaxInt = -1

type Interface interface {
	Len() int
}

// Bitmaps store the existence of values in [0,math.MaxUint32] more
// efficiently than []bool. The empty value starts with no bits set.
type Bitmap struct {
	rb *roaring.Bitmap
}

// The number of set bits in the bitmap. Also known as cardinality.
func (me *Bitmap) Len() int {
	if me.rb == nil {
		return 0
	}
	return int(me.rb.GetCardinality())
}

func (me Bitmap) ToSortedSlice() (ret []int) {
	if me.rb == nil {
		return
	}
	for _, ui32 := range me.rb.ToArray() {
		ret = append(ret, int(int32(ui32)))
	}
	return
}

func (me *Bitmap) lazyRB() *roaring.Bitmap {
	if me.rb == nil {
		me.rb = roaring.NewBitmap()
	}
	return me.rb
}

func (me Bitmap) Iter(cb iter.Callback) {
	me.IterTyped(func(i int) bool {
		return cb(i)
	})
}

// Returns true if all values were traversed without early termination.
func (me Bitmap) IterTyped(f func(int) bool) bool {
	if me.rb == nil {
		return true
	}
	it := me.rb.Iterator()
	for it.HasNext() {
		if !f(int(it.Next())) {
			return false
		}
	}
	return true
}

func checkInt(i int) {
	if i < math.MinInt32 || i > math.MaxInt32 {
		panic("out of bounds")
	}
}

func (me *Bitmap) Add(is ...int) {
	rb := me.lazyRB()
	for _, i := range is {
		checkInt(i)
		rb.AddInt(i)
	}
}

func (me *Bitmap) AddRange(begin, end int) {
	if begin >= end {
		return
	}
	me.lazyRB().AddRange(uint64(begin), uint64(end))
}

func (me *Bitmap) Remove(i int) bool {
	if me.rb == nil {
		return false
	}
	return me.rb.CheckedRemove(uint32(i))
}

func (me *Bitmap) Union(other Bitmap) {
	me.lazyRB().Or(other.lazyRB())
}

func (me *Bitmap) Contains(i int) bool {
	if me.rb == nil {
		return false
	}
	return me.rb.Contains(uint32(i))
}

func (me *Bitmap) Sub(other Bitmap) {
	if other.rb == nil {
		return
	}
	if me.rb == nil {
		return
	}
	me.rb.AndNot(other.rb)
}

func (me *Bitmap) Clear() {
	if me.rb == nil {
		return
	}
	me.rb.Clear()
}

func (me Bitmap) Copy() (ret Bitmap) {
	ret = me
	if ret.rb != nil {
		ret.rb = ret.rb.Clone()
	}
	return
}

func (me *Bitmap) FlipRange(begin, end int) {
	me.lazyRB().FlipInt(begin, end)
}

func (me *Bitmap) Get(bit int) bool {
	return me.rb != nil && me.rb.ContainsInt(bit)
}

func (me *Bitmap) Set(bit int, value bool) {
	if value {
		me.lazyRB().AddInt(bit)
	} else {
		if me.rb != nil {
			me.rb.Remove(uint32(bit))
		}
	}
}

func (me *Bitmap) RemoveRange(begin, end int) *Bitmap {
	if me.rb == nil {
		return me
	}
	me.rb.RemoveRange(uint64(begin), uint64(end))
	return me
}

func (me Bitmap) IsEmpty() bool {
	return me.rb == nil || me.rb.IsEmpty()
}
<commit_msg>bitmap: Add ToEnd<commit_after>// Package bitmap provides a []bool/bitmap implementation with standardized
// iteration. Bitmaps are the equivalent of []bool, with improved compression
// for runs of similar values, and faster operations on ranges and the like.
package bitmap

import (
	"math"

	"github.com/RoaringBitmap/roaring"

	"github.com/anacrolix/missinggo/iter"
)

const MaxInt = -1

type Interface interface {
	Len() int
}

// Bitmaps store the existence of values in [0,math.MaxUint32] more
// efficiently than []bool. The empty value starts with no bits set.
type Bitmap struct {
	rb *roaring.Bitmap
}

var ToEnd int = -1

// The number of set bits in the bitmap. Also known as cardinality.
func (me *Bitmap) Len() int {
	if me.rb == nil {
		return 0
	}
	return int(me.rb.GetCardinality())
}

func (me Bitmap) ToSortedSlice() (ret []int) {
	if me.rb == nil {
		return
	}
	for _, ui32 := range me.rb.ToArray() {
		ret = append(ret, int(int32(ui32)))
	}
	return
}

func (me *Bitmap) lazyRB() *roaring.Bitmap {
	if me.rb == nil {
		me.rb = roaring.NewBitmap()
	}
	return me.rb
}

func (me Bitmap) Iter(cb iter.Callback) {
	me.IterTyped(func(i int) bool {
		return cb(i)
	})
}

// Returns true if all values were traversed without early termination.
func (me Bitmap) IterTyped(f func(int) bool) bool {
	if me.rb == nil {
		return true
	}
	it := me.rb.Iterator()
	for it.HasNext() {
		if !f(int(it.Next())) {
			return false
		}
	}
	return true
}

func checkInt(i int) {
	if i < math.MinInt32 || i > math.MaxInt32 {
		panic("out of bounds")
	}
}

func (me *Bitmap) Add(is ...int) {
	rb := me.lazyRB()
	for _, i := range is {
		checkInt(i)
		rb.AddInt(i)
	}
}

func (me *Bitmap) AddRange(begin, end int) {
	if begin >= end {
		return
	}
	me.lazyRB().AddRange(uint64(begin), uint64(end))
}

func (me *Bitmap) Remove(i int) bool {
	if me.rb == nil {
		return false
	}
	return me.rb.CheckedRemove(uint32(i))
}

func (me *Bitmap) Union(other Bitmap) {
	me.lazyRB().Or(other.lazyRB())
}

func (me *Bitmap) Contains(i int) bool {
	if me.rb == nil {
		return false
	}
	return me.rb.Contains(uint32(i))
}

func (me *Bitmap) Sub(other Bitmap) {
	if other.rb == nil {
		return
	}
	if me.rb == nil {
		return
	}
	me.rb.AndNot(other.rb)
}

func (me *Bitmap) Clear() {
	if me.rb == nil {
		return
	}
	me.rb.Clear()
}

func (me Bitmap) Copy() (ret Bitmap) {
	ret = me
	if ret.rb != nil {
		ret.rb = ret.rb.Clone()
	}
	return
}

func (me *Bitmap) FlipRange(begin, end int) {
	me.lazyRB().FlipInt(begin, end)
}

func (me *Bitmap) Get(bit int) bool {
	return me.rb != nil && me.rb.ContainsInt(bit)
}

func (me *Bitmap) Set(bit int, value bool) {
	if value {
		me.lazyRB().AddInt(bit)
	} else {
		if me.rb != nil {
			me.rb.Remove(uint32(bit))
		}
	}
}

func (me *Bitmap) RemoveRange(begin, end int) *Bitmap {
	if me.rb == nil {
		return me
	}
	rangeEnd := uint64(end)
	if end == ToEnd {
		rangeEnd = 0x100000000
	}
	me.rb.RemoveRange(uint64(begin), rangeEnd)
	return me
}

func (me Bitmap) IsEmpty() bool {
	return me.rb == nil || me.rb.IsEmpty()
}
<|endoftext|>