[ARVADOS] created: 8626abb0a44cfc303bef3552a7bc57163c79231a

git at public.curoverse.com git at public.curoverse.com
Tue Sep 22 19:55:02 EDT 2015


        at  8626abb0a44cfc303bef3552a7bc57163c79231a (commit)


commit 8626abb0a44cfc303bef3552a7bc57163c79231a
Author: Tom Clegg <tom at curoverse.com>
Date:   Tue Sep 22 19:54:12 2015 -0400

    7241: Add AzureBlobVolume

diff --git a/services/keepstore/azure_blob_volume.go b/services/keepstore/azure_blob_volume.go
new file mode 100644
index 0000000..b1d528d
--- /dev/null
+++ b/services/keepstore/azure_blob_volume.go
@@ -0,0 +1,83 @@
+package main
+
+import (
+	"fmt"
+	"io"
+	"time"
+
+	"github.com/Azure/azure-sdk-for-go/storage"
+)
+
+// An AzureBlobVolume stores and retrieves blocks in an Azure Blob
+// container.
+type AzureBlobVolume struct {
+	azClient      storage.Client
+	bsClient      storage.BlobStorageClient
+	containerName string
+	readonly      bool
+}
+
+func NewAzureBlobVolume(client storage.Client, containerName string, readonly bool) *AzureBlobVolume {
+	return &AzureBlobVolume{
+		azClient: client,
+		bsClient: client.GetBlobService(),
+		containerName: containerName,
+		readonly: readonly,
+	}
+}
+
+func (v *AzureBlobVolume) Get(loc string) ([]byte, error) {
+	rdr, err := v.bsClient.GetBlob(v.containerName, loc)
+	if err != nil {
+		return nil, err
+	}
+	buf := bufs.Get(BlockSize)
+	n, err := io.ReadFull(rdr, buf)
+	switch err {
+	case io.EOF, io.ErrUnexpectedEOF:
+		return buf[:n], nil
+	default:
+		bufs.Put(buf)
+		return nil, err
+	}
+}
+
+func (v *AzureBlobVolume) Compare(loc string, data []byte) error {
+	return NotFoundError
+}
+
+func (v *AzureBlobVolume) Put(loc string, block []byte) error {
+	return NotFoundError
+}
+
+func (v *AzureBlobVolume) Touch(loc string) error {
+	return NotFoundError
+}
+
+func (v *AzureBlobVolume) Mtime(loc string) (time.Time, error) {
+	return time.Time{}, NotFoundError
+}
+
+func (v *AzureBlobVolume) IndexTo(prefix string, writer io.Writer) error {
+	return nil
+}
+
+func (v *AzureBlobVolume) Delete(loc string) error {
+	return NotFoundError
+}
+
+func (v *AzureBlobVolume) Status() *VolumeStatus {
+	return &VolumeStatus{
+		DeviceNum: 1,
+		BytesFree: BlockSize * 1000,
+		BytesUsed: 1,
+	}
+}
+
+func (v *AzureBlobVolume) String() string {
+	return fmt.Sprintf("%+v", v.azClient)
+}
+
+func (v *AzureBlobVolume) Writable() bool {
+	return !v.readonly
+}
diff --git a/services/keepstore/azure_blob_volume_test.go b/services/keepstore/azure_blob_volume_test.go
new file mode 100644
index 0000000..59021c0
--- /dev/null
+++ b/services/keepstore/azure_blob_volume_test.go
@@ -0,0 +1,100 @@
+package main
+
+import (
+	"log"
+	"net"
+	"net/http"
+	"net/http/httptest"
+	"regexp"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/Azure/azure-sdk-for-go/storage"
+)
+
+const (
+	// The same fake credentials used by Microsoft's Azure emulator
+	emulatorAccountName = "devstoreaccount1"
+	emulatorAccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
+)
+
+type azStubHandler struct {}
+
+func (azStubHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
+}
+
+// azStubDialer is a net.Dialer that notices when the Azure driver
+// tries to connect to "devstoreaccount1.blob.127.0.0.1:46067", and
+// in such cases transparently dials "127.0.0.1:46067" instead.
+type azStubDialer struct {
+	net.Dialer
+}
+
+var localHostPortRe = regexp.MustCompile(`(127\.0\.0\.1|localhost|\[::1\]):\d+`)
+func (d *azStubDialer) Dial(network, address string) (net.Conn, error) {
+	if hp := localHostPortRe.FindString(address); hp != "" {
+		log.Println("custom dialer: dial", hp, "instead of", address)
+		address = hp
+	}
+	return d.Dialer.Dial(network, address)
+}
+
+type TestableAzureBlobVolume struct {
+	*AzureBlobVolume
+	azStub *httptest.Server
+	t      *testing.T
+}
+
+func NewTestableAzureBlobVolume(t *testing.T, readonly bool) *TestableAzureBlobVolume {
+	azStub := httptest.NewServer(azStubHandler{})
+
+	stubURLBase := strings.Split(azStub.URL, "://")[1]
+	azClient, err := storage.NewClient(emulatorAccountName, emulatorAccountKey, stubURLBase, storage.DefaultAPIVersion, false)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	v := NewAzureBlobVolume(azClient, "fakecontainername", readonly)
+
+	return &TestableAzureBlobVolume{
+		AzureBlobVolume: v,
+		azStub: azStub,
+		t: t,
+	}
+}
+
+func TestAzureBlobVolumeWithGeneric(t *testing.T) {
+	defer func(t http.RoundTripper) {
+		http.DefaultTransport = t
+	}(http.DefaultTransport)
+	http.DefaultTransport = &http.Transport{
+		Dial: (&azStubDialer{}).Dial,
+	}
+	DoGenericVolumeTests(t, func(t *testing.T) TestableVolume {
+		return NewTestableAzureBlobVolume(t, false)
+	})
+}
+
+func TestReadonlyAzureBlobVolumeWithGeneric(t *testing.T) {
+	defer func(t http.RoundTripper) {
+		http.DefaultTransport = t
+	}(http.DefaultTransport)
+	http.DefaultTransport = &http.Transport{
+		Dial: (&azStubDialer{}).Dial,
+	}
+	DoGenericVolumeTests(t, func(t *testing.T) TestableVolume {
+		return NewTestableAzureBlobVolume(t, true)
+	})
+}
+
+func (v *TestableAzureBlobVolume) PutRaw(locator string, data []byte) {
+	v.Put(locator, data)
+}
+
+func (v *TestableAzureBlobVolume) TouchWithDate(locator string, lastPut time.Time) {
+}
+
+func (v *TestableAzureBlobVolume) Teardown() {
+	v.azStub.Close()
+}
diff --git a/services/keepstore/volume_generic_test.go b/services/keepstore/volume_generic_test.go
index 193d9d2..b64f345 100644
--- a/services/keepstore/volume_generic_test.go
+++ b/services/keepstore/volume_generic_test.go
@@ -61,7 +61,7 @@ func testGet(t *testing.T, factory TestableVolumeFactory) {
 
 	buf, err := v.Get(TestHash)
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 
 	bufs.Put(buf)
@@ -397,7 +397,7 @@ func testDeleteOldBlock(t *testing.T, factory TestableVolumeFactory) {
 		t.Error(err)
 	}
 	if _, err := v.Get(TestHash); err == nil || !os.IsNotExist(err) {
-		t.Errorf("os.IsNotExist(%v) should have been true", err.Error())
+		t.Errorf("os.IsNotExist(%v) should have been true", err)
 	}
 }
 

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list