Update godeps

This commit is contained in:
Manuel Alejandro de Brito Fontes 2016-03-19 20:00:11 -03:00 committed by Manuel de Brito Fontes
parent ffe6baa14c
commit 9b142b56f8
1137 changed files with 22773 additions and 189176 deletions

27
Godeps/_workspace/src/google.golang.org/api/LICENSE generated vendored Normal file
View file

@ -0,0 +1,27 @@
Copyright (c) 2011 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,367 +0,0 @@
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gensupport
import (
"encoding/json"
"reflect"
"testing"
"google.golang.org/api/googleapi"
)
type schema struct {
// Basic types
B bool `json:"b,omitempty"`
F float64 `json:"f,omitempty"`
I int64 `json:"i,omitempty"`
Istr int64 `json:"istr,omitempty,string"`
Str string `json:"str,omitempty"`
// Pointers to basic types
PB *bool `json:"pb,omitempty"`
PF *float64 `json:"pf,omitempty"`
PI *int64 `json:"pi,omitempty"`
PIStr *int64 `json:"pistr,omitempty,string"`
PStr *string `json:"pstr,omitempty"`
// Other types
Int64s googleapi.Int64s `json:"i64s,omitempty"`
S []int `json:"s,omitempty"`
M map[string]string `json:"m,omitempty"`
Any interface{} `json:"any,omitempty"`
Child *child `json:"child,omitempty"`
ForceSendFields []string `json:"-"`
}
type child struct {
B bool `json:"childbool,omitempty"`
}
type testCase struct {
s schema
want string
}
func TestBasics(t *testing.T) {
for _, tc := range []testCase{
{
s: schema{},
want: `{}`,
},
{
s: schema{
ForceSendFields: []string{"B", "F", "I", "Istr", "Str", "PB", "PF", "PI", "PIStr", "PStr"},
},
want: `{"b":false,"f":0.0,"i":0,"istr":"0","str":""}`,
},
{
s: schema{
B: true,
F: 1.2,
I: 1,
Istr: 2,
Str: "a",
PB: googleapi.Bool(true),
PF: googleapi.Float64(1.2),
PI: googleapi.Int64(int64(1)),
PIStr: googleapi.Int64(int64(2)),
PStr: googleapi.String("a"),
},
want: `{"b":true,"f":1.2,"i":1,"istr":"2","str":"a","pb":true,"pf":1.2,"pi":1,"pistr":"2","pstr":"a"}`,
},
{
s: schema{
B: false,
F: 0.0,
I: 0,
Istr: 0,
Str: "",
PB: googleapi.Bool(false),
PF: googleapi.Float64(0.0),
PI: googleapi.Int64(int64(0)),
PIStr: googleapi.Int64(int64(0)),
PStr: googleapi.String(""),
},
want: `{"pb":false,"pf":0.0,"pi":0,"pistr":"0","pstr":""}`,
},
{
s: schema{
B: false,
F: 0.0,
I: 0,
Istr: 0,
Str: "",
PB: googleapi.Bool(false),
PF: googleapi.Float64(0.0),
PI: googleapi.Int64(int64(0)),
PIStr: googleapi.Int64(int64(0)),
PStr: googleapi.String(""),
ForceSendFields: []string{"B", "F", "I", "Istr", "Str", "PB", "PF", "PI", "PIStr", "PStr"},
},
want: `{"b":false,"f":0.0,"i":0,"istr":"0","str":"","pb":false,"pf":0.0,"pi":0,"pistr":"0","pstr":""}`,
},
} {
checkMarshalJSON(t, tc)
}
}
func TestSliceFields(t *testing.T) {
for _, tc := range []testCase{
{
s: schema{},
want: `{}`,
},
{
s: schema{S: []int{}, Int64s: googleapi.Int64s{}},
want: `{}`,
},
{
s: schema{S: []int{1}, Int64s: googleapi.Int64s{1}},
want: `{"s":[1],"i64s":["1"]}`,
},
{
s: schema{
ForceSendFields: []string{"S", "Int64s"},
},
want: `{"s":[],"i64s":[]}`,
},
{
s: schema{
S: []int{},
Int64s: googleapi.Int64s{},
ForceSendFields: []string{"S", "Int64s"},
},
want: `{"s":[],"i64s":[]}`,
},
{
s: schema{
S: []int{1},
Int64s: googleapi.Int64s{1},
ForceSendFields: []string{"S", "Int64s"},
},
want: `{"s":[1],"i64s":["1"]}`,
},
} {
checkMarshalJSON(t, tc)
}
}
func TestMapField(t *testing.T) {
for _, tc := range []testCase{
{
s: schema{},
want: `{}`,
},
{
s: schema{M: make(map[string]string)},
want: `{}`,
},
{
s: schema{M: map[string]string{"a": "b"}},
want: `{"m":{"a":"b"}}`,
},
{
s: schema{
ForceSendFields: []string{"M"},
},
want: `{"m":{}}`,
},
{
s: schema{
M: make(map[string]string),
ForceSendFields: []string{"M"},
},
want: `{"m":{}}`,
},
{
s: schema{
M: map[string]string{"a": "b"},
ForceSendFields: []string{"M"},
},
want: `{"m":{"a":"b"}}`,
},
} {
checkMarshalJSON(t, tc)
}
}
type anyType struct {
Field int
}
func (a anyType) MarshalJSON() ([]byte, error) {
return []byte(`"anyType value"`), nil
}
func TestAnyField(t *testing.T) {
// ForceSendFields has no effect on nil interfaces and interfaces that contain nil pointers.
var nilAny *anyType
for _, tc := range []testCase{
{
s: schema{},
want: `{}`,
},
{
s: schema{Any: nilAny},
want: `{"any": null}`,
},
{
s: schema{Any: &anyType{}},
want: `{"any":"anyType value"}`,
},
{
s: schema{Any: anyType{}},
want: `{"any":"anyType value"}`,
},
{
s: schema{
ForceSendFields: []string{"Any"},
},
want: `{}`,
},
{
s: schema{
Any: nilAny,
ForceSendFields: []string{"Any"},
},
want: `{"any": null}`,
},
{
s: schema{
Any: &anyType{},
ForceSendFields: []string{"Any"},
},
want: `{"any":"anyType value"}`,
},
{
s: schema{
Any: anyType{},
ForceSendFields: []string{"Any"},
},
want: `{"any":"anyType value"}`,
},
} {
checkMarshalJSON(t, tc)
}
}
func TestSubschema(t *testing.T) {
// Subschemas are always stored as pointers, so ForceSendFields has no effect on them.
for _, tc := range []testCase{
{
s: schema{},
want: `{}`,
},
{
s: schema{
ForceSendFields: []string{"Child"},
},
want: `{}`,
},
{
s: schema{Child: &child{}},
want: `{"child":{}}`,
},
{
s: schema{
Child: &child{},
ForceSendFields: []string{"Child"},
},
want: `{"child":{}}`,
},
{
s: schema{Child: &child{B: true}},
want: `{"child":{"childbool":true}}`,
},
{
s: schema{
Child: &child{B: true},
ForceSendFields: []string{"Child"},
},
want: `{"child":{"childbool":true}}`,
},
} {
checkMarshalJSON(t, tc)
}
}
// checkMarshalJSON verifies that calling schemaToMap on tc.s yields a result which is equivalent to tc.want.
func checkMarshalJSON(t *testing.T, tc testCase) {
doCheckMarshalJSON(t, tc.s, tc.s.ForceSendFields, tc.want)
if len(tc.s.ForceSendFields) == 0 {
// verify that the code path used when ForceSendFields
// is non-empty produces the same output as the fast
// path that is used when it is empty.
doCheckMarshalJSON(t, tc.s, []string{"dummy"}, tc.want)
}
}
func doCheckMarshalJSON(t *testing.T, s schema, forceSendFields []string, wantJSON string) {
encoded, err := MarshalJSON(s, forceSendFields)
if err != nil {
t.Fatalf("encoding json:\n got err: %v", err)
}
// The expected and obtained JSON can differ in field ordering, so unmarshal before comparing.
var got interface{}
var want interface{}
err = json.Unmarshal(encoded, &got)
if err != nil {
t.Fatalf("decoding json:\n got err: %v", err)
}
err = json.Unmarshal([]byte(wantJSON), &want)
if err != nil {
t.Fatalf("decoding json:\n got err: %v", err)
}
if !reflect.DeepEqual(got, want) {
t.Errorf("schemaToMap:\ngot :%s\nwant:%s", got, want)
}
}
func TestParseJSONTag(t *testing.T) {
for _, tc := range []struct {
tag string
want jsonTag
}{
{
tag: "-",
want: jsonTag{ignore: true},
}, {
tag: "name,omitempty",
want: jsonTag{apiName: "name"},
}, {
tag: "name,omitempty,string",
want: jsonTag{apiName: "name", stringFormat: true},
},
} {
got, err := parseJSONTag(tc.tag)
if err != nil {
t.Fatalf("parsing json:\n got err: %v\ntag: %q", err, tc.tag)
}
if !reflect.DeepEqual(got, tc.want) {
t.Errorf("parseJSONTage:\ngot :%s\nwant:%s", got, tc.want)
}
}
}
func TestParseMalformedJSONTag(t *testing.T) {
for _, tag := range []string{
"",
"name",
"name,",
"name,blah",
"name,blah,string",
",omitempty",
",omitempty,string",
"name,omitempty,string,blah",
} {
_, err := parseJSONTag(tag)
if err == nil {
t.Fatalf("parsing json: expected err, got nil for tag: %v", tag)
}
}
}

View file

@ -1,113 +0,0 @@
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gensupport
import (
"bytes"
"errors"
"io"
"io/ioutil"
"reflect"
"testing"
)
// errReader reads out of a buffer until it is empty, then returns the specified error.
type errReader struct {
buf []byte
err error
}
var errBang error = errors.New("bang")
func (er *errReader) Read(p []byte) (int, error) {
if len(er.buf) == 0 {
if er.err == nil {
return 0, io.EOF
}
return 0, er.err
}
n := copy(p, er.buf)
er.buf = er.buf[n:]
return n, nil
}
func TestAll(t *testing.T) {
type testCase struct {
data []byte // the data to read from the Reader
finalErr error // error to return after data has been read
wantContentType string
wantContentTypeResult bool
}
for _, tc := range []testCase{
{
data: []byte{0, 0, 0, 0},
finalErr: nil,
wantContentType: "application/octet-stream",
wantContentTypeResult: true,
},
{
data: []byte(""),
finalErr: nil,
wantContentType: "text/plain; charset=utf-8",
wantContentTypeResult: true,
},
{
data: []byte(""),
finalErr: errBang,
wantContentType: "text/plain; charset=utf-8",
wantContentTypeResult: false,
},
{
data: []byte("abc"),
finalErr: nil,
wantContentType: "text/plain; charset=utf-8",
wantContentTypeResult: true,
},
{
data: []byte("abc"),
finalErr: errBang,
wantContentType: "text/plain; charset=utf-8",
wantContentTypeResult: false,
},
// The following examples contain more bytes than are buffered for sniffing.
{
data: bytes.Repeat([]byte("a"), 513),
finalErr: nil,
wantContentType: "text/plain; charset=utf-8",
wantContentTypeResult: true,
},
{
data: bytes.Repeat([]byte("a"), 513),
finalErr: errBang,
wantContentType: "text/plain; charset=utf-8",
wantContentTypeResult: true, // true because error is after first 512 bytes.
},
} {
er := &errReader{buf: tc.data, err: tc.finalErr}
sct := NewContentSniffer(er)
// Even if was an error during the first 512 bytes, we should still be able to read those bytes.
buf, err := ioutil.ReadAll(sct)
if !reflect.DeepEqual(buf, tc.data) {
t.Fatalf("Failed reading buffer: got: %q; want:%q", buf, tc.data)
}
if err != tc.finalErr {
t.Fatalf("Reading buffer error: got: %v; want: %v", err, tc.finalErr)
}
ct, ok := sct.ContentType()
if ok != tc.wantContentTypeResult {
t.Fatalf("Content type result got: %v; want: %v", ok, tc.wantContentTypeResult)
}
if ok && ct != tc.wantContentType {
t.Fatalf("Content type got: %q; want: %q", ct, tc.wantContentType)
}
}
}

