<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)
//
// A collection of tests for a file system backed by a GCS bucket, where in
// most cases we interact with the file system directly for creating and
// mofiying files (rather than through the side channel of the GCS bucket
// itself).
//
// These tests are registered by RegisterFSTests.

package fstesting

import (
	"io"
	"io/ioutil"
	"math"
	"os"
	"path"
	"time"

	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
)

////////////////////////////////////////////////////////////////////////
// Read-write interaction
////////////////////////////////////////////////////////////////////////

type readWriteTest struct {
	fsTest
}

func (t *readWriteTest) OpenNonExistent_CreateFlagNotSet() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_Append() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenExistingFile_ReadOnly() {
	// Create a file.
	const contents = "tacoburritoenchilada"
	AssertEq(
		nil,
		ioutil.WriteFile(
			path.Join(t.mfs.Dir(), "foo"),
			[]byte(contents),
			os.FileMode(0644)))

	// Open the file for reading.
	f, err := os.Open(path.Join(t.mfs.Dir(), "foo"))
	AssertEq(nil, err)

	defer func() {
		ExpectEq(nil, f.Close())
	}()

	// Check its vitals.
	ExpectEq(path.Join(t.mfs.Dir(), "foo"), f.Name())

	fi, err := f.Stat()
	ExpectEq("foo", fi.Name())
	ExpectEq(len(contents), fi.Size())
	ExpectEq(os.FileMode(0), fi.Mode() & ^os.ModePerm)
	ExpectLt(math.Abs(time.Since(fi.ModTime()).Seconds()), 10)
	ExpectFalse(fi.IsDir())

	// Read its contents.
	fileContents, err := ioutil.ReadAll(f)
	AssertEq(nil, err)
	ExpectEq(contents, string(fileContents))

	// Attempt to write.
	n, err := f.Write([]byte("taco"))

	AssertEq(0, n)
	AssertNe(nil, err)
	ExpectThat(err, Error(HasSubstr("bad file descriptor")))
}

func (t *readWriteTest) OpenExistingFile_WriteOnly() {
	// Create a file.
	const contents = "tacoburritoenchilada"
	AssertEq(
		nil,
		ioutil.WriteFile(
			path.Join(t.mfs.Dir(), "foo"),
			[]byte(contents),
			os.FileMode(0644)))

	// Open the file for reading.
	f, err := os.OpenFile(path.Join(t.mfs.Dir(), "foo"), os.O_WRONLY, 0)
	AssertEq(nil, err)

	defer func() {
		if f != nil {
			ExpectEq(nil, f.Close())
		}
	}()

	// Check its vitals.
	ExpectEq(path.Join(t.mfs.Dir(), "foo"), f.Name())

	fi, err := f.Stat()
	ExpectEq("foo", fi.Name())
	ExpectEq(len(contents), fi.Size())
	ExpectEq(os.FileMode(0), fi.Mode() & ^os.ModePerm)
	ExpectLt(math.Abs(time.Since(fi.ModTime()).Seconds()), 10)
	ExpectFalse(fi.IsDir())

	// Reading should fail.
	_, err = ioutil.ReadAll(f)

	AssertNe(nil, err)
	ExpectThat(err, Error(HasSubstr("bad file descriptor")))

	// Write to the start of the file using File.Write.
	_, err = f.Write([]byte("000"))
	AssertEq(nil, err)

	// Write to the middle of the file using File.WriteAt.
	_, err = f.WriteAt([]byte("111"), 4)
	AssertEq(nil, err)

	// Seek and write past the end of the file.
	_, err = f.Seek(int64(len(contents)), 0)
	AssertEq(nil, err)

	_, err = f.Write([]byte("222"))
	AssertEq(nil, err)

	// Close the file.
	AssertEq(nil, f.Close())
	f = nil

	// Read back its contents.
	fileContents, err := ioutil.ReadFile(path.Join(t.mfs.Dir(), "foo"))

	AssertEq(nil, err)
	ExpectEq("000o111ritoenchilada222", string(fileContents))
}

func (t *readWriteTest) OpenExistingFile_ReadWrite() {
	// Create a file.
	const contents = "tacoburritoenchilada"
	AssertEq(
		nil,
		ioutil.WriteFile(
			path.Join(t.mfs.Dir(), "foo"),
			[]byte(contents),
			os.FileMode(0644)))

	// Open the file for reading.
	f, err := os.OpenFile(path.Join(t.mfs.Dir(), "foo"), os.O_RDWR, 0)
	AssertEq(nil, err)

	defer func() {
		if f != nil {
			ExpectEq(nil, f.Close())
		}
	}()

	// Check its vitals.
	ExpectEq(path.Join(t.mfs.Dir(), "foo"), f.Name())

	fi, err := f.Stat()
	ExpectEq("foo", fi.Name())
	ExpectEq(len(contents), fi.Size())
	ExpectEq(os.FileMode(0), fi.Mode() & ^os.ModePerm)
	ExpectLt(math.Abs(time.Since(fi.ModTime()).Seconds()), 10)
	ExpectFalse(fi.IsDir())

	// Write to the start of the file using File.Write.
	_, err = f.Write([]byte("000"))
	AssertEq(nil, err)

	// Write to the middle of the file using File.WriteAt.
	_, err = f.WriteAt([]byte("111"), 4)
	AssertEq(nil, err)

	// Seek and write past the end of the file.
	_, err = f.Seek(int64(len(contents)), 0)
	AssertEq(nil, err)

	_, err = f.Write([]byte("222"))
	AssertEq(nil, err)

	// Read some contents with Seek and Read.
	_, err = f.Seek(4, 0)
	AssertEq(nil, err)

	buf := make([]byte, 4)
	_, err = io.ReadFull(f, buf)

	AssertEq(nil, err)
	ExpectEq("111r", string(buf))

	// Read the full contents with ReadAt.
	buf = make([]byte, len(contents)+len("222"))
	_, err = f.ReadAt(buf, 0)

	AssertEq(nil, err)
	ExpectEq("000o111ritoenchilada222", string(buf))

	// Close the file.
	AssertEq(nil, f.Close())
	f = nil

	// Read back its contents after opening anew for reading.
	fileContents, err := ioutil.ReadFile(path.Join(t.mfs.Dir(), "foo"))

	AssertEq(nil, err)
	ExpectEq("000o111ritoenchilada222", string(fileContents))
}

func (t *readWriteTest) OpenExistingFile_Append() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_Append() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_Append() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenReadOnlyFileForWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Seek() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Stat() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Sync() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Truncate() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) CreateEmptyDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) CreateWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) ReadFromWriteOnlyFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) WriteToReadOnlyFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) StatUnopenedFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) LstatUnopenedFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) ListingsAreCached() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) AdditionsAreCached() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) RemovalsAreCached() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) BufferedWritesFlushedOnUnmount() {
	AssertTrue(false, "TODO")
}
<commit_msg>FakeGCS.ReadWriteTest.OpenExistingFile_Append<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)
//
// A collection of tests for a file system backed by a GCS bucket, where in
// most cases we interact with the file system directly for creating and
// mofiying files (rather than through the side channel of the GCS bucket
// itself).
//
// These tests are registered by RegisterFSTests.

package fstesting

import (
	"io"
	"io/ioutil"
	"math"
	"os"
	"path"
	"time"

	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
)

////////////////////////////////////////////////////////////////////////
// Read-write interaction
////////////////////////////////////////////////////////////////////////

type readWriteTest struct {
	fsTest
}

func (t *readWriteTest) OpenNonExistent_CreateFlagNotSet() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_Append() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenExistingFile_ReadOnly() {
	// Create a file.
	const contents = "tacoburritoenchilada"
	AssertEq(
		nil,
		ioutil.WriteFile(
			path.Join(t.mfs.Dir(), "foo"),
			[]byte(contents),
			os.FileMode(0644)))

	// Open the file for reading.
	f, err := os.Open(path.Join(t.mfs.Dir(), "foo"))
	AssertEq(nil, err)

	defer func() {
		ExpectEq(nil, f.Close())
	}()

	// Check its vitals.
	ExpectEq(path.Join(t.mfs.Dir(), "foo"), f.Name())

	fi, err := f.Stat()
	ExpectEq("foo", fi.Name())
	ExpectEq(len(contents), fi.Size())
	ExpectEq(os.FileMode(0), fi.Mode() & ^os.ModePerm)
	ExpectLt(math.Abs(time.Since(fi.ModTime()).Seconds()), 10)
	ExpectFalse(fi.IsDir())

	// Read its contents.
	fileContents, err := ioutil.ReadAll(f)
	AssertEq(nil, err)
	ExpectEq(contents, string(fileContents))

	// Attempt to write.
	n, err := f.Write([]byte("taco"))

	AssertEq(0, n)
	AssertNe(nil, err)
	ExpectThat(err, Error(HasSubstr("bad file descriptor")))
}

func (t *readWriteTest) OpenExistingFile_WriteOnly() {
	// Create a file.
	const contents = "tacoburritoenchilada"
	AssertEq(
		nil,
		ioutil.WriteFile(
			path.Join(t.mfs.Dir(), "foo"),
			[]byte(contents),
			os.FileMode(0644)))

	// Open the file for reading.
	f, err := os.OpenFile(path.Join(t.mfs.Dir(), "foo"), os.O_WRONLY, 0)
	AssertEq(nil, err)

	defer func() {
		if f != nil {
			ExpectEq(nil, f.Close())
		}
	}()

	// Check its vitals.
	ExpectEq(path.Join(t.mfs.Dir(), "foo"), f.Name())

	fi, err := f.Stat()
	ExpectEq("foo", fi.Name())
	ExpectEq(len(contents), fi.Size())
	ExpectEq(os.FileMode(0), fi.Mode() & ^os.ModePerm)
	ExpectLt(math.Abs(time.Since(fi.ModTime()).Seconds()), 10)
	ExpectFalse(fi.IsDir())

	// Reading should fail.
	_, err = ioutil.ReadAll(f)

	AssertNe(nil, err)
	ExpectThat(err, Error(HasSubstr("bad file descriptor")))

	// Write to the start of the file using File.Write.
	_, err = f.Write([]byte("000"))
	AssertEq(nil, err)

	// Write to the middle of the file using File.WriteAt.
	_, err = f.WriteAt([]byte("111"), 4)
	AssertEq(nil, err)

	// Seek and write past the end of the file.
	_, err = f.Seek(int64(len(contents)), 0)
	AssertEq(nil, err)

	_, err = f.Write([]byte("222"))
	AssertEq(nil, err)

	// Check the size now.
	AssertTrue(false, "TODO")

	// Close the file.
	AssertEq(nil, f.Close())
	f = nil

	// Read back its contents.
	fileContents, err := ioutil.ReadFile(path.Join(t.mfs.Dir(), "foo"))

	AssertEq(nil, err)
	ExpectEq("000o111ritoenchilada222", string(fileContents))
}

func (t *readWriteTest) OpenExistingFile_ReadWrite() {
	// Create a file.
	const contents = "tacoburritoenchilada"
	AssertEq(
		nil,
		ioutil.WriteFile(
			path.Join(t.mfs.Dir(), "foo"),
			[]byte(contents),
			os.FileMode(0644)))

	// Open the file for reading.
	f, err := os.OpenFile(path.Join(t.mfs.Dir(), "foo"), os.O_RDWR, 0)
	AssertEq(nil, err)

	defer func() {
		if f != nil {
			ExpectEq(nil, f.Close())
		}
	}()

	// Check its vitals.
	ExpectEq(path.Join(t.mfs.Dir(), "foo"), f.Name())

	fi, err := f.Stat()
	ExpectEq("foo", fi.Name())
	ExpectEq(len(contents), fi.Size())
	ExpectEq(os.FileMode(0), fi.Mode() & ^os.ModePerm)
	ExpectLt(math.Abs(time.Since(fi.ModTime()).Seconds()), 10)
	ExpectFalse(fi.IsDir())

	// Write to the start of the file using File.Write.
	_, err = f.Write([]byte("000"))
	AssertEq(nil, err)

	// Write to the middle of the file using File.WriteAt.
	_, err = f.WriteAt([]byte("111"), 4)
	AssertEq(nil, err)

	// Seek and write past the end of the file.
	_, err = f.Seek(int64(len(contents)), 0)
	AssertEq(nil, err)

	_, err = f.Write([]byte("222"))
	AssertEq(nil, err)

	// Check the size now.
	AssertTrue(false, "TODO")

	// Read some contents with Seek and Read.
	_, err = f.Seek(4, 0)
	AssertEq(nil, err)

	buf := make([]byte, 4)
	_, err = io.ReadFull(f, buf)

	AssertEq(nil, err)
	ExpectEq("111r", string(buf))

	// Read the full contents with ReadAt.
	buf = make([]byte, len(contents)+len("222"))
	_, err = f.ReadAt(buf, 0)

	AssertEq(nil, err)
	ExpectEq("000o111ritoenchilada222", string(buf))

	// Close the file.
	AssertEq(nil, f.Close())
	f = nil

	// Read back its contents after opening anew for reading.
	fileContents, err := ioutil.ReadFile(path.Join(t.mfs.Dir(), "foo"))

	AssertEq(nil, err)
	ExpectEq("000o111ritoenchilada222", string(fileContents))
}

func (t *readWriteTest) OpenExistingFile_Append() {
	// Create a file.
	const contents = "tacoburritoenchilada"
	AssertEq(
		nil,
		ioutil.WriteFile(
			path.Join(t.mfs.Dir(), "foo"),
			[]byte(contents),
			os.FileMode(0644)))

	// Open the file for reading.
	f, err := os.OpenFile(path.Join(t.mfs.Dir(), "foo"), os.O_RDWR|os.O_APPEND, 0)
	AssertEq(nil, err)

	defer func() {
		if f != nil {
			ExpectEq(nil, f.Close())
		}
	}()

	// Check its vitals.
	ExpectEq(path.Join(t.mfs.Dir(), "foo"), f.Name())

	fi, err := f.Stat()
	ExpectEq("foo", fi.Name())
	ExpectEq(len(contents), fi.Size())
	ExpectEq(os.FileMode(0), fi.Mode() & ^os.ModePerm)
	ExpectLt(math.Abs(time.Since(fi.ModTime()).Seconds()), 10)
	ExpectFalse(fi.IsDir())

	// Write using File.Write. This should go to the end of the file regardless
	// of whether we Seek somewhere else first.
	_, err = f.Seek(1, 0)
	AssertEq(nil, err)

	_, err = f.Write([]byte("222"))
	AssertEq(nil, err)

	// Write to the middle of the file using File.WriteAt.
	_, err = f.WriteAt([]byte("111"), 4)
	AssertEq(nil, err)

	// Check the size now.
	fi, err = f.Stat()
	AssertEq(nil, err)
	ExpectEq(len(contents)+len("222"), fi.Size())

	// Read some contents with Seek and Read.
	_, err = f.Seek(4, 0)
	AssertEq(nil, err)

	buf := make([]byte, 4)
	_, err = io.ReadFull(f, buf)

	AssertEq(nil, err)
	ExpectEq("111r", string(buf))

	// Read the full contents with ReadAt.
	buf = make([]byte, len(contents)+len("222"))
	_, err = f.ReadAt(buf, 0)

	AssertEq(nil, err)
	ExpectEq("taco111ritoenchilada222", string(buf))

	// Close the file.
	AssertEq(nil, f.Close())
	f = nil

	// Read back its contents after opening anew for reading.
	fileContents, err := ioutil.ReadFile(path.Join(t.mfs.Dir(), "foo"))

	AssertEq(nil, err)
	ExpectEq("taco111ritoenchilada222", string(fileContents))
}

func (t *readWriteTest) TruncateExistingFile_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_Append() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_Append() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenReadOnlyFileForWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Seek() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Stat() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Sync() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Truncate() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) CreateEmptyDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) CreateWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) ReadFromWriteOnlyFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) WriteToReadOnlyFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) StatUnopenedFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) LstatUnopenedFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) ListingsAreCached() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) AdditionsAreCached() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) RemovalsAreCached() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) BufferedWritesFlushedOnUnmount() {
	AssertTrue(false, "TODO")
}
<|endoftext|>


<commit_before>package postgres_test

import (
	"database/sql"
	"github.com/RangelReale/osin"
	_ "github.com/lib/pq"
	"github.com/ory-am/dockertest"
	"github.com/ory-am/osin-storage/Godeps/_workspace/src/github.com/pborman/uuid"
	"github.com/ory-am/osin-storage/storage"
	. "github.com/ory-am/osin-storage/storage/postgres"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"log"
	"os"
	"reflect"
	"testing"
	"time"
)

var db *sql.DB
var store *Storage
var userDataMock = "bar"

func TestMain(m *testing.M) {
	var err error
	var c dockertest.ContainerID
	c, db, err = dockertest.OpenPostgreSQLContainerConnection(15, time.Millisecond*500)
	if err != nil {
		log.Fatalf("Could not set up PostgreSQL container: %v", err)
	}
	defer c.KillRemove()

	store = New(db)
	if err = store.CreateSchemas(); err != nil {
		log.Fatalf("Could not set up schemas: %v", err)
	}

	os.Exit(m.Run())
}

func TestClientOperations(t *testing.T) {
	create := &osin.DefaultClient{"1", "secret", "http://localhost/", ""}
	createClient(t, store, create)
	getClient(t, store, create)

	update := &osin.DefaultClient{"1", "secret", "http://www.google.com/", ""}
	updateClient(t, store, update)
	getClient(t, store, update)
}

func TestAuthorizeOperations(t *testing.T) {
	client := &osin.DefaultClient{"2", "secret", "http://localhost/", ""}
	createClient(t, store, client)

	for k, authorize := range []*osin.AuthorizeData{
		&osin.AuthorizeData{
			Client:      client,
			Code:        uuid.New(),
			ExpiresIn:   int32(60),
			Scope:       "scope",
			RedirectUri: "http://localhost/",
			State:       "state",
			// FIXME this should be time.Now(), but an upstream ( https://github.com/lib/pq/issues/329 ) issue prevents this.
			CreatedAt: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
			UserData:  userDataMock,
		},
	} {
		// Test save
		require.Nil(t, store.SaveAuthorize(authorize))

		// Test fetch
		result, err := store.LoadAuthorize(authorize.Code)
		require.Nil(t, err)
		require.True(t, reflect.DeepEqual(authorize, result), "Case: %d\n%v\n\n%v", k, authorize, result)

		// Test remove
		require.Nil(t, store.RemoveAuthorize(authorize.Code))
		_, err = store.LoadAuthorize(authorize.Code)
		require.NotNil(t, err)
	}

	removeClient(t, store, client)
}

func TestStoreFailsOnInvalidUserData(t *testing.T) {
	client := &osin.DefaultClient{"3", "secret", "http://localhost/", ""}
	authorize := &osin.AuthorizeData{
		Client:      client,
		Code:        uuid.New(),
		ExpiresIn:   int32(60),
		Scope:       "scope",
		RedirectUri: "http://localhost/",
		State:       "state",
		CreatedAt:   time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
		UserData:    struct{ foo string }{"bar"},
	}
	access := &osin.AccessData{
		Client:        client,
		AuthorizeData: authorize,
		AccessData:    nil,
		AccessToken:   uuid.New(),
		RefreshToken:  uuid.New(),
		ExpiresIn:     int32(60),
		Scope:         "scope",
		RedirectUri:   "https://localhost/",
		CreatedAt:     time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
		UserData:      struct{ foo string }{"bar"},
	}
	assert.NotNil(t, store.SaveAuthorize(authorize))
	assert.NotNil(t, store.SaveAccess(access))
}

func TestAccessOperations(t *testing.T) {
	client := &osin.DefaultClient{"3", "secret", "http://localhost/", ""}
	authorize := &osin.AuthorizeData{
		Client:      client,
		Code:        uuid.New(),
		ExpiresIn:   int32(60),
		Scope:       "scope",
		RedirectUri: "http://localhost/",
		State:       "state",
		// FIXME this should be time.Now(), but an upstream ( https://github.com/lib/pq/issues/329 ) issue prevents this.
		CreatedAt: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
		UserData:  userDataMock,
	}
	nestedAccess := &osin.AccessData{
		Client:        client,
		AuthorizeData: authorize,
		AccessData:    nil,
		AccessToken:   uuid.New(),
		RefreshToken:  uuid.New(),
		ExpiresIn:     int32(60),
		Scope:         "scope",
		RedirectUri:   "https://localhost/",
		// FIXME this should be time.Now(), but an upstream ( https://github.com/lib/pq/issues/329 ) issue prevents this.
		CreatedAt: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
		UserData:  userDataMock,
	}
	access := &osin.AccessData{
		Client:        client,
		AuthorizeData: authorize,
		AccessData:    nestedAccess,
		AccessToken:   uuid.New(),
		RefreshToken:  uuid.New(),
		ExpiresIn:     int32(60),
		Scope:         "scope",
		RedirectUri:   "https://localhost/",
		// FIXME this should be time.Now(), but an upstream ( https://github.com/lib/pq/issues/329 ) issue prevents this.
		CreatedAt: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
		UserData:  userDataMock,
	}

	createClient(t, store, client)
	require.Nil(t, store.SaveAuthorize(authorize))
	require.Nil(t, store.SaveAccess(nestedAccess))
	require.Nil(t, store.SaveAccess(access))

	result, err := store.LoadAccess(access.AccessToken)
	require.Nil(t, err)
	require.True(t, reflect.DeepEqual(access, result))

	require.Nil(t, store.RemoveAccess(access.AccessToken))
	_, err = store.LoadAccess(access.AccessToken)
	require.NotNil(t, err)
	require.Nil(t, store.RemoveAuthorize(authorize.Code))

	removeClient(t, store, client)
}

func TestRefreshOperations(t *testing.T) {
	client := &osin.DefaultClient{"4", "secret", "http://localhost/", ""}
	type test struct {
		access *osin.AccessData
	}

	for k, c := range []*test{
		&test{
			access: &osin.AccessData{
				Client: client,
				AuthorizeData: &osin.AuthorizeData{
					Client:      client,
					Code:        uuid.New(),
					ExpiresIn:   int32(60),
					Scope:       "scope",
					RedirectUri: "http://localhost/",
					State:       "state",
					CreatedAt:   time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
					UserData:    userDataMock,
				},
				AccessData:   nil,
				AccessToken:  uuid.New(),
				RefreshToken: uuid.New(),
				ExpiresIn:    int32(60),
				Scope:        "scope",
				RedirectUri:  "https://localhost/",
				CreatedAt:    time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
				UserData:     userDataMock,
			},
		},
	} {
		createClient(t, store, client)
		require.Nil(t, store.SaveAuthorize(c.access.AuthorizeData), "Case %d", k)
		require.Nil(t, store.SaveAccess(c.access), "Case %d", k)

		result, err := store.LoadRefresh(c.access.RefreshToken)
		require.Nil(t, err)
		require.True(t, reflect.DeepEqual(c.access, result), "Case %d", k)

		require.Nil(t, store.RemoveRefresh(c.access.RefreshToken))
		_, err = store.LoadRefresh(c.access.RefreshToken)

		require.NotNil(t, err, "Case %d", k)
		require.Nil(t, store.RemoveAccess(c.access.AccessToken), "Case %d", k)
		require.Nil(t, store.SaveAccess(c.access), "Case %d", k)

		_, err = store.LoadRefresh(c.access.RefreshToken)
		require.Nil(t, err, "Case %d", k)

		require.Nil(t, store.RemoveAccess(c.access.AccessToken), "Case %d", k)
		_, err = store.LoadRefresh(c.access.RefreshToken)
		require.NotNil(t, err, "Case %d", k)

	}
	removeClient(t, store, client)
}

func getClient(t *testing.T, store storage.Storage, set osin.Client) {
	client, err := store.GetClient(set.GetId())
	require.Nil(t, err)
	require.EqualValues(t, set, client)
}

func createClient(t *testing.T, store storage.Storage, set osin.Client) {
	require.Nil(t, store.CreateClient(set))
}

func updateClient(t *testing.T, store storage.Storage, set osin.Client) {
	require.Nil(t, store.UpdateClient(set))
}

