Add unit test cases
This commit is contained in:
parent
d000984c4d
commit
60ed368ea6
12 changed files with 134 additions and 27 deletions
|
@ -37,7 +37,7 @@ func TestBucketViewHandler(t *testing.T) {
|
||||||
Buckets: []minio.BucketInfo{
|
Buckets: []minio.BucketInfo{
|
||||||
{Name: "testBucket"},
|
{Name: "testBucket"},
|
||||||
},
|
},
|
||||||
ObjectInfos: []minio.ObjectInfo{
|
Objects: []minio.ObjectInfo{
|
||||||
{Key: "testFile"},
|
{Key: "testFile"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -50,7 +50,7 @@ func TestBucketViewHandler(t *testing.T) {
|
||||||
Buckets: []minio.BucketInfo{
|
Buckets: []minio.BucketInfo{
|
||||||
{Name: "testBucket"},
|
{Name: "testBucket"},
|
||||||
},
|
},
|
||||||
ObjectInfos: []minio.ObjectInfo{
|
Objects: []minio.ObjectInfo{
|
||||||
{Key: "archive.tar.gz"},
|
{Key: "archive.tar.gz"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -63,7 +63,7 @@ func TestBucketViewHandler(t *testing.T) {
|
||||||
Buckets: []minio.BucketInfo{
|
Buckets: []minio.BucketInfo{
|
||||||
{Name: "testBucket"},
|
{Name: "testBucket"},
|
||||||
},
|
},
|
||||||
ObjectInfos: []minio.ObjectInfo{
|
Objects: []minio.ObjectInfo{
|
||||||
{Key: "testImage.png"},
|
{Key: "testImage.png"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -76,7 +76,7 @@ func TestBucketViewHandler(t *testing.T) {
|
||||||
Buckets: []minio.BucketInfo{
|
Buckets: []minio.BucketInfo{
|
||||||
{Name: "testBucket"},
|
{Name: "testBucket"},
|
||||||
},
|
},
|
||||||
ObjectInfos: []minio.ObjectInfo{
|
Objects: []minio.ObjectInfo{
|
||||||
{Key: "testSound.mp3"},
|
{Key: "testSound.mp3"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -92,7 +92,7 @@ func TestBucketViewHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
"s3 error": {
|
"s3 error": {
|
||||||
s3: &S3ClientMock{
|
s3: &S3ClientMock{
|
||||||
Err: errors.New("internal S3 error"),
|
Err: errors.New("mocked S3 error"),
|
||||||
},
|
},
|
||||||
bucketName: "testBucket",
|
bucketName: "testBucket",
|
||||||
expectedStatusCode: http.StatusInternalServerError,
|
expectedStatusCode: http.StatusInternalServerError,
|
||||||
|
|
|
@ -34,7 +34,7 @@ func TestBucketsViewHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
"s3 error": {
|
"s3 error": {
|
||||||
s3: &S3ClientMock{
|
s3: &S3ClientMock{
|
||||||
Err: errors.New("internal S3 error"),
|
Err: errors.New("mocked S3 error"),
|
||||||
},
|
},
|
||||||
expectedStatusCode: http.StatusInternalServerError,
|
expectedStatusCode: http.StatusInternalServerError,
|
||||||
expectedBodyContains: "error listing buckets\n",
|
expectedBodyContains: "error listing buckets\n",
|
||||||
|
|
|
@ -39,7 +39,7 @@ func TestCreateBucketHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
"s3 error": {
|
"s3 error": {
|
||||||
s3: &S3ClientMock{
|
s3: &S3ClientMock{
|
||||||
Err: errors.New("internal S3 error"),
|
Err: errors.New("mocked S3 error"),
|
||||||
},
|
},
|
||||||
body: "{\"name\":\"myBucket\"}",
|
body: "{\"name\":\"myBucket\"}",
|
||||||
expectedStatusCode: http.StatusInternalServerError,
|
expectedStatusCode: http.StatusInternalServerError,
|
||||||
|
|
|
@ -24,7 +24,7 @@ func TestDeleteBucketHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
"s3 error": {
|
"s3 error": {
|
||||||
s3: &S3ClientMock{
|
s3: &S3ClientMock{
|
||||||
Err: errors.New("internal S3 error"),
|
Err: errors.New("mocked S3 error"),
|
||||||
},
|
},
|
||||||
expectedStatusCode: http.StatusInternalServerError,
|
expectedStatusCode: http.StatusInternalServerError,
|
||||||
expectedBody: "error removing bucket\n",
|
expectedBody: "error removing bucket\n",
|
||||||
|
|
|
@ -24,7 +24,7 @@ func TestDeleteObjectHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
"s3 error": {
|
"s3 error": {
|
||||||
s3: &S3ClientMock{
|
s3: &S3ClientMock{
|
||||||
Err: errors.New("internal S3 error"),
|
Err: errors.New("mocked S3 error"),
|
||||||
},
|
},
|
||||||
expectedStatusCode: http.StatusInternalServerError,
|
expectedStatusCode: http.StatusInternalServerError,
|
||||||
expectedBody: "error removing object\n",
|
expectedBody: "error removing object\n",
|
||||||
|
|
|
@ -27,7 +27,17 @@ func GetObjectHandler(s3 S3Client) http.Handler {
|
||||||
_, err = io.Copy(w, object)
|
_, err = io.Copy(w, object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg := "error copying object"
|
msg := "error copying object"
|
||||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
code := http.StatusInternalServerError
|
||||||
|
if err.Error() == "The specified key does not exist." {
|
||||||
|
msg = "object not found"
|
||||||
|
code = http.StatusNotFound
|
||||||
|
}
|
||||||
|
if err.Error() == "The specified bucket does not exist." {
|
||||||
|
msg = "bucket not found"
|
||||||
|
code = http.StatusNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
handleHTTPError(w, msg, err, code)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
57
get-object_test.go
Normal file
57
get-object_test.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetObjectHandler(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tests := map[string]struct {
|
||||||
|
s3 S3Client
|
||||||
|
bucketName string
|
||||||
|
objectName string
|
||||||
|
expectedStatusCode int
|
||||||
|
expectedBodyCountains string
|
||||||
|
}{
|
||||||
|
"s3 error": {
|
||||||
|
s3: &S3ClientMock{
|
||||||
|
Err: errors.New("mocked S3 error"),
|
||||||
|
},
|
||||||
|
bucketName: "testBucket",
|
||||||
|
objectName: "testObject",
|
||||||
|
expectedStatusCode: http.StatusInternalServerError,
|
||||||
|
expectedBodyCountains: "error getting object\n",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
r := mux.NewRouter()
|
||||||
|
r.
|
||||||
|
Methods("GET").
|
||||||
|
Path("/buckets/{bucketName}/objects/{objectName}").
|
||||||
|
Handler(GetObjectHandler(tc.s3))
|
||||||
|
|
||||||
|
ts := httptest.NewServer(r)
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s/buckets/%s/objects/%s", ts.URL, tc.bucketName, tc.objectName)
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
assert.NoError(err)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
assert.Equal(tc.expectedStatusCode, resp.StatusCode)
|
||||||
|
assert.Contains(string(body), tc.expectedBodyCountains)
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ package main
|
||||||
|
|
||||||
import "net/http"
|
import "net/http"
|
||||||
|
|
||||||
// IndexHandler forwards to "/buckets"
|
// IndexViewHandler forwards to "/buckets"
|
||||||
func IndexViewHandler() http.Handler {
|
func IndexViewHandler() http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Redirect(w, r, "/buckets", http.StatusPermanentRedirect)
|
http.Redirect(w, r, "/buckets", http.StatusPermanentRedirect)
|
||||||
|
|
36
index-view_test.go
Normal file
36
index-view_test.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIndexViewHandler(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tests := map[string]struct {
|
||||||
|
expectedStatusCode int
|
||||||
|
expectedBodyContains string
|
||||||
|
}{
|
||||||
|
"success": {
|
||||||
|
expectedStatusCode: http.StatusPermanentRedirect,
|
||||||
|
expectedBodyContains: "Redirect",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
req, err := http.NewRequest("GET", "/", nil)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
handler := IndexViewHandler()
|
||||||
|
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(tc.expectedStatusCode, rr.Code)
|
||||||
|
assert.Contains(rr.Body.String(), tc.expectedBodyContains)
|
||||||
|
}
|
||||||
|
}
|
2
main.go
2
main.go
|
@ -11,7 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s3 := NewMinioClient()
|
s3 := newMinioClient()
|
||||||
logger := log.New(os.Stdout, "", log.Ldate|log.Ltime)
|
logger := log.New(os.Stdout, "", log.Ldate|log.Ltime)
|
||||||
router := mux.NewRouter()
|
router := mux.NewRouter()
|
||||||
|
|
||||||
|
|
10
minio.go
10
minio.go
|
@ -7,23 +7,23 @@ import (
|
||||||
"github.com/minio/minio-go"
|
"github.com/minio/minio-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewMinioClient creates a new Minio client
|
// newMinioClient creates a new Minio client
|
||||||
func NewMinioClient() *minio.Client {
|
func newMinioClient() *minio.Client {
|
||||||
var err error
|
var err error
|
||||||
var client *minio.Client
|
var client *minio.Client
|
||||||
|
|
||||||
s3Endpoint := os.Getenv("S3_ENDPOINT")
|
s3Endpoint := os.Getenv("S3_ENDPOINT")
|
||||||
if len(s3Endpoint) == 0 {
|
if s3Endpoint == "" {
|
||||||
s3Endpoint = "s3.amazonaws.com"
|
s3Endpoint = "s3.amazonaws.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
s3AccessKeyID := os.Getenv("S3_ACCESS_KEY_ID")
|
s3AccessKeyID := os.Getenv("S3_ACCESS_KEY_ID")
|
||||||
if len(s3AccessKeyID) == 0 {
|
if s3AccessKeyID == "" {
|
||||||
log.Fatal("Please set S3_ACCESS_KEY_ID")
|
log.Fatal("Please set S3_ACCESS_KEY_ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
s3SecretAccessKey := os.Getenv("S3_SECRET_ACCESS_KEY")
|
s3SecretAccessKey := os.Getenv("S3_SECRET_ACCESS_KEY")
|
||||||
if len(s3SecretAccessKey) == 0 {
|
if s3SecretAccessKey == "" {
|
||||||
log.Fatal("Please set S3_SECRET_ACCESS_KEY")
|
log.Fatal("Please set S3_SECRET_ACCESS_KEY")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,18 +9,21 @@ import (
|
||||||
|
|
||||||
// S3ClientMock is a mocked S3 client
|
// S3ClientMock is a mocked S3 client
|
||||||
type S3ClientMock struct {
|
type S3ClientMock struct {
|
||||||
Buckets []minio.BucketInfo
|
Buckets []minio.BucketInfo
|
||||||
ObjectInfos []minio.ObjectInfo
|
Objects []minio.ObjectInfo
|
||||||
Objects []minio.Object
|
Err error
|
||||||
Err error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s S3ClientMock) CopyObject(string, string, string, minio.CopyConditions) error {
|
func (s S3ClientMock) CopyObject(string, string, string, minio.CopyConditions) error {
|
||||||
return s.Err
|
return s.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s S3ClientMock) GetObject(string, string) (*minio.Object, error) {
|
func (s S3ClientMock) GetObject(bucketName string, objectName string) (*minio.Object, error) {
|
||||||
return &s.Objects[0], s.Err
|
if s.Err != nil {
|
||||||
|
return nil, s.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &minio.Object{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s S3ClientMock) ListBuckets() ([]minio.BucketInfo, error) {
|
func (s S3ClientMock) ListBuckets() ([]minio.BucketInfo, error) {
|
||||||
|
@ -30,7 +33,7 @@ func (s S3ClientMock) ListBuckets() ([]minio.BucketInfo, error) {
|
||||||
func (s S3ClientMock) ListObjectsV2(bucketName string, p string, r bool, d <-chan struct{}) <-chan minio.ObjectInfo {
|
func (s S3ClientMock) ListObjectsV2(bucketName string, p string, r bool, d <-chan struct{}) <-chan minio.ObjectInfo {
|
||||||
// Add error if exists
|
// Add error if exists
|
||||||
if s.Err != nil {
|
if s.Err != nil {
|
||||||
s.ObjectInfos = append(s.ObjectInfos, minio.ObjectInfo{
|
s.Objects = append(s.Objects, minio.ObjectInfo{
|
||||||
Err: s.Err,
|
Err: s.Err,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -40,19 +43,20 @@ func (s S3ClientMock) ListObjectsV2(bucketName string, p string, r bool, d <-cha
|
||||||
for _, b := range s.Buckets {
|
for _, b := range s.Buckets {
|
||||||
if b.Name == bucketName {
|
if b.Name == bucketName {
|
||||||
found = true
|
found = true
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
if !found {
|
||||||
s.ObjectInfos = append(s.ObjectInfos, minio.ObjectInfo{
|
s.Objects = append(s.Objects, minio.ObjectInfo{
|
||||||
Err: errors.New("The specified bucket does not exist."),
|
Err: errors.New("The specified bucket does not exist."),
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
objCh := make(chan minio.ObjectInfo, len(s.ObjectInfos))
|
objCh := make(chan minio.ObjectInfo, len(s.Objects))
|
||||||
defer close(objCh)
|
defer close(objCh)
|
||||||
|
|
||||||
for _, obj := range s.ObjectInfos {
|
for _, obj := range s.Objects {
|
||||||
objCh <- obj
|
objCh <- obj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue