Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/libexec/pkg-serve/tests/pkg_serve_test.sh
178586 views
1
#-
2
# SPDX-License-Identifier: BSD-2-Clause
3
#
4
# Copyright (c) 2026 Baptiste Daroussin <[email protected]>
5
6
PKG_SERVE="${PKG_SERVE:-/usr/libexec/pkg-serve}"
7
8
serve()
9
{
10
printf "$1" | "${PKG_SERVE}" "$2"
11
}
12
13
check_output()
14
{
15
local pattern="$1" ; shift
16
output=$(serve "$@")
17
case "$output" in
18
*${pattern}*)
19
return 0
20
;;
21
*)
22
echo "Expected pattern: ${pattern}"
23
echo "Got: ${output}"
24
return 1
25
;;
26
esac
27
}
28
29
atf_test_case greeting
30
greeting_head()
31
{
32
atf_set "descr" "Server sends greeting on connect"
33
}
34
greeting_body()
35
{
36
mkdir repo
37
check_output "ok: pkg-serve " "quit\n" repo ||
38
atf_fail "greeting not found"
39
}
40
41
atf_test_case unknown_command
42
unknown_command_head()
43
{
44
atf_set "descr" "Unknown commands get ko response"
45
}
46
unknown_command_body()
47
{
48
mkdir repo
49
check_output "ko: unknown command 'plop'" "plop\nquit\n" repo ||
50
atf_fail "expected ko for unknown command"
51
}
52
53
atf_test_case get_missing_file
54
get_missing_file_head()
55
{
56
atf_set "descr" "Requesting a missing file returns ko"
57
}
58
get_missing_file_body()
59
{
60
mkdir repo
61
check_output "ko: file not found" "get nonexistent.pkg 0\nquit\n" repo ||
62
atf_fail "expected file not found"
63
}
64
65
atf_test_case get_file
66
get_file_head()
67
{
68
atf_set "descr" "Requesting an existing file returns its content"
69
}
70
get_file_body()
71
{
72
mkdir repo
73
echo "testcontent" > repo/test.pkg
74
output=$(serve "get test.pkg 0\nquit\n" repo)
75
echo "$output" | grep -q "ok: 12" ||
76
atf_fail "expected ok: 12, got: ${output}"
77
echo "$output" | grep -q "testcontent" ||
78
atf_fail "expected testcontent in output"
79
}
80
81
atf_test_case get_file_leading_slash
82
get_file_leading_slash_head()
83
{
84
atf_set "descr" "Leading slash in path is stripped"
85
}
86
get_file_leading_slash_body()
87
{
88
mkdir repo
89
echo "testcontent" > repo/test.pkg
90
check_output "ok: 12" "get /test.pkg 0\nquit\n" repo ||
91
atf_fail "leading slash not stripped"
92
}
93
94
atf_test_case get_file_uptodate
95
get_file_uptodate_head()
96
{
97
atf_set "descr" "File with old mtime returns ok: 0"
98
}
99
get_file_uptodate_body()
100
{
101
mkdir repo
102
echo "testcontent" > repo/test.pkg
103
check_output "ok: 0" "get test.pkg 9999999999\nquit\n" repo ||
104
atf_fail "expected ok: 0 for up-to-date file"
105
}
106
107
atf_test_case get_directory
108
get_directory_head()
109
{
110
atf_set "descr" "Requesting a directory returns ko"
111
}
112
get_directory_body()
113
{
114
mkdir -p repo/subdir
115
check_output "ko: not a file" "get subdir 0\nquit\n" repo ||
116
atf_fail "expected not a file"
117
}
118
119
atf_test_case get_missing_age
120
get_missing_age_head()
121
{
122
atf_set "descr" "get without age argument returns error"
123
}
124
get_missing_age_body()
125
{
126
mkdir repo
127
check_output "ko: bad command get" "get test.pkg\nquit\n" repo ||
128
atf_fail "expected bad command get"
129
}
130
131
atf_test_case get_bad_age
132
get_bad_age_head()
133
{
134
atf_set "descr" "get with non-numeric age returns error"
135
}
136
get_bad_age_body()
137
{
138
mkdir repo
139
check_output "ko: bad number" "get test.pkg notanumber\nquit\n" repo ||
140
atf_fail "expected bad number"
141
}
142
143
atf_test_case get_empty_arg
144
get_empty_arg_head()
145
{
146
atf_set "descr" "get with no arguments returns error"
147
}
148
get_empty_arg_body()
149
{
150
mkdir repo
151
check_output "ko: bad command get" "get \nquit\n" repo ||
152
atf_fail "expected bad command get"
153
}
154
155
atf_test_case path_traversal
156
path_traversal_head()
157
{
158
atf_set "descr" "Path traversal with .. is rejected"
159
}
160
path_traversal_body()
161
{
162
mkdir repo
163
check_output "ko: file not found" \
164
"get ../etc/passwd 0\nquit\n" repo ||
165
atf_fail "path traversal not rejected"
166
}
167
168
atf_test_case get_subdir_file
169
get_subdir_file_head()
170
{
171
atf_set "descr" "Files in subdirectories are served"
172
}
173
get_subdir_file_body()
174
{
175
mkdir -p repo/sub
176
echo "subcontent" > repo/sub/file.pkg
177
output=$(serve "get sub/file.pkg 0\nquit\n" repo)
178
echo "$output" | grep -q "ok: 11" ||
179
atf_fail "expected ok: 11, got: ${output}"
180
echo "$output" | grep -q "subcontent" ||
181
atf_fail "expected subcontent in output"
182
}
183
184
atf_test_case multiple_gets
185
multiple_gets_head()
186
{
187
atf_set "descr" "Multiple get commands in one session"
188
}
189
multiple_gets_body()
190
{
191
mkdir repo
192
echo "aaa" > repo/a.pkg
193
echo "bbb" > repo/b.pkg
194
output=$(serve "get a.pkg 0\nget b.pkg 0\nquit\n" repo)
195
echo "$output" | grep -q "ok: 4" ||
196
atf_fail "expected ok: 4 for a.pkg"
197
echo "$output" | grep -q "aaa" ||
198
atf_fail "expected content of a.pkg"
199
echo "$output" | grep -q "bbb" ||
200
atf_fail "expected content of b.pkg"
201
}
202
203
atf_test_case bad_basedir
204
bad_basedir_head()
205
{
206
atf_set "descr" "Non-existent basedir causes exit failure"
207
}
208
bad_basedir_body()
209
{
210
atf_check -s not-exit:0 -e match:"open" \
211
"${PKG_SERVE}" /nonexistent/path
212
}
213
214
atf_init_test_cases()
215
{
216
atf_add_test_case greeting
217
atf_add_test_case unknown_command
218
atf_add_test_case get_missing_file
219
atf_add_test_case get_file
220
atf_add_test_case get_file_leading_slash
221
atf_add_test_case get_file_uptodate
222
atf_add_test_case get_directory
223
atf_add_test_case get_missing_age
224
atf_add_test_case get_bad_age
225
atf_add_test_case get_empty_arg
226
atf_add_test_case path_traversal
227
atf_add_test_case get_subdir_file
228
atf_add_test_case multiple_gets
229
atf_add_test_case bad_basedir
230
}
231
232