func removeClient(t *testing.T, store storage.Storage, set osin.Client) {
	require.Nil(t, store.RemoveClient(set.GetId()))
}
<commit_msg>test: import path fix<commit_after>package postgres_test

import (
	"database/sql"
	"github.com/RangelReale/osin"
	_ "github.com/lib/pq"
	"github.com/ory-am/dockertest"
	"github.com/ory-am/osin-storage/storage"
	. "github.com/ory-am/osin-storage/storage/postgres"
	"github.com/pborman/uuid"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"log"
	"os"
	"reflect"
	"testing"
	"time"
)

var db *sql.DB
var store *Storage
var userDataMock = "bar"

func TestMain(m *testing.M) {
	var err error
	var c dockertest.ContainerID
	c, db, err = dockertest.OpenPostgreSQLContainerConnection(15, time.Millisecond*500)
	if err != nil {
		log.Fatalf("Could not set up PostgreSQL container: %v", err)
	}
	defer c.KillRemove()

	store = New(db)
	if err = store.CreateSchemas(); err != nil {
		log.Fatalf("Could not set up schemas: %v", err)
	}

	os.Exit(m.Run())
}

func TestClientOperations(t *testing.T) {
	create := &osin.DefaultClient{"1", "secret", "http://localhost/", ""}
	createClient(t, store, create)
	getClient(t, store, create)

	update := &osin.DefaultClient{"1", "secret", "http://www.google.com/", ""}
	updateClient(t, store, update)
	getClient(t, store, update)
}

func TestAuthorizeOperations(t *testing.T) {
	client := &osin.DefaultClient{"2", "secret", "http://localhost/", ""}
	createClient(t, store, client)

	for k, authorize := range []*osin.AuthorizeData{
		&osin.AuthorizeData{
			Client:      client,
			Code:        uuid.New(),
			ExpiresIn:   int32(60),
			Scope:       "scope",
			RedirectUri: "http://localhost/",
			State:       "state",
			// FIXME this should be time.Now(), but an upstream ( https://github.com/lib/pq/issues/329 ) issue prevents this.
			CreatedAt: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
			UserData:  userDataMock,
		},
	} {
		// Test save
		require.Nil(t, store.SaveAuthorize(authorize))

		// Test fetch
		result, err := store.LoadAuthorize(authorize.Code)
		require.Nil(t, err)
		require.True(t, reflect.DeepEqual(authorize, result), "Case: %d\n%v\n\n%v", k, authorize, result)

		// Test remove
		require.Nil(t, store.RemoveAuthorize(authorize.Code))
		_, err = store.LoadAuthorize(authorize.Code)
		require.NotNil(t, err)
	}

	removeClient(t, store, client)
}

func TestStoreFailsOnInvalidUserData(t *testing.T) {
	client := &osin.DefaultClient{"3", "secret", "http://localhost/", ""}
	authorize := &osin.AuthorizeData{
		Client:      client,
		Code:        uuid.New(),
		ExpiresIn:   int32(60),
		Scope:       "scope",
		RedirectUri: "http://localhost/",
		State:       "state",
		CreatedAt:   time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
		UserData:    struct{ foo string }{"bar"},
	}
	access := &osin.AccessData{
		Client:        client,
		AuthorizeData: authorize,
		AccessData:    nil,
		AccessToken:   uuid.New(),
		RefreshToken:  uuid.New(),
		ExpiresIn:     int32(60),
		Scope:         "scope",
		RedirectUri:   "https://localhost/",
		CreatedAt:     time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
		UserData:      struct{ foo string }{"bar"},
	}
	assert.NotNil(t, store.SaveAuthorize(authorize))
	assert.NotNil(t, store.SaveAccess(access))
}

func TestAccessOperations(t *testing.T) {
	client := &osin.DefaultClient{"3", "secret", "http://localhost/", ""}
	authorize := &osin.AuthorizeData{
		Client:      client,
		Code:        uuid.New(),
		ExpiresIn:   int32(60),
		Scope:       "scope",
		RedirectUri: "http://localhost/",
		State:       "state",
		// FIXME this should be time.Now(), but an upstream ( https://github.com/lib/pq/issues/329 ) issue prevents this.
		CreatedAt: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
		UserData:  userDataMock,
	}
	nestedAccess := &osin.AccessData{
		Client:        client,
		AuthorizeData: authorize,
		AccessData:    nil,
		AccessToken:   uuid.New(),
		RefreshToken:  uuid.New(),
		ExpiresIn:     int32(60),
		Scope:         "scope",
		RedirectUri:   "https://localhost/",
		// FIXME this should be time.Now(), but an upstream ( https://github.com/lib/pq/issues/329 ) issue prevents this.
		CreatedAt: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
		UserData:  userDataMock,
	}
	access := &osin.AccessData{
		Client:        client,
		AuthorizeData: authorize,
		AccessData:    nestedAccess,
		AccessToken:   uuid.New(),
		RefreshToken:  uuid.New(),
		ExpiresIn:     int32(60),
		Scope:         "scope",
		RedirectUri:   "https://localhost/",
		// FIXME this should be time.Now(), but an upstream ( https://github.com/lib/pq/issues/329 ) issue prevents this.
		CreatedAt: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
		UserData:  userDataMock,
	}

	createClient(t, store, client)
	require.Nil(t, store.SaveAuthorize(authorize))
	require.Nil(t, store.SaveAccess(nestedAccess))
	require.Nil(t, store.SaveAccess(access))

	result, err := store.LoadAccess(access.AccessToken)
	require.Nil(t, err)
	require.True(t, reflect.DeepEqual(access, result))

	require.Nil(t, store.RemoveAccess(access.AccessToken))
	_, err = store.LoadAccess(access.AccessToken)
	require.NotNil(t, err)
	require.Nil(t, store.RemoveAuthorize(authorize.Code))

	removeClient(t, store, client)
}

func TestRefreshOperations(t *testing.T) {
	client := &osin.DefaultClient{"4", "secret", "http://localhost/", ""}
	type test struct {
		access *osin.AccessData
	}

	for k, c := range []*test{
		&test{
			access: &osin.AccessData{
				Client: client,
				AuthorizeData: &osin.AuthorizeData{
					Client:      client,
					Code:        uuid.New(),
					ExpiresIn:   int32(60),
					Scope:       "scope",
					RedirectUri: "http://localhost/",
					State:       "state",
					CreatedAt:   time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
					UserData:    userDataMock,
				},
				AccessData:   nil,
				AccessToken:  uuid.New(),
				RefreshToken: uuid.New(),
				ExpiresIn:    int32(60),
				Scope:        "scope",
				RedirectUri:  "https://localhost/",
				CreatedAt:    time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
				UserData:     userDataMock,
			},
		},
	} {
		createClient(t, store, client)
		require.Nil(t, store.SaveAuthorize(c.access.AuthorizeData), "Case %d", k)
		require.Nil(t, store.SaveAccess(c.access), "Case %d", k)

		result, err := store.LoadRefresh(c.access.RefreshToken)
		require.Nil(t, err)
		require.True(t, reflect.DeepEqual(c.access, result), "Case %d", k)

		require.Nil(t, store.RemoveRefresh(c.access.RefreshToken))
		_, err = store.LoadRefresh(c.access.RefreshToken)

		require.NotNil(t, err, "Case %d", k)
		require.Nil(t, store.RemoveAccess(c.access.AccessToken), "Case %d", k)
		require.Nil(t, store.SaveAccess(c.access), "Case %d", k)

		_, err = store.LoadRefresh(c.access.RefreshToken)
		require.Nil(t, err, "Case %d", k)

		require.Nil(t, store.RemoveAccess(c.access.AccessToken), "Case %d", k)
		_, err = store.LoadRefresh(c.access.RefreshToken)
		require.NotNil(t, err, "Case %d", k)

	}
	removeClient(t, store, client)
}

func getClient(t *testing.T, store storage.Storage, set osin.Client) {
	client, err := store.GetClient(set.GetId())
	require.Nil(t, err)
	require.EqualValues(t, set, client)
}

func createClient(t *testing.T, store storage.Storage, set osin.Client) {
	require.Nil(t, store.CreateClient(set))
}

func updateClient(t *testing.T, store storage.Storage, set osin.Client) {
	require.Nil(t, store.UpdateClient(set))
}

func removeClient(t *testing.T, store storage.Storage, set osin.Client) {
	require.Nil(t, store.RemoveClient(set.GetId()))
}
<|endoftext|>


<commit_before>// Copyright 2013 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 filemutex

import (
	"syscall"
	"unsafe"
)

var (
	modkernel32      = syscall.NewLazyDLL("kernel32.dll")
	procLockFileEx   = modkernel32.NewProc("LockFileEx")
	procUnlockFileEx = modkernel32.NewProc("UnlockFileEx")
)

const (
	lockfileExclusiveLock = 2
)

func lockFileEx(h syscall.Handle, flags, reserved, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
	r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(h), uintptr(flags), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)))
	if r1 == 0 {
		if e1 != 0 {
			err = error(e1)
		} else {
			err = syscall.EINVAL
		}
	}
	return
}

func unlockFileEx(h syscall.Handle, reserved, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
	r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(h), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)), 0)
	if r1 == 0 {
		if e1 != 0 {
			err = error(e1)
		} else {
			err = syscall.EINVAL
		}
	}
	return
}

// FileMutex is similar to sync.RWMutex, but also synchronizes across processes.
// This implementation is based on flock syscall.
type FileMutex struct {
	fd syscall.Handle
}

func New(filename string) (*FileMutex, error) {
	fd, err := syscall.CreateFile(&(syscall.StringToUTF16(filename)[0]), syscall.GENERIC_READ|syscall.GENERIC_WRITE,
		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE, nil, syscall.OPEN_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0)
	if err != nil {
		return nil, err
	}
	return &FileMutex{fd: fd}, nil
}

func (m *FileMutex) Lock() error {
	var ol syscall.Overlapped
	if err := lockFileEx(m.fd, lockfileExclusiveLock, 0, 1, 0, &ol); err != nil {
		return err
	}
	return nil
}

func (m *FileMutex) Unlock() error {
	var ol syscall.Overlapped
	if err := unlockFileEx(m.fd, 0, 1, 0, &ol); err != nil {
		return err
	}
	return nil
}

func (m *FileMutex) RLock() error {
	var ol syscall.Overlapped
	if err := lockFileEx(m.fd, 0, 0, 1, 0, &ol); err != nil {
		return err
	}
	return nil
}

func (m *FileMutex) RUnlock() error {
	var ol syscall.Overlapped
	if err := unlockFileEx(m.fd, 0, 1, 0, &ol); err != nil {
		return err
	}
}

// Close does an Unlock() combined with closing and unlinking the associated
// lock file. You should create a New() FileMutex for every Lock() attempt if
// using Close().
func (m *FileMutex) Close() error {
	var ol syscall.Overlapped
	if err := unlockFileEx(m.fd, 0, 1, 0, &ol); err != nil {
		return err
	}
	return syscall.Close(m.fd)
}
<commit_msg>add return nil<commit_after>// Copyright 2013 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 filemutex

import (
	"syscall"
	"unsafe"
)

var (
	modkernel32      = syscall.NewLazyDLL("kernel32.dll")
	procLockFileEx   = modkernel32.NewProc("LockFileEx")
	procUnlockFileEx = modkernel32.NewProc("UnlockFileEx")
)

const (
	lockfileExclusiveLock = 2
)

func lockFileEx(h syscall.Handle, flags, reserved, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
	r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(h), uintptr(flags), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)))
	if r1 == 0 {
		if e1 != 0 {
			err = error(e1)
		} else {
			err = syscall.EINVAL
		}
	}
	return
}

func unlockFileEx(h syscall.Handle, reserved, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
	r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(h), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)), 0)
	if r1 == 0 {
		if e1 != 0 {
			err = error(e1)
		} else {
			err = syscall.EINVAL
		}
	}
	return
}

// FileMutex is similar to sync.RWMutex, but also synchronizes across processes.
// This implementation is based on flock syscall.
type FileMutex struct {
	fd syscall.Handle
}

func New(filename string) (*FileMutex, error) {
	fd, err := syscall.CreateFile(&(syscall.StringToUTF16(filename)[0]), syscall.GENERIC_READ|syscall.GENERIC_WRITE,
		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE, nil, syscall.OPEN_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0)
	if err != nil {
		return nil, err
	}
	return &FileMutex{fd: fd}, nil
}

func (m *FileMutex) Lock() error {
	var ol syscall.Overlapped
	if err := lockFileEx(m.fd, lockfileExclusiveLock, 0, 1, 0, &ol); err != nil {
		return err
	}
	return nil
}

func (m *FileMutex) Unlock() error {
	var ol syscall.Overlapped
	if err := unlockFileEx(m.fd, 0, 1, 0, &ol); err != nil {
		return err
	}
	return nil
}

func (m *FileMutex) RLock() error {
	var ol syscall.Overlapped
	if err := lockFileEx(m.fd, 0, 0, 1, 0, &ol); err != nil {
		return err
	}
	return nil
}

func (m *FileMutex) RUnlock() error {
	var ol syscall.Overlapped
	if err := unlockFileEx(m.fd, 0, 1, 0, &ol); err != nil {
		return err
	}
	return nil
}

// Close does an Unlock() combined with closing and unlinking the associated
// lock file. You should create a New() FileMutex for every Lock() attempt if
// using Close().
func (m *FileMutex) Close() error {
	var ol syscall.Overlapped
	if err := unlockFileEx(m.fd, 0, 1, 0, &ol); err != nil {
		return err
	}
	return syscall.Close(m.fd)
}
<|endoftext|>


<commit_before>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package logger

import (
	"log"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
	"github.com/venicegeo/pz-gocommon/elasticsearch"
	piazza "github.com/venicegeo/pz-gocommon/gocommon"
)

const MOCKING = true

func sleep() {
	time.Sleep(1 * time.Second)
}

type LoggerTester struct {
	suite.Suite

	esi    elasticsearch.IIndex
	sys    *piazza.SystemConfig
	client IClient

	genericServer *piazza.GenericServer
}

func (suite *LoggerTester) setupFixture() {
	t := suite.T()
	assert := assert.New(t)

	var required []piazza.ServiceName
	if MOCKING {
		required = []piazza.ServiceName{}
	} else {
		required = []piazza.ServiceName{piazza.PzElasticSearch}
	}
	sys, err := piazza.NewSystemConfig(piazza.PzLogger, required)
	assert.NoError(err)
	suite.sys = sys

	esi, err := elasticsearch.NewIndexInterface(sys, "loggertest$", MOCKING)
	assert.NoError(err)
	suite.esi = esi

	if MOCKING {
		client, err := NewMockClient(sys)
		assert.NoError(err)
		suite.client = client
	} else {
		client, err := NewClient(sys)
		assert.NoError(err)
		suite.client = client
	}

	loggerService := &LoggerService{}
	loggerService.Init(sys, esi)

	loggerServer := &LoggerServer{}
	loggerServer.Init(loggerService)

	suite.genericServer = &piazza.GenericServer{Sys: sys}

	err = suite.genericServer.Configure(loggerServer.Routes)
	if err != nil {
		log.Fatal(err)
	}

	_, err = suite.genericServer.Start()
	assert.NoError(err)
}

func (suite *LoggerTester) teardownFixture() {
	suite.genericServer.Stop()

	suite.esi.Close()
	suite.esi.Delete()
}

func TestRunSuite(t *testing.T) {
	s := &LoggerTester{}
	suite.Run(t, s)
}

func (suite *LoggerTester) getLastMessage() string {
	t := suite.T()
	assert := assert.New(t)

	client := suite.client

	format := elasticsearch.QueryFormat{Size: 100, From: 0, Order: elasticsearch.SortAscending, Key: "CreatedOn"}
	ms, err := client.GetFromMessages(format, map[string]string{})
	assert.NoError(err)
	assert.True(len(ms) > 0)

	return ms[len(ms)-1].String()
}

func (suite *LoggerTester) Test01Elasticsearch() {
	t := suite.T()
	assert := assert.New(t)

	suite.setupFixture()
	defer suite.teardownFixture()

	version := suite.esi.GetVersion()
	assert.Contains("2.2.0", version)
}

func (suite *LoggerTester) Test02One() {
	t := suite.T()
	assert := assert.New(t)

	suite.setupFixture()
	defer suite.teardownFixture()

	client := suite.client

	var err error

	data1 := Message{
		Service:   "log-tester",
		Address:   "128.1.2.3",
		CreatedOn: time.Now(),
		Severity:  "Info",
		Message:   "The quick brown fox",
	}

	data2 := Message{
		Service:   "log-tester",
		Address:   "128.0.0.0",
		CreatedOn: time.Now(),
		Severity:  "Fatal",
		Message:   "The quick brown fox",
	}

	{
		err = client.LogMessage(&data1)
		assert.NoError(err, "PostToMessages")
	}

	sleep()

	{
		actualMssg := suite.getLastMessage()
		expectedMssg := data1.String()
		assert.EqualValues(actualMssg, expectedMssg)
	}

	{
		err = client.LogMessage(&data2)
		assert.NoError(err, "PostToMessages")
	}

	sleep()

	{
		actualMssg := suite.getLastMessage()
		expectedMssg := data2.String()
		assert.EqualValues(actualMssg, expectedMssg)
	}

	{
		stats, err := client.GetFromAdminStats()
		assert.NoError(err, "GetFromAdminStats")
		assert.Equal(2, stats.NumMessages, "stats check")
	}
}

func (suite *LoggerTester) Test03Help() {
	t := suite.T()
	assert := assert.New(t)

	err := suite.client.Log("mocktest", "0.0.0.0", SeverityInfo, time.Now(), "message from logger unit test via piazza.Log()")
	assert.NoError(err, "pzService.Log()")
}

func (suite *LoggerTester) Test04Admin() {
	t := suite.T()
	assert := assert.New(t)

	suite.setupFixture()
	defer suite.teardownFixture()

	client := suite.client

	_, err := client.GetFromAdminStats()
	assert.NoError(err, "GetFromAdminStats")
}

func (suite *LoggerTester) Test05Pagination() {
	t := suite.T()
	assert := assert.New(t)

	if MOCKING {
		//t.Skip("Skipping test, because mocking.")
	}

	suite.setupFixture()
	defer suite.teardownFixture()

	client := suite.client

	client.SetService("myservice", "1.2.3.4")

	err := client.Debug("d")
	assert.NoError(err)
	sleep()
	err = client.Info("i")
	assert.NoError(err)
	sleep()
	err = client.Warn("w")
	assert.NoError(err)
	sleep()
	err = client.Error("e")
	assert.NoError(err)
	sleep()
	err = client.Fatal("f")
	assert.NoError(err)
	sleep()

	format := elasticsearch.QueryFormat{Size: 1, From: 0, Key: "CreatedOn", Order: elasticsearch.SortAscending}
	ms, err := client.GetFromMessages(format, map[string]string{})
	assert.NoError(err)
	assert.Len(ms, 1)
	assert.EqualValues(SeverityDebug, ms[0].Severity)

	format = elasticsearch.QueryFormat{Size: 5, From: 0, Key: "CreatedOn", Order: elasticsearch.SortAscending}
	ms, err = client.GetFromMessages(format, map[string]string{})
	assert.NoError(err)
	assert.Len(ms, 5)
	assert.EqualValues(SeverityFatal, ms[4].Severity)

	format = elasticsearch.QueryFormat{Size: 3, From: 2, Key: "CreatedOn", Order: elasticsearch.SortDescending}
	ms, err = client.GetFromMessages(format, map[string]string{})
	assert.NoError(err)
	assert.Len(ms, 3)
	assert.EqualValues(SeverityWarning, ms[2].Severity)
	assert.EqualValues(SeverityError, ms[1].Severity)
	assert.EqualValues(SeverityFatal, ms[0].Severity)
}

func (suite *LoggerTester) Test06OtherParams() {
	t := suite.T()
	assert := assert.New(t)

	if MOCKING {
		t.Skip("Skipping test, because mocking.")
	}

	suite.setupFixture()
	defer suite.teardownFixture()

	client := suite.client

	client.SetService("myservice", "1.2.3.4")

	//sometime, err := time.Parse(time.RFC3339, "1985-04-12T23:20:50.52Z")
	//assert.NoError(err)
	sometime := time.Now()

	var testData = []Message{
		{
			Address:   "gnemud7smfv/10.254.0.66",
			Message:   "Received Message to Relay on topic Request-Job with key f3b63085-b482-4ae8-8297-3c7d1fcfff7d",
			Service:   "Dispatcher",
			Severity:  "Info",
			CreatedOn: sometime,
		}, {
			Address:   "gnfbnqsn5m9/10.254.0.14",
			Message:   "Processed Update Status for Job 6d0ea538-4382-4ea5-9669-56519b8c8f58 with Status Success",
			Service:   "JobManager",
			Severity:  "Info",
			CreatedOn: sometime,
		}, {
			Address:   "0.0.0.0",
			Message:   "generated 1: 09d4ec60-ea61-4066-8697-5568a47f84bf",
			Service:   "pz-uuidgen",
			Severity:  "Info",
			CreatedOn: sometime,
		}, {
			Address:   "gnfbnqsn5m9/10.254.0.14",
			Message:   "Handling Job with Topic Create-Job for Job ID 09d4ec60-ea61-4066-8697-5568a47f84bf",
			Service:   "JobManager",
			Severity:  "Info",
			CreatedOn: sometime,
		}, {
			Address:   "gnfbnqsn5m9/10.254.0.14",
			Message:   "Handling Job with Topic Update-Job for Job ID be4ce034-1187-4a4f-95a9-a9c31826248b",
			Service:   "JobManager",
			Severity:  "Info",
			CreatedOn: sometime,
		},
	}

	for _, e := range testData {
		// log.Printf("%d, %v\n", i, e)
		err := client.LogMessage(&e)
		assert.NoError(err)
	}

	sleep()

	format := elasticsearch.QueryFormat{
		Size: 100, From: 0,
		Order: elasticsearch.SortDescending,
		Key:   "CreatedOn"}

	msgs, err := client.GetFromMessages(format,
		map[string]string{
			"service":  "JobManager",
			"contains": "Success",
		})
	assert.NoError(err)
	assert.Len(msgs, 1)

	//for _, msg := range msgs {
	//log.Printf("%v\n", msg)
	//}

	msgs, err = client.GetFromMessages(format,
		map[string]string{
			"before": "1461181461",
			"after":  "1461181362",
		})

	assert.NoError(err)
	assert.Len(msgs, 4)

	//for _, msg := range msgs {
	//log.Printf("%v\n", msg)
	//}

}
<commit_msg>Fix test<commit_after>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package logger

import (
	"log"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
	"github.com/venicegeo/pz-gocommon/elasticsearch"
	piazza "github.com/venicegeo/pz-gocommon/gocommon"
)

const MOCKING = true

func sleep() {
	time.Sleep(1 * time.Second)
}

type LoggerTester struct {
	suite.Suite

	esi    elasticsearch.IIndex
	sys    *piazza.SystemConfig
	client IClient

	genericServer *piazza.GenericServer
}

func (suite *LoggerTester) setupFixture() {
	t := suite.T()
	assert := assert.New(t)

	var required []piazza.ServiceName
	if MOCKING {
		required = []piazza.ServiceName{}
	} else {
		required = []piazza.ServiceName{piazza.PzElasticSearch}
	}
	sys, err := piazza.NewSystemConfig(piazza.PzLogger, required)
	assert.NoError(err)
	suite.sys = sys

	esi, err := elasticsearch.NewIndexInterface(sys, "loggertest$", "", MOCKING)
	assert.NoError(err)
	suite.esi = esi

	if MOCKING {
		client, err := NewMockClient(sys)
		assert.NoError(err)
		suite.client = client
	} else {
		client, err := NewClient(sys)
		assert.NoError(err)
		suite.client = client
	}

	loggerService := &LoggerService{}
	loggerService.Init(sys, esi)

	loggerServer := &LoggerServer{}
	loggerServer.Init(loggerService)

	suite.genericServer = &piazza.GenericServer{Sys: sys}

	err = suite.genericServer.Configure(loggerServer.Routes)
	if err != nil {
		log.Fatal(err)
	}

	_, err = suite.genericServer.Start()
	assert.NoError(err)
}

