Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add isTruncated & add test code #15

Merged
merged 4 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22.4'
go-version: '1.22.5'

- name: Build
run: go build -v ./...
Expand Down
67 changes: 42 additions & 25 deletions core/amazon/awssdk/listobjects_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@ import (
"strings"
)

type ListBucketResult struct {
XMLName xml.Name `xml:"ListBucketResult"`
Name string `xml:"Name"`
Prefix string `xml:"Prefix"`
Marker string `xml:"Marker"`
Items []Item `xml:"Contents"`
type ListObjectsResult struct {
XMLName xml.Name `xml:"ListBucketResult"`
Name string `xml:"Name"`
Prefix string `xml:"Prefix"`
Marker string `xml:"Marker"`
Items []Item `xml:"Contents"`
IsTruncated bool `xml:"IsTruncated"`
}

type Item struct {
Key string `xml:"Key"`
Size int64 `xml:"Size"`
}

func ListObjectsV2(w http.ResponseWriter, r *http.Request) {
func ListObjectsV2(w http.ResponseWriter, r *http.Request, uploadDirName string) {
slog.Info("ListObjectsV2 is called.")

path := strings.Split(r.URL.Path, "?list-type=2")[0] // It has been confirmed in the previous process controller.go that `?list-type=2` is included.
Expand All @@ -33,22 +34,9 @@ func ListObjectsV2(w http.ResponseWriter, r *http.Request) {
return
}

// Define the target directory
rootDir := filepath.Join("upload", dir)
rootDir := filepath.Join(uploadDirName, dir)

var items []Item
err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
items = append(items, Item{
Key: filepath.ToSlash(path[len("upload/"):]), // Convert to a relative path
Size: info.Size(),
})
}
return nil
})
items, err := ListObjects(rootDir, uploadDirName)
if err != nil {
slog.Error("Failed to list objects", "error", err)
http.Error(w, "Failed to list objects", http.StatusInternalServerError)
Expand All @@ -57,9 +45,12 @@ func ListObjectsV2(w http.ResponseWriter, r *http.Request) {

slog.Info("Files are below", "files", items)

response := ListBucketResult{
Name: dir,
Items: items,
isTruncated, items := IsTruncated(items)

response := ListObjectsResult{
Name: dir,
Items: items,
IsTruncated: isTruncated,
}

w.Header().Set("Content-Type", "application/xml")
Expand All @@ -68,3 +59,29 @@ func ListObjectsV2(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
}
}

func ListObjects(rootDir string, uploadDirName string) ([]Item, error) {
var items []Item
err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
items = append(items, Item{
Key: filepath.ToSlash(path[len(uploadDirName+"/"):]),
Size: info.Size(),
})
}
return nil
})

return items, err
}

func IsTruncated(items []Item) (bool, []Item) {
if len(items) > 1000 {
return true, items[:1000]
} else {
return false, items
}
}
82 changes: 82 additions & 0 deletions core/amazon/awssdk/listobjects_v2_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package awssdk

import (
"os"
"path/filepath"
"testing"

"github.com/go-playground/assert/v2"
)

func TestListObjects(t *testing.T) {
// Create a temporary directory and file for testing
tempDir := "test-upload"
err := os.Mkdir(tempDir, 0777)
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tempDir)

err = os.MkdirAll(filepath.Join(tempDir, "dir1"), os.ModePerm)
if err != nil {
t.Fatal(err)
}

err = os.WriteFile(filepath.Join(tempDir, "file1.txt"), []byte("file1 content"), os.ModePerm)
if err != nil {
t.Fatal(err)
}

err = os.WriteFile(filepath.Join(tempDir, "dir1", "file2.txt"), []byte("file2 content"), os.ModePerm)
if err != nil {
t.Fatal(err)
}

// actual
actualItems, err := ListObjects(filepath.Join(tempDir), "test-upload")
if err != nil {
t.Fatalf("ListObjects returned an error: %v", err)
}

// expected
expectedItems := []Item{
{Key: "dir1/file2.txt", Size: int64(len("file2 content"))},
{Key: "file1.txt", Size: int64(len("file1 content"))},
}

// assertion
assert.Equal(t, len(actualItems), len(expectedItems))
for i, item := range actualItems {
assert.Equal(t, item.Key, expectedItems[i].Key)
assert.Equal(t, item.Size, expectedItems[i].Size)
}
}

func TestIsTruncated(t *testing.T) {
items1 := make([]Item, 1)
items999 := make([]Item, 999)
items1000 := make([]Item, 1000)
items1001 := make([]Item, 1001)
items1200 := make([]Item, 1200)

isTruncated1, actualItems1 := IsTruncated(items1)
assert.Equal(t, isTruncated1, false)
assert.Equal(t, actualItems1, items1)

isTruncated999, actualItems999 := IsTruncated(items999)
assert.Equal(t, isTruncated999, false)
assert.Equal(t, actualItems999, items999)

isTruncated1000, actualItems1000 := IsTruncated(items1000)
assert.Equal(t, isTruncated1000, false)
assert.Equal(t, actualItems1000, items1000)

isTruncated1001, actualItems1001 := IsTruncated(items1001)
assert.Equal(t, isTruncated1001, true)
assert.Equal(t, actualItems1001, items1001[:1000])

isTruncated1200, actualItems1200 := IsTruncated(items1200)
assert.Equal(t, isTruncated1200, true)
assert.Equal(t, actualItems1200, items1200[:1000])

}
3 changes: 2 additions & 1 deletion web/constant.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package web

