summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarin Ivanov <[email protected]>2022-08-15 00:15:04 +0300
committerMarin Ivanov <[email protected]>2022-08-15 00:15:04 +0300
commitb135dcf644394394e3250188dea39ff4e91f0e06 (patch)
treefa5946e5ee66c39fde185dc145274c4e85d36d51
parentde77a507ecfe16a9538b20c66ca075a7f780428b (diff)
Add Fs.Open() and read file test
-rw-r--r--file.go24
-rw-r--r--fs.go19
-rw-r--r--fs_test.go13
3 files changed, 48 insertions, 8 deletions
diff --git a/file.go b/file.go
index c20ab62..2498bd8 100644
--- a/file.go
+++ b/file.go
@@ -1,21 +1,29 @@
package s3
import (
+ "context"
+ "io"
"os"
+ "path"
)
type File struct {
- name string
+ fs *Fs
+ key string
+ r io.ReadCloser
+ w io.WriteCloser
+ cancel context.CancelFunc
}
// implements io.Closer
func (f *File) Close() error {
- panic("not implemented")
+ f.cancel()
+ return nil
}
// implements io.Reader
func (f *File) Read(b []byte) (int, error) {
- panic("not implemented")
+ return f.r.Read(b)
}
// implements io.ReaderAt
@@ -25,7 +33,7 @@ func (f *File) ReadAt(p []byte, off int64) (int, error) {
// implements io.Writer
func (f *File) Write(p []byte) (int, error) {
- panic("not implemented")
+ return f.w.Write(p)
}
// implements io.WriterAt
@@ -34,7 +42,7 @@ func (f *File) WriteAt(p []byte, off int64) (int, error) {
}
func (f *File) Name() string {
- return f.name
+ return path.Base(f.key)
}
func (f *File) Readdir(count int) ([]os.FileInfo, error) {
@@ -45,10 +53,14 @@ func (f *File) Readdirnames(n int) ([]string, error) {
panic("not implemented")
}
-func (f *File) Stat() (os.FileInfo, error) {
+func (f *File) Seek(offset int64, whence int) (int64, error) {
panic("not implemented")
}
+func (f *File) Stat() (os.FileInfo, error) {
+ return f.fs.Stat(f.key)
+}
+
func (f *File) Sync() error {
panic("not implemented")
}
diff --git a/fs.go b/fs.go
index a4a1831..2b2e876 100644
--- a/fs.go
+++ b/fs.go
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
+ "io"
neturl "net/url"
"os"
"strings"
@@ -91,8 +92,13 @@ func (fs *Fs) MkdirAll(path string, perm os.FileMode) error {
}
// Open opens a file, returning it or an error, if any happens.
-func (fs *Fs) Open(name string) (File, error) {
- panic("not implemented")
+func (fs *Fs) Open(name string) (afero.File, error) {
+ ctx, cancel := fs.contextWithTimeout()
+ obj, err := fs.client.GetObject(ctx, fs.bucket, name, minio.GetObjectOptions{})
+ if err != nil {
+ return nil, err
+ }
+ return fs.newObjectReader(name, obj, cancel), nil
}
// OpenFile opens a file using the given flags and the given mode.
@@ -181,6 +187,15 @@ func (fs *Fs) contextWithTimeout() (context.Context, context.CancelFunc) {
return context.WithTimeout(context.Background(), fs.Timeout)
}
+func (fs *Fs) newObjectReader(key string, r io.ReadCloser, cancel context.CancelFunc) *File {
+ return &File{
+ fs: fs,
+ key: key,
+ r: r,
+ cancel: cancel,
+ }
+}
+
func transformError(err error) error {
resp, ok := err.(minio.ErrorResponse)
if !ok {
diff --git a/fs_test.go b/fs_test.go
index f8b7db0..f993849 100644
--- a/fs_test.go
+++ b/fs_test.go
@@ -1,6 +1,7 @@
package s3
import (
+ "io"
"testing"
"time"
@@ -75,6 +76,18 @@ func TestFsStatNoExist(t *testing.T) {
is.Equal(err, afero.ErrFileNotFound)
}
+func TestFsOpenRead(t *testing.T) {
+ is := is.New(t)
+ fs, err := newTestFs()
+ is.NoErr(err)
+ f, err := fs.Open("dir/file")
+ is.NoErr(err)
+ defer f.Close()
+ b, err := io.ReadAll(f)
+ is.NoErr(err)
+ is.Equal(b, []byte("test"))
+}
+
func newTestFs() (*Fs, error) {
fs, err := NewFsFromURL("http://testuser:[email protected]:9000/test-bucket")
return fs, err