mirror of https://github.com/kubernetes/kops.git
				
				
				
			
		
			
				
	
	
		
			292 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			292 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Go
		
	
	
	
| // 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 (
 | |
| 	"encoding/json"
 | |
| 	"io/ioutil"
 | |
| 	"net/http"
 | |
| 	"net/url"
 | |
| 	"reflect"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| )
 | |
| 
 | |
| 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/%7Bbucket/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.EscapedPath()
 | |
| 		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)
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestRoundChunkSize(t *testing.T) {
 | |
| 	type testCase struct {
 | |
| 		in   int
 | |
| 		want int
 | |
| 	}
 | |
| 	for _, tc := range []testCase{
 | |
| 		{0, 0},
 | |
| 		{256*1024 - 1, 256 * 1024},
 | |
| 		{256 * 1024, 256 * 1024},
 | |
| 		{256*1024 + 1, 2 * 256 * 1024},
 | |
| 	} {
 | |
| 		mo := &MediaOptions{}
 | |
| 		ChunkSize(tc.in).setOptions(mo)
 | |
| 		if got := mo.ChunkSize; got != tc.want {
 | |
| 			t.Errorf("rounding chunk size: got: %v; want %v", got, tc.want)
 | |
| 		}
 | |
| 	}
 | |
| }
 |