const (
UPLOAD_DIR = "./upload"
UPLOAD_DIR_PATH = "./upload"
UPLOAD_DIR_NAME = "upload"
)
2 changes: 1 addition & 1 deletion web/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func CliSdkHandler(w http.ResponseWriter, r *http.Request) {
if strings.Contains(userAgent, "aws-sdk") {
if r.Method == "GET" {
if r.URL.Query().Get("list-type") == "2" {
awssdk.ListObjectsV2(w, r)
awssdk.ListObjectsV2(w, r, UPLOAD_DIR_NAME)
} else {
awssdk.Get(w, r)
}
Expand Down
4 changes: 2 additions & 2 deletions web/dir_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func MkdirHandler(w http.ResponseWriter, r *http.Request) {

currentPath := r.FormValue("currentPath")
dirname := r.FormValue("dirname")
dir := filepath.Join(UPLOAD_DIR, currentPath, dirname)
dir := filepath.Join(UPLOAD_DIR_PATH, currentPath, dirname)
err := os.Mkdir(dir, os.ModePerm)
if err != nil {
slog.Error("failed to mkdir", "target directory", dir, "error", err)
Expand All @@ -34,7 +34,7 @@ func RmdirHandler(w http.ResponseWriter, r *http.Request) {
}

dirname := r.FormValue("dirname")
err := os.Remove(filepath.Join(UPLOAD_DIR, dirname))
err := os.Remove(filepath.Join(UPLOAD_DIR_PATH, dirname))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
Expand Down
4 changes: 2 additions & 2 deletions web/rename_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func RenameHandler(w http.ResponseWriter, r *http.Request) {

oldFilename := r.FormValue("oldFilename")
newFilename := r.FormValue("newFilename")
err := os.Rename(filepath.Join(UPLOAD_DIR, oldFilename), filepath.Join(UPLOAD_DIR, newFilename))
err := os.Rename(filepath.Join(UPLOAD_DIR_PATH, oldFilename), filepath.Join(UPLOAD_DIR_PATH, newFilename))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
Expand All @@ -31,7 +31,7 @@ func RenamedirHandler(w http.ResponseWriter, r *http.Request) {

oldDirname := r.FormValue("oldDirname")
newDirname := r.FormValue("newDirname")
err := os.Rename(filepath.Join(UPLOAD_DIR, oldDirname), filepath.Join(UPLOAD_DIR, newDirname))
err := os.Rename(filepath.Join(UPLOAD_DIR_PATH, oldDirname), filepath.Join(UPLOAD_DIR_PATH, newDirname))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
Expand Down
2 changes: 1 addition & 1 deletion web/rm_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func RemoveHandler(w http.ResponseWriter, r *http.Request) {
}

path := r.FormValue("path")[len("/s3/"):]
err := os.Remove(filepath.Join(UPLOAD_DIR, path))
err := os.Remove(filepath.Join(UPLOAD_DIR_PATH, path))
if err != nil {
slog.Error("Failed to remove.", "error", err, "path", path)
http.Error(w, err.Error(), http.StatusInternalServerError)
Expand Down
4 changes: 2 additions & 2 deletions web/s3_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func S3Handler(w http.ResponseWriter, r *http.Request) {
slog.Info("S3Handler is called.")
path := r.URL.Path[len("/s3/"):]

s3Objects, err := util.GenerateS3Objects(r, UPLOAD_DIR, GetDirPath(path))
s3Objects, err := util.GenerateS3Objects(r, UPLOAD_DIR_PATH, GetDirPath(path))
if err != nil {
slog.Error("GenerateS3Objects error", "error", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
Expand Down Expand Up @@ -59,7 +59,7 @@ func S3Handler(w http.ResponseWriter, r *http.Request) {
func download(w http.ResponseWriter, path string) (n int64, httpStatus int, err error) {
slog.Info("Start downloading file", "path", path)

file, err := os.Open(filepath.Join(UPLOAD_DIR, path))
file, err := os.Open(filepath.Join(UPLOAD_DIR_PATH, path))
if err != nil {
slog.Error("File open error", "error", err)
return 0, http.StatusNotFound, err
Expand Down
2 changes: 1 addition & 1 deletion web/upload_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func UploadHandler(w http.ResponseWriter, r *http.Request) {
}
defer file.Close()

dst, err := os.Create(filepath.Join(UPLOAD_DIR, path, header.Filename))
dst, err := os.Create(filepath.Join(UPLOAD_DIR_PATH, path, header.Filename))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
Expand Down