Skip to content
This repository has been archived by the owner on Dec 25, 2024. It is now read-only.

Commit

Permalink
test(api): added tests for downloading file
Browse files Browse the repository at this point in the history
  • Loading branch information
Wittano committed Jun 30, 2024
1 parent c7b8fba commit 5169ac6
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 51 deletions.
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,13 @@ protobuf:
mkdir -p $(PROTOBUF_API_DEST)
protoc --go_out=./api --go_opt=paths=source_relative --go-grpc_out=./api --go-grpc_opt=paths=source_relative proto/*

test: protobuf
CGO_CFLAGS="-w" find . -name go.mod -execdir go test ./... \;
test: test-bot test-server

test-bot: protobuf
CGO_CFLAGS="-w" go test ./bot/...;

test-server: protobuf
CGO_CFLAGS="-w" go test ./server/...;

all: bot-prod sever tui test

Expand Down
46 changes: 41 additions & 5 deletions audio/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package audio

import (
"errors"
"fmt"
"io"
"math/rand"
"os"
"os/exec"
"path/filepath"
"strings"
"syscall"
"time"
)
Expand All @@ -16,8 +18,41 @@ const (
assetsDirKey = "ASSETS_DIR"
)

func Path(name string) string {
return filepath.Join(AssertDir(), name)
func Path(name string) (path string, err error) {
assertDir := AssertDir()
path = filepath.Join(assertDir, name)
_, err = os.Stat(path)
if err != nil {
path, err = searchPathByNameOrUUID(name)
}

return
}

func searchPathByNameOrUUID(prefix string) (p string, err error) {
var paths []string
paths, err = Paths()
if err != nil {
return
}

for _, p = range paths {
base := filepath.Base(p)
if strings.HasPrefix(base, prefix) {
return
} else {
split := strings.Split(base, "-")
if len(split) < 2 {
continue
}

if strings.HasPrefix(strings.Join(split[1:], "-"), prefix) {
return
}
}
}

return "", fmt.Errorf("path with prefix %s wasn't found", prefix)
}

func AssertDir() (path string) {
Expand All @@ -30,7 +65,8 @@ func AssertDir() (path string) {
}

func Paths() (paths []string, err error) {
dirs, err := os.ReadDir(AssertDir())
assertDir := AssertDir()
dirs, err := os.ReadDir(assertDir)
if err != nil {
return nil, err
}
Expand All @@ -42,7 +78,7 @@ func Paths() (paths []string, err error) {
paths = make([]string, 0, len(dirs))
for _, dir := range dirs {
if dir.Type() != os.ModeDir {
paths = append(paths, dir.Name())
paths = append(paths, filepath.Join(assertDir, dir.Name()))
}
}

Expand Down Expand Up @@ -77,7 +113,7 @@ func PathsWithPagination(page uint32, size uint32) (paths []string, err error) {
return
}

func RandomPath() (string, error) {
func RandomAudioName() (string, error) {
paths, err := Paths()
if err != nil {
return "", err
Expand Down
4 changes: 2 additions & 2 deletions bot/command/spock.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ func audioPath(data discordgo.ApplicationCommandInteractionData) (path string, e
}

if name == "" {
path, err = audio.RandomPath()
path, err = audio.RandomAudioName()
} else {
path = audio.Path(path)
path, err = audio.Path(path)
}

return
Expand Down
28 changes: 9 additions & 19 deletions server/audio.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,22 @@ func (a audioServer) List(pagination *pb.Pagination, server pb.AudioService_List
return
}

// TODO Add file validation
func (a audioServer) Add(server pb.AudioService_AddServer) error {
id := uuid.NewString()
var path string

au, err := server.Recv()
if err != nil && !errors.Is(err, io.EOF) {
if err != nil {
return status.Error(codes.Internal, err.Error())
}

if fileExistsInAssetsDir(au.Info.Name) {
if _, err := audio.Path(au.Info.Name); err == nil {
return status.Error(codes.AlreadyExists, fmt.Sprintf("file %s already exists", au.Info.Name))
}

if path == "" {
path = audio.Path(fmt.Sprintf("%s-%s.%s", au.Info.Name, id, strings.ToLower(au.Info.Type.String())))
path = filepath.Join(audio.AssertDir(), fmt.Sprintf("%s-%s.%s", au.Info.Name, id, strings.ToLower(au.Info.Type.String())))
}

f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0600)
Expand Down Expand Up @@ -95,24 +96,13 @@ func (a audioServer) Remove(_ context.Context, req *pb.RemoveAudio) (e *emptypb.
}

for _, query := range req.Name {
rmErr := os.Remove(audio.Path(query))
if rmErr != nil {
err = errors.Join(err, status.Error(codes.NotFound, rmErr.Error()))
path, err := audio.Path(query)
if err != nil {
return nil, status.Error(codes.NotFound, err.Error())
}
}

return
}

func fileExistsInAssetsDir(filename string) (exists bool) {
dir, err := os.ReadDir(audio.AssertDir())
if err != nil {
return
}

for _, d := range dir {
if strings.HasPrefix(d.Name(), filename) {
return true
if err = os.Remove(path); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
}

Expand Down
27 changes: 18 additions & 9 deletions server/audio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (c closers) Close() (err error) {
return
}

func createClient() (client pb.AudioServiceClient, server io.Closer, err error) {
func createAudioClient() (client pb.AudioServiceClient, server io.Closer, err error) {
s, err := New(port)
if err != nil {
return nil, nil, err
Expand All @@ -59,7 +59,7 @@ func createClient() (client pb.AudioServiceClient, server io.Closer, err error)
}

func TestRemoveAudio(t *testing.T) {
client, closer, err := createClient()
client, closer, err := createAudioClient()
if err != nil {
t.Fatal(err)
}
Expand All @@ -74,13 +74,17 @@ func TestRemoveAudio(t *testing.T) {
t.Fatal(err)
}

for i, p := range paths {
paths[i] = filepath.Base(p)
}

if _, err := client.Remove(context.Background(), &pb.RemoveAudio{Name: paths}); err != nil {
t.Fatal(err)
}
}

func TestUploadFile(t *testing.T) {
client, closer, err := createClient()
client, closer, err := createAudioClient()
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -116,13 +120,18 @@ func TestUploadFile(t *testing.T) {
t.Fatal(err)
}

if s, err := os.Stat(audio.Path(res.Filename)); err != nil || s.Size() == 0 {
path, err = audio.Path(res.Filename)
if err != nil {
t.Fatal(err)
}

if s, err := os.Stat(path); err != nil || s.Size() == 0 {
t.Fatalf("failed upload file: %v", err)
}
}

func TestUploadFile_FileAlreadyExists(t *testing.T) {
client, closer, err := createClient()
client, closer, err := createAudioClient()
if err != nil {
t.Fatal(err)
}
Expand All @@ -132,9 +141,9 @@ func TestUploadFile_FileAlreadyExists(t *testing.T) {
t.Fatal(err)
}

path := audio.Path("test")
f, err := os.Create(path)
if err != nil {
path := filepath.Join(audio.AssertDir(), "test")
f, createErr := os.Create(path)
if errors.Join(err, createErr) != nil {
t.Fatal(err)
}
f.Close()
Expand Down Expand Up @@ -164,7 +173,7 @@ func fillTempFile(t *testing.T, path string) error {
}
defer f.Close()

for i := 0; i < 1000; i++ {
for i := 0; i < 100; i++ {
if _, err := f.WriteString(strconv.Itoa(rand.Int()) + "\n"); err != nil {
return err
}
Expand Down
34 changes: 22 additions & 12 deletions server/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,54 @@ import (
"fmt"
komputer "github.com/wittano/komputer/api/proto"
"github.com/wittano/komputer/audio"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"io"
"log/slog"
"os"
)

const downloadBufSize = 1024 * 1024

type fileServer struct {
komputer.UnimplementedAudioFileServiceServer
}

// TODO Verification of service structe
func (fs fileServer) Download(req *komputer.DownloadFile, server komputer.AudioFileService_DownloadServer) error {
if req == nil {
return errors.New("download: missing req data")
return status.Error(codes.InvalidArgument, "download: missing required data")
}

path, err := audio.Path(filename(req))
if err != nil {
return status.Error(codes.NotFound, err.Error())
}

path := audio.Path(filename(req))
f, err := os.Open(path)
if err != nil {
slog.Error("failed find f "+path, err)
return err
return status.Error(codes.NotFound, err.Error())
}
defer f.Close()

ctx := server.Context()

buf := make([]byte, 1024)
buf := make([]byte, downloadBufSize)
for {
select {
case <-ctx.Done():
return context.Canceled
case <-server.Context().Done():
return status.Error(codes.Canceled, context.Canceled.Error())
default:
}

n, err := f.Read(buf)
if errors.Is(err, io.EOF) {
break
} else if err != nil {
return err
return status.Error(codes.Internal, err.Error())
}

if err = server.Send(&komputer.FileBuffer{Content: buf, Size: uint64(n)}); err != nil {
return err
slog.Error("failed send chunk of file", err)
return status.Error(codes.Internal, err.Error())
}
}

Expand All @@ -66,5 +72,9 @@ func filename(req *komputer.DownloadFile) (name string) {
return
}

return fmt.Sprintf("%s-%s", name, uuid)
if name == "" {
return string(uuid.Uuid)
}

return fmt.Sprintf("%s-%s", name, uuid.Uuid)
}
Loading

0 comments on commit 5169ac6

Please sign in to comment.