Update dependencies, enable pruning for vendor/

So, `dep` got an nice new feature to remove tests and non-go files from
`vendor/`, and this brings the size of the vendor directory from ~300MiB
down to ~20MiB. We don that now.
This commit is contained in:
Alexander Neumann 2018-08-01 19:43:44 +02:00
parent 3422c1ca83
commit bff635bc5f
6741 changed files with 26942 additions and 4902033 deletions

View file

@ -1,109 +0,0 @@
// Copyright...
// This example demonstrates opening a Connection and doing some basic operations.
package swift_test
import (
"fmt"
"github.com/ncw/swift"
)
func ExampleConnection() {
// Create a v1 auth connection
c := &swift.Connection{
// This should be your username
UserName: "user",
// This should be your api key
ApiKey: "key",
// This should be a v1 auth url, eg
// Rackspace US https://auth.api.rackspacecloud.com/v1.0
// Rackspace UK https://lon.auth.api.rackspacecloud.com/v1.0
// Memset Memstore UK https://auth.storage.memset.com/v1.0
AuthUrl: "auth_url",
}
// Authenticate
err := c.Authenticate()
if err != nil {
panic(err)
}
// List all the containers
containers, err := c.ContainerNames(nil)
fmt.Println(containers)
// etc...
// ------ or alternatively create a v2 connection ------
// Create a v2 auth connection
c = &swift.Connection{
// This is the sub user for the storage - eg "admin"
UserName: "user",
// This should be your api key
ApiKey: "key",
// This should be a version2 auth url, eg
// Rackspace v2 https://identity.api.rackspacecloud.com/v2.0
// Memset Memstore v2 https://auth.storage.memset.com/v2.0
AuthUrl: "v2_auth_url",
// Region to use - default is use first region if unset
Region: "LON",
// Name of the tenant - this is likely your username
Tenant: "jim",
}
// as above...
}
var container string
func ExampleConnection_ObjectsWalk() {
c, rollback := makeConnection(nil)
defer rollback()
objects := make([]string, 0)
err := c.ObjectsWalk(container, nil, func(opts *swift.ObjectsOpts) (interface{}, error) {
newObjects, err := c.ObjectNames(container, opts)
if err == nil {
objects = append(objects, newObjects...)
}
return newObjects, err
})
fmt.Println("Found all the objects", objects, err)
}
func ExampleConnection_VersionContainerCreate() {
c, rollback := makeConnection(nil)
defer rollback()
// Use the helper method to create the current and versions container.
if err := c.VersionContainerCreate("cds", "cd-versions"); err != nil {
fmt.Print(err.Error())
}
}
func ExampleConnection_VersionEnable() {
c, rollback := makeConnection(nil)
defer rollback()
// Build the containers manually and enable them.
if err := c.ContainerCreate("movie-versions", nil); err != nil {
fmt.Print(err.Error())
}
if err := c.ContainerCreate("movies", nil); err != nil {
fmt.Print(err.Error())
}
if err := c.VersionEnable("movies", "movie-versions"); err != nil {
fmt.Print(err.Error())
}
// Access the primary container as usual with ObjectCreate(), ObjectPut(), etc.
// etc...
}
func ExampleConnection_VersionDisable() {
c, rollback := makeConnection(nil)
defer rollback()
// Disable versioning on a container. Note that this does not delete the versioning container.
c.VersionDisable("movies")
}

View file