View file

@ -1,599 +0,0 @@
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package googleapi
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"reflect"
"regexp"
"strconv"
"strings"
"testing"
"time"
"golang.org/x/net/context"
)
type SetOpaqueTest struct {
in *url.URL
wantRequestURI string
}
var setOpaqueTests = []SetOpaqueTest{
// no path
{
&url.URL{
Scheme: "http",
Host: "www.golang.org",
},
"http://www.golang.org",
},
// path
{
&url.URL{
Scheme: "http",
Host: "www.golang.org",
Path: "/",
},
"http://www.golang.org/",
},
// file with hex escaping
{
&url.URL{
Scheme: "https",
Host: "www.golang.org",
Path: "/file%20one&two",
},
"https://www.golang.org/file%20one&two",
},
// query
{
&url.URL{
Scheme: "http",
Host: "www.golang.org",
Path: "/",
RawQuery: "q=go+language",
},
"http://www.golang.org/?q=go+language",
},
// file with hex escaping in path plus query
{
&url.URL{
Scheme: "https",
Host: "www.golang.org",
Path: "/file%20one&two",
RawQuery: "q=go+language",
},
"https://www.golang.org/file%20one&two?q=go+language",
},
// query with hex escaping
{
&url.URL{
Scheme: "http",
Host: "www.golang.org",
Path: "/",
RawQuery: "q=go%20language",
},
"http://www.golang.org/?q=go%20language",
},
}
// prefixTmpl is a template for the expected prefix of the output of writing
// an HTTP request.
const prefixTmpl = "GET %v HTTP/1.1\r\nHost: %v\r\n"
func TestSetOpaque(t *testing.T) {
for _, test := range setOpaqueTests {
u := *test.in
SetOpaque(&u)
w := &bytes.Buffer{}
r := &http.Request{URL: &u}
if err := r.Write(w); err != nil {
t.Errorf("write request: %v", err)
continue
}
prefix := fmt.Sprintf(prefixTmpl, test.wantRequestURI, test.in.Host)
if got := string(w.Bytes()); !strings.HasPrefix(got, prefix) {
t.Errorf("got %q expected prefix %q", got, prefix)
}
}
}
type ExpandTest struct {
in string
expansions map[string]string
want string
}
var expandTests = []ExpandTest{
// no expansions
{
"http://www.golang.org/",
map[string]string{},
"http://www.golang.org/",
},
// one expansion, no escaping
{
"http://www.golang.org/{bucket}/delete",
map[string]string{
"bucket": "red",
},
"http://www.golang.org/red/delete",
},
// one expansion, with hex escapes
{
"http://www.golang.org/{bucket}/delete",
map[string]string{
"bucket": "red/blue",
},
"http://www.golang.org/red%2Fblue/delete",
},
// one expansion, with space
{
"http://www.golang.org/{bucket}/delete",
map[string]string{
"bucket": "red or blue",
},
"http://www.golang.org/red%20or%20blue/delete",
},
// expansion not found
{
"http://www.golang.org/{object}/delete",
map[string]string{
"bucket": "red or blue",
},
"http://www.golang.org//delete",
},
// multiple expansions
{
"http://www.golang.org/{one}/{two}/{three}/get",
map[string]string{
"one": "ONE",
"two": "TWO",
"three": "THREE",
},
"http://www.golang.org/ONE/TWO/THREE/get",
},
// utf-8 characters
{
"http://www.golang.org/{bucket}/get",
map[string]string{
"bucket": "£100",
},
"http://www.golang.org/%C2%A3100/get",
},
// punctuations
{
"http://www.golang.org/{bucket}/get",
map[string]string{
"bucket": `/\@:,.`,
},
"http://www.golang.org/%2F%5C%40%3A%2C./get",
},
// mis-matched brackets
{
"http://www.golang.org/{bucket/get",
map[string]string{
"bucket": "red",
},
"http://www.golang.org/{bucket/get",
},
// "+" prefix for suppressing escape
// See also: http://tools.ietf.org/html/rfc6570#section-3.2.3
{
"http://www.golang.org/{+topic}",
map[string]string{
"topic": "/topics/myproject/mytopic",
},
// The double slashes here look weird, but it's intentional
"http://www.golang.org//topics/myproject/mytopic",
},
}
func TestExpand(t *testing.T) {
for i, test := range expandTests {
u := url.URL{
Path: test.in,
}
Expand(&u, test.expansions)
got := u.Path
if got != test.want {
t.Errorf("got %q expected %q in test %d", got, test.want, i+1)
}
}
}
type CheckResponseTest struct {
in *http.Response
bodyText string
want error
errText string
}
var checkResponseTests = []CheckResponseTest{
{
&http.Response{
StatusCode: http.StatusOK,
},
"",
nil,
"",
},
{
&http.Response{
StatusCode: http.StatusInternalServerError,
},
`{"error":{}}`,
&Error{
Code: http.StatusInternalServerError,
Body: `{"error":{}}`,
},
`googleapi: got HTTP response code 500 with body: {"error":{}}`,
},
{
&http.Response{
StatusCode: http.StatusNotFound,
},
`{"error":{"message":"Error message for StatusNotFound."}}`,
&Error{
Code: http.StatusNotFound,
Message: "Error message for StatusNotFound.",
Body: `{"error":{"message":"Error message for StatusNotFound."}}`,
},
"googleapi: Error 404: Error message for StatusNotFound.",
},
{
&http.Response{
StatusCode: http.StatusBadRequest,
},
`{"error":"invalid_token","error_description":"Invalid Value"}`,
&Error{
Code: http.StatusBadRequest,
Body: `{"error":"invalid_token","error_description":"Invalid Value"}`,
},
`googleapi: got HTTP response code 400 with body: {"error":"invalid_token","error_description":"Invalid Value"}`,
},
{
&http.Response{
StatusCode: http.StatusBadRequest,
},
`{"error":{"errors":[{"domain":"usageLimits","reason":"keyInvalid","message":"Bad Request"}],"code":400,"message":"Bad Request"}}`,
&Error{
Code: http.StatusBadRequest,
Errors: []ErrorItem{
{
Reason: "keyInvalid",
Message: "Bad Request",
},
},
Body: `{"error":{"errors":[{"domain":"usageLimits","reason":"keyInvalid","message":"Bad Request"}],"code":400,"message":"Bad Request"}}`,
Message: "Bad Request",
},
"googleapi: Error 400: Bad Request, keyInvalid",
},
}
func TestCheckResponse(t *testing.T) {
for _, test := range checkResponseTests {
res := test.in
if test.bodyText != "" {
res.Body = ioutil.NopCloser(strings.NewReader(test.bodyText))
}
g := CheckResponse(res)
if !reflect.DeepEqual(g, test.want) {
t.Errorf("CheckResponse: got %v, want %v", g, test.want)
gotJson, err := json.Marshal(g)
if err != nil {
t.Error(err)
}
wantJson, err := json.Marshal(test.want)
if err != nil {
t.Error(err)
}
t.Errorf("json(got): %q\njson(want): %q", string(gotJson), string(wantJson))
}
if g != nil && g.Error() != test.errText {
t.Errorf("CheckResponse: unexpected error message.\nGot: %q\nwant: %q", g, test.errText)
}
}
}
type VariantPoint struct {
Type string
Coordinates []float64
}
type VariantTest struct {
in map[string]interface{}
result bool
want VariantPoint
}
var coords = []interface{}{1.0, 2.0}
var variantTests = []VariantTest{
{
in: map[string]interface{}{
"type": "Point",
"coordinates": coords,
},
result: true,
want: VariantPoint{
Type: "Point",
Coordinates: []float64{1.0, 2.0},
},
},
{
in: map[string]interface{}{
"type": "Point",
"bogus": coords,
},
result: true,
want: VariantPoint{
Type: "Point",
},
},
}
func TestVariantType(t *testing.T) {
for _, test := range variantTests {
if g := VariantType(test.in); g != test.want.Type {
t.Errorf("VariantType(%v): got %v, want %v", test.in, g, test.want.Type)
}
}
}
func TestConvertVariant(t *testing.T) {
for _, test := range variantTests {
g := VariantPoint{}
r := ConvertVariant(test.in, &g)
if r != test.result {
t.Errorf("ConvertVariant(%v): got %v, want %v", test.in, r, test.result)
}
if !reflect.DeepEqual(g, test.want) {
t.Errorf("ConvertVariant(%v): got %v, want %v", test.in, g, test.want)
}
}
}
type unexpectedReader struct{}
func (unexpectedReader) Read([]byte) (int, error) {
return 0, fmt.Errorf("unexpected read in test.")
}
var contentRangeRE = regexp.MustCompile(`^bytes (\d+)\-(\d+)/(\d+)$`)
func (t *testTransport) RoundTrip(req *http.Request) (*http.Response, error) {
t.req = req
if rng := req.Header.Get("Content-Range"); rng != "" && !strings.HasPrefix(rng, "bytes */") { // Read the data
m := contentRangeRE.FindStringSubmatch(rng)
if len(m) != 4 {
return nil, fmt.Errorf("unable to parse content range: %v", rng)
}
start, err := strconv.ParseInt(m[1], 10, 64)
if err != nil {
return nil, fmt.Errorf("unable to parse content range: %v", rng)
}
end, err := strconv.ParseInt(m[2], 10, 64)
if err != nil {
return nil, fmt.Errorf("unable to parse content range: %v", rng)
}
totalSize, err := strconv.ParseInt(m[3], 10, 64)
if err != nil {
return nil, fmt.Errorf("unable to parse content range: %v", rng)
}
partialSize := end - start + 1
t.buf, err = ioutil.ReadAll(req.Body)
if err != nil || int64(len(t.buf)) != partialSize {
return nil, fmt.Errorf("unable to read %v bytes from request data, n=%v: %v", partialSize, len(t.buf), err)
}
if totalSize == end+1 {
t.statusCode = 200 // signify completion of transfer
}
}
f := ioutil.NopCloser(unexpectedReader{})
res := &http.Response{
Body: f,
StatusCode: t.statusCode,
Header: http.Header{},
}
if t.rangeVal != "" {
res.Header.Set("Range", t.rangeVal)
}
return res, nil
}
type testTransport struct {
req *http.Request
statusCode int
rangeVal string
want int64
buf []byte
}
var statusTests = []*testTransport{
&testTransport{statusCode: 308, want: 0},
&testTransport{statusCode: 308, rangeVal: "bytes=0-0", want: 1},
&testTransport{statusCode: 308, rangeVal: "bytes=0-42", want: 43},
}
func TestTransferStatus(t *testing.T) {
ctx := context.Background()
for _, tr := range statusTests {
rx := &ResumableUpload{
Client: &http.Client{Transport: tr},
}
g, _, err := rx.transferStatus(ctx)
if err != nil {
t.Error(err)
}
if g != tr.want {
t.Errorf("transferStatus got %v, want %v", g, tr.want)
}
}
}
func (t *interruptedTransport) RoundTrip(req *http.Request) (*http.Response, error) {
t.req = req
if rng := req.Header.Get("Content-Range"); rng != "" && !strings.HasPrefix(rng, "bytes */") {
t.interruptCount += 1
if t.interruptCount%7 == 0 { // Respond with a "service unavailable" error
res := &http.Response{
StatusCode: http.StatusServiceUnavailable,
Header: http.Header{},
}
t.rangeVal = fmt.Sprintf("bytes=0-%v", len(t.buf)-1) // Set the response for next time
return res, nil
}
m := contentRangeRE.FindStringSubmatch(rng)
if len(m) != 4 {
return nil, fmt.Errorf("unable to parse content range: %v", rng)
}
start, err := strconv.ParseInt(m[1], 10, 64)
if err != nil {
return nil, fmt.Errorf("unable to parse content range: %v", rng)
}
end, err := strconv.ParseInt(m[2], 10, 64)
if err != nil {
return nil, fmt.Errorf("unable to parse content range: %v", rng)
}
totalSize, err := strconv.ParseInt(m[3], 10, 64)
if err != nil {
return nil, fmt.Errorf("unable to parse content range: %v", rng)
}
partialSize := end - start + 1
buf, err := ioutil.ReadAll(req.Body)
if err != nil || int64(len(buf)) != partialSize {
return nil, fmt.Errorf("unable to read %v bytes from request data, n=%v: %v", partialSize, len(buf), err)
}
t.buf = append(t.buf, buf...)
if totalSize == end+1 {
t.statusCode = 200 // signify completion of transfer
}
}
f := ioutil.NopCloser(unexpectedReader{})
res := &http.Response{
Body: f,
StatusCode: t.statusCode,
Header: http.Header{},
}
if t.rangeVal != "" {
res.Header.Set("Range", t.rangeVal)
}
return res, nil
}
type interruptedTransport struct {
req *http.Request
statusCode int
rangeVal string
interruptCount int
buf []byte
progressUpdates []int64
}
func (tr *interruptedTransport) ProgressUpdate(current int64) {
tr.progressUpdates = append(tr.progressUpdates, current)
}
func TestInterruptedTransferChunks(t *testing.T) {
f, err := os.Open("googleapi.go")
if err != nil {
t.Fatalf("unable to open googleapi.go: %v", err)
}
defer f.Close()
slurp, err := ioutil.ReadAll(f)
if err != nil {
t.Fatalf("unable to slurp file: %v", err)
}
st, err := f.Stat()
if err != nil {
t.Fatalf("unable to stat googleapi.go: %v", err)
}
tr := &interruptedTransport{
statusCode: 308,
buf: make([]byte, 0, st.Size()),
}
oldChunkSize := chunkSize
defer func() { chunkSize = oldChunkSize }()
chunkSize = 100 // override to process small chunks for test.
sleep = func(time.Duration) {} // override time.Sleep
rx := &ResumableUpload{
Client: &http.Client{Transport: tr},
Media: f,
MediaType: "text/plain",
ContentLength: st.Size(),
Callback: tr.ProgressUpdate,
}
res, err := rx.Upload(context.Background())
if err != nil || res == nil || res.StatusCode != http.StatusOK {
if res == nil {
t.Errorf("transferChunks not successful, res=nil: %v", err)
} else {
t.Errorf("transferChunks not successful, statusCode=%v: %v", res.StatusCode, err)
}
}
if len(tr.buf) != len(slurp) || bytes.Compare(tr.buf, slurp) != 0 {
t.Errorf("transferred file corrupted:\ngot %s\nwant %s", tr.buf, slurp)
}
want := []int64{}
for i := chunkSize; i <= st.Size(); i += chunkSize {
want = append(want, i)
}
if st.Size()%chunkSize != 0 {
want = append(want, st.Size())
}
if !reflect.DeepEqual(tr.progressUpdates, want) {
t.Errorf("progress update error, got %v, want %v", tr.progressUpdates, want)
}
}
func TestCancelUpload(t *testing.T) {
f, err := os.Open("googleapi.go")
if err != nil {
t.Fatalf("unable to open googleapi.go: %v", err)
}
defer f.Close()
st, err := f.Stat()
if err != nil {
t.Fatalf("unable to stat googleapi.go: %v", err)
}
tr := &interruptedTransport{
statusCode: 308,
buf: make([]byte, 0, st.Size()),
}
oldChunkSize := chunkSize
defer func() { chunkSize = oldChunkSize }()
chunkSize = 100 // override to process small chunks for test.
sleep = func(time.Duration) {} // override time.Sleep
rx := &ResumableUpload{
Client: &http.Client{Transport: tr},
Media: f,
MediaType: "text/plain",
ContentLength: st.Size(),
Callback: tr.ProgressUpdate,
}
ctx, cancelFunc := context.WithCancel(context.Background())
cancelFunc() // stop the upload that hasn't started yet
res, err := rx.Upload(ctx)
if err == nil || res == nil || res.StatusCode != http.StatusRequestTimeout {
if res == nil {
t.Errorf("transferChunks not successful, got res=nil, err=%v, want StatusRequestTimeout", err)
} else {
t.Errorf("transferChunks not successful, got statusCode=%v, err=%v, want StatusRequestTimeout", res.StatusCode, err)
}
}
}