func (suite *LoggerTester) teardownFixture() {
	suite.genericServer.Stop()

	suite.esi.Close()
	suite.esi.Delete()
}

func TestRunSuite(t *testing.T) {
	s := &LoggerTester{}
	suite.Run(t, s)
}

func (suite *LoggerTester) getLastMessage() string {
	t := suite.T()
	assert := assert.New(t)

	client := suite.client

	format := elasticsearch.QueryFormat{Size: 100, From: 0, Order: elasticsearch.SortAscending, Key: "CreatedOn"}
	ms, err := client.GetFromMessages(format, map[string]string{})
	assert.NoError(err)
	assert.True(len(ms) > 0)

	return ms[len(ms)-1].String()
}

func (suite *LoggerTester) Test01Elasticsearch() {
	t := suite.T()
	assert := assert.New(t)

	suite.setupFixture()
	defer suite.teardownFixture()

	version := suite.esi.GetVersion()
	assert.Contains("2.2.0", version)
}

func (suite *LoggerTester) Test02One() {
	t := suite.T()
	assert := assert.New(t)

	suite.setupFixture()
	defer suite.teardownFixture()

	client := suite.client

	var err error

	data1 := Message{
		Service:   "log-tester",
		Address:   "128.1.2.3",
		CreatedOn: time.Now(),
		Severity:  "Info",
		Message:   "The quick brown fox",
	}

	data2 := Message{
		Service:   "log-tester",
		Address:   "128.0.0.0",
		CreatedOn: time.Now(),
		Severity:  "Fatal",
		Message:   "The quick brown fox",
	}

	{
		err = client.LogMessage(&data1)
		assert.NoError(err, "PostToMessages")
	}

	sleep()

	{
		actualMssg := suite.getLastMessage()
		expectedMssg := data1.String()
		assert.EqualValues(actualMssg, expectedMssg)
	}

	{
		err = client.LogMessage(&data2)
		assert.NoError(err, "PostToMessages")
	}

	sleep()

	{
		actualMssg := suite.getLastMessage()
		expectedMssg := data2.String()
		assert.EqualValues(actualMssg, expectedMssg)
	}

	{
		stats, err := client.GetFromAdminStats()
		assert.NoError(err, "GetFromAdminStats")
		assert.Equal(2, stats.NumMessages, "stats check")
	}
}

func (suite *LoggerTester) Test03Help() {
	t := suite.T()
	assert := assert.New(t)

	err := suite.client.Log("mocktest", "0.0.0.0", SeverityInfo, time.Now(), "message from logger unit test via piazza.Log()")
	assert.NoError(err, "pzService.Log()")
}

func (suite *LoggerTester) Test04Admin() {
	t := suite.T()
	assert := assert.New(t)

	suite.setupFixture()
	defer suite.teardownFixture()

	client := suite.client

	_, err := client.GetFromAdminStats()
	assert.NoError(err, "GetFromAdminStats")
}

func (suite *LoggerTester) Test05Pagination() {
	t := suite.T()
	assert := assert.New(t)

	if MOCKING {
		//t.Skip("Skipping test, because mocking.")
	}

	suite.setupFixture()
	defer suite.teardownFixture()

	client := suite.client

	client.SetService("myservice", "1.2.3.4")

	err := client.Debug("d")
	assert.NoError(err)
	sleep()
	err = client.Info("i")
	assert.NoError(err)
	sleep()
	err = client.Warn("w")
	assert.NoError(err)
	sleep()
	err = client.Error("e")
	assert.NoError(err)
	sleep()
	err = client.Fatal("f")
	assert.NoError(err)
	sleep()

	format := elasticsearch.QueryFormat{Size: 1, From: 0, Key: "CreatedOn", Order: elasticsearch.SortAscending}
	ms, err := client.GetFromMessages(format, map[string]string{})
	assert.NoError(err)
	assert.Len(ms, 1)
	assert.EqualValues(SeverityDebug, ms[0].Severity)

	format = elasticsearch.QueryFormat{Size: 5, From: 0, Key: "CreatedOn", Order: elasticsearch.SortAscending}
	ms, err = client.GetFromMessages(format, map[string]string{})
	assert.NoError(err)
	assert.Len(ms, 5)
	assert.EqualValues(SeverityFatal, ms[4].Severity)

	format = elasticsearch.QueryFormat{Size: 3, From: 2, Key: "CreatedOn", Order: elasticsearch.SortDescending}
	ms, err = client.GetFromMessages(format, map[string]string{})
	assert.NoError(err)
	assert.Len(ms, 3)
	assert.EqualValues(SeverityWarning, ms[2].Severity)
	assert.EqualValues(SeverityError, ms[1].Severity)
	assert.EqualValues(SeverityFatal, ms[0].Severity)
}

func (suite *LoggerTester) Test06OtherParams() {
	t := suite.T()
	assert := assert.New(t)

	if MOCKING {
		t.Skip("Skipping test, because mocking.")
	}

	suite.setupFixture()
	defer suite.teardownFixture()

	client := suite.client

	client.SetService("myservice", "1.2.3.4")

	//sometime, err := time.Parse(time.RFC3339, "1985-04-12T23:20:50.52Z")
	//assert.NoError(err)
	sometime := time.Now()

	var testData = []Message{
		{
			Address:   "gnemud7smfv/10.254.0.66",
			Message:   "Received Message to Relay on topic Request-Job with key f3b63085-b482-4ae8-8297-3c7d1fcfff7d",
			Service:   "Dispatcher",
			Severity:  "Info",
			CreatedOn: sometime,
		}, {
			Address:   "gnfbnqsn5m9/10.254.0.14",
			Message:   "Processed Update Status for Job 6d0ea538-4382-4ea5-9669-56519b8c8f58 with Status Success",
			Service:   "JobManager",
			Severity:  "Info",
			CreatedOn: sometime,
		}, {
			Address:   "0.0.0.0",
			Message:   "generated 1: 09d4ec60-ea61-4066-8697-5568a47f84bf",
			Service:   "pz-uuidgen",
			Severity:  "Info",
			CreatedOn: sometime,
		}, {
			Address:   "gnfbnqsn5m9/10.254.0.14",
			Message:   "Handling Job with Topic Create-Job for Job ID 09d4ec60-ea61-4066-8697-5568a47f84bf",
			Service:   "JobManager",
			Severity:  "Info",
			CreatedOn: sometime,
		}, {
			Address:   "gnfbnqsn5m9/10.254.0.14",
			Message:   "Handling Job with Topic Update-Job for Job ID be4ce034-1187-4a4f-95a9-a9c31826248b",
			Service:   "JobManager",
			Severity:  "Info",
			CreatedOn: sometime,
		},
	}

	for _, e := range testData {
		// log.Printf("%d, %v\n", i, e)
		err := client.LogMessage(&e)
		assert.NoError(err)
	}

	sleep()

	format := elasticsearch.QueryFormat{
		Size: 100, From: 0,
		Order: elasticsearch.SortDescending,
		Key:   "CreatedOn"}

	msgs, err := client.GetFromMessages(format,
		map[string]string{
			"service":  "JobManager",
			"contains": "Success",
		})
	assert.NoError(err)
	assert.Len(msgs, 1)

	//for _, msg := range msgs {
	//log.Printf("%v\n", msg)
	//}

	msgs, err = client.GetFromMessages(format,
		map[string]string{
			"before": "1461181461",
			"after":  "1461181362",
		})

	assert.NoError(err)
	assert.Len(msgs, 4)

	//for _, msg := range msgs {
	//log.Printf("%v\n", msg)
	//}

}
<|endoftext|>


<commit_before>package toolbox_test

import (
	"fmt"
	"github.com/stretchr/testify/assert"
	"github.com/viant/toolbox"
	"testing"
)

func TestNewFileSetInfoInfo(t *testing.T) {

	fileSetInfo, err := toolbox.NewFileSetInfo("./fileset_info_test/")
	if err != nil {
		panic(err)
	}
	assert.Equal(t, 2, len(fileSetInfo.FilesInfo()))

	fileInfo := fileSetInfo.FileInfo("user_test.go")
	assert.NotNil(t, fileInfo)
	assert.False(t, fileInfo.HasStructInfo("F"))
	assert.True(t, fileInfo.HasStructInfo("User"))

	assert.Equal(t, 2, len(fileInfo.Structs()))

	address := fileSetInfo.Struct("Address")
	assert.NotNil(t, address)

	address2 := fileSetInfo.Struct("Address2")
	assert.Nil(t, address2)

	userInfo := fileInfo.Struct("User")
	assert.NotNil(t, userInfo)

	assert.True(t, userInfo.HasField("ID"))
	assert.True(t, userInfo.HasField("Name"))
	assert.False(t, userInfo.HasField("FF"))

	assert.Equal(t, 8, len(userInfo.Fields()))

	idInfo := userInfo.Field("ID")
	assert.True(t, idInfo.IsPointer)
	assert.Equal(t, "int", idInfo.TypeName)
	assert.Equal(t, true, idInfo.IsPointer)

	dobInfo := userInfo.Field("DateOfBirth")
	assert.True(t, dobInfo.IsStruct)
	assert.Equal(t, "time.Time", dobInfo.TypeName)
	assert.Equal(t, "time", dobInfo.TypePackage)

	assert.Equal(t, "`foo=\"bar\"`", dobInfo.Tag)

	addressPointer := userInfo.Field("AddressPointer")
	assert.NotNil(t, addressPointer)
	assert.Equal(t, true, addressPointer.IsStruct)
	assert.Equal(t, "Address", addressPointer.TypeName)

	cInfo := userInfo.Field("C")
	assert.True(t, cInfo.IsChannel)

	mInfo := userInfo.Field("M")
	assert.True(t, mInfo.IsMap)
	assert.Equal(t, "string", mInfo.KeyTypeName)
	assert.Equal(t, "[]string", mInfo.ValueTypeName)

	intsInfo := userInfo.Field("Ints")
	assert.True(t, intsInfo.IsSlice)
	assert.Equal(t, "my comments", userInfo.Comment)

	assert.False(t, userInfo.HasReceiver("Abc"))

	assert.Equal(t, 3, len(userInfo.Receivers()))
	assert.True(t, userInfo.HasReceiver("Test"))
	assert.True(t, userInfo.HasReceiver("Test2"))

	receiver := userInfo.Receiver("Test")
	assert.NotNil(t, receiver)

}
<commit_msg>patched test<commit_after>package toolbox_test

import (
	"github.com/stretchr/testify/assert"
	"github.com/viant/toolbox"
	"testing"
)

func TestNewFileSetInfoInfo(t *testing.T) {

	fileSetInfo, err := toolbox.NewFileSetInfo("./fileset_info_test/")
	if err != nil {
		panic(err)
	}
	assert.Equal(t, 2, len(fileSetInfo.FilesInfo()))

	fileInfo := fileSetInfo.FileInfo("user_test.go")
	assert.NotNil(t, fileInfo)
	assert.False(t, fileInfo.HasStructInfo("F"))
	assert.True(t, fileInfo.HasStructInfo("User"))

	assert.Equal(t, 2, len(fileInfo.Structs()))

	address := fileSetInfo.Struct("Address")
	assert.NotNil(t, address)

	address2 := fileSetInfo.Struct("Address2")
	assert.Nil(t, address2)

	userInfo := fileInfo.Struct("User")
	assert.NotNil(t, userInfo)

	assert.True(t, userInfo.HasField("ID"))
	assert.True(t, userInfo.HasField("Name"))
	assert.False(t, userInfo.HasField("FF"))

	assert.Equal(t, 8, len(userInfo.Fields()))

	idInfo := userInfo.Field("ID")
	assert.True(t, idInfo.IsPointer)
	assert.Equal(t, "int", idInfo.TypeName)
	assert.Equal(t, true, idInfo.IsPointer)

	dobInfo := userInfo.Field("DateOfBirth")
	assert.True(t, dobInfo.IsStruct)
	assert.Equal(t, "time.Time", dobInfo.TypeName)
	assert.Equal(t, "time", dobInfo.TypePackage)

	assert.Equal(t, "`foo=\"bar\"`", dobInfo.Tag)

	addressPointer := userInfo.Field("AddressPointer")
	assert.NotNil(t, addressPointer)
	assert.Equal(t, true, addressPointer.IsStruct)
	assert.Equal(t, "Address", addressPointer.TypeName)

	cInfo := userInfo.Field("C")
	assert.True(t, cInfo.IsChannel)

	mInfo := userInfo.Field("M")
	assert.True(t, mInfo.IsMap)
	assert.Equal(t, "string", mInfo.KeyTypeName)
	assert.Equal(t, "[]string", mInfo.ValueTypeName)

	intsInfo := userInfo.Field("Ints")
	assert.True(t, intsInfo.IsSlice)
	assert.Equal(t, "my comments", userInfo.Comment)

	assert.False(t, userInfo.HasReceiver("Abc"))

	assert.Equal(t, 3, len(userInfo.Receivers()))
	assert.True(t, userInfo.HasReceiver("Test"))
	assert.True(t, userInfo.HasReceiver("Test2"))

	receiver := userInfo.Receiver("Test")
	assert.NotNil(t, receiver)

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/DataDog/datadog-go/statsd"
	"github.com/gophr-pm/gophr/lib/config"
	"github.com/gophr-pm/gophr/lib/datadog"
	"github.com/gorilla/mux"
)