@ -1,213 +0,0 @@
// Tests for swift metadata
package swift
import (
"testing"
"time"
)
func TestHeadersToMetadata(t *testing.T) {
}
func TestHeadersToAccountMetadata(t *testing.T) {
}
func TestHeadersToContainerMetadata(t *testing.T) {
}
func TestHeadersToObjectMetadata(t *testing.T) {
}
func TestMetadataToHeaders(t *testing.T) {
}
func TestMetadataToAccountHeaders(t *testing.T) {
}
func TestMetadataToContainerHeaders(t *testing.T) {
}
func TestMetadataToObjectHeaders(t *testing.T) {
}
func TestNsToFloatString(t *testing.T) {
for _, d := range []struct {
ns int64
fs string
}{
{0, "0"},
{1, "0.000000001"},
{1000, "0.000001"},
{1000000, "0.001"},
{100000000, "0.1"},
{1000000000, "1"},
{10000000000, "10"},
{12345678912, "12.345678912"},
{12345678910, "12.34567891"},
{12345678900, "12.3456789"},
{12345678000, "12.345678"},
{12345670000, "12.34567"},
{12345600000, "12.3456"},
{12345000000, "12.345"},
{12340000000, "12.34"},
{12300000000, "12.3"},
{12000000000, "12"},
{10000000000, "10"},
{1347717491123123123, "1347717491.123123123"},
} {
if nsToFloatString(d.ns) != d.fs {
t.Error("Failed", d.ns, "!=", d.fs)
}
if d.ns > 0 && nsToFloatString(-d.ns) != "-"+d.fs {
t.Error("Failed on negative", d.ns, "!=", d.fs)
}
}
}
func TestFloatStringToNs(t *testing.T) {
for _, d := range []struct {
ns int64
fs string
}{
{0, "0"},
{0, "0."},
{0, ".0"},
{0, "0.0"},
{0, "0.0000000001"},
{1, "0.000000001"},
{1000, "0.000001"},
{1000000, "0.001"},
{100000000, "0.1"},
{100000000, "0.10"},
{100000000, "0.1000000001"},
{1000000000, "1"},
{1000000000, "1."},
{1000000000, "1.0"},
{10000000000, "10"},
{12345678912, "12.345678912"},
{12345678912, "12.3456789129"},
{12345678912, "12.34567891299"},
{12345678910, "12.34567891"},
{12345678900, "12.3456789"},
{12345678000, "12.345678"},
{12345670000, "12.34567"},
{12345600000, "12.3456"},
{12345000000, "12.345"},
{12340000000, "12.34"},
{12300000000, "12.3"},
{12000000000, "12"},
{10000000000, "10"},
// This is a typical value which has more bits in than a float64
{1347717491123123123, "1347717491.123123123"},
} {
ns, err := floatStringToNs(d.fs)
if err != nil {
t.Error("Failed conversion", err)
}
if ns != d.ns {
t.Error("Failed", d.fs, "!=", d.ns, "was", ns)
}
if d.ns > 0 {
ns, err := floatStringToNs("-" + d.fs)
if err != nil {
t.Error("Failed conversion", err)
}
if ns != -d.ns {
t.Error("Failed on negative", -d.ns, "!=", "-"+d.fs)
}
}
}
// These are expected to produce errors
for _, fs := range []string{
"",
" 1",
"- 1",
"- 1",
"1.-1",
"1.0.0",
"1x0",
} {
ns, err := floatStringToNs(fs)
if err == nil {
t.Error("Didn't produce expected error", fs, ns)
}
}
}
func TestGetModTime(t *testing.T) {
for _, d := range []struct {
ns string
t string
}{
{"1354040105", "2012-11-27T18:15:05Z"},
{"1354040105.", "2012-11-27T18:15:05Z"},
{"1354040105.0", "2012-11-27T18:15:05Z"},
{"1354040105.000000000000", "2012-11-27T18:15:05Z"},
{"1354040105.123", "2012-11-27T18:15:05.123Z"},
{"1354040105.123456", "2012-11-27T18:15:05.123456Z"},
{"1354040105.123456789", "2012-11-27T18:15:05.123456789Z"},
{"1354040105.123456789123", "2012-11-27T18:15:05.123456789Z"},
{"0", "1970-01-01T00:00:00.000000000Z"},
} {
expected, err := time.Parse(time.RFC3339, d.t)
if err != nil {
t.Error("Bad test", err)
}
m := Metadata{"mtime": d.ns}
actual, err := m.GetModTime()
if err != nil {
t.Error("Parse error", err)
}
if !actual.Equal(expected) {
t.Error("Expecting", expected, expected.UnixNano(), "got", actual, actual.UnixNano())
}
}
for _, ns := range []string{
"EMPTY",
"",
" 1",
"- 1",
"- 1",
"1.-1",
"1.0.0",
"1x0",
} {
m := Metadata{}
if ns != "EMPTY" {
m["mtime"] = ns
}
actual, err := m.GetModTime()
if err == nil {
t.Error("Expected error not produced")
}
if !actual.IsZero() {
t.Error("Expected output to be zero")
}
}
}
func TestSetModTime(t *testing.T) {
for _, d := range []struct {
ns string
t string
}{
{"1354040105", "2012-11-27T18:15:05Z"},
{"1354040105", "2012-11-27T18:15:05.000000Z"},
{"1354040105.123", "2012-11-27T18:15:05.123Z"},
{"1354040105.123456", "2012-11-27T18:15:05.123456Z"},
{"1354040105.123456789", "2012-11-27T18:15:05.123456789Z"},
{"0", "1970-01-01T00:00:00.000000000Z"},
} {
time, err := time.Parse(time.RFC3339, d.t)
if err != nil {
t.Error("Bad test", err)
}
m := Metadata{}
m.SetModTime(time)
if m["mtime"] != d.ns {
t.Error("mtime wrong", m, "should be", d.ns)
}
}
}

83
vendor/github.com/ncw/swift/rs/rs.go generated vendored
View file

