-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfiletransfer_test.go
More file actions
122 lines (112 loc) · 3.57 KB
/
filetransfer_test.go
File metadata and controls
122 lines (112 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright © NGRSoftlab 2020-2025
package rexec
import (
"bytes"
"io"
"os"
"path/filepath"
"strings"
"testing"
)
func TestFileSpec_Validate(t *testing.T) {
tests := []struct {
name string
spec *FileSpec
wantErr string
}{
{name: "nil_spec", spec: nil, wantErr: "file specification empty"},
{name: "no_filename", spec: &FileSpec{TargetDir: "dir", Content: &FileContent{Data: []byte{1}}}, wantErr: "filename required"},
{name: "no_target", spec: &FileSpec{Filename: "file", Content: &FileContent{Data: []byte{1}}}, wantErr: "target directory required"},
{name: "no_content", spec: &FileSpec{Filename: "file", TargetDir: "dir"}, wantErr: "file content required"},
{name: "empty_content", spec: &FileSpec{Filename: "file", TargetDir: "dir", Content: &FileContent{}}, wantErr: "file content empty"},
{name: "valid", spec: &FileSpec{Filename: "file", TargetDir: "dir", Content: &FileContent{Data: []byte{1, 2, 3}}}, wantErr: ""},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := tc.spec.Validate()
if tc.wantErr == "" {
if err != nil {
t.Errorf("%s: unexpected error %v", tc.name, err)
}
} else {
if err == nil || !strings.Contains(err.Error(), tc.wantErr) {
t.Errorf("%s: error = %v; want %q", tc.name, err, tc.wantErr)
}
}
})
}
}
type seekerReader struct{ *bytes.Reader }
type noSeek struct{ io.Reader }
func TestFileContent_ReaderAndSize(t *testing.T) {
tests := []struct {
name string
typeCase string
inputData []byte
wantSize int64
wantErr bool
errContains string
}{
{"data", "data", []byte("hello"), 5, false, ""},
{"source_path", "sourcepath", []byte("abc"), 3, false, ""},
{"seekable_reader", "readerSeek", []byte("seekable"), 8, false, ""},
{"nonseekable_reader", "readerNoSeek", []byte("x"), 0, true, "reader is not seekable"},
{"nil_content", "nil", nil, 0, true, "no file content provided"},
{"open_error", "statError", nil, 0, true, "open source file"},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
var content *FileContent
var expectedData []byte
switch tc.typeCase {
case "data":
content = &FileContent{Data: tc.inputData}
expectedData = tc.inputData
case "sourcepath":
tmpDir := t.TempDir()
file := filepath.Join(tmpDir, "f.txt")
if err := os.WriteFile(file, tc.inputData, 0644); err != nil {
t.Fatalf("setup sourcepath: %v", err)
}
content = &FileContent{SourcePath: file}
expectedData = tc.inputData
case "readerSeek":
r := &seekerReader{Reader: bytes.NewReader(tc.inputData)}
content = &FileContent{Reader: r}
case "readerNoSeek":
r := noSeek{Reader: bytes.NewReader(tc.inputData)}
content = &FileContent{Reader: r}
case "nil":
content = nil
case "statError":
content = &FileContent{SourcePath: "/nonexistent"}
}
r, size, err := content.ReaderAndSize()
if tc.wantErr {
if err == nil || (tc.errContains != "" && !strings.Contains(err.Error(), tc.errContains)) {
t.Errorf("%s: error = %v; want containing %q", tc.name, err, tc.errContains)
}
return
}
if err != nil {
t.Fatalf("%s: unexpected error %v", tc.name, err)
}
if size != tc.wantSize {
t.Errorf("%s: size = %d; want %d", tc.name, size, tc.wantSize)
}
if expectedData != nil {
defer r.Close()
buf, err := io.ReadAll(r)
if err != nil {
t.Fatalf("%s: read error %v", tc.name, err)
}
if !bytes.Equal(buf, expectedData) {
t.Errorf("%s: data = %q; want %q", tc.name, buf, expectedData)
}
}
if r != nil {
r.Close()
}
})
}
}