// DepotRequestHandlerArgs lol
type DepotRequestHandlerArgs struct {
	config        *config.Config
	dataDogClient datadog.Client
}

func main() {
	var (
		r        = mux.NewRouter()
		conf     = config.GetConfig()
		endpoint = fmt.Sprintf(
			"/repos/{%s}/{%s}/{%s}",
			urlVarAuthor,
			urlVarRepo,
			urlVarSHA)
	)

	// Initialize datadog client.
	dataDogClient, err := datadog.NewClient(conf, "depot.")
	if err != nil {
		log.Println(err)
	}

	// Register the status route.
	r.HandleFunc("/status", StatusHandler()).Methods("GET")
	// Register all the remaining routes for the main endpoint.
	r.HandleFunc(endpoint, RepoExistsHandler(conf, dataDogClient)).Methods("GET")
	r.HandleFunc(endpoint, CreateRepoHandler(conf, dataDogClient)).Methods("POST")
	r.HandleFunc(endpoint, DeleteRepoHandler(conf, dataDogClient)).Methods("DELETE")

	// Start tailing the nginx logs.
	if err := tailNginxLogs(); err != nil {
		log.Fatalln("Failed to start a tail on the nginx logs:", err)
	}

	// Start serving.
	log.Printf("Servicing HTTP requests on port %d.\n", conf.Port)
	http.ListenAndServe(fmt.Sprintf(":%d", conf.Port), r)
}
<commit_msg>fix broken import<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gophr-pm/gophr/lib/config"
	"github.com/gophr-pm/gophr/lib/datadog"
	"github.com/gorilla/mux"
)

// DepotRequestHandlerArgs lol
type DepotRequestHandlerArgs struct {
	config        *config.Config
	dataDogClient datadog.Client
}

func main() {
	var (
		r        = mux.NewRouter()
		conf     = config.GetConfig()
		endpoint = fmt.Sprintf(
			"/repos/{%s}/{%s}/{%s}",
			urlVarAuthor,
			urlVarRepo,
			urlVarSHA)
	)

	// Initialize datadog client.
	dataDogClient, err := datadog.NewClient(conf, "depot.")
	if err != nil {
		log.Println(err)
	}

	// Register the status route.
	r.HandleFunc("/status", StatusHandler()).Methods("GET")
	// Register all the remaining routes for the main endpoint.
	r.HandleFunc(endpoint, RepoExistsHandler(conf, dataDogClient)).Methods("GET")
	r.HandleFunc(endpoint, CreateRepoHandler(conf, dataDogClient)).Methods("POST")
	r.HandleFunc(endpoint, DeleteRepoHandler(conf, dataDogClient)).Methods("DELETE")

	// Start tailing the nginx logs.
	if err := tailNginxLogs(); err != nil {
		log.Fatalln("Failed to start a tail on the nginx logs:", err)
	}

	// Start serving.
	log.Printf("Servicing HTTP requests on port %d.\n", conf.Port)
	http.ListenAndServe(fmt.Sprintf(":%d", conf.Port), r)
}
<|endoftext|>


<commit_before>package pewpew

import (
	"reflect"
	"testing"
)

func TestParseKeyValString(t *testing.T) {
	cases := []struct {
		str    string
		delim1 string
		delim2 string
		want   map[string]string
		hasErr bool
	}{
		{"", "", "", map[string]string{}, true},
		{"", ":", ";", map[string]string{}, true},
		{"", ":", ":", map[string]string{}, true},
		{"abc:123;", ";", ":", map[string]string{"abc": "123"}, true},
		{"abc:123", ";", ":", map[string]string{"abc": "123"}, false},
		{"key1: val2, key3 : val4,key5:val6", ",", ":", map[string]string{"key1": "val2", "key3": "val4", "key5": "val6"}, false},
	}
	for _, c := range cases {
		result, err := parseKeyValString(c.str, c.delim1, c.delim2)
		if (err != nil) != c.hasErr {
			t.Errorf("parseKeyValString(%q, %q, %q) err: %t wanted %t", c.str, c.delim1, c.delim2, (err != nil), c.hasErr)
			continue
		}
		if err == nil && !reflect.DeepEqual(result, c.want) {
			t.Errorf("parseKeyValString(%q, %q, %q) == %v wanted %v", c.str, c.delim1, c.delim2, result, c.want)
		}
	}
}

func TestBuildRequest(t *testing.T) {
	cases := []struct {
		target Target
		hasErr bool
	}{
		{Target{}, true},                                 //empty url
		{Target{URL: ""}, true},                          //empty url
		{Target{URL: "", RegexURL: true}, true},          //empty regex url
		{Target{URL: "h"}, true},                         //hostname too short
		{Target{URL: "http://(*", RegexURL: true}, true}, //invalid regex
		{Target{URL: "http://///"}, true},                //invalid hostname
		{Target{URL: "http://%%%"}, true},                //net/url will fail parsing
		{Target{URL: "http://"}, true},                   //empty hostname
		{Target{URL: "http://localhost",
			BodyFilename: "/thisfiledoesnotexist"}, true}, //bad file
		{Target{URL: "http://localhost",
			Headers: ",,,"}, true}, //invalid headers
		{Target{URL: "http://localhost",
			Headers: "a:b,c,d"}, true}, //invalid headers
		{Target{URL: "http://localhost",
			Cookies: ";;;"}, true}, //invalid cookies
		{Target{URL: "http://localhost",
			Cookies: "a=b;c;d"}, true}, //invalid cookies
		{Target{URL: "http://localhost",
			BasicAuth: "user:"}, true}, //invalid basic auth
		{Target{URL: "http://localhost",
			BasicAuth: ":pass"}, true}, //invalid basic auth
		{Target{URL: "http://localhost",
			BasicAuth: "::"}, true}, //invalid basic auth
		{Target{URL: "http://localhost",
			Method: "@"}, true}, //invalid method

		//good cases
		{Target{URL: "localhost"}, false}, //missing scheme (http://) should be auto fixed
		{Target{URL: "http://localhost:80"}, false},
		{Target{URL: "http://localhost",
			Method: "POST",
			Body:   "data"}, false},
		{Target{URL: "https://www.github.com"}, false},
		{Target{URL: "http://github.com"}, false},
		{Target{URL: "http://localhost",
			BodyFilename: ""}, false},
		{Target{URL: "http://localhost",
			BodyFilename: tempFilename}, false},
		{Target{URL: "http://localhost:80/path/?param=val&another=one",
			Headers:   "Accept-Encoding:gzip, Content-Type:application/json",
			Cookies:   "a=b;c=d",
			UserAgent: "pewpewpew",
			BasicAuth: "user:pass"}, false},
	}
	for _, c := range cases {
		_, err := buildRequest(c.target)
		if (err != nil) != c.hasErr {
			t.Errorf("buildRequest(%+v) err: %t wanted: %t", c.target, (err != nil), c.hasErr)
		}
	}
}

func TestCreateClient(t *testing.T) {
	cases := []struct {
		target Target
	}{
		{Target{}}, //empty
		{Target{EnforceSSL: true}},
		{Target{EnforceSSL: false}},
		{Target{Compress: true}},
		{Target{Compress: false}},
		{Target{KeepAlive: true}},
		{Target{KeepAlive: false}},
		{Target{NoHTTP2: true}},
		{Target{NoHTTP2: false}},
		{Target{Timeout: ""}},
		{Target{Timeout: "1s"}},
		{Target{FollowRedirects: true}},
		{Target{FollowRedirects: false}},
	}
	for _, c := range cases {
		createClient(c.target)
	}
}
<commit_msg>Tests for DNS Prefetch (#24)<commit_after>package pewpew

import (
	"reflect"
	"testing"
)

func TestParseKeyValString(t *testing.T) {
	cases := []struct {
		str    string
		delim1 string
		delim2 string
		want   map[string]string
		hasErr bool
	}{
		{"", "", "", map[string]string{}, true},
		{"", ":", ";", map[string]string{}, true},
		{"", ":", ":", map[string]string{}, true},
		{"abc:123;", ";", ":", map[string]string{"abc": "123"}, true},
		{"abc:123", ";", ":", map[string]string{"abc": "123"}, false},
		{"key1: val2, key3 : val4,key5:val6", ",", ":", map[string]string{"key1": "val2", "key3": "val4", "key5": "val6"}, false},
	}
	for _, c := range cases {
		result, err := parseKeyValString(c.str, c.delim1, c.delim2)
		if (err != nil) != c.hasErr {
			t.Errorf("parseKeyValString(%q, %q, %q) err: %t wanted %t", c.str, c.delim1, c.delim2, (err != nil), c.hasErr)
			continue
		}
		if err == nil && !reflect.DeepEqual(result, c.want) {
			t.Errorf("parseKeyValString(%q, %q, %q) == %v wanted %v", c.str, c.delim1, c.delim2, result, c.want)
		}
	}
}

func TestBuildRequest(t *testing.T) {
	cases := []struct {
		target Target
		hasErr bool
	}{
		{Target{}, true},                                 //empty url
		{Target{URL: ""}, true},                          //empty url
		{Target{URL: "", RegexURL: true}, true},          //empty regex url
		{Target{URL: "h"}, true},                         //hostname too short
		{Target{URL: "http://(*", RegexURL: true}, true}, //invalid regex
		{Target{URL: "http://///"}, true},                //invalid hostname
		{Target{URL: "http://%%%"}, true},                //net/url will fail parsing
		{Target{URL: "http://"}, true},                   //empty hostname
		{Target{URL: "http://localhost",
			BodyFilename: "/thisfiledoesnotexist"}, true}, //bad file
		{Target{URL: "http://localhost",
			Headers: ",,,"}, true}, //invalid headers
		{Target{URL: "http://localhost",
			Headers: "a:b,c,d"}, true}, //invalid headers
		{Target{URL: "http://localhost",
			Cookies: ";;;"}, true}, //invalid cookies
		{Target{URL: "http://localhost",
			Cookies: "a=b;c;d"}, true}, //invalid cookies
		{Target{URL: "http://localhost",
			BasicAuth: "user:"}, true}, //invalid basic auth
		{Target{URL: "http://localhost",
			BasicAuth: ":pass"}, true}, //invalid basic auth
		{Target{URL: "http://localhost",
			BasicAuth: "::"}, true}, //invalid basic auth
		{Target{URL: "http://localhost",
			Method: "@"}, true}, //invalid method
		{Target{URL: "https://invaliddomain.invalidtld",
			DNSPrefetch: true}, true},

		//good cases
		{Target{URL: "localhost"}, false}, //missing scheme (http://) should be auto fixed
		{Target{URL: "http://localhost:80"}, false},
		{Target{URL: "http://localhost",
			Method: "POST",
			Body:   "data"}, false},
		{Target{URL: "https://www.github.com"}, false},
		{Target{URL: "http://github.com"}, false},
		{Target{URL: "https://www.github.com",
			DNSPrefetch: true}, false},
		{Target{URL: "http://localhost",
			BodyFilename: ""}, false},
		{Target{URL: "http://localhost",
			BodyFilename: tempFilename}, false},
		{Target{URL: "http://localhost:80/path/?param=val&another=one",
			Headers:   "Accept-Encoding:gzip, Content-Type:application/json",
			Cookies:   "a=b;c=d",
			UserAgent: "pewpewpew",
			BasicAuth: "user:pass"}, false},
	}
	for _, c := range cases {
		_, err := buildRequest(c.target)
		if (err != nil) != c.hasErr {
			t.Errorf("buildRequest(%+v) err: %t wanted: %t", c.target, (err != nil), c.hasErr)
		}
	}
}

func TestCreateClient(t *testing.T) {
	cases := []struct {
		target Target
	}{
		{Target{}}, //empty
		{Target{EnforceSSL: true}},
		{Target{EnforceSSL: false}},
		{Target{Compress: true}},
		{Target{Compress: false}},
		{Target{KeepAlive: true}},
		{Target{KeepAlive: false}},
		{Target{NoHTTP2: true}},
		{Target{NoHTTP2: false}},
		{Target{Timeout: ""}},
		{Target{Timeout: "1s"}},
		{Target{FollowRedirects: true}},
		{Target{FollowRedirects: false}},
	}
	for _, c := range cases {
		createClient(c.target)
	}
}
<|endoftext|>


<commit_before>package digitalocean

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/StackExchange/dnscontrol/models"
	"github.com/StackExchange/dnscontrol/providers"
	"github.com/StackExchange/dnscontrol/providers/diff"
	"github.com/miekg/dns/dnsutil"

	"github.com/digitalocean/godo"
	"golang.org/x/oauth2"
)