@ -1,83 +0,0 @@
package rs
import (
"errors"
"net/http"
"strconv"
"github.com/ncw/swift"
)
// RsConnection is a RackSpace specific wrapper to the core swift library which
// exposes the RackSpace CDN commands via the CDN Management URL interface.
type RsConnection struct {
swift.Connection
cdnUrl string
}
// manage is similar to the swift storage method, but uses the CDN Management URL for CDN specific calls.
func (c *RsConnection) manage(p swift.RequestOpts) (resp *http.Response, headers swift.Headers, err error) {
p.OnReAuth = func() (string, error) {
if c.cdnUrl == "" {
c.cdnUrl = c.Auth.CdnUrl()
}
if c.cdnUrl == "" {
return "", errors.New("The X-CDN-Management-Url does not exist on the authenticated platform")
}
return c.cdnUrl, nil
}
if c.Authenticated() {
_, err = p.OnReAuth()
if err != nil {
return nil, nil, err
}
}
return c.Connection.Call(c.cdnUrl, p)
}
// ContainerCDNEnable enables a container for public CDN usage.
//
// Change the default TTL of 259200 seconds (72 hours) by passing in an integer value.
//
// This method can be called again to change the TTL.
func (c *RsConnection) ContainerCDNEnable(container string, ttl int) (swift.Headers, error) {
h := swift.Headers{"X-CDN-Enabled": "true"}
if ttl > 0 {
h["X-TTL"] = strconv.Itoa(ttl)
}
_, headers, err := c.manage(swift.RequestOpts{
Container: container,
Operation: "PUT",
ErrorMap: swift.ContainerErrorMap,
NoResponse: true,
Headers: h,
})
return headers, err
}
// ContainerCDNDisable disables CDN access to a container.
func (c *RsConnection) ContainerCDNDisable(container string) error {
h := swift.Headers{"X-CDN-Enabled": "false"}
_, _, err := c.manage(swift.RequestOpts{
Container: container,
Operation: "PUT",
ErrorMap: swift.ContainerErrorMap,
NoResponse: true,
Headers: h,
})
return err
}
// ContainerCDNMeta returns the CDN metadata for a container.
func (c *RsConnection) ContainerCDNMeta(container string) (swift.Headers, error) {
_, headers, err := c.manage(swift.RequestOpts{
Container: container,
Operation: "HEAD",
ErrorMap: swift.ContainerErrorMap,
NoResponse: true,
Headers: swift.Headers{},
})
return headers, err
}

View file

@ -1,96 +0,0 @@
// See swift_test.go for requirements to run this test.
package rs_test
import (
"os"
"testing"
"github.com/ncw/swift/rs"
)
var (
c rs.RsConnection
)
const (
CONTAINER = "GoSwiftUnitTest"
OBJECT = "test_object"
CONTENTS = "12345"
CONTENT_SIZE = int64(len(CONTENTS))
CONTENT_MD5 = "827ccb0eea8a706c4c34a16891f84e7b"
)
// Test functions are run in order - this one must be first!
func TestAuthenticate(t *testing.T) {
UserName := os.Getenv("SWIFT_API_USER")
ApiKey := os.Getenv("SWIFT_API_KEY")
AuthUrl := os.Getenv("SWIFT_AUTH_URL")
if UserName == "" || ApiKey == "" || AuthUrl == "" {
t.Fatal("SWIFT_API_USER, SWIFT_API_KEY and SWIFT_AUTH_URL not all set")
}
c = rs.RsConnection{}
c.UserName = UserName
c.ApiKey = ApiKey
c.AuthUrl = AuthUrl
err := c.Authenticate()
if err != nil {
t.Fatal("Auth failed", err)
}
if !c.Authenticated() {
t.Fatal("Not authenticated")
}
}
// Setup
func TestContainerCreate(t *testing.T) {
err := c.ContainerCreate(CONTAINER, nil)
if err != nil {
t.Fatal(err)
}
}
func TestCDNEnable(t *testing.T) {
headers, err := c.ContainerCDNEnable(CONTAINER, 0)
if err != nil {
t.Error(err)
}
if _, ok := headers["X-Cdn-Uri"]; !ok {
t.Error("Failed to enable CDN for container")
}
}
func TestOnReAuth(t *testing.T) {
c2 := rs.RsConnection{}
c2.UserName = c.UserName
c2.ApiKey = c.ApiKey
c2.AuthUrl = c.AuthUrl
_, err := c2.ContainerCDNEnable(CONTAINER, 0)
if err != nil {
t.Fatalf("Failed to reauthenticate: %v", err)
}
}
func TestCDNMeta(t *testing.T) {
headers, err := c.ContainerCDNMeta(CONTAINER)
if err != nil {
t.Error(err)
}
if _, ok := headers["X-Cdn-Uri"]; !ok {
t.Error("CDN is not enabled")
}
}
func TestCDNDisable(t *testing.T) {
err := c.ContainerCDNDisable(CONTAINER) // files stick in CDN until TTL expires
if err != nil {
t.Error(err)
}
}
// Teardown
func TestContainerDelete(t *testing.T) {
err := c.ContainerDelete(CONTAINER)
if err != nil {
t.Fatal(err)
}
}

View file