View file

@ -1,38 +0,0 @@
// Copyright 2012 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package transport contains HTTP transports used to make
// authenticated API requests.
package transport
import (
"errors"
"net/http"
)
// APIKey is an HTTP Transport which wraps an underlying transport and
// appends an API Key "key" parameter to the URL of outgoing requests.
type APIKey struct {
// Key is the API Key to set on requests.
Key string
// Transport is the underlying HTTP transport.
// If nil, http.DefaultTransport is used.
Transport http.RoundTripper
}
func (t *APIKey) RoundTrip(req *http.Request) (*http.Response, error) {
rt := t.Transport
if rt == nil {
rt = http.DefaultTransport
if rt == nil {
return nil, errors.New("googleapi/transport: no Transport specified or available")
}
}
newReq := *req
args := newReq.URL.Query()
args.Set("key", t.Key)
newReq.URL.RawQuery = args.Encode()
return rt.RoundTrip(&newReq)
}

View file

@ -1,44 +0,0 @@
// Copyright 2013 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package googleapi
import (
"encoding/json"
"reflect"
"testing"
)
func TestTypes(t *testing.T) {
type T struct {
I32 Int32s
I64 Int64s
U32 Uint32s
U64 Uint64s
F64 Float64s
}
v := &T{
I32: Int32s{-1, 2, 3},
I64: Int64s{-1, 2, 1 << 33},
U32: Uint32s{1, 2},
U64: Uint64s{1, 2, 1 << 33},
F64: Float64s{1.5, 3.33},
}
got, err := json.Marshal(v)
if err != nil {
t.Fatal(err)
}
want := `{"I32":["-1","2","3"],"I64":["-1","2","8589934592"],"U32":["1","2"],"U64":["1","2","8589934592"],"F64":["1.5","3.33"]}`
if string(got) != want {
t.Fatalf("Marshal mismatch.\n got: %s\nwant: %s\n", got, want)
}
v2 := new(T)
if err := json.Unmarshal(got, v2); err != nil {
t.Fatalf("Unmarshal: %v", err)
}
if !reflect.DeepEqual(v, v2) {
t.Fatalf("Unmarshal didn't produce same results.\n got: %#v\nwant: %#v\n", v, v2)
}
}