/*

Digitalocean API DNS provider:

Info required in `creds.json`:
   - token

*/

type DoApi struct {
	client *godo.Client
}

var defaultNameServerNames = []string{
	"ns1.digitalocean.com",
	"ns2.digitalocean.com",
	"ns3.digitalocean.com",
}

func newDo(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
	if m["token"] == "" {
		return nil, fmt.Errorf("Digitalocean Token must be provided.")
	}

	ctx := context.Background()
	oauthClient := oauth2.NewClient(
		ctx,
		oauth2.StaticTokenSource(&oauth2.Token{AccessToken: m["token"]}),
	)
	client := godo.NewClient(oauthClient)

	api := &DoApi{client: client}

	// Get a domain to validate the token
	_, resp, err := api.client.Domains.List(ctx, &godo.ListOptions{PerPage: 1})
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Digitalocean Token is not valid.")
	}

	return api, nil
}

var docNotes = providers.DocumentationNotes{
	providers.DocCreateDomains:       providers.Can(),
	providers.DocOfficiallySupported: providers.Cannot(),
}

func init() {
	providers.RegisterDomainServiceProviderType("DIGITALOCEAN", newDo, providers.CanUseSRV, docNotes)
}

func (api *DoApi) EnsureDomainExists(domain string) error {
	ctx := context.Background()
	_, resp, err := api.client.Domains.Get(ctx, domain)
	if resp.StatusCode == http.StatusNotFound {
		_, _, err := api.client.Domains.Create(ctx, &godo.DomainCreateRequest{
			Name:      domain,
			IPAddress: "",
		})
		return err
	} else {
		return err
	}
}

func (api *DoApi) GetNameservers(domain string) ([]*models.Nameserver, error) {
	return models.StringsToNameservers(defaultNameServerNames), nil
}

func (api *DoApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
	ctx := context.Background()
	dc.Punycode()

	records, err := getRecords(api, dc.Name)
	if err != nil {
		return nil, err
	}

	existingRecords := make([]*models.RecordConfig, len(records))
	for i := range records {
		existingRecords[i] = toRc(dc, &records[i])
	}

	differ := diff.New(dc)
	_, create, delete, modify := differ.IncrementalDiff(existingRecords)

	var corrections = []*models.Correction{}

	// Deletes first so changing type works etc.
	for _, m := range delete {
		id := m.Existing.Original.(*godo.DomainRecord).ID
		corr := &models.Correction{
			Msg: fmt.Sprintf("%s, DO ID: %d", m.String(), id),
			F: func() error {
				_, err := api.client.Domains.DeleteRecord(ctx, dc.Name, id)
				return err
			},
		}
		corrections = append(corrections, corr)
	}
	for _, m := range create {
		req := toReq(dc, m.Desired)
		corr := &models.Correction{
			Msg: m.String(),
			F: func() error {
				_, _, err := api.client.Domains.CreateRecord(ctx, dc.Name, req)
				return err
			},
		}
		corrections = append(corrections, corr)
	}
	for _, m := range modify {
		id := m.Existing.Original.(*godo.DomainRecord).ID
		req := toReq(dc, m.Desired)
		corr := &models.Correction{
			Msg: fmt.Sprintf("%s, DO ID: %d", m.String(), id),
			F: func() error {
				_, _, err := api.client.Domains.EditRecord(ctx, dc.Name, id, req)
				return err
			},
		}
		corrections = append(corrections, corr)
	}

	return corrections, nil
}

func getRecords(api *DoApi, name string) ([]godo.DomainRecord, error) {
	ctx := context.Background()

	records := []godo.DomainRecord{}
	opt := &godo.ListOptions{}
	for {
		result, resp, err := api.client.Domains.Records(ctx, name, opt)
		if err != nil {
			return nil, err
		}

		for _, d := range result {
			records = append(records, d)
		}

		if resp.Links == nil || resp.Links.IsLastPage() {
			break
		}

		page, err := resp.Links.CurrentPage()
		if err != nil {
			return nil, err
		}

		opt.Page = page + 1
	}

	return records, nil
}

func toRc(dc *models.DomainConfig, r *godo.DomainRecord) *models.RecordConfig {
	// This handles "@" etc.
	name := dnsutil.AddOrigin(r.Name, dc.Name)

	target := r.Data
	// Make target FQDN (#rtype_variations)
	if r.Type == "CNAME" || r.Type == "MX" || r.Type == "NS" || r.Type == "SRV" {
		// If target is the domainname, e.g. cname foo.example.com -> example.com,
		// DO returns "@" on read even if fqdn was written.
		if target == "@" {
			target = dc.Name
		}
		target = dnsutil.AddOrigin(target+".", dc.Name)
	}

	return &models.RecordConfig{
		NameFQDN:     name,
		Type:         r.Type,
		Target:       target,
		TTL:          uint32(r.TTL),
		MxPreference: uint16(r.Priority),
		SrvPriority:  uint16(r.Priority),
		SrvWeight:    uint16(r.Weight),
		SrvPort:      uint16(r.Port),
		Original:     r,
	}
}

func toReq(dc *models.DomainConfig, rc *models.RecordConfig) *godo.DomainRecordEditRequest {
	// DO wants the short name, e.g. @
	name := dnsutil.TrimDomainName(rc.NameFQDN, dc.Name)

	// DO uses the same property for MX and SRV priority
	priority := 0
	switch rc.Type { // #rtype_variations
	case "MX":
		priority = int(rc.MxPreference)
	case "SRV":
		priority = int(rc.SrvPriority)
	}

	return &godo.DomainRecordEditRequest{
		Type:     rc.Type,
		Name:     name,
		Data:     rc.Target,
		TTL:      int(rc.TTL),
		Priority: priority,
		Port:     int(rc.SrvPort),
		Weight:   int(rc.SrvWeight),
	}
}
<commit_msg>export newdo<commit_after>package digitalocean

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/StackExchange/dnscontrol/models"
	"github.com/StackExchange/dnscontrol/providers"
	"github.com/StackExchange/dnscontrol/providers/diff"
	"github.com/miekg/dns/dnsutil"

	"github.com/digitalocean/godo"
	"golang.org/x/oauth2"
)

/*

Digitalocean API DNS provider:

Info required in `creds.json`:
   - token

*/

type DoApi struct {
	client *godo.Client
}

var defaultNameServerNames = []string{
	"ns1.digitalocean.com",
	"ns2.digitalocean.com",
	"ns3.digitalocean.com",
}

func NewDo(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
	if m["token"] == "" {
		return nil, fmt.Errorf("Digitalocean Token must be provided.")
	}

	ctx := context.Background()
	oauthClient := oauth2.NewClient(
		ctx,
		oauth2.StaticTokenSource(&oauth2.Token{AccessToken: m["token"]}),
	)
	client := godo.NewClient(oauthClient)

	api := &DoApi{client: client}

	// Get a domain to validate the token
	_, resp, err := api.client.Domains.List(ctx, &godo.ListOptions{PerPage: 1})
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Digitalocean Token is not valid.")
	}

	return api, nil
}

var docNotes = providers.DocumentationNotes{
	providers.DocCreateDomains:       providers.Can(),
	providers.DocOfficiallySupported: providers.Cannot(),
}

func init() {
	providers.RegisterDomainServiceProviderType("DIGITALOCEAN", NewDo, providers.CanUseSRV, docNotes)
}

func (api *DoApi) EnsureDomainExists(domain string) error {
	ctx := context.Background()
	_, resp, err := api.client.Domains.Get(ctx, domain)
	if resp.StatusCode == http.StatusNotFound {
		_, _, err := api.client.Domains.Create(ctx, &godo.DomainCreateRequest{
			Name:      domain,
			IPAddress: "",
		})
		return err
	} else {
		return err
	}
}

func (api *DoApi) GetNameservers(domain string) ([]*models.Nameserver, error) {
	return models.StringsToNameservers(defaultNameServerNames), nil
}

func (api *DoApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
	ctx := context.Background()
	dc.Punycode()

	records, err := getRecords(api, dc.Name)
	if err != nil {
		return nil, err
	}

	existingRecords := make([]*models.RecordConfig, len(records))
	for i := range records {
		existingRecords[i] = toRc(dc, &records[i])
	}

	differ := diff.New(dc)
	_, create, delete, modify := differ.IncrementalDiff(existingRecords)

	var corrections = []*models.Correction{}

	// Deletes first so changing type works etc.
	for _, m := range delete {
		id := m.Existing.Original.(*godo.DomainRecord).ID
		corr := &models.Correction{
			Msg: fmt.Sprintf("%s, DO ID: %d", m.String(), id),
			F: func() error {
				_, err := api.client.Domains.DeleteRecord(ctx, dc.Name, id)
				return err
			},
		}
		corrections = append(corrections, corr)
	}
	for _, m := range create {
		req := toReq(dc, m.Desired)
		corr := &models.Correction{
			Msg: m.String(),
			F: func() error {
				_, _, err := api.client.Domains.CreateRecord(ctx, dc.Name, req)
				return err
			},
		}
		corrections = append(corrections, corr)
	}
	for _, m := range modify {
		id := m.Existing.Original.(*godo.DomainRecord).ID
		req := toReq(dc, m.Desired)
		corr := &models.Correction{
			Msg: fmt.Sprintf("%s, DO ID: %d", m.String(), id),
			F: func() error {
				_, _, err := api.client.Domains.EditRecord(ctx, dc.Name, id, req)
				return err
			},
		}
		corrections = append(corrections, corr)
	}

	return corrections, nil
}

func getRecords(api *DoApi, name string) ([]godo.DomainRecord, error) {
	ctx := context.Background()

	records := []godo.DomainRecord{}
	opt := &godo.ListOptions{}
	for {
		result, resp, err := api.client.Domains.Records(ctx, name, opt)
		if err != nil {
			return nil, err
		}

		for _, d := range result {
			records = append(records, d)
		}

		if resp.Links == nil || resp.Links.IsLastPage() {
			break
		}

		page, err := resp.Links.CurrentPage()
		if err != nil {
			return nil, err
		}

		opt.Page = page + 1
	}

	return records, nil
}

func toRc(dc *models.DomainConfig, r *godo.DomainRecord) *models.RecordConfig {
	// This handles "@" etc.
	name := dnsutil.AddOrigin(r.Name, dc.Name)

	target := r.Data
	// Make target FQDN (#rtype_variations)
	if r.Type == "CNAME" || r.Type == "MX" || r.Type == "NS" || r.Type == "SRV" {
		// If target is the domainname, e.g. cname foo.example.com -> example.com,
		// DO returns "@" on read even if fqdn was written.
		if target == "@" {
			target = dc.Name
		}
		target = dnsutil.AddOrigin(target+".", dc.Name)
	}

	return &models.RecordConfig{
		NameFQDN:     name,
		Type:         r.Type,
		Target:       target,
		TTL:          uint32(r.TTL),
		MxPreference: uint16(r.Priority),
		SrvPriority:  uint16(r.Priority),
		SrvWeight:    uint16(r.Weight),
		SrvPort:      uint16(r.Port),
		Original:     r,
	}
}