@ -1,629 +0,0 @@
// This tests the swift package internals
//
// It does not require access to a swift server
//
// FIXME need to add more tests and to check URLs and parameters
package swift
import (
"fmt"
"io"
"net"
"net/http"
"os"
"reflect"
"testing"
"time"
)
const (
TEST_ADDRESS = "localhost:5324"
AUTH_URL = "http://" + TEST_ADDRESS + "/v1.0"
PROXY_URL = "http://" + TEST_ADDRESS + "/proxy"
USERNAME = "test"
APIKEY = "apikey"
AUTH_TOKEN = "token"
)
// Globals
var (
server *SwiftServer
c *Connection
)
// SwiftServer implements a test swift server
type SwiftServer struct {
t *testing.T
checks []*Check
}
// Used to check and reply to http transactions
type Check struct {
in Headers
out Headers
rx *string
tx *string
err *Error
url *string
}
// Add a in check
func (check *Check) In(in Headers) *Check {
check.in = in
return check
}
// Add an out check
func (check *Check) Out(out Headers) *Check {
check.out = out
return check
}
// Add an Error check
func (check *Check) Error(StatusCode int, Text string) *Check {
check.err = newError(StatusCode, Text)
return check
}
// Add a rx check
func (check *Check) Rx(rx string) *Check {
check.rx = &rx
return check
}
// Add an tx check
func (check *Check) Tx(tx string) *Check {
check.tx = &tx
return check
}
// Add an URL check
func (check *Check) Url(url string) *Check {
check.url = &url
return check
}
// Add a check
func (s *SwiftServer) AddCheck(t *testing.T) *Check {
server.t = t
check := &Check{
in: Headers{},
out: Headers{},
err: nil,
}
s.checks = append(s.checks, check)
return check
}
// Responds to a request
func (s *SwiftServer) Respond(w http.ResponseWriter, r *http.Request) {
if len(s.checks) < 1 {
s.t.Fatal("Unexpected http transaction")
}
check := s.checks[0]
s.checks = s.checks[1:]
// Check URL
if check.url != nil && *check.url != r.URL.String() {
s.t.Errorf("Expecting URL %q but got %q", *check.url, r.URL)
}
// Check headers
for k, v := range check.in {
actual := r.Header.Get(k)
if actual != v {
s.t.Errorf("Expecting header %q=%q but got %q", k, v, actual)
}
}
// Write output headers
h := w.Header()
for k, v := range check.out {
h.Set(k, v)
}
// Return an error if required
if check.err != nil {
http.Error(w, check.err.Text, check.err.StatusCode)
} else {
if check.tx != nil {
_, err := w.Write([]byte(*check.tx))
if err != nil {
s.t.Error("Write failed", err)
}
}
}
}
// Checks to see all responses are used up
func (s *SwiftServer) Finished() {
if len(s.checks) > 0 {
s.t.Error("Unused checks", s.checks)
}
}
func handle(w http.ResponseWriter, r *http.Request) {
// out, _ := httputil.DumpRequest(r, true)
// os.Stdout.Write(out)
server.Respond(w, r)
}
func NewSwiftServer() *SwiftServer {
server := &SwiftServer{}
http.HandleFunc("/", handle)
go http.ListenAndServe(TEST_ADDRESS, nil)
fmt.Print("Waiting for server to start ")
for {
fmt.Print(".")
conn, err := net.Dial("tcp", TEST_ADDRESS)
if err == nil {
conn.Close()
fmt.Println(" Started")
break
}
}
return server
}
func init() {
server = NewSwiftServer()
c = &Connection{
UserName: USERNAME,
ApiKey: APIKEY,
AuthUrl: AUTH_URL,
}
}
// Check the error is a swift error
func checkError(t *testing.T, err error, StatusCode int, Text string) {
if err == nil {
t.Fatal("No error returned")
}
err2, ok := err.(*Error)
if !ok {
t.Fatal("Bad error type")
}
if err2.StatusCode != StatusCode {
t.Fatalf("Bad status code, expecting %d got %d", StatusCode, err2.StatusCode)
}
if err2.Text != Text {
t.Fatalf("Bad error string, expecting %q got %q", Text, err2.Text)
}
}
// FIXME copied from swift_test.go
func compareMaps(t *testing.T, a, b map[string]string) {
if len(a) != len(b) {
t.Error("Maps different sizes", a, b)
}
for ka, va := range a {
if vb, ok := b[ka]; !ok || va != vb {
t.Error("Difference in key", ka, va, b[ka])
}
}
for kb, vb := range b {
if va, ok := a[kb]; !ok || vb != va {
t.Error("Difference in key", kb, vb, a[kb])
}
}
}
func TestInternalError(t *testing.T) {
e := newError(404, "Not Found!")
if e.StatusCode != 404 || e.Text != "Not Found!" {
t.Fatal("Bad error")
}
if e.Error() != "Not Found!" {
t.Fatal("Bad error")
}
}
func testCheckClose(rd io.ReadCloser, e error) (err error) {
err = e
defer checkClose(rd, &err)
return
}
// Make a closer which returns the error of our choice
type myCloser struct {
err error
}
func (c *myCloser) Read([]byte) (int, error) {
return 0, io.EOF
}
func (c *myCloser) Close() error {
return c.err
}
func TestInternalCheckClose(t *testing.T) {
if testCheckClose(&myCloser{nil}, nil) != nil {
t.Fatal("bad 1")
}
if testCheckClose(&myCloser{nil}, ObjectCorrupted) != ObjectCorrupted {
t.Fatal("bad 2")
}
if testCheckClose(&myCloser{ObjectNotFound}, nil) != ObjectNotFound {
t.Fatal("bad 3")
}
if testCheckClose(&myCloser{ObjectNotFound}, ObjectCorrupted) != ObjectCorrupted {
t.Fatal("bad 4")
}
}
func TestInternalParseHeaders(t *testing.T) {
resp := &http.Response{StatusCode: 200}
if c.parseHeaders(resp, nil) != nil {
t.Error("Bad 1")
}
if c.parseHeaders(resp, authErrorMap) != nil {
t.Error("Bad 1")
}
resp = &http.Response{StatusCode: 299}
if c.parseHeaders(resp, nil) != nil {
t.Error("Bad 1")
}
resp = &http.Response{StatusCode: 199, Status: "BOOM"}
checkError(t, c.parseHeaders(resp, nil), 199, "HTTP Error: 199: BOOM")
resp = &http.Response{StatusCode: 300, Status: "BOOM"}
checkError(t, c.parseHeaders(resp, nil), 300, "HTTP Error: 300: BOOM")
resp = &http.Response{StatusCode: 404, Status: "BOOM"}
checkError(t, c.parseHeaders(resp, nil), 404, "HTTP Error: 404: BOOM")
if c.parseHeaders(resp, ContainerErrorMap) != ContainerNotFound {
t.Error("Bad 1")
}
if c.parseHeaders(resp, objectErrorMap) != ObjectNotFound {
t.Error("Bad 1")
}
}
func TestInternalReadHeaders(t *testing.T) {
resp := &http.Response{Header: http.Header{}}
compareMaps(t, readHeaders(resp), Headers{})
resp = &http.Response{Header: http.Header{
"one": []string{"1"},
"two": []string{"2"},
}}
compareMaps(t, readHeaders(resp), Headers{"one": "1", "two": "2"})
// FIXME this outputs a log which we should test and check
resp = &http.Response{Header: http.Header{
"one": []string{"1", "11", "111"},
"two": []string{"2"},
}}
compareMaps(t, readHeaders(resp), Headers{"one": "1", "two": "2"})
}
func TestInternalStorage(t *testing.T) {
// FIXME
}
// ------------------------------------------------------------
func TestInternalAuthenticate(t *testing.T) {
server.AddCheck(t).In(Headers{
"User-Agent": DefaultUserAgent,
"X-Auth-Key": APIKEY,
"X-Auth-User": USERNAME,
}).Out(Headers{
"X-Storage-Url": PROXY_URL,
"X-Auth-Token": AUTH_TOKEN,
}).Url("/v1.0")
defer server.Finished()
err := c.Authenticate()
if err != nil {
t.Fatal(err)
}
if c.StorageUrl != PROXY_URL {
t.Error("Bad storage url")
}
if c.AuthToken != AUTH_TOKEN {
t.Error("Bad auth token")
}
if !c.Authenticated() {
t.Error("Didn't authenticate")
}
}
func TestInternalAuthenticateDenied(t *testing.T) {
server.AddCheck(t).Error(400, "Bad request")
server.AddCheck(t).Error(401, "DENIED")
defer server.Finished()
c.UnAuthenticate()
err := c.Authenticate()
if err != AuthorizationFailed {
t.Fatal("Expecting AuthorizationFailed", err)
}
// FIXME
// if c.Authenticated() {
// t.Fatal("Expecting not authenticated")
// }
}
func TestInternalAuthenticateBad(t *testing.T) {
server.AddCheck(t).Out(Headers{
"X-Storage-Url": PROXY_URL,
})
defer server.Finished()
err := c.Authenticate()
checkError(t, err, 0, "Response didn't have storage url and auth token")
if c.Authenticated() {
t.Fatal("Expecting not authenticated")
}
server.AddCheck(t).Out(Headers{
"X-Auth-Token": AUTH_TOKEN,
})
err = c.Authenticate()
checkError(t, err, 0, "Response didn't have storage url and auth token")
if c.Authenticated() {
t.Fatal("Expecting not authenticated")
}
server.AddCheck(t)
err = c.Authenticate()
checkError(t, err, 0, "Response didn't have storage url and auth token")
if c.Authenticated() {
t.Fatal("Expecting not authenticated")
}
server.AddCheck(t).Out(Headers{
"X-Storage-Url": PROXY_URL,
"X-Auth-Token": AUTH_TOKEN,
})
err = c.Authenticate()
if err != nil {
t.Fatal(err)
}
if !c.Authenticated() {
t.Fatal("Expecting authenticated")
}
}
func testContainerNames(t *testing.T, rx string, expected []string) {
server.AddCheck(t).In(Headers{
"User-Agent": DefaultUserAgent,
"X-Auth-Token": AUTH_TOKEN,
}).Tx(rx).Url("/proxy")
containers, err := c.ContainerNames(nil)
if err != nil {
t.Fatal(err)
}
if len(containers) != len(expected) {
t.Fatal("Wrong number of containers", len(containers), rx, len(expected), expected)
}
for i := range containers {
if containers[i] != expected[i] {
t.Error("Bad container", containers[i], expected[i])
}
}
}
func TestInternalContainerNames(t *testing.T) {
defer server.Finished()
testContainerNames(t, "", []string{})
testContainerNames(t, "one", []string{"one"})
testContainerNames(t, "one\n", []string{"one"})
testContainerNames(t, "one\ntwo\nthree\n", []string{"one", "two", "three"})
}
func TestInternalObjectPutBytes(t *testing.T) {
server.AddCheck(t).In(Headers{
"User-Agent": DefaultUserAgent,
"X-Auth-Token": AUTH_TOKEN,
"Content-Length": "5",
"Content-Type": "text/plain",
}).Rx("12345")
defer server.Finished()
c.ObjectPutBytes("container", "object", []byte{'1', '2', '3', '4', '5'}, "text/plain")
}
func TestInternalObjectPutString(t *testing.T) {
server.AddCheck(t).In(Headers{
"User-Agent": DefaultUserAgent,
"X-Auth-Token": AUTH_TOKEN,
"Content-Length": "5",
"Content-Type": "text/plain",
}).Rx("12345")
defer server.Finished()
c.ObjectPutString("container", "object", "12345", "text/plain")
}
func TestSetFromEnv(t *testing.T) {
// String
s := ""
os.Setenv("POTATO", "")
err := setFromEnv(&s, "POTATO")
if err != nil {
t.Fatal(err)
}
os.Setenv("POTATO", "this is a test")
err = setFromEnv(&s, "POTATO")
if err != nil {
t.Fatal(err)
}
if s != "this is a test" {
t.Fatal("incorrect", s)
}
os.Setenv("POTATO", "new")
err = setFromEnv(&s, "POTATO")
if err != nil {
t.Fatal(err)
}
if s != "this is a test" {
t.Fatal("was reset when it shouldn't have been")
}
// Integer
i := 0
os.Setenv("POTATO", "42")
err = setFromEnv(&i, "POTATO")
if err != nil {
t.Fatal(err)
}
if i != 42 {
t.Fatal("incorrect", i)
}
os.Setenv("POTATO", "43")
err = setFromEnv(&i, "POTATO")
if err != nil {
t.Fatal(err)
}
if i != 42 {
t.Fatal("was reset when it shouldn't have been")
}
i = 0
os.Setenv("POTATO", "not a number")
err = setFromEnv(&i, "POTATO")
if err == nil {
t.Fatal("expecting error but didn't get one")
}
// bool
var b bool
os.Setenv("POTATO", "1")
err = setFromEnv(&b, "POTATO")
if err != nil {
t.Fatal(err)
}
if b != true {
t.Fatal("incorrect", b)
}
// time.Duration
var dt time.Duration
os.Setenv("POTATO", "5s")
err = setFromEnv(&dt, "POTATO")
if err != nil {
t.Fatal(err)
}
if dt != 5*time.Second {
t.Fatal("incorrect", dt)
}
// EndpointType
var e EndpointType
os.Setenv("POTATO", "internal")
err = setFromEnv(&e, "POTATO")
if err != nil {
t.Fatal(err)
}
if e != EndpointType("internal") {
t.Fatal("incorrect", e)
}
// Unknown
var unknown struct{}
err = setFromEnv(&unknown, "POTATO")
if err == nil {
t.Fatal("expecting error")
}
os.Setenv("POTATO", "")
}
func TestApplyEnvironment(t *testing.T) {
// We've tested all the setting logic above, so just do a quick test here
c := new(Connection)
os.Setenv("GOSWIFT_CONNECT_TIMEOUT", "100s")
err := c.ApplyEnvironment()
if err != nil {
t.Fatal(err)
}
if c.ConnectTimeout != 100*time.Second {
t.Fatal("timeout incorrect", c.ConnectTimeout)
}
c.ConnectTimeout = 0
os.Setenv("GOSWIFT_CONNECT_TIMEOUT", "parse error")
err = c.ApplyEnvironment()
if err == nil {
t.Fatal("expecting error")
}
if c.ConnectTimeout != 0 {
t.Fatal("timeout incorrect", c.ConnectTimeout)
}
os.Setenv("GOSWIFT_CONNECT_TIMEOUT", "")
}
func TestApplyEnvironmentAll(t *testing.T) {
// we do this in two phases because some of the variable set the same thing
for phase := 1; phase <= 2; phase++ {
c := new(Connection)
items := []struct {
phase int
result interface{}
name string
value string
want interface{}
oldValue string
}{
// Copied and amended from ApplyEnvironment
// Environment variables - keep in same order as Connection
{1, &c.Domain, "OS_USER_DOMAIN_NAME", "os_user_domain_name", "os_user_domain_name", ""},
{1, &c.DomainId, "OS_USER_DOMAIN_ID", "os_user_domain_id", "os_user_domain_id", ""},
{1, &c.UserName, "OS_USERNAME", "os_username", "os_username", ""},
{1, &c.UserId, "OS_USER_ID", "os_user_id", "os_user_id", ""},
{1, &c.ApiKey, "OS_PASSWORD", "os_password", "os_password", ""},
{1, &c.AuthUrl, "OS_AUTH_URL", "os_auth_url", "os_auth_url", ""},
{1, &c.Retries, "GOSWIFT_RETRIES", "4", 4, ""},
{1, &c.UserAgent, "GOSWIFT_USER_AGENT", "goswift_user_agent", "goswift_user_agent", ""},
{1, &c.ConnectTimeout, "GOSWIFT_CONNECT_TIMEOUT", "98s", 98 * time.Second, ""},
{1, &c.Timeout, "GOSWIFT_TIMEOUT", "99s", 99 * time.Second, ""},
{1, &c.Region, "OS_REGION_NAME", "os_region_name", "os_region_name", ""},
{1, &c.AuthVersion, "ST_AUTH_VERSION", "3", 3, ""},
{1, &c.Internal, "GOSWIFT_INTERNAL", "true", true, ""},
{1, &c.Tenant, "OS_TENANT_NAME", "os_tenant_name", "os_tenant_name", ""},
{2, &c.Tenant, "OS_PROJECT_NAME", "os_project_name", "os_project_name", ""},
{1, &c.TenantId, "OS_TENANT_ID", "os_tenant_id", "os_tenant_id", ""},
{1, &c.EndpointType, "OS_ENDPOINT_TYPE", "internal", EndpointTypeInternal, ""},
{1, &c.TenantDomain, "OS_PROJECT_DOMAIN_NAME", "os_project_domain_name", "os_project_domain_name", ""},
{1, &c.TenantDomainId, "OS_PROJECT_DOMAIN_ID", "os_project_domain_id", "os_project_domain_id", ""},
{1, &c.TrustId, "OS_TRUST_ID", "os_trust_id", "os_trust_id", ""},
{1, &c.StorageUrl, "OS_STORAGE_URL", "os_storage_url", "os_storage_url", ""},
{1, &c.AuthToken, "OS_AUTH_TOKEN", "os_auth_token", "os_auth_token", ""},
// v1 auth alternatives
{2, &c.ApiKey, "ST_KEY", "st_key", "st_key", ""},
{2, &c.UserName, "ST_USER", "st_user", "st_user", ""},
{2, &c.AuthUrl, "ST_AUTH", "st_auth", "st_auth", ""},
}
for i := range items {
item := &items[i]
if item.phase == phase {
item.oldValue = os.Getenv(item.name) // save old value
os.Setenv(item.name, item.value) // set new value
}
}
err := c.ApplyEnvironment()
if err != nil {
t.Fatalf("unexpected error %v", err)
}
for i := range items {
item := &items[i]
if item.phase == phase {
got := reflect.Indirect(reflect.ValueOf(item.result)).Interface()
if !reflect.DeepEqual(item.want, got) {
t.Errorf("%s: %v != %v", item.name, item.want, got)
}
os.Setenv(item.name, item.oldValue) // restore old value
}
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,107 +0,0 @@
// This tests TimeoutReader
package swift
import (
"io"
"io/ioutil"
"sync"
"testing"
"time"
)
// An io.ReadCloser for testing
type testReader struct {
sync.Mutex
n int
delay time.Duration
closed bool
}
// Returns n bytes with at time.Duration delay
func newTestReader(n int, delay time.Duration) *testReader {
return &testReader{
n: n,
delay: delay,
}
}
// Returns 1 byte at a time after delay
func (t *testReader) Read(p []byte) (n int, err error) {
if t.n <= 0 {
return 0, io.EOF
}
time.Sleep(t.delay)
p[0] = 'A'
t.Lock()
t.n--
t.Unlock()
return 1, nil
}
// Close the channel
func (t *testReader) Close() error {
t.Lock()
t.closed = true
t.Unlock()
return nil
}
func TestTimeoutReaderNoTimeout(t *testing.T) {
test := newTestReader(3, 10*time.Millisecond)
cancelled := false
cancel := func() {
cancelled = true
}
tr := newTimeoutReader(test, 100*time.Millisecond, cancel)
b, err := ioutil.ReadAll(tr)
if err != nil || string(b) != "AAA" {
t.Fatalf("Bad read %s %s", err, b)
}
if cancelled {
t.Fatal("Cancelled when shouldn't have been")
}
if test.n != 0 {
t.Fatal("Didn't read all")
}
if test.closed {
t.Fatal("Shouldn't be closed")
}
tr.Close()
if !test.closed {
t.Fatal("Should be closed")
}
}
func TestTimeoutReaderTimeout(t *testing.T) {
// Return those bytes slowly so we get an idle timeout
test := newTestReader(3, 100*time.Millisecond)
cancelled := false
cancel := func() {
cancelled = true
}
tr := newTimeoutReader(test, 10*time.Millisecond, cancel)
_, err := ioutil.ReadAll(tr)
if err != TimeoutError {
t.Fatal("Expecting TimeoutError, got", err)
}
if !cancelled {
t.Fatal("Not cancelled when should have been")
}
test.Lock()
n := test.n
test.Unlock()
if n == 0 {
t.Fatal("Read all")
}
if n != 3 {
t.Fatal("Didn't read any")
}
if test.closed {
t.Fatal("Shouldn't be closed")
}
tr.Close()
if !test.closed {
t.Fatal("Should be closed")
}
}

View file

@ -1,137 +0,0 @@
// This tests WatchdogReader
package swift
import (
"bytes"
"io"
"io/ioutil"
"testing"
"time"
)
// Uses testReader from timeout_reader_test.go
func testWatchdogReaderTimeout(t *testing.T, initialTimeout, watchdogTimeout time.Duration, expectedTimeout bool) {
test := newTestReader(3, 10*time.Millisecond)
timer, firedChan := setupTimer(initialTimeout)
wr := newWatchdogReader(test, watchdogTimeout, timer)
b, err := ioutil.ReadAll(wr)
if err != nil || string(b) != "AAA" {
t.Fatalf("Bad read %s %s", err, b)
}
checkTimer(t, firedChan, expectedTimeout)
}
func setupTimer(initialTimeout time.Duration) (timer *time.Timer, fired <-chan bool) {
timer = time.NewTimer(initialTimeout)
firedChan := make(chan bool)
started := make(chan bool)
go func() {
started <- true
select {
case <-timer.C:
firedChan <- true
}
}()
<-started
return timer, firedChan
}
func checkTimer(t *testing.T, firedChan <-chan bool, expectedTimeout bool) {
fired := false
select {
case fired = <-firedChan:
default:
}
if expectedTimeout {
if !fired {
t.Fatal("Timer should have fired")
}
} else {
if fired {
t.Fatal("Timer should not have fired")
}
}
}
func TestWatchdogReaderNoTimeout(t *testing.T) {
testWatchdogReaderTimeout(t, 100*time.Millisecond, 100*time.Millisecond, false)
}
func TestWatchdogReaderTimeout(t *testing.T) {
testWatchdogReaderTimeout(t, 5*time.Millisecond, 5*time.Millisecond, true)
}
func TestWatchdogReaderNoTimeoutShortInitial(t *testing.T) {
testWatchdogReaderTimeout(t, 5*time.Millisecond, 100*time.Millisecond, false)
}
func TestWatchdogReaderTimeoutLongInitial(t *testing.T) {
testWatchdogReaderTimeout(t, 100*time.Millisecond, 5*time.Millisecond, true)
}
//slowReader simulates reading from a slow network connection by introducing a delay
//in each Read() proportional to the amount of bytes read.
type slowReader struct {
reader io.Reader
delayPerByte time.Duration
}
func (r *slowReader) Read(p []byte) (n int, err error) {
n, err = r.reader.Read(p)
if n > 0 {
time.Sleep(time.Duration(n) * r.delayPerByte)
}
return
}
//This test verifies that the watchdogReader's timeout is not triggered by data
//that comes in very slowly. (It should only be triggered if no data arrives at
//all.)
func TestWatchdogReaderOnSlowNetwork(t *testing.T) {
byteString := make([]byte, 8*watchdogChunkSize)
reader := &slowReader{
reader: bytes.NewReader(byteString),
//reading everything at once would take 100 ms, which is longer than the
//watchdog timeout below
delayPerByte: 200 * time.Millisecond / time.Duration(len(byteString)),
}
timer, firedChan := setupTimer(10 * time.Millisecond)
wr := newWatchdogReader(reader, 190*time.Millisecond, timer)
//use io.ReadFull instead of ioutil.ReadAll here because ReadAll already does
//some chunking that would keep this testcase from failing
b := make([]byte, len(byteString))
n, err := io.ReadFull(wr, b)
if err != nil || n != len(b) || !bytes.Equal(b, byteString) {
t.Fatalf("Bad read %s %d", err, n)
}
checkTimer(t, firedChan, false)
}
//This test verifies that the watchdogReader's chunking logic does not mess up
//the byte strings that are read.
func TestWatchdogReaderValidity(t *testing.T) {
byteString := []byte("abcdefghij")
//make a reader with a non-standard chunk size (1 MiB would be much too huge
//to comfortably look at the bytestring that comes out of the reader)
wr := &watchdogReader{
reader: bytes.NewReader(byteString),
chunkSize: 3, //len(byteString) % chunkSize != 0 to be extra rude :)
//don't care about the timeout stuff here
timeout: 5 * time.Minute,
timer: time.NewTimer(5 * time.Minute),
}
b := make([]byte, len(byteString))
n, err := io.ReadFull(wr, b)
if err != nil || n != len(b) {
t.Fatalf("Read error: %s", err)
}
if !bytes.Equal(b, byteString) {
t.Fatalf("Bad read: %#v != %#v", string(b), string(byteString))
}
}