1 use std
::path
::PathBuf
;
3 use anyhow
::{bail, format_err, Error}
;
5 use proxmox_apt
::config
::APTConfig
;
7 use proxmox_apt
::repositories
::{
8 check_repositories
, standard_repositories
, APTRepositoryFile
, APTRepositoryHandle
,
9 APTRepositoryInfo
, APTStandardRepository
,
13 fn test_parse_write() -> Result
<(), Error
> {
14 let test_dir
= std
::env
::current_dir()?
.join("tests");
15 let read_dir
= test_dir
.join("sources.list.d");
16 let write_dir
= test_dir
.join("sources.list.d.actual");
17 let expected_dir
= test_dir
.join("sources.list.d.expected");
19 if write_dir
.is_dir() {
20 std
::fs
::remove_dir_all(&write_dir
)
21 .map_err(|err
| format_err
!("unable to remove dir {:?} - {}", write_dir
, err
))?
;
24 std
::fs
::create_dir_all(&write_dir
)
25 .map_err(|err
| format_err
!("unable to create dir {:?} - {}", write_dir
, err
))?
;
27 let mut files
= vec
![];
28 let mut errors
= vec
![];
30 for entry
in std
::fs
::read_dir(read_dir
)?
{
31 let path
= entry?
.path();
33 match APTRepositoryFile
::new(&path
)?
{
34 Some(mut file
) => match file
.parse() {
35 Ok(()) => files
.push(file
),
36 Err(err
) => errors
.push(err
),
38 None
=> bail
!("unexpected None for '{:?}'", path
),
42 assert
!(errors
.is_empty());
44 for file
in files
.iter_mut() {
45 let path
= PathBuf
::from(&file
.path
);
46 let new_path
= write_dir
.join(path
.file_name().unwrap());
47 file
.path
= new_path
.into_os_string().into_string().unwrap();
52 let mut expected_count
= 0;
54 for entry
in std
::fs
::read_dir(expected_dir
)?
{
57 let expected_path
= entry?
.path();
58 let actual_path
= write_dir
.join(expected_path
.file_name().unwrap());
60 let expected_contents
= std
::fs
::read(&expected_path
)
61 .map_err(|err
| format_err
!("unable to read {:?} - {}", expected_path
, err
))?
;
63 let actual_contents
= std
::fs
::read(&actual_path
)
64 .map_err(|err
| format_err
!("unable to read {:?} - {}", actual_path
, err
))?
;
67 expected_contents
, actual_contents
,
68 "Use\n\ndiff {:?} {:?}\n\nif you're not fluent in byte decimals",
69 expected_path
, actual_path
73 let actual_count
= std
::fs
::read_dir(write_dir
)?
.count();
75 assert_eq
!(expected_count
, actual_count
);
81 fn test_digest() -> Result
<(), Error
> {
82 let test_dir
= std
::env
::current_dir()?
.join("tests");
83 let read_dir
= test_dir
.join("sources.list.d");
84 let write_dir
= test_dir
.join("sources.list.d.digest");
86 if write_dir
.is_dir() {
87 std
::fs
::remove_dir_all(&write_dir
)
88 .map_err(|err
| format_err
!("unable to remove dir {:?} - {}", write_dir
, err
))?
;
91 std
::fs
::create_dir_all(&write_dir
)
92 .map_err(|err
| format_err
!("unable to create dir {:?} - {}", write_dir
, err
))?
;
94 let path
= read_dir
.join("standard.list");
96 let mut file
= APTRepositoryFile
::new(&path
)?
.unwrap();
99 let new_path
= write_dir
.join(path
.file_name().unwrap());
100 file
.path
= new_path
.clone().into_os_string().into_string().unwrap();
102 let old_digest
= file
.digest
.unwrap();
104 // file does not exist yet...
105 assert
!(file
.read_with_digest().is_err());
106 assert
!(file
.write().is_err());
108 // ...but it should work if there's no digest
112 // overwrite with old contents...
113 std
::fs
::copy(path
, new_path
)?
;
116 let mut repo
= file
.repositories
.first_mut().unwrap();
117 repo
.enabled
= !repo
.enabled
;
119 // ...then it should work
120 file
.digest
= Some(old_digest
);
123 // expect a different digest, because the repo was modified
124 let (_
, new_digest
) = file
.read_with_digest()?
;
125 assert_ne
!(old_digest
, new_digest
);
127 assert
!(file
.write().is_err());
133 fn test_empty_write() -> Result
<(), Error
> {
134 let test_dir
= std
::env
::current_dir()?
.join("tests");
135 let read_dir
= test_dir
.join("sources.list.d");
136 let write_dir
= test_dir
.join("sources.list.d.remove");
138 if write_dir
.is_dir() {
139 std
::fs
::remove_dir_all(&write_dir
)
140 .map_err(|err
| format_err
!("unable to remove dir {:?} - {}", write_dir
, err
))?
;
143 std
::fs
::create_dir_all(&write_dir
)
144 .map_err(|err
| format_err
!("unable to create dir {:?} - {}", write_dir
, err
))?
;
146 let path
= read_dir
.join("standard.list");
148 let mut file
= APTRepositoryFile
::new(&path
)?
.unwrap();
151 let new_path
= write_dir
.join(path
.file_name().unwrap());
152 file
.path
= new_path
.clone().into_os_string().into_string().unwrap();
158 assert
!(file
.exists());
160 file
.repositories
.clear();
164 assert
!(!file
.exists());
170 fn test_check_repositories() -> Result
<(), Error
> {
171 let test_dir
= std
::env
::current_dir()?
.join("tests");
172 let read_dir
= test_dir
.join("sources.list.d");
174 proxmox_apt
::config
::init(APTConfig
::new(
175 Some(&test_dir
.into_os_string().into_string().unwrap()),
179 let absolute_suite_list
= read_dir
.join("absolute_suite.list");
180 let mut file
= APTRepositoryFile
::new(&absolute_suite_list
)?
.unwrap();
183 let infos
= check_repositories(&vec
![file
])?
;
185 assert_eq
!(infos
.is_empty(), true);
186 let pve_list
= read_dir
.join("pve.list");
187 let mut file
= APTRepositoryFile
::new(&pve_list
)?
.unwrap();
190 let path_string
= pve_list
.into_os_string().into_string().unwrap();
193 "Debian", "Debian", "Proxmox", "Proxmox", "Proxmox", "Debian",
196 let mut expected_infos
= vec
![];
198 expected_infos
.push(APTRepositoryInfo
{
199 path
: path_string
.clone(),
202 kind
: "origin".to_string(),
203 message
: origins
[n
].to_string(),
206 expected_infos
.sort();
208 let mut infos
= check_repositories(&vec
![file
])?
;
211 assert_eq
!(infos
, expected_infos
);
213 let bad_sources
= read_dir
.join("bad.sources");
214 let mut file
= APTRepositoryFile
::new(&bad_sources
)?
.unwrap();
217 let path_string
= bad_sources
.into_os_string().into_string().unwrap();
219 let mut expected_infos
= vec
![
221 path
: path_string
.clone(),
223 property
: Some("Suites".to_string()),
224 kind
: "warning".to_string(),
225 message
: "suite 'sid' should not be used in production!".to_string(),
228 path
: path_string
.clone(),
230 property
: Some("Suites".to_string()),
231 kind
: "warning".to_string(),
232 message
: "old suite 'lenny' configured!".to_string(),
235 path
: path_string
.clone(),
237 property
: Some("Suites".to_string()),
238 kind
: "warning".to_string(),
239 message
: "old suite 'stretch' configured!".to_string(),
242 path
: path_string
.clone(),
244 property
: Some("Suites".to_string()),
245 kind
: "warning".to_string(),
246 message
: "use the name of the stable distribution instead of 'stable'!".to_string(),
249 path
: path_string
.clone(),
251 property
: Some("Suites".to_string()),
252 kind
: "ignore-pre-upgrade-warning".to_string(),
253 message
: "suite 'bookworm' should not be used in production!".to_string(),
256 path
: path_string
.clone(),
258 property
: Some("Suites".to_string()),
259 kind
: "warning".to_string(),
260 message
: "suite 'testing' should not be used in production!".to_string(),
264 expected_infos
.push(APTRepositoryInfo
{
265 path
: path_string
.clone(),
268 kind
: "origin".to_string(),
269 message
: "Debian".to_string(),
272 expected_infos
.sort();
274 let mut infos
= check_repositories(&vec
![file
])?
;
277 assert_eq
!(infos
, expected_infos
);
283 fn test_get_cached_origin() -> Result
<(), Error
> {
284 let test_dir
= std
::env
::current_dir()?
.join("tests");
285 let read_dir
= test_dir
.join("sources.list.d");
287 proxmox_apt
::config
::init(APTConfig
::new(
288 Some(&test_dir
.into_os_string().into_string().unwrap()),
292 let pve_list
= read_dir
.join("pve.list");
293 let mut file
= APTRepositoryFile
::new(&pve_list
)?
.unwrap();
297 Some("Debian".to_string()),
298 Some("Debian".to_string()),
299 Some("Proxmox".to_string()),
300 None
, // no cache file exists
301 None
, // no cache file exists
302 Some("Debian".to_string()),
305 assert_eq
!(file
.repositories
.len(), origins
.len());
307 for (n
, repo
) in file
.repositories
.iter().enumerate() {
308 assert_eq
!(repo
.get_cached_origin()?
, origins
[n
]);
315 fn test_standard_repositories() -> Result
<(), Error
> {
316 let test_dir
= std
::env
::current_dir()?
.join("tests");
317 let read_dir
= test_dir
.join("sources.list.d");
319 let mut expected
= vec
![
320 APTStandardRepository
::from(APTRepositoryHandle
::Enterprise
),
321 APTStandardRepository
::from(APTRepositoryHandle
::NoSubscription
),
322 APTStandardRepository
::from(APTRepositoryHandle
::Test
),
323 APTStandardRepository
::from(APTRepositoryHandle
::CephPacific
),
324 APTStandardRepository
::from(APTRepositoryHandle
::CephPacificTest
),
325 APTStandardRepository
::from(APTRepositoryHandle
::CephOctopus
),
326 APTStandardRepository
::from(APTRepositoryHandle
::CephOctopusTest
),
329 let absolute_suite_list
= read_dir
.join("absolute_suite.list");
330 let mut file
= APTRepositoryFile
::new(&absolute_suite_list
)?
.unwrap();
333 let std_repos
= standard_repositories("pve", &vec
![file
]);
335 assert_eq
!(std_repos
, expected
);
337 let pve_list
= read_dir
.join("pve.list");
338 let mut file
= APTRepositoryFile
::new(&pve_list
)?
.unwrap();
341 let file_vec
= vec
![file
];
343 let std_repos
= standard_repositories("pbs", &file_vec
);
345 assert_eq
!(&std_repos
, &expected
[0..=2]);
347 expected
[0].status
= Some(false);
348 expected
[1].status
= Some(true);
350 let std_repos
= standard_repositories("pve", &file_vec
);
352 assert_eq
!(std_repos
, expected
);