func toReq(dc *models.DomainConfig, rc *models.RecordConfig) *godo.DomainRecordEditRequest {
	// DO wants the short name, e.g. @
	name := dnsutil.TrimDomainName(rc.NameFQDN, dc.Name)

	// DO uses the same property for MX and SRV priority
	priority := 0
	switch rc.Type { // #rtype_variations
	case "MX":
		priority = int(rc.MxPreference)
	case "SRV":
		priority = int(rc.SrvPriority)
	}

	return &godo.DomainRecordEditRequest{
		Type:     rc.Type,
		Name:     name,
		Data:     rc.Target,
		TTL:      int(rc.TTL),
		Priority: priority,
		Port:     int(rc.SrvPort),
		Weight:   int(rc.SrvWeight),
	}
}
<|endoftext|>


<commit_before>package app

type notFound struct {
	Compo
	Icon string
}

func (n *notFound) OnMount() {
	links := Window().Get("document").Call("getElementsByTagName", "link")

	for i := 0; i < links.Length(); i++ {
		link := links.Index(i)
		rel := link.Call("getAttribute", "rel")

		if rel.String() == "icon" {
			favicon := link.Call("getAttribute", "href")
			n.Icon = favicon.String()
			n.Update()
			return
		}
	}
}

func (n *notFound) Render() UI {
	return Div().
		Class("app-wasm-layout").
		Body(
			Div().
				Class("app-notfound-title").
				Body(
					Text("4"),
					Img().
						Class("app-wasm-icon").
						Alt("0").
						Src(n.Icon),
					Text("4"),
				),
			P().
				Class("app-wasm-label").
				Text("Not Found"),
		)
}
<commit_msg>Update notfound.go<commit_after>package app

var (
	// NotFound is the ui element that is displayed when a request is not
	// routed.
	NotFound UI = &notFound{}
)

type notFound struct {
	Compo
	Icon string
}

func (n *notFound) OnMount() {
	links := Window().Get("document").Call("getElementsByTagName", "link")

	for i := 0; i < links.Length(); i++ {
		link := links.Index(i)
		rel := link.Call("getAttribute", "rel")

		if rel.String() == "icon" {
			favicon := link.Call("getAttribute", "href")
			n.Icon = favicon.String()
			n.Update()
			return
		}
	}
}

func (n *notFound) Render() UI {
	return Div().
		Class("app-wasm-layout").
		Body(
			Div().
				Class("app-notfound-title").
				Body(
					Text("4"),
					Img().
						Class("app-wasm-icon").
						Alt("0").
						Src(n.Icon),
					Text("4"),
				),
			P().
				Class("app-wasm-label").
				Text("Not Found"),
		)
}
<|endoftext|>


<commit_before>// Copyright 2015 The Serviced Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dfs

import (
	"archive/tar"
	"bytes"
	"encoding/json"
	"io"
	"path"
	"time"

	"github.com/control-center/serviced/commons/docker"
	"github.com/control-center/serviced/dfs/utils"
	"github.com/zenoss/glog"
)

const (
	BackupMetadataFile   = ".BACKUPINFO"
	SnapshotsMetadataDir = "SNAPSHOTS/"
	DockerImagesFile     = "IMAGES.dkr"
)

// Backup writes all application data into an export stream
func (dfs *DistributedFilesystem) Backup(data BackupInfo, w io.Writer) error {
	tarfile := tar.NewWriter(w)
	defer tarfile.Close()
	buffer := bytes.NewBufferString("")
	spool, err := utils.NewSpool(dfs.tmp)
	if err != nil {
		glog.Errorf("Could not create spool: %s", err)
		return err
	}
	defer spool.Remove()
	// write the backup metadata
	glog.Infof("Writing backup metadata")
	if err := json.NewEncoder(buffer).Encode(data); err != nil {
		glog.Errorf("Could not encode backup metadata: %s", err)
		return err
	}
	header := &tar.Header{Name: BackupMetadataFile, Size: int64(buffer.Len())}
	if err := tarfile.WriteHeader(header); err != nil {
		glog.Errorf("Could not create metadata header for backup: %s", err)
		return err
	}
	if _, err := buffer.WriteTo(tarfile); err != nil {
		glog.Errorf("Could not write backup metadata: %s", err)
		return err
	}
	// download the base images
	for _, image := range data.BaseImages {
		if _, err := dfs.docker.FindImage(image); docker.IsImageNotFound(err) {
			if err := dfs.docker.PullImage(image); err != nil {
				glog.Errorf("Could not pull image %s: %s", image, err)
				return err
			}
		} else if err != nil {
			glog.Errorf("Could not find image %s: %s", image, err)
			return err
		}
	}
	images := data.BaseImages
	// export the snapshots
	for _, snapshot := range data.Snapshots {
		vol, info, err := dfs.getSnapshotVolumeAndInfo(snapshot)
		if err != nil {
			return err
		}
		// load the images from this snapshot
		glog.Infof("Preparing images for tenant %s", info.TenantID)
		r, err := vol.ReadMetadata(info.Label, ImagesMetadataFile)
		if err != nil {
			glog.Errorf("Could not receive images metadata for tenant %s: %s", info.TenantID, err)
			return err
		}
		var imgs []string
		if err := importJSON(r, &imgs); err != nil {
			glog.Errorf("Could not interpret images metadata for tenant %s: %s", info.TenantID, err)
			return err
		}
		timer := time.NewTimer(0)
		for _, img := range imgs {
			timer.Reset(30 * time.Minute)
			if err := dfs.reg.PullImage(timer.C, img); err != nil {
				glog.Errorf("Could not pull image %s from registry: %s", img, err)
				return err
			}
			image, err := dfs.reg.ImagePath(img)
			if err != nil {
				glog.Errorf("Could not get the image path from registry %s: %s", img, err)
				return err
			}
			images = append(images, image)
		}
		timer.Stop()
		// export the snapshot
		if err := vol.Export(info.Label, "", spool); err != nil {
			glog.Errorf("Could not export tenant %s: %s", info.TenantID, err)
			return err
		}
		glog.Infof("Exporting tenant volume %s", info.TenantID)
		header := &tar.Header{Name: path.Join(SnapshotsMetadataDir, info.TenantID, info.Label), Size: spool.Size()}
		if err := tarfile.WriteHeader(header); err != nil {
			glog.Errorf("Could not create header for tenant %s: %s", info.TenantID, err)
			return err
		}
		if _, err := spool.WriteTo(tarfile); err != nil {
			glog.Errorf("Could not write tenant %s to backup: %s", info.TenantID, err)
			return err
		}
		glog.Infof("Finished exporting tenant volume %s", info.TenantID)
	}
	// export the images
	glog.Infof("Saving images to backup")
	if err := dfs.docker.SaveImages(images, spool); err != nil {
		glog.Errorf("Could not save images to backup: %s", err)
		return err
	}
	header = &tar.Header{Name: DockerImagesFile, Size: spool.Size()}
	if err := tarfile.WriteHeader(header); err != nil {
		glog.Errorf("Could not create docker images header for backup: %s", err)
		return err
	}
	if _, err := spool.WriteTo(tarfile); err != nil {
		glog.Errorf("Could not write docker images: %s", err)
		return err
	}
	glog.Infof("Successfully completed backup")
	return nil
}
<commit_msg>using configured timeout as pull timeout during backups<commit_after>// Copyright 2015 The Serviced Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dfs

import (
	"archive/tar"
	"bytes"
	"encoding/json"
	"io"
	"path"
	"time"

	"github.com/control-center/serviced/commons/docker"
	"github.com/control-center/serviced/dfs/utils"
	"github.com/zenoss/glog"
)

const (
	BackupMetadataFile   = ".BACKUPINFO"
	SnapshotsMetadataDir = "SNAPSHOTS/"
	DockerImagesFile     = "IMAGES.dkr"
)

// Backup writes all application data into an export stream
func (dfs *DistributedFilesystem) Backup(data BackupInfo, w io.Writer) error {
	tarfile := tar.NewWriter(w)
	defer tarfile.Close()
	buffer := bytes.NewBufferString("")
	spool, err := utils.NewSpool(dfs.tmp)
	if err != nil {
		glog.Errorf("Could not create spool: %s", err)
		return err
	}
	defer spool.Remove()
	// write the backup metadata
	glog.Infof("Writing backup metadata")
	if err := json.NewEncoder(buffer).Encode(data); err != nil {
		glog.Errorf("Could not encode backup metadata: %s", err)
		return err
	}
	header := &tar.Header{Name: BackupMetadataFile, Size: int64(buffer.Len())}
	if err := tarfile.WriteHeader(header); err != nil {
		glog.Errorf("Could not create metadata header for backup: %s", err)
		return err
	}
	if _, err := buffer.WriteTo(tarfile); err != nil {
		glog.Errorf("Could not write backup metadata: %s", err)
		return err
	}
	// download the base images
	for _, image := range data.BaseImages {
		if _, err := dfs.docker.FindImage(image); docker.IsImageNotFound(err) {
			if err := dfs.docker.PullImage(image); err != nil {
				glog.Errorf("Could not pull image %s: %s", image, err)
				return err
			}
		} else if err != nil {
			glog.Errorf("Could not find image %s: %s", image, err)
			return err
		}
	}
	images := data.BaseImages
	// export the snapshots
	for _, snapshot := range data.Snapshots {
		vol, info, err := dfs.getSnapshotVolumeAndInfo(snapshot)
		if err != nil {
			return err
		}
		// load the images from this snapshot
		glog.Infof("Preparing images for tenant %s", info.TenantID)
		r, err := vol.ReadMetadata(info.Label, ImagesMetadataFile)
		if err != nil {
			glog.Errorf("Could not receive images metadata for tenant %s: %s", info.TenantID, err)
			return err
		}
		var imgs []string
		if err := importJSON(r, &imgs); err != nil {
			glog.Errorf("Could not interpret images metadata for tenant %s: %s", info.TenantID, err)
			return err
		}
		timer := time.NewTimer(0)
		for _, img := range imgs {
			timer.Reset(dfs.timeout)
			if err := dfs.reg.PullImage(timer.C, img); err != nil {
				glog.Errorf("Could not pull image %s from registry: %s", img, err)
				return err
			}
			image, err := dfs.reg.ImagePath(img)
			if err != nil {
				glog.Errorf("Could not get the image path from registry %s: %s", img, err)
				return err
			}
			images = append(images, image)
		}
		timer.Stop()
		// export the snapshot
		if err := vol.Export(info.Label, "", spool); err != nil {
			glog.Errorf("Could not export tenant %s: %s", info.TenantID, err)
			return err
		}
		glog.Infof("Exporting tenant volume %s", info.TenantID)
		header := &tar.Header{Name: path.Join(SnapshotsMetadataDir, info.TenantID, info.Label), Size: spool.Size()}
		if err := tarfile.WriteHeader(header); err != nil {
			glog.Errorf("Could not create header for tenant %s: %s", info.TenantID, err)
			return err
		}
		if _, err := spool.WriteTo(tarfile); err != nil {
			glog.Errorf("Could not write tenant %s to backup: %s", info.TenantID, err)
			return err
		}
		glog.Infof("Finished exporting tenant volume %s", info.TenantID)
	}
	// export the images
	glog.Infof("Saving images to backup")
	if err := dfs.docker.SaveImages(images, spool); err != nil {
		glog.Errorf("Could not save images to backup: %s", err)
		return err
	}
	header = &tar.Header{Name: DockerImagesFile, Size: spool.Size()}
	if err := tarfile.WriteHeader(header); err != nil {
		glog.Errorf("Could not create docker images header for backup: %s", err)
		return err
	}
	if _, err := spool.WriteTo(tarfile); err != nil {
		glog.Errorf("Could not write docker images: %s", err)
		return err
	}
	glog.Infof("Successfully completed backup")
	return nil
}
<|endoftext|>